From ca6baf8fcb2e3ecc917c8ec1e11c1ddbec29afcb Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] "Finish off" this program, add manpage. --- virt-df/.depend | 4 +- virt-df/Makefile.in | 22 ++--- virt-df/README | 35 +------ virt-df/virt-df.1 | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++ virt-df/virt-df.pod | 174 ++++++++++++++++++++++++++++++++ virt-df/virt-df.txt | 139 ++++++++++++++++++++++++++ virt-df/virt_df.ml | 140 +++++++++++++++----------- 7 files changed, 693 insertions(+), 101 deletions(-) mode change 100755 => 100644 virt-df/Makefile.in mode change 100755 => 100644 virt-df/README create mode 100644 virt-df/virt-df.1 create mode 100644 virt-df/virt-df.pod create mode 100644 virt-df/virt-df.txt mode change 100755 => 100644 virt-df/virt_df.ml diff --git a/virt-df/.depend b/virt-df/.depend index 8cb0e7e..1a7750e 100644 --- a/virt-df/.depend +++ b/virt-df/.depend @@ -6,5 +6,5 @@ virt_df_lvm2.cmo: virt_df.cmo virt_df_lvm2.cmx: virt_df.cmx virt_df_main.cmo: virt_df.cmo virt_df_main.cmx: virt_df.cmx -virt_df.cmo: ../libvirt/libvirt.cmi -virt_df.cmx: ../libvirt/libvirt.cmx +virt_df.cmo: ../libvirt/libvirt_version.cmi ../libvirt/libvirt.cmi +virt_df.cmx: ../libvirt/libvirt_version.cmx ../libvirt/libvirt.cmx diff --git a/virt-df/Makefile.in b/virt-df/Makefile.in old mode 100755 new mode 100644 index cc25c9c..13d386e --- a/virt-df/Makefile.in +++ b/virt-df/Makefile.in @@ -50,9 +50,9 @@ export LD_LIBRARY_PATH=../libvirt BYTE_TARGETS := virt-df OPT_TARGETS := virt-df.opt -#ifeq ($(HAVE_PERLDOC),perldoc) -#BYTE_TARGETS += virt-df.1 virt-df.txt -#endif +ifeq ($(HAVE_PERLDOC),perldoc) +BYTE_TARGETS += virt-df.1 virt-df.txt +endif all: $(BYTE_TARGETS) @@ -68,14 +68,14 @@ virt-df.opt: $(XOBJS) ../libvirt/mllibvirt.cmxa -cclib -lncurses -o $@ $^ # Manual page. -#ifeq ($(HAVE_PERLDOC),perldoc) -#virt-df.1: virt-df.pod -# pod2man -c "Virtualization Support" --release "$(PACKAGE)-$(VERSION)" \ -# $< > $@ -# -#virt-df.txt: virt-df.pod -# pod2text $< > $@ -#endif +ifeq ($(HAVE_PERLDOC),perldoc) +virt-df.1: virt-df.pod + pod2man -c "Virtualization Support" --release "$(PACKAGE)-$(VERSION)" \ + $< > $@ + +virt-df.txt: virt-df.pod + pod2text $< > $@ +endif install: if [ -x virt-df.opt ]; then \ diff --git a/virt-df/README b/virt-df/README old mode 100755 new mode 100644 index c6dfcc7..0623030 --- a/virt-df/README +++ b/virt-df/README @@ -1,33 +1,2 @@ -virt-df is a 'df' tool for printing out the used and available disk -space in all active and inactive domains. Without this tool you would -need to log in to each domain individually or set up monitoring. - -It is only a proof-of-concept. Please bare in mind the following -limitations when using this tool: - -(1) It does not work over remote connections. Part of the reason why -I wrote virt-df was to get an idea of how the remote storage API for -libvirt might look. - -(2) It only understands a limited set of partition types. Assuming -that the files and partitions that we get back from libvirt / Xen -correspond to block devices in the guests, we can go some way towards -manually parsing those partitions to find out what they contain. We -can read the MBR, LVM, superblocks and so on. However that's a lot of -parsing work, and currently there is no library which understands a -wide range of partition schemes and filesystem types (not even -libparted which doesn't support LVM yet). The Linux kernel does -support that, but there's not really any good way to access that work. - -The current implementation uses a hand-coded parser which understands -some simple formats (MBR, LVM2, ext2/3). In future we should use -something like libparted. - -(3) The statistics you get are delayed. The real state of, for -example, an ext2 filesystem is only stored in the memory of the -guest's kernel. The ext2 superblock contains some meta-information -about blocks used and free, but this superblock is not up to date. In -fact the guest kernel may not update it even on a 'sync', not until -the filesystem is unmounted. Some operations do appear to write the -superblock, for example fsync(2) [that is my reading of the ext2/3 -source code at least]. +Please see the manual page (virt-df.pod or virt-df.txt in this +directory). \ No newline at end of file diff --git a/virt-df/virt-df.1 b/virt-df/virt-df.1 new file mode 100644 index 0000000..ff7e92d --- /dev/null +++ b/virt-df/virt-df.1 @@ -0,0 +1,280 @@ +.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to +.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' +.\" expand to `' in nroff, nothing in troff, for use with C<>. +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "VIRT-DF 1" +.TH VIRT-DF 1 "2008-03-04" "ocaml-libvirt-0.4.0.3" "Virtualization Support" +.SH "NAME" +virt\-df \- 'df'\-like utility for virtualization stats +.SH "SUMMARY" +.IX Header "SUMMARY" +virt-df [\-options] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +virt-df is a \fIdf\fR\|(1)\-like utility for showing the actual disk usage +of guests. Many command line options are the same as for ordinary +\&\fIdf\fR. +.PP +It uses libvirt so it is capable of showing stats across a variety of +different virtualization systems. +.PP +There are some shortcomings to the whole approach of reading disk +state from outside the guest. Please read \s-1SHORTCOMINGS\s0 section below +for more details. +.SH "OPTIONS" +.IX Header "OPTIONS" +.IP "\fB\-a\fR, \fB\-\-all\fR" 4 +.IX Item "-a, --all" +Show all domains. The default is show only running (active) domains. +.IP "\fB\-c uri\fR, \fB\-\-connect uri\fR" 4 +.IX Item "-c uri, --connect uri" +Connect to libvirt \s-1URI\s0. The default is to connect to the default +libvirt \s-1URI\s0, normally Xen. +.IP "\fB\-h\fR, \fB\-\-human\-readable\fR" 4 +.IX Item "-h, --human-readable" +Display human-readable sizes (eg. 10GiB). +.IP "\fB\-i\fR, \fB\-\-inodes\fR" 4 +.IX Item "-i, --inodes" +Display inode information. +.IP "\fB\-\-help\fR" 4 +.IX Item "--help" +Display usage summary. +.IP "\fB\-\-version\fR" 4 +.IX Item "--version" +Display version and exit. +.SH "SHORTCOMINGS" +.IX Header "SHORTCOMINGS" +virt-df spies on the guest's disk image to try to work out how much +disk space it is actually using. There are some shortcomings to this, +described here. +.PP +(1) It does not work over remote connections. The storage \s-1API\s0 does +not support peeking into remote disks, and libvirt has rejected a +request to add this support. +.PP +(2) It only understands a limited set of partition types. Assuming +that the files and partitions that we get back from libvirt / Xen +correspond to block devices in the guests, we can go some way towards +manually parsing those partitions to find out what they contain. We +can read the \s-1MBR\s0, \s-1LVM\s0, superblocks and so on. However that's a lot of +parsing work, and currently there is no library which understands a +wide range of partition schemes and filesystem types (not even +libparted which doesn't support \s-1LVM\s0 yet). The Linux kernel does +support that, but there's not really any good way to access that work. +.PP +The current implementation uses a hand-coded parser which understands +some simple formats (\s-1MBR\s0, \s-1LVM2\s0, ext2/3). In future we should use +something like libparted. +.PP +(3) The statistics you get are delayed. The real state of, for +example, an ext2 filesystem is only stored in the memory of the +guest's kernel. The ext2 superblock contains some meta-information +about blocks used and free, but this superblock is not up to date. In +fact the guest kernel may not update it even on a 'sync', not until +the filesystem is unmounted. Some operations do appear to write the +superblock, for example \fIfsync\fR\|(2) [that is my reading of the ext2/3 +source code at least]. +.SH "SECURITY" +.IX Header "SECURITY" +The current code is probably not secure against malicious guests. In +particular a malicious guest can set up a disk in such a way that disk +structures with loops can cause virt-df to spin forever. We are +preparing a parsing library which can fix these sorts of problems. +.PP +In the meantime, do not run virt-df on untrusted guests. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fIdf\fR\|(1), +\&\fIvirsh\fR\|(1), +\&\fIxm\fR\|(1), +, +, +, + +.SH "AUTHORS" +.IX Header "AUTHORS" +Richard W.M. Jones +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +(C) Copyright 2007\-2008 Red Hat Inc., Richard W.M. Jones +http://libvirt.org/ +.PP +This program is free software; you can redistribute it and/or modify +it under the terms of the \s-1GNU\s0 General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +.PP +This program is distributed in the hope that it will be useful, +but \s-1WITHOUT\s0 \s-1ANY\s0 \s-1WARRANTY\s0; without even the implied warranty of +\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0. See the +\&\s-1GNU\s0 General Public License for more details. +.PP +You should have received a copy of the \s-1GNU\s0 General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, \s-1MA\s0 02139, \s-1USA\s0. +.SH "REPORTING BUGS" +.IX Header "REPORTING BUGS" +Bugs can be viewed on the Red Hat Bugzilla page: +. +.PP +If you find a bug in virt\-df, please follow these steps to report it: +.IP "1. Check for existing bug reports" 4 +.IX Item "1. Check for existing bug reports" +Go to and search for similar bugs. +Someone may already have reported the same bug, and they may even +have fixed it. +.IP "2. Capture debug and error messages" 4 +.IX Item "2. Capture debug and error messages" +Run +.Sp +.Vb 1 +\& virt-df > virt-df.log 2>&1 +.Ve +.Sp +and keep \fIvirt\-df.log\fR. It contains error messages which you should +submit with your bug report. +.IP "3. Get version of virt-df and version of libvirt." 4 +.IX Item "3. Get version of virt-df and version of libvirt." +Run +.Sp +.Vb 1 +\& virt-df --version +.Ve +.IP "4. Submit a bug report." 4 +.IX Item "4. Submit a bug report." +Go to and enter a new bug. +Please describe the problem in as much detail as possible. +.Sp +Remember to include the version numbers (step 3) and the debug +messages file (step 2). +.IP "5. Assign the bug to rjones @ redhat.com" 4 +.IX Item "5. Assign the bug to rjones @ redhat.com" +Assign or reassign the bug to \fBrjones @ redhat.com\fR (without the +spaces). You can also send me an email with the bug number if you +want a faster response. diff --git a/virt-df/virt-df.pod b/virt-df/virt-df.pod new file mode 100644 index 0000000..84b1d97 --- /dev/null +++ b/virt-df/virt-df.pod @@ -0,0 +1,174 @@ +=head1 NAME + +virt-df - 'df'-like utility for virtualization stats + +=head1 SUMMARY + +virt-df [-options] + +=head1 DESCRIPTION + +virt-df is a L-like utility for showing the actual disk usage +of guests. Many command line options are the same as for ordinary +I. + +It uses libvirt so it is capable of showing stats across a variety of +different virtualization systems. + +There are some shortcomings to the whole approach of reading disk +state from outside the guest. Please read SHORTCOMINGS section below +for more details. + +=head1 OPTIONS + +=over 4 + +=item B<-a>, B<--all> + +Show all domains. The default is show only running (active) domains. + +=item B<-c uri>, B<--connect uri> + +Connect to libvirt URI. The default is to connect to the default +libvirt URI, normally Xen. + +=item B<-h>, B<--human-readable> + +Display human-readable sizes (eg. 10GiB). + +=item B<-i>, B<--inodes> + +Display inode information. + +=item B<--help> + +Display usage summary. + +=item B<--version> + +Display version and exit. + +=back + +=head1 SHORTCOMINGS + +virt-df spies on the guest's disk image to try to work out how much +disk space it is actually using. There are some shortcomings to this, +described here. + +(1) It does not work over remote connections. The storage API does +not support peeking into remote disks, and libvirt has rejected a +request to add this support. + +(2) It only understands a limited set of partition types. Assuming +that the files and partitions that we get back from libvirt / Xen +correspond to block devices in the guests, we can go some way towards +manually parsing those partitions to find out what they contain. We +can read the MBR, LVM, superblocks and so on. However that's a lot of +parsing work, and currently there is no library which understands a +wide range of partition schemes and filesystem types (not even +libparted which doesn't support LVM yet). The Linux kernel does +support that, but there's not really any good way to access that work. + +The current implementation uses a hand-coded parser which understands +some simple formats (MBR, LVM2, ext2/3). In future we should use +something like libparted. + +(3) The statistics you get are delayed. The real state of, for +example, an ext2 filesystem is only stored in the memory of the +guest's kernel. The ext2 superblock contains some meta-information +about blocks used and free, but this superblock is not up to date. In +fact the guest kernel may not update it even on a 'sync', not until +the filesystem is unmounted. Some operations do appear to write the +superblock, for example L [that is my reading of the ext2/3 +source code at least]. + +=head1 SECURITY + +The current code is probably not secure against malicious guests. In +particular a malicious guest can set up a disk in such a way that disk +structures with loops can cause virt-df to spin forever. We are +preparing a parsing library which can fix these sorts of problems. + +In the meantime, do not run virt-df on untrusted guests. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 AUTHORS + +Richard W.M. Jones + +=head1 COPYRIGHT + +(C) Copyright 2007-2008 Red Hat Inc., Richard W.M. Jones +http://libvirt.org/ + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +=head1 REPORTING BUGS + +Bugs can be viewed on the Red Hat Bugzilla page: +L. + +If you find a bug in virt-df, please follow these steps to report it: + +=over 4 + +=item 1. Check for existing bug reports + +Go to L and search for similar bugs. +Someone may already have reported the same bug, and they may even +have fixed it. + +=item 2. Capture debug and error messages + +Run + + virt-df > virt-df.log 2>&1 + +and keep I. It contains error messages which you should +submit with your bug report. + +=item 3. Get version of virt-df and version of libvirt. + +Run + + virt-df --version + +=item 4. Submit a bug report. + +Go to L and enter a new bug. +Please describe the problem in as much detail as possible. + +Remember to include the version numbers (step 3) and the debug +messages file (step 2). + +=item 5. Assign the bug to rjones @ redhat.com + +Assign or reassign the bug to B (without the +spaces). You can also send me an email with the bug number if you +want a faster response. + +=back + +=end diff --git a/virt-df/virt-df.txt b/virt-df/virt-df.txt new file mode 100644 index 0000000..fcddafb --- /dev/null +++ b/virt-df/virt-df.txt @@ -0,0 +1,139 @@ +NAME + virt-df - 'df'-like utility for virtualization stats + +SUMMARY + virt-df [-options] + +DESCRIPTION + virt-df is a df(1)-like utility for showing the actual disk usage of + guests. Many command line options are the same as for ordinary *df*. + + It uses libvirt so it is capable of showing stats across a variety of + different virtualization systems. + + There are some shortcomings to the whole approach of reading disk state + from outside the guest. Please read SHORTCOMINGS section below for more + details. + +OPTIONS + -a, --all + Show all domains. The default is show only running (active) domains. + + -c uri, --connect uri + Connect to libvirt URI. The default is to connect to the default + libvirt URI, normally Xen. + + -h, --human-readable + Display human-readable sizes (eg. 10GiB). + + -i, --inodes + Display inode information. + + --help + Display usage summary. + + --version + Display version and exit. + +SHORTCOMINGS + virt-df spies on the guest's disk image to try to work out how much disk + space it is actually using. There are some shortcomings to this, + described here. + + (1) It does not work over remote connections. The storage API does not + support peeking into remote disks, and libvirt has rejected a request to + add this support. + + (2) It only understands a limited set of partition types. Assuming that + the files and partitions that we get back from libvirt / Xen correspond + to block devices in the guests, we can go some way towards manually + parsing those partitions to find out what they contain. We can read the + MBR, LVM, superblocks and so on. However that's a lot of parsing work, + and currently there is no library which understands a wide range of + partition schemes and filesystem types (not even libparted which doesn't + support LVM yet). The Linux kernel does support that, but there's not + really any good way to access that work. + + The current implementation uses a hand-coded parser which understands + some simple formats (MBR, LVM2, ext2/3). In future we should use + something like libparted. + + (3) The statistics you get are delayed. The real state of, for example, + an ext2 filesystem is only stored in the memory of the guest's kernel. + The ext2 superblock contains some meta-information about blocks used and + free, but this superblock is not up to date. In fact the guest kernel + may not update it even on a 'sync', not until the filesystem is + unmounted. Some operations do appear to write the superblock, for + example fsync(2) [that is my reading of the ext2/3 source code at + least]. + +SECURITY + The current code is probably not secure against malicious guests. In + particular a malicious guest can set up a disk in such a way that disk + structures with loops can cause virt-df to spin forever. We are + preparing a parsing library which can fix these sorts of problems. + + In the meantime, do not run virt-df on untrusted guests. + +SEE ALSO + df(1), virsh(1), xm(1), , + , , + + +AUTHORS + Richard W.M. Jones + +COPYRIGHT + (C) Copyright 2007-2008 Red Hat Inc., Richard W.M. Jones + http://libvirt.org/ + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 675 Mass Ave, Cambridge, MA 02139, USA. + +REPORTING BUGS + Bugs can be viewed on the Red Hat Bugzilla page: + . + + If you find a bug in virt-df, please follow these steps to report it: + + 1. Check for existing bug reports + Go to and search for similar bugs. + Someone may already have reported the same bug, and they may even + have fixed it. + + 2. Capture debug and error messages + Run + + virt-df > virt-df.log 2>&1 + + and keep *virt-df.log*. It contains error messages which you should + submit with your bug report. + + 3. Get version of virt-df and version of libvirt. + Run + + virt-df --version + + 4. Submit a bug report. + Go to and enter a new bug. Please + describe the problem in as much detail as possible. + + Remember to include the version numbers (step 3) and the debug + messages file (step 2). + + 5. Assign the bug to rjones @ redhat.com + Assign or reassign the bug to rjones @ redhat.com (without the + spaces). You can also send me an email with the bug number if you + want a faster response. + diff --git a/virt-df/virt_df.ml b/virt-df/virt_df.ml old mode 100755 new mode 100644 index bbaaa7d..350d535 --- 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 @@ -37,6 +37,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 +105,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 +125,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 @@ -243,57 +244,59 @@ and probe_partition target part_type fd start size = ProbeFailed (sprintf "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,13 +326,26 @@ 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 [ + "-a", Arg.Set all, " Show all domains (default: only active domains)"; + "--all", Arg.Set all, " Show all domains (default: only active domains)"; "-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"; + "--version", Arg.Unit version, " Display version and exit"; ] in let anon_fun str = raise (Arg.Bad (str ^ ": unknown parameter")) in @@ -361,11 +377,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 @@ -460,6 +480,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 -> "1K-blocks", "Used", "Available" + | false, true -> "Size", "Used", "Available" + | true, _ -> "Inodes", "IUse", "IFree" in + printf "%-20s %10s %10s %10s %s\n%!" + "Filesystem" total used avail "Type" in + (* Probe the devices. *) List.iter ( fun { dom_name = dom_name; dom_disks = dom_disks } -> -- 1.8.3.1