@@ -3889,23 +3889,23 @@ module VBD = struct
3889
3889
)
3890
3890
(fun () -> cleanup_attached_vdis vm vbd.id)
3891
3891
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 () ->
3894
3894
with_xc_and_xs (fun xc xs ->
3895
3895
try
3896
3896
(* On destroying the datapath
3897
3897
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
3900
3900
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
3903
3903
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. *)
3906
3906
let domid = domid_of_uuid ~xs (uuid_of_string vm) in
3907
3907
(* 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. *)
3909
3909
let dev =
3910
3910
try
3911
3911
Some (device_by_id xc xs vm (device_kind_of ~xs vbd) (id_of vbd))
@@ -3943,8 +3943,9 @@ module VBD = struct
3943
3943
vm (id_of vbd) ;
3944
3944
(* this happens on normal shutdown too *)
3945
3945
(* 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 () ->
3948
3949
Xenops_task. with_subtask task
3949
3950
(Printf. sprintf " Vbd.clean_shutdown %s" (id_of vbd))
3950
3951
(fun () ->
@@ -3954,10 +3955,10 @@ module VBD = struct
3954
3955
)
3955
3956
dev ;
3956
3957
(* 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 *)
3958
3959
finally
3959
3960
(fun () ->
3960
- ( with_tracing ~task ~name: " VBD_device_release " @@ fun () ->
3961
+ ( with_tracing ~task ~name: " VBD_deactivate_release " @@ fun () ->
3961
3962
Option. iter
3962
3963
(fun dev ->
3963
3964
Xenops_task. with_subtask task
@@ -3967,7 +3968,7 @@ module VBD = struct
3967
3968
dev
3968
3969
) ;
3969
3970
(* 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 () ->
3971
3972
let _ =
3972
3973
DB. update vm
3973
3974
(Option. map (fun vm_t ->
@@ -3998,11 +3999,14 @@ module VBD = struct
3998
3999
()
3999
4000
)
4000
4001
(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
4002
4004
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? *)
4006
4010
| _ ->
4007
4011
()
4008
4012
)
@@ -4011,6 +4015,47 @@ module VBD = struct
4011
4015
raise (Xenopsd_error (Device_detach_rejected (" VBD" , id_of vbd, s)))
4012
4016
)
4013
4017
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
+
4014
4059
let insert task vm vbd d =
4015
4060
on_frontend
4016
4061
(fun xc xs frontend_domid domain_type ->
0 commit comments