X-Git-Url: http://git.annexia.org/?p=virt-top.git;a=blobdiff_plain;f=virt-df%2Fvirt_df.ml;h=4fbc706ec853af1fac81cf4ebceb57cef953c55b;hp=bbaaa7dff8530694f7971c39315b97470e856c70;hb=e6cca10e5cf86b9bd280e371fb1195835a96bff0;hpb=9bb5f67c0d8a6e8dad7de72e2488ee73c90f7d43 diff --git a/virt-df/virt_df.ml b/virt-df/virt_df.ml index bbaaa7d..4fbc706 100644 --- a/virt-df/virt_df.ml +++ b/virt-df/virt_df.ml @@ -1,5 +1,5 @@ (* 'df' command for virtual domains. - (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc. + (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc. http://libvirt.org/ This program is free software; you can redistribute it and/or modify @@ -19,9 +19,10 @@ open Printf open ExtList - open Unix +open Virt_df_gettext.Gettext + module C = Libvirt.Connect module D = Libvirt.Domain module N = Libvirt.Network @@ -37,6 +38,7 @@ let (/^) = Int64.div let uri = ref None let inodes = ref false let human = ref false +let all = ref false (* Maximum number of extended partitions possible. *) let max_extended_partitions = 100 @@ -104,7 +106,7 @@ let rec probe_device dom_name target source = let size = (LargeFile.fstat fd).LargeFile.st_size in let size = size /^ sector_size in (* Size in sectors. *) - print_device dom_name target source size; + (*print_device dom_name target source size;*) let partitions = probe_mbr fd in @@ -124,9 +126,9 @@ let rec probe_device dom_name target source = None ) partitions in let stats = List.filter_map (fun x -> x) stats in - print_stats stats + print_stats dom_name stats ) else (* Not an MBR, assume it's a single partition. *) - print_stats [target, probe_partition target None fd 0L size]; + print_stats dom_name [target, probe_partition target None fd 0L size]; close fd @@ -144,7 +146,7 @@ and probe_mbr fd = lseek fd 446 SEEK_SET; let str = String.create 64 in if read fd str 0 64 <> 64 then - failwith "error reading partition table" + failwith (s_ "error reading partition table") else ( (* Extract partitions from the data. *) let primaries = List.map (get_partition str) [ 0; 16; 32; 48 ] in @@ -177,13 +179,13 @@ and probe_extended_partition max fd epart sect = LargeFile.lseek fd (ebr_offs +^ 446L) SEEK_SET; let str = String.create 32 in if read fd str 0 32 <> 32 then - failwith "error reading extended partition" + failwith (s_ "error reading extended partition") else ( (* Extract partitions from the data. *) let part1, part2 = match List.map (get_partition str) [ 0; 16 ] with | [p1;p2] -> p1,p2 - | _ -> failwith "probe_extended_partition: internal error" in + | _ -> failwith (s_ "probe_extended_partition: internal error") in (* First partition entry has offset to the start of this partition. *) let part1 = { part1 with part_lba_start = sect +^ part1.part_lba_start } in @@ -231,7 +233,7 @@ and get_partition str offs = and probe_partition target part_type fd start size = match part_type with | None -> - ProbeFailed "detection of unpartitioned devices not yet supported" + ProbeFailed (s_ "detection of unpartitioned devices not yet supported") | Some 0x05 -> ProbeIgnore (* Extended partition - ignore it. *) | Some part_type -> @@ -241,59 +243,61 @@ and probe_partition target part_type fd start size = with Not_found -> ProbeFailed - (sprintf "unsupported partition type %02x" part_type) + (sprintf (f_ "unsupported partition type %02x") part_type) -and print_stats statss = +and print_stats dom_name statss = List.iter ( - function - (* Swap partition. *) - | (target, Swap { swap_name = swap_name; - swap_block_size = block_size; - swap_blocks_total = blocks_total }) -> - if not !human then - printf "\t%s %Ld %s\n" - target (block_size *^ blocks_total /^ 1024L) swap_name - else - printf "\t%s %s %s\n" - target (printable_size (block_size *^ blocks_total)) swap_name - - (* Ordinary filesystem. *) - | (target, Filesystem stats) -> - printf "\t%s " target; - - if not !inodes then ( (* Block display. *) - (* 'df' doesn't count the restricted blocks. *) - let blocks_total = - stats.fs_blocks_total -^ stats.fs_blocks_reserved in - let blocks_avail = - stats.fs_blocks_avail -^ stats.fs_blocks_reserved in - let blocks_avail = - if blocks_avail < 0L then 0L else blocks_avail in - - if not !human then ( (* Display 1K blocks. *) - printf "%Ld %Ld %Ld %s\n" - (blocks_total *^ stats.fs_block_size /^ 1024L) - (stats.fs_blocks_used *^ stats.fs_block_size /^ 1024L) - (blocks_avail *^ stats.fs_block_size /^ 1024L) - stats.fs_name - ) else ( (* Human-readable blocks. *) - printf "%s %s %s %s\n" - (printable_size (blocks_total *^ stats.fs_block_size)) - (printable_size (stats.fs_blocks_used *^ stats.fs_block_size)) - (printable_size (blocks_avail *^ stats.fs_block_size)) + fun (target, fs_probe_t) -> + let dom_target = dom_name ^ ":" ^ target in + printf "%-20s " dom_target; + + match fs_probe_t with + (* Swap partition. *) + | Swap { swap_name = swap_name; + swap_block_size = block_size; + swap_blocks_total = blocks_total } -> + if not !human then + printf "%10Ld %s\n" + (block_size *^ blocks_total /^ 1024L) swap_name + else + printf "%10s %s\n" + (printable_size (block_size *^ blocks_total)) swap_name + + (* Ordinary filesystem. *) + | Filesystem stats -> + if not !inodes then ( (* Block display. *) + (* 'df' doesn't count the restricted blocks. *) + let blocks_total = + stats.fs_blocks_total -^ stats.fs_blocks_reserved in + let blocks_avail = + stats.fs_blocks_avail -^ stats.fs_blocks_reserved in + let blocks_avail = + if blocks_avail < 0L then 0L else blocks_avail in + + if not !human then ( (* Display 1K blocks. *) + printf "%10Ld %10Ld %10Ld %s\n" + (blocks_total *^ stats.fs_block_size /^ 1024L) + (stats.fs_blocks_used *^ stats.fs_block_size /^ 1024L) + (blocks_avail *^ stats.fs_block_size /^ 1024L) + stats.fs_name + ) else ( (* Human-readable blocks. *) + printf "%10s %10s %10s %s\n" + (printable_size (blocks_total *^ stats.fs_block_size)) + (printable_size (stats.fs_blocks_used *^ stats.fs_block_size)) + (printable_size (blocks_avail *^ stats.fs_block_size)) + stats.fs_name + ) + ) else ( (* Inodes display. *) + printf "%10Ld %10Ld %10Ld %s\n" + stats.fs_inodes_total stats.fs_inodes_used stats.fs_inodes_avail stats.fs_name ) - ) else ( (* Inodes display. *) - printf "%Ld %Ld %Ld %s\n" - stats.fs_inodes_total stats.fs_inodes_used stats.fs_inodes_avail - stats.fs_name - ) - (* Unsupported filesystem or other failure. *) - | (target, ProbeFailed reason) -> - printf "\t%s %s\n" target reason + (* Unsupported filesystem or other failure. *) + | ProbeFailed reason -> + printf " %s\n" reason - | (_, ProbeIgnore) -> () + | ProbeIgnore -> () ) statss (* Target is something like "hda" and size is the size in sectors. *) @@ -323,17 +327,40 @@ let main () = (* Command line argument parsing. *) let set_uri = function "" -> uri := None | u -> uri := Some u in + let version () = + printf "virt-df %s\n" (Libvirt_version.version); + + let major, minor, release = + let v, _ = Libvirt.get_version () in + v / 1_000_000, (v / 1_000) mod 1_000, v mod 1_000 in + printf "libvirt %d.%d.%d\n" major minor release; + exit 0 + in + let argspec = Arg.align [ - "-c", Arg.String set_uri, "uri Connect to URI (default: Xen)"; - "--connect", Arg.String set_uri, "uri Connect to URI (default: Xen)"; - "-h", Arg.Set human, " Print sizes in human-readable format"; - "--human-readable", Arg.Set human, " Print sizes in human-readable format"; - "-i", Arg.Set inodes, " Show inodes instead of blocks"; - "--inodes", Arg.Set inodes, " Show inodes instead of blocks"; + "-a", Arg.Set all, + " " ^ s_ "Show all domains (default: only active domains)"; + "--all", Arg.Set all, + " " ^ s_ "Show all domains (default: only active domains)"; + "-c", Arg.String set_uri, + "uri " ^ s_ "Connect to URI (default: Xen)"; + "--connect", Arg.String set_uri, + "uri " ^ s_ "Connect to URI (default: Xen)"; + "-h", Arg.Set human, + " " ^ s_ "Print sizes in human-readable format"; + "--human-readable", Arg.Set human, + " " ^ s_ "Print sizes in human-readable format"; + "-i", Arg.Set inodes, + " " ^ s_ "Show inodes instead of blocks"; + "--inodes", Arg.Set inodes, + " " ^ s_ "Show inodes instead of blocks"; + "--version", Arg.Unit version, + " " ^ s_ "Display version and exit"; ] in - let anon_fun str = raise (Arg.Bad (str ^ ": unknown parameter")) in - let usage_msg = "virt-df : like 'df', shows disk space used in guests + let anon_fun str = + raise (Arg.Bad (sprintf (f_ "%s: unknown parameter") str)) in + let usage_msg = s_ "virt-df : like 'df', shows disk space used in guests SUMMARY virt-df [-options] @@ -352,7 +379,7 @@ OPTIONS" in prerr_endline (Libvirt.Virterror.to_string err); (* If non-root and no explicit connection URI, print a warning. *) if geteuid () <> 0 && name = None then ( - print_endline "NB: If you want to monitor a local Xen hypervisor, you usually need to be root"; + print_endline (s_ "NB: If you want to monitor a local Xen hypervisor, you usually need to be root"); ); exit 1 in @@ -361,11 +388,15 @@ OPTIONS" in let nr_active_doms = C.num_of_domains conn in let active_doms = Array.to_list (C.list_domains conn nr_active_doms) in let active_doms = List.map (D.lookup_by_id conn) active_doms in - let nr_inactive_doms = C.num_of_defined_domains conn in - let inactive_doms = - Array.to_list (C.list_defined_domains conn nr_inactive_doms) in - let inactive_doms = List.map (D.lookup_by_name conn) inactive_doms in - active_doms @ inactive_doms in + if not !all then + active_doms + else ( + let nr_inactive_doms = C.num_of_defined_domains conn in + let inactive_doms = + Array.to_list (C.list_defined_domains conn nr_inactive_doms) in + let inactive_doms = List.map (D.lookup_by_name conn) inactive_doms in + active_doms @ inactive_doms + ) in (* Get their XML. *) let xmls = List.map D.get_xml_desc doms in @@ -385,7 +416,7 @@ OPTIONS" in let nodes, domain_attrs = match xml with | Xml.Element ("domain", attrs, children) -> children, attrs - | _ -> failwith "get_xml_desc didn't return " in + | _ -> failwith (s_ "get_xml_desc didn't return ") in let domid = try Some (int_of_string (List.assoc "id" domain_attrs)) @@ -393,10 +424,10 @@ OPTIONS" in let rec loop = function | [] -> - failwith "get_xml_desc returned no node in XML" + failwith (s_ "get_xml_desc returned no node in XML") | Xml.Element ("name", _, [Xml.PCData name]) :: _ -> name | Xml.Element ("name", _, _) :: _ -> - failwith "get_xml_desc returned strange node" + failwith (s_ "get_xml_desc returned strange node") | _ :: rest -> loop rest in let name = loop nodes in @@ -460,6 +491,16 @@ OPTIONS" in { dom_name = name; dom_id = domid; dom_disks = disks } ) xmls in + (* Print the title. *) + let () = + let total, used, avail = + match !inodes, !human with + | false, false -> s_ "1K-blocks", s_ "Used", s_ "Available" + | false, true -> s_ "Size", s_ "Used", s_ "Available" + | true, _ -> s_ "Inodes", s_ "IUse", s_ "IFree" in + printf "%-20s %10s %10s %10s %s\n%!" + (s_ "Filesystem") total used avail (s_ "Type") in + (* Probe the devices. *) List.iter ( fun { dom_name = dom_name; dom_disks = dom_disks } -> @@ -470,6 +511,6 @@ OPTIONS" in | { d_device = Some "cdrom" } -> () (* Ignore physical CD-ROM devices. *) | _ -> - printf "(device omitted)\n"; + print_endline (s_ "(device omitted)"); ) dom_disks ) doms