1 From 792693bb90768cfde4898e8dd31ee1b5de803d2f Mon Sep 17 00:00:00 2001
2 From: Alexander Kanavin <alex.kanavin@gmail.com>
3 Date: Thu, 8 Jun 2017 17:08:09 +0300
4 Subject: [PATCH] build/pack.c: remove static local variables from buildHost()
7 Their use is causing difficult to diagnoze data races when building multiple
8 packages in parallel, and is a bad idea in general, as it also makes it more
9 difficult to reason about code.
11 Upstream-Status: Submitted [https://github.com/rpm-software-management/rpm/pull/226]
12 Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
14 Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
17 build/build.c | 54 ++++++++++++++++++++++++++++--
18 build/pack.c | 84 +++++++++--------------------------------------
19 build/rpmbuild_internal.h | 8 +++--
20 3 files changed, 74 insertions(+), 72 deletions(-)
22 diff --git a/build/build.c b/build/build.c
23 index 13c3df2..b154f08 100644
34 #include <rpm/rpmlog.h>
39 +static rpm_time_t getBuildTime(void)
41 + rpm_time_t buildTime = 0;
46 + srcdate = getenv("SOURCE_DATE_EPOCH");
49 + epoch = strtol(srcdate, &endptr, 10);
50 + if (srcdate == endptr || *endptr || errno != 0)
51 + rpmlog(RPMLOG_ERR, _("unable to parse SOURCE_DATE_EPOCH\n"));
53 + buildTime = (int32_t) epoch;
55 + buildTime = (int32_t) time(NULL);
60 +static char * buildHost(void)
63 + struct hostent *hbn;
66 + bhMacro = rpmExpand("%{?_buildhost}", NULL);
67 + if (strcmp(bhMacro, "") != 0) {
68 + rasprintf(&hostname, "%s", bhMacro);
70 + hostname = rcalloc(1024, sizeof(*hostname));
71 + (void) gethostname(hostname, 1024);
72 + hbn = gethostbyname(hostname);
74 + strcpy(hostname, hbn->h_name);
76 + rpmlog(RPMLOG_WARNING,
77 + _("Could not canonicalize hostname: %s\n"), hostname);
85 static rpmRC doRmSource(rpmSpec spec)
86 @@ -201,6 +247,9 @@ static rpmRC buildSpec(BTA_t buildArgs, rpmSpec spec, int what)
88 int test = (what & RPMBUILD_NOBUILD);
89 char *cookie = buildArgs->cookie ? xstrdup(buildArgs->cookie) : NULL;
90 + const char* host = buildHost();
91 + rpm_time_t buildTime = getBuildTime();
94 if (rpmExpandNumeric("%{?source_date_epoch_from_changelog}") &&
95 getenv("SOURCE_DATE_EPOCH") == NULL) {
96 @@ -269,11 +318,11 @@ static rpmRC buildSpec(BTA_t buildArgs, rpmSpec spec, int what)
99 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
100 - (rc = packageSources(spec, &cookie)))
101 + (rc = packageSources(spec, &cookie, buildTime, host)))
104 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
105 - (rc = packageBinaries(spec, cookie, (didBuild == 0))))
106 + (rc = packageBinaries(spec, cookie, (didBuild == 0), buildTime, host)))
109 if ((what & RPMBUILD_CLEAN) &&
110 @@ -293,6 +342,7 @@ static rpmRC buildSpec(BTA_t buildArgs, rpmSpec spec, int what)
111 (void) unlink(spec->specFile);
116 spec->rootDir = NULL;
117 if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
118 diff --git a/build/pack.c b/build/pack.c
119 index df15876..17a4b09 100644
128 #include <sys/wait.h>
130 #include <rpm/rpmlib.h> /* RPMSIGTAG*, rpmReadPackageFile */
131 @@ -152,57 +150,6 @@ exit:
135 -static rpm_time_t * getBuildTime(void)
137 - static rpm_time_t buildTime[1];
142 - if (buildTime[0] == 0) {
143 - srcdate = getenv("SOURCE_DATE_EPOCH");
146 - epoch = strtol(srcdate, &endptr, 10);
147 - if (srcdate == endptr || *endptr || errno != 0)
148 - rpmlog(RPMLOG_ERR, _("unable to parse SOURCE_DATE_EPOCH\n"));
150 - buildTime[0] = (int32_t) epoch;
152 - buildTime[0] = (int32_t) time(NULL);
158 -static const char * buildHost(void)
160 - static char hostname[1024];
161 - static int oneshot = 0;
162 - struct hostent *hbn;
166 - bhMacro = rpmExpand("%{?_buildhost}", NULL);
167 - if (strcmp(bhMacro, "") != 0 && strlen(bhMacro) < 1024) {
168 - strcpy(hostname, bhMacro);
170 - if (strcmp(bhMacro, "") != 0)
171 - rpmlog(RPMLOG_WARNING, _("The _buildhost macro is too long\n"));
172 - (void) gethostname(hostname, sizeof(hostname));
173 - hbn = gethostbyname(hostname);
175 - strcpy(hostname, hbn->h_name);
177 - rpmlog(RPMLOG_WARNING,
178 - _("Could not canonicalize hostname: %s\n"), hostname);
186 static rpmRC processScriptFiles(rpmSpec spec, Package pkg)
188 struct TriggerFileEntry *p;
189 @@ -476,7 +423,8 @@ exit:
190 * order to how the RPM format is laid on disk.
192 static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
193 - const char *fileName, char **cookie)
194 + const char *fileName, char **cookie,
195 + rpm_time_t buildTime, const char* buildHost)
198 char * rpmio_flags = NULL;
199 @@ -500,7 +448,7 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
201 /* Create and add the cookie */
203 - rasprintf(cookie, "%s %d", buildHost(), (int) (*getBuildTime()));
204 + rasprintf(cookie, "%s %d", buildHost, buildTime);
205 headerPutString(pkg->header, RPMTAG_COOKIE, *cookie);
208 @@ -641,7 +589,7 @@ static rpmRC checkPackages(char *pkgcheck)
212 -static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int cheating, char** filename)
213 +static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int cheating, char** filename, rpm_time_t buildTime, const char* buildHost)
215 const char *errorString;
217 @@ -660,8 +608,8 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch
218 headerCopyTags(spec->packages->header, pkg->header, copyTags);
220 headerPutString(pkg->header, RPMTAG_RPMVERSION, VERSION);
221 - headerPutString(pkg->header, RPMTAG_BUILDHOST, buildHost());
222 - headerPutUint32(pkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
223 + headerPutString(pkg->header, RPMTAG_BUILDHOST, buildHost);
224 + headerPutUint32(pkg->header, RPMTAG_BUILDTIME, &buildTime, 1);
226 if (spec->sourcePkgId != NULL) {
227 headerPutBin(pkg->header, RPMTAG_SOURCEPKGID, spec->sourcePkgId,16);
228 @@ -699,7 +647,7 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch
232 - rc = writeRPM(pkg, NULL, *filename, NULL);
233 + rc = writeRPM(pkg, NULL, *filename, NULL, buildTime, buildHost);
234 if (rc == RPMRC_OK) {
235 /* Do check each written package if enabled */
236 char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", *filename, NULL);
237 @@ -719,7 +667,7 @@ struct binaryPackageTaskData
238 struct binaryPackageTaskData *next;
241 -static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const char *cookie, int cheating)
242 +static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const char *cookie, int cheating, rpm_time_t buildTime, char* buildHost)
244 struct binaryPackageTaskData *tasks = NULL;
245 struct binaryPackageTaskData *task = NULL;
246 @@ -731,7 +679,7 @@ static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const c
247 if (pkg == spec->packages) {
248 // the first package needs to be processed ahead of others, as they copy
249 // changelog data from it, and so otherwise data races would happen
250 - task->result = packageBinary(spec, pkg, cookie, cheating, &(task->filename));
251 + task->result = packageBinary(spec, pkg, cookie, cheating, &(task->filename), buildTime, buildHost);
252 rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename);
255 @@ -748,7 +696,7 @@ static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const c
259 - task->result = packageBinary(spec, task->pkg, cookie, cheating, &(task->filename));
260 + task->result = packageBinary(spec, task->pkg, cookie, cheating, &(task->filename), buildTime, buildHost);
261 rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename);
264 @@ -766,11 +714,11 @@ static void freeBinaryPackageTasks(struct binaryPackageTaskData* tasks)
268 -rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
269 +rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating, rpm_time_t buildTime, char* buildHost)
271 char *pkglist = NULL;
273 - struct binaryPackageTaskData *tasks = runBinaryPackageTasks(spec, cookie, cheating);
274 + struct binaryPackageTaskData *tasks = runBinaryPackageTasks(spec, cookie, cheating, buildTime, buildHost);
276 for (struct binaryPackageTaskData *task = tasks; task != NULL; task = task->next) {
277 if (task->result == RPMRC_OK) {
278 @@ -797,7 +745,7 @@ rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
282 -rpmRC packageSources(rpmSpec spec, char **cookie)
283 +rpmRC packageSources(rpmSpec spec, char **cookie, rpm_time_t buildTime, char* buildHost)
285 Package sourcePkg = spec->sourcePackage;
287 @@ -805,8 +753,8 @@ rpmRC packageSources(rpmSpec spec, char **cookie)
290 headerPutString(sourcePkg->header, RPMTAG_RPMVERSION, VERSION);
291 - headerPutString(sourcePkg->header, RPMTAG_BUILDHOST, buildHost());
292 - headerPutUint32(sourcePkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
293 + headerPutString(sourcePkg->header, RPMTAG_BUILDHOST, buildHost);
294 + headerPutUint32(sourcePkg->header, RPMTAG_BUILDTIME, &buildTime, 1);
295 headerPutUint32(sourcePkg->header, RPMTAG_SOURCEPACKAGE, &one, 1);
297 /* XXX this should be %_srpmdir */
298 @@ -814,7 +762,7 @@ rpmRC packageSources(rpmSpec spec, char **cookie)
299 char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);
301 spec->sourcePkgId = NULL;
302 - rc = writeRPM(sourcePkg, &spec->sourcePkgId, fn, cookie);
303 + rc = writeRPM(sourcePkg, &spec->sourcePkgId, fn, cookie, buildTime, buildHost);
305 /* Do check SRPM package if enabled */
306 if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
307 diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
308 index 439b7d3..07e8338 100644
309 --- a/build/rpmbuild_internal.h
310 +++ b/build/rpmbuild_internal.h
311 @@ -427,19 +427,23 @@ rpmRC processSourceFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags);
312 * @param spec spec file control structure
313 * @param cookie build identifier "cookie" or NULL
314 * @param cheating was build shortcircuited?
315 + * @param buildTime the build timestamp that goes into packages
316 + * @param buildHost the hostname where the build is happening
317 * @return RPMRC_OK on success
320 -rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating);
321 +rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating, rpm_time_t buildTime, char* buildHost);
323 /** \ingroup rpmbuild
324 * Generate source package.
325 * @param spec spec file control structure
326 * @retval cookie build identifier "cookie" or NULL
327 + * @param buildTime the build timestamp that goes into packages
328 + * @param buildHost the hostname where the build is happening
329 * @return RPMRC_OK on success
332 -rpmRC packageSources(rpmSpec spec, char **cookie);
333 +rpmRC packageSources(rpmSpec spec, char **cookie, rpm_time_t buildTime, char* buildHost);
336 int addLangTag(rpmSpec spec, Header h, rpmTagVal tag,