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/;
31 use Locale::TextDomain 'libguestfs';
37 virt-df - Display free space on virtual filesystems
43 virt-df [--options] domname
45 virt-df [--options] disk.img [disk.img ...]
49 C<virt-df> is a command line tool to display free space on virtual
50 machine filesystems. Unlike other tools, it doesn't just display the
51 amount of space allocated to a virtual machine, but can look inside
52 the virtual machine to see how much space is really being used.
54 It is like the L<df(1)> command, but for virtual machines, except that
55 it also works for Windows virtual machines.
57 If used without any arguments, C<virt-df> checks with libvirt to get a
58 list of all active and inactive guests, and performs a C<df>-type
59 operation on each one in turn, printing out the results.
61 If used with any argument(s), C<virt-df> performs a C<df>-type
62 operation on either the single named libvirt domain, or on the disk
63 image(s) listed on the command line (which must all belong to a single
64 VM). In this mode (with arguments), C<virt-df> will I<only work for a
65 single guest>. If you want to run on multiple guests, then you have
66 to invoke C<virt-df> multiple times.
68 Use the C<--csv> option to get a format which can be easily parsed by
69 other programs. Other options are mostly similar to standard C<df>
70 options. See below for the complete list.
90 Display version number and exit.
96 =item B<--connect URI> | B<-c URI>
98 If using libvirt, connect to the given I<URI>. If omitted, then we
99 connect to the default libvirt hypervisor.
101 If you specify guest block devices directly, then libvirt is not used
110 Write out the results in CSV format (comma-separated values).
111 This format can be imported easily into databases and spreadsheets.
117 =item B<--human-readable> | B<-h>
119 Print sizes in human-readable format.
125 =item B<--inodes> | B<-i>
127 Print inodes instead of blocks.
133 GetOptions ("help|?" => \$help,
134 "version" => \$version,
135 "connect|c=s" => \$uri,
137 "human-readable|human|h" => \$human,
138 "inodes|i" => \$inodes,
140 pod2usage (1) if $help;
142 my $g = Sys::Guestfs->new ();
143 my %h = $g->version ();
144 print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
148 # Open the guest handle.
154 $conn = Sys::Virt->new (readonly => 1, address => $uri);
156 $conn = Sys::Virt->new (readonly => 1);
159 my @doms = $conn->list_defined_domains ();
160 push @doms, $conn->list_domains ();
162 my @domnames = map { $_->get_name () } @doms;
166 foreach (@domnames) {
180 $g = open_guest (\@_, address => $uri);
182 $g = open_guest (\@_);
187 my @partitions = get_partitions ($g);
189 # Think of a printable name for this domain. Just choose the
190 # first parameter passed to this function, which will work for
191 # most cases (it'll either be the domain name or the first disk
195 # Mount each partition in turn, and if mountable, do a statvfs on it.
196 foreach my $partition (@partitions) {
199 $g->mount_ro ($partition, "/");
200 %stat = $g->statvfs ("/");
203 print_stat ($domname, $partition, \%stat);
212 my $partition = shift;
215 my @cols = ($domname, $partition);
218 my $bsize = $stat->{bsize}; # block size
219 my $blocks = $stat->{blocks}; # total number of blocks
220 my $bfree = $stat->{bfree}; # blocks free (total)
221 my $bavail = $stat->{bavail}; # blocks free (for non-root users)
223 my $factor = $bsize / 1024;
225 push @cols, $blocks*$factor; # total 1K blocks
226 push @cols, ($blocks-$bfree)*$factor; # total 1K blocks used
227 push @cols, $bavail*$factor; # total 1K blocks available
229 # XXX %used column comes out different from the native 'df'
230 # program. Need to check how 'df' calculates this.
231 push @cols, 100.0 - 100.0 * $bavail / $blocks;
234 $cols[2] = human_size ($cols[2]);
235 $cols[3] = human_size ($cols[3]);
236 $cols[4] = human_size ($cols[4]);
239 my $files = $stat->{files}; # total number of inodes
240 my $ffree = $stat->{ffree}; # inodes free (total)
241 my $favail = $stat->{favail}; # inodes free (for non-root users)
244 push @cols, $files-$ffree;
247 # XXX %used column comes out different from the native 'df'
248 # program. Need to check how 'df' calculates this.
249 push @cols, 100.0 - 100.0 * $favail / $files;
257 my @cols = (__"Virtual Machine", __"Filesystem");
260 push @cols, __"1K-blocks";
262 push @cols, __"Size";
264 push @cols, __"Used";
265 push @cols, __"Available";
266 push @cols, __"Use%";
268 push @cols, __"Inodes";
269 push @cols, __"IUsed";
270 push @cols, __"IFree";
271 push @cols, __"IUse%";
275 # ignore $cols[0] in this mode
276 printf "%-36s%10s %10s %10s %5s\n",
277 $cols[1], $cols[2], $cols[3], $cols[4], $cols[5];
279 print (join (",", @cols), "\n");
286 my $label = sprintf "%s:%s", $_[0], $_[1];
288 printf ("%-36s", $label);
289 print "\n"," "x36 if length ($label) > 36;
291 my $percent = sprintf "%3.1f%%", $_[5];
292 printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent);
294 printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);
298 # Convert a number of 1K blocks to a human-readable number.
305 } elsif ($_ < 1024 * 1024) {
306 sprintf "%.1fM", ($_ / 1024);
308 sprintf "%.1fG", ($_ / 1024 / 1024);
317 L<Sys::Guestfs::Lib(3)>,
319 L<http://libguestfs.org/>.
323 Richard W.M. Jones L<http://et.redhat.com/~rjones/>
327 Copyright (C) 2009 Red Hat Inc.
329 This program is free software; you can redistribute it and/or modify
330 it under the terms of the GNU General Public License as published by
331 the Free Software Foundation; either version 2 of the License, or
332 (at your option) any later version.
334 This program is distributed in the hope that it will be useful,
335 but WITHOUT ANY WARRANTY; without even the implied warranty of
336 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
337 GNU General Public License for more details.
339 You should have received a copy of the GNU General Public License
340 along with this program; if not, write to the Free Software
341 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.