teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame 0022-unbreak-short-circuit.patch

Mark Wielaard 027778
commit eea78b023539875309b7d38e4c8924f647644924
Mark Wielaard 027778
Author: Panu Matilainen <pmatilai@redhat.com>
Mark Wielaard 027778
Date:   Thu Jan 5 13:47:28 2017 +0200
Mark Wielaard 027778
Mark Wielaard 027778
    Unbreak short-circuited binary builds
Mark Wielaard 027778
    
Mark Wielaard 027778
    Commit bbfe1f86b2e4b5c0bd499d9f3dd9de9c9c20fff2 broke short-circuited
Mark Wielaard 027778
    binary builds (which can be handy for testing when working on large
Mark Wielaard 027778
    packages), eg:
Mark Wielaard 027778
         rpmbuild -bi foo.spec; rpmbuild -bb --short-circuit foo.spec
Mark Wielaard 027778
    
Mark Wielaard 027778
    The problem is that in a short-circuited build all the links already
Mark Wielaard 027778
    exist and point to the right place, but the code doesn't realize this
Mark Wielaard 027778
    and creates new links instead, which leaves the old links unowned
Mark Wielaard 027778
    in the buildroot which ultimately causes the build to fail with
Mark Wielaard 027778
    "Installed (but unpackaged) file(s) found" for the previously created
Mark Wielaard 027778
    build-id links.
Mark Wielaard 027778
    
Mark Wielaard 027778
    When checking for pre-existing links see if they already point to
Mark Wielaard 027778
    the right file and in that case just reuse it instead of creating new ones.
Mark Wielaard 027778
    Keep track of duplicate build-ids found by noticing existing links that
Mark Wielaard 027778
    point to different targets. But don't do this for compat links, they should
Mark Wielaard 027778
    just point to the last (duplicate) main build-id symlink found.
Mark Wielaard 027778
    
Mark Wielaard 027778
    Signed-off-by: Mark Wielaard <mark@klomp.org>
Mark Wielaard 027778
Mark Wielaard 027778
diff --git a/build/files.c b/build/files.c
Mark Wielaard 027778
index cca14b9..93021d1 100644
Mark Wielaard 027778
--- a/build/files.c
Mark Wielaard 027778
+++ b/build/files.c
Mark Wielaard 027778
@@ -1592,11 +1592,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)
Mark Wielaard 027778
@@ -1606,6 +1607,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++;
Mark Wielaard 027778
@@ -1613,21 +1634,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
Mark Wielaard 027778
@@ -1656,8 +1672,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
 }
Mark Wielaard 027778
@@ -1897,6 +1913,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";
Mark Wielaard 027778
@@ -1908,7 +1925,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
Mark Wielaard 027778
@@ -1931,16 +1948,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
Mark Wielaard 027778
@@ -1978,7 +2009,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
 			}