@ISA = qw(Exporter);
@EXPORT_OK = qw(open_guest get_partitions resolve_windows_path
inspect_all_partitions inspect_partition
- inspect_operating_systems mount_operating_system inspect_in_detail);
+ inspect_operating_systems mount_operating_system inspect_in_detail
+ inspect_linux_kernel);
=head2 open_guest
=item default
-The index of the default configuration in the configs array
+The index of the default configuration in the configs array.
+
+=item grub_fs
+
+The path of the filesystem containing the grub partition.
=back
$os->{apps} = \@apps;
}
+# Find the path which needs to be prepended to paths in grub.conf to make them
+# absolute
+sub _find_grub_prefix
+{
+ my ($g, $os) = @_;
+
+ my $fses = $os->{filesystems};
+ die("filesystems undefined") unless(defined($fses));
+
+ # Look for the filesystem which contains grub
+ my $grubdev;
+ foreach my $dev (keys(%$fses)) {
+ my $fsinfo = $fses->{$dev};
+ if(exists($fsinfo->{content}) && $fsinfo->{content} eq "linux-grub") {
+ $grubdev = $dev;
+ last;
+ }
+ }
+
+ my $mounts = $os->{mounts};
+ die("mounts undefined") unless(defined($mounts));
+
+ # Find where the filesystem is mounted
+ if(defined($grubdev)) {
+ foreach my $mount (keys(%$mounts)) {
+ if($mounts->{$mount} eq $grubdev) {
+ return "" if($mount eq '/');
+ return $mount;
+ }
+ }
+
+ die("$grubdev defined in filesystems, but not in mounts");
+ }
+
+ # If we didn't find it, look for /boot/grub/menu.lst, then try to work out
+ # what filesystem it's on. We use menu.lst rather than grub.conf because
+ # debian only uses menu.lst, and anaconda creates a symlink for it.
+ die(__"Can't find grub on guest") unless($g->exists('/boot/grub/menu.lst'));
+
+ # Look for the most specific mount point in mounts
+ foreach my $path qw(/boot/grub /boot /) {
+ if(exists($mounts->{$path})) {
+ return "" if($path eq '/');
+ return $path;
+ }
+ }
+
+ die("Couldn't determine which filesystem holds /boot/grub/menu.lst");
+}
+
sub _check_for_kernels
{
my ($g, $os) = @_;
# Iterate over entries in grub.conf, populating $os->{boot}
# For every kernel we find, inspect it and add to $os->{kernels}
+ my $grub = _find_grub_prefix($g, $os);
+
my @boot_configs;
# We want
# ->{cmdline} = "ro root=/dev/mapper/vg_mbooth-lv_root rhgb"
# ->{initrd} = \initrd
# ->{default} = \config
+ # ->{grub_fs} = "/boot"
# Initialise augeas
$g->aug_init("/", 16);
# Check we've got a kernel entry
if(defined($grub_kernel)) {
- my $path = "/boot$grub_kernel";
+ my $path = "$grub$grub_kernel";
# Reconstruct the kernel command line
my @args = ();
}
$config{cmdline} = join(' ', @args) if(scalar(@args) > 0);
- my $kernel = _inspect_linux_kernel($g, $os, "$path");
+ my $kernel =
+ inspect_linux_kernel($g, $path, $os->{package_format});
# Check the kernel was recognised
if(defined($kernel)) {
+ # Put this kernel on the top level kernel list
+ my $kernels = $os->{kernels};
+ if(!defined($kernels)) {
+ $kernels = [];
+ $os->{kernels} = $kernels;
+ }
+ push(@$kernels, $kernel);
+
$config{kernel} = $kernel;
# Look for an initrd entry
unless($@) {
$config{initrd} =
- _inspect_initrd($g, $os, "/boot$initrd",
+ _inspect_initrd($g, $os, "$grub$initrd",
$kernel->{version});
} else {
warn __x("Grub entry {title} does not specify an ".
# Create the top level boot entry
my %boot;
$boot{configs} = \@configs;
+ $boot{grub_fs} = $grub;
# Add the default configuration
eval {
}
}
-sub _inspect_linux_kernel
+=head2 inspect_linux_kernel
+
+ my $kernel_hash = inspect_linux_kernel($g, $vmlinuz_path, $package_format);
+
+inspect_linux_kernel returns a hash describing the target linux kernel. For the
+contents of the hash, see the I<kernels> structure described under
+L</inspect_in_detail>.
+
+=cut
+
+sub inspect_linux_kernel
{
- my ($g, $os, $path) = @_;
+ my ($g, $path, $package_format) = @_;
my %kernel = ();
# If this is a packaged kernel, try to work out the name of the package
# which installed it. This lets us know what to install to replace it with,
# e.g. kernel, kernel-smp, kernel-hugemem, kernel-PAE
- if($os->{package_format} eq "rpm") {
+ if($package_format eq "rpm") {
my $package;
eval { $package = $g->command(['rpm', '-qf', '--qf',
'%{NAME}', $path]); };
# of any kernel module.
$kernel{arch} = file_architecture ($g, $any_module);
- # Put this kernel on the top level kernel list
- my $kernels = $os->{kernels};
- if(!defined($kernels)) {
- $kernels = [];
- $os->{kernels} = $kernels;
- }
- push(@$kernels, \%kernel);
-
return \%kernel;
}