Skip to content

Commit faea8ea

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

File tree

5 files changed

+96
-20
lines changed

5 files changed

+96
-20
lines changed

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 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) ->
@@ -2062,7 +2076,18 @@ let rec perform_atomic ~progress_callback ?result (op : atomic)
20622076
| VBD_unplug (id, force) ->
20632077
debug "VBD.unplug %s" (VBD_DB.string_of_id id) ;
20642078
finally
2065-
(fun () -> B.VBD.unplug t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force)
2079+
(fun () ->
2080+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force ;
2081+
B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id)
2082+
)
2083+
(fun () -> VBD_DB.signal id)
2084+
| VBD_deactivate (id, force) ->
2085+
debug "VBD.deactivate %s" (VBD_DB.string_of_id id) ;
2086+
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force
2087+
| VBD_detach id ->
2088+
debug "VBD.detach %s" (VBD_DB.string_of_id id) ;
2089+
finally
2090+
(fun () -> B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id))
20662091
(fun () -> VBD_DB.signal id)
20672092
| VBD_insert (id, disk) -> (
20682093
(* NB this is also used to "refresh" ie signal a qemu that it should
@@ -2478,6 +2503,8 @@ and trigger_cleanup_after_failure_atom op t =
24782503
| VBD_epoch_end (id, _)
24792504
| VBD_set_qos id
24802505
| VBD_unplug (id, _)
2506+
| VBD_deactivate (id, _)
2507+
| VBD_detach id
24812508
| VBD_insert (id, _) ->
24822509
immediate_operation dbg (fst id) (VBD_check_state id)
24832510
| 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

+57-14
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)