Pino Toscano
2020-Sep-23 09:02 UTC
[Libguestfs] [v2v PATCH 1/3] linux: remove warning for packages with no files
Metapackages are valid packages with no files, used to easily install something without manually installing bits. This is the case of the "kernel" package in Fedora/RHEL/etc in the last couple of years. --- v2v/linux_kernels.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml index 9a41225a..78c1ee59 100644 --- a/v2v/linux_kernels.ml +++ b/v2v/linux_kernels.ml @@ -107,7 +107,6 @@ let detect_kernels (g : G.guestfs) inspect family bootloader let files = Linux.file_list_of_package g inspect app in if files = [] then ( - warning (f_"package ‘%s’ contains no files") name; None ) else ( -- 2.26.2
Pino Toscano
2020-Sep-23 09:02 UTC
[Libguestfs] [v2v PATCH 2/3] linux: avoid bogus "file" in empty RPM packages
RPM writes "(contains no files)" to stdout for packages with no files, and thus we consider that string as single file in such packages. Workaround this locally, so we do not get bogus files in the file listing of RPMs with no files. --- v2v/linux.ml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/v2v/linux.ml b/v2v/linux.ml index 6fd0eb50..5496d056 100644 --- a/v2v/linux.ml +++ b/v2v/linux.ml @@ -123,8 +123,16 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app let cmd = [| "rpm"; "-ql"; pkg_name |] in debug "%s" (String.concat " " (Array.to_list cmd)); let files = g#command_lines cmd in - let files = Array.to_list files in - List.sort compare files + (* RPM prints "(contains no files)" on stdout when a package + * has no files in it: + * https://github.com/rpm-software-management/rpm/issues/962 + *) + if files = [| "(contains no files)" |] then + [] + else ( + let files = Array.to_list files in + List.sort compare files + ) | format -> error (f_"don’t know how to get list of files from package using %s") -- 2.26.2
Pino Toscano
2020-Sep-23 09:02 UTC
[Libguestfs] [v2v PATCH 3/3] linux: remove special handling of packages with no files
We check for /boot/vmlinuz-* files in packages with files, and List.find will raise Not_found if there are none. Iterating on an empty list gives the same result, so there is no need to handle empty packages in a special way. --- v2v/linux_kernels.ml | 321 +++++++++++++++++++++---------------------- 1 file changed, 158 insertions(+), 163 deletions(-) diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml index 78c1ee59..7e171eae 100644 --- a/v2v/linux_kernels.ml +++ b/v2v/linux_kernels.ml @@ -106,181 +106,176 @@ let detect_kernels (g : G.guestfs) inspect family bootloader (* For each kernel, list the files directly owned by the kernel. *) let files = Linux.file_list_of_package g inspect app in - if files = [] then ( - None - ) - else ( - (* 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 - let vmlinuz_stat - try g#statns vmlinuz with G.Error _ -> raise Not_found in + (* 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 + let vmlinuz_stat + try g#statns vmlinuz with G.Error _ -> raise Not_found 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 && - 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 + (* 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 && + 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; + (* 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 - * to be covered by the RPM file list, this is basically - * guesswork. + (* Find the initramfs which corresponds to the kernel. + * Since the initramfs is built at runtime, and doesn't have + * to be covered by the RPM file list, this is basically + * guesswork. + *) + let initrd + let files = g#ls "/boot" in + let files = Array.to_list files in + let files + List.filter (fun n -> PCRE.matches rex_initrd n) files in + let files + List.filter ( + fun n -> + String.find n version >= 0 + ) files in + (* Don't consider kdump initramfs images (RHBZ#1138184). *) + let files + List.filter (fun n -> String.find n "kdump" == -1) files in + (* If several files match, take the shortest match. This + * handles the case where we have a mix of same-version non-Xen + * and Xen kernels: + * initrd-2.6.18-308.el5.img + * initrd-2.6.18-308.el5xen.img + * and kernel 2.6.18-308.el5 (non-Xen) will match both + * (RHBZ#1141145). *) - let initrd - let files = g#ls "/boot" in - let files = Array.to_list files in - let files - List.filter (fun n -> PCRE.matches rex_initrd n) files in - let files - List.filter ( - fun n -> - String.find n version >= 0 - ) files in - (* Don't consider kdump initramfs images (RHBZ#1138184). *) - let files - List.filter (fun n -> String.find n "kdump" == -1) files in - (* If several files match, take the shortest match. This - * handles the case where we have a mix of same-version non-Xen - * and Xen kernels: - * initrd-2.6.18-308.el5.img - * initrd-2.6.18-308.el5xen.img - * and kernel 2.6.18-308.el5 (non-Xen) will match both - * (RHBZ#1141145). - *) - let cmp a b = compare (String.length a) (String.length b) in - let files = List.sort cmp files in - match files with - | [] -> - warning (f_"no initrd was found in /boot matching %s %s.") - name version; - None - | x :: _ -> Some ("/boot/" ^ x) in + let cmp a b = compare (String.length a) (String.length b) in + let files = List.sort cmp files in + match files with + | [] -> + warning (f_"no initrd was found in /boot matching %s %s.") + name version; + None + | x :: _ -> Some ("/boot/" ^ x) in - (* Get all modules, which might include custom-installed - * modules that don't appear in 'files' list above. - *) - let modules = g#find modpath in - let modules = Array.to_list modules in - let modules - List.filter (fun m -> PCRE.matches rex_ko m) modules in - assert (List.length modules > 0); + (* Get all modules, which might include custom-installed + * modules that don't appear in 'files' list above. + *) + let modules = g#find modpath in + let modules = Array.to_list modules in + let modules + List.filter (fun m -> PCRE.matches rex_ko m) modules in + assert (List.length modules > 0); - (* Determine the kernel architecture by looking at the - * architecture of a kernel module. - * - * To avoid architecture detection issues with 3rd party - * modules (RHBZ#1690574), try to pick one of the well - * known modules, if available. Otherwise, an arbitrary - * module is used. - *) - let arch - (* Well known kernel modules. *) - let candidates = [ "virtio"; "kvm" ] in - let all_candidates = List.flatten ( - List.map ( - fun f -> - [ "/" ^ f ^ ".o"; "/" ^ f ^ ".ko"; "/" ^ f ^ ".ko.xz" ] - ) candidates - ) in - let candidate - try - List.find ( - fun m -> - List.exists (String.is_suffix m) all_candidates - ) modules - with Not_found -> - (* No known module found, pick an arbitrary one - * (the first). - *) - List.hd modules in - let candidate = modpath ^ candidate in - g#file_architecture (g#realpath candidate) in + (* Determine the kernel architecture by looking at the + * architecture of a kernel module. + * + * To avoid architecture detection issues with 3rd party + * modules (RHBZ#1690574), try to pick one of the well + * known modules, if available. Otherwise, an arbitrary + * module is used. + *) + let arch + (* Well known kernel modules. *) + let candidates = [ "virtio"; "kvm" ] in + let all_candidates = List.flatten ( + List.map ( + fun f -> + [ "/" ^ f ^ ".o"; "/" ^ f ^ ".ko"; "/" ^ f ^ ".ko.xz" ] + ) candidates + ) in + let candidate + try + List.find ( + fun m -> + List.exists (String.is_suffix m) all_candidates + ) modules + with Not_found -> + (* No known module found, pick an arbitrary one + * (the first). + *) + List.hd modules in + let candidate = modpath ^ candidate in + g#file_architecture (g#realpath candidate) in - (* Just return the module names, without path or extension. *) - let modules = List.filter_map ( - fun m -> - if PCRE.matches rex_ko_extract m then - Some (PCRE.sub 1) - else - None - ) modules in - assert (List.length modules > 0); + (* Just return the module names, without path or extension. *) + let modules = List.filter_map ( + fun m -> + if PCRE.matches rex_ko_extract m then + Some (PCRE.sub 1) + else + None + ) modules in + assert (List.length modules > 0); - let config_file - let cfg = "/boot/config-" ^ version in - if g#is_file ~followsymlinks:true cfg then Some cfg - else None in + let config_file + let cfg = "/boot/config-" ^ version in + if g#is_file ~followsymlinks:true cfg then Some cfg + else None in - let kernel_supports what kconf - List.mem what modules || check_config kconf config_file in + let kernel_supports what kconf + List.mem what modules || check_config kconf config_file in - let supports_virtio_blk - kernel_supports "virtio_blk" "VIRTIO_BLK" in - let supports_virtio_net - kernel_supports "virtio_net" "VIRTIO_NET" in - let supports_virtio_rng - kernel_supports "virtio-rng" "HW_RANDOM_VIRTIO" in - let supports_virtio_balloon - kernel_supports "virtio_balloon" "VIRTIO_BALLOON" in - let supports_isa_pvpanic - kernel_supports "pvpanic" "PVPANIC" in - let is_xen_pv_only_kernel - check_config "X86_XEN" config_file || - check_config "X86_64_XEN" config_file in + let supports_virtio_blk + kernel_supports "virtio_blk" "VIRTIO_BLK" in + let supports_virtio_net + kernel_supports "virtio_net" "VIRTIO_NET" in + let supports_virtio_rng + kernel_supports "virtio-rng" "HW_RANDOM_VIRTIO" in + let supports_virtio_balloon + kernel_supports "virtio_balloon" "VIRTIO_BALLOON" in + let supports_isa_pvpanic + kernel_supports "pvpanic" "PVPANIC" in + let is_xen_pv_only_kernel + check_config "X86_XEN" config_file || + check_config "X86_64_XEN" config_file in - (* If the package name is like "kernel-debug", then it's - * a debug kernel. - *) - let is_debug - String.is_suffix app.G.app2_name "-debug" || - String.is_suffix app.G.app2_name "-dbg" in + (* If the package name is like "kernel-debug", then it's + * a debug kernel. + *) + let is_debug + String.is_suffix app.G.app2_name "-debug" || + String.is_suffix app.G.app2_name "-dbg" in - Some { - ki_app = app; - ki_name = name; - ki_version = version; - ki_arch = arch; - ki_vmlinuz = vmlinuz; - ki_vmlinuz_stat = vmlinuz_stat; - ki_initrd = initrd; - ki_modpath = modpath; - ki_modules = modules; - ki_supports_virtio_blk = supports_virtio_blk; - ki_supports_virtio_net = supports_virtio_net; - ki_supports_virtio_rng = supports_virtio_rng; - ki_supports_virtio_balloon = supports_virtio_balloon; - ki_supports_isa_pvpanic = supports_isa_pvpanic; - ki_is_xen_pv_only_kernel = is_xen_pv_only_kernel; - ki_is_debug = is_debug; - ki_config_file = config_file; - } - ) + Some { + ki_app = app; + ki_name = name; + ki_version = version; + ki_arch = arch; + ki_vmlinuz = vmlinuz; + ki_vmlinuz_stat = vmlinuz_stat; + ki_initrd = initrd; + ki_modpath = modpath; + ki_modules = modules; + ki_supports_virtio_blk = supports_virtio_blk; + ki_supports_virtio_net = supports_virtio_net; + ki_supports_virtio_rng = supports_virtio_rng; + ki_supports_virtio_balloon = supports_virtio_balloon; + ki_supports_isa_pvpanic = supports_isa_pvpanic; + ki_is_xen_pv_only_kernel = is_xen_pv_only_kernel; + ki_is_debug = is_debug; + ki_config_file = config_file; + } with Not_found -> None ) -- 2.26.2
Richard W.M. Jones
2020-Sep-23 09:35 UTC
Re: [Libguestfs] [v2v PATCH 3/3] linux: remove special handling of packages with no files
ACK series. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Possibly Parallel Threads
- [v2v PATCH 1/3] linux: remove warning for packages with no files
- [PATCH v4 3/9] v2v: linux: Replace 'ki_supports_virtio' field.
- [PATCH v2] v2v: linux: fix kernel detection when split in different packages
- [PATCH v3 2/8] v2v: linux: Fix Xen PV-only detection.
- [PATCH v4 2/9] v2v: linux: Fix Xen PV-only detection.