Skip to content

Commit 3a6d281

Browse files
committed
CP-53555: Split unplug atomic into deactivate/detach
Signed-off-by: Steven Woods <[email protected]>
1 parent a1f364e commit 3a6d281

6 files changed

+105
-24
lines changed

ocaml/xenopsd/lib/storage.ml

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ let deactivate task dp sr vdi vmdomid =
8484
(Printf.sprintf "VDI.deactivate %s" dp)
8585
(transform_exception (fun () -> Client.VDI.deactivate dbg dp sr vdi vmdomid))
8686

87+
(* TODO replace DP.destroy with something that just detaches? *)
88+
(* This should work for now as, based on current usage of deactivate above during migrate,
89+
DP.destroy must have an idempotent deactivate, so can be safely used just for its detach *)
8790
let dp_destroy task dp =
8891
Xenops_task.with_subtask task
8992
(Printf.sprintf "DP.destroy %s" dp)

ocaml/xenopsd/lib/xenops_server.ml

+30-3
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ type atomic =
130130
| VBD_epoch_end of (Vbd.id * disk)
131131
| VBD_set_qos of Vbd.id
132132
| VBD_unplug of Vbd.id * bool
133+
| VBD_deactivate of Vbd.id * bool
134+
| VBD_detach of Vbd.id
133135
| VBD_insert of Vbd.id * disk
134136
| VBD_set_active of Vbd.id * bool
135137
| VM_remove of Vm.id
@@ -211,6 +213,10 @@ let rec name_of_atomic = function
211213
"VBD_set_qos"
212214
| VBD_unplug _ ->
213215
"VBD_unplug"
216+
| VBD_deactivate _ ->
217+
"VBD_deactivate"
218+
| VBD_detach _ ->
219+
"VBD_detach"
214220
| VBD_insert _ ->
215221
"VBD_insert"
216222
| VBD_set_active _ ->
@@ -1600,6 +1606,14 @@ let split_plug_atomic id vbd_id =
16001606
serial_of "VBD.attach_and_activate" ~id (VBD_attach vbd_id)
16011607
(VBD_activate vbd_id) []
16021608

1609+
let split_unplug_atomic id vbd_id force =
1610+
if !xenopsd_vbd_plug_unplug_legacy then
1611+
VBD_unplug (vbd_id, force)
1612+
else
1613+
serial_of "VBD.deactivate_and_detach" ~id
1614+
(VBD_deactivate (vbd_id, force))
1615+
(VBD_detach vbd_id) []
1616+
16031617
let rec atomics_of_operation = function
16041618
| VM_start (id, force) ->
16051619
let vbds_rw, vbds_ro = VBD_DB.vbds id |> vbd_plug_sets in
@@ -1688,7 +1702,7 @@ let rec atomics_of_operation = function
16881702
]
16891703
; parallel_concat "Devices.unplug" ~id
16901704
[
1691-
List.map (fun vbd -> VBD_unplug (vbd.Vbd.id, true)) vbds
1705+
List.map (fun vbd -> split_unplug_atomic id vbd.Vbd.id true) vbds
16921706
; List.map (fun vif -> VIF_unplug (vif.Vif.id, true)) vifs
16931707
; List.map (fun pci -> PCI_unplug pci.Pci.id) pcis
16941708
]
@@ -1850,7 +1864,7 @@ let rec atomics_of_operation = function
18501864
| VBD_hotplug id ->
18511865
[VBD_set_active (id, true); split_plug_atomic "VBD_hotplug" id]
18521866
| VBD_hotunplug (id, force) ->
1853-
[VBD_unplug (id, force); VBD_set_active (id, false)]
1867+
[split_unplug_atomic "VBD_hotunplug" id force; VBD_set_active (id, false)]
18541868
| VIF_hotplug id ->
18551869
[VIF_set_active (id, true); VIF_plug id]
18561870
| VIF_hotunplug (id, force) ->
@@ -2065,7 +2079,18 @@ let rec perform_atomic ~progress_callback ?result (op : atomic)
20652079
| VBD_unplug (id, force) ->
20662080
debug "VBD.unplug %s" (VBD_DB.string_of_id id) ;
20672081
finally
2068-
(fun () -> B.VBD.unplug t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force)
2082+
(fun () ->
2083+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force ;
2084+
B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id)
2085+
)
2086+
(fun () -> VBD_DB.signal id)
2087+
| VBD_deactivate (id, force) ->
2088+
debug "VBD.deactivate %s" (VBD_DB.string_of_id id) ;
2089+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force
2090+
| VBD_detach id ->
2091+
debug "VBD.detach %s" (VBD_DB.string_of_id id) ;
2092+
finally
2093+
(fun () -> B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id))
20692094
(fun () -> VBD_DB.signal id)
20702095
| VBD_insert (id, disk) -> (
20712096
(* NB this is also used to "refresh" ie signal a qemu that it should
@@ -2481,6 +2506,8 @@ and trigger_cleanup_after_failure_atom op t =
24812506
| VBD_epoch_end (id, _)
24822507
| VBD_set_qos id
24832508
| VBD_unplug (id, _)
2509+
| VBD_deactivate (id, _)
2510+
| VBD_detach id
24842511
| VBD_insert (id, _) ->
24852512
immediate_operation dbg (fst id) (VBD_check_state id)
24862513
| VIF_plug id

ocaml/xenopsd/lib/xenops_server_plugin.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ module type S = sig
211211

212212
val activate : Xenops_task.task_handle -> Vm.id -> Vbd.t -> unit
213213

214-
val unplug : Xenops_task.task_handle -> Vm.id -> Vbd.t -> bool -> unit
214+
val deactivate : Xenops_task.task_handle -> Vm.id -> Vbd.t -> bool -> unit
215+
216+
val detach : Xenops_task.task_handle -> Vm.id -> Vbd.t -> unit
215217

216218
val insert : Xenops_task.task_handle -> Vm.id -> Vbd.t -> disk -> unit
217219

ocaml/xenopsd/lib/xenops_server_simulator.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,9 @@ module VBD = struct
677677

678678
let activate _ (_vm : Vm.id) (_vbd : Vbd.t) = ()
679679

680-
let unplug _ vm vbd _ = with_lock m (remove_vbd vm vbd)
680+
let deactivate _ vm vbd _ = with_lock m (remove_vbd vm vbd)
681+
682+
let detach _ _vm _vbd = ()
681683

682684
let insert _ _vm _vbd _disk = ()
683685

ocaml/xenopsd/lib/xenops_server_skeleton.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ module VBD = struct
149149

150150
let activate _ _ _ = unimplemented "VBD.activate"
151151

152-
let unplug _ _ _ _ = unimplemented "VBD.unplug"
152+
let deactivate _ _ _ _ = unimplemented "VBD.deactivate"
153+
154+
let detach _ _ _ = unimplemented "VBD.detach"
153155

154156
let insert _ _ _ _ = unimplemented "VBD.insert"
155157

ocaml/xenopsd/xc/xenops_server_xen.ml

+63-18
Original file line numberDiff line numberDiff line change
@@ -3889,23 +3889,23 @@ module VBD = struct
38893889
)
38903890
(fun () -> cleanup_attached_vdis vm vbd.id)
38913891

3892-
let unplug task vm vbd force =
3893-
with_tracing ~task ~name:"VBD_unplug" @@ fun () ->
3892+
let deactivate task vm vbd force =
3893+
with_tracing ~task ~name:"VBD_deactivate" @@ fun () ->
38943894
with_xc_and_xs (fun xc xs ->
38953895
try
38963896
(* On destroying the datapath
38973897
3898-
1. if the device has already been shutdown and deactivated (as in
3899-
suspend) we must call DP.destroy here to avoid leaks
3898+
1. if the device has already been shutdown and deactivated (as in
3899+
suspend) we must call DP.destroy here to avoid leaks
39003900
3901-
2. if the device is successfully shutdown here then we must call
3902-
DP.destroy because no-one else will
3901+
2. if the device is successfully shutdown here then we must call
3902+
DP.destroy because no-one else will
39033903
3904-
3. if the device shutdown is rejected then we should leave the DP
3905-
alone and rely on the event thread calling us again later. *)
3904+
3. if the device shutdown is rejected then we should leave the DP
3905+
alone and rely on the event thread calling us again later. *)
39063906
let domid = domid_of_uuid ~xs (uuid_of_string vm) in
39073907
(* If the device is gone then we don't need to shut it down but we do
3908-
need to free any storage resources. *)
3908+
need to free any storage resources. *)
39093909
let dev =
39103910
try
39113911
Some (device_by_id xc xs vm (device_kind_of ~xs vbd) (id_of vbd))
@@ -3943,8 +3943,9 @@ module VBD = struct
39433943
vm (id_of vbd) ;
39443944
(* this happens on normal shutdown too *)
39453945
(* Case (1): success; Case (2): success; Case (3): an exception is
3946-
thrown *)
3947-
with_tracing ~task ~name:"VBD_device_shutdown" @@ fun () ->
3946+
thrown *)
3947+
with_tracing ~task ~name:"VBD_deactivate_clean_shutdown"
3948+
@@ fun () ->
39483949
Xenops_task.with_subtask task
39493950
(Printf.sprintf "Vbd.clean_shutdown %s" (id_of vbd))
39503951
(fun () ->
@@ -3954,10 +3955,10 @@ module VBD = struct
39543955
)
39553956
dev ;
39563957
(* We now have a shutdown device but an active DP: we should destroy
3957-
the DP if the backend is of type VDI *)
3958+
the DP if the backend is of type VDI *)
39583959
finally
39593960
(fun () ->
3960-
( with_tracing ~task ~name:"VBD_device_release" @@ fun () ->
3961+
( with_tracing ~task ~name:"VBD_deactivate_release" @@ fun () ->
39613962
Option.iter
39623963
(fun dev ->
39633964
Xenops_task.with_subtask task
@@ -3967,7 +3968,7 @@ module VBD = struct
39673968
dev
39683969
) ;
39693970
(* If we have a qemu frontend, detach this too. *)
3970-
with_tracing ~task ~name:"VBD_detach_qemu" @@ fun () ->
3971+
with_tracing ~task ~name:"VBD_deactivate_detach_qemu" @@ fun () ->
39713972
let _ =
39723973
DB.update vm
39733974
(Option.map (fun vm_t ->
@@ -3998,11 +3999,14 @@ module VBD = struct
39983999
()
39994000
)
40004001
(fun () ->
4001-
with_tracing ~task ~name:"VBD_dp_destroy" @@ fun () ->
4002+
with_tracing ~task ~name:"VBD_deactivate_deactivate" @@ fun () ->
4003+
let vmid = Storage.vm_of_domid domid in
40024004
match (domid, backend) with
4003-
| Some x, None | Some x, Some (VDI _) ->
4004-
Storage.dp_destroy task
4005-
(Storage.id_of (string_of_int x) vbd.Vbd.id)
4005+
| Some x, Some (VDI path) ->
4006+
let sr, vdi = Storage.get_disk_by_name task path in
4007+
let dp = Storage.id_of (string_of_int x) vbd.id in
4008+
Storage.deactivate task dp sr vdi vmid
4009+
(* TODO Do we only need to deactivate VDIs, not Local or CD? *)
40064010
| _ ->
40074011
()
40084012
)
@@ -4011,6 +4015,47 @@ module VBD = struct
40114015
raise (Xenopsd_error (Device_detach_rejected ("VBD", id_of vbd, s)))
40124016
)
40134017

4018+
let detach task vm vbd =
4019+
with_tracing ~task ~name:"VBD_detach" @@ fun () ->
4020+
with_xc_and_xs (fun xc xs ->
4021+
let domid = domid_of_uuid ~xs (uuid_of_string vm) in
4022+
let dev =
4023+
try
4024+
Some (device_by_id xc xs vm (device_kind_of ~xs vbd) (id_of vbd))
4025+
with
4026+
| Xenopsd_error (Does_not_exist (_, _)) ->
4027+
debug "VM = %s; VBD = %s; Ignoring missing domain" vm (id_of vbd) ;
4028+
None
4029+
| Xenopsd_error Device_not_connected ->
4030+
debug "VM = %s; VBD = %s; Ignoring missing device" vm (id_of vbd) ;
4031+
None
4032+
in
4033+
let backend =
4034+
match dev with
4035+
| None ->
4036+
None
4037+
| Some dv -> (
4038+
match
4039+
Rpcmarshal.unmarshal typ_of_backend
4040+
(Device.Generic.get_private_key ~xs dv _vdi_id
4041+
|> Jsonrpc.of_string
4042+
)
4043+
with
4044+
| Ok x ->
4045+
x
4046+
| Error (`Msg m) ->
4047+
internal_error "Failed to unmarshal VBD backend: %s" m
4048+
)
4049+
in
4050+
with_tracing ~task ~name:"VBD_detach_dp_destroy" @@ fun () ->
4051+
match (domid, backend) with
4052+
| Some x, None | Some x, Some (VDI _) ->
4053+
Storage.dp_destroy task (Storage.id_of (string_of_int x) vbd.Vbd.id)
4054+
| _ ->
4055+
()
4056+
) ;
4057+
cleanup_attached_vdis vm vbd.id
4058+
40144059
let insert task vm vbd d =
40154060
on_frontend
40164061
(fun xc xs frontend_domid domain_type ->

0 commit comments

Comments
 (0)