3 # Copyright (C) 2009 Red Hat Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path
24 inspect_all_partitions inspect_partition
25 inspect_operating_systems mount_operating_system inspect_in_detail);
29 use File::Temp qw/tempdir/;
36 virt-df - Display free space on virtual filesystems
42 virt-df [--options] domname
44 virt-df [--options] disk.img [disk.img ...]
48 C<virt-df> is a command line tool to display free space on virtual
49 machine filesystems. Unlike other tools, it doesn't just display the
50 amount of space allocated to a virtual machine, but can look inside
51 the virtual machine to see how much space is really being used.
53 It is like the L<df(1)> command, but for virtual machines, except that
54 it also works for Windows virtual machines.
56 If used without any arguments, C<virt-df> checks with libvirt to get a
57 list of all active and inactive guests, and performs a C<df>-type
58 operation on each one in turn, printing out the results.
60 If used with any argument(s), C<virt-df> performs a C<df>-type
61 operation on either the single named libvirt domain, or on the disk
62 image(s) listed on the command line (which must all belong to a single
63 VM). In this mode (with arguments), C<virt-df> will I<only work for a
64 single guest>. If you want to run on multiple guests, then you have
65 to invoke C<virt-df> multiple times.
67 Use the C<--csv> option to get a format which can be easily parsed by
68 other programs. Other options are mostly similar to standard C<df>
69 options. See below for the complete list.
87 =item B<--connect URI> | B<-c URI>
89 If using libvirt, connect to the given I<URI>. If omitted, then we
90 connect to the default libvirt hypervisor.
92 If you specify guest block devices directly, then libvirt is not used
101 Write out the results in CSV format (comma-separated values).
102 This format can be imported easily into databases and spreadsheets.
108 =item B<--human-readable> | B<-h>
110 Print sizes in human-readable format.
116 =item B<--inodes> | B<-i>
118 Print inodes instead of blocks.
124 GetOptions ("help|?" => \$help,
125 "connect|c=s" => \$uri,
127 "human-readable|human|h" => \$human,
128 "inodes|i" => \$inodes,
130 pod2usage (1) if $help;
132 # Open the guest handle.
138 $conn = Sys::Virt->new (readonly => 1, address => $uri);
140 $conn = Sys::Virt->new (readonly => 1);
143 my @doms = $conn->list_defined_domains ();
144 push @doms, $conn->list_domains ();
146 my @domnames = map { $_->get_name () } @doms;
150 foreach (@domnames) {
164 $g = open_guest (\@_, address => $uri);
166 $g = open_guest (\@_);
172 my @partitions = get_partitions ($g);
174 # Think of a printable name for this domain. Just choose the
175 # first parameter passed to this function, which will work for
176 # most cases (it'll either be the domain name or the first disk
180 # Mount each partition in turn, and if mountable, do a statvfs on it.
181 foreach my $partition (@partitions) {
184 $g->mount_ro ($partition, "/");
185 %stat = $g->statvfs ("/");
188 print_stat ($domname, $partition, \%stat);
197 my $partition = shift;
200 my @cols = ($domname, $partition);
203 my $bsize = $stat->{bsize}; # block size
204 my $blocks = $stat->{blocks}; # total number of blocks
205 my $bfree = $stat->{bfree}; # blocks free (total)
206 my $bavail = $stat->{bavail}; # blocks free (for non-root users)
208 my $factor = $bsize / 1024;
210 push @cols, $blocks*$factor; # total 1K blocks
211 push @cols, ($blocks-$bfree)*$factor; # total 1K blocks used
212 push @cols, $bavail*$factor; # total 1K blocks available
214 # XXX %used column comes out different from the native 'df'
215 # program. Need to check how 'df' calculates this.
216 push @cols, 100.0 - 100.0 * $bavail / $blocks;
219 $cols[2] = human_size ($cols[2]);
220 $cols[3] = human_size ($cols[3]);
221 $cols[4] = human_size ($cols[4]);
224 my $files = $stat->{files}; # total number of inodes
225 my $ffree = $stat->{ffree}; # inodes free (total)
226 my $favail = $stat->{favail}; # inodes free (for non-root users)
229 push @cols, $files-$ffree;
232 # XXX %used column comes out different from the native 'df'
233 # program. Need to check how 'df' calculates this.
234 push @cols, 100.0 - 100.0 * $favail / $files;
242 my @cols = ("Virtual Machine", "Filesystem");
245 push @cols, "1K-blocks";
250 push @cols, "Available";
253 push @cols, "Inodes";
260 # ignore $cols[0] in this mode
261 printf "%-36s%10s %10s %10s %5s\n",
262 $cols[1], $cols[2], $cols[3], $cols[4], $cols[5];
264 print (join (",", @cols), "\n");
271 my $label = sprintf "%s:%s", $_[0], $_[1];
273 printf ("%-36s", $label);
274 print "\n"," "x32 if length ($label) > 36;
276 my $percent = sprintf "%3.1f%%", $_[5];
277 printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent);
279 printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);
283 # Convert a number of 1K blocks to a human-readable number.
290 } elsif ($_ < 1024 * 1024) {
291 sprintf "%.1fM", ($_ / 1024);
293 sprintf "%.1fG", ($_ / 1024 / 1024);
302 L<Sys::Guestfs::Lib(3)>,
304 L<http://libguestfs.org/>.
308 Richard W.M. Jones L<http://et.redhat.com/~rjones/>
312 Copyright (C) 2009 Red Hat Inc.
314 This program is free software; you can redistribute it and/or modify
315 it under the terms of the GNU General Public License as published by
316 the Free Software Foundation; either version 2 of the License, or
317 (at your option) any later version.
319 This program is distributed in the hope that it will be useful,
320 but WITHOUT ANY WARRANTY; without even the implied warranty of
321 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
322 GNU General Public License for more details.
324 You should have received a copy of the GNU General Public License
325 along with this program; if not, write to the Free Software
326 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.