xref: /dragonfly/usr.bin/dsynth/build.c (revision 029e6489)
1 /*
2  * Copyright (c) 2019-2020 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * This code uses concepts and configuration based on 'synth', by
8  * John R. Marino <draco@marino.st>, which was written in ada.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  * 3. Neither the name of The DragonFly Project nor the names of its
21  *    contributors may be used to endorse or promote products derived
22  *    from this software without specific, prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 #include "dsynth.h"
38 
39 worker_t WorkerAry[MAXWORKERS];
40 int BuildInitialized;
41 int RunningWorkers;
42 int DynamicMaxWorkers;
43 int FailedWorkers;
44 long RunningPkgDepSize;
45 pthread_mutex_t WorkerMutex;
46 pthread_cond_t WorkerCond;
47 
48 static int build_find_leaves(pkg_t *parent, pkg_t *pkg,
49 			pkg_t ***build_tailp, int *app, int *hasworkp,
50 			int depth, int first, int first_one_only);
51 static int buildCalculateDepiDepth(pkg_t *pkg);
52 static void build_clear_trav(pkg_t *pkg);
53 static void startbuild(pkg_t **build_listp, pkg_t ***build_tailp);
54 static int qsort_depi(const void *pkg1, const void *pkg2);
55 static int qsort_idep(const void *pkg1, const void *pkg2);
56 static void startworker(pkg_t *pkg, worker_t *work);
57 static void cleanworker(worker_t *work);
58 static void waitbuild(int whilematch, int dynamicmax);
59 static void workercomplete(worker_t *work);
60 static void *childBuilderThread(void *arg);
61 static int childInstallPkgDeps(worker_t *work);
62 static size_t childInstallPkgDeps_recurse(FILE *fp, pkglink_t *list,
63 			int undoit, int depth, int first_one_only);
64 static void dophase(worker_t *work, wmsg_t *wmsg,
65 			int wdog, int phaseid, const char *phase);
66 static void phaseReapAll(void);
67 static void phaseTerminateSignal(int sig);
68 static char *buildskipreason(pkglink_t *parent, pkg_t *pkg);
69 static int buildskipcount_dueto(pkg_t *pkg, int mode);
70 static int mptylogpoll(int ptyfd, int fdlog, wmsg_t *wmsg,
71 			time_t *wdog_timep);
72 static void doHook(pkg_t *pkg, const char *id, const char *path, int waitfor);
73 static void childHookRun(bulk_t *bulk);
74 static void adjloadavg(double *dload);
75 static void check_packaged(const char *dbmpath, pkg_t *pkgs);
76 
77 static worker_t *SigWork;
78 static int MasterPtyFd = -1;
79 static int CopyFileFd = -1;
80 static pid_t SigPid;
81 static const char *WorkerFlavorPrt = "";	/* "" or "@flavor" */
82 static DBM *CheckDBM;
83 
84 #define MPTY_FAILED	-2
85 #define MPTY_AGAIN	-1
86 #define MPTY_EOF	0
87 #define MPTY_DATA	1
88 
89 int BuildTotal;
90 int BuildCount;
91 int BuildSkipCount;
92 int BuildIgnoreCount;
93 int BuildFailCount;
94 int BuildSuccessCount;
95 int BuildMissingCount;
96 
97 /*
98  * Initialize the WorkerAry[]
99  */
100 void
101 DoInitBuild(int slot_override)
102 {
103 	worker_t *work;
104 	struct stat st;
105 	int i;
106 
107 	ddassert(slot_override < 0 || MaxWorkers == 1);
108 
109 	bzero(WorkerAry, MaxWorkers * sizeof(worker_t));
110 	pthread_mutex_init(&WorkerMutex, NULL);
111 
112 	for (i = 0; i < MaxWorkers; ++i) {
113 		work = &WorkerAry[i];
114 		work->index = (slot_override >= 0) ? slot_override : i;
115 		work->state = WORKER_NONE;
116 		asprintf(&work->basedir, "%s/SL%02d", BuildBase, work->index);
117 		pthread_cond_init(&work->cond, NULL);
118 	}
119 	BuildCount = 0;
120 
121 	/*
122 	 * Create required sub-directories. The base directories must already
123 	 * exist as a dsynth configuration safety.
124 	 */
125 	if (stat(RepositoryPath, &st) < 0) {
126 		if (mkdir(RepositoryPath, 0755) < 0)
127 			dfatal("Cannot mkdir %s\n", RepositoryPath);
128 	}
129 
130 	BuildInitialized = 1;
131 
132 	/*
133 	 * slow-start (increases at a rate of 1 per 5 seconds)
134 	 */
135 	if (SlowStartOpt > MaxWorkers)
136 		DynamicMaxWorkers = MaxWorkers;
137 	else if (SlowStartOpt > 0)
138 		DynamicMaxWorkers = SlowStartOpt;
139 	else
140 		DynamicMaxWorkers = MaxWorkers;
141 }
142 
143 /*
144  * Called by the frontend to clean-up any hanging mounts.
145  */
146 void
147 DoCleanBuild(int resetlogs)
148 {
149 	int i;
150 
151 	ddassert(BuildInitialized);
152 
153 	if (resetlogs)
154 		dlogreset();
155 	for (i = 0; i < MaxWorkers; ++i) {
156 		DoWorkerUnmounts(&WorkerAry[i]);
157 	}
158 }
159 
160 void
161 DoBuild(pkg_t *pkgs)
162 {
163 	pkg_t *build_list = NULL;
164 	pkg_t **build_tail = &build_list;
165 	pkg_t *scan;
166 	bulk_t *bulk;
167 	int haswork = 1;
168 	int first = 1;
169 	int newtemplate;
170 	time_t startTime;
171 	time_t t;
172 	int h, m, s;
173 	char *dbmpath;
174 
175 	/*
176 	 * We use our bulk system to run hooks.  This will be for
177 	 * Skipped and Ignored.  Success and Failure are handled by
178 	 * WorkerProcess() which is a separately-exec'd dsynth.
179 	 */
180 	if (UsingHooks)
181 		initbulk(childHookRun, MaxBulk);
182 
183 	/*
184 	 * Count up the packages, not counting dummies
185 	 */
186 	for (scan = pkgs; scan; scan = scan->bnext) {
187 		if ((scan->flags & PKGF_DUMMY) == 0)
188 			++BuildTotal;
189 	}
190 
191 	/*
192 	 * Remove binary package files for dports whos directory
193 	 * has changed.
194 	 */
195 	asprintf(&dbmpath, "%s/ports_crc", BuildBase);
196 	CheckDBM = dbm_open(dbmpath, O_CREAT|O_RDWR, 0644);
197 	check_packaged(dbmpath, pkgs);
198 
199 	doHook(NULL, "hook_run_start", HookRunStart, 1);
200 
201 	/*
202 	 * The pkg and pkg-static binaries are needed.  If already present
203 	 * then assume that the template is also valid, otherwise add to
204 	 * the list and build both.
205 	 */
206 	scan = GetPkgPkg(&pkgs);
207 
208 	/*
209 	 * Create our template.  The template will be missing pkg
210 	 * and pkg-static.
211 	 */
212 	if ((scan->flags & (PKGF_SUCCESS | PKGF_PACKAGED)) == 0) {
213 		/* force a fresh template */
214 		newtemplate = DoCreateTemplate(1);
215 	} else {
216 		newtemplate = DoCreateTemplate(0);
217 	}
218 
219 	/*
220 	 * This will clear the screen and set-up our gui, so sleep
221 	 * a little first in case the user wants to see what was
222 	 * printed before.
223 	 */
224 	sleep(2);
225 	pthread_mutex_lock(&WorkerMutex);
226 	startTime = time(NULL);
227 	RunStatsInit();
228 	RunStatsReset();
229 
230 	/*
231 	 * Build pkg/pkg-static.
232 	 */
233 	if ((scan->flags & (PKGF_SUCCESS | PKGF_PACKAGED)) == 0) {
234 		build_list = scan;
235 		build_tail = &scan->build_next;
236 		startbuild(&build_list, &build_tail);
237 		while (RunningWorkers == 1)
238 			waitbuild(1, 0);
239 
240 		if (scan->flags & PKGF_NOBUILD)
241 			dfatal("Unable to build 'pkg'");
242 		if (scan->flags & PKGF_ERROR)
243 			dfatal("Error building 'pkg'");
244 		if ((scan->flags & PKGF_SUCCESS) == 0)
245 			dfatal("Error building 'pkg'");
246 		newtemplate = 1;
247 	}
248 
249 	/*
250 	 * Install pkg/pkg-static into the template
251 	 */
252 	if (newtemplate) {
253 		char *buf;
254 		int rc;
255 
256 		asprintf(&buf,
257 			 "cd %s/Template; "
258 			 "tar --exclude '+*' --exclude '*/man/*' "
259 			 "-xvzpf %s/%s > /dev/null 2>&1",
260 			 BuildBase,
261 			 RepositoryPath,
262 			 scan->pkgfile);
263 		rc = system(buf);
264 		if (rc)
265 			dfatal("Command failed: %s\n", buf);
266 		freestrp(&buf);
267 	}
268 
269 	/*
270 	 * Calculate depi_depth, the longest chain of dependencies
271 	 * for who depends on me, weighted by powers of two.
272 	 */
273 	for (scan = pkgs; scan; scan = scan->bnext) {
274 		buildCalculateDepiDepth(scan);
275 	}
276 
277 	/*
278 	 * Nominal bulk build sequence
279 	 */
280 	while (haswork) {
281 		haswork = 0;
282 		fflush(stdout);
283 		for (scan = pkgs; scan; scan = scan->bnext) {
284 			ddprintf(0, "SCANLEAVES %08x %s\n",
285 				 scan->flags, scan->portdir);
286 			scan->flags |= PKGF_BUILDLOOP;
287 			/*
288 			 * NOTE: We must still find dependencies if PACKAGED
289 			 *	 to fill in the gaps, as some of them may
290 			 *	 need to be rebuilt.
291 			 */
292 			if (scan->flags & (PKGF_SUCCESS | PKGF_FAILURE |
293 					   PKGF_ERROR)) {
294 #if 0
295 				ddprintf(0, "%s: already built\n",
296 					 scan->portdir);
297 #endif
298 			} else {
299 				int ap = 0;
300 				build_find_leaves(NULL, scan, &build_tail,
301 						  &ap, &haswork, 0, first, 0);
302 				ddprintf(0, "TOPLEVEL %s %08x\n",
303 					 scan->portdir, ap);
304 			}
305 			scan->flags &= ~PKGF_BUILDLOOP;
306 			build_clear_trav(scan);
307 		}
308 		first = 0;
309 		fflush(stdout);
310 		startbuild(&build_list, &build_tail);
311 
312 		if (haswork == 0 && RunningWorkers) {
313 			waitbuild(RunningWorkers, 1);
314 			haswork = 1;
315 		}
316 	}
317 	pthread_mutex_unlock(&WorkerMutex);
318 
319 	/*
320 	 * What is left that cannot be built?  The list really ought to be
321 	 * empty at this point, report anything that remains.
322 	 */
323 	for (scan = pkgs; scan; scan = scan->bnext) {
324 		if (scan->flags & (PKGF_SUCCESS | PKGF_FAILURE))
325 			continue;
326 		dlog(DLOG_ABN, "[XXX] %s lost in the ether [flags=%08x]\n",
327 		     scan->portdir, scan->flags);
328 		++BuildMissingCount;
329 	}
330 
331 	/*
332 	 * Final updates
333 	 */
334 	RunStatsUpdateTop(0);
335 	RunStatsUpdateLogs();
336 	RunStatsSync();
337 	RunStatsDone();
338 
339 	doHook(NULL, "hook_run_end", HookRunEnd, 1);
340 	if (UsingHooks) {
341 		while ((bulk = getbulk()) != NULL)
342 			freebulk(bulk);
343 		donebulk();
344 	}
345 
346 	t = time(NULL) - startTime;
347 	h = t / 3600;
348 	m = t / 60 % 60;
349 	s = t % 60;
350 
351 	if (CheckDBM) {
352 		dbm_close(CheckDBM);
353 		CheckDBM = NULL;
354 	}
355 
356 	dlog(DLOG_ALL|DLOG_STDOUT,
357 		"\n"
358 		"Initial queue size: %d\n"
359 		"    packages built: %d\n"
360 		"           ignored: %d\n"
361 		"           skipped: %d\n"
362 		"            failed: %d\n"
363 		"           missing: %d\n"
364 		"\n"
365 		"Duration: %02d:%02d:%02d\n"
366 		"\n",
367 		BuildTotal,
368 		BuildSuccessCount,
369 		BuildIgnoreCount,
370 		BuildSkipCount,
371 		BuildFailCount,
372 		BuildMissingCount,
373 		h, m, s);
374 }
375 
376 /*
377  * Traverse the packages (pkg) depends on recursively until we find
378  * a leaf to build or report as unbuildable.  Calculates and assigns a
379  * dependency count.  Returns all parallel-buildable packages.
380  *
381  * (pkg) itself is only added to the list if it is immediately buildable.
382  */
383 static
384 int
385 build_find_leaves(pkg_t *parent, pkg_t *pkg, pkg_t ***build_tailp,
386 		  int *app, int *hasworkp, int depth, int first,
387 		  int first_one_only)
388 {
389 	pkglink_t *link;
390 	pkg_t *scan;
391 	int idep_count = 0;
392 	int apsub;
393 	int dfirst_one_only;
394 	int ndepth;
395 	char *buf;
396 
397 	ndepth = depth + 1;
398 
399 	/*
400 	 * Already on build list, possibly in-progress, tell caller that
401 	 * it is not ready.
402 	 */
403 	ddprintf(ndepth, "sbuild_find_leaves %d %s %08x {\n",
404 		 depth, pkg->portdir, pkg->flags);
405 	if (pkg->flags & PKGF_BUILDLIST) {
406 		ddprintf(ndepth, "} (already on build list)\n");
407 		*app |= PKGF_NOTREADY;
408 		return (pkg->idep_count);
409 	}
410 
411 	/*
412 	 * Check dependencies
413 	 */
414 	PKGLIST_FOREACH(link, &pkg->idepon_list) {
415 		scan = link->pkg;
416 
417 		if (scan == NULL) {
418 			if (first_one_only)
419 				break;
420 			continue;
421 		}
422 		ddprintf(ndepth, "check %s %08x\t", scan->portdir, scan->flags);
423 
424 		/*
425 		 * If this dependency is to a DUMMY node it is a dependency
426 		 * only on the default flavor which is only the first node
427 		 * under this one, not all of them.
428 		 *
429 		 * DUMMY nodes can be marked SUCCESS so the build skips past
430 		 * them, but this doesn't mean that their sub-nodes succeeded.
431 		 * We have to check, so recurse even if it is marked
432 		 * successful.
433 		 *
434 		 * NOTE: The depth is not being for complex dependency type
435 		 *	 tests like it is in childInstallPkgDeps_recurse(),
436 		 *	 so we don't have to hicup it like we do in that
437 		 *	 procedure.
438 		 */
439 		dfirst_one_only = (scan->flags & PKGF_DUMMY) ? 1 : 0;
440 		if (dfirst_one_only)
441 			goto skip_to_flavor;
442 
443 		/*
444 		 * When accounting for a successful build, just bump
445 		 * idep_count by one.  scan->idep_count will heavily
446 		 * overlap packages that we count down multiple branches.
447 		 *
448 		 * We must still recurse through PACKAGED packages as
449 		 * some of their dependencies might be missing.
450 		 */
451 		if (scan->flags & PKGF_SUCCESS) {
452 			ddprintf(0, "SUCCESS - OK\n");
453 			++idep_count;
454 			if (first_one_only)
455 				break;
456 			continue;
457 		}
458 
459 		/*
460 		 * ERROR includes FAILURE, which is set in numerous situations
461 		 * including when NOBUILD state is finally processed.  So
462 		 * check for NOBUILD state first.
463 		 *
464 		 * An ERROR in a sub-package causes a NOBUILD in packages
465 		 * that depend on it.
466 		 */
467 		if (scan->flags & PKGF_NOBUILD) {
468 			ddprintf(0, "NOBUILD - OK "
469 				    "(propagate failure upward)\n");
470 			*app |= PKGF_NOBUILD_S;
471 			if (first_one_only)
472 				break;
473 			continue;
474 		}
475 		if (scan->flags & PKGF_ERROR) {
476 			ddprintf(0, "ERROR - OK (propagate failure upward)\n");
477 			*app |= PKGF_NOBUILD_S;
478 			if (first_one_only)
479 				break;
480 			continue;
481 		}
482 
483 		/*
484 		 * If already on build-list this dependency is not ready.
485 		 */
486 		if (scan->flags & PKGF_BUILDLIST) {
487 			ddprintf(0, " [BUILDLIST]");
488 			*app |= PKGF_NOTREADY;
489 		}
490 
491 		/*
492 		 * If not packaged this dependency is not ready for
493 		 * the caller.
494 		 */
495 		if ((scan->flags & PKGF_PACKAGED) == 0) {
496 			ddprintf(0, " [NOT_PACKAGED]");
497 			*app |= PKGF_NOTREADY;
498 		}
499 
500 		/*
501 		 * Reduce search complexity, if we have already processed
502 		 * scan in the traversal it will either already be on the
503 		 * build list or it will not be buildable.  Either way
504 		 * the parent is not buildable.
505 		 */
506 		if (scan->flags & PKGF_BUILDTRAV) {
507 			ddprintf(0, " [BUILDTRAV]\n");
508 			*app |= PKGF_NOTREADY;
509 			if (first_one_only)
510 				break;
511 			continue;
512 		}
513 skip_to_flavor:
514 
515 		/*
516 		 * Assert on dependency loop
517 		 */
518 		++idep_count;
519 		if (scan->flags & PKGF_BUILDLOOP) {
520 			dfatal("pkg dependency loop %s -> %s",
521 				parent->portdir, scan->portdir);
522 		}
523 
524 		/*
525 		 * NOTE: For debug tabbing purposes we use (ndepth + 1)
526 		 *	 here (i.e. depth + 2) in our iteration.
527 		 */
528 		scan->flags |= PKGF_BUILDLOOP;
529 		apsub = 0;
530 		ddprintf(0, " SUBRECURSION {\n");
531 		idep_count += build_find_leaves(pkg, scan, build_tailp,
532 						&apsub, hasworkp,
533 						ndepth + 1, first,
534 						dfirst_one_only);
535 		scan->flags &= ~PKGF_BUILDLOOP;
536 		*app |= apsub;
537 		if (apsub & PKGF_NOBUILD) {
538 			ddprintf(ndepth, "} (sub-nobuild)\n");
539 		} else if (apsub & PKGF_ERROR) {
540 			ddprintf(ndepth, "} (sub-error)\n");
541 		} else if (apsub & PKGF_NOTREADY) {
542 			ddprintf(ndepth, "} (sub-notready)\n");
543 		} else {
544 			ddprintf(ndepth, "} (sub-ok)\n");
545 		}
546 		if (first_one_only)
547 			break;
548 	}
549 	pkg->idep_count = idep_count;
550 	pkg->flags |= PKGF_BUILDTRAV;
551 
552 	/*
553 	 * Incorporate scan results into pkg state.
554 	 */
555 	if ((pkg->flags & PKGF_NOBUILD) == 0 && (*app & PKGF_NOBUILD)) {
556 		*hasworkp = 1;
557 	} else if ((pkg->flags & PKGF_ERROR) == 0 && (*app & PKGF_ERROR)) {
558 		*hasworkp = 1;
559 	}
560 	pkg->flags |= *app & ~PKGF_NOTREADY;
561 
562 	/*
563 	 * Clear the PACKAGED bit if sub-dependencies aren't clean.
564 	 *
565 	 * NOTE: PKGF_NOTREADY is not stored in pkg->flags, only in *app,
566 	 *	 so incorporate *app to test for it.
567 	 */
568 	if ((pkg->flags & PKGF_PACKAGED) &&
569 	    ((pkg->flags | *app) & (PKGF_NOTREADY|PKGF_ERROR|PKGF_NOBUILD))) {
570 		pkg->flags &= ~PKGF_PACKAGED;
571 		ddassert(pkg->pkgfile);
572 		asprintf(&buf, "%s/%s", RepositoryPath, pkg->pkgfile);
573 		if (OverridePkgDeleteOpt >= 1) {
574 			pkg->flags |= PKGF_PACKAGED;
575 			dlog(DLOG_ALL,
576 			     "[XXX] %s DELETE-PACKAGE %s "
577 			     "(OVERRIDE, NOT DELETED)\n",
578 			     pkg->portdir, buf);
579 		} else if (remove(buf) < 0) {
580 			dlog(DLOG_ALL,
581 			     "[XXX] %s DELETE-PACKAGE %s (failed)\n",
582 			     pkg->portdir, buf);
583 		} else {
584 			dlog(DLOG_ALL,
585 			     "[XXX] %s DELETE-PACKAGE %s "
586 			     "(due to dependencies)\n",
587 			     pkg->portdir, buf);
588 		}
589 		freestrp(&buf);
590 		*hasworkp = 1;
591 	}
592 
593 	/*
594 	 * Set PKGF_NOBUILD_I if there is IGNORE data
595 	 */
596 	if (pkg->ignore) {
597 		pkg->flags |= PKGF_NOBUILD_I;
598 	}
599 
600 	/*
601 	 * Handle propagated flags
602 	 */
603 	if (pkg->flags & PKGF_ERROR) {
604 		/*
605 		 * This can only happen if the ERROR has already been
606 		 * processed and accounted for.
607 		 */
608 		ddprintf(depth, "} (ERROR - %s)\n", pkg->portdir);
609 	} else if (*app & PKGF_NOTREADY) {
610 		/*
611 		 * We don't set PKGF_NOTREADY in the pkg, it is strictly
612 		 * a transient flag propagated via build_find_leaves().
613 		 *
614 		 * Just don't add the package to the list.
615 		 *
616 		 * NOTE: Even if NOBUILD is set (meaning we could list it
617 		 *	 and let startbuild() finish it up as a skip, we
618 		 *	 don't process it to the list because we want to
619 		 *	 process all the dependencies, so someone doing a
620 		 *	 manual build can get more complete information and
621 		 *	 does not have to iterate each failed dependency one
622 		 *	 at a time.
623 		 */
624 		;
625 	} else if (pkg->flags & PKGF_SUCCESS) {
626 		ddprintf(depth, "} (SUCCESS - %s)\n", pkg->portdir);
627 	} else if (pkg->flags & PKGF_DUMMY) {
628 		/*
629 		 * Just mark dummy packages as successful when all of their
630 		 * sub-depends (flavors) complete successfully.  Note that
631 		 * dummy packages are not counted in the total, so do not
632 		 * decrement BuildTotal.
633 		 *
634 		 * Do not propagate *app up for the dummy node or add it to
635 		 * the build list.  The dummy node itself is not an actual
636 		 * dependency.  Packages which depend on the default flavor
637 		 * (aka this dummy node) actually depend on the first flavor
638 		 * under this node.
639 		 *
640 		 * So if there is a generic dependency (i.e. no flavor
641 		 * specified), the upper recursion detects PKGF_DUMMY and
642 		 * traverses through the dummy node to the default flavor
643 		 * without checking the error/nobuild flags on this dummy
644 		 * node.
645 		 */
646 		if (pkg->flags & PKGF_NOBUILD) {
647 			ddprintf(depth, "} (DUMMY/META - IGNORED "
648 				 "- MARK SUCCESS ANYWAY)\n");
649 		} else {
650 			ddprintf(depth, "} (DUMMY/META - SUCCESS)\n");
651 		}
652 		pkg->flags |= PKGF_SUCCESS;
653 		*hasworkp = 1;
654 		if (first) {
655 			dlog(DLOG_ALL | DLOG_FILTER,
656 			     "[XXX] %s META-ALREADY-BUILT\n",
657 			     pkg->portdir);
658 		} else {
659 			dlog(DLOG_SUCC, "[XXX] %s meta-node complete\n",
660 			     pkg->portdir);
661 			RunStatsUpdateCompletion(NULL, DLOG_SUCC, pkg, "", "");
662 		}
663 	} else if (pkg->flags & PKGF_PACKAGED) {
664 		/*
665 		 * We can just mark the pkg successful.  If this is
666 		 * the first pass, we count this as an initial pruning
667 		 * pass and reduce BuildTotal.
668 		 */
669 		ddprintf(depth, "} (PACKAGED - SUCCESS)\n");
670 		pkg->flags |= PKGF_SUCCESS;
671 		*hasworkp = 1;
672 		if (first) {
673 			dlog(DLOG_ALL | DLOG_FILTER,
674 			     "[XXX] %s Already-Built\n",
675 			     pkg->portdir);
676 			--BuildTotal;
677 		} else {
678 			dlog(DLOG_ABN | DLOG_FILTER,
679 			     "[XXX] %s flags=%08x Packaged Unexpectedly\n",
680 			     pkg->portdir, pkg->flags);
681 			/* ++BuildSuccessTotal; XXX not sure */
682 			goto addlist;
683 		}
684 	} else {
685 		/*
686 		 * All dependencies are successful, queue new work
687 		 * and indicate not-ready to the parent (since our
688 		 * package has to be built).
689 		 *
690 		 * NOTE: The NOBUILD case propagates to here as well
691 		 *	 and is ultimately handled by startbuild().
692 		 */
693 addlist:
694 		*hasworkp = 1;
695 		if (pkg->flags & PKGF_NOBUILD_I)
696 			ddprintf(depth, "} (ADDLIST(IGNORE/BROKEN) - %s)\n",
697 				 pkg->portdir);
698 		else if (pkg->flags & PKGF_NOBUILD)
699 			ddprintf(depth, "} (ADDLIST(NOBUILD) - %s)\n",
700 				 pkg->portdir);
701 		else
702 			ddprintf(depth, "} (ADDLIST - %s)\n", pkg->portdir);
703 		pkg->flags |= PKGF_BUILDLIST;
704 		**build_tailp = pkg;
705 		*build_tailp = &pkg->build_next;
706 		pkg->build_next = NULL;
707 		*app |= PKGF_NOTREADY;
708 	}
709 
710 	return idep_count;
711 }
712 
713 static
714 void
715 build_clear_trav(pkg_t *pkg)
716 {
717 	pkglink_t *link;
718 	pkg_t *scan;
719 
720 	pkg->flags &= ~PKGF_BUILDTRAV;
721 	PKGLIST_FOREACH(link, &pkg->idepon_list) {
722 		scan = link->pkg;
723 		if (scan && (scan->flags & PKGF_BUILDTRAV))
724 			build_clear_trav(scan);
725 	}
726 }
727 
728 /*
729  * Calculate the longest chain of packages that depend on me.  The
730  * long the chain, the more important my package is to build earlier
731  * rather than later.
732  */
733 static int
734 buildCalculateDepiDepth(pkg_t *pkg)
735 {
736 	pkglink_t *link;
737 	pkg_t *scan;
738 	int best_depth = 0;
739 	int res;
740 
741 	if (pkg->depi_depth)
742 		return(pkg->depi_depth + 1);
743 	pkg->flags |= PKGF_BUILDLOOP;
744 	PKGLIST_FOREACH(link, &pkg->deponi_list) {
745 		scan = link->pkg;
746 		if (scan && (scan->flags & PKGF_BUILDLOOP) == 0) {
747 			res = buildCalculateDepiDepth(scan);
748 			if (best_depth < res)
749 				best_depth = res;
750 		}
751 	}
752 	pkg->flags &= ~PKGF_BUILDLOOP;
753 	pkg->depi_depth = best_depth;
754 
755 	return (best_depth + 1);
756 }
757 
758 /*
759  * Take a list of pkg ready to go, sort it, and assign it to worker
760  * slots.  This routine blocks in waitbuild() until it can dispose of
761  * the entire list.
762  *
763  * WorkerMutex is held by the caller.
764  */
765 static
766 void
767 startbuild(pkg_t **build_listp, pkg_t ***build_tailp)
768 {
769 	pkg_t *pkg;
770 	pkg_t **idep_ary;
771 	pkg_t **depi_ary;
772 	int count;
773 	int idep_index;
774 	int depi_index;
775 	int i;
776 	int n;
777 	worker_t *work;
778 	static int IterateWorker;
779 
780 	/*
781 	 * Nothing to do
782 	 */
783 	if (*build_listp == NULL)
784 		return;
785 
786 	/*
787 	 * Sort
788 	 */
789 	count = 0;
790 	for (pkg = *build_listp; pkg; pkg = pkg->build_next)
791 		++count;
792 	idep_ary = calloc(count, sizeof(pkg_t *));
793 	depi_ary = calloc(count, sizeof(pkg_t *));
794 
795 	count = 0;
796 	for (pkg = *build_listp; pkg; pkg = pkg->build_next) {
797 		idep_ary[count] = pkg;
798 		depi_ary[count] = pkg;
799 		++count;
800 	}
801 
802 	/*
803 	 * idep_ary - sorted by #of dependencies this pkg has.
804 	 * depi_ary - sorted by #of other packages that depend on this pkg.
805 	 */
806 	qsort(idep_ary, count, sizeof(pkg_t *), qsort_idep);
807 	qsort(depi_ary, count, sizeof(pkg_t *), qsort_depi);
808 
809 	idep_index = 0;
810 	depi_index = 0;
811 
812 	/*
813 	 * Half the workers build based on the highest depi count,
814 	 * the other half build based on the highest idep count.
815 	 *
816 	 * This is an attempt to get projects which many other projects
817 	 * depend on built first, but to also try to build large projects
818 	 * (which tend to have a lot of dependencies) earlier rather than
819 	 * later so the end of the bulk run doesn't inefficiently build
820 	 * the last few huge projects.
821 	 *
822 	 * Loop until we manage to assign slots to everyone.  We do not
823 	 * wait for build completion.
824 	 *
825 	 * This is the point where we handle DUMMY packages (these are
826 	 * dummy unflavored packages which 'cover' all the flavors for
827 	 * a package).  These are not real packages are marked SUCCESS
828 	 * at this time because their dependencies (the flavors) have all
829 	 * been built.
830 	 */
831 	while (idep_index != count || depi_index != count) {
832 		pkg_t *pkgi;
833 		pkg_t *ipkg;
834 
835 		/*
836 		 * Find candidate to start sorted by depi or idep.
837 		 */
838 		ipkg = NULL;
839 		while (idep_index < count) {
840 			ipkg = idep_ary[idep_index];
841 			if ((ipkg->flags &
842 			     (PKGF_SUCCESS | PKGF_FAILURE |
843 			      PKGF_ERROR | PKGF_RUNNING)) == 0) {
844 				break;
845 			}
846 			ipkg = NULL;
847 			++idep_index;
848 		}
849 
850 		pkgi = NULL;
851 		while (depi_index < count) {
852 			pkgi = depi_ary[depi_index];
853 			if ((pkgi->flags &
854 			     (PKGF_SUCCESS | PKGF_FAILURE |
855 			      PKGF_ERROR | PKGF_RUNNING)) == 0) {
856 				break;
857 			}
858 			pkgi = NULL;
859 			++depi_index;
860 		}
861 
862 		/*
863 		 * ipkg and pkgi must either both be NULL, or both
864 		 * be non-NULL.
865 		 */
866 		if (ipkg == NULL && pkgi == NULL)
867 			break;
868 		ddassert(ipkg && pkgi);
869 
870 		/*
871 		 * Handle the NOBUILD case right here, there's no point
872 		 * queueing it anywhere.
873 		 */
874 		if (ipkg->flags & PKGF_NOBUILD) {
875 			char *reason;
876 			char skipbuf[16];
877 			int scount;
878 
879 			scount = buildskipcount_dueto(ipkg, 1);
880 			buildskipcount_dueto(ipkg, 0);
881 			if (scount) {
882 				snprintf(skipbuf, sizeof(skipbuf), " %d",
883 					 scount);
884 			} else {
885 				skipbuf[0] = 0;
886 			}
887 
888 			ipkg->flags |= PKGF_FAILURE;
889 			ipkg->flags &= ~PKGF_BUILDLIST;
890 
891 			reason = buildskipreason(NULL, ipkg);
892 			if (ipkg->flags & PKGF_NOBUILD_I) {
893 				++BuildIgnoreCount;
894 				dlog(DLOG_IGN,
895 				     "[XXX] %s%s ignored due to %s\n",
896 				     ipkg->portdir, skipbuf, reason);
897 				RunStatsUpdateCompletion(NULL, DLOG_IGN, ipkg,
898 							 reason, skipbuf);
899 				doHook(ipkg, "hook_pkg_ignored",
900 				       HookPkgIgnored, 0);
901 			} else {
902 				++BuildSkipCount;
903 				dlog(DLOG_SKIP,
904 				     "[XXX] %s%s skipped due to %s\n",
905 				     ipkg->portdir, skipbuf, reason);
906 				RunStatsUpdateCompletion(NULL, DLOG_SKIP, ipkg,
907 							 reason, skipbuf);
908 				doHook(ipkg, "hook_pkg_skipped",
909 				       HookPkgSkipped, 0);
910 			}
911 			free(reason);
912 			++BuildCount;
913 			continue;
914 		}
915 		if (pkgi->flags & PKGF_NOBUILD) {
916 			char *reason;
917 			char skipbuf[16];
918 			int scount;
919 
920 			scount = buildskipcount_dueto(pkgi, 1);
921 			buildskipcount_dueto(pkgi, 0);
922 			if (scount) {
923 				snprintf(skipbuf, sizeof(skipbuf), " %d",
924 					 scount);
925 			} else {
926 				skipbuf[0] = 0;
927 			}
928 
929 			pkgi->flags |= PKGF_FAILURE;
930 			pkgi->flags &= ~PKGF_BUILDLIST;
931 
932 			reason = buildskipreason(NULL, pkgi);
933 			if (pkgi->flags & PKGF_NOBUILD_I) {
934 				++BuildIgnoreCount;
935 				dlog(DLOG_IGN, "[XXX] %s%s ignored due to %s\n",
936 				     pkgi->portdir, skipbuf, reason);
937 				RunStatsUpdateCompletion(NULL, DLOG_IGN, pkgi,
938 							 reason, skipbuf);
939 				doHook(pkgi, "hook_pkg_ignored",
940 				       HookPkgIgnored, 0);
941 			} else {
942 				++BuildSkipCount;
943 				dlog(DLOG_SKIP,
944 				     "[XXX] %s%s skipped due to %s\n",
945 				     pkgi->portdir, skipbuf, reason);
946 				RunStatsUpdateCompletion(NULL, DLOG_SKIP, pkgi,
947 							 reason, skipbuf);
948 				doHook(pkgi, "hook_pkg_skipped",
949 				       HookPkgSkipped, 0);
950 			}
951 			free(reason);
952 			++BuildCount;
953 			continue;
954 		}
955 
956 		/*
957 		 * Block while no slots are available.  waitbuild()
958 		 * will clean out any DONE states.
959 		 */
960 		while (RunningWorkers >= DynamicMaxWorkers ||
961 		       RunningWorkers >= MaxWorkers - FailedWorkers) {
962 			waitbuild(RunningWorkers, 1);
963 		}
964 
965 		/*
966 		 * Find an available worker slot, there should be at
967 		 * least one.
968 		 */
969 		for (i = 0; i < MaxWorkers; ++i) {
970 			n = IterateWorker % MaxWorkers;
971 			work = &WorkerAry[n];
972 
973 			if (work->state == WORKER_DONE ||
974 			    work->state == WORKER_FAILED) {
975 				workercomplete(work);
976 			}
977 			if (work->state == WORKER_NONE ||
978 			    work->state == WORKER_IDLE) {
979 				if (n <= MaxWorkers / 2) {
980 					startworker(pkgi, work);
981 				} else {
982 					startworker(ipkg, work);
983 				}
984 				/*RunStatsUpdate(work);*/
985 				break;
986 			}
987 			++IterateWorker;
988 		}
989 		ddassert(i != MaxWorkers);
990 	}
991 	RunStatsSync();
992 
993 	/*
994 	 * We disposed of the whole list
995 	 */
996 	free(idep_ary);
997 	free(depi_ary);
998 	*build_listp = NULL;
999 	*build_tailp = build_listp;
1000 }
1001 
1002 typedef const pkg_t *pkg_tt;
1003 
1004 static int
1005 qsort_idep(const void *pkg1_arg, const void *pkg2_arg)
1006 {
1007 	const pkg_t *pkg1 = *(const pkg_tt *)pkg1_arg;
1008 	const pkg_t *pkg2 = *(const pkg_tt *)pkg2_arg;
1009 
1010 	return (pkg2->idep_count - pkg1->idep_count);
1011 }
1012 
1013 static int
1014 qsort_depi(const void *pkg1_arg, const void *pkg2_arg)
1015 {
1016 	const pkg_t *pkg1 = *(const pkg_tt *)pkg1_arg;
1017 	const pkg_t *pkg2 = *(const pkg_tt *)pkg2_arg;
1018 
1019 	return ((pkg2->depi_count * pkg2->depi_depth) -
1020 		(pkg1->depi_count * pkg1->depi_depth));
1021 }
1022 
1023 /*
1024  * Frontend starts a pkg up on a worker
1025  *
1026  * WorkerMutex must be held.
1027  */
1028 static void
1029 startworker(pkg_t *pkg, worker_t *work)
1030 {
1031 	switch(work->state) {
1032 	case WORKER_NONE:
1033 		pthread_create(&work->td, NULL, childBuilderThread, work);
1034 		work->state = WORKER_IDLE;
1035 		/* fall through */
1036 	case WORKER_IDLE:
1037 		work->pkg_dep_size =
1038 		childInstallPkgDeps_recurse(NULL, &pkg->idepon_list, 0, 1, 0);
1039 		childInstallPkgDeps_recurse(NULL, &pkg->idepon_list, 1, 1, 0);
1040 		RunningPkgDepSize += work->pkg_dep_size;
1041 
1042 		dlog(DLOG_ALL, "[%03d] START   %s "
1043 			       "##idep=%02d depi=%02d/%02d dep=%-4.2fG\n",
1044 		     work->index, pkg->portdir,
1045 		     pkg->idep_count, pkg->depi_count, pkg->depi_depth,
1046 		     (double)work->pkg_dep_size / (double)ONEGB);
1047 
1048 		cleanworker(work);
1049 		pkg->flags |= PKGF_RUNNING;
1050 		work->pkg = pkg;
1051 		pthread_cond_signal(&work->cond);
1052 		++RunningWorkers;
1053 		/*RunStatsUpdate(work);*/
1054 		break;
1055 	case WORKER_PENDING:
1056 	case WORKER_RUNNING:
1057 	case WORKER_DONE:
1058 	case WORKER_FAILED:
1059 	case WORKER_FROZEN:
1060 	case WORKER_EXITING:
1061 	default:
1062 		dfatal("startworker: [%03d] Unexpected state %d for worker %d",
1063 		       work->index, work->state, work->index);
1064 		break;
1065 	}
1066 }
1067 
1068 static void
1069 cleanworker(worker_t *work)
1070 {
1071 	work->state = WORKER_PENDING;
1072 	work->flags = 0;
1073 	work->accum_error = 0;
1074 	work->start_time = time(NULL);
1075 }
1076 
1077 /*
1078  * Frontend finishes up a completed pkg on a worker.
1079  *
1080  * If the worker is in a FAILED state we clean the pkg out but (for now)
1081  * leave it in its failed state so we can debug.  At this point
1082  * workercomplete() will be called every once in a while on the state
1083  * and we have to deal with the NULL pkg.
1084  *
1085  * WorkerMutex must be held.
1086  */
1087 static void
1088 workercomplete(worker_t *work)
1089 {
1090 	pkg_t *pkg;
1091 	time_t t;
1092 	int h;
1093 	int m;
1094 	int s;
1095 
1096 	/*
1097 	 * Steady state FAILED case.
1098 	 */
1099 	if (work->state == WORKER_FAILED) {
1100 		if (work->pkg == NULL)
1101 			return;
1102 	}
1103 
1104 	t = time(NULL) - work->start_time;
1105 	h = t / 3600;
1106 	m = t / 60 % 60;
1107 	s = t % 60;
1108 
1109 	/*
1110 	 * Reduce total dep size
1111 	 */
1112 	RunningPkgDepSize -= work->pkg_dep_size;
1113 	RunningPkgDepSize -= work->memuse;
1114 	work->pkg_dep_size = 0;
1115 	work->memuse = 0;
1116 
1117 	/*
1118 	 * Process pkg out of the worker
1119 	 */
1120 	pkg = work->pkg;
1121 	if (pkg->flags & (PKGF_ERROR|PKGF_NOBUILD)) {
1122 		char skipbuf[16];
1123 		int scount;
1124 
1125 		pkg->flags |= PKGF_FAILURE;
1126 
1127 		scount = buildskipcount_dueto(pkg, 1);
1128 		buildskipcount_dueto(pkg, 0);
1129 		if (scount) {
1130 			snprintf(skipbuf, sizeof(skipbuf), " %d",
1131 				 scount);
1132 		} else {
1133 			skipbuf[0] = 0;
1134 		}
1135 
1136 		/*
1137 		 * This NOBUILD condition XXX can occur if the package is
1138 		 * not allowed to be built.
1139 		 */
1140 		if (pkg->flags & PKGF_NOBUILD) {
1141 			char *reason;
1142 
1143 			reason = buildskipreason(NULL, pkg);
1144 			if (pkg->flags & PKGF_NOBUILD_I) {
1145 				++BuildIgnoreCount;
1146 				dlog(DLOG_SKIP, "[%03d] IGNORD %s%s - %s\n",
1147 				     work->index, pkg->portdir,
1148 				     skipbuf, reason);
1149 				RunStatsUpdateCompletion(work, DLOG_SKIP, pkg,
1150 							 reason, skipbuf);
1151 				doHook(pkg, "hook_pkg_ignored",
1152 				       HookPkgIgnored, 0);
1153 			} else {
1154 				++BuildSkipCount;
1155 				dlog(DLOG_SKIP, "[%03d] SKIPPD %s%s - %s\n",
1156 				     work->index, pkg->portdir,
1157 				     skipbuf, reason);
1158 				RunStatsUpdateCompletion(work, DLOG_SKIP, pkg,
1159 							 reason, skipbuf);
1160 				doHook(pkg, "hook_pkg_skipped",
1161 				       HookPkgSkipped, 0);
1162 			}
1163 			free(reason);
1164 		} else {
1165 			++BuildFailCount;
1166 			dlog(DLOG_FAIL | DLOG_RED,
1167 			     "[%03d] FAILURE %s%s ##%16.16s %02d:%02d:%02d\n",
1168 			     work->index, pkg->portdir, skipbuf,
1169 			     getphasestr(work->phase),
1170 			     h, m, s);
1171 			RunStatsUpdateCompletion(work, DLOG_FAIL, pkg,
1172 						 skipbuf, "");
1173 			doHook(pkg, "hook_pkg_failure", HookPkgFailure, 0);
1174 		}
1175 	} else {
1176 		if (CheckDBM) {
1177 			datum key;
1178 			datum data;
1179 
1180 			key.dptr = pkg->portdir;
1181 			key.dsize = strlen(pkg->portdir);
1182 			data.dptr = &pkg->crc32;
1183 			data.dsize = sizeof(pkg->crc32);
1184 			dbm_store(CheckDBM, key, data, DBM_REPLACE);
1185 		}
1186 		pkg->flags |= PKGF_SUCCESS;
1187 		++BuildSuccessCount;
1188 		dlog(DLOG_SUCC | DLOG_GRN,
1189 		     "[%03d] SUCCESS %s ##%02d:%02d:%02d\n",
1190 		     work->index, pkg->portdir, h, m, s);
1191 		RunStatsUpdateCompletion(work, DLOG_SUCC, pkg, "", "");
1192 		doHook(pkg, "hook_pkg_success", HookPkgSuccess, 0);
1193 	}
1194 	++BuildCount;
1195 	pkg->flags &= ~PKGF_BUILDLIST;
1196 	pkg->flags &= ~PKGF_RUNNING;
1197 	work->pkg = NULL;
1198 	--RunningWorkers;
1199 
1200 	if (work->state == WORKER_FAILED) {
1201 		dlog(DLOG_ALL, "[%03d] XXX/XXX WORKER IS IN A FAILED STATE\n",
1202 		     work->index);
1203 		++FailedWorkers;
1204 	} else if (work->flags & WORKERF_FREEZE) {
1205 		dlog(DLOG_ALL, "[%03d] FROZEN(DEBUG) %s\n",
1206 		     work->index, pkg->portdir);
1207 		work->state = WORKER_FROZEN;
1208 	} else {
1209 		work->state = WORKER_IDLE;
1210 	}
1211 }
1212 
1213 /*
1214  * Wait for one or more workers to complete.
1215  *
1216  * WorkerMutex must be held.
1217  */
1218 static void
1219 waitbuild(int whilematch, int dynamicmax)
1220 {
1221 	static time_t wblast_time;
1222 	static time_t dmlast_time;
1223 	struct timespec ts;
1224 	worker_t *work;
1225 	time_t t;
1226 	int i;
1227 
1228 	if (whilematch == 0)
1229 		whilematch = 1;
1230 
1231 	while (RunningWorkers == whilematch) {
1232 		for (i = 0; i < MaxWorkers; ++i) {
1233 			work = &WorkerAry[i];
1234 			if (work->state == WORKER_DONE ||
1235 			    work->state == WORKER_FAILED) {
1236 				workercomplete(work);
1237 			} else {
1238 				pthread_cond_signal(&work->cond);
1239 			}
1240 			RunStatsUpdate(work, NULL);
1241 		}
1242 		RunStatsUpdateTop(1);
1243 		RunStatsUpdateLogs();
1244 		RunStatsSync();
1245 		if (RunningWorkers == whilematch) {
1246 			clock_gettime(CLOCK_REALTIME, &ts);
1247 			ts.tv_sec += 1;
1248 			ts.tv_nsec = 0;
1249 			pthread_cond_timedwait(&WorkerCond, &WorkerMutex, &ts);
1250 		}
1251 
1252 		/*
1253 		 * Dynamically reduce MaxWorkers based on the load.  When
1254 		 * the load exceeds 2 x ncpus we reduce the number of workers
1255 		 * up to 75% of MaxWorkers @ (5 x ncpus) load.
1256 		 *
1257 		 * Dynamically reduce MaxWorkers based on swap use, starting
1258 		 * at 10% swap and up to 75% of MaxWorkers at 40% swap.
1259 		 *
1260 		 * NOTE! Generally speaking this allows more workers to be
1261 		 *	 configured which helps in two ways.  First it allows
1262 		 *	 a higher build rate for smaller packages.  Second
1263 		 *	 it allows dsynth to ratchet-down the number of slots
1264 		 *	 when large packages are forcing the load up.
1265 		 *
1266 		 *	 A high load doesn't hurt efficiency, but swap usage
1267 		 *	 due to loading the tmpfs in lots of worker slots up
1268 		 *	 with tons of pkg install's (pre-reqs for a build)
1269 		 *	 does.  Reducing the number of worker slots has a
1270 		 *	 huge beneficial effect on reducing swap use / paging.
1271 		 */
1272 		t = time(NULL);
1273 		if (dynamicmax && (wblast_time == 0 ||
1274 				   (unsigned)(t - wblast_time) >= 5)) {
1275 			double min_load = 1.5 * NumCores;
1276 			double max_load = 5.0 * NumCores;
1277 			double min_swap = 0.10;
1278 			double max_swap = 0.40;
1279 			double dload[3];
1280 			double dswap;
1281 			int max1;
1282 			int max2;
1283 			int max3;
1284 			int max_sel;
1285 			int noswap;
1286 
1287 			wblast_time = t;
1288 
1289 			/*
1290 			 * Cap based on load.  This is back-loaded.
1291 			 */
1292 			getloadavg(dload, 3);
1293 			adjloadavg(dload);
1294 			if (dload[0] < min_load) {
1295 				max1 = MaxWorkers;
1296 			} else if (dload[0] <= max_load) {
1297 				max1 = MaxWorkers -
1298 				       MaxWorkers * 0.75 *
1299 				       (dload[0] - min_load) /
1300 				       (max_load - min_load);
1301 			} else {
1302 				max1 = MaxWorkers * 25 / 100;
1303 			}
1304 
1305 			/*
1306 			 * Cap based on swap use.  This is back-loaded.
1307 			 */
1308 			dswap = getswappct(&noswap);
1309 			if (dswap < min_swap) {
1310 				max2 = MaxWorkers;
1311 			} else if (dswap <= max_swap) {
1312 				max2 = MaxWorkers -
1313 				       MaxWorkers * 0.75 *
1314 				       (dswap - min_swap) /
1315 				       (max_swap - min_swap);
1316 			} else {
1317 				max2 = MaxWorkers * 25 / 100;
1318 			}
1319 
1320 			/*
1321 			 * Cap based on aggregate pkg-dependency memory
1322 			 * use installed in worker slots.  This is
1323 			 * front-loaded.
1324 			 *
1325 			 * Since it can take a while for workers to retire
1326 			 * (to reduce RunningPkgDepSize), just set our
1327 			 * target 1 below the current run count to allow
1328 			 * jobs to retire without being replaced with new
1329 			 * jobs.
1330 			 *
1331 			 * In addition, in order to avoid a paging 'shock',
1332 			 * We enforce a 30 second-per-increment slow-start
1333 			 * once RunningPkgDepSize exceeds 1/2 the target.
1334 			 */
1335 			if (RunningPkgDepSize > PkgDepMemoryTarget) {
1336 				max3 = RunningWorkers - 1;
1337 			} else if (RunningPkgDepSize > PkgDepMemoryTarget / 2) {
1338 				if (dmlast_time == 0 ||
1339 				    (unsigned)(t - dmlast_time) >= 30) {
1340 					dmlast_time = t;
1341 					max3 = RunningWorkers + 1;
1342 				} else {
1343 					max3 = RunningWorkers;
1344 				}
1345 			} else {
1346 				max3 = MaxWorkers;
1347 			}
1348 
1349 			/*
1350 			 * Priority reduction, convert to DynamicMaxWorkers
1351 			 */
1352 			max_sel = max1;
1353 			if (max_sel > max2)
1354 				max_sel = max2;
1355 			if (max_sel > max3)
1356 				max_sel = max3;
1357 
1358 			/*
1359 			 * Restrict to allowed range, and also handle
1360 			 * slow-start.
1361 			 */
1362 			if (max_sel < 1)
1363 				max_sel = 1;
1364 			if (max_sel > DynamicMaxWorkers + 1)
1365 				max_sel = DynamicMaxWorkers + 1;
1366 			if (max_sel > MaxWorkers)
1367 				max_sel = MaxWorkers;
1368 
1369 			/*
1370 			 * Stop waiting if DynamicMaxWorkers is going to
1371 			 * increase.
1372 			 */
1373 			if (DynamicMaxWorkers < max1)
1374 				whilematch = -1;
1375 
1376 			/*
1377 			 * And adjust
1378 			 */
1379 			if (DynamicMaxWorkers != max1) {
1380 				dlog(DLOG_ALL | DLOG_FILTER,
1381 				     "[XXX] Load=%-6.2f(%2d) "
1382 				     "Swap=%-3.2f%%(%2d) "
1383 				     "Mem=%3.2fG(%2d) "
1384 				     "Adjust Workers %d->%d\n",
1385 				     dload[0], max1,
1386 				     dswap * 100.0, max2,
1387 				     RunningPkgDepSize / (double)ONEGB, max3,
1388 				     DynamicMaxWorkers, max_sel);
1389 				DynamicMaxWorkers = max_sel;
1390 			}
1391 		}
1392 	}
1393 }
1394 
1395 
1396 /*
1397  * Worker pthread (WorkerAry)
1398  *
1399  * This thread belongs to the dsynth master process and handled a worker slot.
1400  * (this_thread) -> WORKER fork/exec (WorkerPocess) -> (pty) -> sub-processes.
1401  */
1402 static void *
1403 childBuilderThread(void *arg)
1404 {
1405 	char *envary[1] = { NULL };
1406 	worker_t *work = arg;
1407 	wmsg_t wmsg;
1408 	pkg_t *pkg;
1409 	pid_t pid;
1410 	int status;
1411 	int flags;
1412 	volatile int dowait;
1413 	char slotbuf[8];
1414 	char fdbuf[8];
1415 	char flagsbuf[16];
1416 
1417 	pthread_mutex_lock(&WorkerMutex);
1418 	while (work->terminate == 0) {
1419 		dowait = 1;
1420 
1421 		switch(work->state) {
1422 		case WORKER_IDLE:
1423 			break;
1424 		case WORKER_PENDING:
1425 			/*
1426 			 * Fork the management process for the pkg operation
1427 			 * on this worker slot.
1428 			 *
1429 			 * This process will set up the environment, do the
1430 			 * mounts, will become the reaper, and will process
1431 			 * pipe commands and handle chroot operations.
1432 			 *
1433 			 * NOTE: If SOCK_CLOEXEC is not supported WorkerMutex
1434 			 *	 is sufficient to interlock F_SETFD FD_CLOEXEC
1435 			 *	 operations.
1436 			 */
1437 			ddassert(work->pkg);
1438 			if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC,
1439 				       PF_UNSPEC, work->fds)) {
1440 				dfatal_errno("socketpair() during worker fork");
1441 			}
1442 			snprintf(slotbuf, sizeof(slotbuf), "%d", work->index);
1443 			snprintf(fdbuf, sizeof(fdbuf), "3");
1444 
1445 			/*
1446 			 * Pass global flags and add-in the DEBUGSTOP if
1447 			 * the package is flagged for debugging.
1448 			 */
1449 			flags = WorkerProcFlags;
1450 			if (work->pkg->flags & PKGF_DEBUGSTOP) {
1451 				flags |= WORKER_PROC_DEBUGSTOP;
1452 			} else {
1453 				flags &= ~WORKER_PROC_DEBUGSTOP;
1454 			}
1455 			snprintf(flagsbuf, sizeof(flagsbuf), "%d", flags);
1456 
1457 			/*
1458 			 * fds[0] - master
1459 			 * fds[1] - slave
1460 			 *
1461 			 * We pass the salve descriptor in fd 3 and close all
1462 			 * other descriptors for security.
1463 			 */
1464 			pthread_mutex_unlock(&WorkerMutex);
1465 			pid = vfork();
1466 			if (pid == 0) {
1467 				close(work->fds[0]);
1468 				dup2(work->fds[1], 3);
1469 				closefrom(4);
1470 				fcntl(3, F_SETFD, 0);
1471 				execle(DSynthExecPath, DSynthExecPath,
1472 				       "-p", Profile,
1473 				       "WORKER", slotbuf, fdbuf,
1474 				       work->pkg->portdir, work->pkg->pkgfile,
1475 				       flagsbuf,
1476 				       NULL, envary);
1477 				write(2, "EXECLE FAILURE\n", 15);
1478 				_exit(1);
1479 			}
1480 			pthread_mutex_lock(&WorkerMutex);
1481 			close(work->fds[1]);
1482 			work->phase = PHASE_PENDING;
1483 			work->lines = 0;
1484 			work->memuse = 0;
1485 			work->pid = pid;
1486 			work->state = WORKER_RUNNING;
1487 			/* fall through */
1488 		case WORKER_RUNNING:
1489 			/*
1490 			 * Poll for status updates, if NULL is returned
1491 			 * and status is non-zero, the communications link
1492 			 * failed unexpectedly.
1493 			 */
1494 			pkg = work->pkg;
1495 			pthread_mutex_unlock(&WorkerMutex);
1496 			status = ipcreadmsg(work->fds[0], &wmsg);
1497 			pthread_mutex_lock(&WorkerMutex);
1498 
1499 			if (status == 0) {
1500 				/*
1501 				 * Normal message, can include normal
1502 				 * termination which changes us over
1503 				 * to another state.
1504 				 */
1505 				dowait = 0;
1506 				switch(wmsg.cmd) {
1507 				case WMSG_CMD_INSTALL_PKGS:
1508 					wmsg.cmd = WMSG_RES_INSTALL_PKGS;
1509 					wmsg.status = childInstallPkgDeps(work);
1510 					pthread_mutex_unlock(&WorkerMutex);
1511 					ipcwritemsg(work->fds[0], &wmsg);
1512 					pthread_mutex_lock(&WorkerMutex);
1513 					break;
1514 				case WMSG_CMD_STATUS_UPDATE:
1515 					work->phase = wmsg.phase;
1516 					work->lines = wmsg.lines;
1517 					if (work->memuse != wmsg.memuse) {
1518 						RunningPkgDepSize +=
1519 						wmsg.memuse - work->memuse;
1520 						work->memuse = wmsg.memuse;
1521 					}
1522 					break;
1523 				case WMSG_CMD_SUCCESS:
1524 					work->flags |= WORKERF_SUCCESS;
1525 					break;
1526 				case WMSG_CMD_FAILURE:
1527 					work->flags |= WORKERF_FAILURE;
1528 					break;
1529 				case WMSG_CMD_FREEZEWORKER:
1530 					work->flags |= WORKERF_FREEZE;
1531 					break;
1532 				default:
1533 					break;
1534 				}
1535 				RunStatsUpdate(work, NULL);
1536 				RunStatsSync();
1537 			} else {
1538 				close(work->fds[0]);
1539 				pthread_mutex_unlock(&WorkerMutex);
1540 				while (waitpid(work->pid, &status, 0) < 0 &&
1541 				       errno == EINTR) {
1542 					;
1543 				}
1544 				pthread_mutex_lock(&WorkerMutex);
1545 
1546 				if (work->flags & WORKERF_SUCCESS) {
1547 					pkg->flags |= PKGF_SUCCESS;
1548 					work->state = WORKER_DONE;
1549 				} else if (work->flags & WORKERF_FAILURE) {
1550 					pkg->flags |= PKGF_FAILURE;
1551 					work->state = WORKER_DONE;
1552 				} else {
1553 					pkg->flags |= PKGF_FAILURE;
1554 					work->state = WORKER_FAILED;
1555 				}
1556 				work->flags |= WORKERF_STATUS_UPDATE;
1557 				pthread_cond_signal(&WorkerCond);
1558 			}
1559 			break;
1560 		case WORKER_DONE:
1561 			/*
1562 			 * pkg remains attached until frontend processes the
1563 			 * completion.  The frontend will then set the state
1564 			 * back to idle.
1565 			 */
1566 			break;
1567 		case WORKER_FAILED:
1568 			/*
1569 			 * A worker failure means that the worker did not
1570 			 * send us a WMSG_CMD_SUCCESS or WMSG_CMD_FAILURE
1571 			 * ipc before terminating.
1572 			 *
1573 			 * We just sit in this state until the front-end
1574 			 * does something about it.
1575 			 */
1576 			break;
1577 		case WORKER_FROZEN:
1578 			/*
1579 			 * A worker getting frozen is debug-related.  We
1580 			 * just sit in this state (likely forever).
1581 			 */
1582 			break;
1583 		default:
1584 			dfatal("worker: [%03d] Unexpected state %d "
1585 			       "for worker %d",
1586 			       work->index, work->state, work->index);
1587 			/* NOT REACHED */
1588 			break;
1589 		}
1590 
1591 		/*
1592 		 * The dsynth frontend will poll us approximately once
1593 		 * a second (its variable).
1594 		 */
1595 		if (dowait)
1596 			pthread_cond_wait(&work->cond, &WorkerMutex);
1597 	}
1598 
1599 	/*
1600 	 * Scrap the comm socket if running, this should cause the worker
1601 	 * process to kill its sub-programs and cleanup.
1602 	 */
1603 	if (work->state == WORKER_RUNNING) {
1604 		pthread_mutex_unlock(&WorkerMutex);
1605 		close(work->fds[0]);
1606 		while (waitpid(work->pid, &status, 0) < 0 &&
1607 		       errno == EINTR);
1608 		pthread_mutex_lock(&WorkerMutex);
1609 	}
1610 
1611 	/*
1612 	 * Final handshake
1613 	 */
1614 	work->state = WORKER_EXITING;
1615 	pthread_cond_signal(&WorkerCond);
1616 	pthread_mutex_unlock(&WorkerMutex);
1617 
1618 	return NULL;
1619 }
1620 
1621 /*
1622  * Install all the binary packages (we have already built them) that
1623  * the current work package depends on, without duplicates, in a script
1624  * which will be run from within the specified work jail.
1625  *
1626  * Locked by WorkerMutex (global)
1627  */
1628 static int
1629 childInstallPkgDeps(worker_t *work)
1630 {
1631 	char *buf;
1632 	FILE *fp;
1633 
1634 	if (PKGLIST_EMPTY(&work->pkg->idepon_list))
1635 		return 0;
1636 
1637 	asprintf(&buf, "%s/tmp/dsynth_install_pkgs", work->basedir);
1638 	fp = fopen(buf, "w");
1639 	ddassert(fp != NULL);
1640 	fprintf(fp, "#!/bin/sh\n");
1641 	fprintf(fp, "#\n");
1642 	fchmod(fileno(fp), 0755);
1643 
1644 	childInstallPkgDeps_recurse(fp, &work->pkg->idepon_list, 0, 1, 0);
1645 	childInstallPkgDeps_recurse(fp, &work->pkg->idepon_list, 1, 1, 0);
1646 	fprintf(fp, "\nexit 0\n");
1647 	fclose(fp);
1648 	freestrp(&buf);
1649 
1650 	return 1;
1651 }
1652 
1653 /*
1654  * Recursive child install dependencies.
1655  *
1656  * first_one_only is only specified if the pkg the list comes from
1657  * is a generic unflavored package that has flavors, telling us to
1658  * dive the first flavor only.
1659  *
1660  * However, in nearly all cases this flag will now be zero because
1661  * this code now dives the first flavor when encountering a dummy node
1662  * and clears nfirst on success.  Hence if you are asking why 'nfirst'
1663  * is set to 1, and then zero, instead of just being removed entirely,
1664  * it is because there might still be an edge case here.
1665  */
1666 static size_t
1667 childInstallPkgDeps_recurse(FILE *fp, pkglink_t *list, int undoit,
1668 			    int depth, int first_one_only)
1669 {
1670 	pkglink_t *link;
1671 	pkg_t *pkg;
1672 	size_t tot = 0;
1673 	int ndepth;
1674 	int nfirst;
1675 
1676 	PKGLIST_FOREACH(link, list) {
1677 		pkg = link->pkg;
1678 
1679 		/*
1680 		 * We don't want to mess up our depth test just below if
1681 		 * a DUMMY node had to be inserted.  The nodes under the
1682 		 * dummy node.
1683 		 *
1684 		 * The elements under a dummy node represent all the flabor,
1685 		 * a dependency that directly references a dummy node only
1686 		 * uses the first flavor (first_one_only / nfirst).
1687 		 */
1688 		ndepth = (pkg->flags & PKGF_DUMMY) ? depth : depth + 1;
1689 		nfirst = (pkg->flags & PKGF_DUMMY) ? 1 : 0;
1690 
1691 		/*
1692 		 * We only need all packages for the top-level dependencies.
1693 		 * The deeper ones only need DEP_TYPE_LIB and DEP_TYPE_RUN
1694 		 * (types greater than DEP_TYPE_BUILD) since they are already
1695 		 * built.
1696 		 */
1697 		if (depth > 1 && link->dep_type <= DEP_TYPE_BUILD) {
1698 			if (first_one_only)
1699 				break;
1700 			continue;
1701 		}
1702 
1703 		/*
1704 		 * If this is a dummy node with no package, the originator
1705 		 * is requesting a flavored package.  We select the default
1706 		 * flavor which we presume is the first one.
1707 		 */
1708 		if (pkg->pkgfile == NULL && (pkg->flags & PKGF_DUMMY)) {
1709 			pkg_t *spkg = pkg->idepon_list.next->pkg;
1710 
1711 			if (spkg) {
1712 				if (fp) {
1713 					fprintf(fp,
1714 						"echo 'UNFLAVORED %s -> use "
1715 						"%s'\n",
1716 						pkg->portdir,
1717 						spkg->portdir);
1718 				}
1719 				pkg = spkg;
1720 				nfirst = 0;
1721 			} else {
1722 				if (fp) {
1723 					fprintf(fp,
1724 						"echo 'CANNOT FIND DEFAULT "
1725 						"FLAVOR FOR %s'\n",
1726 						pkg->portdir);
1727 				}
1728 			}
1729 		}
1730 
1731 		if (undoit) {
1732 			if (pkg->dsynth_install_flg == 1) {
1733 				pkg->dsynth_install_flg = 0;
1734 				tot += childInstallPkgDeps_recurse(fp,
1735 							    &pkg->idepon_list,
1736 							    undoit,
1737 							    ndepth, nfirst);
1738 			}
1739 			if (first_one_only)
1740 				break;
1741 			continue;
1742 		}
1743 
1744 		if (pkg->dsynth_install_flg) {
1745 			if (DebugOpt >= 2 && pkg->pkgfile && fp) {
1746 				fprintf(fp, "echo 'AlreadyHave %s'\n",
1747 					pkg->pkgfile);
1748 			}
1749 			if (first_one_only)
1750 				break;
1751 			continue;
1752 		}
1753 
1754 		tot += childInstallPkgDeps_recurse(fp, &pkg->idepon_list,
1755 						   undoit, ndepth, nfirst);
1756 		if (pkg->dsynth_install_flg) {
1757 			if (first_one_only)
1758 				break;
1759 			continue;
1760 		}
1761 		pkg->dsynth_install_flg = 1;
1762 
1763 		/*
1764 		 * Generate package installation command
1765 		 */
1766 		if (fp && pkg->pkgfile) {
1767 			fprintf(fp, "echo 'Installing /packages/All/%s'\n",
1768 				pkg->pkgfile);
1769 			fprintf(fp, "pkg install -q -U -y /packages/All/%s "
1770 				"|| exit 1\n",
1771 				pkg->pkgfile);
1772 		} else if (fp) {
1773 			fprintf(fp, "echo 'CANNOT FIND PKG FOR %s'\n",
1774 				pkg->portdir);
1775 		}
1776 
1777 		if (pkg->pkgfile) {
1778 			struct stat st;
1779 			char *path;
1780 			char *ptr;
1781 
1782 			asprintf(&path, "%s/%s", RepositoryPath, pkg->pkgfile);
1783 			ptr = strrchr(pkg->pkgfile, '.');
1784 			if (stat(path, &st) == 0) {
1785 				if (strcmp(ptr, ".tar") == 0)
1786 					tot += st.st_size;
1787 				else if (strcmp(ptr, ".tgz") == 0)
1788 					tot += st.st_size * 3;
1789 				else if (strcmp(ptr, ".txz") == 0)
1790 					tot += st.st_size * 5;
1791 				else if (strcmp(ptr, ".tbz") == 0)
1792 					tot += st.st_size * 3;
1793 				else
1794 					tot += st.st_size * 2;
1795 			}
1796 			free(path);
1797 		}
1798 		if (first_one_only)
1799 			break;
1800 	}
1801 	return tot;
1802 }
1803 
1804 /*
1805  * Worker process interactions.
1806  *
1807  * The worker process is responsible for managing the build of a single
1808  * package.  It is exec'd by the master dsynth and only loads the
1809  * configuration.
1810  *
1811  * This process does not run in the chroot.  It will become the reaper for
1812  * all sub-processes and it will enter the chroot to execute various phases.
1813  * It catches SIGINTR, SIGHUP, and SIGPIPE and will iterate, terminate, and
1814  * reap all sub-process upon kill or exit.
1815  *
1816  * The command line forwarded to this function is:
1817  *
1818  *	WORKER slot# socketfd portdir/subdir
1819  *
1820  * TERM=dumb
1821  * USER=root
1822  * HOME=/root
1823  * LANG=C
1824  * SSL_NO_VERIFY_PEER=1
1825  * USE_PACKAGE_DEPENDS_ONLY=1
1826  * PORTSDIR=/xports
1827  * PORT_DBDIR=/options		For ports options
1828  * PACKAGE_BUILDING=yes		Don't build packages that aren't legally
1829  *				buildable for a binary repo.
1830  * PKG_DBDIR=/var/db/pkg
1831  * PKG_CACHEDIR=/var/cache/pkg
1832  * PKG_CREATE_VERBOSE=yes	Ensure periodic output during packaging
1833  * (custom environment)
1834  * PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
1835  * UNAME_s=DragonFly		(example)
1836  * UNAME_v=DragonFly 5.7-SYNTH	(example)
1837  * UNAME_p=x86_64		(example)
1838  * UNAME_m=x86_64		(example)
1839  * UNAME_r=5.7-SYNTH		(example)
1840  * NO_DEPENDS=yes		(conditional based on phase)
1841  * DISTDIR=/distfiles
1842  * WRKDIRPREFIX=/construction
1843  * BATCH=yes
1844  * MAKE_JOBS_NUMBER=n
1845  *
1846  * SETUP:
1847  *	ldconfig -R
1848  *	/usr/local/sbin/pkg-static install /packages/All/<the pkg pkg>
1849  *	/usr/local/sbin/pkg-static install /packages/All/<pkg>
1850  *			(for all dependencies)
1851  *
1852  * PHASES: 		make -C path FLAVOR=flavor <phase>
1853  *	check-sanity
1854  *	pkg-depends
1855  *	fetch-depends
1856  *	fetch
1857  *	checksum
1858  *	extract-depends
1859  *	extract
1860  *	patch-depends
1861  *	patch
1862  *	build-depends
1863  *	lib-depends
1864  *	configure
1865  *	build
1866  *	run-depends
1867  *	stage
1868  *	test		(skipped)
1869  *	check-plist	('dsynth test blahblah' or 'dsynth -D everything' only)
1870  *	package		 e.g. /construction/lang/perl5.28/pkg/perl5-5.28.2.txz
1871  *	install-mtree	(skipped)
1872  *	install		(skipped)
1873  *	deinstall	(skipped)
1874  */
1875 void
1876 WorkerProcess(int ac, char **av)
1877 {
1878 	wmsg_t wmsg;
1879 	int fd;
1880 	int slot;
1881 	int tmpfd;
1882 	int pkgpkg = 0;
1883 	int status;
1884 	int len;
1885 	int do_install_phase;
1886 	char *portdir;
1887 	char *pkgfile;
1888 	char *flavor;
1889 	char *buf;
1890 	worker_t *work;
1891 	bulk_t *bulk;
1892 	pkg_t pkg;
1893 	buildenv_t *benv;
1894 	FILE *fp;
1895 
1896 	/*
1897 	 * Parse arguments
1898 	 */
1899 	if (ac != 6) {
1900 		dlog(DLOG_ALL, "WORKER PROCESS %d- bad arguments\n", getpid());
1901 		exit(1);
1902 	}
1903 	slot = strtol(av[1], NULL, 0);
1904 	fd = strtol(av[2], NULL, 0);	/* master<->slave messaging */
1905 	portdir = av[3];
1906 	pkgfile = av[4];
1907 	flavor = strchr(portdir, '@');
1908 	if (flavor) {
1909 		*flavor++ = 0;
1910 		asprintf(&buf, "@%s", flavor);
1911 		WorkerFlavorPrt = buf;
1912 		buf = NULL;	/* safety */
1913 	}
1914 	WorkerProcFlags = strtol(av[5], NULL, 0);
1915 
1916 	bzero(&wmsg, sizeof(wmsg));
1917 
1918 	setproctitle("[%02d] WORKER STARTUP  %s%s",
1919 		     slot, portdir, WorkerFlavorPrt);
1920 
1921 	if (strcmp(portdir, "ports-mgmt/pkg") == 0)
1922 		pkgpkg = 1;
1923 
1924 	signal(SIGTERM, phaseTerminateSignal);
1925 	signal(SIGINT, phaseTerminateSignal);
1926 	signal(SIGHUP, phaseTerminateSignal);
1927 
1928 	/*
1929 	 * Set up the environment
1930 	 */
1931 	setenv("TERM", "dumb", 1);
1932 	setenv("USER", "root", 1);
1933 	setenv("HOME", "/root", 1);
1934 	setenv("LANG", "C", 1);
1935 	setenv("SSL_NO_VERIFY_PEER", "1", 1);
1936 
1937 	addbuildenv("USE_PACKAGE_DEPENDS_ONLY", "yes", BENV_MAKECONF);
1938 	addbuildenv("PORTSDIR", "/xports", BENV_MAKECONF);
1939 	addbuildenv("PORT_DBDIR", "/options", BENV_MAKECONF);
1940 	addbuildenv("PKG_DBDIR", "/var/db/pkg", BENV_MAKECONF);
1941 	addbuildenv("PKG_CACHEDIR", "/var/cache/pkg", BENV_MAKECONF);
1942 	addbuildenv("PKG_SUFX", UsePkgSufx, BENV_MAKECONF);
1943 	if (WorkerProcFlags & WORKER_PROC_DEVELOPER)
1944 		addbuildenv("DEVELOPER", "1", BENV_MAKECONF);
1945 
1946 	/*
1947 	 * CCache is a horrible unreliable hack but... leave the
1948 	 * mechanism in-place in case someone has a death wish.
1949 	 */
1950 	if (UseCCache) {
1951 		addbuildenv("WITH_CCACHE_BUILD", "yes", BENV_MAKECONF);
1952 		addbuildenv("CCACHE_DIR", "/ccache", BENV_MAKECONF);
1953 	}
1954 
1955 	addbuildenv("UID", "0", BENV_MAKECONF);
1956 	addbuildenv("ARCH", ArchitectureName, BENV_MAKECONF);
1957 
1958 #ifdef __DragonFly__
1959 	addbuildenv("OPSYS", "DragonFly", BENV_MAKECONF);
1960 	addbuildenv("DFLYVERSION", VersionFromParamHeader, BENV_MAKECONF);
1961 	addbuildenv("OSVERSION", "9999999", BENV_MAKECONF);
1962 #else
1963 #error "Need OS-specific data to generate make.conf"
1964 #endif
1965 
1966 	addbuildenv("OSREL", ReleaseName, BENV_MAKECONF);
1967 	addbuildenv("_OSRELEASE", VersionOnlyName, BENV_MAKECONF);
1968 
1969 	setenv("PATH",
1970 	       "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
1971 	       1);
1972 
1973 	setenv("UNAME_s", OperatingSystemName, 1);
1974 	setenv("UNAME_v", VersionName, 1);
1975 	setenv("UNAME_p", ArchitectureName, 1);
1976 	setenv("UNAME_m", MachineName, 1);
1977 	setenv("UNAME_r", ReleaseName, 1);
1978 
1979 	addbuildenv("DISTDIR", "/distfiles", BENV_MAKECONF);
1980 	addbuildenv("WRKDIRPREFIX", "/construction", BENV_MAKECONF);
1981 	addbuildenv("BATCH", "yes", BENV_MAKECONF);
1982 
1983 	/*
1984 	 * Special consideration
1985 	 *
1986 	 * PACKAGE_BUILDING	- Disallow packaging ports which do not allow
1987 	 *			  for binary distribution.
1988 	 *
1989 	 * PKG_CREATE_VERBOSE	- Ensure periodic output during the packaging
1990 	 *			  process to avoid a watchdog timeout.
1991 	 *
1992 	 */
1993 	addbuildenv("PACKAGE_BUILDING", "yes", BENV_MAKECONF);
1994 	addbuildenv("PKG_CREATE_VERBOSE", "yes", BENV_MAKECONF);
1995 	asprintf(&buf, "%d", MaxJobs);
1996 	addbuildenv("MAKE_JOBS_NUMBER", buf, BENV_MAKECONF);
1997 	freestrp(&buf);
1998 
1999 	if (flavor)
2000 		setenv("FLAVOR", flavor, 1);
2001 
2002 	/*
2003 	 * Become the reaper
2004 	 */
2005 	if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) < 0)
2006 		dfatal_errno("procctl() - Cannot become reaper");
2007 
2008 	/*
2009 	 * Initialize a worker structure
2010 	 */
2011 	DoInitBuild(slot);
2012 
2013 	bzero(&pkg, sizeof(pkg));
2014 	pkg.portdir = portdir;		/* sans flavor */
2015 	pkg.pkgfile = pkgfile;
2016 	if (strchr(portdir, '/'))
2017 		len = strchr(portdir, '/') - portdir;
2018 	else
2019 		len = 0;
2020 
2021 	/*
2022 	 * Setup the logfile
2023 	 */
2024 	asprintf(&pkg.logfile,
2025 		 "%s/%*.*s___%s%s%s.log",
2026 		 LogsPath, len, len, portdir,
2027 		 ((portdir[len] == '/') ? portdir + len + 1 : portdir + len),
2028 		 (flavor ? "@" : ""),
2029 		 (flavor ? flavor : ""));
2030 	tmpfd = open(pkg.logfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
2031 	if (tmpfd >= 0) {
2032 		if (DebugOpt >= 2) {
2033 			dlog(DLOG_ALL, "[%03d] %s LOGFILE %s\n",
2034 			     slot, pkg.portdir, pkg.logfile);
2035 		}
2036 		close(tmpfd);
2037 	} else {
2038 		dlog(DLOG_ALL, "[%03d] LOGFILE %s (create failed)\n",
2039 		     slot, pkg.logfile);
2040 	}
2041 
2042 	/*
2043 	 * Setup the work structure.  Because this is an exec'd sub-process,
2044 	 * there is only one work structure.
2045 	 */
2046 	work = &WorkerAry[0];
2047 	work->flavor = flavor;
2048 	work->fds[0] = fd;
2049 	work->pkg = &pkg;
2050 	work->start_time = time(NULL);
2051 
2052 	/*
2053 	 * Do mounts
2054 	 */
2055 	SigWork = work;
2056 	setproctitle("[%02d] WORKER MOUNTS   %s%s",
2057 		     slot, portdir, WorkerFlavorPrt);
2058 	DoWorkerMounts(work);
2059 
2060 	/*
2061 	 * Generate an /etc/make.conf in the build base
2062 	 */
2063 	asprintf(&buf, "%s/etc/make.conf", work->basedir);
2064 	fp = fopen(buf, "w");
2065 	dassert_errno(fp, "Unable to create %s\n", buf);
2066 	for (benv = BuildEnv; benv; benv = benv->next) {
2067 		if (benv->type & BENV_PKGLIST)
2068 			continue;
2069 		if ((benv->type & BENV_CMDMASK) == BENV_MAKECONF) {
2070 			if (DebugOpt >= 2) {
2071 				dlog(DLOG_ALL, "[%03d] ENV %s=%s\n",
2072 				     slot, benv->label, benv->data);
2073 			}
2074 			fprintf(fp, "%s=%s\n", benv->label, benv->data);
2075 		}
2076 	}
2077 	fclose(fp);
2078 	freestrp(&buf);
2079 
2080 	/*
2081 	 * Set up our hooks
2082 	 */
2083 	if (UsingHooks)
2084 		initbulk(childHookRun, MaxBulk);
2085 
2086 	/*
2087 	 * Start phases
2088 	 */
2089 	wmsg.cmd = WMSG_CMD_INSTALL_PKGS;
2090 	ipcwritemsg(fd, &wmsg);
2091 	status = ipcreadmsg(fd, &wmsg);
2092 	if (status < 0 || wmsg.cmd != WMSG_RES_INSTALL_PKGS)
2093 		dfatal("pkg installation handshake failed");
2094 	do_install_phase = wmsg.status;
2095 
2096 	wmsg.cmd = WMSG_CMD_STATUS_UPDATE;
2097 	wmsg.phase = PHASE_INSTALL_PKGS;
2098 	wmsg.lines = 0;
2099 
2100 	status = ipcwritemsg(fd, &wmsg);
2101 
2102 	if (pkgpkg) {
2103 		dophase(work, &wmsg,
2104 			WDOG5, PHASE_PACKAGE, "package");
2105 	} else {
2106 		if (do_install_phase) {
2107 			dophase(work, &wmsg,
2108 				WDOG4, PHASE_INSTALL_PKGS, "setup");
2109 		}
2110 		dophase(work, &wmsg,
2111 			WDOG2, PHASE_CHECK_SANITY, "check-sanity");
2112 		dophase(work, &wmsg,
2113 			WDOG2, PHASE_PKG_DEPENDS, "pkg-depends");
2114 		dophase(work, &wmsg,
2115 			WDOG7, PHASE_FETCH_DEPENDS, "fetch-depends");
2116 		dophase(work, &wmsg,
2117 			WDOG7, PHASE_FETCH, "fetch");
2118 		dophase(work, &wmsg,
2119 			WDOG2, PHASE_CHECKSUM, "checksum");
2120 		dophase(work, &wmsg,
2121 			WDOG3, PHASE_EXTRACT_DEPENDS, "extract-depends");
2122 		dophase(work, &wmsg,
2123 			WDOG3, PHASE_EXTRACT, "extract");
2124 		dophase(work, &wmsg,
2125 			WDOG2, PHASE_PATCH_DEPENDS, "patch-depends");
2126 		dophase(work, &wmsg,
2127 			WDOG2, PHASE_PATCH, "patch");
2128 		dophase(work, &wmsg,
2129 			WDOG5, PHASE_BUILD_DEPENDS, "build-depends");
2130 		dophase(work, &wmsg,
2131 			WDOG5, PHASE_LIB_DEPENDS, "lib-depends");
2132 		dophase(work, &wmsg,
2133 			WDOG3, PHASE_CONFIGURE, "configure");
2134 		dophase(work, &wmsg,
2135 			WDOG9, PHASE_BUILD, "build");
2136 		dophase(work, &wmsg,
2137 			WDOG5, PHASE_RUN_DEPENDS, "run-depends");
2138 		dophase(work, &wmsg,
2139 			WDOG5, PHASE_STAGE, "stage");
2140 #if 0
2141 		dophase(work, &wmsg,
2142 			WDOG5, PHASE_TEST, "test");
2143 #endif
2144 		if (WorkerProcFlags & WORKER_PROC_CHECK_PLIST) {
2145 			dophase(work, &wmsg,
2146 				WDOG1, PHASE_CHECK_PLIST, "check-plist");
2147 		}
2148 		dophase(work, &wmsg,
2149 			WDOG5, PHASE_PACKAGE, "package");
2150 #if 0
2151 		dophase(work, &wmsg,
2152 			WDOG5, PHASE_INSTALL_MTREE, "install-mtree");
2153 		dophase(work, &wmsg,
2154 			WDOG5, PHASE_INSTALL, "install");
2155 		dophase(work, &wmsg,
2156 			WDOG5, PHASE_DEINSTALL, "deinstall");
2157 #endif
2158 	}
2159 
2160 	if (MasterPtyFd >= 0) {
2161 		close(MasterPtyFd);
2162 		MasterPtyFd = -1;
2163 	}
2164 
2165 	setproctitle("[%02d] WORKER CLEANUP  %s%s",
2166 		     slot, portdir, WorkerFlavorPrt);
2167 
2168 	/*
2169 	 * Copy the package to the repo.
2170 	 */
2171 	if (work->accum_error == 0) {
2172 		char *b1;
2173 		char *b2;
2174 
2175 		asprintf(&b1, "%s/construction/%s/pkg/%s",
2176 			 work->basedir, pkg.portdir, pkg.pkgfile);
2177 		asprintf(&b2, "%s/%s", RepositoryPath, pkg.pkgfile);
2178 		if (copyfile(b1, b2)) {
2179 			++work->accum_error;
2180 			dlog(DLOG_ALL, "[%03d] %s Unable to copy %s to %s\n",
2181 			     work->index, pkg.portdir, b1, b2);
2182 		}
2183 		free(b1);
2184 		free(b2);
2185 	}
2186 
2187 	/*
2188 	 * Unmount, unless we are in DebugStopMode.
2189 	 */
2190 	if ((WorkerProcFlags & WORKER_PROC_DEBUGSTOP) == 0)
2191 		DoWorkerUnmounts(work);
2192 
2193 	/*
2194 	 * Send completion status to master dsynth worker thread.
2195 	 */
2196 	if (work->accum_error) {
2197 		wmsg.cmd = WMSG_CMD_FAILURE;
2198 	} else {
2199 		wmsg.cmd = WMSG_CMD_SUCCESS;
2200 	}
2201 	ipcwritemsg(fd, &wmsg);
2202 	if (WorkerProcFlags & WORKER_PROC_DEBUGSTOP) {
2203 		wmsg.cmd = WMSG_CMD_FREEZEWORKER;
2204 		ipcwritemsg(fd, &wmsg);
2205 	}
2206 	if (UsingHooks) {
2207 		while ((bulk = getbulk()) != NULL)
2208 			freebulk(bulk);
2209 		donebulk();
2210 	}
2211 }
2212 
2213 static void
2214 dophase(worker_t *work, wmsg_t *wmsg, int wdog, int phaseid, const char *phase)
2215 {
2216 	pkg_t *pkg = work->pkg;
2217 	char buf[1024];
2218 	pid_t pid;
2219 	int status;
2220 	int ms;
2221 	pid_t wpid;
2222 	int wpid_reaped;
2223 	int fdlog;
2224 	time_t start_time;
2225 	time_t last_time;
2226 	time_t next_time;
2227 	time_t wdog_time;
2228 	FILE *fp;
2229 
2230 	if (work->accum_error)
2231 		return;
2232 	setproctitle("[%02d] WORKER %-8.8s %s%s",
2233 		     work->index, phase, pkg->portdir, WorkerFlavorPrt);
2234 	wmsg->phase = phaseid;
2235 	if (ipcwritemsg(work->fds[0], wmsg) < 0) {
2236 		dlog(DLOG_ALL, "[%03d] %s Lost Communication with dsynth, "
2237 		     "aborting worker\n",
2238 		     work->index, pkg->portdir);
2239 		++work->accum_error;
2240 		return;
2241 	}
2242 
2243 	/*
2244 	 * Execute the port make command in chroot on a pty.
2245 	 */
2246 	fflush(stdout);
2247 	fflush(stderr);
2248 	if (MasterPtyFd >= 0) {
2249 		int slavefd;
2250 
2251 		/*
2252 		 * NOTE: We can't open the slave in the child because the
2253 		 *	 master may race a disconnection test.  If we open
2254 		 *	 it in the parent our close() will flush any pending
2255 		 *	 output not read by the master (which is the same
2256 		 *	 parent process) and deadlock.
2257 		 *
2258 		 *	 Solve this by hand-shaking the slave tty to give
2259 		 *	 the master time to close its slavefd (after this
2260 		 *	 section).
2261 		 *
2262 		 *	 Leave the tty defaults intact, which also likely
2263 		 *	 means it will be in line-buffered mode, so handshake
2264 		 *	 with a full line.
2265 		 *
2266 		 * TODO: Our handshake probably echos back to the master pty
2267 		 *	 due to tty echo, and ends up in the log, so just
2268 		 *	 pass through a newline.
2269 		 */
2270 		slavefd = open(ptsname(MasterPtyFd), O_RDWR);
2271 		dassert_errno(slavefd >= 0, "Cannot open slave pty");
2272 
2273 		/*
2274 		 * Now do the fork.
2275 		 */
2276 		pid = fork();
2277 		if (pid == 0) {
2278 			login_tty(slavefd);
2279 			/* login_tty() closes slavefd */
2280 		} else {
2281 			close(slavefd);
2282 		}
2283 	} else {
2284 		/*
2285 		 * Initial MasterPtyFd for the slot, just use forkpty().
2286 		 */
2287 		pid = forkpty(&MasterPtyFd, NULL, NULL, NULL);
2288 	}
2289 
2290 	/*
2291 	 * The slave must make sure the master has time to close slavefd
2292 	 * in the re-use case before going its merry way.  The master needs
2293 	 * to set terminal modes and the window as well.
2294 	 */
2295 	if (pid == 0) {
2296 		/*
2297 		 * Slave nices itself and waits for handshake
2298 		 */
2299 		char ttybuf[2];
2300 
2301 		/*
2302 		 * Self-nice to be nice (ignore any error)
2303 		 */
2304 		if (NiceOpt)
2305 			setpriority(PRIO_PROCESS, 0, NiceOpt);
2306 
2307 		read(0, ttybuf, 1);
2308 	} else {
2309 		/*
2310 		 * We are going through a pty, so set the tty modes to
2311 		 * Set tty modes so we do not get ^M's in the log files.
2312 		 *
2313 		 * This isn't fatal if it doesn't work.  Remember that
2314 		 * our output goes through the pty to the management
2315 		 * process which will log it.
2316 		 */
2317 		struct termios tio;
2318 		struct winsize win;
2319 
2320 		if (tcgetattr(MasterPtyFd, &tio) == 0) {
2321 			tio.c_oflag |= OPOST | ONOCR;
2322 			tio.c_oflag &= ~(OCRNL | ONLCR);
2323 			tio.c_iflag |= ICRNL;
2324 			tio.c_iflag &= ~(INLCR | IGNCR);
2325 			if (tcsetattr(MasterPtyFd, TCSANOW, &tio)) {
2326 				printf("tcsetattr failed: %s\n",
2327 				       strerror(errno));
2328 			}
2329 
2330 			/*
2331 			 * Give the tty a non-zero columns field.
2332 			 * This fixes at least one port (textproc/po4a)
2333 			 */
2334 			if (ioctl(MasterPtyFd, TIOCGWINSZ, &win) == 0) {
2335 				win.ws_col = 80;
2336 				ioctl(MasterPtyFd, TIOCSWINSZ, &win);
2337 			} else {
2338 				printf("TIOCGWINSZ failed: %s\n",
2339 				       strerror(errno));
2340 			}
2341 
2342 		} else {
2343 			printf("tcgetattr failed: %s\n", strerror(errno));
2344 		}
2345 
2346 		/*
2347 		 * Master issues handshake
2348 		 */
2349 		write(MasterPtyFd, "\n", 1);
2350 	}
2351 
2352 	if (pid == 0) {
2353 		/*
2354 		 * Additional phase-specific environment variables
2355 		 *
2356 		 * - Do not try to process missing depends outside of the
2357 		 *   depends phases.  Also relies on USE_PACKAGE_DEPENDS_ONLY
2358 		 *   in the make.conf.
2359 		 */
2360 		switch(phaseid) {
2361 		case PHASE_CHECK_SANITY:
2362 		case PHASE_FETCH:
2363 		case PHASE_CHECKSUM:
2364 		case PHASE_EXTRACT:
2365 		case PHASE_PATCH:
2366 		case PHASE_CONFIGURE:
2367 		case PHASE_STAGE:
2368 		case PHASE_TEST:
2369 		case PHASE_CHECK_PLIST:
2370 		case PHASE_INSTALL_MTREE:
2371 		case PHASE_INSTALL:
2372 		case PHASE_DEINSTALL:
2373 			break;
2374 		case PHASE_PKG_DEPENDS:
2375 		case PHASE_FETCH_DEPENDS:
2376 		case PHASE_EXTRACT_DEPENDS:
2377 		case PHASE_PATCH_DEPENDS:
2378 		case PHASE_BUILD_DEPENDS:
2379 		case PHASE_LIB_DEPENDS:
2380 		case PHASE_RUN_DEPENDS:
2381 			break;
2382 		default:
2383 			setenv("NO_DEPENDS", "1", 1);
2384 			break;
2385 		}
2386 
2387 		/*
2388 		 * Clean-up, chdir, and chroot.
2389 		 */
2390 		closefrom(3);
2391 		if (chdir(work->basedir) < 0)
2392 			dfatal_errno("chdir in phase initialization");
2393 		if (chroot(work->basedir) < 0)
2394 			dfatal_errno("chroot in phase initialization");
2395 
2396 		/*
2397 		 * We have a choice here on how to handle stdin (fd 0).
2398 		 * We can leave it connected to the pty in which case
2399 		 * the build will just block if it tries to ask a
2400 		 * question (and the watchdog will kill it, eventually),
2401 		 * or we can try to EOF the pty, or we can attach /dev/null
2402 		 * to descriptor 0.
2403 		 */
2404 		if (NullStdinOpt) {
2405 			int fd;
2406 
2407 			fd = open("/dev/null", O_RDWR);
2408 			dassert_errno(fd >= 0, "cannot open /dev/null");
2409 			if (fd != 0) {
2410 				dup2(fd, 0);
2411 				close(fd);
2412 			}
2413 		}
2414 
2415 		/*
2416 		 * Execute the appropriate command.
2417 		 */
2418 		switch(phaseid) {
2419 		case PHASE_INSTALL_PKGS:
2420 			snprintf(buf, sizeof(buf), "/tmp/dsynth_install_pkgs");
2421 			execl(buf, buf, NULL);
2422 			break;
2423 		default:
2424 			snprintf(buf, sizeof(buf), "/xports/%s", pkg->portdir);
2425 			execl(MAKE_BINARY, MAKE_BINARY, "-C", buf, phase, NULL);
2426 			break;
2427 		}
2428 		_exit(1);
2429 	}
2430 	fcntl(MasterPtyFd, F_SETFL, O_NONBLOCK);
2431 
2432 	if (pid < 0) {
2433 		dlog(DLOG_ALL, "[%03d] %s Fork Failed: %s\n",
2434 		     work->index, pkg->logfile, strerror(errno));
2435 		++work->accum_error;
2436 		return;
2437 	}
2438 
2439 	SigPid = pid;
2440 
2441 	fdlog = open(pkg->logfile, O_RDWR|O_CREAT|O_APPEND, 0644);
2442 	if (fdlog < 0) {
2443 		dlog(DLOG_ALL, "[%03d] %s Cannot open logfile '%s': %s\n",
2444 		     work->index, pkg->portdir,
2445 		     pkg->logfile, strerror(errno));
2446 	}
2447 
2448 	snprintf(buf, sizeof(buf),
2449 		 "----------------------------------------"
2450 		 "---------------------------------------\n"
2451 		 "-- Phase: %s\n"
2452 		 "----------------------------------------"
2453 		 "---------------------------------------\n",
2454 		 phase);
2455 	write(fdlog, buf, strlen(buf));
2456 
2457 	start_time = time(NULL);
2458 	last_time = start_time;
2459 	wdog_time = start_time;
2460 	wpid_reaped = 0;
2461 
2462 	status = 0;
2463 	for (;;) {
2464 		ms = mptylogpoll(MasterPtyFd, fdlog, wmsg, &wdog_time);
2465 		if (ms == MPTY_FAILED) {
2466 			dlog(DLOG_ALL,
2467 			     "[%03d] %s lost pty in phase %s, terminating\n",
2468 			     work->index, pkg->portdir, phase);
2469 			break;
2470 		}
2471 		if (ms == MPTY_EOF)
2472 			break;
2473 
2474 		/*
2475 		 * Generally speaking update status once a second.
2476 		 * This also allows us to detect if the management
2477 		 * dsynth process has gone away.
2478 		 */
2479 		next_time = time(NULL);
2480 		if (next_time != last_time) {
2481 			double dload[3];
2482 			double dv;
2483 			int wdog_scaled;
2484 
2485 			/*
2486 			 * Send status update to the worker management thread
2487 			 * in the master dsynth process.  Remember, *WE* are
2488 			 * the worker management process sub-fork.
2489 			 */
2490 			if (ipcwritemsg(work->fds[0], wmsg) < 0)
2491 				break;
2492 			last_time = next_time;
2493 
2494 			/*
2495 			 * Watchdog scaling
2496 			 */
2497 			getloadavg(dload, 3);
2498 			adjloadavg(dload);
2499 			dv = dload[2] / NumCores;
2500 			if (dv < (double)NumCores) {
2501 				wdog_scaled = wdog;
2502 			} else {
2503 				if (dv > 4.0 * NumCores)
2504 					dv = 4.0 * NumCores;
2505 				wdog_scaled = wdog * dv / NumCores;
2506 			}
2507 
2508 			/*
2509 			 * Watchdog
2510 			 */
2511 			if (next_time - wdog_time >= wdog_scaled * 60) {
2512 				snprintf(buf, sizeof(buf),
2513 					 "\n--------\n"
2514 					 "WATCHDOG TIMEOUT FOR %s in %s "
2515 					 "after %d minutes\n"
2516 					 "Killing pid %d\n"
2517 					 "--------\n",
2518 					 pkg->portdir, phase, wdog_scaled, pid);
2519 				if (fdlog >= 0)
2520 					write(fdlog, buf, strlen(buf));
2521 				dlog(DLOG_ALL,
2522 				     "[%03d] %s WATCHDOG TIMEOUT in %s "
2523 				     "after %d minutes (%d min scaled)\n",
2524 				     work->index, pkg->portdir, phase,
2525 				     wdog, wdog_scaled);
2526 				kill(pid, SIGKILL);
2527 				++work->accum_error;
2528 				break;
2529 			}
2530 		}
2531 
2532 		/*
2533 		 * Check process exit.  Normally the pty will EOF
2534 		 * but if background processes remain we need to
2535 		 * check here to see if our primary exec is done,
2536 		 * so we can break out and reap those processes.
2537 		 *
2538 		 * Generally reap any other processes we have inherited
2539 		 * while we are here.
2540 		 */
2541 		do {
2542 			wpid = wait3(&status, WNOHANG, NULL);
2543 		} while (wpid > 0 && wpid != pid);
2544 		if (wpid == pid && WIFEXITED(status)) {
2545 			wpid_reaped = 1;
2546 			break;
2547 		}
2548 	}
2549 
2550 	next_time = time(NULL);
2551 
2552 	setproctitle("[%02d] WORKER EXITREAP %s%s",
2553 		     work->index, pkg->portdir, WorkerFlavorPrt);
2554 
2555 	/*
2556 	 * We usually get here due to a mpty EOF, but not always as there
2557 	 * could be persistent processes still holding the slave.  Finish
2558 	 * up getting the exit status for the main process we are waiting
2559 	 * on and clean out any data left on the MasterPtyFd (as it could
2560 	 * be blocking the exit).
2561 	 */
2562 	while (wpid_reaped == 0) {
2563 		(void)mptylogpoll(MasterPtyFd, fdlog, wmsg, &wdog_time);
2564 		wpid = waitpid(pid, &status, WNOHANG);
2565 		if (wpid == pid && WIFEXITED(status)) {
2566 			wpid_reaped = 1;
2567 			break;
2568 		}
2569 		if (wpid < 0 && errno != EINTR) {
2570 			break;
2571 		}
2572 
2573 		/*
2574 		 * Safety.  The normal phase waits until the fork/exec'd
2575 		 * pid finishes, causing a pty EOF on exit (the slave
2576 		 * descriptor is closed by the kernel on exit so the
2577 		 * process should already have exited).
2578 		 *
2579 		 * However, it is also possible to get here if the pty fails
2580 		 * for some reason.  In this case, make sure that the process
2581 		 * is killed.
2582 		 */
2583 		kill(pid, SIGKILL);
2584 	}
2585 
2586 	/*
2587 	 * Clean out anything left on the pty but don't wait around
2588 	 * because there could be background processes preventing the
2589 	 * slave side from closing.
2590 	 */
2591 	while (mptylogpoll(MasterPtyFd, fdlog, wmsg, &wdog_time) == MPTY_DATA)
2592 		;
2593 
2594 	/*
2595 	 * Report on the exit condition.  If the pid was somehow lost
2596 	 * (probably due to someone gdb'ing the process), assume an error.
2597 	 */
2598 	if (wpid_reaped) {
2599 		if (WEXITSTATUS(status)) {
2600 			dlog(DLOG_ALL | DLOG_FILTER,
2601 			     "[%03d] %s Build phase '%s' failed exit %d\n",
2602 			     work->index, pkg->portdir, phase,
2603 			     WEXITSTATUS(status));
2604 			++work->accum_error;
2605 		}
2606 	} else {
2607 		dlog(DLOG_ALL, "[%03d] %s Build phase '%s' failed - lost pid\n",
2608 		     work->index, pkg->portdir, phase);
2609 		++work->accum_error;
2610 	}
2611 
2612 	/*
2613 	 * Kill any processes still running (sometimes processes end up in
2614 	 * the background during a dports build), and clean up any other
2615 	 * children that we have inherited.
2616 	 */
2617 	phaseReapAll();
2618 
2619 	/*
2620 	 * After the extraction phase add the space used by /construction
2621 	 * to the memory use.  This helps us reduce the amount of paging
2622 	 * we do due to extremely large package extractions (languages,
2623 	 * chromium, etc).
2624 	 *
2625 	 * (dsynth already estimated the space used by the package deps
2626 	 * up front, but this will help us further).
2627 	 */
2628 	if (work->accum_error == 0 && phaseid == PHASE_EXTRACT) {
2629 		struct statfs sfs;
2630 		char *b1;
2631 
2632 		asprintf(&b1, "%s/construction", work->basedir);
2633 		if (statfs(b1, &sfs) == 0) {
2634 			wmsg->memuse = (sfs.f_blocks - sfs.f_bfree) *
2635 				       sfs.f_bsize;
2636 			ipcwritemsg(work->fds[0], wmsg);
2637 		}
2638 	}
2639 
2640 	/*
2641 	 * Update log
2642 	 */
2643 	if (fdlog >= 0) {
2644 		struct stat st;
2645 		int h;
2646 		int m;
2647 		int s;
2648 
2649 		last_time = next_time - start_time;
2650 		s = last_time % 60;
2651 		m = last_time / 60 % 60;
2652 		h = last_time / 3600;
2653 
2654 		fp = fdopen(fdlog, "a");
2655 		if (fp == NULL) {
2656 			dlog(DLOG_ALL, "[%03d] %s Cannot fdopen fdlog: %s %d\n",
2657 			     work->index, pkg->portdir,
2658 			     strerror(errno), fstat(fdlog, &st));
2659 			close(fdlog);
2660 			goto skip;
2661 		}
2662 
2663 		fprintf(fp, "\n");
2664 		if (work->accum_error) {
2665 			fprintf(fp, "FAILED %02d:%02d:%02d\n", h, m, s);
2666 		} else {
2667 			if (phaseid == PHASE_EXTRACT && wmsg->memuse) {
2668 				fprintf(fp, "Extracted Memory Use: %6.2fM\n",
2669 					wmsg->memuse / (1024.0 * 1024.0));
2670 			}
2671 			fprintf(fp, "SUCCEEDED %02d:%02d:%02d\n", h, m, s);
2672 		}
2673 		last_time = next_time - work->start_time;
2674 		s = last_time % 60;
2675 		m = last_time / 60 % 60;
2676 		h = last_time / 3600;
2677 		if (phaseid == PHASE_PACKAGE) {
2678 			fprintf(fp, "TOTAL TIME %02d:%02d:%02d\n", h, m, s);
2679 		}
2680 		fprintf(fp, "\n");
2681 		fclose(fp);
2682 skip:
2683 		;
2684 	}
2685 
2686 }
2687 
2688 static void
2689 phaseReapAll(void)
2690 {
2691 	struct reaper_status rs;
2692 	int status;
2693 
2694 	while (procctl(P_PID, getpid(), PROC_REAP_STATUS, &rs) == 0) {
2695 		if ((rs.flags & PROC_REAP_ACQUIRE) == 0)
2696 			break;
2697 		if (rs.pid_head < 0)
2698 			break;
2699 		if (kill(rs.pid_head, SIGKILL) == 0) {
2700 			while (waitpid(rs.pid_head, &status, 0) < 0)
2701 				;
2702 		}
2703 	}
2704 	while (wait3(&status, 0, NULL) > 0)
2705 		;
2706 }
2707 
2708 static void
2709 phaseTerminateSignal(int sig __unused)
2710 {
2711 	if (CopyFileFd >= 0)
2712 		close(CopyFileFd);
2713 	if (MasterPtyFd >= 0)
2714 		close(MasterPtyFd);
2715 	if (SigPid > 1)
2716 		kill(SigPid, SIGKILL);
2717 	phaseReapAll();
2718 	if (SigWork)
2719 		DoWorkerUnmounts(SigWork);
2720 	exit(1);
2721 }
2722 
2723 static
2724 char *
2725 buildskipreason(pkglink_t *parent, pkg_t *pkg)
2726 {
2727 	pkglink_t *link;
2728 	pkg_t *scan;
2729 	char *reason = NULL;
2730 	char *ptr;
2731 	size_t tot;
2732 	size_t len;
2733 	pkglink_t stack;
2734 
2735 	if ((pkg->flags & PKGF_NOBUILD_I) && pkg->ignore)
2736 		asprintf(&reason, "%s ", pkg->ignore);
2737 
2738 	tot = 0;
2739 	PKGLIST_FOREACH(link, &pkg->idepon_list) {
2740 #if 0
2741 		if (link->dep_type > DEP_TYPE_BUILD)
2742 			continue;
2743 #endif
2744 		scan = link->pkg;
2745 		if (scan == NULL)
2746 			continue;
2747 		if ((scan->flags & (PKGF_ERROR | PKGF_NOBUILD)) == 0)
2748 			continue;
2749 		if (scan->flags & PKGF_NOBUILD) {
2750 			stack.pkg = scan;
2751 			stack.next = parent;
2752 			ptr = buildskipreason(&stack, scan);
2753 			len = strlen(scan->portdir) + strlen(ptr) + 8;
2754 			reason = realloc(reason, tot + len);
2755 			snprintf(reason + tot, len, "%s->%s",
2756 				 scan->portdir, ptr);
2757 			free(ptr);
2758 		} else {
2759 			len = strlen(scan->portdir) + 8;
2760 			reason = realloc(reason, tot + len);
2761 			snprintf(reason + tot, len, "%s", scan->portdir);
2762 		}
2763 
2764 		/*
2765 		 * Don't try to print the entire graph
2766 		 */
2767 		if (parent)
2768 			break;
2769 		tot += strlen(reason + tot);
2770 		reason[tot++] = ' ';
2771 		reason[tot] = 0;
2772 	}
2773 	return (reason);
2774 }
2775 
2776 /*
2777  * Count number of packages that would be skipped due to the
2778  * specified package having failed.
2779  *
2780  * Call with mode 1 to count, and mode 0 to clear the
2781  * cumulative rscan flag (used to de-duplicate the count).
2782  *
2783  * Must be serialized.
2784  */
2785 static int
2786 buildskipcount_dueto(pkg_t *pkg, int mode)
2787 {
2788 	pkglink_t *link;
2789 	pkg_t *scan;
2790 	int total;
2791 
2792 	total = 0;
2793 	PKGLIST_FOREACH(link, &pkg->deponi_list) {
2794 		scan = link->pkg;
2795 		if (scan == NULL || scan->rscan == mode)
2796 			continue;
2797 		scan->rscan = mode;
2798 		++total;
2799 		total += buildskipcount_dueto(scan, mode);
2800 	}
2801 	return total;
2802 }
2803 
2804 /*
2805  * The master ptyfd is in non-blocking mode.  Drain up to 1024 bytes
2806  * and update wmsg->lines and *wdog_timep as appropriate.
2807  *
2808  * This function will poll, stalling up to 1 second.
2809  */
2810 static int
2811 mptylogpoll(int ptyfd, int fdlog, wmsg_t *wmsg, time_t *wdog_timep)
2812 {
2813 	struct pollfd pfd;
2814 	char buf[1024];
2815 	ssize_t r;
2816 
2817 	pfd.fd = ptyfd;
2818 	pfd.events = POLLIN;
2819 	pfd.revents = 0;
2820 
2821 	poll(&pfd, 1, 1000);
2822 	if (pfd.revents) {
2823 		r = read(ptyfd, buf, sizeof(buf));
2824 		if (r > 0) {
2825 			*wdog_timep = time(NULL);
2826 			if (r > 0 && fdlog >= 0)
2827 				write(fdlog, buf, r);
2828 			while (--r >= 0) {
2829 				if (buf[r] == '\n')
2830 					++wmsg->lines;
2831 			}
2832 			return MPTY_DATA;
2833 		} else if (r < 0) {
2834 			if (errno != EINTR && errno != EAGAIN)
2835 				return MPTY_FAILED;
2836 			return MPTY_AGAIN;
2837 		} else if (r == 0) {
2838 			return MPTY_EOF;
2839 		}
2840 	}
2841 	return MPTY_AGAIN;
2842 }
2843 
2844 /*
2845  * Copy a (package) file from (src) to (dst), use an intermediate file and
2846  * rename to ensure that interruption does not leave us with a corrupt
2847  * package file.
2848  *
2849  * This is called by the WORKER process.
2850  *
2851  * (dsynth management thread -> WORKER process -> sub-processes)
2852  */
2853 #define COPYBLKSIZE	32768
2854 
2855 int
2856 copyfile(char *src, char *dst)
2857 {
2858 	char *tmp;
2859 	char *buf;
2860 	int fd1;
2861 	int fd2;
2862 	int error = 0;
2863 	int mask;
2864 	ssize_t r;
2865 
2866 	asprintf(&tmp, "%s.new", dst);
2867 	buf = malloc(COPYBLKSIZE);
2868 
2869 	mask = sigsetmask(sigmask(SIGTERM)|sigmask(SIGINT)|sigmask(SIGHUP));
2870 	fd1 = open(src, O_RDONLY|O_CLOEXEC);
2871 	fd2 = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
2872 	CopyFileFd = fd1;
2873 	sigsetmask(mask);
2874 	while ((r = read(fd1, buf, COPYBLKSIZE)) > 0) {
2875 		if (write(fd2, buf, r) != r)
2876 			error = 1;
2877 	}
2878 	if (r < 0)
2879 		error = 1;
2880 	mask = sigsetmask(sigmask(SIGTERM)|sigmask(SIGINT)|sigmask(SIGHUP));
2881 	CopyFileFd = -1;
2882 	close(fd1);
2883 	close(fd2);
2884 	sigsetmask(mask);
2885 	if (error) {
2886 		remove(tmp);
2887 	} else {
2888 		if (rename(tmp, dst)) {
2889 			error = 1;
2890 			remove(tmp);
2891 		}
2892 	}
2893 
2894 	freestrp(&buf);
2895 	freestrp(&tmp);
2896 
2897 	return error;
2898 }
2899 
2900 /*
2901  * doHook()
2902  *
2903  * primary process (threaded) - run_start, run_end, pkg_ignored, pkg_skipped
2904  * worker process  (threaded) - pkg_sucess, pkg_failure
2905  *
2906  * If waitfor is non-zero this hook will be serialized.
2907  */
2908 static void
2909 doHook(pkg_t *pkg, const char *id, const char *path, int waitfor)
2910 {
2911 	if (path == NULL)
2912 		return;
2913 	while (waitfor && getbulk() != NULL)
2914 		;
2915 	if (pkg)
2916 		queuebulk(pkg->portdir, id, path, pkg->pkgfile);
2917 	else
2918 		queuebulk(NULL, id, path, NULL);
2919 	while (waitfor && getbulk() != NULL)
2920 		;
2921 }
2922 
2923 /*
2924  * Execute hook (backend)
2925  *
2926  * s1 - portdir
2927  * s2 - id
2928  * s3 - script path
2929  * s4 - pkgfile		(if applicable)
2930  */
2931 static void
2932 childHookRun(bulk_t *bulk)
2933 {
2934 	const char *cav[MAXCAC];
2935 	buildenv_t benv[MAXCAC];
2936 	char buf1[128];
2937 	char buf2[128];
2938 	char buf3[128];
2939 	char buf4[128];
2940 	FILE *fp;
2941 	char *ptr;
2942 	size_t len;
2943 	pid_t pid;
2944 	int cac;
2945 	int bi;
2946 
2947 	cac = 0;
2948 	bi = 0;
2949 	bzero(benv, sizeof(benv));
2950 
2951 	cav[cac++] = bulk->s3;
2952 
2953 	benv[bi].label = "PROFILE";
2954 	benv[bi].data = Profile;
2955 	++bi;
2956 
2957 	benv[bi].label = "DIR_PACKAGES";
2958 	benv[bi].data = PackagesPath;
2959 	++bi;
2960 
2961 	benv[bi].label = "DIR_REPOSITORY";
2962 	benv[bi].data = RepositoryPath;
2963 	++bi;
2964 
2965 	benv[bi].label = "DIR_PORTS";
2966 	benv[bi].data = DPortsPath;
2967 	++bi;
2968 
2969 	benv[bi].label = "DIR_OPTIONS";
2970 	benv[bi].data = OptionsPath;
2971 	++bi;
2972 
2973 	benv[bi].label = "DIR_DISTFILES";
2974 	benv[bi].data = DistFilesPath;
2975 	++bi;
2976 
2977 	benv[bi].label = "DIR_LOGS";
2978 	benv[bi].data = LogsPath;
2979 	++bi;
2980 
2981 	benv[bi].label = "DIR_BUILDBASE";
2982 	benv[bi].data = BuildBase;
2983 	++bi;
2984 
2985 	if (strcmp(bulk->s2, "hook_run_start") == 0) {
2986 		snprintf(buf1, sizeof(buf1), "%d", BuildTotal);
2987 		benv[bi].label = "PORTS_QUEUED";
2988 		benv[bi].data = buf1;
2989 		++bi;
2990 	} else if (strcmp(bulk->s2, "hook_run_end") == 0) {
2991 		snprintf(buf1, sizeof(buf1), "%d", BuildSuccessCount);
2992 		benv[bi].label = "PORTS_BUILT";
2993 		benv[bi].data = buf1;
2994 		++bi;
2995 		snprintf(buf2, sizeof(buf2), "%d", BuildFailCount);
2996 		benv[bi].label = "PORTS_FAILED";
2997 		benv[bi].data = buf2;
2998 		++bi;
2999 		snprintf(buf3, sizeof(buf3), "%d", BuildIgnoreCount);
3000 		benv[bi].label = "PORTS_IGNORED";
3001 		benv[bi].data = buf3;
3002 		++bi;
3003 		snprintf(buf4, sizeof(buf4), "%d", BuildSkipCount);
3004 		benv[bi].label = "PORTS_SKIPPED";
3005 		benv[bi].data = buf4;
3006 		++bi;
3007 	} else {
3008 		/*
3009 		 * success, failure, ignored, skipped
3010 		 */
3011 		benv[bi].label = "RESULT";
3012 		if (strcmp(bulk->s2, "hook_pkg_success") == 0) {
3013 			benv[bi].data = "success";
3014 		} else if (strcmp(bulk->s2, "hook_pkg_failure") == 0) {
3015 			benv[bi].data = "failure";
3016 		} else if (strcmp(bulk->s2, "hook_pkg_ignored") == 0) {
3017 			benv[bi].data = "ignored";
3018 		} else if (strcmp(bulk->s2, "hook_pkg_skipped") == 0) {
3019 			benv[bi].data = "skipped";
3020 		} else {
3021 			dfatal("Unknown hook id: %s", bulk->s2);
3022 			/* NOT REACHED */
3023 		}
3024 		++bi;
3025 
3026 		/*
3027 		 * For compatibility with synth:
3028 		 *
3029 		 * ORIGIN does not include any @flavor, thus it is suitable
3030 		 * for finding the actual port directory/subdirectory.
3031 		 *
3032 		 * FLAVOR is set to ORIGIN if there is no flavor, otherwise
3033 		 * it is set to only the flavor sans the '@'.
3034 		 */
3035 		if ((ptr = strchr(bulk->s1, '@')) != NULL) {
3036 			snprintf(buf1, sizeof(buf1), "%*.*s",
3037 				 (int)(ptr - bulk->s1),
3038 				 (int)(ptr - bulk->s1),
3039 				 bulk->s1);
3040 			benv[bi].label = "ORIGIN";
3041 			benv[bi].data = buf1;
3042 			++bi;
3043 			benv[bi].label = "FLAVOR";
3044 			benv[bi].data = ptr + 1;
3045 			++bi;
3046 		} else {
3047 			benv[bi].label = "ORIGIN";
3048 			benv[bi].data = bulk->s1;
3049 			++bi;
3050 			benv[bi].label = "FLAVOR";
3051 			benv[bi].data = bulk->s1;
3052 			++bi;
3053 		}
3054 		benv[bi].label = "PKGNAME";
3055 		benv[bi].data = bulk->s4;
3056 		++bi;
3057 	}
3058 
3059 	benv[bi].label = NULL;
3060 	benv[bi].data = NULL;
3061 
3062 	fp = dexec_open(bulk->s1, cav, cac, &pid, benv, 0, 0);
3063 	while ((ptr = fgetln(fp, &len)) != NULL)
3064 		;
3065 
3066 	if (dexec_close(fp, pid)) {
3067 		dlog(DLOG_ALL,
3068 		     "[XXX] %s SCRIPT %s (%s)\n",
3069 		     bulk->s1, bulk->s2, bulk->s3);
3070 	}
3071 }
3072 
3073 /*
3074  * Adjusts dload[0] by adding in t_pw (processes waiting on page-fault).
3075  * We don't want load reductions due to e.g. thrashing to cause dsynth
3076  * to increase the dynamic limit because it thinks the load is low.
3077  *
3078  * This has a desirable property.  If the system pager cannot keep up
3079  * with process demand t_pw will spike while loadavg will only drop
3080  * slowly, resulting in a high adjusted load calculation that causes
3081  * dsynth to quickly clamp-down the limit.  If the condition alleviates,
3082  * the limit will then rise slowly again, possibly even before existing
3083  * jobs are retired to meet the clamp-down from the original spike.
3084  */
3085 static void
3086 adjloadavg(double *dload)
3087 {
3088 #if defined(__DragonFly__)
3089 	struct vmtotal total;
3090 	size_t size;
3091 
3092 	size = sizeof(total);
3093 	if (sysctlbyname("vm.vmtotal", &total, &size, NULL, 0) == 0) {
3094 		dload[0] += (double)total.t_pw;
3095 	}
3096 #else
3097 	dload[0] += 0.0;	/* just avoid compiler 'unused' warnings */
3098 #endif
3099 }
3100 
3101 /*
3102  * Check if the ports directory contents has changed and force a
3103  * package to be rebuilt if it has by clearing the PACKAGED bit.
3104  */
3105 static
3106 void
3107 check_packaged(const char *dbmpath, pkg_t *pkgs)
3108 {
3109 	pkg_t *scan;
3110 	datum key;
3111 	datum data;
3112 	char *buf;
3113 
3114 	if (CheckDBM == NULL) {
3115 		dlog(DLOG_ABN, "[XXX] Unable to open/create dbm %s\n", dbmpath);
3116 		return;
3117 	}
3118 	for (scan = pkgs; scan; scan = scan->bnext) {
3119 		if ((scan->flags & PKGF_PACKAGED) == 0)
3120 			continue;
3121 		key.dptr = scan->portdir;
3122 		key.dsize = strlen(scan->portdir);
3123 		data = dbm_fetch(CheckDBM, key);
3124 		if (data.dptr && data.dsize == sizeof(uint32_t) &&
3125 		    *(uint32_t *)data.dptr != scan->crc32) {
3126 			scan->flags &= ~PKGF_PACKAGED;
3127 			asprintf(&buf, "%s/%s", RepositoryPath, scan->pkgfile);
3128 			if (OverridePkgDeleteOpt >= 2) {
3129 				scan->flags |= PKGF_PACKAGED;
3130 				dlog(DLOG_ALL,
3131 				     "[XXX] %s DELETE-PACKAGE %s "
3132 				     "(port content changed CRC %08x/%08x "
3133 				     "OVERRIDE, NOT DELETED)\n",
3134 				     scan->portdir, buf,
3135 				     *(uint32_t *)data.dptr, scan->crc32);
3136 			} else if (remove(buf) < 0) {
3137 				dlog(DLOG_ALL,
3138 				     "[XXX] %s DELETE-PACKAGE %s (failed)\n",
3139 				     scan->portdir, buf);
3140 			} else {
3141 				dlog(DLOG_ALL,
3142 				     "[XXX] %s DELETE-PACKAGE %s "
3143 				     "(port content changed CRC %08x/%08x)\n",
3144 				     scan->portdir, buf,
3145 				     *(uint32_t *)data.dptr, scan->crc32);
3146 			}
3147 			freestrp(&buf);
3148 		} else if (data.dptr == NULL) {
3149 			data.dptr = &scan->crc32;
3150 			data.dsize = sizeof(scan->crc32);
3151 			dbm_store(CheckDBM, key, data, DBM_REPLACE);
3152 		}
3153 	}
3154 }
3155