X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=inspector%2Fvirt-inspector.pl;h=3557a38aa57c8032c3a1fa7f1d890d1ee91a8254;hb=f1fadb92179b68519b57680718e30a389a63d5e5;hp=6aa63ad364d3f225154d1423aef20dd66f5a55f0;hpb=215041c7178922341ecbfdb23eb203f2bb8c29c4;p=libguestfs.git diff --git a/inspector/virt-inspector.pl b/inspector/virt-inspector.pl index 6aa63ad..3557a38 100755 --- a/inspector/virt-inspector.pl +++ b/inspector/virt-inspector.pl @@ -24,11 +24,13 @@ use Pod::Usage; use Getopt::Long; use Data::Dumper; use File::Temp qw/tempdir/; +use XML::Writer; # Optional: eval "use Sys::Virt;"; eval "use XML::XPath;"; eval "use XML::XPath::XMLParser;"; +eval "use YAML::Any;"; =encoding utf8 @@ -134,6 +136,11 @@ Produce no output at all. If you select I<--xml> then you get XML output which can be fed to other programs. +=item B<--yaml> + +If you select I<--yaml> then you get YAML output which can be fed +to other programs. + =item B<--perl> If you select I<--perl> then you get Perl structures output which @@ -183,6 +190,7 @@ GetOptions ("help|?" => \$help, "text" => sub { $output = "text" }, "none" => sub { $output = "none" }, "xml" => sub { $output = "xml" }, + "yaml" => sub { $output = "yaml" }, "perl" => sub { $output = "perl" }, "fish" => sub { $output = "fish" }, "guestfish" => sub { $output = "fish" }, @@ -222,6 +230,13 @@ if (-e $ARGV[0]) { die "cannot connect to libvirt $uri\n" unless $vmm; my @doms = $vmm->list_defined_domains (); + my $isitinactive = "an inactive libvirt domain"; + if ($output ne "fish") { + # In the special case where we want read-only access to + # a domain, allow the user to specify an active domain too. + push @doms, $vmm->list_domains (); + $isitinactive = "a libvirt domain"; + } my $dom; foreach (@doms) { if ($_->get_name () eq $ARGV[0]) { @@ -229,8 +244,7 @@ if (-e $ARGV[0]) { last; } } - die "$ARGV[0] is not the name of an inactive libvirt domain\n" - unless $dom; + die "$ARGV[0] is not the name of $isitinactive\n" unless $dom; # Get the names of the image(s). my $xml = $dom->get_xml_description (); @@ -658,6 +672,7 @@ sub assign_mount_points } else { $fs->{used} = 1 } + $fs->{spec} = $spec; } } } @@ -691,6 +706,12 @@ sub find_filesystem } else { return ($_, $fses{$_}) if exists $fses{$_}; + # The following is to handle the case where an fstab entry specifies a + # specific device rather than its label or uuid, and the libguestfs + # appliance has named the device differently due to the use of a + # different driver. + # This will work as long as the underlying drivers recognise devices in + # the same order. if (m{^/dev/hd(.*)} && exists $fses{"/dev/sd$1"}) { return ("/dev/sd$1", $fses{"/dev/sd$1"}); } @@ -713,9 +734,6 @@ sub find_filesystem # we don't need to know. if ($output !~ /.*fish$/) { - # Temporary directory for use by check_for_initrd. - my $dir = tempdir (CLEANUP => 1); - my $root_dev; foreach $root_dev (sort keys %oses) { my $mounts = $oses{$root_dev}->{mounts}; @@ -730,7 +748,7 @@ if ($output !~ /.*fish$/) { check_for_kernels ($root_dev); if ($oses{$root_dev}->{os} eq "linux") { check_for_modprobe_aliases ($root_dev); - check_for_initrd ($root_dev, $dir); + check_for_initrd ($root_dev); } $g->umount_all (); @@ -831,14 +849,56 @@ sub check_for_modprobe_aliases local $_; my $root_dev = shift; - my @lines; - eval { @lines = $g->read_lines ("/etc/modprobe.conf"); }; - return if $@ || !@lines; + # Initialise augeas + my $success = 0; + $success = $g->aug_init("/", 16); + + # Register /etc/modules.conf and /etc/conf.modules to the Modprobe lens + my @results; + @results = $g->aug_match("/augeas/load/Modprobe/incl"); + + # Calculate the next index of /augeas/load/Modprobe/incl + my $i = 1; + foreach ( @results ) { + next unless m{/augeas/load/Modprobe/incl\[(\d*)]}; + $i = $1 + 1 if ($1 == $i); + } + + $success = $g->aug_set("/augeas/load/Modprobe/incl[$i]", + "/etc/modules.conf"); + $i++; + $success = $g->aug_set("/augeas/load/Modprobe/incl[$i]", + "/etc/conf.modules"); + + # Make augeas reload + $success = $g->aug_load(); my %modprobe_aliases; - foreach (@lines) { - $modprobe_aliases{$1} = $2 if /^\s*alias\s+(\S+)\s+(\S+)/; + for my $pattern qw(/files/etc/conf.modules/alias + /files/etc/modules.conf/alias + /files/etc/modprobe.conf/alias + /files/etc/modprobe.d/*/alias) { + @results = $g->aug_match($pattern); + + for my $path ( @results ) { + $path =~ m{^/files(.*)/alias(?:\[\d*\])?$} + or die("$path doesn't match augeas pattern"); + my $file = $1; + + my $alias; + $alias = $g->aug_get($path); + + my $modulename; + $modulename = $g->aug_get($path.'/modulename'); + + my %aliasinfo; + $aliasinfo{modulename} = $modulename; + $aliasinfo{augeas} = $path; + $aliasinfo{file} = $file; + + $modprobe_aliases{$alias} = \%aliasinfo; + } } $oses{$root_dev}->{modprobe_aliases} = \%modprobe_aliases; @@ -851,42 +911,22 @@ sub check_for_initrd { local $_; my $root_dev = shift; - my $dir = shift; my %initrd_modules; foreach my $initrd ($g->ls ("/boot")) { if ($initrd =~ m/^initrd-(.*)\.img$/ && $g->is_file ("/boot/$initrd")) { my $version = $1; - my @modules = (); - # We have to download these to a temporary file. - $g->download ("/boot/$initrd", "$dir/initrd"); - - my $cmd = "zcat $dir/initrd | file -"; - open P, "$cmd |" or die "$cmd: $!"; - my $lines; - { local $/ = undef; $lines =
; } - close P; - if ($lines =~ /ext\d filesystem data/) { - # Before initramfs came along, these were compressed - # ext2 filesystems. We could run another libguestfs - # instance to unpack these, but punt on them for now. (XXX) - warn "initrd image is unsupported ext2/3/4 filesystem\n"; - } - elsif ($lines =~ /cpio/) { - my $cmd = "zcat $dir/initrd | cpio --quiet -it"; - open P, "$cmd |" or die "$cmd: $!"; - while (
) {
- push @modules, $1
- if m,([^/]+)\.ko$, || m,([^/]+)\.o$,;
- }
- close P;
- unlink "$dir/initrd";
- $initrd_modules{$version} = \@modules;
- }
- else {
- # What?
- warn "unrecognized initrd image: $lines\n";
+ my @modules;
+
+ eval {
+ @modules = $g->initrd_list ("/boot/$initrd");
+ };
+ unless ($@) {
+ @modules = grep { m,([^/]+)\.ko$, || m,([^/]+)\.o$, } @modules;
+ $initrd_modules{$version} = \@modules
+ } else {
+ warn "/boot/$initrd: could not read initrd format"
}
}
}
@@ -924,6 +964,14 @@ elsif ($output eq "perl") {
print Dumper(\%oses);
}
+# YAML output
+elsif ($output eq "yaml") {
+ die "virt-inspector: no YAML support\n"
+ unless exists $INC{"YAML/Any.pm"};
+
+ print Dump(\%oses);
+}
+
# Plain text output (the default).
elsif ($output eq "text") {
output_text ();
@@ -979,7 +1027,7 @@ sub output_text_os
if (@keys) {
print " Modprobe aliases:\n";
foreach (@keys) {
- printf " %-30s %s\n", $_, $aliases{$_}
+ printf " %-30s %s\n", $_, $aliases{$_}->{modulename}
}
}
}
@@ -1024,55 +1072,70 @@ sub output_text_os
sub output_xml
{
- print "