diff options
-rw-r--r-- | TODO | 16 | ||||
-rwxr-xr-x | inspector/virt-inspector.pl | 54 | ||||
-rw-r--r-- | perl/lib/Sys/Guestfs/Lib.pm | 64 |
3 files changed, 113 insertions, 21 deletions
@@ -182,22 +182,6 @@ Swap space Allow swap space from the guest to be used. Is it a good idea? -Query guest architecture ------------------------- - -Need a way to query a binary or library file for its architecture. -Using objdump or readelf? -What about non-ELF files (eg. Windows, BSD). - -To do this properly requires some serious logic, eg. to cover Linux -and Windows we'd need objdump and i686-pc-mingw32-objdump, and more to -cover a.out, COFF and 64 bit Windows. Therefore this cannot be done -inside the daemon, and should be done by a separate, external program -similar to virt-inspector. - -Probably we should go all the way and have virt-inspector able to -determine kernel and userspace architectures of guests. - Other initrd-* commands ----------------------- diff --git a/inspector/virt-inspector.pl b/inspector/virt-inspector.pl index 9148a486..d2acf062 100755 --- a/inspector/virt-inspector.pl +++ b/inspector/virt-inspector.pl @@ -357,6 +357,7 @@ sub output_text_os print $os->{os}, " " if exists $os->{os}; print $os->{distro}, " " if exists $os->{distro}; + print $os->{arch}, " " if exists $os->{arch}; print $os->{major_version} if exists $os->{major_version}; print ".", $os->{minor_version} if exists $os->{minor_version}; print " "; @@ -415,7 +416,7 @@ sub output_text_os print __" Kernels:\n"; my @kernels = @{$os->{kernels}}; foreach (@kernels) { - print " $_->{version}\n"; + print " $_->{version} ($_->{arch})\n"; my @modules = @{$_->{modules}}; foreach (@modules) { print " $_\n"; @@ -450,6 +451,7 @@ sub output_xml_os foreach ( [ "name" => "os" ], [ "distro" => "distro" ], + [ "arch" => "arch" ], [ "major_version" => "major_version" ], [ "minor_version" => "minor_version" ], [ "package_format" => "package_format" ], @@ -531,7 +533,9 @@ sub output_xml_os $xml->startTag("kernels"); my @kernels = @{$os->{kernels}}; foreach (@kernels) { - $xml->startTag("kernel", "version" => $_->{version}); + $xml->startTag("kernel", + "version" => $_->{version}, + "arch" => $_->{arch}); $xml->startTag("modules"); my @modules = @{$_->{modules}}; foreach (@modules) { @@ -591,6 +595,8 @@ sub output_query output_query_xen_domU_kernel (); output_query_xen_pv_drivers (); output_query_virtio_drivers (); + output_query_kernel_arch (); + output_query_userspace_arch (); } =item windows=(yes|no) @@ -763,6 +769,50 @@ sub output_query_virtio_drivers print "virtio_drivers=no\n"; } +=item userspace_arch=(x86_64|...) + +Print the architecture of userspace. + +NB. For multi-boot VMs this can print several lines. + +=cut + +sub output_query_userspace_arch +{ + my %arches; + + foreach my $os (keys %$oses) { + $arches{$oses->{$os}->{arch}} = 1 if exists $oses->{$os}->{arch}; + } + + foreach (sort keys %arches) { + print "userspace_arch=$_\n"; + } +} + +=item kernel_arch=(x86_64|...) + +Print the architecture of the kernel. + +NB. For multi-boot VMs this can print several lines. + +=cut + +sub output_query_kernel_arch +{ + my %arches; + + foreach my $os (keys %$oses) { + foreach my $kernel (@{$oses->{$os}->{kernels}}) { + $arches{$kernel->{arch}} = 1 if exists $kernel->{arch}; + } + } + + foreach (sort keys %arches) { + print "kernel_arch=$_\n"; + } +} + =back =head1 SEE ALSO diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 081b4b9b..1e5638e3 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -876,6 +876,17 @@ sub _check_linux_root } $r->{fstab} = \@fstab if @fstab; } + + # Determine the architecture of this root. + my $arch; + foreach ("/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh") { + if ($g->is_file ($_)) { + $arch = file_architecture ($g, $_); + last; + } + } + + $r->{arch} = $arch if defined $arch; } # We only support NT. The control file /boot.ini contains a list of @@ -914,13 +925,30 @@ sub _check_windows_root if (defined $systemroot) { $r->{systemroot} = resolve_windows_path ($g, "/$systemroot"); - if (defined $r->{systemroot} && $use_windows_registry) { - _check_windows_registry ($g, $r, $r->{systemroot}); + if (defined $r->{systemroot}) { + _check_windows_arch ($g, $r, $r->{systemroot}); + if ($use_windows_registry) { + _check_windows_registry ($g, $r, $r->{systemroot}); + } } } } } +# Find Windows userspace arch. + +sub _check_windows_arch +{ + local $_; + my $g = shift; + my $r = shift; + my $systemroot = shift; + + my $cmd_exe = + resolve_windows_path ($g, $r->{systemroot} . "/system32/cmd.exe"); + $r->{arch} = file_architecture ($g, $cmd_exe) if $cmd_exe; +} + sub _check_windows_registry { local $_; @@ -1034,6 +1062,10 @@ The C<\%os> hash contains the following keys (any can be omitted): Operating system type, eg. "linux", "windows". +=item arch + +Operating system userspace architecture, eg. "i386", "x86_64". + =item distro Operating system distribution, eg. "debian". @@ -1118,6 +1150,7 @@ sub _get_os_version if exists $r->{root}->{package_format}; $r->{package_management} = $r->{root}->{package_management} if exists $r->{root}->{package_management}; + $r->{arch} = $r->{root}->{arch} if exists $r->{root}->{arch}; } sub _assign_mount_points @@ -1267,6 +1300,24 @@ List of applications. List of kernels. +This is a hash of kernel version =E<gt> a hash with the following keys: + +=over 4 + +=item version + +Kernel version. + +=item arch + +Kernel architecture (eg. C<x86-64>). + +=item modules + +List of modules. + +=back + =item modprobe_aliases (For Linux VMs). @@ -1359,14 +1410,21 @@ sub _check_for_kernels # List modules. my @modules; - foreach ($g->find ("/lib/modules/$_")) { + my $any_module; + my $prefix = "/lib/modules/$_"; + foreach ($g->find ($prefix)) { if (m,/([^/]+)\.ko$, || m,([^/]+)\.o$,) { + $any_module = "$prefix$_" unless defined $any_module; push @modules, $1; } } $kernel{modules} = \@modules; + # Determine kernel architecture by looking at the arch + # of any kernel module. + $kernel{arch} = file_architecture ($g, $any_module); + push @kernels, \%kernel; } } |