diff options
author | Matthew Booth <mbooth@redhat.com> | 2009-08-13 11:48:27 +0100 |
---|---|---|
committer | Matthew Booth <mbooth@redhat.com> | 2009-08-13 12:17:58 +0100 |
commit | da90c9d8761caced81b9cf7d6e41180afa53ecb9 (patch) | |
tree | 05da1a3741a5a40c74c923bc3e418acdaba025cf /perl | |
parent | d082a76d679b019784bc0b131028ee74e381f4a2 (diff) | |
download | libguestfs-da90c9d8761caced81b9cf7d6e41180afa53ecb9.tar.gz libguestfs-da90c9d8761caced81b9cf7d6e41180afa53ecb9.tar.xz libguestfs-da90c9d8761caced81b9cf7d6e41180afa53ecb9.zip |
Don't assume grub is on a separate boot filesystem
Paths in grub.conf are relative to the filesystem containing it. grub parsing
currently assumes that it is on /boot, and will fail if it isn't, for example
because a guest only has a single partition.
This patch makes grub parsing work harder to work out what grub paths are
relative to. Firstly, it looks for a previous detected 'linux-grub' filesystem.
If this isn't found, it tries to work out which filesystem contains
/boot/grub/menu.lst and uses that.
Diffstat (limited to 'perl')
-rw-r--r-- | perl/lib/Sys/Guestfs/Lib.pm | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 72b0f7df..89f2aa67 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -1435,6 +1435,56 @@ sub _check_for_applications $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) = @_; @@ -1443,6 +1493,8 @@ sub _check_for_kernels # 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 @@ -1474,7 +1526,7 @@ sub _check_for_kernels # 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 = (); @@ -1508,7 +1560,7 @@ sub _check_for_kernels 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 ". |