On Tue, May 22, 2018 at 11:09:22AM +0200, Pino Toscano wrote: > The current detection code for Linux kernels assumes that a kernel > package contains everything in it, i.e. the kernel itself, its modules, > and its configuration. However, since recent Ubuntu versions (e.g. > starting from 18.04) modules & config (with few more files) are split in > an own package, thus not detecting the modpath from installed vmlinuz > files. > > To overcome this situation, rework this detection a bit: > 1) find the vmlinuz file as before, but then immediately make sure it > exists by stat'ing it > 2) find the modules path from the package as before: > 2a) if found, extract the version in the same step > 2b) if not found, get the kernel version from the vmlinuz filename, > and use it to detect the modules path > 3) check that the modules path exists > > The detection done in (2b) is based on the current packaging scheme > found in the most important Linux distributions (Fedora, RHEL, CentOS, > Debian, Ubuntu, openSUSE, AltLinux, and possibly more). The notable > exception is Arch Linux. > > As additional change, do not assume the config file is in the same > package as vmlinuz, but directly look into the filesystem using the > version we already have. > --- > v2v/linux_kernels.ml | 47 +++++++++++++++++++++++++++++--------------- > 1 file changed, 31 insertions(+), 16 deletions(-) > > diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml > index c047d6deb..24f61429d 100644 > --- a/v2v/linux_kernels.ml > +++ b/v2v/linux_kernels.ml > @@ -103,27 +103,42 @@ let detect_kernels (g : G.guestfs) inspect family > bootloader = > None > ) > else ( > - (* Which of these is the kernel itself? *) > + (* Which of these is the kernel itself? Also, make sure to > check > + * it exists by stat'ing it. > + *) > let vmlinuz = List.find ( > fun filename -> String.is_prefix filename "/boot/vmlinuz-" > ) files in > - (* Which of these is the modpath? *) > - let modpath = List.find ( > - fun filename -> > - String.length filename >= 14 && > - String.is_prefix filename "/lib/modules/" > - ) files in > - > - (* Check vmlinuz & modpath exist. *) > - if not (g#is_dir ~followsymlinks:true modpath) then > - raise Not_found; > let vmlinuz_stat = > try g#statns vmlinuz with G.Error _ -> raise Not_found in > > - (* Get/construct the version. XXX Read this from kernel file. > *) > - let version = > - let prefix_len = String.length "/lib/modules/" in > - String.sub modpath prefix_len (String.length modpath - > prefix_len) in > + (* Determine the modpath from the package, falling back to the > + * version in the vmlinuz file name. > + *) > + let modpath, version = > + let prefix = "/lib/modules/" in > + try > + let prefix_len = String.length prefix in > + List.find_map ( > + fun filename -> > + let filename_len = String.length filename in > + if filename_len > prefix_len &&
Strictly speaking this test is not needed, since String.is_prefix implies it. Anyway, the patch is good, ACK. Rich. > + String.is_prefix filename prefix then ( > + let version = String.sub filename prefix_len > + (filename_len - prefix_len) > in > + Some (filename, version) > + ) else > + None > + ) files > + with Not_found -> > + let version = > + String.sub vmlinuz 14 (String.length vmlinuz - 14) in > + let modpath = prefix ^ version in > + modpath, version in > + > + (* Check that the modpath exists. *) > + if not (g#is_dir ~followsymlinks:true modpath) then > + raise Not_found; > > (* Find the initramfs which corresponds to the kernel. > * Since the initramfs is built at runtime, and doesn't have > @@ -188,7 +203,7 @@ let detect_kernels (g : G.guestfs) inspect family > bootloader = > > let config_file = > let cfg = "/boot/config-" ^ version in > - if List.mem cfg files then Some cfg > + if g#is_file ~followsymlinks:true cfg then Some cfg > else None in > > let kernel_supports what kconf = > -- > 2.17.0 > > _______________________________________________ > Libguestfs mailing list > [email protected] > https://www.redhat.com/mailman/listinfo/libguestfs -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
