From: Richard Jones Date: Tue, 30 Mar 2010 15:14:09 +0000 (+0100) Subject: virt-df: Match output with native (coreutils) 'df' command (RHBZ#578123). X-Git-Tag: 1.0.89~5 X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;h=29c78cc979297b95407a5956b4caa34240a2f5a8;p=libguestfs.git virt-df: Match output with native (coreutils) 'df' command (RHBZ#578123). This commit fixes the 'Use%' field in the output so it matches what coreutils' 'df' command would print. Firstly we change the calculation to use the space available to root, not the space available to non-root. This means it matches what 'df' when run as root in the guest would show. Secondly we display this rounded up to the next whole percent (ie. using ceil), which is also what 'df' does. Thirdly we change the regression test so it tests this. Note that even with these changes you are not guaranteed to get precisely the same figures from inside and outside the guest, as it depends on how quiescent the guest is and how recently the superblock was synced. Thanks: Rita Wu --- diff --git a/tools/make-test-img.sh b/tools/make-test-img.sh index c6481cd..9752f1d 100755 --- a/tools/make-test-img.sh +++ b/tools/make-test-img.sh @@ -49,11 +49,11 @@ lvcreate LV2 VG 32 lvcreate LV3 VG 64 # Phony /boot filesystem. -mkfs ext2 /dev/sda1 +mkfs-b ext2 4096 /dev/sda1 set-e2label /dev/sda1 BOOT # Phony root filesystem. -mkfs ext2 /dev/VG/Root +mkfs-b ext2 4096 /dev/VG/Root set-e2label /dev/VG/Root ROOT # Enough to fool virt-inspector. @@ -79,9 +79,10 @@ mkfifo 0777 /bin/test6 mknod 0777 10 10 /bin/test7 # Other filesystems. -mkfs ext2 /dev/VG/LV1 -mkfs ext2 /dev/VG/LV2 -mkfs ext2 /dev/VG/LV3 +# Note that these should be empty, for testing virt-df. +mkfs-b ext2 4096 /dev/VG/LV1 +mkfs-b ext2 1024 /dev/VG/LV2 +mkfs-b ext2 2048 /dev/VG/LV3 EOF rm fstab diff --git a/tools/test-virt-df.sh b/tools/test-virt-df.sh index 8e61063..a7b50b8 100755 --- a/tools/test-virt-df.sh +++ b/tools/test-virt-df.sh @@ -4,13 +4,10 @@ export LANG=C set -e # Run virt-df. -output=$(./virt-df test.img -h) - -# The output will be slightly different from one machine to another. -# So just do some tests to make sure it looks reasonable. +output=$(./virt-df test.img) # Check title is the first line. -if [[ ! $output =~ ^Filesystem[[:space:]]+Size[[:space:]]+Used[[:space:]]+Available[[:space:]]+Use% ]]; then +if [[ ! $output =~ ^Filesystem.* ]]; then echo "$0: error: no title line" exit 1 fi @@ -44,3 +41,32 @@ if [[ ! $output =~ test.img:/dev/[hsv]da1 ]]; then echo "$0: error: filesystem /dev/VG/sda1 was not found" exit 1 fi + +# This is what df itself prints for these filesystems (determined +# by running the test image under virt-rescue): +# +# > df -h +# Filesystem Size Used Avail Use% Mounted on +# /dev/dm-1 31M 28K 30M 1% /sysroot/lv1 +# /dev/dm-2 31M 395K 29M 2% /sysroot/lv2 +# /dev/dm-3 62M 144K 59M 1% /sysroot/lv3 +# > df -i +# Filesystem Inodes IUsed IFree IUse% Mounted on +# /dev/dm-1 8192 11 8181 1% /sysroot/lv1 +# /dev/dm-2 8192 11 8181 1% /sysroot/lv2 +# /dev/dm-3 16384 11 16373 1% /sysroot/lv3 +# > df +# Filesystem 1K-blocks Used Available Use% Mounted on +# /dev/dm-1 31728 28 30064 1% /sysroot/lv1 +# /dev/dm-2 31729 395 29696 2% /sysroot/lv2 +# /dev/dm-3 63472 144 60052 1% /sysroot/lv3 +# +# Only test plain 'df' output at the moment (XXX). + +if [ "$(echo "$output" | sort | awk '/VG.LV[123]/ { print $2 " " $3 " " $4 " " $5 }')" != \ +"31728 28 30064 1% +31729 395 29696 2% +63472 144 60052 1%" ]; then + echo "$0: error: output of virt-df did not match expected (df) output" + exit 1 +fi diff --git a/tools/virt-df b/tools/virt-df index 5a064cc..684334d 100755 --- a/tools/virt-df +++ b/tools/virt-df @@ -23,10 +23,13 @@ use Sys::Guestfs; use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path inspect_all_partitions inspect_partition inspect_operating_systems mount_operating_system inspect_in_detail); + use Pod::Usage; use Getopt::Long; use Data::Dumper; use XML::Writer; +use POSIX qw(ceil); + use Locale::TextDomain 'libguestfs'; =encoding utf8 @@ -106,8 +109,8 @@ my $csv; =item B<--csv> -Write out the results in CSV format (comma-separated values). This -format can be imported easily into databases and spreadsheets, but +Write out the results in CSV format (comma-separated values). This format +can be imported easily into databases and spreadsheets, but read L below. =cut @@ -230,9 +233,7 @@ sub print_stat push @cols, ($blocks-$bfree)*$factor; # total 1K blocks used push @cols, $bavail*$factor; # total 1K blocks available - # XXX %used column comes out different from the native 'df' - # program. Need to check how 'df' calculates this. - push @cols, 100.0 - 100.0 * $bavail / $blocks; + push @cols, 100.0 - 100.0 * $bfree / $blocks; if ($human) { $cols[2] = human_size ($cols[2]); @@ -248,9 +249,7 @@ sub print_stat push @cols, $files-$ffree; push @cols, $ffree; - # XXX %used column comes out different from the native 'df' - # program. Need to check how 'df' calculates this. - push @cols, 100.0 - 100.0 * $favail / $files; + push @cols, 100.0 - 100.0 * $ffree / $files; } print_cols (@cols); @@ -292,7 +291,10 @@ sub print_cols printf ("%-36s", $label); print "\n"," "x36 if length ($label) > 36; - my $percent = sprintf "%3.1f%%", $_[5]; + # Use 'ceil' on the percentage in order to emulate + # what df itself does. + my $percent = sprintf "%3d%%", ceil($_[5]); + printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent); } else { printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);