From 6af8291ba9ba08049cec670ab34c0fc9a85ebbbf Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 14 Feb 2020 15:52:15 +0100 Subject: [PATCH 1/3] fpLookupSubdir: get rid of a poolid->str->poolid roundtrip Use doLookupId() instead of doLookup() so that we can reuse the baseNameId. --- lib/fprint.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/fprint.c b/lib/fprint.c index 5cae13b3c3..bb624212b6 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -372,7 +372,7 @@ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint rpmfiles foundfi = rpmteFiles(recs[i].p); char const *linktarget = rpmfilesFLink(foundfi, recs[i].fileno); char *link; - const char *bn; + rpmsid linkId; /* Ignore already removed (by eg %pretrans) links */ if (linktarget && rpmteType(recs[i].p) == TR_REMOVED) { @@ -399,15 +399,13 @@ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint rstrscat(&link, dn, subDir ? subDir : "", "/", NULL); } rstrscat(&link, linktarget, "/", NULL); - if (strlen(currentsubdir + bnEnd)) { + if (currentsubdir[bnEnd]) rstrscat(&link, currentsubdir + bnEnd, NULL); - } - - bn = rpmstrPoolStr(fpc->pool, fp->baseNameId); - doLookup(fpc, link, bn, fp); /* modifies the fingerprint! */ - + linkId = rpmstrPoolId(fpc->pool, link, 1); free(link); + /* this modifies the fingerprint! */ + doLookupId(fpc, linkId, fp->baseNameId, fp); found = 1; break; } From 1c9343142a728dce571ee0c8ce4f6fae42354588 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 14 Feb 2020 15:54:32 +0100 Subject: [PATCH 2/3] Reduce the number of calls to fpLookupSubdir() If the entry/subdirid parts of the fingerprint are equal to the ones of the last added fingerprint, we know that calling fpLookupSubdir() will not modify anything. So skip the call in that case. --- lib/fprint.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/fprint.c b/lib/fprint.c index bb624212b6..213bd65ae1 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -497,7 +497,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { - fingerPrint *fpList; + fingerPrint *fpList, *lastfp = NULL; (void) rpmsqPoll(); if ((fi = rpmteFiles(p)) == NULL) @@ -511,11 +511,17 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) struct rpmffi_s ffi; if (XFA_SKIPPING(rpmfsGetAction(fs, i))) continue; - if (havesymlinks) - fpLookupSubdir(symlinks, fpc, fpList + i); + if (havesymlinks) { + /* if the entry/subdirid matches the one from the + * last entry we do not need to call fpLookupSubdir */ + if (!lastfp || lastfp->entry != fpList[i].entry || + lastfp->subDirId != fpList[i].subDirId) + fpLookupSubdir(symlinks, fpc, fpList + i); + } ffi.p = p; ffi.fileno = i; rpmFpHashAddEntry(fpc->fp, fpList + i, ffi); + lastfp = fpList + i; } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); rpmfilesFree(fi); From 4db183db61ca56d035712ca752234aa7c8e8b097 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Wed, 19 Feb 2020 11:29:28 +0100 Subject: [PATCH 3/3] Only look at symlinks in new packages in fpLookupSubdir For already installed packages only the on-disk state matters, which is already picked up by the fingerprinting code. --- lib/fprint.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/fprint.c b/lib/fprint.c index 213bd65ae1..5744566caf 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -374,21 +374,12 @@ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint char *link; rpmsid linkId; - /* Ignore already removed (by eg %pretrans) links */ - if (linktarget && rpmteType(recs[i].p) == TR_REMOVED) { - char *path = rpmfilesFN(foundfi, recs[i].fileno); - struct stat sb; - if (lstat(path, &sb) == -1) - linktarget = NULL; - free(path); - } - foundfi = rpmfilesFree(foundfi); if (!linktarget || *linktarget == '\0') continue; - /* this "directory" is a symlink */ + /* this "directory" will be symlink */ link = NULL; if (*linktarget != '/') { const char *dn, *subDir = NULL; @@ -459,9 +450,10 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) rpmFpHash symlinks = rpmFpHashCreate(fileCount/16+16, fpHashFunction, fpEqual, NULL, NULL); + /* populate the fingerprints of all packages in the transaction */ + /* also create a hash of all symlinks in the new packages */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { - fingerPrint *fpList; (void) rpmsqPoll(); if ((fi = rpmteFiles(p)) == NULL) @@ -471,21 +463,25 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) rpmfilesFpLookup(fi, fpc); fs = rpmteGetFileStates(p); fc = rpmfsFC(fs); - fpList = rpmfilesFps(fi); - /* collect symbolic links */ - for (i = 0; i < fc; i++) { - struct rpmffi_s ffi; - char const *linktarget; - if (XFA_SKIPPING(rpmfsGetAction(fs, i))) - continue; - linktarget = rpmfilesFLink(fi, i); - if (!(linktarget && *linktarget != '\0')) - continue; - ffi.p = p; - ffi.fileno = i; - rpmFpHashAddEntry(symlinks, fpList + i, ffi); - havesymlinks = 1; + + if (rpmteType(p) != TR_REMOVED) { + fingerPrint *fpList = rpmfilesFps(fi); + /* collect symbolic links */ + for (i = 0; i < fc; i++) { + struct rpmffi_s ffi; + char const *linktarget; + if (XFA_SKIPPING(rpmfsGetAction(fs, i))) + continue; + linktarget = rpmfilesFLink(fi, i); + if (!(linktarget && *linktarget != '\0')) + continue; + ffi.p = p; + ffi.fileno = i; + rpmFpHashAddEntry(symlinks, fpList + i, ffi); + havesymlinks = 1; + } } + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc); rpmfilesFree(fi); }