Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 30 additions & 22 deletions xenvm/lvchange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ type action = Activate | Deactivate
let dev_path_of vg_name lv_name =
Printf.sprintf "/dev/%s/%s" vg_name lv_name

let activate vg lv local_device =
let path = dev_path_of vg.Lvm.Vg.name lv.Lvm.Lv.name in
Lwt.catch (fun () -> Lwt_unix.mkdir (Filename.dirname path) 0x755) (fun _ -> Lwt.return ()) >>= fun () ->
Mapper.read [ local_device ]
>>= fun devices ->
let targets = Mapper.to_targets devices vg lv in
let name = Mapper.name_of vg lv in
(* Don't recreate it if it already exists *)
let all = Devmapper.ls () in
if not(List.mem name all)
then Devmapper.create name targets;
(* Recreate the device node *)
Lwt.catch (fun () -> Lwt_unix.unlink path) (fun _ -> Lwt.return ()) >>= fun () ->
Devmapper.mknod name path 0o0600;
return ()

let lvchange_activate copts vg_name lv_name physical_device =
let open Xenvm_common in
Lwt_main.run (
Expand All @@ -22,35 +38,27 @@ let lvchange_activate copts vg_name lv_name physical_device =
| Some info, None -> info.local_device (* If we've got a default, use that *)
| None, None -> failwith "Need to know the local device!"
in
let path = dev_path_of vg_name lv_name in
Lwt.catch (fun () -> Lwt_unix.mkdir (Filename.dirname path) 0x755) (fun _ -> Lwt.return ()) >>= fun () ->
Mapper.read [ local_device ]
>>= fun devices ->
let targets = Mapper.to_targets devices vg lv in
let name = Mapper.name_of vg lv in
(* Don't recreate it if it already exists *)
let all = Devmapper.ls () in
if not(List.mem name all)
then Devmapper.create name targets;
(* Recreate the device node *)
Lwt.catch (fun () -> Lwt_unix.unlink path) (fun _ -> Lwt.return ()) >>= fun () ->
Devmapper.mknod name path 0o0600;
return ())
activate vg lv local_device
)

let deactivate vg lv =
let name = Mapper.name_of vg lv in
let all = Devmapper.ls () in
if List.mem name all
then Devmapper.remove name;
(* 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 ()

let lvchange_deactivate copts vg_name lv_name =
let open Xenvm_common in
Lwt_main.run (
get_vg_info_t copts vg_name >>= fun info ->
set_uri copts info;
Client.get_lv ~name:lv_name >>= fun (vg, lv) ->
let name = Mapper.name_of vg lv in
let all = Devmapper.ls () in
if List.mem name all
then Devmapper.remove name;
(* Delete the device node *)
let path = dev_path_of vg_name lv_name in
Lwt.catch (fun () -> Lwt_unix.unlink path) (fun _ -> Lwt.return ()) >>= fun () ->
return ())
deactivate vg lv
)

let lvchange copts (vg_name,lv_name_opt) physical_device action perm =
let lv_name = match lv_name_opt with Some l -> l | None -> failwith "Need LV name" in
Expand Down
46 changes: 33 additions & 13 deletions xenvm/lvresize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,41 @@
open Cmdliner
open Lwt

let lvresize copts (vg_name,lv_opt) real_size percent_size =
let lvresize copts live (vg_name,lv_opt) real_size percent_size =
let lv_name = match lv_opt with | Some l -> l | None -> failwith "Need an LV name" in
let open Xenvm_common in
let size = match parse_size real_size percent_size with
| `IncreaseBy x -> `IncreaseBy x
| `Absolute x -> `Absolute x
| `DecreaseBy _ -> failwith "Shrinking volumes not supported" in

Lwt_main.run (
get_vg_info_t copts vg_name >>= fun info ->
set_uri copts info;
Client.get_lv ~name:lv_name >>= fun (vg, lv) ->
if vg.Lvm.Vg.name <> vg_name then failwith "Invalid VG name";
let local_device = match info with
| Some info -> info.local_device (* If we've got a default, use that *)
| None -> failwith "Need to know the local device!" in

let resize_remotely () = match size with
| `Absolute size -> Client.resize lv_name size
| `IncreaseBy delta -> Client.resize lv_name Int64.(add delta (mul (mul 512L vg.Lvm.Vg.extent_size) (Lvm.Lv.size_in_extents lv))) in
let device_is_active =
let name = Mapper.name_of vg lv in
let all = Devmapper.ls () in
List.mem name all in

let resize_remotely () =
( if device_is_active
then Lvchange.deactivate vg lv
else return () )
>>= fun () ->
( match size with
| `Absolute size -> Client.resize lv_name size
| `IncreaseBy delta -> Client.resize lv_name Int64.(add delta (mul (mul 512L vg.Lvm.Vg.extent_size) (Lvm.Lv.size_in_extents lv))) )
>>= fun () ->
( if device_is_active then begin
Client.get_lv ~name:lv_name >>= fun (vg, lv) ->
Lvchange.activate vg lv local_device
end else return () ) in

let resize_locally allocator =
let name = Mapper.name_of vg lv in
Expand All @@ -31,26 +50,27 @@ let lvresize copts (vg_name,lv_opt) real_size percent_size =
>>= fun () ->
Lwt_io.close oc in

match info with
| Some { Xenvm_common.local_allocator_path = Some allocator } ->
let name = Mapper.name_of vg lv in
let all = Devmapper.ls () in
(* An active device with local allocator running must be resized locally *)
if List.mem name all
match live, info with
| true, Some { Xenvm_common.local_allocator_path = Some allocator } ->
if device_is_active
then resize_locally allocator
else resize_remotely ()
| _ ->
| _, _ ->
(* safe to allocate remotely *)
resize_remotely ()
)

let live_arg =
let doc = "Resize a live device using the local allocator" in
Arg.(value & flag & info ["live"] ~doc)

let lvresize_cmd =
let doc = "Resize a logical volume" in
let man = [
`S "DESCRIPTION";
`P "lvresize will resize an existing logical volume.";
] in
Term.(pure lvresize $ Xenvm_common.copts_t $ Xenvm_common.name_arg $ Xenvm_common.real_size_arg $ Xenvm_common.percent_size_arg),
Term.(pure lvresize $ Xenvm_common.copts_t $ live_arg $ Xenvm_common.name_arg $ Xenvm_common.real_size_arg $ Xenvm_common.percent_size_arg),
Term.info "lvresize" ~sdocs:"COMMON OPTIONS" ~doc ~man

let lvextend_cmd =
Expand All @@ -59,5 +79,5 @@ let lvextend_cmd =
`S "DESCRIPTION";
`P "lvextend will resize an existing logical volume.";
] in
Term.(pure lvresize $ Xenvm_common.copts_t $ Xenvm_common.name_arg $ Xenvm_common.real_size_arg $ Xenvm_common.percent_size_arg),
Term.(pure lvresize $ Xenvm_common.copts_t $ live_arg $ Xenvm_common.name_arg $ Xenvm_common.real_size_arg $ Xenvm_common.percent_size_arg),
Term.info "lvextend" ~sdocs:"COMMON OPTIONS" ~doc ~man