[Libguestfs] [PATCH v2] v2v: linux: fix kernel detection when split in different packages

Richard W.M. Jones rjones at redhat.com
Tue May 22 10:41:13 UTC 2018


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
> Libguestfs at redhat.com
> 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




More information about the Libguestfs mailing list