Skip to content

Commit 71f220e

Browse files
committed
CP-53555: Split unplug atomic into deactivate/detach
This consists of two parts, splitting the unplug function into functionally equivalent deactivate and detach functions, and splitting the VBD_unplug atomic itself's behaviour into two new atomics: VBD_deactivate and VBD_detach If the xenopsd_vbd_plug_unplug_legacy flag is true, the only difference will be that VBD_unplug calls deactivate and detach sequentially instead of unplug If xenopsd_vbd_plug_unplug_legacy is false, the VBD_deactivate and VBD_detach atomics will be used in place of VBD_unplug in all places that it is used. This should still be functionally equivalent. The purpose of this change is to allow optimisations in this area as there are some situations where they do not need to be called at the same time. For example we could skip detaching on reboot and only deactivate and activate again reducing reboot time. Signed-off-by: Steven Woods <[email protected]>
1 parent ef0eddd commit 71f220e

File tree

5 files changed

+96
-20
lines changed

5 files changed

+96
-20
lines changed

ocaml/xenopsd/lib/xenops_server.ml

Lines changed: 30 additions & 3 deletions
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 vbd_plug vbd_id =
16001606
serial_of "VBD.attach_and_activate" ~id:(VBD_DB.vm_of vbd_id)
16011607
(VBD_attach vbd_id) (VBD_activate vbd_id) []
16021608

1609+
let vbd_unplug 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:(VBD_DB.vm_of vbd_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 -> vbd_unplug 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
]
@@ -1847,7 +1861,7 @@ let rec atomics_of_operation = function
18471861
| VBD_hotplug id ->
18481862
[VBD_set_active (id, true); vbd_plug id]
18491863
| VBD_hotunplug (id, force) ->
1850-
[VBD_unplug (id, force); VBD_set_active (id, false)]
1864+
[vbd_unplug id force; VBD_set_active (id, false)]
18511865
| VIF_hotplug id ->
18521866
[VIF_set_active (id, true); VIF_plug id]
18531867
| VIF_hotunplug (id, force) ->
@@ -2064,7 +2078,18 @@ let rec perform_atomic ~progress_callback ?result (op : atomic)
20642078
| VBD_unplug (id, force) ->
20652079
debug "VBD.unplug %s" (VBD_DB.string_of_id id) ;
20662080
finally
2067-
(fun () -> B.VBD.unplug t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force)
2081+
(fun () ->
2082+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force ;
2083+
B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id)
2084+
)
2085+
(fun () -> VBD_DB.signal id)
2086+
| VBD_deactivate (id, force) ->
2087+
debug "VBD.deactivate %s" (VBD_DB.string_of_id id) ;
2088+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force
2089+
| VBD_detach id ->
2090+
debug "VBD.detach %s" (VBD_DB.string_of_id id) ;
2091+
finally
2092+
(fun () -> B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id))
20682093
(fun () -> VBD_DB.signal id)
20692094
| VBD_insert (id, disk) -> (
20702095
(* NB this is also used to "refresh" ie signal a qemu that it should
@@ -2480,6 +2505,8 @@ and trigger_cleanup_after_failure_atom op t =
24802505
| VBD_epoch_end (id, _)
24812506
| VBD_set_qos id
24822507
| VBD_unplug (id, _)
2508+
| VBD_deactivate (id, _)
2509+
| VBD_detach id
24832510
| VBD_insert (id, _) ->
24842511
immediate_operation dbg (fst id) (VBD_check_state id)
24852512
| VIF_plug id

ocaml/xenopsd/lib/xenops_server_plugin.ml

Lines changed: 3 additions & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,22 +3888,22 @@ module VBD = struct
38883888
)
38893889
(fun () -> cleanup_attached_vdis vm vbd.id)
38903890

3891-
let unplug task vm vbd force =
3891+
let deactivate task vm vbd force =
38923892
with_xc_and_xs (fun xc xs ->
38933893
try
38943894
(* On destroying the datapath
38953895
3896-
1. if the device has already been shutdown and deactivated (as in
3897-
suspend) we must call DP.destroy here to avoid leaks
3896+
1. if the device has already been shutdown and deactivated (as in
3897+
suspend) we must call DP.destroy here to avoid leaks
38983898
3899-
2. if the device is successfully shutdown here then we must call
3900-
DP.destroy because no-one else will
3899+
2. if the device is successfully shutdown here then we must call
3900+
DP.destroy because no-one else will
39013901
3902-
3. if the device shutdown is rejected then we should leave the DP
3903-
alone and rely on the event thread calling us again later. *)
3902+
3. if the device shutdown is rejected then we should leave the DP
3903+
alone and rely on the event thread calling us again later. *)
39043904
let domid = domid_of_uuid ~xs (uuid_of_string vm) in
39053905
(* If the device is gone then we don't need to shut it down but we do
3906-
need to free any storage resources. *)
3906+
need to free any storage resources. *)
39073907
let dev =
39083908
try
39093909
Some (device_by_id xc xs vm (device_kind_of ~xs vbd) (id_of vbd))
@@ -3941,7 +3941,7 @@ module VBD = struct
39413941
vm (id_of vbd) ;
39423942
(* this happens on normal shutdown too *)
39433943
(* Case (1): success; Case (2): success; Case (3): an exception is
3944-
thrown *)
3944+
thrown *)
39453945
with_tracing ~task ~name:"VBD_device_shutdown" @@ fun () ->
39463946
Xenops_task.with_subtask task
39473947
(Printf.sprintf "Vbd.clean_shutdown %s" (id_of vbd))
@@ -3952,7 +3952,7 @@ module VBD = struct
39523952
)
39533953
dev ;
39543954
(* We now have a shutdown device but an active DP: we should destroy
3955-
the DP if the backend is of type VDI *)
3955+
the DP if the backend is of type VDI *)
39563956
finally
39573957
(fun () ->
39583958
with_tracing ~task ~name:"VBD_device_release" (fun () ->
@@ -3996,11 +3996,14 @@ module VBD = struct
39963996
()
39973997
)
39983998
(fun () ->
3999-
with_tracing ~task ~name:"VBD_dp_destroy" @@ fun () ->
3999+
with_tracing ~task ~name:"VBD_deactivate" @@ fun () ->
4000+
let vmid = Storage.vm_of_domid domid in
40004001
match (domid, backend) with
4001-
| Some x, None | Some x, Some (VDI _) ->
4002-
Storage.dp_destroy task
4003-
(Storage.id_of (string_of_int x) vbd.Vbd.id)
4002+
| Some x, Some (VDI path) ->
4003+
let sr, vdi = Storage.get_disk_by_name task path in
4004+
let dp = Storage.id_of (string_of_int x) vbd.id in
4005+
Storage.deactivate task dp sr vdi vmid
4006+
(* We don't need to detach Local or CDROM *)
40044007
| _ ->
40054008
()
40064009
)
@@ -4009,6 +4012,46 @@ module VBD = struct
40094012
raise (Xenopsd_error (Device_detach_rejected ("VBD", id_of vbd, s)))
40104013
)
40114014

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

0 commit comments

Comments
 (0)