From 29afe986863f4dfb960bd9261f7f9a774e302e1a Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Dec 10 2019 18:49:01 +0000 Subject: Add further patch to fix symlinks (RHBZ#1770304). Add all patches since 5.1.20 was released. --- diff --git a/0001-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch b/0001-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch deleted file mode 100644 index 85bc272..0000000 --- a/0001-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 487e8c964078f823646d3b0584745ab7d0ef99ca Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 26 Nov 2019 09:01:21 +0000 -Subject: [PATCH] ext2: Build symbolic links correctly (RHBZ#1770304). - -We created symlinks in two steps, by creating the empty inode and then -calling ext2fs_symlink to populate it. This created broken symlinks -where the directory name contained a / character, eg: - -lrwxrwxrwx 1 root root 7 Nov 26 08:43 /bin -> usr/bin -lrwxrwxrwx 1 root root 7 Nov 26 08:43 /lib -> usr/lib -lrwxrwxrwx 1 root root 9 Nov 26 08:43 /lib64 -> usr/lib64 -lrwxrwxrwx 1 root root 8 Nov 26 08:43 /sbin -> usr/sbin -lrwxrwxrwx 1 root root 7 Nov 26 08:38 bin -> usr/bin - -This breaks with Linux >= 5.3.8, most likely because of extra -validation now being done at the VFS layer: - -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/readdir.c?id=8a23eb804ca4f2be909e372cf5a9e7b30ae476cd - -It's unnecessary to create the empty inode since ext2fs_symlink can -create the inode for us perfectly fine if we simply pass ino == 0, and -it creates them correctly too. - -Thanks: Toolybird for identifying the problem and kernel patch. ---- - src/ext2fs-c.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - -diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c -index e8ab972..8903f74 100644 ---- a/src/ext2fs-c.c -+++ b/src/ext2fs-c.c -@@ -782,12 +782,6 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) - } - /* Create a symlink. */ - else if (S_ISLNK (statbuf.st_mode)) { -- ext2_ino_t ino; -- ext2_empty_inode (data->fs, dir_ino, dirname, basename, -- statbuf.st_mode, statbuf.st_uid, statbuf.st_gid, -- statbuf.st_ctime, statbuf.st_atime, statbuf.st_mtime, -- 0, 0, EXT2_FT_SYMLINK, &ino); -- - char *buf = malloc (statbuf.st_size+1); - if (buf == NULL) - caml_raise_out_of_memory (); -@@ -797,7 +791,7 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) - if (r > statbuf.st_size) - r = statbuf.st_size; - buf[r] = '\0'; -- ext2fs_symlink (data->fs, dir_ino, ino, dest, buf); -+ ext2fs_symlink (data->fs, dir_ino, 0, basename, buf); - free (buf); - } - /* Create directory. */ --- -2.23.0 - diff --git a/0001-rpm-extend-the-Multiple_matches-exception.patch b/0001-rpm-extend-the-Multiple_matches-exception.patch index 30a69bb..35516ef 100644 --- a/0001-rpm-extend-the-Multiple_matches-exception.patch +++ b/0001-rpm-extend-the-Multiple_matches-exception.patch @@ -1,7 +1,7 @@ From 42955541dc3aa8ae3361f3bd6eb0ae338f307545 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Wed, 23 Jan 2019 12:22:19 +0100 -Subject: [PATCH 1/2] rpm: extend the Multiple_matches exception +Subject: [PATCH 01/12] rpm: extend the Multiple_matches exception Add the package that raised the issue, so it can be used to provide better diagnostic. @@ -85,5 +85,5 @@ index 5229be6..53b4b2c 100644 val rpm_open : ?debug:int -> t (** Open the librpm (transaction set) handle. *) -- -2.20.1 +2.23.0 diff --git a/0002-Print-Librpm.Multiple_matches-exceptions.patch b/0002-Print-Librpm.Multiple_matches-exceptions.patch index f13620b..47ff7f3 100644 --- a/0002-Print-Librpm.Multiple_matches-exceptions.patch +++ b/0002-Print-Librpm.Multiple_matches-exceptions.patch @@ -1,7 +1,7 @@ From 36878992ebdd08f0f9b37017f347f5eab18ce9ed Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Wed, 23 Jan 2019 12:23:02 +0100 -Subject: [PATCH 2/2] Print Librpm.Multiple_matches exceptions +Subject: [PATCH 02/12] Print Librpm.Multiple_matches exceptions Print a better diagnostic for them, so it is more clear which package is detected as present multiple times. @@ -23,5 +23,5 @@ index f9798f9..71d8b64 100644 error "internal error: invalid argument: %s" msg | Assert_failure (file, line, char) -> (* should never happen *) -- -2.20.1 +2.23.0 diff --git a/0003-Use-external-command-mv-to-rename-old-output-directo.patch b/0003-Use-external-command-mv-to-rename-old-output-directo.patch new file mode 100644 index 0000000..1806bf5 --- /dev/null +++ b/0003-Use-external-command-mv-to-rename-old-output-directo.patch @@ -0,0 +1,38 @@ +From 6579cf5f72d5de345ae1cc97d0344dfa1771460a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 28 Jan 2019 22:20:33 +0000 +Subject: [PATCH 03/12] Use external command mv to rename old output directory + (RHBZ#1670191). + +See https://bugzilla.redhat.com/show_bug.cgi?id=1670191#c0 +for explanation. + +Thanks: Sam Eiderman +--- + src/supermin.ml | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/supermin.ml b/src/supermin.ml +index 71d8b64..7c7135b3 100644 +--- a/src/supermin.ml ++++ b/src/supermin.ml +@@ -264,12 +264,10 @@ appliance automatically. + + (* Delete the old output directory if it exists. *) + let old_outputdir = +- try +- let old_outputdir = outputdir ^ "." ^ string_random8 () in +- rename outputdir old_outputdir; +- Some old_outputdir +- with +- Unix_error _ -> None in ++ let old_outputdir = outputdir ^ "." ^ string_random8 () in ++ let cmd = sprintf "mv %s %s 2>/dev/null" ++ (quote outputdir) (quote old_outputdir) in ++ if Sys.command cmd == 0 then Some old_outputdir else None in + + if debug >= 1 then + printf "supermin: renaming %s to %s\n%!" new_outputdir outputdir; +-- +2.23.0 + diff --git a/0004-Add-OpenMandriva-support-RHBZ-1694267.patch b/0004-Add-OpenMandriva-support-RHBZ-1694267.patch new file mode 100644 index 0000000..4fa888d --- /dev/null +++ b/0004-Add-OpenMandriva-support-RHBZ-1694267.patch @@ -0,0 +1,128 @@ +From bca633bfd14aeeb8ae1331d468db75d1ef31f9ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= +Date: Tue, 2 Apr 2019 08:28:06 +0100 +Subject: [PATCH 04/12] Add OpenMandriva support (RHBZ#1694267). + +--- + src/ph_rpm.ml | 28 +++++++++++++++++++++++++--- + tests/test-harder.sh | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 56 insertions(+), 3 deletions(-) + +diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml +index 46b7f1f..3ff5c94 100644 +--- a/src/ph_rpm.ml ++++ b/src/ph_rpm.ml +@@ -50,6 +50,12 @@ let mageia_detect () = + (Os_release.get_id () = "mageia" || + try (stat "/etc/mageia-release").st_kind = S_REG with Unix_error _ -> false) + ++let openmandriva_detect () = ++ Config.rpm <> "no" && Config.rpm2cpio <> "no" && rpm_is_available () && ++ ((Config.urpmi <> "no" && Config.fakeroot <> "no") || Config.dnf <> "no") && ++ (Os_release.get_id () = "openmandriva" || ++ try (stat "/etc/openmandriva-release").st_kind = S_REG with Unix_error _ -> false) ++ + let ibm_powerkvm_detect () = + Config.rpm <> "no" && Config.rpm2cpio <> "no" && rpm_is_available () && + Config.yumdownloader <> "no" && +@@ -386,17 +392,27 @@ and opensuse_download_all_packages pkgs dir = + + rpm_unpack tdir dir + ++and openmandriva_download_all_packages pkgs dir = ++ let tdir = !settings.tmpdir // string_random8 () in ++ ++ if Config.dnf <> "no" then ++ download_all_packages_with_dnf pkgs dir tdir ++ else (* Config.urpmi <> "no" && Config.fakeroot <> "no" *) ++ download_all_packages_with_urpmi pkgs dir tdir; ++ ++ rpm_unpack tdir dir ++ + and mageia_download_all_packages pkgs dir = + let tdir = !settings.tmpdir // string_random8 () in + + if Config.dnf <> "no" then + download_all_packages_with_dnf pkgs dir tdir + else (* Config.urpmi <> "no" && Config.fakeroot <> "no" *) +- mageia_download_all_packages_with_urpmi pkgs dir tdir; ++ download_all_packages_with_urpmi pkgs dir tdir; + + rpm_unpack tdir dir + +-and mageia_download_all_packages_with_urpmi pkgs dir tdir = ++and download_all_packages_with_urpmi pkgs dir tdir = + let rpms = List.map rpm_package_name (PackageSet.elements pkgs) in + + let cmd = +@@ -484,4 +500,10 @@ let () = + ph_detect = mageia_detect; + ph_download_package = PHDownloadAllPackages mageia_download_all_packages; + } in +- register_package_handler "mageia" "rpm" mageia ++ register_package_handler "mageia" "rpm" mageia; ++ let openmandriva = { ++ fedora with ++ ph_detect = openmandriva_detect; ++ ph_download_package = PHDownloadAllPackages openmandriva_download_all_packages; ++ } in ++ register_package_handler "openmandriva" "rpm" openmandriva +diff --git a/tests/test-harder.sh b/tests/test-harder.sh +index c827f13..aceef21 100755 +--- a/tests/test-harder.sh ++++ b/tests/test-harder.sh +@@ -31,6 +31,7 @@ if [ -f /etc/os-release ]; then + fedora|rhel|centos) distro=redhat ;; + opensuse*|sled|sles) distro=suse ;; + ubuntu) distro=debian ;; ++ openmandriva) distro=openmandriva ;; + esac + elif [ -f /etc/arch-release ]; then + distro=arch +@@ -77,6 +78,9 @@ case $distro in + ibm-powerkvm) + pkgs="augeas hivex tar" + ;; ++ openmandriva) ++ pkgs="augeas hivex rpm" ++ ;; + *) + echo "Unhandled distro '$distro'" + exit 77 +@@ -153,6 +157,33 @@ case $distro in + exit 1 + fi + ;; ++ openmandriva) ++ if [ ! -x $d2/usr/bin/augtool ]; then ++ echo "$0: $distro: augtool binary not installed in chroot" ++ ls -lR $d2 ++ exit 1 ++ fi ++ if [ "$(find $d2/lib* $d2/usr/lib* -name libaugeas.so.0 | wc -l)" -lt 1 ]; then ++ echo "$0: $distro: augeas library not installed in chroot" ++ ls -lR $d2 ++ exit 1 ++ fi ++ if [ ! -x $d2/usr/bin/hivexget ]; then ++ echo "$0: $distro: hivexget binary not installed in chroot" ++ ls -lR $d2 ++ exit 1 ++ fi ++ if [ "$(find $d2/usr/lib* -name libhivex.so.0 | wc -l)" -lt 1 ]; then ++ echo "$0: $distro: hivex library not installed in chroot" ++ ls -lR $d2 ++ exit 1 ++ fi ++ if [ ! -x $d2/bin/rpm ]; then ++ echo "$0: $distro: rpm binary not installed in chroot" ++ ls -lR $d2 ++ exit 1 ++ fi ++ ;; + redhat) + if [ ! -x $d2/usr/bin/augtool ]; then + echo "$0: $distro: augtool binary not installed in chroot" +-- +2.23.0 + diff --git a/0005-rpm-do-not-unpack-parameters.patch b/0005-rpm-do-not-unpack-parameters.patch new file mode 100644 index 0000000..4242c0c --- /dev/null +++ b/0005-rpm-do-not-unpack-parameters.patch @@ -0,0 +1,33 @@ +From 941f72d05302d265af763c7f8ed6b999e4f85eeb Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 12 Apr 2019 11:58:49 +0200 +Subject: [PATCH 05/12] rpm: do not unpack parameters + +They will be used as parameters again soon. + +This has no behaviour changes. +--- + src/ph_rpm.ml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml +index 3ff5c94..6769e7b 100644 +--- a/src/ph_rpm.ml ++++ b/src/ph_rpm.ml +@@ -144,10 +144,10 @@ let rpm_package_of_string str = + * interested in the highest version with the best + * architecture. + *) +- let cmp { version = v1; arch = a1 } { version = v2; arch = a2 } = +- let i = rpm_vercmp v2 v1 in ++ let cmp pkg1 pkg2 = ++ let i = rpm_vercmp pkg2.version pkg1.version in + if i <> 0 then i +- else compare_architecture a2 a1 ++ else compare_architecture pkg2.arch pkg1.arch + in + let rpms = List.sort cmp rpms in + List.hd rpms +-- +2.23.0 + diff --git a/0006-rpm-fix-version-comparison.patch b/0006-rpm-fix-version-comparison.patch new file mode 100644 index 0000000..d2f646c --- /dev/null +++ b/0006-rpm-fix-version-comparison.patch @@ -0,0 +1,70 @@ +From de075776722741a67b0956f36a6357fcedd66ae0 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 12 Apr 2019 12:13:07 +0200 +Subject: [PATCH 06/12] rpm: fix version comparison + +When comparing two RPMs, also the epoch, and the release must be taken +into account. Hence, add a new helper to get the EVR string of a +package, and use it when sorting each list of installed packages. + +The mapping is done to avoid recreating the EVR strings at every +comparison. +--- + src/ph_rpm.ml | 29 ++++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml +index 6769e7b..a8bcf7c 100644 +--- a/src/ph_rpm.ml ++++ b/src/ph_rpm.ml +@@ -136,21 +136,44 @@ let rpm_of_pkg, pkg_of_rpm = get_memo_functions () + (* Memo of rpm_package_of_string. *) + let rpmh = Hashtbl.create 13 + ++let rpm_to_evr_string rpm = ++ (* In RPM < 4.11 query commands that use the epoch number in the ++ * package name did not work. ++ * ++ * For example: ++ * RHEL 6 (rpm 4.8.0): ++ * $ rpm -q tar-2:1.23-11.el6.x86_64 ++ * package tar-2:1.23-11.el6.x86_64 is not installed ++ * Fedora 20 (rpm 4.11.2): ++ * $ rpm -q tar-2:1.26-30.fc20.x86_64 ++ * tar-1.26-30.fc20.x86_64 ++ * ++ *) ++ let is_rpm_lt_4_11 = ++ !rpm_major < 4 || (!rpm_major = 4 && !rpm_minor < 11) in ++ ++ if is_rpm_lt_4_11 || rpm.epoch = 0 then ++ sprintf "%s-%s" rpm.version rpm.release ++ else ++ sprintf "%d:%s-%s" ++ rpm.epoch rpm.version rpm.release ++ + let rpm_package_of_string str = + let query rpm = + let rpms = Array.to_list (rpm_installed (get_rpm ()) rpm) in ++ let rpms = List.map (fun rpm -> (rpm, rpm_to_evr_string rpm)) rpms in + (* RPM will return multiple hits when either multiple versions or + * multiple arches are installed at the same time. We are only + * interested in the highest version with the best + * architecture. + *) +- let cmp pkg1 pkg2 = +- let i = rpm_vercmp pkg2.version pkg1.version in ++ let cmp (pkg1, evr1) (pkg2, evr2) = ++ let i = rpm_vercmp evr2 evr2 in + if i <> 0 then i + else compare_architecture pkg2.arch pkg1.arch + in + let rpms = List.sort cmp rpms in +- List.hd rpms ++ fst (List.hd rpms) + in + + try +-- +2.23.0 + diff --git a/0007-rpm-query-the-RPM-architecture.patch b/0007-rpm-query-the-RPM-architecture.patch new file mode 100644 index 0000000..d0b4f0e --- /dev/null +++ b/0007-rpm-query-the-RPM-architecture.patch @@ -0,0 +1,90 @@ +From e57e988c39aca015100fb92377dbd8d114c0bece Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 12 Apr 2019 12:26:11 +0200 +Subject: [PATCH 07/12] rpm: query the RPM architecture + +Query the RPM library for the current architecture of RPM, storing it +for later use, and printing it to the debug output. +--- + src/librpm-c.c | 10 ++++++++++ + src/librpm.ml | 1 + + src/librpm.mli | 3 +++ + src/ph_rpm.ml | 8 ++++++-- + 4 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/librpm-c.c b/src/librpm-c.c +index 75ca4d7..2e2f048 100644 +--- a/src/librpm-c.c ++++ b/src/librpm-c.c +@@ -132,6 +132,16 @@ supermin_rpm_vercmp (value av, value bv) + return Val_int (rpmvercmp (String_val (av), String_val (bv))); + } + ++value ++supermin_rpm_get_arch (value unit) ++{ ++ const char *str; ++ ++ rpmGetArchInfo (&str, NULL); ++ ++ return caml_copy_string (str); ++} ++ + value + supermin_rpm_open (value debugv) + { +diff --git a/src/librpm.ml b/src/librpm.ml +index b6f9ff8..c987e21 100644 +--- a/src/librpm.ml ++++ b/src/librpm.ml +@@ -20,6 +20,7 @@ external rpm_is_available : unit -> bool = "supermin_rpm_is_available" "noalloc" + + external rpm_version : unit -> string = "supermin_rpm_version" + external rpm_vercmp : string -> string -> int = "supermin_rpm_vercmp" "noalloc" ++external rpm_get_arch : unit -> string = "supermin_rpm_get_arch" + + type t + +diff --git a/src/librpm.mli b/src/librpm.mli +index 53b4b2c..c0d7bdf 100644 +--- a/src/librpm.mli ++++ b/src/librpm.mli +@@ -28,6 +28,9 @@ val rpm_version : unit -> string + val rpm_vercmp : string -> string -> int + (** Compare two RPM version strings using RPM version compare rules. *) + ++val rpm_get_arch : unit -> string ++(** The current main RPM architecture. *) ++ + type t + (** The librpm handle. *) + +diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml +index a8bcf7c..e27d226 100644 +--- a/src/ph_rpm.ml ++++ b/src/ph_rpm.ml +@@ -64,7 +64,7 @@ let ibm_powerkvm_detect () = + with Unix_error _ -> false + + let settings = ref no_settings +-let rpm_major, rpm_minor = ref 0, ref 0 ++let rpm_major, rpm_minor, rpm_arch = ref 0, ref 0, ref "" + let zypper_major, zypper_minor, zypper_patch = ref 0, ref 0, ref 0 + let t = ref None + +@@ -93,7 +93,11 @@ let rec rpm_init s = + if !settings.debug >= 1 then + printf "supermin: rpm: detected RPM version %d.%d\n" major minor; + +- t := Some (rpm_open ~debug:!settings.debug) ++ t := Some (rpm_open ~debug:!settings.debug); ++ ++ rpm_arch := rpm_get_arch (); ++ if !settings.debug >= 1 then ++ printf "supermin: rpm: detected RPM architecture %s\n" !rpm_arch + + and opensuse_init s = + rpm_init s; +-- +2.23.0 + diff --git a/0008-rpm-fix-package-sorting-RHBZ-1696822.patch b/0008-rpm-fix-package-sorting-RHBZ-1696822.patch new file mode 100644 index 0000000..d787252 --- /dev/null +++ b/0008-rpm-fix-package-sorting-RHBZ-1696822.patch @@ -0,0 +1,49 @@ +From 72735dd11c83eb59d90e04b3c1e580af43b1ba0a Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 12 Apr 2019 12:38:46 +0200 +Subject: [PATCH 08/12] rpm: fix package sorting (RHBZ#1696822) + +The sorting algorithm for RPMs sorted this way: +- before the packages with the higher versions +- among the packages with the version version, first noarch packages, + then 64bit packages, and then 32bit packages +This was broken in at least two ways: +- the higher installed version may not be of the same host architecture +- if the host architecture is 32bit, and there is a 64bit package of a + 32bit installed one, the 64bit version was preferred + +Instead: +- first sort by architecture, preferring noarch packages, and + packages of the host architecture +- then sort by version + +This way, the higher version of the host architecture is preferred, +otherwise the higher version of any foreign architecture is chosen. +--- + src/ph_rpm.ml | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml +index e27d226..dbe3bda 100644 +--- a/src/ph_rpm.ml ++++ b/src/ph_rpm.ml +@@ -172,9 +172,14 @@ let rpm_package_of_string str = + * architecture. + *) + let cmp (pkg1, evr1) (pkg2, evr2) = +- let i = rpm_vercmp evr2 evr2 in ++ let weight_of_arch = function ++ | "noarch" -> 100 ++ | a when a = !rpm_arch -> 50 ++ | _ -> 0 ++ in ++ let i = compare (weight_of_arch pkg2.arch) (weight_of_arch pkg1.arch) in + if i <> 0 then i +- else compare_architecture pkg2.arch pkg1.arch ++ else rpm_vercmp evr2 evr2 + in + let rpms = List.sort cmp rpms in + fst (List.hd rpms) +-- +2.23.0 + diff --git a/0009-utils-remove-unused-compare_architecture-function.patch b/0009-utils-remove-unused-compare_architecture-function.patch new file mode 100644 index 0000000..299ea19 --- /dev/null +++ b/0009-utils-remove-unused-compare_architecture-function.patch @@ -0,0 +1,66 @@ +From b2401285cd3e3d42006fc164ef1f046cc35a50c4 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 12 Apr 2019 12:47:52 +0200 +Subject: [PATCH 09/12] utils: remove unused 'compare_architecture' function + +This was used only in the RPM package handler. +--- + src/utils.ml | 27 --------------------------- + src/utils.mli | 3 --- + 2 files changed, 30 deletions(-) + +diff --git a/src/utils.ml b/src/utils.ml +index f85418f..b25df88 100644 +--- a/src/utils.ml ++++ b/src/utils.ml +@@ -172,33 +172,6 @@ and split_version = function + ) in + first :: split_version rest + +-let compare_architecture a1 a2 = +- let index_of_architecture = function +- | "noarch" | "all" -> 100 +- | "i386" | "i486" | "i586" | "i686" | "x86_32" | "x86-32" -> 32 +- | "x86_64" | "x86-64" | "amd64" -> 64 +- | "armel" | "armhf" -> 32 +- | "aarch64" -> 64 +- | a when string_prefix "armv5" a -> 32 +- | a when string_prefix "armv6" a -> 32 +- | a when string_prefix "armv7" a -> 32 +- | a when string_prefix "armv8" a -> 64 +- | "hppa" | "parisc" -> 32 +- | "hppa64" | "parisc64" -> 64 +- | "ppc" | "ppc32" -> 32 +- | a when string_prefix "ppc64" a -> 64 +- | "sparc" | "sparc32" -> 32 +- | "sparc64" -> 64 +- | "ia64" -> 64 +- | "s390" -> 32 +- | "s390x" -> 64 +- | "alpha" -> 64 +- | a -> +- error "missing support for architecture '%s'\nIt may need to be added to supermin." +- a +- in +- compare (index_of_architecture a1) (index_of_architecture a2) +- + (* Parse a size field, eg. "10G". *) + let parse_size = + let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$" in +diff --git a/src/utils.mli b/src/utils.mli +index 7837dbb..b86586a 100644 +--- a/src/utils.mli ++++ b/src/utils.mli +@@ -86,9 +86,6 @@ val filter_map : ('a -> 'b option) -> 'a list -> 'b list + val compare_version : string -> string -> int + (** Compare two version-like strings. *) + +-val compare_architecture : string -> string -> int +- (** Compare two architecture strings. *) +- + val parse_size : string -> int64 + (** Parse a size field, eg. [10G] *) + +-- +2.23.0 + diff --git a/0010-rpm-provide-a-dummy-supermin_rpm_get_arch-implementa.patch b/0010-rpm-provide-a-dummy-supermin_rpm_get_arch-implementa.patch new file mode 100644 index 0000000..22ffd97 --- /dev/null +++ b/0010-rpm-provide-a-dummy-supermin_rpm_get_arch-implementa.patch @@ -0,0 +1,33 @@ +From c97b3917068597a0e68e88d9a905da766ade40da Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 24 May 2019 13:31:07 +0200 +Subject: [PATCH 10/12] rpm: provide a dummy supermin_rpm_get_arch + implementation + +Make sure supermin builds fine also without the RPM development files. + +Fixes commit e57e988c39aca015100fb92377dbd8d114c0bece. +--- + src/librpm-c.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/librpm-c.c b/src/librpm-c.c +index 2e2f048..523fe0b 100644 +--- a/src/librpm-c.c ++++ b/src/librpm-c.c +@@ -483,6 +483,12 @@ supermin_rpm_vercmp (value av, value bv) + abort (); + } + ++value ++supermin_rpm_get_arch (value unit) ++{ ++ abort (); ++} ++ + value + supermin_rpm_open (value debugv) + { +-- +2.23.0 + diff --git a/0011-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch b/0011-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch new file mode 100644 index 0000000..bddf338 --- /dev/null +++ b/0011-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch @@ -0,0 +1,58 @@ +From 487e8c964078f823646d3b0584745ab7d0ef99ca Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 26 Nov 2019 09:01:21 +0000 +Subject: [PATCH 11/12] ext2: Build symbolic links correctly (RHBZ#1770304). + +We created symlinks in two steps, by creating the empty inode and then +calling ext2fs_symlink to populate it. This created broken symlinks +where the directory name contained a / character, eg: + +lrwxrwxrwx 1 root root 7 Nov 26 08:43 /bin -> usr/bin +lrwxrwxrwx 1 root root 7 Nov 26 08:43 /lib -> usr/lib +lrwxrwxrwx 1 root root 9 Nov 26 08:43 /lib64 -> usr/lib64 +lrwxrwxrwx 1 root root 8 Nov 26 08:43 /sbin -> usr/sbin +lrwxrwxrwx 1 root root 7 Nov 26 08:38 bin -> usr/bin + +This breaks with Linux >= 5.3.8, most likely because of extra +validation now being done at the VFS layer: + +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/readdir.c?id=8a23eb804ca4f2be909e372cf5a9e7b30ae476cd + +It's unnecessary to create the empty inode since ext2fs_symlink can +create the inode for us perfectly fine if we simply pass ino == 0, and +it creates them correctly too. + +Thanks: Toolybird for identifying the problem and kernel patch. +--- + src/ext2fs-c.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c +index e8ab972..8903f74 100644 +--- a/src/ext2fs-c.c ++++ b/src/ext2fs-c.c +@@ -782,12 +782,6 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) + } + /* Create a symlink. */ + else if (S_ISLNK (statbuf.st_mode)) { +- ext2_ino_t ino; +- ext2_empty_inode (data->fs, dir_ino, dirname, basename, +- statbuf.st_mode, statbuf.st_uid, statbuf.st_gid, +- statbuf.st_ctime, statbuf.st_atime, statbuf.st_mtime, +- 0, 0, EXT2_FT_SYMLINK, &ino); +- + char *buf = malloc (statbuf.st_size+1); + if (buf == NULL) + caml_raise_out_of_memory (); +@@ -797,7 +791,7 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) + if (r > statbuf.st_size) + r = statbuf.st_size; + buf[r] = '\0'; +- ext2fs_symlink (data->fs, dir_ino, ino, dest, buf); ++ ext2fs_symlink (data->fs, dir_ino, 0, basename, buf); + free (buf); + } + /* Create directory. */ +-- +2.23.0 + diff --git a/0012-ext2-Expand-directory-when-adding-symlinks-RHBZ-1770.patch b/0012-ext2-Expand-directory-when-adding-symlinks-RHBZ-1770.patch new file mode 100644 index 0000000..5802837 --- /dev/null +++ b/0012-ext2-Expand-directory-when-adding-symlinks-RHBZ-1770.patch @@ -0,0 +1,42 @@ +From 62d5c774d6c8fcac11e28fcba99754b5478e5088 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 10 Dec 2019 18:43:00 +0000 +Subject: [PATCH 12/12] ext2: Expand directory when adding symlinks + (RHBZ#1770304). + +This produced very weird bugs with missing symlinks under +certain conditions, see: +https://bugzilla.redhat.com/show_bug.cgi?id=1781803 + +Fixes commit 487e8c964078f823646d3b0584745ab7d0ef99ca. +--- + src/ext2fs-c.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c +index 8903f74..0000865 100644 +--- a/src/ext2fs-c.c ++++ b/src/ext2fs-c.c +@@ -791,7 +791,18 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) + if (r > statbuf.st_size) + r = statbuf.st_size; + buf[r] = '\0'; +- ext2fs_symlink (data->fs, dir_ino, 0, basename, buf); ++ symlink_again: ++ err = ext2fs_symlink (data->fs, dir_ino, 0, basename, buf); ++ if (err) { ++ if (err == EXT2_ET_DIR_NO_SPACE) { ++ err = ext2fs_expand_dir (data->fs, dir_ino); ++ if (err) ++ ext2_error_to_exception ("ext2fs_expand_dir", err, dirname); ++ goto symlink_again; ++ } ++ else ++ ext2_error_to_exception ("ext2fs_symlink", err, basename); ++ } + free (buf); + } + /* Create directory. */ +-- +2.23.0 + diff --git a/supermin.spec b/supermin.spec index 4df1f69..d338815 100644 --- a/supermin.spec +++ b/supermin.spec @@ -26,7 +26,7 @@ Summary: Tool for creating supermin appliances Name: supermin Version: 5.1.20 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv2+ %if 0%{?rhel} >= 7 @@ -46,14 +46,19 @@ Source1: http://libguestfs.org/download/supermin/%{name}-%{version}.tar.gz Source2: libguestfs.keyring %endif -# Upstream patches to diagnose possible F29 issue: -# https://www.redhat.com/archives/libguestfs/2019-January/thread.html#00168 -Patch1: 0001-rpm-extend-the-Multiple_matches-exception.patch -Patch2: 0002-Print-Librpm.Multiple_matches-exceptions.patch - -# Upstream patch to fix symlinks. -# https://bugzilla.redhat.com/show_bug.cgi?id=1770304 -Patch3: 0001-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch +# Upstream patches since 5.1.20 was released. +Patch0001: 0001-rpm-extend-the-Multiple_matches-exception.patch +Patch0002: 0002-Print-Librpm.Multiple_matches-exceptions.patch +Patch0003: 0003-Use-external-command-mv-to-rename-old-output-directo.patch +Patch0004: 0004-Add-OpenMandriva-support-RHBZ-1694267.patch +Patch0005: 0005-rpm-do-not-unpack-parameters.patch +Patch0006: 0006-rpm-fix-version-comparison.patch +Patch0007: 0007-rpm-query-the-RPM-architecture.patch +Patch0008: 0008-rpm-fix-package-sorting-RHBZ-1696822.patch +Patch0009: 0009-utils-remove-unused-compare_architecture-function.patch +Patch0010: 0010-rpm-provide-a-dummy-supermin_rpm_get_arch-implementa.patch +Patch0011: 0011-ext2-Build-symbolic-links-correctly-RHBZ-1770304.patch +Patch0012: 0012-ext2-Expand-directory-when-adding-symlinks-RHBZ-1770.patch BuildRequires: /usr/bin/pod2man BuildRequires: /usr/bin/pod2html @@ -175,6 +180,10 @@ make check || { %changelog +* Tue Dec 10 2019 Richard W.M. Jones - 5.1.20-11 +- Add further patch to fix symlinks (RHBZ#1770304). +- Add all patches since 5.1.20 was released. + * Thu Nov 28 2019 Richard W.M. Jones - 5.1.20-10 - Add upstream patch to fix symlinks on recent kernels (RHBZ#1770304).