---
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