diff --git a/idl/xenvm_interface.ml b/idl/xenvm_interface.ml index b54700a..cdd9596 100644 --- a/idl/xenvm_interface.ml +++ b/idl/xenvm_interface.ml @@ -10,7 +10,7 @@ external get_lv: name:string -> (Vg_wrapper.t * Lv_wrapper.t) = "" and metadata for the LV in question. *) external get : unit -> Vg_wrapper.t = "" -external create : name:string -> size:int64 -> tags:string list -> unit = "" +external create : name:string -> size:int64 -> creation_host:string -> creation_time:int64 -> tags:string list -> unit = "" external rename : oldname:string -> newname:string -> unit = "" external remove : name:string -> unit = "" external resize : name:string -> size:int64 -> unit = "" diff --git a/setup.sh b/setup.sh index b310e04..6126e1b 100755 --- a/setup.sh +++ b/setup.sh @@ -38,6 +38,9 @@ mkdir -p /tmp/xenvm.d ./xenvm.native lvcreate -n live -L 4 djstest --configdir /tmp/xenvm.d $MOCK_ARG ./xenvm.native lvchange -ay /dev/djstest/live --configdir /tmp/xenvm.d $MOCK_ARG +./xenvm.native lvdisplay /dev/djstest --configdir /tmp/xenvm.d $MOCK_ARG +./xenvm.native lvdisplay /dev/djstest -c --configdir /tmp/xenvm.d $MOCK_ARG + #./xenvm.native benchmark # create and connect to hosts ./xenvm.native host-create /dev/djstest host1 --configdir /tmp/xenvm.d $MOCK_ARG diff --git a/xenvm/lvcreate.ml b/xenvm/lvcreate.ml index 480870b..9385bbb 100644 --- a/xenvm/lvcreate.ml +++ b/xenvm/lvcreate.ml @@ -23,7 +23,9 @@ let lvcreate copts lv_name real_size percent_size tags vg_name = bytes | _ -> failwith "Initial size must be absolute" in if vg.Lvm.Vg.name <> vg_name then failwith "Invalid VG name"; - Client.create lv_name size tags >>= fun () -> + let creation_host = Unix.gethostname () in + let creation_time = Unix.gettimeofday () |> Int64.of_float in + Client.create lv_name size creation_host creation_time tags >>= fun () -> return info) in match info with | Some i -> Lvchange.lvchange_activate copts vg_name lv_name (Some i.local_device) | None -> () diff --git a/xenvm/lvdisplay.ml b/xenvm/lvdisplay.ml index 8b2abfd..49239bc 100644 --- a/xenvm/lvdisplay.ml +++ b/xenvm/lvdisplay.ml @@ -13,6 +13,22 @@ let print_verbose vg lv = then [ "write" ] else []) in String.concat "/" all in let size = Int64.mul vg.Lvm.Vg.extent_size (Lvm.Lv.size_in_extents lv) in + let creation_time = + let open Unix in + let tm = gmtime (Int64.to_float lv.Lvm.Lv.creation_time) in + Printf.sprintf "%d-%02d-%02d %02d:%02d:%02d +0000" + (tm.tm_year + 1900) (tm.tm_mon + 1) tm.tm_mday + tm.tm_hour tm.tm_min tm.tm_sec in + + let device = + let module Devmapper = (val !dm: Devmapper.S.DEVMAPPER) in + let name = Mapper.name_of vg lv in + match Devmapper.stat name with + | Some info -> + Some (Printf.sprintf "%ld:%ld" info.Devmapper.major info.Devmapper.minor) + | None -> + None in + let lines = [ "--- Logical volume ---"; Printf.sprintf "LV Path /dev/%s/%s" vg.Lvm.Vg.name lv.Lvm.Lv.name; @@ -20,24 +36,37 @@ let print_verbose vg lv = Printf.sprintf "VG Name %s" vg.Lvm.Vg.name; Printf.sprintf "LV UUID %s" (Lvm.Uuid.to_string lv.Lvm.Lv.id); Printf.sprintf "LV Write Access %s" read_write; - Printf.sprintf "LV Creation host, time unknown, unknown"; + Printf.sprintf "LV Creation host, time %s, %s" lv.Lvm.Lv.creation_host creation_time; Printf.sprintf "LV Status %s" (if List.mem Lvm.Lv.Status.Visible lv.Lvm.Lv.status then "available" else ""); Printf.sprintf "# open uknown"; Printf.sprintf "LV Size %Lds" size; Printf.sprintf "Current LE %Ld" (Lvm.Lv.size_in_extents lv); Printf.sprintf "Segments %d" (List.length lv.Lvm.Lv.segments); - Printf.sprintf "Allocation: inherit"; - Printf.sprintf "Read ahead sectors: auto"; + Printf.sprintf "Allocation inherit"; + Printf.sprintf "Read ahead sectors auto"; (* - currently set to 256 - Block device 253:0 *) + ] @ (match device with + | Some device -> [ Printf.sprintf "Block device %s" device ] + | None -> []) @ [ ""; ] in Lwt_list.iter_s (fun line -> stdout " %s" line) lines +(* Example output: + /dev/packer-virtualbox-iso-vg/root:packer-virtualbox-iso-vg:3:1:-1:1:132661248:16194:-1:0:-1:252:0 +*) let print_colon vg lv = let sectors = Int64.mul vg.Lvm.Vg.extent_size (Lvm.Lv.size_in_extents lv) in + let major, minor = + let module Devmapper = (val !dm: Devmapper.S.DEVMAPPER) in + let name = Mapper.name_of vg lv in + match Devmapper.stat name with + | Some info -> + Int32.to_string info.Devmapper.major, Int32.to_string info.Devmapper.minor + | None -> + "-1", "-1" in let parts = [ Printf.sprintf "/dev/%s/%s" vg.Lvm.Vg.name lv.Lvm.Lv.name; vg.Lvm.Vg.name; @@ -50,8 +79,8 @@ let print_colon vg lv = "?"; (* allocated extents *) "?"; (* allocation policy *) "?"; (* read ahead sectors *) - "?"; (* major *) - "?"; (* minor *) + major; + minor; ] in stdout " %s" (String.concat ":" parts) diff --git a/xenvm/vgcreate.ml b/xenvm/vgcreate.ml index b5643f4..a6eca49 100644 --- a/xenvm/vgcreate.ml +++ b/xenvm/vgcreate.ml @@ -24,7 +24,9 @@ let vgcreate _ vg_name devices = | `Error (`Msg x) -> failwith x in (name,block) ) blocks in - Vg_IO.format vg_name ~magic:`Journalled pvs >>|= fun () -> + let creation_host = Unix.gethostname () in + let creation_time = Unix.gettimeofday () |> Int64.of_float in + Vg_IO.format vg_name ~creation_host ~creation_time ~magic:`Journalled pvs >>|= fun () -> Vg_IO.connect (List.map snd pvs) `RW >>|= fun vg -> (return (Vg.create (Vg_IO.metadata_of vg) _journal_name size)) diff --git a/xenvm/xenvm.ml b/xenvm/xenvm.ml index db21edc..2c38a93 100644 --- a/xenvm/xenvm.ml +++ b/xenvm/xenvm.ml @@ -67,22 +67,18 @@ let format config name filenames = | `Error (`Msg x) -> failwith x in (name,block) ) blocks in - Vg_IO.format name ~magic:`Journalled pvs >>|= fun () -> + let creation_host = Unix.gethostname () in + let creation_time = Unix.gettimeofday () |> Int64.of_float in + Vg_IO.format name ~creation_host ~creation_time ~magic:`Journalled pvs >>|= fun () -> Vg_IO.connect (List.map snd pvs) `RW >>|= fun vg -> - (return (Vg.create (Vg_IO.metadata_of vg) _journal_name size)) + (return (Vg.create (Vg_IO.metadata_of vg) _journal_name size ~creation_host ~creation_time)) >>|= fun (_, op) -> Vg_IO.update vg [ op ] >>|= fun () -> return () in Lwt_main.run t -let create config name size = - set_uri config None; - Lwt_main.run - (let size_in_bytes = Int64.mul 1048576L size in - Client.create ~name ~size:size_in_bytes ~tags:[]) - let host_create copts (vg_name,_) host = let t = get_vg_info_t copts vg_name >>= fun info -> @@ -153,6 +149,7 @@ let shutdown copts (vg_name,_) = let benchmark copts (vg_name,_) = let t = + let creation_host = Unix.gethostname () in get_vg_info_t copts vg_name >>= fun info -> set_uri copts info; let mib = Int64.mul 1048576L 4L in @@ -167,7 +164,7 @@ let benchmark copts (vg_name,_) = then stderr "%s %d %% complete\n%!" test_name (100 - (n * 100) / number) else return () ) >>= fun () -> fori test_name ((number - n, Unix.gettimeofday () -. start) :: acc) f (n - 1) in - fori "Creating volumes" [] (fun i -> Client.create ~name:(Printf.sprintf "test-lv-%d" i) ~size:mib ~tags:[]) number + fori "Creating volumes" [] (fun i -> Client.create ~name:(Printf.sprintf "test-lv-%d" i) ~size:mib ~creation_host ~creation_time:(Unix.gettimeofday () |> Int64.of_float) ~tags:[]) number >>= fun creates -> let time = Unix.gettimeofday () -. start in let oc = open_out "benchmark.dat" in @@ -232,15 +229,6 @@ let format_cmd = Term.(pure format $ copts_t $ vgname $ filenames), Term.info "format" ~sdocs:copts_sect ~doc ~man -let create_cmd = - let doc = "Create a logical volume" in - let man = [ - `S "DESCRIPTION"; - `P "Creates a logical volume"; - ] in - Term.(pure create $ copts_t $ lvname $ size), - Term.info "create" ~sdocs:copts_sect ~doc ~man - let host_connect_cmd = let doc = "Connect to a host" in let man = [ @@ -310,7 +298,7 @@ let default_cmd = let cmds = [ Lvresize.lvresize_cmd; Lvresize.lvextend_cmd; - format_cmd; create_cmd; + format_cmd; shutdown_cmd; host_create_cmd; host_destroy_cmd; host_list_cmd; host_connect_cmd; host_disconnect_cmd; benchmark_cmd; diff --git a/xenvmd/xenvmd.ml b/xenvmd/xenvmd.ml index f2393f3..0a085aa 100644 --- a/xenvmd/xenvmd.ml +++ b/xenvmd/xenvmd.ml @@ -196,11 +196,13 @@ module VolumeManager = struct | None -> begin debug "No freeLVM volume"; let size = Int64.(mul 4L (mul 1024L 1024L)) in + let creation_host = Unix.gethostname () in + let creation_time = Unix.gettimeofday () |> Int64.of_float in write (fun vg -> - Lvm.Vg.create vg toLVM size + Lvm.Vg.create vg toLVM size ~creation_host ~creation_time ) >>= fun () -> write (fun vg -> - Lvm.Vg.create vg fromLVM size + Lvm.Vg.create vg fromLVM size ~creation_host ~creation_time ) >>= fun () -> (* The local allocator needs to see the volumes now *) sync () >>= fun () -> @@ -240,7 +242,7 @@ module VolumeManager = struct (* Create the freeLVM LV at the end - we can use the existence of this as a flag to show that we've finished host creation *) write (fun vg -> - Lvm.Vg.create vg freeLVM size + Lvm.Vg.create vg freeLVM size ~creation_host ~creation_time ) >>= fun () -> sync () end @@ -573,9 +575,9 @@ module Impl = struct let get context () = fatal_error "get" (VolumeManager.read (fun x -> return (`Ok x))) - let create context ~name ~size ~tags = + let create context ~name ~size ~creation_host ~creation_time ~tags = VolumeManager.write (fun vg -> - Lvm.Vg.create vg name ~tags size + Lvm.Vg.create vg name ~creation_host ~creation_time ~tags size ) let rename context ~oldname ~newname =