Skip to content

Commit

Permalink
virt-df: Better output when multiple -a/-d options are specified (RHB…
Browse files Browse the repository at this point in the history
…Z#880801).

This is very well explained in the bugzilla comments:
https://bugzilla.redhat.com/show_bug.cgi?id=880801#c1

With this change, the disk name has a one or more plus signs ('+')
appended to show that there are additional disks:

  $ virt-df -a Win7x32TwoDisks-a -a Win7x32TwoDisks-b
  Filesystem                   1K-blocks    Used  Available  Use%
  Win7x32TwoDisks-a+:/dev/sda1    102396   24712      77684   25%
  Win7x32TwoDisks-a+:/dev/sda2  12478460 7403416    5075044   60%
  Win7x32TwoDisks-a+:/dev/sdb1    521212   55728     465484   11%
  • Loading branch information
rwmjones committed Nov 29, 2012
1 parent 6255cc8 commit 9e7daf2
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 17 deletions.
101 changes: 85 additions & 16 deletions df/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ int inodes = 0; /* --inodes */
int one_per_guest = 0; /* --one-per-guest */
int uuid = 0; /* --uuid */

static char *make_display_name (struct drv *drvs);

static inline char *
bad_cast (char const *s)
{
Expand Down Expand Up @@ -269,7 +271,7 @@ main (int argc, char *argv[])
#endif
}
else {
const char *name;
char *name;

/* Add domains/drives from the command line (for a single guest). */
add_drives (drvs, 'a');
Expand All @@ -280,21 +282,7 @@ main (int argc, char *argv[])
print_title ();

/* Synthesize a display name. */
switch (drvs->type) {
case drv_a:
name = strrchr (drvs->a.filename, '/');
if (name == NULL)
name = drvs->a.filename;
else
name++; /* skip '/' character */
break;
case drv_d:
name = drvs->d.guest;
break;
case drv_N:
default:
abort ();
}
name = make_display_name (drvs);

/* XXX regression: in the Perl version we cached the UUID from the
* libvirt domain handle so it was available to us here. In this
Expand All @@ -304,6 +292,8 @@ main (int argc, char *argv[])
*/
(void) df_on_handle (name, NULL, NULL, 0);

free (name);

/* Free up data structures, no longer needed after this point. */
free_drives (drvs);
}
Expand All @@ -312,3 +302,82 @@ main (int argc, char *argv[])

exit (EXIT_SUCCESS);
}

/* Generate a display name for the single guest mode. See comments in
* https://bugzilla.redhat.com/show_bug.cgi?id=880801
*/
static const char *
single_drive_display_name (struct drv *drvs)
{
const char *name;

assert (drvs != NULL);
assert (drvs->next == NULL);

switch (drvs->type) {
case drv_a:
name = strrchr (drvs->a.filename, '/');
if (name == NULL)
name = drvs->a.filename;
else
name++; /* skip '/' character */
break;
case drv_d:
name = drvs->d.guest;
break;
case drv_N:
default:
abort ();
}

return name;
}

static char *
make_display_name (struct drv *drvs)
{
char *ret;

assert (drvs != NULL);

/* Single disk or domain. */
if (drvs->next == NULL) {
const char *name;

name = single_drive_display_name (drvs);
ret = strdup (name);
if (ret == NULL) {
perror ("strdup");
exit (EXIT_FAILURE);
}
}
/* Multiple disks. Multiple domains are possible, although that is
* probably user error. Choose the first name (last in the list),
* and add '+' for each additional disk.
*/
else {
size_t pluses = 0;
size_t i, len;
const char *name;

while (drvs->next != NULL) {
drvs = drvs->next;
pluses++;
}

name = single_drive_display_name (drvs);
len = strlen (name);

ret = malloc (len + pluses + 1);
if (ret == NULL) {
perror ("malloc");
exit (EXIT_FAILURE);
}
memcpy (ret, name, len);
for (i = len; i < len + pluses; ++i)
ret[i] = '+';
ret[i] = '\0';
}

return ret;
}
16 changes: 15 additions & 1 deletion df/virt-df.pod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ virt-df - Display free space on virtual filesystems

=head1 SYNOPSIS

All guests:

virt-df [--options]

Single guest:

virt-df [--options] -d domname

virt-df [--options] -a disk.img [-a disk.img ...]
Expand All @@ -32,7 +36,7 @@ a C<df>-type operation on each one in turn, printing out the results.
If any I<-a> or I<-d> arguments are specified, C<virt-df> performs a
C<df>-type operation on either the single named libvirt domain, or on
the disk image(s) listed on the command line (which must all belong to
a single VM). In this mode (with arguments), C<virt-df> will I<only
a single VM). B<In this mode (with arguments), C<virt-df> will only
work for a single guest>. If you want to run on multiple guests, then
you have to invoke C<virt-df> multiple times.

Expand All @@ -56,6 +60,16 @@ Show disk usage for a disk image file called C<test.img>:
Filesystem 1K-blocks Used Available Use%
test1.img:/dev/sda1 99099 1551 92432 2%

If a single guest has multiple disks, use the I<-a> option repeatedly.
A plus sign (C<+>) is displayed for each additional disk. B<Note: Do
not do this with unrelated guest disks.>

$ virt-df -a Win7x32TwoDisks-a -a Win7x32TwoDisks-b
Filesystem 1K-blocks Used Available Use%
Win7x32TwoDisks-a+:/dev/sda1 102396 24712 77684 25%
Win7x32TwoDisks-a+:/dev/sda2 12478460 7403416 5075044 60%
Win7x32TwoDisks-a+:/dev/sdb1 521212 55728 465484 11%

=head1 OPTIONS

=over 4
Expand Down

0 comments on commit 9e7daf2

Please sign in to comment.