File speedup4.patch of Package rpm

From ec305795a302d226343e69031ff2024dfcde69c0 Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex.kanavin@gmail.com>
Date: Thu, 8 Jun 2017 17:08:09 +0300
Subject: [PATCH 3/3] build/pack.c: remove static local variables from
 buildHost() and getBuildTime()

Their use is causing difficult to diagnoze data races when building multiple
packages in parallel, and is a bad idea in general, as it also makes it more
difficult to reason about code.

Upstream-Status: Submitted [https://github.com/rpm-software-management/rpm/pull/226]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>


Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
---
 build/build.c             | 54 ++++++++++++++++++++++++++++--
 build/pack.c              | 84 +++++++++--------------------------------------
 build/rpmbuild_internal.h |  8 +++--
 3 files changed, 74 insertions(+), 72 deletions(-)

Index: rpm-4.14.1/build/build.c
===================================================================
--- rpm-4.14.1.orig/build/build.c
+++ rpm-4.14.1/build/build.c
@@ -6,6 +6,8 @@
 #include "system.h"

 #include <errno.h>
+#include <netdb.h>
+#include <time.h>
 #include <sys/wait.h>

 #include <rpm/rpmlog.h>
@@ -16,6 +18,50 @@

 #include "debug.h"

+static rpm_time_t getBuildTime(void)
+{
+    rpm_time_t buildTime = 0;
+    char *srcdate;
+    time_t epoch;
+    char *endptr;
+
+    srcdate = getenv("SOURCE_DATE_EPOCH");
+    if (srcdate && rpmExpandNumeric("%{?use_source_date_epoch_as_buildtime}")) {
+        errno = 0;
+        epoch = strtol(srcdate, &endptr, 10);
+        if (srcdate == endptr || *endptr || errno != 0)
+            rpmlog(RPMLOG_ERR, _("unable to parse SOURCE_DATE_EPOCH\n"));
+        else
+            buildTime = (int32_t) epoch;
+    } else
+        buildTime = (int32_t) time(NULL);
+
+    return buildTime;
+}
+
+static char * buildHost(void)
+{
+    char* hostname;
+    struct hostent *hbn;
+    char *bhMacro;
+
+    bhMacro = rpmExpand("%{?_buildhost}", NULL);
+    if (strcmp(bhMacro, "") != 0) {
+        rasprintf(&hostname, "%s", bhMacro);
+    } else {
+        hostname = rcalloc(1024, sizeof(*hostname));
+        (void) gethostname(hostname, 1024);
+        hbn = gethostbyname(hostname);
+        if (hbn)
+            strcpy(hostname, hbn->h_name);
+        else
+            rpmlog(RPMLOG_WARNING,
+                    _("Could not canonicalize hostname: %s\n"), hostname);
+    }
+    free(bhMacro);
+    return(hostname);
+}
+
 /**
  */
 static rpmRC doRmSource(rpmSpec spec)
@@ -201,6 +247,9 @@ static rpmRC buildSpec(BTA_t buildArgs,
     rpmRC rc = RPMRC_OK;
     int test = (what & RPMBUILD_NOBUILD);
     char *cookie = buildArgs->cookie ? xstrdup(buildArgs->cookie) : NULL;
+    const char* host = buildHost();
+    rpm_time_t buildTime = getBuildTime();
+

     if (rpmExpandNumeric("%{?source_date_epoch_from_changelog}") &&
 	getenv("SOURCE_DATE_EPOCH") == NULL) {
@@ -293,6 +342,7 @@ static rpmRC buildSpec(BTA_t buildArgs,
 	(void) unlink(spec->specFile);

 exit:
+    free(host);
     free(cookie);
     spec->rootDir = NULL;
     if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
Index: rpm-4.14.1/build/pack.c
===================================================================
--- rpm-4.14.1.orig/build/pack.c
+++ rpm-4.14.1/build/pack.c
@@ -6,8 +6,6 @@
 #include "system.h"

 #include <errno.h>
-#include <netdb.h>
-#include <time.h>
 #include <sys/wait.h>

 #include <rpm/rpmlib.h>			/* RPMSIGTAG*, rpmReadPackageFile */
@@ -152,57 +150,6 @@ exit:
     return rc;
 }

-static rpm_time_t * getBuildTime(void)
-{
-    static rpm_time_t buildTime[1];
-    char *srcdate;
-    time_t epoch;
-    char *endptr;
-
-    if (buildTime[0] == 0) {
-        srcdate = getenv("SOURCE_DATE_EPOCH");
-        if (srcdate && rpmExpandNumeric("%{?use_source_date_epoch_as_buildtime}")) {
-            errno = 0;
-            epoch = strtol(srcdate, &endptr, 10);
-            if (srcdate == endptr || *endptr || errno != 0)
-                rpmlog(RPMLOG_ERR, _("unable to parse SOURCE_DATE_EPOCH\n"));
-            else
-                buildTime[0] = (int32_t) epoch;
-        } else
-            buildTime[0] = (int32_t) time(NULL);
-    }
-
-    return buildTime;
-}
-
-static const char * buildHost(void)
-{
-    static char hostname[1024];
-    static int oneshot = 0;
-    struct hostent *hbn;
-    char *bhMacro;
-
-    if (! oneshot) {
-        bhMacro = rpmExpand("%{?_buildhost}", NULL);
-        if (strcmp(bhMacro, "") != 0 && strlen(bhMacro) < 1024) {
-            strcpy(hostname, bhMacro);
-        } else {
-            if (strcmp(bhMacro, "") != 0)
-                rpmlog(RPMLOG_WARNING, _("The _buildhost macro is too long\n"));
-            (void) gethostname(hostname, sizeof(hostname));
-            hbn = gethostbyname(hostname);
-            if (hbn)
-                strcpy(hostname, hbn->h_name);
-            else
-                rpmlog(RPMLOG_WARNING,
-                        _("Could not canonicalize hostname: %s\n"), hostname);
-        }
-        free(bhMacro);
-        oneshot = 1;
-    }
-    return(hostname);
-}
-
 static rpmRC processScriptFiles(rpmSpec spec, Package pkg)
 {
     struct TriggerFileEntry *p;
@@ -431,8 +378,8 @@ static rpmRC fdConsume(FD_t fd, off_t st
     };

     if (left) {
-	rpmlog(RPMLOG_ERR, _("Failed to read %jd bytes in file %s: %s\n"),
-	       (intmax_t) nbytes, Fdescr(fd), Fstrerror(fd));
+	rpmlog(RPMLOG_ERR, _("Failed to read %ld bytes in file %s: %s\n"),
+		nbytes, Fdescr(fd), Fstrerror(fd));
     }

     return (left == 0) ? RPMRC_OK : RPMRC_FAIL;
@@ -476,7 +423,8 @@ exit:
  * order to how the RPM format is laid on disk.
  */
 static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
-		      const char *fileName, char **cookie)
+		      const char *fileName, char **cookie,
+		      rpm_time_t buildTime, const char* buildHost)
 {
     FD_t fd = NULL;
     char * rpmio_flags = NULL;
@@ -500,7 +448,7 @@ static rpmRC writeRPM(Package pkg, unsig

     /* Create and add the cookie */
     if (cookie) {
-	rasprintf(cookie, "%s %d", buildHost(), (int) (*getBuildTime()));
+	rasprintf(cookie, "%s %d");
 	headerPutString(pkg->header, RPMTAG_COOKIE, *cookie);
     }

@@ -601,8 +549,6 @@ exit:
 	if (MD5 != NULL) {
 	    *pkgidp = MD5;
 	}
-    } else {
-	free(MD5);
     }

     Fclose(fd);
@@ -641,73 +587,10 @@ static rpmRC checkPackages(char *pkgchec
     return RPMRC_OK;
 }

-static void trimChangelog(Header h)
-{
-    static int oneshot;
-    static int cuttime, minnum, maxnum;
-    rpm_count_t i, keep;
-    struct rpmtd_s timestd, namestd, textstd;
-    rpm_count_t count;
-
-    if (!oneshot) {
-	char *binarychangelogtrim = rpmExpand("%{?_binarychangelogtrim}", NULL);
-	oneshot = 1;
-	if (binarychangelogtrim && *binarychangelogtrim) {
-	    maxnum = atoi(binarychangelogtrim);
-	    binarychangelogtrim = strchr(binarychangelogtrim, ',');
-	    if (binarychangelogtrim)
-	      binarychangelogtrim++;
-	}
-	if (binarychangelogtrim && *binarychangelogtrim) {
-	    cuttime = atoi(binarychangelogtrim);
-	    binarychangelogtrim = strchr(binarychangelogtrim, ',');
-	    if (binarychangelogtrim)
-	      binarychangelogtrim++;
-	}
-	if (binarychangelogtrim && *binarychangelogtrim) {
-	    minnum = atoi(binarychangelogtrim);
-	    binarychangelogtrim = strchr(binarychangelogtrim, ',');
-	}
-    }
-    if (!cuttime && !minnum && !maxnum) {
-	return;
-    }
-
-    if (!headerGet(h, RPMTAG_CHANGELOGTIME, &timestd, HEADERGET_MINMEM))
-	return;
-    count = rpmtdCount(&timestd);
-    if ((!cuttime || count <= minnum) && (!maxnum || count <= maxnum)) {
-	rpmtdFreeData(&timestd);
-	return;
-    }
-    keep = count;
-    if (maxnum && keep > maxnum)
-	keep = maxnum;
-    if (cuttime) {
-	for (i = 0; i < keep; i++) {
-	    uint32_t *tp = rpmtdNextUint32(&timestd);
-	    if (i >= minnum && tp && *tp < cuttime)
-		break;
-	}
-	keep = i;
-    }
-    if (keep >= count) {
-	rpmtdFreeData(&timestd);
-	return;
-    }
-    headerGet(h, RPMTAG_CHANGELOGNAME, &namestd, HEADERGET_MINMEM);
-    headerGet(h, RPMTAG_CHANGELOGTEXT, &textstd, HEADERGET_MINMEM);
-    timestd.count = namestd.count = textstd.count = keep;
-    headerMod(h, &timestd);
-    headerMod(h, &namestd);
-    headerMod(h, &textstd);
-    rpmtdFreeData(&textstd);
-    rpmtdFreeData(&namestd);
-    rpmtdFreeData(&timestd);
-}
-
 static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int cheating, char** filename)
 {
+	const char *errorString;
+	rpmRC rc = RPMRC_OK;

 	if (pkg->fileList == NULL)
 	    return rc;
@@ -723,8 +606,8 @@ static rpmRC packageBinary(rpmSpec spec,
 	headerCopyTags(spec->packages->header, pkg->header, copyTags);

 	headerPutString(pkg->header, RPMTAG_RPMVERSION, VERSION);
-	headerPutString(pkg->header, RPMTAG_BUILDHOST, buildHost());
-	headerPutUint32(pkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
+	headerPutString(pkg->header, RPMTAG_BUILDHOST, spec->buildHost);
+	headerPutUint32(pkg->header, RPMTAG_BUILDTIME, &(spec->buildTime), 1);

 	if (spec->sourcePkgId != NULL) {
 	    headerPutBin(pkg->header, RPMTAG_SOURCEPKGID, spec->sourcePkgId,16);
@@ -766,7 +649,7 @@ static rpmRC packageBinary(rpmSpec spec,
 	    free(binRpm);
 	}

-	rc = writeRPM(pkg, NULL, *filename, NULL);
+	rc = writeRPM(pkg, NULL, *filename, NULL, spec->buildTime, spec->buildHost);
 	if (rc == RPMRC_OK) {
 	    /* Do check each written package if enabled */
 	    char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", *filename, NULL);
@@ -872,8 +755,8 @@ rpmRC packageSources(rpmSpec spec, char

     /* Add some cruft */
     headerPutString(sourcePkg->header, RPMTAG_RPMVERSION, VERSION);
-    headerPutString(sourcePkg->header, RPMTAG_BUILDHOST, buildHost());
-    headerPutUint32(sourcePkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
+    headerPutString(sourcePkg->header, RPMTAG_BUILDHOST, spec->buildHost);
+    headerPutUint32(sourcePkg->header, RPMTAG_BUILDTIME, &(spec->buildTime), 1);
     headerPutUint32(sourcePkg->header, RPMTAG_SOURCEPACKAGE, &one, 1);

     /* XXX this should be %_srpmdir */
@@ -881,7 +764,7 @@ rpmRC packageSources(rpmSpec spec, char
 	char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);

 	spec->sourcePkgId = NULL;
-	rc = writeRPM(sourcePkg, &spec->sourcePkgId, fn, cookie);
+	rc = writeRPM(sourcePkg, &spec->sourcePkgId, fn, cookie, spec->buildTime, spec->buildHost);

 	/* Do check SRPM package if enabled */
 	if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
Index: rpm-4.14.1/build/rpmbuild_internal.h
===================================================================
--- rpm-4.14.1.orig/build/rpmbuild_internal.h
+++ rpm-4.14.1/build/rpmbuild_internal.h
@@ -49,6 +49,8 @@ typedef struct Package_s * Package;
  * The structure used to store values parsed from a spec file.
  */
 struct rpmSpec_s {
+    char * buildHost;
+    rpm_time_t buildTime;
     char * specFile;	/*!< Name of the spec file. */
     char * buildRoot;
     char * buildSubdir;
@@ -427,6 +429,8 @@ rpmRC processSourceFiles(rpmSpec spec, r
  * @param spec		spec file control structure
  * @param cookie	build identifier "cookie" or NULL
  * @param cheating	was build shortcircuited?
+ * @param buildTime	the build timestamp that goes into packages
+ * @param buildHost	the hostname where the build is happening
  * @return		RPMRC_OK on success
  */
 RPM_GNUC_INTERNAL
@@ -436,6 +440,8 @@ rpmRC packageBinaries(rpmSpec spec, cons
  * Generate source package.
  * @param spec		spec file control structure
  * @retval cookie	build identifier "cookie" or NULL
+ * @param buildTime	the build timestamp that goes into packages
+ * @param buildHost	the hostname where the build is happening
  * @return		RPMRC_OK on success
  */
 RPM_GNUC_INTERNAL