[Libguestfs] [PATCH 1/7] Push $desc creation into Sys::VirtConvert::Converter->convert

Matthew Booth mbooth at redhat.com
Tue Apr 26 16:03:46 UTC 2011


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




More information about the Libguestfs mailing list