Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 1/7] Push $desc creation into Sys::VirtConvert::Converter->convert
This change is part of an ongoing effort to remove use of $desc and inspect the
OS directly as required during conversion.
---
lib/Sys/VirtConvert/Connection/LibVirtTarget.pm | 4 +-
lib/Sys/VirtConvert/Connection/RHEVTarget.pm | 41 +++++++++---------
lib/Sys/VirtConvert/Converter.pm | 35 ++++++++++++----
lib/Sys/VirtConvert/Converter/RedHat.pm | 45 +++++++++++--------
lib/Sys/VirtConvert/Converter/Windows.pm | 10 +++-
p2v-server/virt-p2v-server.pl | 52 ++++-------------------
v2v/virt-v2v.pl | 49 ++++------------------
7 files changed, 99 insertions(+), 137 deletions(-)
diff --git a/lib/Sys/VirtConvert/Connection/LibVirtTarget.pm
b/lib/Sys/VirtConvert/Connection/LibVirtTarget.pm
index a74f9df..b77ce1d 100644
--- a/lib/Sys/VirtConvert/Connection/LibVirtTarget.pm
+++ b/lib/Sys/VirtConvert/Connection/LibVirtTarget.pm
@@ -269,7 +269,7 @@ sub guest_exists
return 1;
}
-=item create_guest(desc, meta, config, guestcaps, output_name)
+=item create_guest(g, root, meta, config, guestcaps, output_name)
Create the guest in the target
@@ -278,7 +278,7 @@ Create the guest in the target
sub create_guest
{
my $self = shift;
- my ($desc, $meta, $config, $guestcaps, $output_name) = @_;
+ my (undef, undef, $meta, $config, $guestcaps, $output_name) = @_;
my $vmm = $self->{vmm};
diff --git a/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
b/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
index 4ebdcb9..5f0fe47 100644
--- a/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
+++ b/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
@@ -605,7 +605,7 @@ sub guest_exists
return 0;
}
-=item create_guest(desc, meta, config, guestcaps, output_name)
+=item create_guest(g, root, meta, config, guestcaps, output_name)
Create the guest in the target
@@ -614,7 +614,7 @@ Create the guest in the target
sub create_guest
{
my $self = shift;
- my ($desc, $meta, $config, $guestcaps, $output_name) = @_;
+ my ($g, $root, $meta, $config, $guestcaps, $output_name) = @_;
# Get the number of virtual cpus
my $ncpus = $meta->{cpus};
@@ -627,7 +627,7 @@ sub create_guest
my $vmuuid = rhev_util::get_uuid();
- my $ostype = _get_os_type($desc);
+ my $ostype = _get_os_type($g, $root);
my $ovf = new XML::DOM::Parser->parse(<<EOF);
<ovf:Envelope
@@ -798,23 +798,24 @@ EOF
# one of the above values in case we're wrong.
sub _get_os_type
{
- my ($desc) = @_;
+ my ($g, $root) = @_;
+
+ my $arch = $g->inspect_get_arch($root);
my $arch_suffix = '';
- if ($desc->{arch} eq 'x86_64') {
+ if ($arch eq 'x86_64') {
$arch_suffix = 'x64';
- } elsif ($desc->{arch} ne 'i386') {
- logmsg WARN, __x('Unsupported architecture: {arch}',
- arch => $desc->{arch});
+ } elsif ($arch ne 'i386') {
+ logmsg WARN, __x('Unsupported architecture: {arch}', arch =>
$arch);
return undef;
}
my $type;
- $type = _get_os_type_linux($desc, $arch_suffix)
- if ($desc->{os} eq 'linux');
- $type = _get_os_type_windows($desc, $arch_suffix)
- if ($desc->{os} eq 'windows');
+ $type = _get_os_type_linux($g, $root, $arch_suffix)
+ if ($g->inspect_get_type($root) eq 'linux');
+ $type = _get_os_type_windows($g, $root, $arch_suffix)
+ if ($g->inspect_get_type($root) eq 'windows');
return 'Unassigned' if (!defined($type));
return $type;
@@ -822,11 +823,11 @@ sub _get_os_type
sub _get_os_type_windows
{
- my ($desc, $arch_suffix) = @_;
+ my ($g, $root, $arch_suffix) = @_;
- my $major = $desc->{major_version};
- my $minor = $desc->{minor_version};
- my $product = $desc->{product_name};
+ my $major = $g->inspect_get_major_version($root);
+ my $minor = $g->inspect_get_minor_version($root);
+ my $product = $g->inspect_get_product_name($root);
if ($major == 5) {
if ($minor == 1 ||
@@ -847,7 +848,7 @@ sub _get_os_type_windows
}
if ($major == 6 && $minor == 1) {
- if ($desc->{product_variant} eq 'Client') {
+ if ($g->inspect_get_product_variant($root) eq 'Client') {
return "Windows7".$arch_suffix;
}
@@ -861,10 +862,10 @@ sub _get_os_type_windows
sub _get_os_type_linux
{
- my ($desc, $arch_suffix) = @_;
+ my ($g, $root, $arch_suffix) = @_;
- my $distro = $desc->{distro};
- my $major = $desc->{major_version};
+ my $distro = $g->inspect_get_distro($root);
+ my $major = $g->inspect_get_major_version($root);
# XXX: RHEV 2.2 doesn't support a RHEL 6 target, however RHEV 2.3+
will.
# For the moment, we set RHEL 6 to be 'OtherLinux', however we will
need to
diff --git a/lib/Sys/VirtConvert/Converter.pm b/lib/Sys/VirtConvert/Converter.pm
index cfee3da..28c57d5 100644
--- a/lib/Sys/VirtConvert/Converter.pm
+++ b/lib/Sys/VirtConvert/Converter.pm
@@ -40,7 +40,7 @@ Sys::VirtConvert::Converter - Convert a guest to run on KVM
use Sys::VirtConvert::Converter;
- Sys::VirtConvert::Converter->convert($g, $config, $desc, $meta);
+ Sys::VirtConvert::Converter->convert($g, $config, $root, $meta);
=head1 DESCRIPTION
@@ -51,7 +51,7 @@ guest OS, and uses it to convert the guest to run on KVM.
=over
-=item Sys::VirtConvert::Converter->convert(g, config, desc, meta)
+=item Sys::VirtConvert::Converter->convert(g, config, root, meta)
Instantiate an appropriate backend and call convert on it.
@@ -65,9 +65,9 @@ A libguestfs handle to the target.
An initialised Sys::VirtConvert::Config object.
-=item desc
+=item root
-The OS description (see virt-v2v.pl:inspect_guest).
+The root device of the os to be converted.
=item meta
@@ -81,18 +81,37 @@ sub convert
{
my $class = shift;
- my ($g, $config, $desc, $meta) = @_;
+ my ($g, $config, $root, $meta) = @_;
croak("convert called without g argument") unless defined($g);
croak("convert called without config argument") unless
defined($config);
- croak("convert called without desc argument") unless
defined($desc);
+ croak("convert called without root argument") unless
defined($root);
croak("convert called without meta argument") unless
defined($meta);
my $guestcaps;
+ # Mount up the disks.
+ my %fses = $g->inspect_get_mountpoints ($root);
+ my @fses = sort { length $a <=> length $b } keys %fses;
+ foreach (@fses) {
+ eval { $g->mount_options ("", $fses{$_}, $_) };
+ print __x("{e} (ignored)\n", e => $@) if $@;
+ }
+
+ # Construct the "$desc" hashref which contains the main features
+ # found by inspection.
+ my %desc;
+
+ $desc{os} = $g->inspect_get_type($root);
+ $desc{distro} = $g->inspect_get_distro($root);
+ $desc{product_name} = $g->inspect_get_product_name($root);
+ $desc{major_version} = $g->inspect_get_major_version($root);
+ $desc{minor_version} = $g->inspect_get_minor_version($root);
+ $desc{arch} = $g->inspect_get_arch($root);
+
# Find a module which can convert the guest and run it
foreach my $module ($class->modules()) {
- if($module->can_handle($desc)) {
- $guestcaps = $module->convert($g, $config, $desc, $meta);
+ if($module->can_handle(\%desc)) {
+ $guestcaps = $module->convert($g, $root, $config, \%desc,
$meta);
last;
}
}
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm
b/lib/Sys/VirtConvert/Converter/RedHat.pm
index cd7bde1..8a6ff6b 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -68,7 +68,7 @@ sub can_handle
$desc->{distro} =~ /^(rhel|fedora)$/);
}
-=item Sys::VirtConvert::Converter::RedHat->convert(g, config, meta, desc)
+=item Sys::VirtConvert::Converter::RedHat->convert(g, root, config, meta,
desc)
Convert a Red Hat based guest. Assume that can_handle has previously returned
1.
@@ -78,13 +78,17 @@ Convert a Red Hat based guest. Assume that can_handle has
previously returned 1.
An initialised Sys::Guestfs handle
+=item root
+
+The root device of this operating system.
+
=item config
An initialised Sys::VirtConvert::Config
=item desc
-A description of the guest OS (see virt-v2v.pl:inspect_guest).
+A description of the guest OS (see Sys::VirtConvert::Converter->convert()).
=item meta
@@ -98,8 +102,9 @@ sub convert
{
my $class = shift;
- my ($g, $config, $desc, $meta) = @_;
+ my ($g, $root, $config, $desc, $meta) = @_;
croak("convert called without g argument") unless defined($g);
+ croak("convert called without root argument") unless
defined($root);
croak("convert called without config argument") unless
defined($config);
croak("convert called without desc argument") unless
defined($desc);
croak("convert called without meta argument") unless
defined($meta);
@@ -112,7 +117,7 @@ sub convert
# Un-configure HV specific attributes which don't require a direct
# replacement
- _unconfigure_hv($g, $desc);
+ _unconfigure_hv($g, $root, $desc);
# Try to install the virtio capability
my $virtio = _install_capability('virtio', $g, $config, $meta,
$desc);
@@ -125,7 +130,7 @@ sub convert
_configure_display_driver($g);
_remap_block_devices($meta, $virtio, $g, $desc);
_configure_kernel_modules($g, $desc, $virtio, $modpath);
- _configure_boot($kernel, $virtio, $g, $desc);
+ _configure_boot($kernel, $virtio, $g, $root, $desc);
my %guestcaps;
@@ -850,18 +855,18 @@ sub _configure_kernel
sub _configure_boot
{
- my ($kernel, $virtio, $g, $desc) = @_;
+ my ($kernel, $virtio, $g, $root, $desc) = @_;
if($virtio) {
# The order of modules here is deliberately the same as the order
# specified in the postinstall script of kmod-virtio in RHEL3. The
# reason is that the probing order determines the major number of vdX
# block devices. If we change it, RHEL 3 KVM guests won't boot.
- _prepare_bootable($g, $desc, $kernel, "virtio",
"virtio_ring",
- "virtio_blk",
"virtio_net",
- "virtio_pci");
+ _prepare_bootable($g, $root, $desc, $kernel, "virtio",
"virtio_ring",
+ "virtio_blk",
"virtio_net",
+ "virtio_pci");
} else {
- _prepare_bootable($g, $desc, $kernel, "sym53c8xx");
+ _prepare_bootable($g, $root, $desc, $kernel, "sym53c8xx");
}
}
@@ -934,21 +939,23 @@ sub _get_application_owner
sub _unconfigure_hv
{
- my ($g, $desc) = @_;
+ my ($g, $root, $desc) = @_;
- _unconfigure_xen($g, $desc);
- _unconfigure_vmware($g, $desc);
+ my @apps = $g->inspect_list_applications($root);
+
+ _unconfigure_xen($g, $desc, \@apps);
+ _unconfigure_vmware($g, $desc, \@apps);
}
# Unconfigure Xen specific guest modifications
sub _unconfigure_xen
{
- my ($g, $desc) = @_;
+ my ($g, $desc, $apps) = @_;
my $found_kmod = 0;
# Look for kmod-xenpv-*, which can be found on RHEL 3 machines
- foreach my $app (@{$desc->{apps}}) {
+ foreach my $app (@$apps) {
my $name = $app->{app_name};
if($name =~ /^kmod-xenpv(-.*)?$/) {
@@ -1005,10 +1012,10 @@ sub _unconfigure_xen
# Unconfigure VMware specific guest modifications
sub _unconfigure_vmware
{
- my ($g, $desc) = @_;
+ my ($g, $desc, $apps) = @_;
# Uninstall VMwareTools
- foreach my $app (@{$desc->{apps}}) {
+ foreach my $app (@$apps) {
my $name = $app->{app_name};
if ($name eq "VMwareTools") {
@@ -2161,7 +2168,7 @@ sub _drivecmp
sub _prepare_bootable
{
- my ($g, $desc, $version, @modules) = @_;
+ my ($g, $root, $desc, $version, @modules) = @_;
# Find the grub entry for the given kernel
my $initrd;
@@ -2255,7 +2262,7 @@ sub _prepare_bootable
# internal variable in mkinitrd, and is therefore extremely nasty
# and applicable only to a particular version of mkinitrd.
if ($desc->{distro} eq 'rhel' &&
$desc->{major_version} eq '4') {
- push(@env, 'root_lvm=1') if
($g->is_lv($desc->{root_device}));
+ push(@env, 'root_lvm=1') if ($g->is_lv($root));
}
$g->sh(join(' ', @env).' /sbin/mkinitrd
'.join(' ', @module_args).
diff --git a/lib/Sys/VirtConvert/Converter/Windows.pm
b/lib/Sys/VirtConvert/Converter/Windows.pm
index b4eae74..321f797 100644
--- a/lib/Sys/VirtConvert/Converter/Windows.pm
+++ b/lib/Sys/VirtConvert/Converter/Windows.pm
@@ -80,7 +80,7 @@ sub can_handle
return ($desc->{os} eq 'windows');
}
-=item Sys::VirtConvert::Converter::Windows->convert(g, config, desc, meta)
+=item Sys::VirtConvert::Converter::Windows->convert(g, root, config, desc,
meta)
(Pre-)convert a Windows guest. Assume that can_handle has previously
returned 1.
@@ -91,13 +91,17 @@ returned 1.
A libguestfs handle to the target.
+=item root
+
+The root device of this operating system.
+
=item config
An initialised Sys::VirtConvert::Config object.
=item desc
-A description of the guest OS (see virt-v2v.pl:inspect_guest).
+A description of the guest OS (see Sys::VirtConvert::Converter->convert).
=item meta
@@ -111,7 +115,7 @@ sub convert
{
my $class = shift;
- my ($g, $config, $desc, undef) = @_;
+ my ($g, undef, $config, $desc, undef) = @_;
croak("convert called without g argument") unless defined($g);
croak("convert called without config argument") unless
defined($config);
croak("convert called without desc argument") unless
defined($desc);
diff --git a/p2v-server/virt-p2v-server.pl b/p2v-server/virt-p2v-server.pl
index 5b1cb68..c193e1c 100755
--- a/p2v-server/virt-p2v-server.pl
+++ b/p2v-server/virt-p2v-server.pl
@@ -306,8 +306,6 @@ sub convert
my @localpaths = map { $_->{local_path} } @{$meta->{disks}};
my $g;
- my $desc;
- my $guestcaps;
eval {
$g = new Sys::VirtConvert::GuestfsHandle(
\@localpaths,
@@ -315,10 +313,11 @@ sub convert
$target->isa('Sys::VirtConvert::Connection::RHEVTarget')
);
- $desc = inspect_guest($g);
- $guestcaps - Sys::VirtConvert::Converter->convert($g,
$config, $desc, $meta);
- $target->create_guest($desc, $meta, $config, $guestcaps,
$meta->{name});
+ my $root = inspect_guest($g);
+ my $guestcaps + Sys::VirtConvert::Converter->convert($g,
$config, $root, $meta);
+ $target->create_guest($g, $root, $meta, $config, $guestcaps,
+ $meta->{name});
if($guestcaps->{block} eq 'virtio' &&
$guestcaps->{net} eq 'virtio') {
logmsg NOTICE, __x('{name} configured with virtio
drivers.',
@@ -373,14 +372,13 @@ END {
}
# Perform guest inspection using the libguestfs core inspection API.
-# Returns a hashref ("$desc") which contains the main features from
-# inspection.
+# Returns the root device of the os to be converted.
sub inspect_guest
{
my $g = shift;
# Get list of roots, sorted
- my @roots = $g->inspect_os ();
+ my @roots = $g->inspect_os();
@roots = sort @roots;
# Only work on single-root operating systems.
@@ -390,41 +388,7 @@ sub inspect_guest
v2vdie __('Multiboot operating systems are not supported.')
if @roots > 1;
- my $root_dev = $roots[0];
-
- # Mount up the disks.
- my %fses = $g->inspect_get_mountpoints ($root_dev);
- my @fses = sort { length $a <=> length $b } keys %fses;
- foreach (@fses) {
- eval { $g->mount_options ("", $fses{$_}, $_) };
- print __x("{e} (ignored)\n", e => $@) if $@;
- }
-
- # Construct the "$desc" hashref which contains the main features
- # found by inspection.
- my %desc;
-
- $desc{root_device} = $root_dev;
-
- $desc{os} = $g->inspect_get_type ($root_dev);
- $desc{distro} = $g->inspect_get_distro ($root_dev);
- $desc{product_name} = $g->inspect_get_product_name ($root_dev);
- $desc{product_variant} = $g->inspect_get_product_variant ($root_dev);
- $desc{major_version} = $g->inspect_get_major_version ($root_dev);
- $desc{minor_version} = $g->inspect_get_minor_version ($root_dev);
- $desc{arch} = $g->inspect_get_arch ($root_dev);
-
- # Notes:
- # (1) Filesystems have to be mounted for this to work. Do not
- # move this code over the filesystem mounting code above.
- # (2) For RPM-based distros, new libguestfs inspection code
- # is only able to populate the 'app_name' field (old Perl code
- # populated a lot more). Fortunately this is the only field
- # that the code currently uses.
- my @apps = $g->inspect_list_applications ($root_dev);
- $desc{apps} = \@apps;
-
- return \%desc;
+ return $roots[0];
}
sub p2v_receive
diff --git a/v2v/virt-v2v.pl b/v2v/virt-v2v.pl
index 6e73102..3d71afe 100755
--- a/v2v/virt-v2v.pl
+++ b/v2v/virt-v2v.pl
@@ -504,14 +504,14 @@ if (defined($transferiso)) {
}
my $guestcaps;
-my $desc;
+my $root;
eval {
# Inspect the guest
- $desc = inspect_guest($g, $transferdev);
+ $root = inspect_guest($g, $transferdev);
# Modify the guest and its metadata
$guestcaps - Sys::VirtConvert::Converter->convert($g, $config,
$desc, $meta);
+ Sys::VirtConvert::Converter->convert($g, $config, $root, $meta);
};
# If any of the above commands result in failure, we need to ensure that the
@@ -523,9 +523,9 @@ if ($@) {
die($err);
}
-$g->close();
+$target->create_guest($g, $root, $meta, $config, $guestcaps, $output_name);
-$target->create_guest($desc, $meta, $config, $guestcaps, $output_name);
+$g->close();
if($guestcaps->{block} eq 'virtio' && $guestcaps->{net}
eq 'virtio') {
logmsg NOTICE, __x('{name} configured with virtio drivers.',
@@ -561,15 +561,14 @@ sub signal_exit
}
# Perform guest inspection using the libguestfs core inspection API.
-# Returns a hashref ("$desc") which contains the main features from
-# inspection.
+# Returns the root device of the os to be converted.
sub inspect_guest
{
my $g = shift;
my $transferdev = shift;
# Get list of roots, sorted.
- my @roots = $g->inspect_os ();
+ my @roots = $g->inspect_os();
# Filter out the transfer device from the results of inspect_os
# There's a libguestfs bug (fixed upstream) which meant the transfer
ISO
@@ -655,39 +654,7 @@ sub inspect_guest
}
}
- # Mount up the disks.
- my %fses = $g->inspect_get_mountpoints ($root_dev);
- my @fses = sort { length $a <=> length $b } keys %fses;
- foreach (@fses) {
- eval { $g->mount_options ("", $fses{$_}, $_) };
- print __x("{e} (ignored)\n", e => $@) if $@;
- }
-
- # Construct the "$desc" hashref which contains the main features
- # found by inspection.
- my %desc;
-
- $desc{root_device} = $root_dev;
-
- $desc{os} = $g->inspect_get_type ($root_dev);
- $desc{distro} = $g->inspect_get_distro ($root_dev);
- $desc{product_name} = $g->inspect_get_product_name ($root_dev);
- $desc{product_variant} = $g->inspect_get_product_variant ($root_dev);
- $desc{major_version} = $g->inspect_get_major_version ($root_dev);
- $desc{minor_version} = $g->inspect_get_minor_version ($root_dev);
- $desc{arch} = $g->inspect_get_arch ($root_dev);
-
- # Notes:
- # (1) Filesystems have to be mounted for this to work. Do not
- # move this code over the filesystem mounting code above.
- # (2) For RPM-based distros, new libguestfs inspection code
- # is only able to populate the 'app_name' field (old Perl code
- # populated a lot more). Fortunately this is the only field
- # that the code currently uses.
- my @apps = $g->inspect_list_applications ($root_dev);
- $desc{apps} = \@apps;
-
- return \%desc;
+ return $root_dev;
}
=head1 PREPARING TO CONVERT A GUEST
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 2/7] Check for availability of inspect_get_product_variant
F14 doesn't have inspect_get_product_variant (F15 does). The only thing
it's
needed for is differentiating Win7 from Win2k8r2 when writing to RHEV, so work
round it if it's not there.
---
lib/Sys/VirtConvert/Connection/RHEVTarget.pm | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
b/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
index 5f0fe47..687f745 100644
--- a/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
+++ b/lib/Sys/VirtConvert/Connection/RHEVTarget.pm
@@ -848,7 +848,11 @@ sub _get_os_type_windows
}
if ($major == 6 && $minor == 1) {
- if ($g->inspect_get_product_variant($root) eq 'Client') {
+ # This API is new in libguestfs 1.10
+ # If it's not present, we can't differentiate between Win7 and
Win2k8r2
+ if ($g->can('inspect_get_product_variant') &&
+ $g->inspect_get_product_variant($root) eq 'Client')
+ {
return "Windows7".$arch_suffix;
}
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 3/7] RedHat: Don't add kernel entry to $desc for unidentified kernel
---
lib/Sys/VirtConvert/Converter/RedHat.pm | 97 +++++++++++++++----------------
1 files changed, 47 insertions(+), 50 deletions(-)
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm
b/lib/Sys/VirtConvert/Converter/RedHat.pm
index 8a6ff6b..5704fd8 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -621,67 +621,64 @@ sub _init_kernels
if($@) {
warn __x("Grub entry {title} has no kernel",
title => $config{title});
+ next;
}
- # Check we've got a kernel entry
- if(defined($grub_kernel)) {
- my $path = "$grub$grub_kernel";
+ my $path = "$grub$grub_kernel";
- # Reconstruct the kernel command line
- my @args = ();
- foreach my $arg
($g->aug_match("$bootable/kernel/*")) {
- $arg =~ m{/kernel/([^/]*)$}
- or die("Unexpected return from aug_match:
$arg");
+ # Reconstruct the kernel command line
+ my @args = ();
+ foreach my $arg ($g->aug_match("$bootable/kernel/*"))
{
+ $arg =~ m{/kernel/([^/]*)$}
+ or die("Unexpected return from aug_match: $arg");
- my $name = $1;
- my $value;
- eval { $value = $g->aug_get($arg); };
+ my $name = $1;
+ my $value;
+ eval { $value = $g->aug_get($arg); };
- if(defined($value)) {
- push(@args, "$name=$value");
- } else {
- push(@args, $name);
- }
- }
- $config{cmdline} = join(' ', @args) if(scalar(@args)
> 0);
-
- my $kernel;
- if ($g->exists($path)) {
- $kernel = _inspect_linux_kernel($g, $path);
+ if(defined($value)) {
+ push(@args, "$name=$value");
} else {
- warn __x("grub refers to {path}, which doesn't
exist\n",
- path => $path);
+ push(@args, $name);
}
+ }
+ $config{cmdline} = join(' ', @args) if(scalar(@args) >
0);
- # Check the kernel was recognised
- if(defined($kernel)) {
- # Put this kernel on the top level kernel list
- $desc->{kernels} ||= [];
- push(@{$desc->{kernels}}, $kernel);
-
- $config{kernel} = $kernel;
-
- # Look for an initrd entry
- my $initrd;
- eval {
- $initrd = $g->aug_get("$bootable/initrd");
- };
-
- unless($@) {
- $config{initrd} -
_inspect_initrd($g, $desc, "$grub$initrd",
- $kernel->{version});
- } else {
- warn __x("Grub entry {title} does not specify an
".
- "initrd", title =>
$config{title});
- }
- }
+ my $kernel;
+ if ($g->exists($path)) {
+ $kernel = _inspect_linux_kernel($g, $path);
+ } else {
+ warn __x("grub refers to {path}, which doesn't
exist\n",
+ path => $path);
+ }
+
+ # Check the kernel was recognised
+ next unless defined($kernel);
+
+ # Put this kernel on the top level kernel list
+ $desc->{kernels} ||= [];
+ push(@{$desc->{kernels}}, $kernel);
+
+ $config{kernel} = $kernel;
+
+ # Look for an initrd entry
+ my $initrd;
+ eval {
+ $initrd = $g->aug_get("$bootable/initrd");
+ };
+
+ unless($@) {
+ $config{initrd} + _inspect_initrd($g, $desc,
"$grub$initrd",
+ $kernel->{version});
+ } else {
+ warn __x("Grub entry {title} does not specify an ".
+ "initrd", title => $config{title});
}
push(@configs, \%config);
}
-
# Create the top level boot entry
my %boot;
$boot{configs} = \@configs;
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 4/7] RedHat: Don't die if we can't determine anything about an installed kernel
Assume we need to upgrade the kernel if we can't automatically detect
anything
about any installed kernel.
---
lib/Sys/VirtConvert/Converter/RedHat.pm | 121 +++++++++++++++++--------------
1 files changed, 66 insertions(+), 55 deletions(-)
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm
b/lib/Sys/VirtConvert/Converter/RedHat.pm
index 5704fd8..456110b 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -1113,66 +1113,80 @@ sub _install_capability
# Kernels are special
if ($name eq 'kernel') {
- my ($kernel_pkg, $kernel_rpmver, $kernel_arch) + my
($kernel_pkg, $kernel_arch, $kernel_rpmver)
_discover_kernel($desc);
- my ($kernel_epoch, $kernel_ver, $kernel_release);
- eval {
- ($kernel_epoch, $kernel_ver, $kernel_release) -
_parse_evr($kernel_rpmver);
- };
- if ($@) {
- # Don't die here, just make best effort to do a version
- # comparison by directly comparing the full strings
- $kernel_epoch = undef;
- $kernel_ver = $kernel_rpmver;
- $kernel_release = undef;
-
- $min_epoch = undef;
- $min_version = $props->{minversion};
- $min_release = undef;
+ # If we didn't establish a kernel version, assume we have to
upgrade
+ # it.
+ if (!defined($kernel_rpmver)) {
+ $kernel = [$kernel_pkg, $kernel_arch];
}
- # If the guest is using a Xen PV kernel, choose an appropriate
- # normal kernel replacement
- if ($kernel_pkg eq "kernel-xen" || $kernel_pkg eq
"kernel-xenU") {
- $kernel_pkg -
_get_replacement_kernel_name($kernel_arch, $desc, $meta);
-
- # Check if we've got already got an appropriate kernel
- my ($installed) -
_get_installed("$kernel_pkg.$kernel_arch", $g);
+ else {
+ my ($kernel_epoch, $kernel_ver, $kernel_release);
+ eval {
+ ($kernel_epoch, $kernel_ver, $kernel_release) +
_parse_evr($kernel_rpmver);
+ };
+ if ($@) {
+ # Don't die here, just make best effort to do a version
+ # comparison by directly comparing the full strings
+ $kernel_epoch = undef;
+ $kernel_ver = $kernel_rpmver;
+ $kernel_release = undef;
+
+ $min_epoch = undef;
+ $min_version = $props->{minversion};
+ $min_release = undef;
+ }
- if (!defined($installed) ||
- _evr_cmp($installed->[0], $installed->[1],
$installed->[2],
- $min_epoch, $min_version, $min_release) < 0)
+ # If the guest is using a Xen PV kernel, choose an appropriate
+ # normal kernel replacement
+ if ($kernel_pkg eq "kernel-xen" || $kernel_pkg eq
"kernel-xenU")
{
- # filter out xen/xenU from release field
- if (defined($kernel_release) &&
- $kernel_release =~ /^(\S+?)(xen)?(U)?$/)
- {
- $kernel_release = $1;
- }
+ $kernel_pkg +
_get_replacement_kernel_name($kernel_arch, $desc,
+ $meta);
- # If the guest kernel is new enough, but PV, try to replace
- # it with an equivalent version FV kernel
- if (_evr_cmp($kernel_epoch, $kernel_ver, $kernel_release,
- $min_epoch, $min_version, $min_release) >=
0) {
- $kernel = [$kernel_pkg, $kernel_arch,
- $kernel_epoch, $kernel_ver,
$kernel_release];
- }
+ # Check if we've got already got an appropriate kernel
+ my ($inst) +
_get_installed("$kernel_pkg.$kernel_arch", $g);
- # Otherwise, just grab the latest
- else {
- $kernel = [$kernel_pkg, $kernel_arch];
+ if (!defined($inst) ||
+ _evr_cmp($inst->[0], $inst->[1], $inst->[2],
+ $min_epoch, $min_version, $min_release) <
0)
+ {
+ # filter out xen/xenU from release field
+ if (defined($kernel_release) &&
+ $kernel_release =~ /^(\S+?)(xen)?(U)?$/)
+ {
+ $kernel_release = $1;
+ }
+
+ # If the guest kernel is new enough, but PV, try to
+ # replace it with an equivalent version FV kernel
+ if (_evr_cmp($kernel_epoch, $kernel_ver,
+ $kernel_release,
+ $min_epoch, $min_version,
+ $min_release) >= 0)
+ {
+ $kernel = [$kernel_pkg, $kernel_arch,
+ $kernel_epoch, $kernel_ver,
+ $kernel_release];
+ }
+
+ # Otherwise, just grab the latest
+ else {
+ $kernel = [$kernel_pkg, $kernel_arch];
+ }
}
}
- }
- # If the kernel is too old, grab the latest replacement
- elsif (_evr_cmp($kernel_epoch, $kernel_ver, $kernel_release,
- $min_epoch, $min_version, $min_release) < 0) {
- $kernel = [$kernel_pkg, $kernel_arch];
+ # If the kernel is too old, grab the latest replacement
+ elsif (_evr_cmp($kernel_epoch, $kernel_ver, $kernel_release,
+ $min_epoch, $min_version, $min_release) < 0)
{
+ $kernel = [$kernel_pkg, $kernel_arch];
+ }
}
}
@@ -1557,8 +1571,8 @@ sub _discover_kernel
# Get a current bootable kernel, preferrably the default
my $kernel_pkg;
- my $kernel_ver;
my $kernel_arch;
+ my $kernel_ver;
foreach my $i (@configs) {
my $config = $boot->{configs}->[$i];
@@ -1587,14 +1601,11 @@ sub _discover_kernel
# directly detected
$kernel_arch = $desc->{arch} if (!defined($kernel_arch));
- v2vdie __('Unable to determine a kernel architecture for this
guest.')
- unless defined($kernel_arch);
-
# We haven't supported anything other than i686 for the kernel on 32
bit for
# a very long time.
$kernel_arch = 'i686' if ('i386' eq $kernel_arch);
- return ($kernel_pkg, $kernel_ver, $kernel_arch);
+ return ($kernel_pkg, $kernel_arch, $kernel_ver);
}
sub _get_replacement_kernel_name
@@ -1665,7 +1676,7 @@ sub _install_good_kernel
{
my ($g, $config, $desc, $meta) = @_;
- my ($kernel_pkg, $kernel_rpmver, $kernel_arch) = _discover_kernel($desc);
+ my ($kernel_pkg, $kernel_arch, undef) = _discover_kernel($desc);
# If the guest is using a Xen PV kernel, choose an appropriate
# normal kernel replacement
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 5/7] RedHat: Check which filesystem the grub configuration is on
---
lib/Sys/VirtConvert/Converter/RedHat.pm | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm
b/lib/Sys/VirtConvert/Converter/RedHat.pm
index 456110b..82d52de 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -112,7 +112,7 @@ sub convert
_init_selinux($g);
_init_augeas($g);
_init_modprobe_aliases($g, $desc);
- _init_kernels($g, $desc);
+ _init_kernels($g, $root, $desc);
my $modpath = _init_modpath($g);
# Un-configure HV specific attributes which don't require a direct
@@ -583,17 +583,26 @@ sub _list_kernels
sub _init_kernels
{
- my ($g, $desc) = @_;
+ my ($g, $root, $desc) = @_;
if ($desc->{os} eq "linux") {
# Iterate over entries in grub.conf, populating $desc->{boot}
# For every kernel we find, inspect it and add to $desc->{kernels}
- # All known past and present Red Hat-based distros mount a
- # boot partition on /boot. We may have to revisit this if
- # this assumption changes in future. (Old Perl inspection
- # code used to try to detect this setting).
- my $grub = "/boot";
+ # Find the path which needs to be prepended to paths in grub.conf to
+ # make them absolute
+ # Default to / (no prefix required)
+ my $grub = "";
+
+ # Look for the most specific mount point discovered
+ my %mounts = $g->inspect_get_mountpoints($root);
+ foreach my $path qw(/boot/grub /boot) {
+ if (exists($mounts{$path})) {
+ $grub = $path;
+ last;
+ }
+ }
+
my $grub_conf = "/etc/grub.conf";
my @boot_configs;
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 6/7] Fix logging of error messages in augeas_error
---
lib/Sys/VirtConvert/Util.pm | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Sys/VirtConvert/Util.pm b/lib/Sys/VirtConvert/Util.pm
index 94211a5..b74d750 100644
--- a/lib/Sys/VirtConvert/Util.pm
+++ b/lib/Sys/VirtConvert/Util.pm
@@ -121,8 +121,8 @@ sub augeas_error
chomp($msg);
- v2vdie $msg if length($msg) > 0;
- v2vdie $err;
+ v2vdie($msg) if length($msg) > 0;
+ v2vdie($err);
}
--
1.7.4.4
Matthew Booth
2011-Apr-26 16:03 UTC
[Libguestfs] [PATCH 7/7] RedHat: Use whichever of /boot/grub/{grub.conf, menu.lst} is available
---
lib/Sys/VirtConvert/Converter/RedHat.pm | 140 ++++++++++++++++--------------
1 files changed, 75 insertions(+), 65 deletions(-)
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm
b/lib/Sys/VirtConvert/Converter/RedHat.pm
index 82d52de..4b8467a 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -109,10 +109,13 @@ sub convert
croak("convert called without desc argument") unless
defined($desc);
croak("convert called without meta argument") unless
defined($meta);
+ _init_grub($g, $root, $desc);
+ my $grub_conf = $desc->{boot}->{grub_conf};
+
_init_selinux($g);
- _init_augeas($g);
+ _init_augeas($g, $grub_conf);
_init_modprobe_aliases($g, $desc);
- _init_kernels($g, $root, $desc);
+ _init_kernels($g, $desc);
my $modpath = _init_modpath($g);
# Un-configure HV specific attributes which don't require a direct
@@ -126,7 +129,7 @@ sub convert
my $kernel = _configure_kernel($virtio, $g, $config, $desc, $meta);
# Configure the rest of the system
- _configure_console($g);
+ _configure_console($g, $grub_conf);
_configure_display_driver($g);
_remap_block_devices($meta, $virtio, $g, $desc);
_configure_kernel_modules($g, $desc, $virtio, $modpath);
@@ -154,18 +157,49 @@ sub _init_selinux
$g->touch('/.autorelabel');
}
+sub _init_grub
+{
+ my ($g, $root, $desc) = @_;
+
+ # Find the path which needs to be prepended to paths in grub.conf to
+ # make them absolute
+ # Default to / (no prefix required)
+ my $grub = "";
+
+ # Look for the most specific mount point discovered
+ my %mounts = $g->inspect_get_mountpoints($root);
+ foreach my $path qw(/boot/grub /boot) {
+ if (exists($mounts{$path})) {
+ $grub = $path;
+ last;
+ }
+ }
+
+ my $grub_conf;
+ foreach my $path qw(boot/grub/grub.conf boot/grub/menu.lst) {
+ if ($g->exists("/$path")) {
+ $grub_conf = $path;
+ last;
+ }
+ }
+
+ $desc->{boot} ||= {};
+ $desc->{boot}->{grub_fs} = $grub;
+ $desc->{boot}->{grub_conf} = $grub_conf;
+}
+
sub _init_augeas
{
- my ($g) = @_;
+ my ($g, $grub_conf) = @_;
# Initialise augeas
eval {
$g->aug_init("/", 1);
- # Check if /boot/grub/menu.lst is included by the Grub lens
+ # Check grub_conf is included by the Grub lens
my $found = 0;
foreach my $incl ($g->aug_match("/augeas/load/Grub/incl"))
{
- if ($g->aug_get($incl) eq '/boot/grub/menu.lst') {
+ if ($g->aug_get($incl) eq $grub_conf) {
$found = 1;
last;
}
@@ -173,12 +207,11 @@ sub _init_augeas
# If it wasn't there, add it
unless ($found) {
- $g->aug_set("/augeas/load/Grub/incl[last()+1]",
- "/boot/grub/menu.lst");
- }
+ $g->aug_set("/augeas/load/Grub/incl[last()+1]",
$grub_conf);
- # Make augeas pick up the new configuration
- $g->aug_load();
+ # Make augeas pick up the new configuration
+ $g->aug_load();
+ }
};
# The augeas calls will die() on any error.
@@ -437,7 +470,7 @@ sub _configure_kernel_modules
# /dev/ttyS0 for RHEL 6 anyway.
sub _configure_console
{
- my ($g) = @_;
+ my ($g, $grub_conf) = @_;
# Look for gettys which use xvc0 or hvc0
# RHEL 6 doesn't use /etc/inittab, but this doesn't hurt
@@ -462,7 +495,7 @@ sub _configure_console
# Update any kernel console lines
foreach my $augpath
-
($g->aug_match("/files/boot/grub/menu.lst/title/kernel/console"))
+ ($g->aug_match("/files/$grub_conf/title/kernel/console"))
{
my $console = $g->aug_get($augpath);
if ($console =~ /\b(x|h)vc0\b/) {
@@ -524,10 +557,12 @@ sub _list_kernels
{
my ($g, $desc) = @_;
+ my $grub_conf = $desc->{boot}->{grub_conf};
+
# Get the default kernel from grub if it's set
my $default;
eval {
- $default = $g->aug_get('/files/boot/grub/menu.lst/default');
+ $default = $g->aug_get("/files/$grub_conf/default");
};
# Doesn't matter if get fails
@@ -537,10 +572,9 @@ sub _list_kernels
# Look for a kernel, starting with the default
my @paths;
eval {
- push(@paths, $g->aug_match("/files/boot/grub/menu.lst/".
- "title[$default]/kernel"))
+ push(@paths,
$g->aug_match("/files/$grub_conf/title[$default]/kernel"))
if defined($default);
- push(@paths,
$g->aug_match('/files/boot/grub/menu.lst/title/kernel'));
+ push(@paths,
$g->aug_match("/files/$grub_conf/title/kernel"));
};
augeas_error($g, $@) if ($@);
@@ -583,27 +617,14 @@ sub _list_kernels
sub _init_kernels
{
- my ($g, $root, $desc) = @_;
+ my ($g, $desc) = @_;
if ($desc->{os} eq "linux") {
# Iterate over entries in grub.conf, populating $desc->{boot}
# For every kernel we find, inspect it and add to $desc->{kernels}
- # Find the path which needs to be prepended to paths in grub.conf to
- # make them absolute
- # Default to / (no prefix required)
- my $grub = "";
-
- # Look for the most specific mount point discovered
- my %mounts = $g->inspect_get_mountpoints($root);
- foreach my $path qw(/boot/grub /boot) {
- if (exists($mounts{$path})) {
- $grub = $path;
- last;
- }
- }
-
- my $grub_conf = "/etc/grub.conf";
+ my $grub = $desc->{boot}->{grub_fs};
+ my $grub_conf = $desc->{boot}->{grub_conf};
my @boot_configs;
@@ -689,16 +710,13 @@ sub _init_kernels
}
# Create the top level boot entry
- my %boot;
- $boot{configs} = \@configs;
- $boot{grub_fs} = $grub;
+ $desc->{boot} ||= {};
+ my $boot = $desc->{boot};
- # Add the default configuration
- eval {
- $boot{default} =
$g->aug_get("/files/$grub_conf/default");
- };
+ $boot->{configs} = \@configs;
- $desc->{boot} = \%boot;
+ # Add the default configuration
+ eval { $boot->{default} =
$g->aug_get("/files/$grub_conf/default") };
}
}
@@ -1739,14 +1757,13 @@ sub _check_grub
{
my ($version, $kernel, $g, $desc) = @_;
- my $grubfs = $desc->{boot}->{grub_fs};
- my $prefix = $grubfs eq '/boot' ? '' : '/boot';
+ my $grub_conf = $desc->{boot}->{grub_conf};
+ my $grubfs = $desc->{boot}->{grub_fs};
+ my $prefix = $grubfs eq '/boot' ? '' :
'/boot';
# Nothing to do if there's already a grub entry
return if eval {
- foreach my $augpath
-
($g->aug_match('/files/boot/grub/menu.lst/title/kernel'))
- {
+ foreach my $augpath
($g->aug_match("/files/$grub_conf/title/kernel")) {
return 1 if ($grubfs.$g->aug_get($augpath) eq $kernel);
}
@@ -1771,30 +1788,25 @@ sub _check_grub
my $default;
# Doesn't matter if there's no default
- eval {
- $default = $g->aug_get('/files/boot/grub/menu.lst/default');
- };
+ eval { $default = $g->aug_get("/files/$grub_conf/default"); };
eval {
if (defined($default)) {
$g->aug_defvar('template',
- '/files/boot/grub/menu.lst/title['.($default +
1).']');
+ "/files/$grub_conf/title[".($default +
1).']');
}
# If there's no default, take the first entry with a kernel
else {
- my ($match) -
$g->aug_match('/files/boot/grub/menu.lst/title/kernel');
- die("No template kernel found in grub.")
unless(defined($match));
+ my ($match) =
$g->aug_match("/files/$grub_conf/title/kernel");
+ die("No template kernel found in grub.") unless
defined($match);
$match =~ s/\/kernel$//;
$g->aug_defvar('template', $match);
}
# Add a new title node at the end
- $g->aug_defnode('new',
- '/files/boot/grub/menu.lst/title[last()+1]',
- $title);
+ $g->aug_defnode('new',
"/files/$grub_conf/title[last()+1]", $title);
# N.B. Don't change the order of root, kernel and initrd below, or
the
# guest will not boot.
@@ -1827,9 +1839,7 @@ sub _check_grub
my ($new) = $g->aug_match('$new');
$new =~ /\[(\d+)\]$/;
- $g->aug_set('/files/boot/grub/menu.lst/default',
- defined($1) ? $1 - 1 : 0);
-
+ $g->aug_set("/files/$grub_conf/default", defined($1) ? $1
- 1 : 0);
$g->aug_save();
};
augeas_error($g, $@) if ($@);
@@ -2198,12 +2208,12 @@ sub _prepare_bootable
$prefix = '/boot';
}
- foreach my $kernel
-
($g->aug_match('/files/boot/grub/menu.lst/title/kernel')) {
+ my $grub_conf = $desc->{boot}->{grub_conf};
+ foreach my $kernel
($g->aug_match("/files/$grub_conf/title/kernel")) {
if($g->aug_get($kernel) eq "$prefix/vmlinuz-$version")
{
# Ensure it's the default
- $kernel =~
m{/files/boot/grub/menu.lst/title(?:\[(\d+)\])?/kernel}
+ $kernel =~ m{/files/$grub_conf/title(?:\[(\d+)\])?/kernel}
or die($kernel);
my $aug_index;
@@ -2213,11 +2223,11 @@ sub _prepare_bootable
$aug_index = 1;
}
- $g->aug_set('/files/boot/grub/menu.lst/default',
- $aug_index - 1);
+ $g->aug_set("/files/$grub_conf/default",
$aug_index - 1);
# Get the initrd for this kernel
- $initrd =
$g->aug_get("/files/boot/grub/menu.lst/title[$aug_index]/initrd");
+ $initrd +
$g->aug_get("/files/$grub_conf/title[$aug_index]/initrd");
$found = 1;
last;
--
1.7.4.4
Richard W.M. Jones
2011-Apr-26 16:41 UTC
[Libguestfs] [PATCH 1/7] Push $desc creation into Sys::VirtConvert::Converter->convert
On Tue, Apr 26, 2011 at 05:03:46PM +0100, Matthew Booth wrote:> @@ -934,21 +939,23 @@ sub _get_application_owner > > sub _unconfigure_hv > { > - my ($g, $desc) = @_; > + my ($g, $root, $desc) = @_; > > - _unconfigure_xen($g, $desc); > - _unconfigure_vmware($g, $desc); > + my @apps = $g->inspect_list_applications($root);I can't tell without looking at the full context, but this might not be safe. inspect_list_applications will only work if the mountpoints are all mounted up. That's because this one call can read files out of the filesystem, where as all the inspect_get_* calls just return data that was cached in the handle (by inspect_os). Note the comment in the removed code below which says just about the same thing:> - my $root_dev = $roots[0]; > - > - # Mount up the disks. > - my %fses = $g->inspect_get_mountpoints ($root_dev); > - my @fses = sort { length $a <=> length $b } keys %fses; > - foreach (@fses) { > - eval { $g->mount_options ("", $fses{$_}, $_) }; > - print __x("{e} (ignored)\n", e => $@) if $@; > - } > - > - # Construct the "$desc" hashref which contains the main features > - # found by inspection. > - my %desc; > - > - $desc{root_device} = $root_dev; > - > - $desc{os} = $g->inspect_get_type ($root_dev); > - $desc{distro} = $g->inspect_get_distro ($root_dev); > - $desc{product_name} = $g->inspect_get_product_name ($root_dev); > - $desc{product_variant} = $g->inspect_get_product_variant ($root_dev); > - $desc{major_version} = $g->inspect_get_major_version ($root_dev); > - $desc{minor_version} = $g->inspect_get_minor_version ($root_dev); > - $desc{arch} = $g->inspect_get_arch ($root_dev); > - > - # Notes: > - # (1) Filesystems have to be mounted for this to work. Do not > - # move this code over the filesystem mounting code above. > - # (2) For RPM-based distros, new libguestfs inspection code > - # is only able to populate the 'app_name' field (old Perl code > - # populated a lot more). Fortunately this is the only field > - # that the code currently uses. > - my @apps = $g->inspect_list_applications ($root_dev); > - $desc{apps} = \@apps; > - > - return \%desc; > + return $roots[0]; > }References: http://libguestfs.org/guestfs.3.html#inspection http://libguestfs.org/guestfs.3.html#guestfs_inspect_list_applications The rest seems all fine. I'd be a lot happier if our language/ compiler was strongly type-checking all of these changes though ... Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones New in Fedora 11: Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 70 libraries supprt'd http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
Maybe Matching Threads
- [PATCH 0/4] Add SUSE guest converter to virt-v2v
- Re: [PATCH] virt-v2v: Convert RedHat.pm to Linux.pm - for SUSE support
- Re: [PATCH] virt-v2v: Convert RedHat.pm to Linux.pm - for SUSE support
- Re: [PATCH 3/4] Add SUSE converter
- [PATCH 0/4] virt-v2v: Convert RedHat.pm to Linux.pm