diff --git a/Generate-digest-lists-before-calling-genCpioAndHeader.patch b/Generate-digest-lists-before-calling-genCpioAndHeader.patch new file mode 100644 index 0000000..488c7c2 --- /dev/null +++ b/Generate-digest-lists-before-calling-genCpioAndHeader.patch @@ -0,0 +1,256 @@ +From 6b50298b38da203d4402855bf0caea61bcc5e8d6 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Wed, 12 Aug 2020 18:23:42 +0200 +Subject: [PATCH] Generate digest lists before calling genCpioListAndHeader() + +--- + build/files.c | 184 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 148 insertions(+), 36 deletions(-) + +diff --git a/build/files.c b/build/files.c +index ab6938d8c..454ce23bf 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -987,19 +987,149 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid) + * @param pkg (sub) package + * @param isSrc pass 1 for source packages 0 otherwise + */ +-static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) ++static void genDigestListInput(FileList fl, Package pkg, int isSrc) + { + FileListRec flp; + char buf[BUFSIZ]; + char file_info[BUFSIZ]; + char file_digest[128 * 2 + 1]; ++ int i; ++ uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; ++ Header h = pkg->header; /* just a shortcut */ ++ ++ /* ++ * See if non-md5 file digest algorithm is requested. If not ++ * specified, quietly assume md5. Otherwise check if supported type. ++ */ ++ digestalgo = rpmExpandNumeric(isSrc ? "%{_source_filedigest_algorithm}" : ++ "%{_binary_filedigest_algorithm}"); ++ if (digestalgo == 0) { ++ digestalgo = defaultalgo; ++ } ++ ++ if (rpmDigestLength(digestalgo) == 0) { ++ rpmlog(RPMLOG_WARNING, ++ _("Unknown file digest algorithm %u, falling back to MD5\n"), ++ digestalgo); ++ digestalgo = defaultalgo; ++ } ++ ++ /* Sort the big list */ ++ if (fl->files.recs) { ++ qsort(fl->files.recs, fl->files.used, ++ sizeof(*(fl->files.recs)), compareFileListRecs); ++ } ++ ++ /* Generate the header. */ ++ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { ++ /* Merge duplicate entries. */ ++ while (i < (fl->files.used - 1) && ++ rstreq(flp->cpioPath, flp[1].cpioPath)) { ++ ++ /* Two entries for the same file found, merge the entries. */ ++ /* Note that an %exclude is a duplication of a file reference */ ++ ++ /* file flags */ ++ flp[1].flags |= flp->flags; ++ ++ if (!(flp[1].flags & RPMFILE_EXCLUDE)) ++ rpmlog(RPMLOG_WARNING, _("File listed twice: %s\n"), ++ flp->cpioPath); ++ ++ /* file mode */ ++ if (S_ISDIR(flp->fl_mode)) { ++ if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) < ++ (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE))) ++ flp[1].fl_mode = flp->fl_mode; ++ } else { ++ if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) < ++ (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE))) ++ flp[1].fl_mode = flp->fl_mode; ++ } ++ ++ /* uid */ ++ if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) < ++ (flp->specdFlags & (SPECD_UID | SPECD_DEFUID))) ++ { ++ flp[1].fl_uid = flp->fl_uid; ++ flp[1].uname = flp->uname; ++ } ++ ++ /* gid */ ++ if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) < ++ (flp->specdFlags & (SPECD_GID | SPECD_DEFGID))) ++ { ++ flp[1].fl_gid = flp->fl_gid; ++ flp[1].gname = flp->gname; ++ } ++ ++ /* verify flags */ ++ if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) < ++ (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY))) ++ flp[1].verifyFlags = flp->verifyFlags; ++ ++ /* XXX to-do: language */ ++ ++ flp++; i++; ++ } ++ ++ /* Skip files that were marked with %exclude. */ ++ if (flp->flags & RPMFILE_EXCLUDE) ++ { ++ argvAdd(&pkg->fileExcludeList, flp->cpioPath); ++ continue; ++ } ++ ++ buf[0] = '\0'; ++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) ++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1, ++ (unsigned char *)buf); ++ headerPutString(h, RPMTAG_FILEDIGESTS, buf); ++ snprintf(file_digest, sizeof(file_digest), "%s", buf); ++ ++ if (check_fileList_bin_pkg && S_ISREG(flp->fl_mode) && ++ !(flp->flags & RPMFILE_GHOST)) { ++ appendStringBuf(check_fileList_bin_pkg, "path="); ++ appendStringBuf(check_fileList_bin_pkg, flp->diskPath); ++ snprintf(file_info, sizeof(file_info), ++ "|digestalgopgp=%d|digest=%s|mode=%d" ++ "|uname=%s|gname=%s|caps=%s\n", ++ digestalgo, file_digest, flp->fl_mode, ++ rpmstrPoolStr(fl->pool, flp->uname), ++ rpmstrPoolStr(fl->pool, flp->gname), flp->caps && ++ strlen(flp->caps) ? flp->caps : ""); ++ appendStringBuf(check_fileList_bin_pkg, file_info); ++ } ++ } ++ ++ if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) ++ fl->processingFailed = 1; ++} ++ ++/** ++ * Add file entries to header. ++ * @todo Should directories have %doc/%config attributes? (#14531) ++ * @todo Remove RPMTAG_OLDFILENAMES, add dirname/basename instead. ++ * @param fl package file tree walk data ++ * @param pkg (sub) package ++ * @param isSrc pass 1 for source packages 0 otherwise ++ */ ++static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) ++{ ++ FileListRec flp; ++ char buf[BUFSIZ]; + int i, npaths = 0; + uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; + rpm_loff_t totalFileSize = 0; + Header h = pkg->header; /* just a shortcut */ +- int override_date = 0, processed = 0; ++ int override_date = 0; + time_t source_date_epoch; + char *srcdate = getenv("SOURCE_DATE_EPOCH"); ++ struct rpmtd_s oldfiledigests; ++ ++ headerGet(h, RPMTAG_FILEDIGESTS, &oldfiledigests, HEADERGET_ALLOC); ++ headerDel(h, RPMTAG_FILEDIGESTS); ++ rpmtdInit(&oldfiledigests); + + /* Limit the maximum date to SOURCE_DATE_EPOCH if defined + * similar to the tar --clamp-mtime option +@@ -1067,9 +1197,8 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + + pkg->dpaths = xmalloc((fl->files.used + 1) * sizeof(*pkg->dpaths)); + +-process_files: + /* Generate the header. */ +- for (i = processed, flp = fl->files.recs + processed; i < fl->files.used; i++, flp++) { ++ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { + rpm_ino_t fileid = flp - fl->files.recs; + + /* Merge duplicate entries. */ +@@ -1194,13 +1323,17 @@ process_files: + if (fl->haveCaps) { + headerPutString(h, RPMTAG_FILECAPS, flp->caps); + } +- ++ + buf[0] = '\0'; +- if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) +- (void) rpmDoDigest(digestalgo, flp->diskPath, 1, +- (unsigned char *)buf); +- headerPutString(h, RPMTAG_FILEDIGESTS, buf); +- snprintf(file_digest, sizeof(file_digest), "%s", buf); ++ if (strstr(flp->diskPath, DIGEST_LIST_DIR) || !oldfiledigests.count) { ++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) ++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1, ++ (unsigned char *)buf); ++ headerPutString(h, RPMTAG_FILEDIGESTS, buf); ++ } else { ++ headerPutString(h, RPMTAG_FILEDIGESTS, ++ rpmtdNextString(&oldfiledigests)); ++ } + + buf[0] = '\0'; + if (S_ISLNK(flp->fl_mode)) { +@@ -1241,33 +1374,7 @@ process_files: + flp->flags &= PARSEATTR_MASK; + + headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1); +- +- if (!processed && check_fileList_bin_pkg && S_ISREG(flp->fl_mode) && +- !(flp->flags & RPMFILE_GHOST)) { +- appendStringBuf(check_fileList_bin_pkg, "path="); +- appendStringBuf(check_fileList_bin_pkg, flp->diskPath); +- snprintf(file_info, sizeof(file_info), +- "|digestalgopgp=%d|digest=%s|mode=%d" +- "|uname=%s|gname=%s|caps=%s\n", +- digestalgo, file_digest, flp->fl_mode, +- rpmstrPoolStr(fl->pool, flp->uname), +- rpmstrPoolStr(fl->pool, flp->gname), flp->caps && +- strlen(flp->caps) ? flp->caps : ""); +- appendStringBuf(check_fileList_bin_pkg, file_info); +- } +- } +- +- if (!processed) { +- if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) { +- fl->processingFailed = 1; +- } else if (i < fl->files.used) { +- pkg->dpaths = xrealloc(pkg->dpaths, +- (fl->files.used + 1) * sizeof(*pkg->dpaths)); +- processed = i; +- goto process_files; +- } + } +- + pkg->dpaths[npaths] = NULL; + + if (totalFileSize < UINT32_MAX) { +@@ -1306,6 +1413,7 @@ process_files: + /* Binary packages with dirNames cannot be installed by legacy rpm. */ + (void) rpmlibNeedsFeature(pkg, "CompressedFileNames", "3.0.4-1"); + } ++ rpmtdFreeData(&oldfiledigests); + } + + static FileRecords FileRecordsFree(FileRecords files) +@@ -2776,6 +2884,10 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + if (checkHardLinks(&fl.files)) + (void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1"); + ++ genDigestListInput(&fl, pkg, 0); ++ if (fl.processingFailed) ++ goto exit; ++ + genCpioListAndHeader(&fl, pkg, 0); + + exit: +-- +2.27.GIT + diff --git a/rpm.spec b/rpm.spec index 64776f2..fbe5024 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,6 +1,6 @@ Name: rpm Version: 4.15.1 -Release: 20 +Release: 21 Summary: RPM Package Manager License: GPLv2+ URL: http://www.rpm.org/ @@ -78,6 +78,8 @@ Patch66: backport-Always-open-and-initialize-the-entire-database-at-on.patch Patch67: backport-Stop-on-first-failure-when-trying-to-open-a-database.patch Patch68: backport-Only-attempt-loading-the-keyring-once-the-rpmdb-is-o.patch +Patch69: Generate-digest-lists-before-calling-genCpioAndHeader.patch + BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel BuildRequires: zlib-devel libzstd-devel xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils @@ -344,6 +346,12 @@ make check || (cat tests/rpmtests.log; exit 0) %{_mandir}/man1/gendiff.1* %changelog +* Sat Feb 27 2021 Anakin Zhang - 4.15.1-21 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:reorder digest lists to fix anaconda build failure + * Tue Jan 12 2021 panxiaohe - 4.15.1-20 - Type:enhancement - ID:NA