Skip to content

Commit 7501f70

Browse files
authored
CA-413304: Restore VBD.unplug function to keep old functionality (xapi-project#6571)
This is a partial revert of 1a46f33. It retains the deactivate and detach functions introduced but restores the original unplug function so that the VBD_unplug atom is completely unchanged when xenops_vbd_plug_unplug_legacy=true instead of running deactivate followed by detach. This will fix the S(Does_not_exist) Xenopsd errors we are seeing in some VBD_unplug calls, until a fix for the split functions is found (I have created CA-413304 to track that issue)
2 parents c941af3 + 30c0ba1 commit 7501f70

5 files changed

Lines changed: 128 additions & 4 deletions

File tree

ocaml/xenopsd/lib/xenops_server.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,10 +2097,7 @@ let rec perform_atomic ~progress_callback ?result (op : atomic)
20972097
| VBD_unplug (id, force) ->
20982098
debug "VBD.unplug %s" (VBD_DB.string_of_id id) ;
20992099
finally
2100-
(fun () ->
2101-
B.VBD.deactivate t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force ;
2102-
B.VBD.detach t (VBD_DB.vm_of id) (VBD_DB.read_exn id)
2103-
)
2100+
(fun () -> B.VBD.unplug t (VBD_DB.vm_of id) (VBD_DB.read_exn id) force)
21042101
(fun () -> VBD_DB.signal id)
21052102
| VBD_deactivate (id, force) ->
21062103
debug "VBD.deactivate %s" (VBD_DB.string_of_id id) ;

ocaml/xenopsd/lib/xenops_server_plugin.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ 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
215+
214216
val deactivate : Xenops_task.task_handle -> Vm.id -> Vbd.t -> bool -> unit
215217

216218
val detach : Xenops_task.task_handle -> Vm.id -> Vbd.t -> unit

ocaml/xenopsd/lib/xenops_server_simulator.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ 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)
681+
680682
let deactivate _ vm vbd _ = with_lock m (remove_vbd vm vbd)
681683

682684
let detach _ _vm _vbd = ()

ocaml/xenopsd/lib/xenops_server_skeleton.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ module VBD = struct
148148

149149
let activate _ _ _ = unimplemented __FUNCTION__
150150

151+
let unplug _ _ _ _ = unimplemented __FUNCTION__
152+
151153
let deactivate _ _ _ _ = unimplemented __FUNCTION__
152154

153155
let detach _ _ _ = unimplemented __FUNCTION__

ocaml/xenopsd/xc/xenops_server_xen.ml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3863,6 +3863,127 @@ module VBD = struct
38633863
)
38643864
(fun () -> cleanup_attached_vdis vm (id_of vbd))
38653865

3866+
let unplug task vm vbd force =
3867+
with_xc_and_xs (fun xc xs ->
3868+
try
3869+
(* On destroying the datapath
3870+
3871+
1. if the device has already been shutdown and deactivated (as in
3872+
suspend) we must call DP.destroy here to avoid leaks
3873+
3874+
2. if the device is successfully shutdown here then we must call
3875+
DP.destroy because no-one else will
3876+
3877+
3. if the device shutdown is rejected then we should leave the DP
3878+
alone and rely on the event thread calling us again later. *)
3879+
let domid = domid_of_uuid ~xs (uuid_of_string vm) in
3880+
(* If the device is gone then we don't need to shut it down but we do
3881+
need to free any storage resources. *)
3882+
let dev =
3883+
try
3884+
Some (device_by_id xc xs vm (device_kind_of ~xs vbd) (id_of vbd))
3885+
with
3886+
| Xenopsd_error (Does_not_exist (_, _)) ->
3887+
debug "VM = %s; VBD = %s; Ignoring missing domain" vm (id_of vbd) ;
3888+
None
3889+
| Xenopsd_error Device_not_connected ->
3890+
debug "VM = %s; VBD = %s; Ignoring missing device" vm (id_of vbd) ;
3891+
None
3892+
in
3893+
let backend =
3894+
match dev with
3895+
| None ->
3896+
None
3897+
| Some dv -> (
3898+
match
3899+
Rpcmarshal.unmarshal typ_of_backend
3900+
(Device.Generic.get_private_key ~xs dv _vdi_id
3901+
|> Jsonrpc.of_string
3902+
)
3903+
with
3904+
| Ok x ->
3905+
x
3906+
| Error (`Msg m) ->
3907+
internal_error "Failed to unmarshal VBD backend: %s" m
3908+
)
3909+
in
3910+
Option.iter
3911+
(fun dev ->
3912+
if force && not (Device.can_surprise_remove ~xs dev) then
3913+
debug
3914+
"VM = %s; VBD = %s; Device is not surprise-removable \
3915+
(ignoring and removing anyway)"
3916+
vm (id_of vbd) ;
3917+
(* this happens on normal shutdown too *)
3918+
(* Case (1): success; Case (2): success; Case (3): an exception is
3919+
thrown *)
3920+
with_tracing ~task ~name:"VBD_device_shutdown" @@ fun () ->
3921+
Xenops_task.with_subtask task
3922+
(Printf.sprintf "Vbd.clean_shutdown %s" (id_of vbd))
3923+
(fun () ->
3924+
(if force then Device.hard_shutdown else Device.clean_shutdown)
3925+
task ~xs dev
3926+
)
3927+
)
3928+
dev ;
3929+
(* We now have a shutdown device but an active DP: we should destroy
3930+
the DP if the backend is of type VDI *)
3931+
finally
3932+
(fun () ->
3933+
with_tracing ~task ~name:"VBD_device_release" (fun () ->
3934+
Option.iter
3935+
(fun dev ->
3936+
Xenops_task.with_subtask task
3937+
(Printf.sprintf "Vbd.release %s" (id_of vbd))
3938+
(fun () -> Device.Vbd.release task ~xc ~xs dev)
3939+
)
3940+
dev
3941+
) ;
3942+
(* If we have a qemu frontend, detach this too. *)
3943+
with_tracing ~task ~name:"VBD_detach_qemu" @@ fun () ->
3944+
let _ =
3945+
DB.update vm
3946+
(Option.map (fun vm_t ->
3947+
let persistent = vm_t.VmExtra.persistent in
3948+
if List.mem_assoc vbd.Vbd.id persistent.VmExtra.qemu_vbds
3949+
then (
3950+
let _, qemu_vbd =
3951+
List.assoc vbd.Vbd.id persistent.VmExtra.qemu_vbds
3952+
in
3953+
(* destroy_vbd_frontend ignores 'refusing to close'
3954+
transients' *)
3955+
destroy_vbd_frontend ~xc ~xs task qemu_vbd ;
3956+
VmExtra.
3957+
{
3958+
persistent=
3959+
{
3960+
persistent with
3961+
qemu_vbds=
3962+
List.remove_assoc vbd.Vbd.id
3963+
persistent.qemu_vbds
3964+
}
3965+
}
3966+
) else
3967+
vm_t
3968+
)
3969+
)
3970+
in
3971+
()
3972+
)
3973+
(fun () ->
3974+
with_tracing ~task ~name:"VBD_dp_destroy" @@ fun () ->
3975+
match (domid, backend) with
3976+
| Some x, None | Some x, Some (VDI _) ->
3977+
Storage.dp_destroy task
3978+
(Storage.id_of (string_of_int x) vbd.Vbd.id)
3979+
| _ ->
3980+
()
3981+
)
3982+
with Device_common.Device_error (_, s) ->
3983+
debug "Caught Device_error: %s" s ;
3984+
raise (Xenopsd_error (Device_detach_rejected ("VBD", id_of vbd, s)))
3985+
)
3986+
38663987
let deactivate task vm vbd force =
38673988
with_xc_and_xs (fun xc xs ->
38683989
try

0 commit comments

Comments
 (0)