Richard W.M. Jones
2009-Nov-24 15:22 UTC
[Libguestfs] [PATCH] New tool: virt-list-filesystems
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming blog: http://rwmj.wordpress.com Fedora now supports 80 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora -------------- next part -------------->From 2945ef77d09eef25fe32d36ad14afacdf0c3a374 Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at redhat.com> Date: Tue, 24 Nov 2009 15:19:08 +0000 Subject: [PATCH] New tool: virt-list-filesystems Use this program as a convenient way to list the filesystems available in a disk image or libvirt guest. Example: $ virt-list-filesystems /dev/vg_trick/Debian5x64 /dev/debian5x64/home /dev/debian5x64/root /dev/debian5x64/tmp /dev/debian5x64/usr /dev/debian5x64/var /dev/sda1 This is designed to make it easier for novices to use guestfish and guestmount. In particular with guestmount this acts as a way to get a list of filesystems to use with the '-m' option. ie: $ virt-list-filesystems unknowndisk.img /dev/sda1 /dev/sda2 $ guestmount -a unknowndisk.img -m /dev/sda1 /mnt --- .gitignore | 1 + Makefile.am | 2 + fuse/guestmount.pod | 5 + guestfish.pod | 6 + po/POTFILES.in | 1 + tools/Makefile.am | 2 +- tools/virt-list-filesystems | 223 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 239 insertions(+), 1 deletions(-) create mode 100755 tools/virt-list-filesystems diff --git a/.gitignore b/.gitignore index 3348b97..1af0b68 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ html/virt-cat.1.html html/virt-df.1.html html/virt-edit.1.html html/virt-inspector.1.html +html/virt-list-filesystems.1.html html/virt-ls.1.html html/virt-rescue.1.html html/virt-tar.1.html diff --git a/Makefile.am b/Makefile.am index bbdb0ed..d0ad5ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -170,6 +170,7 @@ HTMLFILES = \ html/virt-df.1.html \ html/virt-edit.1.html \ html/virt-inspector.1.html \ + html/virt-list-filesystems.1.html \ html/virt-ls.1.html \ html/virt-rescue.1.html \ html/virt-tar.1.html \ @@ -205,6 +206,7 @@ all-local: -name 'virt-df' -o \ -name 'virt-edit' -o \ -name 'virt-inspector' -o \ + -name 'virt-list-filesystems' -o \ -name 'virt-ls' -o \ -name 'virt-rescue' -o \ -name 'virt-tar' -o \ diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod index ee9a7c8..9da7407 100644 --- a/fuse/guestmount.pod +++ b/fuse/guestmount.pod @@ -53,6 +53,11 @@ mountpoints for you: option is called I<--ro-fish> or I<--fish> because these parameters are compatible with L<guestfish(1)>. +If you don't know what filesystems are contained in a guest or +disk image, use L<virt-list-filesystems(1)> first: + + virt-list-filesystems MyGuest + If you want to trace the libguestfs calls but without excessive debugging, we recommend: diff --git a/guestfish.pod b/guestfish.pod index 026f82d..876b988 100644 --- a/guestfish.pod +++ b/guestfish.pod @@ -152,6 +152,11 @@ You have to mount something on C</> before most commands will work. If any C<-m> or C<--mount> options are given, the guest is automatically launched. +If you don't know what filesystems a disk image contains, you +can either run guestfish without this option, then list the partitions +and LVs available (see L</list-partitions> and L</lvs> commands), +or you can use the L<virt-list-filesystems(1)> program. + =item B<-n> | B<--no-sync> Disable autosync. This is enabled by default. See the discussion @@ -682,6 +687,7 @@ L<guestfs(3)>, L<http://libguestfs.org/>, L<virt-cat(1)>, L<virt-edit(1)>, +L<virt-list-filesystems(1)>, L<virt-ls(1)>, L<virt-rescue(1)>, L<virt-tar(1)>. diff --git a/po/POTFILES.in b/po/POTFILES.in index afaa33b..c944067 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -100,6 +100,7 @@ test-tool/test-tool.c tools/virt-cat tools/virt-df tools/virt-edit +tools/virt-list-filesystems tools/virt-ls tools/virt-rescue tools/virt-tar diff --git a/tools/Makefile.am b/tools/Makefile.am index 3055ab7..6e6872c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -17,7 +17,7 @@ include $(top_srcdir)/subdir-rules.mk -tools = cat df edit ls rescue tar win-reg +tools = cat df edit list-filesystems ls rescue tar win-reg EXTRA_DIST = \ run-locally \ diff --git a/tools/virt-list-filesystems b/tools/virt-list-filesystems new file mode 100755 index 0000000..50024aa --- /dev/null +++ b/tools/virt-list-filesystems @@ -0,0 +1,223 @@ +#!/usr/bin/perl -w +# virt-list-filesystems +# Copyright (C) 2009 Red Hat Inc. +# +# 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. + +use warnings; +use strict; + +use Sys::Guestfs; +use Sys::Guestfs::Lib qw(open_guest get_partitions); +use Pod::Usage; +use Getopt::Long; +use Locale::TextDomain 'libguestfs'; +use File::Temp qw/tempdir/; + +=encoding utf8 + +=head1 NAME + +virt-list-filesystems - List filesystems in a virtual machine or disk image + +=head1 SYNOPSIS + + virt-list-filesystems [--options] domname + + virt-list-filesystems [--options] disk.img [disk.img ...] + +=head1 DESCRIPTION + +C<virt-list-filesystems> is a command line tool to list +the filesystems that are contained in a virtual machine or +disk image. + +C<virt-list-filesystems> is just a simple wrapper around +L<libguestfs(3)> functionality. For more complex cases you should +look at the L<guestfish(1)> tool. + +=head1 OPTIONS + +=over 4 + +=cut + +my $help; + +=item B<--help> + +Display brief help. + +=cut + +my $version; + +=item B<--version> + +Display version number and exit. + +=cut + +my $uri; + +=item B<--connect URI> | B<-c URI> + +If using libvirt, connect to the given I<URI>. If omitted, then we +connect to the default libvirt hypervisor. + +If you specify guest block devices directly, then libvirt is not used +at all. + +=cut + +my $long; + +=item B<-l> | B<--long> + +With this option, C<virt-list-filesystems> displays the type of +each filesystem too (where "type" means C<ext3>, C<xfs> etc.) + +=cut + +my $all; + +=item B<-a> | B<--all> + +Normally we only show mountable filesystems. If this option +is given then swap devices are shown too. + +=back + +=cut + +# Configure bundling, otherwise '-al' is treated as '--all'. +Getopt::Long::Configure ("bundling"); + +GetOptions ("help|?" => \$help, + "version" => \$version, + "connect|c=s" => \$uri, + "long|l" => \$long, + "all|a" => \$all, + ) or pod2usage (2); +pod2usage (1) if $help; +if ($version) { + my $g = Sys::Guestfs->new (); + my %h = $g->version (); + print "$h{major}.$h{minor}.$h{release}$h{extra}\n"; + exit +} + +pod2usage (__"virt-list-filesystems: no image or VM name given") + if @ARGV <= 0; + +my $g; +if ($uri) { + $g = open_guest (\@ARGV, address => $uri); +} else { + $g = open_guest (\@ARGV); +} + +$g->launch (); + +# List of partitions, LVs etc. +my @partitions = get_partitions ($g); + +my @fses; +my @not_mountable; +my $dev; + +# Try and mount each one, to see what's mountable. +foreach $dev (@partitions) { + eval { $g->mount_ro ($dev, "/"); }; + my $mountable = $@ ? 0 : 1; + $g->umount_all (); + if ($mountable) { + push @fses, $dev; + } else { + push @not_mountable, $dev; + } +} + +foreach $dev (@fses) { + print canonicalize($dev); + if ($long) { + my $fstype; + eval { $fstype = $g->vfs_type ($dev); }; + if ($fstype) { + print " $fstype"; + } else { + print " unknown"; + } + } + print "\n"; +} + +# If asked, look in the not_mountable list for potential swap devices. +if ($all) { + foreach $dev (@not_mountable) { + my $file; + eval { $file = $g->file ($dev); }; + if ($file && $file =~ /\bswap\b/) { + print canonicalize($dev); + print " swap" if $long; + print "\n" + } + } +} + +# The reverse of device name translation, see +# BLOCK DEVICE NAMING in guestfs(3). +sub canonicalize +{ + local $_ = shift; + + if (m{^/dev/[hv]d([a-z]\d)$}) { + return "/dev/sd$1"; + } + $_; +} + +=head1 SEE ALSO + +L<guestfs(3)>, +L<guestfish(1)>, +L<virt-cat(1)>, +L<virt-tar(1)>, +L<Sys::Guestfs(3)>, +L<Sys::Guestfs::Lib(3)>, +L<Sys::Virt(3)>, +L<http://libguestfs.org/>. + +=head1 AUTHOR + +Richard W.M. Jones L<http://et.redhat.com/~rjones/> + +=head1 COPYRIGHT + +Copyright (C) 2009 Red Hat Inc. + +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. -- 1.6.5.2
Richard W.M. Jones wrote:> Subject: [PATCH] New tool: virt-list-filesystems... Another neat tool. Nice.> +# Try and mount each one, to see what's mountable. > +foreach $dev (@partitions) { > + eval { $g->mount_ro ($dev, "/"); }; > + my $mountable = $@ ? 0 : 1; > + $g->umount_all (); > + if ($mountable) { > + push @fses, $dev; > + } else { > + push @not_mountable, $dev; > + } > +} > + > +foreach $dev (@fses) { > + print canonicalize($dev); > + if ($long) { > + my $fstype; > + eval { $fstype = $g->vfs_type ($dev); }; > + if ($fstype) { > + print " $fstype"; > + } else { > + print " unknown"; > + }A small stylistic suggestion: I would write the above 5 lines using the ||= idiom, like this: $fstype ||= 'unknown'; print " $fstype"; Note, that that's ok as long as you really want to use 'unknown' even when the incoming $fstype happens to evaluate to 0, too. But since that would never be a valid file system type, this use of ||= is robust.> + } > + print "\n"; > +}