teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame 0027-Unbreak-short-circuited-binary-builds.patch

Igor Gnatenko 082d5d
From 6328e1e0da3ba26885f095ccbd83d223d5830527 Mon Sep 17 00:00:00 2001
Igor Gnatenko 082d5d
From: Panu Matilainen <pmatilai@redhat.com>
Igor Gnatenko 082d5d
Date: Thu, 5 Jan 2017 13:47:28 +0200
Mark Wielaard 284dc3
Subject: [PATCH] Unbreak short-circuited binary builds
Mark Wielaard 027778
Igor Gnatenko 082d5d
Commit bbfe1f86b2e4b5c0bd499d9f3dd9de9c9c20fff2 broke short-circuited
Igor Gnatenko 082d5d
binary builds (which can be handy for testing when working on large
Igor Gnatenko 082d5d
packages), eg:
Igor Gnatenko 082d5d
     rpmbuild -bi foo.spec; rpmbuild -bb --short-circuit foo.spec
Igor Gnatenko 082d5d
Igor Gnatenko 082d5d
The problem is that in a short-circuited build all the links already
Igor Gnatenko 082d5d
exist and point to the right place, but the code doesn't realize this
Igor Gnatenko 082d5d
and creates new links instead, which leaves the old links unowned
Igor Gnatenko 082d5d
in the buildroot which ultimately causes the build to fail with
Igor Gnatenko 082d5d
"Installed (but unpackaged) file(s) found" for the previously created
Igor Gnatenko 082d5d
build-id links.
Igor Gnatenko 082d5d
Igor Gnatenko 082d5d
When checking for pre-existing links see if they already point to
Igor Gnatenko 082d5d
the right file and in that case just reuse it instead of creating new ones.
Igor Gnatenko 082d5d
Keep track of duplicate build-ids found by noticing existing links that
Igor Gnatenko 082d5d
point to different targets. But don't do this for compat links, they should
Igor Gnatenko 082d5d
just point to the last (duplicate) main build-id symlink found.
Igor Gnatenko 082d5d
Igor Gnatenko 082d5d
Signed-off-by: Mark Wielaard <mark@klomp.org>
Igor Gnatenko 082d5d
(cherry picked from commit eea78b023539875309b7d38e4c8924f647644924)
Igor Gnatenko 082d5d
---
Igor Gnatenko 082d5d
 build/files.c | 71 ++++++++++++++++++++++++++++++++++++++++++-----------------
Igor Gnatenko 082d5d
 1 file changed, 51 insertions(+), 20 deletions(-)
Mark Wielaard 027778
Mark Wielaard 027778
diff --git a/build/files.c b/build/files.c
Igor Gnatenko 082d5d
index 9f7def78c..2f02587f0 100644
Mark Wielaard 027778
--- a/build/files.c
Mark Wielaard 027778
+++ b/build/files.c
Igor Gnatenko 082d5d
@@ -1565,11 +1565,12 @@ exit:
Mark Wielaard 027778
 
Mark Wielaard 027778
 static int addNewIDSymlink(FileList fl,
Mark Wielaard 027778
 			   char *targetpath, char *idlinkpath,
Mark Wielaard 027778
-			   int isDbg, int isCompat)
Mark Wielaard 027778
+			   int isDbg, int *dups)
Mark Wielaard 027778
 {
Mark Wielaard 027778
     const char *linkerr = _("failed symlink");
Mark Wielaard 027778
     int rc = 0;
Mark Wielaard 027778
     int nr = 0;
Mark Wielaard 027778
+    int exists = 0;
Mark Wielaard 027778
     char *origpath, *linkpath;
Mark Wielaard 027778
 
Mark Wielaard 027778
     if (isDbg)
Igor Gnatenko 082d5d
@@ -1579,6 +1580,26 @@ static int addNewIDSymlink(FileList fl,
Mark Wielaard 027778
     origpath = linkpath;
Mark Wielaard 027778
 
Mark Wielaard 027778
     while (faccessat(AT_FDCWD, linkpath, F_OK, AT_SYMLINK_NOFOLLOW) == 0) {
Mark Wielaard 027778
+        /* We don't care about finding dups for compat links, they are
Mark Wielaard 027778
+	   OK as is.  Otherwise we will need to double check if
Mark Wielaard 027778
+	   existing link points to the correct target. */
Mark Wielaard 027778
+	if (dups == NULL)
Mark Wielaard 027778
+	  {
Mark Wielaard 027778
+	    exists = 1;
Mark Wielaard 027778
+	    break;
Mark Wielaard 027778
+	  }
Mark Wielaard 027778
+
Mark Wielaard 027778
+	char ltarget[PATH_MAX];
Mark Wielaard 027778
+	ssize_t llen;
Mark Wielaard 027778
+	/* In short-circuited builds the link might already exist  */
Mark Wielaard 027778
+	if ((llen = readlink(linkpath, ltarget, sizeof(ltarget)-1)) != -1) {
Mark Wielaard 027778
+	    ltarget[llen] = '\0';
Mark Wielaard 027778
+	    if (rstreq(ltarget, targetpath)) {
Mark Wielaard 027778
+		exists = 1;
Mark Wielaard 027778
+		break;
Mark Wielaard 027778
+	    }
Mark Wielaard 027778
+	}
Mark Wielaard 027778
+
Mark Wielaard 027778
 	if (nr > 0)
Mark Wielaard 027778
 	    free(linkpath);
Mark Wielaard 027778
 	nr++;
Igor Gnatenko 082d5d
@@ -1586,21 +1607,16 @@ static int addNewIDSymlink(FileList fl,
Mark Wielaard 027778
 		  isDbg ? ".debug" : "");
Mark Wielaard 027778
     }
Mark Wielaard 027778
 
Mark Wielaard 027778
-    char *symtarget = targetpath;
Mark Wielaard 027778
-    if (nr > 0 && isCompat)
Mark Wielaard 027778
-	rasprintf (&symtarget, "%s.%d", targetpath, nr);
Mark Wielaard 027778
-
Mark Wielaard 027778
-    if (symlink(symtarget, linkpath) < 0) {
Mark Wielaard 027778
+    if (!exists && symlink(targetpath, linkpath) < 0) {
Mark Wielaard 027778
 	rc = 1;
Mark Wielaard 027778
 	rpmlog(RPMLOG_ERR, "%s: %s -> %s: %m\n",
Mark Wielaard 027778
-	       linkerr, linkpath, symtarget);
Mark Wielaard 027778
+	       linkerr, linkpath, targetpath);
Mark Wielaard 027778
     } else {
Mark Wielaard 027778
 	fl->cur.isDir = 0;
Mark Wielaard 027778
 	rc = addFile(fl, linkpath, NULL);
Mark Wielaard 027778
     }
Mark Wielaard 027778
 
Mark Wielaard 027778
-    /* Don't warn (again) if this is a compat id-link, we retarget it. */
Mark Wielaard 027778
-    if (nr > 0 && !isCompat) {
Mark Wielaard 027778
+    if (nr > 0) {
Mark Wielaard 027778
 	/* Lets see why there are multiple build-ids. If the original
Mark Wielaard 027778
 	   targets are hard linked, then it is OK, otherwise warn
Mark Wielaard 027778
 	   something fishy is going on. Would be nice to call
Igor Gnatenko 082d5d
@@ -1629,8 +1645,8 @@ static int addNewIDSymlink(FileList fl,
Mark Wielaard 027778
 	free(origpath);
Mark Wielaard 027778
     if (nr > 0)
Mark Wielaard 027778
 	free(linkpath);
Mark Wielaard 027778
-    if (nr > 0 && isCompat)
Mark Wielaard 027778
-	free(symtarget);
Mark Wielaard 027778
+    if (dups != NULL)
Mark Wielaard 027778
+      *dups = nr;
Mark Wielaard 027778
 
Mark Wielaard 027778
     return rc;
Mark Wielaard 027778
 }
Igor Gnatenko 082d5d
@@ -1872,6 +1888,7 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard 027778
 			|| (rc = addFile(fl, buildidsubdir, NULL)) == 0) {
Mark Wielaard 027778
 			char *linkpattern, *targetpattern;
Mark Wielaard 027778
 			char *linkpath, *targetpath;
Mark Wielaard 027778
+			int dups = 0;
Mark Wielaard 027778
 			if (isDbg) {
Mark Wielaard 027778
 			    linkpattern = "%s/%s";
Mark Wielaard 027778
 			    targetpattern = "../../../../..%s";
Igor Gnatenko 082d5d
@@ -1883,7 +1900,7 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard 027778
 				  buildidsubdir, &ids[i][2]);
Mark Wielaard 027778
 			rasprintf(&targetpath, targetpattern, paths[i]);
Mark Wielaard 027778
 			rc = addNewIDSymlink(fl, targetpath, linkpath,
Mark Wielaard 027778
-					     isDbg, 0);
Mark Wielaard 027778
+					     isDbg, &dups);
Mark Wielaard 027778
 
Mark Wielaard 027778
 			/* We might want to have a link from the debug
Mark Wielaard 027778
 			   build_ids dir to the main one. We create it
Igor Gnatenko 082d5d
@@ -1906,16 +1923,30 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard 027778
 			    && build_id_links == BUILD_IDS_COMPAT) {
Mark Wielaard 027778
 			    /* buildidsubdir already points to the
Mark Wielaard 027778
 			       debug buildid. We just need to setup
Mark Wielaard 027778
-			       the symlink to the main one.  */
Mark Wielaard 027778
+			       the symlink to the main one. There
Mark Wielaard 027778
+			       might be duplicate IDs, those are found
Mark Wielaard 027778
+			       by the addNewIDSymlink above. Target
Mark Wielaard 027778
+			       the last found duplicate, if any. */
Mark Wielaard 027778
 			    free(linkpath);
Mark Wielaard 027778
 			    free(targetpath);
Mark Wielaard 027778
-			    rasprintf(&linkpath, "%s/%s",
Mark Wielaard 027778
-				      buildidsubdir, &ids[i][2]);
Mark Wielaard 027778
-			    rasprintf(&targetpath,
Mark Wielaard 027778
-				      "../../../.build-id%s/%s",
Mark Wielaard 027778
-				      subdir, &ids[i][2]);
Mark Wielaard 027778
+			    if (dups == 0)
Mark Wielaard 027778
+			      {
Mark Wielaard 027778
+				rasprintf(&linkpath, "%s/%s",
Mark Wielaard 027778
+					  buildidsubdir, &ids[i][2]);
Mark Wielaard 027778
+				rasprintf(&targetpath,
Mark Wielaard 027778
+					  "../../../.build-id%s/%s",
Mark Wielaard 027778
+					  subdir, &ids[i][2]);
Mark Wielaard 027778
+			      }
Mark Wielaard 027778
+			    else
Mark Wielaard 027778
+			      {
Mark Wielaard 027778
+				rasprintf(&linkpath, "%s/%s.%d",
Mark Wielaard 027778
+					  buildidsubdir, &ids[i][2], dups);
Mark Wielaard 027778
+				rasprintf(&targetpath,
Mark Wielaard 027778
+					  "../../../.build-id%s/%s.%d",
Mark Wielaard 027778
+					  subdir, &ids[i][2], dups);
Mark Wielaard 027778
+			      }
Mark Wielaard 027778
 			    rc = addNewIDSymlink(fl, targetpath, linkpath,
Mark Wielaard 027778
-						 0, 1);
Mark Wielaard 027778
+						 0, NULL);
Mark Wielaard 027778
 			}
Mark Wielaard 027778
 
Mark Wielaard 027778
 			if (rc == 0 && isDbg
Igor Gnatenko 082d5d
@@ -1953,7 +1984,7 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard 027778
 				rasprintf(&targetpath, "../../../../..%s",
Mark Wielaard 027778
 					  targetstr);
Mark Wielaard 027778
 				rc = addNewIDSymlink(fl, targetpath,
Mark Wielaard 027778
-						     linkpath, 0, 0);
Mark Wielaard 027778
+						     linkpath, 0, &dups);
Mark Wielaard 027778
 				free(targetstr);
Mark Wielaard 027778
 			    }
Mark Wielaard 027778
 			}