--- lib/Sys/VirtConvert/Converter/Linux.pm | 125 +++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 28 deletions(-) diff --git a/lib/Sys/VirtConvert/Converter/Linux.pm b/lib/Sys/VirtConvert/Converter/Linux.pm index dd3573e..344d89b 100644 --- a/lib/Sys/VirtConvert/Converter/Linux.pm +++ b/lib/Sys/VirtConvert/Converter/Linux.pm @@ -31,16 +31,50 @@ sub get_initrd { my $self = shift; my ($path) = @_; + my $initrd; my $g = $self->{g}; - foreach my $line ($g->command_lines(['grubby', '--info', $path])) { - return $1 if $line =~ /^initrd=(\S+)/; + if ($g->exists('/sbin/grubby')) { + foreach my $line ($g->command_lines(['grubby', '--info', $path])) { + return $1 if $line =~ /^initrd=(\S+)/; + } } + # If initrd has not been found, use heuristics if the file exists + ($initrd = $path) =~ s/vmlinuz/initrd/; + return $initrd if ($g->exists($initrd)); + v2vdie __x('Didn\'t find initrd for kernel {path}', path => $path); } +sub get_default_image +{ + my $self = shift; + my $default; + + my $g = $self->{g}; + + if ($g->exists('/sbin/grubby')) { + $default = $g->command(['grubby', '--default-kernel']); + } + + chomp($default); + return $default; +} + +sub set_default_image +{ + my $self = shift; + my ($path) = @_; + + my $g = $self->{g}; + + if ($g->exists('/sbin/grubby')) { + $g->command(['grubby', '--set-default', $path]); + } +} + sub check_efi { my $self = shift; @@ -237,7 +271,7 @@ sub update_console sub check { my $self = shift; - my ($path) = @_; + my ($path, $root) = @_; my $g = $self->{g}; my $grub_conf = $self->{grub_conf}; @@ -256,11 +290,13 @@ sub check my $version = $kernel->{version}; my $grub_initrd = dirname($path)."/initrd-$version"; - # No point in dying if /etc/redhat-release can't be read - my ($title) = eval { $g->read_lines('/etc/redhat-release') }; + # No point in dying if /etc/(distro)-release can't be read + my ($title) = eval { $g->inspect_get_product_name($root) }; $title ||= 'Linux'; - # This is how new-kernel-pkg does it + # Remove codename or architecture + $title =~ s/ \(.*\)//; + # Remove release string and add version (like new-kernel-pkg) $title =~ s/ release.*//; $title .= " ($version)"; @@ -408,8 +444,7 @@ sub list_kernels my @kernels; # Start by adding the default kernel - my $default = $g->command(['grubby', '--default-kernel']); - chomp($default); + my $default = $self->get_default_image(); push(@kernels, $default) if length($default) > 0; # This is how the grub2 config generator enumerates kernels @@ -431,8 +466,15 @@ sub update_console my $g = $self->{g}; + my $grub_cmdline; + if ($g->exists('/etc/sysconfig/grub')) { + $grub_cmdline = '/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX'; + } else { + $grub_cmdline = '/files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT'; + } + my $cmdline = - eval { $g->aug_get('/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX') }; + eval { $g->aug_get($grub_cmdline) }; if (defined($cmdline) && $cmdline =~ /\bconsole=(?:x|h)vc0\b/) { if ($remove) { @@ -442,7 +484,7 @@ sub update_console } eval { - $g->aug_set('/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX', $cmdline); + $g->aug_set($grub_cmdline, $cmdline); $g->aug_save(); }; augeas_error($g, $@) if ($@); @@ -464,11 +506,14 @@ sub write my $g = $self->{g}; - my $default = $g->command(['grubby', '--default-kernel']); - chomp($default); + my $default = $self->get_default_image(); if ($default ne $path) { - $g->command(['grubby', '--set-default', $path]); + eval { $self->set_default_image($path) }; + if ($@) { + logmsg WARN, __x('Unable to set default kernel to {path}', + path => $path); + } } } @@ -626,7 +671,8 @@ sub convert my $remove_serial_console = exists($options->{NO_SERIAL_CONSOLE}); _configure_console($g, $grub, $remove_serial_console); - _configure_display_driver($g, $root, $config, $meta, $grub); + my $display = _get_display_driver($g, $root); + _configure_display_driver($g, $root, $config, $meta, $grub, $driver); _remap_block_devices($meta, $virtio, $g, $root); _configure_kernel_modules($g, $virtio); _configure_boot($kernel, $virtio, $g, $root, $grub); @@ -637,6 +683,7 @@ sub convert $guestcaps{net} = $virtio == 1 ? 'virtio' : 'e1000'; $guestcaps{arch} = _get_os_arch($g, $root, $grub); $guestcaps{acpi} = _supports_acpi($g, $root, $guestcaps{arch}); + $guestcaps{display} = $display; return \%guestcaps; } @@ -843,7 +890,7 @@ sub _configure_console sub _configure_display_driver { - my ($g, $root, $config, $meta, $grub) = @_; + my ($g, $root, $config, $meta, $grub, $display) = @_; # Update the display driver if it exists my $updated = 0; @@ -867,7 +914,7 @@ sub _configure_display_driver } foreach my $path ($g->aug_match('/files'.$xorg.'/Device/Driver')) { - $g->aug_set($path, 'qxl'); + $g->aug_set($path, $display); $updated = 1; } @@ -886,13 +933,14 @@ sub _configure_display_driver augeas_error($g, $@) if ($@); # If we updated the X driver, check if X itself is actually installed. If it - # is, ensure the qxl driver is installed. + # is, ensure the specified driver is installed. if ($updated && ($g->exists('/usr/bin/X') || $g->exists('/usr/bin/X11/X')) && - !_install_capability('qxl', $g, $root, $config, $meta, $grub)) + !_install_capability($display, $g, $root, $config, $meta, $grub)) { - logmsg WARN, __('Display driver was updated to qxl, but unable to '. - 'install qxl driver. X may not function correctly'); + logmsg WARN, __('Display driver was updated to {display}, but unable '. + 'to install {display} driver. X may not function '. + 'correctly', display => $display); } } @@ -1014,7 +1062,7 @@ sub _configure_kernel # 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") { + if ($kernel_pkg =~ /^kernel-xen/) { $kernel_pkg = _get_replacement_kernel_name($g, $root, $kernel_arch, $meta); @@ -1122,8 +1170,8 @@ sub _get_os_arch # Default to x86_64 if we still didn't find an architecture return 'x86_64' unless defined($arch); - # We want an i686 guest for i[345]86 - return 'i686' if($arch =~ /^i[345]86$/); + # Determine the correct 32bit arch + $arch = _set_32bit_arch($g, $root, $arch); return $arch; } @@ -1507,7 +1555,7 @@ sub _install_capability # 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") + if ($kernel_pkg =~ /^kernel-xen/) { $kernel_pkg = _get_replacement_kernel_name($g, $root, $kernel_arch, @@ -1658,7 +1706,7 @@ sub _install_any if (defined($kernel)) { foreach my $k ($g->glob_expand('/boot/vmlinuz-*')) { if (!grep(/^$k$/, @k_before)) { - $grub->check($k); + $grub->check($k, $root); last; } } @@ -1976,9 +2024,8 @@ sub _discover_kernel # directly detected $kernel_arch = $g->inspect_get_arch($root) 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); + # Determine the correct 32bit kernel_arch + $kernel_arch = _set_32bit_arch($g, $root, $kernel_arch); return ($kernel_pkg, $kernel_arch, $kernel_ver); } @@ -2468,6 +2515,28 @@ sub _supports_virtio return 1; } +# Distributions may use different display drivers. +sub _get_display_driver +{ + my ($g, $root) = @_; + + # RedHat uses qxl, which should be the default driver. + return 'qxl'; +} + +# Distributions may use either i586 or i686 for 32bit architectures +sub _set_32bit_arch +{ + my ($g, $root, $arch) = @_; + + if ($arch =~ /^i[345]86$/) { + # RedHat uses i686, which should be the default 32bit arch + $arch = 'i686'; + } + + return $arch; +} + =back =head1 COPYRIGHT -- 1.8.1.4