diff --git a/idl/xenvm_interface.ml b/idl/xenvm_interface.ml index 2804509..03df446 100644 --- a/idl/xenvm_interface.ml +++ b/idl/xenvm_interface.ml @@ -16,6 +16,10 @@ external remove : name:string -> unit = "" external resize : name:string -> size:int64 -> unit = "" external set_status : name:string -> readonly:bool -> unit = "" +external flush : name:string -> unit = "" +(** [flush lv] processes all pending allocations for this LV, such that + future calls to [get_lv] will return accurate metadata. *) + external shutdown : unit -> unit = "" type queue = { diff --git a/xenvm/lvchange.ml b/xenvm/lvchange.ml index c4a37b6..f8284ae 100644 --- a/xenvm/lvchange.ml +++ b/xenvm/lvchange.ml @@ -42,6 +42,7 @@ let lvchange_activate copts vg_name lv_name physical_device = ) let deactivate vg lv = + let open Xenvm_common in let name = Mapper.name_of vg lv in let all = Devmapper.ls () in if List.mem name all @@ -49,7 +50,7 @@ let deactivate vg lv = (* Delete the device node *) let path = dev_path_of vg.Lvm.Vg.name lv.Lvm.Lv.name in Lwt.catch (fun () -> Lwt_unix.unlink path) (fun _ -> Lwt.return ()) >>= fun () -> - return () + Client.flush ~name:lv.Lvm.Lv.name let lvchange_deactivate copts vg_name lv_name = let open Xenvm_common in diff --git a/xenvmd/xenvmd.ml b/xenvmd/xenvmd.ml index 171b975..1e1329a 100644 --- a/xenvmd/xenvmd.ml +++ b/xenvmd/xenvmd.ml @@ -279,7 +279,10 @@ module VolumeManager = struct free_LVs := (name, (freeLVM,freeLVMid)) :: !free_LVs; return () - let flush name = + (* Hold this mutex when actively flushing from the ToLVM queues *) + let flush_m = Lwt_mutex.create () + + let flush_already_locked name = if not(List.mem_assoc name !to_LVMs) then return () else begin @@ -309,7 +312,7 @@ module VolumeManager = struct ToLVM.suspend to_lvm >>= fun () -> (* There may still be updates in the ToLVM queue *) - flush name + Lwt_mutex.with_lock flush_m (fun () -> flush_already_locked name) >>= fun () -> debug "ToLVM queue for %s has been suspended and flushed" name; to_LVMs := List.filter (fun (n, _) -> n <> name) !to_LVMs; @@ -358,6 +361,15 @@ module VolumeManager = struct ) !to_LVMs end + let flush_all () = + Lwt_mutex.with_lock Host.flush_m + (fun () -> + Lwt_list.iter_s + (fun (host, _) -> + Host.flush_already_locked host + ) !to_LVMs + ) + let shutdown () = Lwt_list.iter_s (fun (host, _) -> @@ -566,6 +578,10 @@ module Impl = struct return (`Ok ({ vg with Vg.lvs = Vg.LVs.empty }, lv)) )) + let flush context ~name = + (* We don't know where [name] is attached so we have to flush everything *) + VolumeManager.flush_all () + let shutdown context () = VolumeManager.shutdown () >>= fun () -> @@ -616,10 +632,7 @@ let run port config daemon = >>= fun () -> (* 2. Are there any pending LVM updates from hosts? *) - Lwt_list.iter_s - (fun (host, _) -> - VolumeManager.Host.flush host - ) !VolumeManager.to_LVMs + VolumeManager.flush_all () >>= fun () -> debug "sleeping for 5s";