xref: /aosp_15_r20/external/igt-gpu-tools/runner/executor.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
2*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
3*d83cc019SAndroid Build Coastguard Worker #include <linux/watchdog.h>
4*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
5*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
6*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
7*d83cc019SAndroid Build Coastguard Worker #include <string.h>
8*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
9*d83cc019SAndroid Build Coastguard Worker #include <sys/select.h>
10*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
11*d83cc019SAndroid Build Coastguard Worker #include <sys/signalfd.h>
12*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
13*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
14*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
15*d83cc019SAndroid Build Coastguard Worker #include <sys/utsname.h>
16*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
17*d83cc019SAndroid Build Coastguard Worker #include <time.h>
18*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
19*d83cc019SAndroid Build Coastguard Worker 
20*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
21*d83cc019SAndroid Build Coastguard Worker #include "executor.h"
22*d83cc019SAndroid Build Coastguard Worker #include "output_strings.h"
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker static struct {
25*d83cc019SAndroid Build Coastguard Worker 	int *fds;
26*d83cc019SAndroid Build Coastguard Worker 	size_t num_dogs;
27*d83cc019SAndroid Build Coastguard Worker } watchdogs;
28*d83cc019SAndroid Build Coastguard Worker 
__close_watchdog(int fd)29*d83cc019SAndroid Build Coastguard Worker static void __close_watchdog(int fd)
30*d83cc019SAndroid Build Coastguard Worker {
31*d83cc019SAndroid Build Coastguard Worker 	ssize_t ret = write(fd, "V", 1);
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker 	if (ret == -1)
34*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to stop a watchdog: %s\n",
35*d83cc019SAndroid Build Coastguard Worker 			strerror(errno));
36*d83cc019SAndroid Build Coastguard Worker 
37*d83cc019SAndroid Build Coastguard Worker 	close(fd);
38*d83cc019SAndroid Build Coastguard Worker }
39*d83cc019SAndroid Build Coastguard Worker 
close_watchdogs(struct settings * settings)40*d83cc019SAndroid Build Coastguard Worker static void close_watchdogs(struct settings *settings)
41*d83cc019SAndroid Build Coastguard Worker {
42*d83cc019SAndroid Build Coastguard Worker 	size_t i;
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker 	if (settings && settings->log_level >= LOG_LEVEL_VERBOSE)
45*d83cc019SAndroid Build Coastguard Worker 		printf("Closing watchdogs\n");
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker 	if (settings == NULL && watchdogs.num_dogs != 0)
48*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Closing watchdogs from exit handler!\n");
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < watchdogs.num_dogs; i++) {
51*d83cc019SAndroid Build Coastguard Worker 		__close_watchdog(watchdogs.fds[i]);
52*d83cc019SAndroid Build Coastguard Worker 	}
53*d83cc019SAndroid Build Coastguard Worker 
54*d83cc019SAndroid Build Coastguard Worker 	free(watchdogs.fds);
55*d83cc019SAndroid Build Coastguard Worker 	watchdogs.num_dogs = 0;
56*d83cc019SAndroid Build Coastguard Worker 	watchdogs.fds = NULL;
57*d83cc019SAndroid Build Coastguard Worker }
58*d83cc019SAndroid Build Coastguard Worker 
close_watchdogs_atexit(void)59*d83cc019SAndroid Build Coastguard Worker static void close_watchdogs_atexit(void)
60*d83cc019SAndroid Build Coastguard Worker {
61*d83cc019SAndroid Build Coastguard Worker 	close_watchdogs(NULL);
62*d83cc019SAndroid Build Coastguard Worker }
63*d83cc019SAndroid Build Coastguard Worker 
init_watchdogs(struct settings * settings)64*d83cc019SAndroid Build Coastguard Worker static void init_watchdogs(struct settings *settings)
65*d83cc019SAndroid Build Coastguard Worker {
66*d83cc019SAndroid Build Coastguard Worker 	int i;
67*d83cc019SAndroid Build Coastguard Worker 	char name[32];
68*d83cc019SAndroid Build Coastguard Worker 	int fd;
69*d83cc019SAndroid Build Coastguard Worker 
70*d83cc019SAndroid Build Coastguard Worker 	memset(&watchdogs, 0, sizeof(watchdogs));
71*d83cc019SAndroid Build Coastguard Worker 
72*d83cc019SAndroid Build Coastguard Worker 	if (!settings->use_watchdog || settings->inactivity_timeout <= 0)
73*d83cc019SAndroid Build Coastguard Worker 		return;
74*d83cc019SAndroid Build Coastguard Worker 
75*d83cc019SAndroid Build Coastguard Worker 	if (settings->log_level >= LOG_LEVEL_VERBOSE) {
76*d83cc019SAndroid Build Coastguard Worker 		printf("Initializing watchdogs\n");
77*d83cc019SAndroid Build Coastguard Worker 	}
78*d83cc019SAndroid Build Coastguard Worker 
79*d83cc019SAndroid Build Coastguard Worker 	atexit(close_watchdogs_atexit);
80*d83cc019SAndroid Build Coastguard Worker 
81*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; ; i++) {
82*d83cc019SAndroid Build Coastguard Worker 		snprintf(name, sizeof(name), "/dev/watchdog%d", i);
83*d83cc019SAndroid Build Coastguard Worker 		if ((fd = open(name, O_RDWR | O_CLOEXEC)) < 0)
84*d83cc019SAndroid Build Coastguard Worker 			break;
85*d83cc019SAndroid Build Coastguard Worker 
86*d83cc019SAndroid Build Coastguard Worker 		watchdogs.num_dogs++;
87*d83cc019SAndroid Build Coastguard Worker 		watchdogs.fds = realloc(watchdogs.fds, watchdogs.num_dogs * sizeof(int));
88*d83cc019SAndroid Build Coastguard Worker 		watchdogs.fds[i] = fd;
89*d83cc019SAndroid Build Coastguard Worker 
90*d83cc019SAndroid Build Coastguard Worker 		if (settings->log_level >= LOG_LEVEL_VERBOSE)
91*d83cc019SAndroid Build Coastguard Worker 			printf(" %s\n", name);
92*d83cc019SAndroid Build Coastguard Worker 	}
93*d83cc019SAndroid Build Coastguard Worker }
94*d83cc019SAndroid Build Coastguard Worker 
watchdogs_set_timeout(int timeout)95*d83cc019SAndroid Build Coastguard Worker static int watchdogs_set_timeout(int timeout)
96*d83cc019SAndroid Build Coastguard Worker {
97*d83cc019SAndroid Build Coastguard Worker 	size_t i;
98*d83cc019SAndroid Build Coastguard Worker 	int orig_timeout = timeout;
99*d83cc019SAndroid Build Coastguard Worker 
100*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < watchdogs.num_dogs; i++) {
101*d83cc019SAndroid Build Coastguard Worker 		if (ioctl(watchdogs.fds[i], WDIOC_SETTIMEOUT, &timeout)) {
102*d83cc019SAndroid Build Coastguard Worker 			__close_watchdog(watchdogs.fds[i]);
103*d83cc019SAndroid Build Coastguard Worker 			watchdogs.fds[i] = -1;
104*d83cc019SAndroid Build Coastguard Worker 			continue;
105*d83cc019SAndroid Build Coastguard Worker 		}
106*d83cc019SAndroid Build Coastguard Worker 
107*d83cc019SAndroid Build Coastguard Worker 		if (timeout < orig_timeout) {
108*d83cc019SAndroid Build Coastguard Worker 			/*
109*d83cc019SAndroid Build Coastguard Worker 			 * Timeout of this caliber refused. We want to
110*d83cc019SAndroid Build Coastguard Worker 			 * use the same timeout for all devices.
111*d83cc019SAndroid Build Coastguard Worker 			 */
112*d83cc019SAndroid Build Coastguard Worker 			return watchdogs_set_timeout(timeout);
113*d83cc019SAndroid Build Coastguard Worker 		}
114*d83cc019SAndroid Build Coastguard Worker 	}
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	return timeout;
117*d83cc019SAndroid Build Coastguard Worker }
118*d83cc019SAndroid Build Coastguard Worker 
ping_watchdogs(void)119*d83cc019SAndroid Build Coastguard Worker static void ping_watchdogs(void)
120*d83cc019SAndroid Build Coastguard Worker {
121*d83cc019SAndroid Build Coastguard Worker 	size_t i;
122*d83cc019SAndroid Build Coastguard Worker 	int ret;
123*d83cc019SAndroid Build Coastguard Worker 
124*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < watchdogs.num_dogs; i++) {
125*d83cc019SAndroid Build Coastguard Worker 		ret = ioctl(watchdogs.fds[i], WDIOC_KEEPALIVE, NULL);
126*d83cc019SAndroid Build Coastguard Worker 
127*d83cc019SAndroid Build Coastguard Worker 		if (ret == -1)
128*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Failed to ping a watchdog: %s\n",
129*d83cc019SAndroid Build Coastguard Worker 				strerror(errno));
130*d83cc019SAndroid Build Coastguard Worker 	}
131*d83cc019SAndroid Build Coastguard Worker }
132*d83cc019SAndroid Build Coastguard Worker 
handle_lockdep(void)133*d83cc019SAndroid Build Coastguard Worker static char *handle_lockdep(void)
134*d83cc019SAndroid Build Coastguard Worker {
135*d83cc019SAndroid Build Coastguard Worker 	const char *header = "Lockdep not active\n\n/proc/lockdep_stats contents:\n";
136*d83cc019SAndroid Build Coastguard Worker 	int fd = open("/proc/lockdep_stats", O_RDONLY);
137*d83cc019SAndroid Build Coastguard Worker 	const char *debug_locks_line = " debug_locks:";
138*d83cc019SAndroid Build Coastguard Worker 	char buf[4096], *p;
139*d83cc019SAndroid Build Coastguard Worker 	ssize_t bufsize = 0;
140*d83cc019SAndroid Build Coastguard Worker 	int val;
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
143*d83cc019SAndroid Build Coastguard Worker 		return NULL;
144*d83cc019SAndroid Build Coastguard Worker 
145*d83cc019SAndroid Build Coastguard Worker 	strcpy(buf, header);
146*d83cc019SAndroid Build Coastguard Worker 
147*d83cc019SAndroid Build Coastguard Worker 	if ((bufsize = read(fd, buf + strlen(header), sizeof(buf) - strlen(header) - 1)) < 0)
148*d83cc019SAndroid Build Coastguard Worker 		return NULL;
149*d83cc019SAndroid Build Coastguard Worker 	bufsize += strlen(header);
150*d83cc019SAndroid Build Coastguard Worker 	buf[bufsize] = '\0';
151*d83cc019SAndroid Build Coastguard Worker 	close(fd);
152*d83cc019SAndroid Build Coastguard Worker 
153*d83cc019SAndroid Build Coastguard Worker 	if ((p = strstr(buf, debug_locks_line)) != NULL &&
154*d83cc019SAndroid Build Coastguard Worker 	    sscanf(p + strlen(debug_locks_line), "%d", &val) == 1 &&
155*d83cc019SAndroid Build Coastguard Worker 	    val != 1) {
156*d83cc019SAndroid Build Coastguard Worker 		return strdup(buf);
157*d83cc019SAndroid Build Coastguard Worker 	}
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 	return NULL;
160*d83cc019SAndroid Build Coastguard Worker }
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker /* see Linux's include/linux/kernel.h */
163*d83cc019SAndroid Build Coastguard Worker static const struct {
164*d83cc019SAndroid Build Coastguard Worker 	unsigned long bit;
165*d83cc019SAndroid Build Coastguard Worker 	const char *explanation;
166*d83cc019SAndroid Build Coastguard Worker } abort_taints[] = {
167*d83cc019SAndroid Build Coastguard Worker   {(1 << 5), "TAINT_BAD_PAGE: Bad page reference or an unexpected page flags."},
168*d83cc019SAndroid Build Coastguard Worker   {(1 << 7), "TAINT_DIE: Kernel has died - BUG/OOPS."},
169*d83cc019SAndroid Build Coastguard Worker   {(1 << 9), "TAINT_WARN: WARN_ON has happened."},
170*d83cc019SAndroid Build Coastguard Worker   {0, 0}};
171*d83cc019SAndroid Build Coastguard Worker 
tainted(unsigned long * taints)172*d83cc019SAndroid Build Coastguard Worker static unsigned long tainted(unsigned long *taints)
173*d83cc019SAndroid Build Coastguard Worker {
174*d83cc019SAndroid Build Coastguard Worker 	FILE *f;
175*d83cc019SAndroid Build Coastguard Worker 	unsigned long bad_taints = 0;
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 	for (typeof(*abort_taints) *taint = abort_taints; taint->bit; taint++)
178*d83cc019SAndroid Build Coastguard Worker 		bad_taints |= taint->bit;
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	*taints = 0;
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	f = fopen("/proc/sys/kernel/tainted", "r");
183*d83cc019SAndroid Build Coastguard Worker 	if (f) {
184*d83cc019SAndroid Build Coastguard Worker 		fscanf(f, "%lu", taints);
185*d83cc019SAndroid Build Coastguard Worker 		fclose(f);
186*d83cc019SAndroid Build Coastguard Worker 	}
187*d83cc019SAndroid Build Coastguard Worker 
188*d83cc019SAndroid Build Coastguard Worker 	return *taints & bad_taints;
189*d83cc019SAndroid Build Coastguard Worker }
190*d83cc019SAndroid Build Coastguard Worker 
handle_taint(void)191*d83cc019SAndroid Build Coastguard Worker static char *handle_taint(void)
192*d83cc019SAndroid Build Coastguard Worker {
193*d83cc019SAndroid Build Coastguard Worker 	unsigned long taints;
194*d83cc019SAndroid Build Coastguard Worker 	char *reason;
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	if (!tainted(&taints))
197*d83cc019SAndroid Build Coastguard Worker 		return NULL;
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker 	asprintf(&reason, "Kernel badly tainted (%#lx) (check dmesg for details):\n",
200*d83cc019SAndroid Build Coastguard Worker 		 taints);
201*d83cc019SAndroid Build Coastguard Worker 
202*d83cc019SAndroid Build Coastguard Worker 	for (typeof(*abort_taints) *taint = abort_taints; taint->bit; taint++) {
203*d83cc019SAndroid Build Coastguard Worker 		if (taint->bit & taints) {
204*d83cc019SAndroid Build Coastguard Worker 			char *old_reason = reason;
205*d83cc019SAndroid Build Coastguard Worker 			asprintf(&reason, "%s\t(%#lx) %s\n",
206*d83cc019SAndroid Build Coastguard Worker 					old_reason,
207*d83cc019SAndroid Build Coastguard Worker 					taint->bit,
208*d83cc019SAndroid Build Coastguard Worker 					taint->explanation);
209*d83cc019SAndroid Build Coastguard Worker 			free(old_reason);
210*d83cc019SAndroid Build Coastguard Worker 		}
211*d83cc019SAndroid Build Coastguard Worker 	}
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	return reason;
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker 
216*d83cc019SAndroid Build Coastguard Worker static const struct {
217*d83cc019SAndroid Build Coastguard Worker 	int condition;
218*d83cc019SAndroid Build Coastguard Worker 	char *(*handler)(void);
219*d83cc019SAndroid Build Coastguard Worker } abort_handlers[] = {
220*d83cc019SAndroid Build Coastguard Worker 	{ ABORT_LOCKDEP, handle_lockdep },
221*d83cc019SAndroid Build Coastguard Worker 	{ ABORT_TAINT, handle_taint },
222*d83cc019SAndroid Build Coastguard Worker 	{ 0, 0 },
223*d83cc019SAndroid Build Coastguard Worker };
224*d83cc019SAndroid Build Coastguard Worker 
need_to_abort(const struct settings * settings)225*d83cc019SAndroid Build Coastguard Worker static char *need_to_abort(const struct settings* settings)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker 	typeof(*abort_handlers) *it;
228*d83cc019SAndroid Build Coastguard Worker 
229*d83cc019SAndroid Build Coastguard Worker 	for (it = abort_handlers; it->condition; it++) {
230*d83cc019SAndroid Build Coastguard Worker 		char *abort;
231*d83cc019SAndroid Build Coastguard Worker 
232*d83cc019SAndroid Build Coastguard Worker 		if (!(settings->abort_mask & it->condition))
233*d83cc019SAndroid Build Coastguard Worker 			continue;
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 		abort = it->handler();
236*d83cc019SAndroid Build Coastguard Worker 		if (!abort)
237*d83cc019SAndroid Build Coastguard Worker 			continue;
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 		if (settings->log_level >= LOG_LEVEL_NORMAL)
240*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Aborting: %s\n", abort);
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 		return abort;
243*d83cc019SAndroid Build Coastguard Worker 	}
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	return NULL;
246*d83cc019SAndroid Build Coastguard Worker }
247*d83cc019SAndroid Build Coastguard Worker 
prune_subtest(struct job_list_entry * entry,char * subtest)248*d83cc019SAndroid Build Coastguard Worker static void prune_subtest(struct job_list_entry *entry, char *subtest)
249*d83cc019SAndroid Build Coastguard Worker {
250*d83cc019SAndroid Build Coastguard Worker 	char *excl;
251*d83cc019SAndroid Build Coastguard Worker 
252*d83cc019SAndroid Build Coastguard Worker 	/*
253*d83cc019SAndroid Build Coastguard Worker 	 * Subtest pruning is done by adding exclusion strings to the
254*d83cc019SAndroid Build Coastguard Worker 	 * subtest list. The last matching item on the subtest
255*d83cc019SAndroid Build Coastguard Worker 	 * selection command line flag decides whether to run a
256*d83cc019SAndroid Build Coastguard Worker 	 * subtest, see igt_core.c for details.  If the list is empty,
257*d83cc019SAndroid Build Coastguard Worker 	 * the expected subtest set is unknown, so we need to add '*'
258*d83cc019SAndroid Build Coastguard Worker 	 * first so we can start excluding.
259*d83cc019SAndroid Build Coastguard Worker 	 */
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	if (entry->subtest_count == 0) {
262*d83cc019SAndroid Build Coastguard Worker 		entry->subtest_count++;
263*d83cc019SAndroid Build Coastguard Worker 		entry->subtests = realloc(entry->subtests, entry->subtest_count * sizeof(*entry->subtests));
264*d83cc019SAndroid Build Coastguard Worker 		entry->subtests[0] = strdup("*");
265*d83cc019SAndroid Build Coastguard Worker 	}
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	excl = malloc(strlen(subtest) + 2);
268*d83cc019SAndroid Build Coastguard Worker 	excl[0] = '!';
269*d83cc019SAndroid Build Coastguard Worker 	strcpy(excl + 1, subtest);
270*d83cc019SAndroid Build Coastguard Worker 
271*d83cc019SAndroid Build Coastguard Worker 	entry->subtest_count++;
272*d83cc019SAndroid Build Coastguard Worker 	entry->subtests = realloc(entry->subtests, entry->subtest_count * sizeof(*entry->subtests));
273*d83cc019SAndroid Build Coastguard Worker 	entry->subtests[entry->subtest_count - 1] = excl;
274*d83cc019SAndroid Build Coastguard Worker }
275*d83cc019SAndroid Build Coastguard Worker 
prune_from_journal(struct job_list_entry * entry,int fd)276*d83cc019SAndroid Build Coastguard Worker static bool prune_from_journal(struct job_list_entry *entry, int fd)
277*d83cc019SAndroid Build Coastguard Worker {
278*d83cc019SAndroid Build Coastguard Worker 	char *subtest;
279*d83cc019SAndroid Build Coastguard Worker 	FILE *f;
280*d83cc019SAndroid Build Coastguard Worker 	size_t pruned = 0;
281*d83cc019SAndroid Build Coastguard Worker 	size_t old_count = entry->subtest_count;
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	/*
284*d83cc019SAndroid Build Coastguard Worker 	 * Each journal line is a subtest that has been started, or
285*d83cc019SAndroid Build Coastguard Worker 	 * the line 'exit:$exitcode (time)', or 'timeout:$exitcode (time)'.
286*d83cc019SAndroid Build Coastguard Worker 	 */
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 	f = fdopen(fd, "r");
289*d83cc019SAndroid Build Coastguard Worker 	if (!f)
290*d83cc019SAndroid Build Coastguard Worker 		return false;
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 	while (fscanf(f, "%ms", &subtest) == 1) {
293*d83cc019SAndroid Build Coastguard Worker 		if (!strncmp(subtest, EXECUTOR_EXIT, strlen(EXECUTOR_EXIT))) {
294*d83cc019SAndroid Build Coastguard Worker 			/* Fully done. Mark that by making the binary name invalid. */
295*d83cc019SAndroid Build Coastguard Worker 			fscanf(f, " (%*fs)");
296*d83cc019SAndroid Build Coastguard Worker 			entry->binary[0] = '\0';
297*d83cc019SAndroid Build Coastguard Worker 			free(subtest);
298*d83cc019SAndroid Build Coastguard Worker 			continue;
299*d83cc019SAndroid Build Coastguard Worker 		}
300*d83cc019SAndroid Build Coastguard Worker 
301*d83cc019SAndroid Build Coastguard Worker 		if (!strncmp(subtest, EXECUTOR_TIMEOUT, strlen(EXECUTOR_TIMEOUT))) {
302*d83cc019SAndroid Build Coastguard Worker 			fscanf(f, " (%*fs)");
303*d83cc019SAndroid Build Coastguard Worker 			free(subtest);
304*d83cc019SAndroid Build Coastguard Worker 			continue;
305*d83cc019SAndroid Build Coastguard Worker 		}
306*d83cc019SAndroid Build Coastguard Worker 
307*d83cc019SAndroid Build Coastguard Worker 		prune_subtest(entry, subtest);
308*d83cc019SAndroid Build Coastguard Worker 
309*d83cc019SAndroid Build Coastguard Worker 		free(subtest);
310*d83cc019SAndroid Build Coastguard Worker 		pruned++;
311*d83cc019SAndroid Build Coastguard Worker 	}
312*d83cc019SAndroid Build Coastguard Worker 
313*d83cc019SAndroid Build Coastguard Worker 	fclose(f);
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	/*
316*d83cc019SAndroid Build Coastguard Worker 	 * If we know the subtests we originally wanted to run, check
317*d83cc019SAndroid Build Coastguard Worker 	 * if we got an equal amount already.
318*d83cc019SAndroid Build Coastguard Worker 	 */
319*d83cc019SAndroid Build Coastguard Worker 	if (old_count > 0 && pruned >= old_count)
320*d83cc019SAndroid Build Coastguard Worker 		entry->binary[0] = '\0';
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker 	return pruned > 0;
323*d83cc019SAndroid Build Coastguard Worker }
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker static const char *filenames[_F_LAST] = {
326*d83cc019SAndroid Build Coastguard Worker 	[_F_JOURNAL] = "journal.txt",
327*d83cc019SAndroid Build Coastguard Worker 	[_F_OUT] = "out.txt",
328*d83cc019SAndroid Build Coastguard Worker 	[_F_ERR] = "err.txt",
329*d83cc019SAndroid Build Coastguard Worker 	[_F_DMESG] = "dmesg.txt",
330*d83cc019SAndroid Build Coastguard Worker };
331*d83cc019SAndroid Build Coastguard Worker 
open_at_end(int dirfd,const char * name)332*d83cc019SAndroid Build Coastguard Worker static int open_at_end(int dirfd, const char *name)
333*d83cc019SAndroid Build Coastguard Worker {
334*d83cc019SAndroid Build Coastguard Worker 	int fd = openat(dirfd, name, O_RDWR | O_CREAT | O_CLOEXEC, 0666);
335*d83cc019SAndroid Build Coastguard Worker 	char last;
336*d83cc019SAndroid Build Coastguard Worker 
337*d83cc019SAndroid Build Coastguard Worker 	if (fd >= 0) {
338*d83cc019SAndroid Build Coastguard Worker 		if (lseek(fd, -1, SEEK_END) >= 0 &&
339*d83cc019SAndroid Build Coastguard Worker 		    read(fd, &last, 1) == 1 &&
340*d83cc019SAndroid Build Coastguard Worker 		    last != '\n') {
341*d83cc019SAndroid Build Coastguard Worker 			write(fd, "\n", 1);
342*d83cc019SAndroid Build Coastguard Worker 		}
343*d83cc019SAndroid Build Coastguard Worker 		lseek(fd, 0, SEEK_END);
344*d83cc019SAndroid Build Coastguard Worker 	}
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker 	return fd;
347*d83cc019SAndroid Build Coastguard Worker }
348*d83cc019SAndroid Build Coastguard Worker 
open_for_reading(int dirfd,const char * name)349*d83cc019SAndroid Build Coastguard Worker static int open_for_reading(int dirfd, const char *name)
350*d83cc019SAndroid Build Coastguard Worker {
351*d83cc019SAndroid Build Coastguard Worker 	return openat(dirfd, name, O_RDONLY);
352*d83cc019SAndroid Build Coastguard Worker }
353*d83cc019SAndroid Build Coastguard Worker 
open_output_files(int dirfd,int * fds,bool write)354*d83cc019SAndroid Build Coastguard Worker bool open_output_files(int dirfd, int *fds, bool write)
355*d83cc019SAndroid Build Coastguard Worker {
356*d83cc019SAndroid Build Coastguard Worker 	int i;
357*d83cc019SAndroid Build Coastguard Worker 	int (*openfunc)(int, const char*) = write ? open_at_end : open_for_reading;
358*d83cc019SAndroid Build Coastguard Worker 
359*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < _F_LAST; i++) {
360*d83cc019SAndroid Build Coastguard Worker 		if ((fds[i] = openfunc(dirfd, filenames[i])) < 0) {
361*d83cc019SAndroid Build Coastguard Worker 			while (--i >= 0)
362*d83cc019SAndroid Build Coastguard Worker 				close(fds[i]);
363*d83cc019SAndroid Build Coastguard Worker 			return false;
364*d83cc019SAndroid Build Coastguard Worker 		}
365*d83cc019SAndroid Build Coastguard Worker 	}
366*d83cc019SAndroid Build Coastguard Worker 
367*d83cc019SAndroid Build Coastguard Worker 	return true;
368*d83cc019SAndroid Build Coastguard Worker }
369*d83cc019SAndroid Build Coastguard Worker 
close_outputs(int * fds)370*d83cc019SAndroid Build Coastguard Worker void close_outputs(int *fds)
371*d83cc019SAndroid Build Coastguard Worker {
372*d83cc019SAndroid Build Coastguard Worker 	int i;
373*d83cc019SAndroid Build Coastguard Worker 
374*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < _F_LAST; i++) {
375*d83cc019SAndroid Build Coastguard Worker 		close(fds[i]);
376*d83cc019SAndroid Build Coastguard Worker 	}
377*d83cc019SAndroid Build Coastguard Worker }
378*d83cc019SAndroid Build Coastguard Worker 
dump_dmesg(int kmsgfd,int outfd)379*d83cc019SAndroid Build Coastguard Worker static void dump_dmesg(int kmsgfd, int outfd)
380*d83cc019SAndroid Build Coastguard Worker {
381*d83cc019SAndroid Build Coastguard Worker 	/*
382*d83cc019SAndroid Build Coastguard Worker 	 * Write kernel messages to the log file until we reach
383*d83cc019SAndroid Build Coastguard Worker 	 * 'now'. Unfortunately, /dev/kmsg doesn't support seeking to
384*d83cc019SAndroid Build Coastguard Worker 	 * -1 from SEEK_END so we need to use a second fd to read a
385*d83cc019SAndroid Build Coastguard Worker 	 * message to match against, or stop when we reach EAGAIN.
386*d83cc019SAndroid Build Coastguard Worker 	 */
387*d83cc019SAndroid Build Coastguard Worker 
388*d83cc019SAndroid Build Coastguard Worker 	int comparefd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
389*d83cc019SAndroid Build Coastguard Worker 	unsigned flags;
390*d83cc019SAndroid Build Coastguard Worker 	unsigned long long seq, cmpseq, usec;
391*d83cc019SAndroid Build Coastguard Worker 	char cont;
392*d83cc019SAndroid Build Coastguard Worker 	char buf[2048];
393*d83cc019SAndroid Build Coastguard Worker 	ssize_t r;
394*d83cc019SAndroid Build Coastguard Worker 
395*d83cc019SAndroid Build Coastguard Worker 	if (comparefd < 0)
396*d83cc019SAndroid Build Coastguard Worker 		return;
397*d83cc019SAndroid Build Coastguard Worker 	lseek(comparefd, 0, SEEK_END);
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker 	if (fcntl(kmsgfd, F_SETFL, O_NONBLOCK)) {
400*d83cc019SAndroid Build Coastguard Worker 		close(comparefd);
401*d83cc019SAndroid Build Coastguard Worker 		return;
402*d83cc019SAndroid Build Coastguard Worker 	}
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker 	while (1) {
405*d83cc019SAndroid Build Coastguard Worker 		if (comparefd >= 0) {
406*d83cc019SAndroid Build Coastguard Worker 			r = read(comparefd, buf, sizeof(buf) - 1);
407*d83cc019SAndroid Build Coastguard Worker 			if (r < 0) {
408*d83cc019SAndroid Build Coastguard Worker 				if (errno != EAGAIN && errno != EPIPE) {
409*d83cc019SAndroid Build Coastguard Worker 					close(comparefd);
410*d83cc019SAndroid Build Coastguard Worker 					return;
411*d83cc019SAndroid Build Coastguard Worker 				}
412*d83cc019SAndroid Build Coastguard Worker 			} else {
413*d83cc019SAndroid Build Coastguard Worker 				buf[r] = '\0';
414*d83cc019SAndroid Build Coastguard Worker 				if (sscanf(buf, "%u,%llu,%llu,%c;",
415*d83cc019SAndroid Build Coastguard Worker 					   &flags, &cmpseq, &usec, &cont) == 4) {
416*d83cc019SAndroid Build Coastguard Worker 					/* Reading comparison record done. */
417*d83cc019SAndroid Build Coastguard Worker 					close(comparefd);
418*d83cc019SAndroid Build Coastguard Worker 					comparefd = -1;
419*d83cc019SAndroid Build Coastguard Worker 				}
420*d83cc019SAndroid Build Coastguard Worker 			}
421*d83cc019SAndroid Build Coastguard Worker 		}
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker 		r = read(kmsgfd, buf, sizeof(buf));
424*d83cc019SAndroid Build Coastguard Worker 		if (r <= 0) {
425*d83cc019SAndroid Build Coastguard Worker 			if (errno == EPIPE)
426*d83cc019SAndroid Build Coastguard Worker 				continue;
427*d83cc019SAndroid Build Coastguard Worker 
428*d83cc019SAndroid Build Coastguard Worker 			/*
429*d83cc019SAndroid Build Coastguard Worker 			 * If EAGAIN, we're done. If some other error,
430*d83cc019SAndroid Build Coastguard Worker 			 * we can't do anything anyway.
431*d83cc019SAndroid Build Coastguard Worker 			 */
432*d83cc019SAndroid Build Coastguard Worker 			close(comparefd);
433*d83cc019SAndroid Build Coastguard Worker 			return;
434*d83cc019SAndroid Build Coastguard Worker 		}
435*d83cc019SAndroid Build Coastguard Worker 
436*d83cc019SAndroid Build Coastguard Worker 		write(outfd, buf, r);
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 		if (comparefd < 0 && sscanf(buf, "%u,%llu,%llu,%c;",
439*d83cc019SAndroid Build Coastguard Worker 					    &flags, &seq, &usec, &cont) == 4) {
440*d83cc019SAndroid Build Coastguard Worker 			/*
441*d83cc019SAndroid Build Coastguard Worker 			 * Comparison record has been read, compare
442*d83cc019SAndroid Build Coastguard Worker 			 * the sequence number to see if we have read
443*d83cc019SAndroid Build Coastguard Worker 			 * enough.
444*d83cc019SAndroid Build Coastguard Worker 			 */
445*d83cc019SAndroid Build Coastguard Worker 			if (seq >= cmpseq)
446*d83cc019SAndroid Build Coastguard Worker 				return;
447*d83cc019SAndroid Build Coastguard Worker 		}
448*d83cc019SAndroid Build Coastguard Worker 	}
449*d83cc019SAndroid Build Coastguard Worker }
450*d83cc019SAndroid Build Coastguard Worker 
kill_child(int sig,pid_t child)451*d83cc019SAndroid Build Coastguard Worker static bool kill_child(int sig, pid_t child)
452*d83cc019SAndroid Build Coastguard Worker {
453*d83cc019SAndroid Build Coastguard Worker 	/*
454*d83cc019SAndroid Build Coastguard Worker 	 * Send the signal to the child directly, and to the child's
455*d83cc019SAndroid Build Coastguard Worker 	 * process group.
456*d83cc019SAndroid Build Coastguard Worker 	 */
457*d83cc019SAndroid Build Coastguard Worker 	kill(-child, sig);
458*d83cc019SAndroid Build Coastguard Worker 	if (kill(child, sig) && errno == ESRCH) {
459*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Child process does not exist. This shouldn't happen.\n");
460*d83cc019SAndroid Build Coastguard Worker 		return false;
461*d83cc019SAndroid Build Coastguard Worker 	}
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 	return true;
464*d83cc019SAndroid Build Coastguard Worker }
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker /*
467*d83cc019SAndroid Build Coastguard Worker  * Returns:
468*d83cc019SAndroid Build Coastguard Worker  *  =0 - Success
469*d83cc019SAndroid Build Coastguard Worker  *  <0 - Failure executing
470*d83cc019SAndroid Build Coastguard Worker  *  >0 - Timeout happened, need to recreate from journal
471*d83cc019SAndroid Build Coastguard Worker  */
monitor_output(pid_t child,int outfd,int errfd,int kmsgfd,int sigfd,int * outputs,double * time_spent,struct settings * settings)472*d83cc019SAndroid Build Coastguard Worker static int monitor_output(pid_t child,
473*d83cc019SAndroid Build Coastguard Worker 			   int outfd, int errfd, int kmsgfd, int sigfd,
474*d83cc019SAndroid Build Coastguard Worker 			   int *outputs,
475*d83cc019SAndroid Build Coastguard Worker 			   double *time_spent,
476*d83cc019SAndroid Build Coastguard Worker 			   struct settings *settings)
477*d83cc019SAndroid Build Coastguard Worker {
478*d83cc019SAndroid Build Coastguard Worker 	fd_set set;
479*d83cc019SAndroid Build Coastguard Worker 	char buf[2048];
480*d83cc019SAndroid Build Coastguard Worker 	char *outbuf = NULL;
481*d83cc019SAndroid Build Coastguard Worker 	size_t outbufsize = 0;
482*d83cc019SAndroid Build Coastguard Worker 	char current_subtest[256] = {};
483*d83cc019SAndroid Build Coastguard Worker 	struct signalfd_siginfo siginfo;
484*d83cc019SAndroid Build Coastguard Worker 	ssize_t s;
485*d83cc019SAndroid Build Coastguard Worker 	int n, status;
486*d83cc019SAndroid Build Coastguard Worker 	int nfds = outfd;
487*d83cc019SAndroid Build Coastguard Worker 	int timeout = settings->inactivity_timeout;
488*d83cc019SAndroid Build Coastguard Worker 	int timeout_intervals = 1, intervals_left;
489*d83cc019SAndroid Build Coastguard Worker 	int wd_extra = 10;
490*d83cc019SAndroid Build Coastguard Worker 	int killed = 0; /* 0 if not killed, signal number otherwise */
491*d83cc019SAndroid Build Coastguard Worker 	struct timespec time_beg, time_end;
492*d83cc019SAndroid Build Coastguard Worker 	unsigned long taints = 0;
493*d83cc019SAndroid Build Coastguard Worker 	bool aborting = false;
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 	igt_gettime(&time_beg);
496*d83cc019SAndroid Build Coastguard Worker 
497*d83cc019SAndroid Build Coastguard Worker 	if (errfd > nfds)
498*d83cc019SAndroid Build Coastguard Worker 		nfds = errfd;
499*d83cc019SAndroid Build Coastguard Worker 	if (kmsgfd > nfds)
500*d83cc019SAndroid Build Coastguard Worker 		nfds = kmsgfd;
501*d83cc019SAndroid Build Coastguard Worker 	if (sigfd > nfds)
502*d83cc019SAndroid Build Coastguard Worker 		nfds = sigfd;
503*d83cc019SAndroid Build Coastguard Worker 	nfds++;
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 	if (timeout > 0) {
506*d83cc019SAndroid Build Coastguard Worker 		/*
507*d83cc019SAndroid Build Coastguard Worker 		 * Use original timeout plus some leeway. If we're still
508*d83cc019SAndroid Build Coastguard Worker 		 * alive, we want to kill the test process instead of cutting
509*d83cc019SAndroid Build Coastguard Worker 		 * power.
510*d83cc019SAndroid Build Coastguard Worker 		 */
511*d83cc019SAndroid Build Coastguard Worker 		int wd_timeout = watchdogs_set_timeout(timeout + wd_extra);
512*d83cc019SAndroid Build Coastguard Worker 
513*d83cc019SAndroid Build Coastguard Worker 		if (wd_timeout < timeout + wd_extra) {
514*d83cc019SAndroid Build Coastguard Worker 			/* Watchdog timeout smaller, so ping it more often */
515*d83cc019SAndroid Build Coastguard Worker 			if (wd_timeout - wd_extra < 0)
516*d83cc019SAndroid Build Coastguard Worker 				wd_extra = wd_timeout / 2;
517*d83cc019SAndroid Build Coastguard Worker 			timeout_intervals = timeout / (wd_timeout - wd_extra);
518*d83cc019SAndroid Build Coastguard Worker 			timeout /= timeout_intervals;
519*d83cc019SAndroid Build Coastguard Worker 
520*d83cc019SAndroid Build Coastguard Worker 			if (settings->log_level >= LOG_LEVEL_VERBOSE) {
521*d83cc019SAndroid Build Coastguard Worker 				printf("Watchdog doesn't support the timeout we requested (shortened to %d seconds).\n"
522*d83cc019SAndroid Build Coastguard Worker 				       "Using %d intervals of %d seconds.\n",
523*d83cc019SAndroid Build Coastguard Worker 				       wd_timeout, timeout_intervals, timeout);
524*d83cc019SAndroid Build Coastguard Worker 			}
525*d83cc019SAndroid Build Coastguard Worker 		}
526*d83cc019SAndroid Build Coastguard Worker 	}
527*d83cc019SAndroid Build Coastguard Worker 
528*d83cc019SAndroid Build Coastguard Worker 	intervals_left = timeout_intervals;
529*d83cc019SAndroid Build Coastguard Worker 
530*d83cc019SAndroid Build Coastguard Worker 	while (outfd >= 0 || errfd >= 0 || sigfd >= 0) {
531*d83cc019SAndroid Build Coastguard Worker 		struct timeval tv = { .tv_sec = timeout };
532*d83cc019SAndroid Build Coastguard Worker 
533*d83cc019SAndroid Build Coastguard Worker 		FD_ZERO(&set);
534*d83cc019SAndroid Build Coastguard Worker 		if (outfd >= 0)
535*d83cc019SAndroid Build Coastguard Worker 			FD_SET(outfd, &set);
536*d83cc019SAndroid Build Coastguard Worker 		if (errfd >= 0)
537*d83cc019SAndroid Build Coastguard Worker 			FD_SET(errfd, &set);
538*d83cc019SAndroid Build Coastguard Worker 		if (kmsgfd >= 0)
539*d83cc019SAndroid Build Coastguard Worker 			FD_SET(kmsgfd, &set);
540*d83cc019SAndroid Build Coastguard Worker 		if (sigfd >= 0)
541*d83cc019SAndroid Build Coastguard Worker 			FD_SET(sigfd, &set);
542*d83cc019SAndroid Build Coastguard Worker 
543*d83cc019SAndroid Build Coastguard Worker 		n = select(nfds, &set, NULL, NULL, timeout == 0 ? NULL : &tv);
544*d83cc019SAndroid Build Coastguard Worker 		if (n < 0) {
545*d83cc019SAndroid Build Coastguard Worker 			/* TODO */
546*d83cc019SAndroid Build Coastguard Worker 			return -1;
547*d83cc019SAndroid Build Coastguard Worker 		}
548*d83cc019SAndroid Build Coastguard Worker 
549*d83cc019SAndroid Build Coastguard Worker 		if (n == 0) {
550*d83cc019SAndroid Build Coastguard Worker 			if (--intervals_left)
551*d83cc019SAndroid Build Coastguard Worker 				continue;
552*d83cc019SAndroid Build Coastguard Worker 
553*d83cc019SAndroid Build Coastguard Worker 			ping_watchdogs();
554*d83cc019SAndroid Build Coastguard Worker 
555*d83cc019SAndroid Build Coastguard Worker 			switch (killed) {
556*d83cc019SAndroid Build Coastguard Worker 			case 0:
557*d83cc019SAndroid Build Coastguard Worker 				if (settings->log_level >= LOG_LEVEL_NORMAL) {
558*d83cc019SAndroid Build Coastguard Worker 					printf("Timeout. Killing the current test with SIGQUIT.\n");
559*d83cc019SAndroid Build Coastguard Worker 					fflush(stdout);
560*d83cc019SAndroid Build Coastguard Worker 				}
561*d83cc019SAndroid Build Coastguard Worker 
562*d83cc019SAndroid Build Coastguard Worker 				killed = SIGQUIT;
563*d83cc019SAndroid Build Coastguard Worker 				if (!kill_child(killed, child))
564*d83cc019SAndroid Build Coastguard Worker 					return -1;
565*d83cc019SAndroid Build Coastguard Worker 
566*d83cc019SAndroid Build Coastguard Worker 				/*
567*d83cc019SAndroid Build Coastguard Worker 				 * Now continue the loop and let the
568*d83cc019SAndroid Build Coastguard Worker 				 * dying child be handled normally.
569*d83cc019SAndroid Build Coastguard Worker 				 */
570*d83cc019SAndroid Build Coastguard Worker 				timeout = 20;
571*d83cc019SAndroid Build Coastguard Worker 				watchdogs_set_timeout(120);
572*d83cc019SAndroid Build Coastguard Worker 				intervals_left = timeout_intervals = 1;
573*d83cc019SAndroid Build Coastguard Worker 				break;
574*d83cc019SAndroid Build Coastguard Worker 			case SIGQUIT:
575*d83cc019SAndroid Build Coastguard Worker 				if (settings->log_level >= LOG_LEVEL_NORMAL) {
576*d83cc019SAndroid Build Coastguard Worker 					printf("Timeout. Killing the current test with SIGKILL.\n");
577*d83cc019SAndroid Build Coastguard Worker 					fflush(stdout);
578*d83cc019SAndroid Build Coastguard Worker 				}
579*d83cc019SAndroid Build Coastguard Worker 
580*d83cc019SAndroid Build Coastguard Worker 				killed = SIGKILL;
581*d83cc019SAndroid Build Coastguard Worker 				if (!kill_child(killed, child))
582*d83cc019SAndroid Build Coastguard Worker 					return -1;
583*d83cc019SAndroid Build Coastguard Worker 
584*d83cc019SAndroid Build Coastguard Worker 				intervals_left = timeout_intervals = 1;
585*d83cc019SAndroid Build Coastguard Worker 				break;
586*d83cc019SAndroid Build Coastguard Worker 			case SIGKILL:
587*d83cc019SAndroid Build Coastguard Worker 				/*
588*d83cc019SAndroid Build Coastguard Worker 				 * If the child still exists, and the kernel
589*d83cc019SAndroid Build Coastguard Worker 				 * hasn't oopsed, assume it is still making
590*d83cc019SAndroid Build Coastguard Worker 				 * forward progress towards exiting (i.e. still
591*d83cc019SAndroid Build Coastguard Worker 				 * freeing all of its resources).
592*d83cc019SAndroid Build Coastguard Worker 				 */
593*d83cc019SAndroid Build Coastguard Worker 				if (kill(child, 0) == 0 && !tainted(&taints)) {
594*d83cc019SAndroid Build Coastguard Worker 					intervals_left =  1;
595*d83cc019SAndroid Build Coastguard Worker 					break;
596*d83cc019SAndroid Build Coastguard Worker 				}
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker 				/* Nothing that can be done, really. Let's tell the caller we want to abort. */
599*d83cc019SAndroid Build Coastguard Worker 				if (settings->log_level >= LOG_LEVEL_NORMAL) {
600*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Child refuses to die, tainted %lx. Aborting.\n",
601*d83cc019SAndroid Build Coastguard Worker 						taints);
602*d83cc019SAndroid Build Coastguard Worker 				}
603*d83cc019SAndroid Build Coastguard Worker 				close_watchdogs(settings);
604*d83cc019SAndroid Build Coastguard Worker 				free(outbuf);
605*d83cc019SAndroid Build Coastguard Worker 				close(outfd);
606*d83cc019SAndroid Build Coastguard Worker 				close(errfd);
607*d83cc019SAndroid Build Coastguard Worker 				close(kmsgfd);
608*d83cc019SAndroid Build Coastguard Worker 				return -1;
609*d83cc019SAndroid Build Coastguard Worker 			}
610*d83cc019SAndroid Build Coastguard Worker 
611*d83cc019SAndroid Build Coastguard Worker 			continue;
612*d83cc019SAndroid Build Coastguard Worker 		}
613*d83cc019SAndroid Build Coastguard Worker 
614*d83cc019SAndroid Build Coastguard Worker 		intervals_left = timeout_intervals;
615*d83cc019SAndroid Build Coastguard Worker 		ping_watchdogs();
616*d83cc019SAndroid Build Coastguard Worker 
617*d83cc019SAndroid Build Coastguard Worker 		/* TODO: Refactor these handlers to their own functions */
618*d83cc019SAndroid Build Coastguard Worker 		if (outfd >= 0 && FD_ISSET(outfd, &set)) {
619*d83cc019SAndroid Build Coastguard Worker 			char *newline;
620*d83cc019SAndroid Build Coastguard Worker 
621*d83cc019SAndroid Build Coastguard Worker 			s = read(outfd, buf, sizeof(buf));
622*d83cc019SAndroid Build Coastguard Worker 			if (s <= 0) {
623*d83cc019SAndroid Build Coastguard Worker 				if (s < 0) {
624*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Error reading test's stdout: %s\n",
625*d83cc019SAndroid Build Coastguard Worker 						strerror(errno));
626*d83cc019SAndroid Build Coastguard Worker 				}
627*d83cc019SAndroid Build Coastguard Worker 
628*d83cc019SAndroid Build Coastguard Worker 				close(outfd);
629*d83cc019SAndroid Build Coastguard Worker 				outfd = -1;
630*d83cc019SAndroid Build Coastguard Worker 				goto out_end;
631*d83cc019SAndroid Build Coastguard Worker 			}
632*d83cc019SAndroid Build Coastguard Worker 
633*d83cc019SAndroid Build Coastguard Worker 			write(outputs[_F_OUT], buf, s);
634*d83cc019SAndroid Build Coastguard Worker 			if (settings->sync) {
635*d83cc019SAndroid Build Coastguard Worker 				fdatasync(outputs[_F_OUT]);
636*d83cc019SAndroid Build Coastguard Worker 			}
637*d83cc019SAndroid Build Coastguard Worker 
638*d83cc019SAndroid Build Coastguard Worker 			outbuf = realloc(outbuf, outbufsize + s);
639*d83cc019SAndroid Build Coastguard Worker 			memcpy(outbuf + outbufsize, buf, s);
640*d83cc019SAndroid Build Coastguard Worker 			outbufsize += s;
641*d83cc019SAndroid Build Coastguard Worker 
642*d83cc019SAndroid Build Coastguard Worker 			while ((newline = memchr(outbuf, '\n', outbufsize)) != NULL) {
643*d83cc019SAndroid Build Coastguard Worker 				size_t linelen = newline - outbuf + 1;
644*d83cc019SAndroid Build Coastguard Worker 
645*d83cc019SAndroid Build Coastguard Worker 				if (linelen > strlen(STARTING_SUBTEST) &&
646*d83cc019SAndroid Build Coastguard Worker 				    !memcmp(outbuf, STARTING_SUBTEST, strlen(STARTING_SUBTEST))) {
647*d83cc019SAndroid Build Coastguard Worker 					write(outputs[_F_JOURNAL], outbuf + strlen(STARTING_SUBTEST),
648*d83cc019SAndroid Build Coastguard Worker 					      linelen - strlen(STARTING_SUBTEST));
649*d83cc019SAndroid Build Coastguard Worker 					memcpy(current_subtest, outbuf + strlen(STARTING_SUBTEST),
650*d83cc019SAndroid Build Coastguard Worker 					       linelen - strlen(STARTING_SUBTEST));
651*d83cc019SAndroid Build Coastguard Worker 					current_subtest[linelen - strlen(STARTING_SUBTEST)] = '\0';
652*d83cc019SAndroid Build Coastguard Worker 
653*d83cc019SAndroid Build Coastguard Worker 					if (settings->log_level >= LOG_LEVEL_VERBOSE) {
654*d83cc019SAndroid Build Coastguard Worker 						fwrite(outbuf, 1, linelen, stdout);
655*d83cc019SAndroid Build Coastguard Worker 					}
656*d83cc019SAndroid Build Coastguard Worker 				}
657*d83cc019SAndroid Build Coastguard Worker 				if (linelen > strlen(SUBTEST_RESULT) &&
658*d83cc019SAndroid Build Coastguard Worker 				    !memcmp(outbuf, SUBTEST_RESULT, strlen(SUBTEST_RESULT))) {
659*d83cc019SAndroid Build Coastguard Worker 					char *delim = memchr(outbuf, ':', linelen);
660*d83cc019SAndroid Build Coastguard Worker 
661*d83cc019SAndroid Build Coastguard Worker 					if (delim != NULL) {
662*d83cc019SAndroid Build Coastguard Worker 						size_t subtestlen = delim - outbuf - strlen(SUBTEST_RESULT);
663*d83cc019SAndroid Build Coastguard Worker 						if (memcmp(current_subtest, outbuf + strlen(SUBTEST_RESULT),
664*d83cc019SAndroid Build Coastguard Worker 							   subtestlen)) {
665*d83cc019SAndroid Build Coastguard Worker 							/* Result for a test that didn't ever start */
666*d83cc019SAndroid Build Coastguard Worker 							write(outputs[_F_JOURNAL],
667*d83cc019SAndroid Build Coastguard Worker 							      outbuf + strlen(SUBTEST_RESULT),
668*d83cc019SAndroid Build Coastguard Worker 							      subtestlen);
669*d83cc019SAndroid Build Coastguard Worker 							write(outputs[_F_JOURNAL], "\n", 1);
670*d83cc019SAndroid Build Coastguard Worker 							if (settings->sync) {
671*d83cc019SAndroid Build Coastguard Worker 								fdatasync(outputs[_F_JOURNAL]);
672*d83cc019SAndroid Build Coastguard Worker 							}
673*d83cc019SAndroid Build Coastguard Worker 							current_subtest[0] = '\0';
674*d83cc019SAndroid Build Coastguard Worker 						}
675*d83cc019SAndroid Build Coastguard Worker 
676*d83cc019SAndroid Build Coastguard Worker 						if (settings->log_level >= LOG_LEVEL_VERBOSE) {
677*d83cc019SAndroid Build Coastguard Worker 							fwrite(outbuf, 1, linelen, stdout);
678*d83cc019SAndroid Build Coastguard Worker 						}
679*d83cc019SAndroid Build Coastguard Worker 					}
680*d83cc019SAndroid Build Coastguard Worker 				}
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 				memmove(outbuf, newline + 1, outbufsize - linelen);
683*d83cc019SAndroid Build Coastguard Worker 				outbufsize -= linelen;
684*d83cc019SAndroid Build Coastguard Worker 			}
685*d83cc019SAndroid Build Coastguard Worker 		}
686*d83cc019SAndroid Build Coastguard Worker 	out_end:
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker 		if (errfd >= 0 && FD_ISSET(errfd, &set)) {
689*d83cc019SAndroid Build Coastguard Worker 			s = read(errfd, buf, sizeof(buf));
690*d83cc019SAndroid Build Coastguard Worker 			if (s <= 0) {
691*d83cc019SAndroid Build Coastguard Worker 				if (s < 0) {
692*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Error reading test's stderr: %s\n",
693*d83cc019SAndroid Build Coastguard Worker 						strerror(errno));
694*d83cc019SAndroid Build Coastguard Worker 				}
695*d83cc019SAndroid Build Coastguard Worker 				close(errfd);
696*d83cc019SAndroid Build Coastguard Worker 				errfd = -1;
697*d83cc019SAndroid Build Coastguard Worker 			} else {
698*d83cc019SAndroid Build Coastguard Worker 				write(outputs[_F_ERR], buf, s);
699*d83cc019SAndroid Build Coastguard Worker 				if (settings->sync) {
700*d83cc019SAndroid Build Coastguard Worker 					fdatasync(outputs[_F_ERR]);
701*d83cc019SAndroid Build Coastguard Worker 				}
702*d83cc019SAndroid Build Coastguard Worker 			}
703*d83cc019SAndroid Build Coastguard Worker 		}
704*d83cc019SAndroid Build Coastguard Worker 
705*d83cc019SAndroid Build Coastguard Worker 		if (kmsgfd >= 0 && FD_ISSET(kmsgfd, &set)) {
706*d83cc019SAndroid Build Coastguard Worker 			s = read(kmsgfd, buf, sizeof(buf));
707*d83cc019SAndroid Build Coastguard Worker 			if (s < 0) {
708*d83cc019SAndroid Build Coastguard Worker 				if (errno != EPIPE && errno != EINVAL) {
709*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Error reading from kmsg, stopping monitoring: %s\n",
710*d83cc019SAndroid Build Coastguard Worker 						strerror(errno));
711*d83cc019SAndroid Build Coastguard Worker 					close(kmsgfd);
712*d83cc019SAndroid Build Coastguard Worker 					kmsgfd = -1;
713*d83cc019SAndroid Build Coastguard Worker 				} else if (errno == EINVAL) {
714*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Warning: Buffer too small for kernel log record, record lost.\n");
715*d83cc019SAndroid Build Coastguard Worker 				}
716*d83cc019SAndroid Build Coastguard Worker 			} else {
717*d83cc019SAndroid Build Coastguard Worker 				write(outputs[_F_DMESG], buf, s);
718*d83cc019SAndroid Build Coastguard Worker 				if (settings->sync) {
719*d83cc019SAndroid Build Coastguard Worker 					fdatasync(outputs[_F_DMESG]);
720*d83cc019SAndroid Build Coastguard Worker 				}
721*d83cc019SAndroid Build Coastguard Worker 			}
722*d83cc019SAndroid Build Coastguard Worker 		}
723*d83cc019SAndroid Build Coastguard Worker 
724*d83cc019SAndroid Build Coastguard Worker 		if (sigfd >= 0 && FD_ISSET(sigfd, &set)) {
725*d83cc019SAndroid Build Coastguard Worker 			double time;
726*d83cc019SAndroid Build Coastguard Worker 
727*d83cc019SAndroid Build Coastguard Worker 			s = read(sigfd, &siginfo, sizeof(siginfo));
728*d83cc019SAndroid Build Coastguard Worker 			if (s < 0) {
729*d83cc019SAndroid Build Coastguard Worker 				fprintf(stderr, "Error reading from signalfd: %s\n",
730*d83cc019SAndroid Build Coastguard Worker 					strerror(errno));
731*d83cc019SAndroid Build Coastguard Worker 				continue;
732*d83cc019SAndroid Build Coastguard Worker 			} else if (siginfo.ssi_signo == SIGCHLD) {
733*d83cc019SAndroid Build Coastguard Worker 				if (child != waitpid(child, &status, WNOHANG)) {
734*d83cc019SAndroid Build Coastguard Worker 					fprintf(stderr, "Failed to reap child\n");
735*d83cc019SAndroid Build Coastguard Worker 					status = 9999;
736*d83cc019SAndroid Build Coastguard Worker 				} else if (WIFEXITED(status)) {
737*d83cc019SAndroid Build Coastguard Worker 					status = WEXITSTATUS(status);
738*d83cc019SAndroid Build Coastguard Worker 					if (status >= 128) {
739*d83cc019SAndroid Build Coastguard Worker 						status = 128 - status;
740*d83cc019SAndroid Build Coastguard Worker 					}
741*d83cc019SAndroid Build Coastguard Worker 				} else if (WIFSIGNALED(status)) {
742*d83cc019SAndroid Build Coastguard Worker 					status = -WTERMSIG(status);
743*d83cc019SAndroid Build Coastguard Worker 				} else {
744*d83cc019SAndroid Build Coastguard Worker 					status = 9999;
745*d83cc019SAndroid Build Coastguard Worker 				}
746*d83cc019SAndroid Build Coastguard Worker 			} else {
747*d83cc019SAndroid Build Coastguard Worker 				/* We're dying, so we're taking them with us */
748*d83cc019SAndroid Build Coastguard Worker 				if (settings->log_level >= LOG_LEVEL_NORMAL)
749*d83cc019SAndroid Build Coastguard Worker 					printf("Abort requested via %s, terminating children\n",
750*d83cc019SAndroid Build Coastguard Worker 					       strsignal(siginfo.ssi_signo));
751*d83cc019SAndroid Build Coastguard Worker 
752*d83cc019SAndroid Build Coastguard Worker 				aborting = true;
753*d83cc019SAndroid Build Coastguard Worker 				timeout = 2;
754*d83cc019SAndroid Build Coastguard Worker 				killed = SIGQUIT;
755*d83cc019SAndroid Build Coastguard Worker 				if (!kill_child(killed, child))
756*d83cc019SAndroid Build Coastguard Worker 					return -1;
757*d83cc019SAndroid Build Coastguard Worker 
758*d83cc019SAndroid Build Coastguard Worker 				continue;
759*d83cc019SAndroid Build Coastguard Worker 			}
760*d83cc019SAndroid Build Coastguard Worker 
761*d83cc019SAndroid Build Coastguard Worker 			igt_gettime(&time_end);
762*d83cc019SAndroid Build Coastguard Worker 
763*d83cc019SAndroid Build Coastguard Worker 			time = igt_time_elapsed(&time_beg, &time_end);
764*d83cc019SAndroid Build Coastguard Worker 			if (time < 0.0)
765*d83cc019SAndroid Build Coastguard Worker 				time = 0.0;
766*d83cc019SAndroid Build Coastguard Worker 
767*d83cc019SAndroid Build Coastguard Worker 			if (!aborting) {
768*d83cc019SAndroid Build Coastguard Worker 				dprintf(outputs[_F_JOURNAL], "%s%d (%.3fs)\n",
769*d83cc019SAndroid Build Coastguard Worker 					killed ? EXECUTOR_TIMEOUT : EXECUTOR_EXIT,
770*d83cc019SAndroid Build Coastguard Worker 					status, time);
771*d83cc019SAndroid Build Coastguard Worker 				if (settings->sync) {
772*d83cc019SAndroid Build Coastguard Worker 					fdatasync(outputs[_F_JOURNAL]);
773*d83cc019SAndroid Build Coastguard Worker 				}
774*d83cc019SAndroid Build Coastguard Worker 
775*d83cc019SAndroid Build Coastguard Worker 				if (time_spent)
776*d83cc019SAndroid Build Coastguard Worker 					*time_spent = time;
777*d83cc019SAndroid Build Coastguard Worker 			}
778*d83cc019SAndroid Build Coastguard Worker 
779*d83cc019SAndroid Build Coastguard Worker 			child = 0;
780*d83cc019SAndroid Build Coastguard Worker 			sigfd = -1; /* we are dying, no signal handling for now */
781*d83cc019SAndroid Build Coastguard Worker 		}
782*d83cc019SAndroid Build Coastguard Worker 	}
783*d83cc019SAndroid Build Coastguard Worker 
784*d83cc019SAndroid Build Coastguard Worker 	dump_dmesg(kmsgfd, outputs[_F_DMESG]);
785*d83cc019SAndroid Build Coastguard Worker 	if (settings->sync)
786*d83cc019SAndroid Build Coastguard Worker 		fdatasync(outputs[_F_DMESG]);
787*d83cc019SAndroid Build Coastguard Worker 
788*d83cc019SAndroid Build Coastguard Worker 	free(outbuf);
789*d83cc019SAndroid Build Coastguard Worker 	close(outfd);
790*d83cc019SAndroid Build Coastguard Worker 	close(errfd);
791*d83cc019SAndroid Build Coastguard Worker 	close(kmsgfd);
792*d83cc019SAndroid Build Coastguard Worker 
793*d83cc019SAndroid Build Coastguard Worker 	if (aborting)
794*d83cc019SAndroid Build Coastguard Worker 		return -1;
795*d83cc019SAndroid Build Coastguard Worker 
796*d83cc019SAndroid Build Coastguard Worker 	return killed;
797*d83cc019SAndroid Build Coastguard Worker }
798*d83cc019SAndroid Build Coastguard Worker 
799*d83cc019SAndroid Build Coastguard Worker static void __attribute__((noreturn))
execute_test_process(int outfd,int errfd,struct settings * settings,struct job_list_entry * entry)800*d83cc019SAndroid Build Coastguard Worker execute_test_process(int outfd, int errfd,
801*d83cc019SAndroid Build Coastguard Worker 		     struct settings *settings,
802*d83cc019SAndroid Build Coastguard Worker 		     struct job_list_entry *entry)
803*d83cc019SAndroid Build Coastguard Worker {
804*d83cc019SAndroid Build Coastguard Worker 	char *argv[4] = {};
805*d83cc019SAndroid Build Coastguard Worker 	size_t rootlen;
806*d83cc019SAndroid Build Coastguard Worker 
807*d83cc019SAndroid Build Coastguard Worker 	dup2(outfd, STDOUT_FILENO);
808*d83cc019SAndroid Build Coastguard Worker 	dup2(errfd, STDERR_FILENO);
809*d83cc019SAndroid Build Coastguard Worker 
810*d83cc019SAndroid Build Coastguard Worker 	setpgid(0, 0);
811*d83cc019SAndroid Build Coastguard Worker 
812*d83cc019SAndroid Build Coastguard Worker 	rootlen = strlen(settings->test_root);
813*d83cc019SAndroid Build Coastguard Worker 	argv[0] = malloc(rootlen + strlen(entry->binary) + 2);
814*d83cc019SAndroid Build Coastguard Worker 	strcpy(argv[0], settings->test_root);
815*d83cc019SAndroid Build Coastguard Worker 	argv[0][rootlen] = '/';
816*d83cc019SAndroid Build Coastguard Worker 	strcpy(argv[0] + rootlen + 1, entry->binary);
817*d83cc019SAndroid Build Coastguard Worker 
818*d83cc019SAndroid Build Coastguard Worker 	if (entry->subtest_count) {
819*d83cc019SAndroid Build Coastguard Worker 		size_t argsize;
820*d83cc019SAndroid Build Coastguard Worker 		size_t i;
821*d83cc019SAndroid Build Coastguard Worker 
822*d83cc019SAndroid Build Coastguard Worker 		argv[1] = strdup("--run-subtest");
823*d83cc019SAndroid Build Coastguard Worker 		argsize = strlen(entry->subtests[0]);
824*d83cc019SAndroid Build Coastguard Worker 		argv[2] = malloc(argsize + 1);
825*d83cc019SAndroid Build Coastguard Worker 		strcpy(argv[2], entry->subtests[0]);
826*d83cc019SAndroid Build Coastguard Worker 
827*d83cc019SAndroid Build Coastguard Worker 		for (i = 1; i < entry->subtest_count; i++) {
828*d83cc019SAndroid Build Coastguard Worker 			char *sub = entry->subtests[i];
829*d83cc019SAndroid Build Coastguard Worker 			size_t sublen = strlen(sub);
830*d83cc019SAndroid Build Coastguard Worker 
831*d83cc019SAndroid Build Coastguard Worker 			argv[2] = realloc(argv[2], argsize + sublen + 2);
832*d83cc019SAndroid Build Coastguard Worker 			argv[2][argsize] = ',';
833*d83cc019SAndroid Build Coastguard Worker 			strcpy(argv[2] + argsize + 1, sub);
834*d83cc019SAndroid Build Coastguard Worker 			argsize += sublen + 1;
835*d83cc019SAndroid Build Coastguard Worker 		}
836*d83cc019SAndroid Build Coastguard Worker 	}
837*d83cc019SAndroid Build Coastguard Worker 
838*d83cc019SAndroid Build Coastguard Worker 	execv(argv[0], argv);
839*d83cc019SAndroid Build Coastguard Worker 	fprintf(stderr, "Cannot execute %s\n", argv[0]);
840*d83cc019SAndroid Build Coastguard Worker 	exit(IGT_EXIT_INVALID);
841*d83cc019SAndroid Build Coastguard Worker }
842*d83cc019SAndroid Build Coastguard Worker 
digits(size_t num)843*d83cc019SAndroid Build Coastguard Worker static int digits(size_t num)
844*d83cc019SAndroid Build Coastguard Worker {
845*d83cc019SAndroid Build Coastguard Worker 	int ret = 0;
846*d83cc019SAndroid Build Coastguard Worker 	while (num) {
847*d83cc019SAndroid Build Coastguard Worker 		num /= 10;
848*d83cc019SAndroid Build Coastguard Worker 		ret++;
849*d83cc019SAndroid Build Coastguard Worker 	}
850*d83cc019SAndroid Build Coastguard Worker 
851*d83cc019SAndroid Build Coastguard Worker 	if (ret == 0) ret++;
852*d83cc019SAndroid Build Coastguard Worker 	return ret;
853*d83cc019SAndroid Build Coastguard Worker }
854*d83cc019SAndroid Build Coastguard Worker 
print_time_left(struct execute_state * state,struct settings * settings)855*d83cc019SAndroid Build Coastguard Worker static void print_time_left(struct execute_state *state,
856*d83cc019SAndroid Build Coastguard Worker 			    struct settings *settings)
857*d83cc019SAndroid Build Coastguard Worker {
858*d83cc019SAndroid Build Coastguard Worker 	int width;
859*d83cc019SAndroid Build Coastguard Worker 
860*d83cc019SAndroid Build Coastguard Worker 	if (settings->overall_timeout <= 0)
861*d83cc019SAndroid Build Coastguard Worker 		return;
862*d83cc019SAndroid Build Coastguard Worker 
863*d83cc019SAndroid Build Coastguard Worker 	width = digits(settings->overall_timeout);
864*d83cc019SAndroid Build Coastguard Worker 	printf("(%*.0fs left) ", width, state->time_left);
865*d83cc019SAndroid Build Coastguard Worker }
866*d83cc019SAndroid Build Coastguard Worker 
entry_display_name(struct job_list_entry * entry)867*d83cc019SAndroid Build Coastguard Worker static char *entry_display_name(struct job_list_entry *entry)
868*d83cc019SAndroid Build Coastguard Worker {
869*d83cc019SAndroid Build Coastguard Worker 	size_t size = strlen(entry->binary) + 1;
870*d83cc019SAndroid Build Coastguard Worker 	char *ret = malloc(size);
871*d83cc019SAndroid Build Coastguard Worker 
872*d83cc019SAndroid Build Coastguard Worker 	sprintf(ret, "%s", entry->binary);
873*d83cc019SAndroid Build Coastguard Worker 
874*d83cc019SAndroid Build Coastguard Worker 	if (entry->subtest_count > 0) {
875*d83cc019SAndroid Build Coastguard Worker 		size_t i;
876*d83cc019SAndroid Build Coastguard Worker 		const char *delim = "";
877*d83cc019SAndroid Build Coastguard Worker 
878*d83cc019SAndroid Build Coastguard Worker 		size += 3; /* strlen(" (") + strlen(")") */
879*d83cc019SAndroid Build Coastguard Worker 		ret = realloc(ret, size);
880*d83cc019SAndroid Build Coastguard Worker 		strcat(ret, " (");
881*d83cc019SAndroid Build Coastguard Worker 
882*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < entry->subtest_count; i++) {
883*d83cc019SAndroid Build Coastguard Worker 			size += strlen(delim) + strlen(entry->subtests[i]);
884*d83cc019SAndroid Build Coastguard Worker 			ret = realloc(ret, size);
885*d83cc019SAndroid Build Coastguard Worker 
886*d83cc019SAndroid Build Coastguard Worker 			strcat(ret, delim);
887*d83cc019SAndroid Build Coastguard Worker 			strcat(ret, entry->subtests[i]);
888*d83cc019SAndroid Build Coastguard Worker 
889*d83cc019SAndroid Build Coastguard Worker 			delim = ", ";
890*d83cc019SAndroid Build Coastguard Worker 		}
891*d83cc019SAndroid Build Coastguard Worker 		/* There's already room for this */
892*d83cc019SAndroid Build Coastguard Worker 		strcat(ret, ")");
893*d83cc019SAndroid Build Coastguard Worker 	}
894*d83cc019SAndroid Build Coastguard Worker 
895*d83cc019SAndroid Build Coastguard Worker 	return ret;
896*d83cc019SAndroid Build Coastguard Worker }
897*d83cc019SAndroid Build Coastguard Worker 
898*d83cc019SAndroid Build Coastguard Worker /*
899*d83cc019SAndroid Build Coastguard Worker  * Returns:
900*d83cc019SAndroid Build Coastguard Worker  *  =0 - Success
901*d83cc019SAndroid Build Coastguard Worker  *  <0 - Failure executing
902*d83cc019SAndroid Build Coastguard Worker  *  >0 - Timeout happened, need to recreate from journal
903*d83cc019SAndroid Build Coastguard Worker  */
execute_next_entry(struct execute_state * state,size_t total,double * time_spent,struct settings * settings,struct job_list_entry * entry,int testdirfd,int resdirfd,int sigfd,sigset_t * sigmask)904*d83cc019SAndroid Build Coastguard Worker static int execute_next_entry(struct execute_state *state,
905*d83cc019SAndroid Build Coastguard Worker 			      size_t total,
906*d83cc019SAndroid Build Coastguard Worker 			      double *time_spent,
907*d83cc019SAndroid Build Coastguard Worker 			      struct settings *settings,
908*d83cc019SAndroid Build Coastguard Worker 			      struct job_list_entry *entry,
909*d83cc019SAndroid Build Coastguard Worker 			      int testdirfd, int resdirfd,
910*d83cc019SAndroid Build Coastguard Worker 			      int sigfd, sigset_t *sigmask)
911*d83cc019SAndroid Build Coastguard Worker {
912*d83cc019SAndroid Build Coastguard Worker 	int dirfd;
913*d83cc019SAndroid Build Coastguard Worker 	int outputs[_F_LAST];
914*d83cc019SAndroid Build Coastguard Worker 	int kmsgfd;
915*d83cc019SAndroid Build Coastguard Worker 	int outpipe[2] = { -1, -1 };
916*d83cc019SAndroid Build Coastguard Worker 	int errpipe[2] = { -1, -1 };
917*d83cc019SAndroid Build Coastguard Worker 	int outfd, errfd;
918*d83cc019SAndroid Build Coastguard Worker 	char name[32];
919*d83cc019SAndroid Build Coastguard Worker 	pid_t child;
920*d83cc019SAndroid Build Coastguard Worker 	int result;
921*d83cc019SAndroid Build Coastguard Worker 	size_t idx = state->next;
922*d83cc019SAndroid Build Coastguard Worker 
923*d83cc019SAndroid Build Coastguard Worker 	snprintf(name, sizeof(name), "%zd", idx);
924*d83cc019SAndroid Build Coastguard Worker 	mkdirat(resdirfd, name, 0777);
925*d83cc019SAndroid Build Coastguard Worker 	if ((dirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
926*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error accessing individual test result directory\n");
927*d83cc019SAndroid Build Coastguard Worker 		return -1;
928*d83cc019SAndroid Build Coastguard Worker 	}
929*d83cc019SAndroid Build Coastguard Worker 
930*d83cc019SAndroid Build Coastguard Worker 	if (!open_output_files(dirfd, outputs, true)) {
931*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error opening output files\n");
932*d83cc019SAndroid Build Coastguard Worker 		result = -1;
933*d83cc019SAndroid Build Coastguard Worker 		goto out_dirfd;
934*d83cc019SAndroid Build Coastguard Worker 	}
935*d83cc019SAndroid Build Coastguard Worker 
936*d83cc019SAndroid Build Coastguard Worker 	if (settings->sync) {
937*d83cc019SAndroid Build Coastguard Worker 		fsync(dirfd);
938*d83cc019SAndroid Build Coastguard Worker 		fsync(resdirfd);
939*d83cc019SAndroid Build Coastguard Worker 	}
940*d83cc019SAndroid Build Coastguard Worker 
941*d83cc019SAndroid Build Coastguard Worker 	if (pipe(outpipe) || pipe(errpipe)) {
942*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error creating pipes: %s\n", strerror(errno));
943*d83cc019SAndroid Build Coastguard Worker 		result = -1;
944*d83cc019SAndroid Build Coastguard Worker 		goto out_pipe;
945*d83cc019SAndroid Build Coastguard Worker 	}
946*d83cc019SAndroid Build Coastguard Worker 
947*d83cc019SAndroid Build Coastguard Worker 	if ((kmsgfd = open("/dev/kmsg", O_RDONLY | O_CLOEXEC)) < 0) {
948*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Warning: Cannot open /dev/kmsg\n");
949*d83cc019SAndroid Build Coastguard Worker 	} else {
950*d83cc019SAndroid Build Coastguard Worker 		/* TODO: Checking of abort conditions in pre-execute dmesg */
951*d83cc019SAndroid Build Coastguard Worker 		lseek(kmsgfd, 0, SEEK_END);
952*d83cc019SAndroid Build Coastguard Worker 	}
953*d83cc019SAndroid Build Coastguard Worker 
954*d83cc019SAndroid Build Coastguard Worker 
955*d83cc019SAndroid Build Coastguard Worker 	if (settings->log_level >= LOG_LEVEL_NORMAL) {
956*d83cc019SAndroid Build Coastguard Worker 		char *displayname;
957*d83cc019SAndroid Build Coastguard Worker 		int width = digits(total);
958*d83cc019SAndroid Build Coastguard Worker 		printf("[%0*zd/%0*zd] ", width, idx + 1, width, total);
959*d83cc019SAndroid Build Coastguard Worker 
960*d83cc019SAndroid Build Coastguard Worker 		print_time_left(state, settings);
961*d83cc019SAndroid Build Coastguard Worker 
962*d83cc019SAndroid Build Coastguard Worker 		displayname = entry_display_name(entry);
963*d83cc019SAndroid Build Coastguard Worker 		printf("%s", displayname);
964*d83cc019SAndroid Build Coastguard Worker 		free(displayname);
965*d83cc019SAndroid Build Coastguard Worker 
966*d83cc019SAndroid Build Coastguard Worker 		printf("\n");
967*d83cc019SAndroid Build Coastguard Worker 	}
968*d83cc019SAndroid Build Coastguard Worker 
969*d83cc019SAndroid Build Coastguard Worker 	/*
970*d83cc019SAndroid Build Coastguard Worker 	 * Flush outputs before forking so our (buffered) output won't
971*d83cc019SAndroid Build Coastguard Worker 	 * end up in the test outputs.
972*d83cc019SAndroid Build Coastguard Worker 	 */
973*d83cc019SAndroid Build Coastguard Worker 	fflush(stdout);
974*d83cc019SAndroid Build Coastguard Worker 	fflush(stderr);
975*d83cc019SAndroid Build Coastguard Worker 
976*d83cc019SAndroid Build Coastguard Worker 	child = fork();
977*d83cc019SAndroid Build Coastguard Worker 	if (child < 0) {
978*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to fork: %s\n", strerror(errno));
979*d83cc019SAndroid Build Coastguard Worker 		result = -1;
980*d83cc019SAndroid Build Coastguard Worker 		goto out_kmsgfd;
981*d83cc019SAndroid Build Coastguard Worker 	} else if (child == 0) {
982*d83cc019SAndroid Build Coastguard Worker 		outfd = outpipe[1];
983*d83cc019SAndroid Build Coastguard Worker 		errfd = errpipe[1];
984*d83cc019SAndroid Build Coastguard Worker 		close(outpipe[0]);
985*d83cc019SAndroid Build Coastguard Worker 		close(errpipe[0]);
986*d83cc019SAndroid Build Coastguard Worker 
987*d83cc019SAndroid Build Coastguard Worker 		sigprocmask(SIG_UNBLOCK, sigmask, NULL);
988*d83cc019SAndroid Build Coastguard Worker 
989*d83cc019SAndroid Build Coastguard Worker 		setenv("IGT_SENTINEL_ON_STDERR", "1", 1);
990*d83cc019SAndroid Build Coastguard Worker 
991*d83cc019SAndroid Build Coastguard Worker 		execute_test_process(outfd, errfd, settings, entry);
992*d83cc019SAndroid Build Coastguard Worker 		/* unreachable */
993*d83cc019SAndroid Build Coastguard Worker 	}
994*d83cc019SAndroid Build Coastguard Worker 
995*d83cc019SAndroid Build Coastguard Worker 	outfd = outpipe[0];
996*d83cc019SAndroid Build Coastguard Worker 	errfd = errpipe[0];
997*d83cc019SAndroid Build Coastguard Worker 	close(outpipe[1]);
998*d83cc019SAndroid Build Coastguard Worker 	close(errpipe[1]);
999*d83cc019SAndroid Build Coastguard Worker 	outpipe[1] = errpipe[1] = -1;
1000*d83cc019SAndroid Build Coastguard Worker 
1001*d83cc019SAndroid Build Coastguard Worker 	result = monitor_output(child, outfd, errfd, kmsgfd, sigfd,
1002*d83cc019SAndroid Build Coastguard Worker 				outputs, time_spent, settings);
1003*d83cc019SAndroid Build Coastguard Worker 
1004*d83cc019SAndroid Build Coastguard Worker out_kmsgfd:
1005*d83cc019SAndroid Build Coastguard Worker 	close(kmsgfd);
1006*d83cc019SAndroid Build Coastguard Worker out_pipe:
1007*d83cc019SAndroid Build Coastguard Worker 	close_outputs(outputs);
1008*d83cc019SAndroid Build Coastguard Worker 	close(outpipe[0]);
1009*d83cc019SAndroid Build Coastguard Worker 	close(outpipe[1]);
1010*d83cc019SAndroid Build Coastguard Worker 	close(errpipe[0]);
1011*d83cc019SAndroid Build Coastguard Worker 	close(errpipe[1]);
1012*d83cc019SAndroid Build Coastguard Worker 	close_outputs(outputs);
1013*d83cc019SAndroid Build Coastguard Worker out_dirfd:
1014*d83cc019SAndroid Build Coastguard Worker 	close(dirfd);
1015*d83cc019SAndroid Build Coastguard Worker 
1016*d83cc019SAndroid Build Coastguard Worker 	return result;
1017*d83cc019SAndroid Build Coastguard Worker }
1018*d83cc019SAndroid Build Coastguard Worker 
remove_file(int dirfd,const char * name)1019*d83cc019SAndroid Build Coastguard Worker static int remove_file(int dirfd, const char *name)
1020*d83cc019SAndroid Build Coastguard Worker {
1021*d83cc019SAndroid Build Coastguard Worker 	return unlinkat(dirfd, name, 0) && errno != ENOENT;
1022*d83cc019SAndroid Build Coastguard Worker }
1023*d83cc019SAndroid Build Coastguard Worker 
clear_test_result_directory(int dirfd)1024*d83cc019SAndroid Build Coastguard Worker static bool clear_test_result_directory(int dirfd)
1025*d83cc019SAndroid Build Coastguard Worker {
1026*d83cc019SAndroid Build Coastguard Worker 	int i;
1027*d83cc019SAndroid Build Coastguard Worker 
1028*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < _F_LAST; i++) {
1029*d83cc019SAndroid Build Coastguard Worker 		if (remove_file(dirfd, filenames[i])) {
1030*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Error deleting %s from test result directory: %s\n",
1031*d83cc019SAndroid Build Coastguard Worker 				filenames[i],
1032*d83cc019SAndroid Build Coastguard Worker 				strerror(errno));
1033*d83cc019SAndroid Build Coastguard Worker 			return false;
1034*d83cc019SAndroid Build Coastguard Worker 		}
1035*d83cc019SAndroid Build Coastguard Worker 	}
1036*d83cc019SAndroid Build Coastguard Worker 
1037*d83cc019SAndroid Build Coastguard Worker 	return true;
1038*d83cc019SAndroid Build Coastguard Worker }
1039*d83cc019SAndroid Build Coastguard Worker 
clear_old_results(char * path)1040*d83cc019SAndroid Build Coastguard Worker static bool clear_old_results(char *path)
1041*d83cc019SAndroid Build Coastguard Worker {
1042*d83cc019SAndroid Build Coastguard Worker 	int dirfd;
1043*d83cc019SAndroid Build Coastguard Worker 	size_t i;
1044*d83cc019SAndroid Build Coastguard Worker 
1045*d83cc019SAndroid Build Coastguard Worker 	if ((dirfd = open(path, O_DIRECTORY | O_RDONLY)) < 0) {
1046*d83cc019SAndroid Build Coastguard Worker 		if (errno == ENOENT) {
1047*d83cc019SAndroid Build Coastguard Worker 			/* Successfully cleared if it doesn't even exist */
1048*d83cc019SAndroid Build Coastguard Worker 			return true;
1049*d83cc019SAndroid Build Coastguard Worker 		}
1050*d83cc019SAndroid Build Coastguard Worker 
1051*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error clearing old results: %s\n", strerror(errno));
1052*d83cc019SAndroid Build Coastguard Worker 		return false;
1053*d83cc019SAndroid Build Coastguard Worker 	}
1054*d83cc019SAndroid Build Coastguard Worker 
1055*d83cc019SAndroid Build Coastguard Worker 	if (remove_file(dirfd, "uname.txt") ||
1056*d83cc019SAndroid Build Coastguard Worker 	    remove_file(dirfd, "starttime.txt") ||
1057*d83cc019SAndroid Build Coastguard Worker 	    remove_file(dirfd, "endtime.txt") ||
1058*d83cc019SAndroid Build Coastguard Worker 	    remove_file(dirfd, "aborted.txt")) {
1059*d83cc019SAndroid Build Coastguard Worker 		close(dirfd);
1060*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error clearing old results: %s\n", strerror(errno));
1061*d83cc019SAndroid Build Coastguard Worker 		return false;
1062*d83cc019SAndroid Build Coastguard Worker 	}
1063*d83cc019SAndroid Build Coastguard Worker 
1064*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; true; i++) {
1065*d83cc019SAndroid Build Coastguard Worker 		char name[32];
1066*d83cc019SAndroid Build Coastguard Worker 		int resdirfd;
1067*d83cc019SAndroid Build Coastguard Worker 
1068*d83cc019SAndroid Build Coastguard Worker 		snprintf(name, sizeof(name), "%zd", i);
1069*d83cc019SAndroid Build Coastguard Worker 		if ((resdirfd = openat(dirfd, name, O_DIRECTORY | O_RDONLY)) < 0)
1070*d83cc019SAndroid Build Coastguard Worker 			break;
1071*d83cc019SAndroid Build Coastguard Worker 
1072*d83cc019SAndroid Build Coastguard Worker 		if (!clear_test_result_directory(resdirfd)) {
1073*d83cc019SAndroid Build Coastguard Worker 			close(resdirfd);
1074*d83cc019SAndroid Build Coastguard Worker 			close(dirfd);
1075*d83cc019SAndroid Build Coastguard Worker 			return false;
1076*d83cc019SAndroid Build Coastguard Worker 		}
1077*d83cc019SAndroid Build Coastguard Worker 		close(resdirfd);
1078*d83cc019SAndroid Build Coastguard Worker 		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
1079*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr,
1080*d83cc019SAndroid Build Coastguard Worker 				"Warning: Result directory %s contains extra files\n",
1081*d83cc019SAndroid Build Coastguard Worker 				name);
1082*d83cc019SAndroid Build Coastguard Worker 		}
1083*d83cc019SAndroid Build Coastguard Worker 	}
1084*d83cc019SAndroid Build Coastguard Worker 
1085*d83cc019SAndroid Build Coastguard Worker 	close(dirfd);
1086*d83cc019SAndroid Build Coastguard Worker 
1087*d83cc019SAndroid Build Coastguard Worker 	return true;
1088*d83cc019SAndroid Build Coastguard Worker }
1089*d83cc019SAndroid Build Coastguard Worker 
timeofday_double(void)1090*d83cc019SAndroid Build Coastguard Worker static double timeofday_double(void)
1091*d83cc019SAndroid Build Coastguard Worker {
1092*d83cc019SAndroid Build Coastguard Worker 	struct timeval tv;
1093*d83cc019SAndroid Build Coastguard Worker 
1094*d83cc019SAndroid Build Coastguard Worker 	if (!gettimeofday(&tv, NULL))
1095*d83cc019SAndroid Build Coastguard Worker 		return tv.tv_sec + tv.tv_usec / 1000000.0;
1096*d83cc019SAndroid Build Coastguard Worker 	return 0.0;
1097*d83cc019SAndroid Build Coastguard Worker }
1098*d83cc019SAndroid Build Coastguard Worker 
init_time_left(struct execute_state * state,struct settings * settings)1099*d83cc019SAndroid Build Coastguard Worker static void init_time_left(struct execute_state *state,
1100*d83cc019SAndroid Build Coastguard Worker 			   struct settings *settings)
1101*d83cc019SAndroid Build Coastguard Worker {
1102*d83cc019SAndroid Build Coastguard Worker 	if (settings->overall_timeout <= 0)
1103*d83cc019SAndroid Build Coastguard Worker 		state->time_left = -1;
1104*d83cc019SAndroid Build Coastguard Worker 	else
1105*d83cc019SAndroid Build Coastguard Worker 		state->time_left = settings->overall_timeout;
1106*d83cc019SAndroid Build Coastguard Worker }
1107*d83cc019SAndroid Build Coastguard Worker 
initialize_execute_state_from_resume(int dirfd,struct execute_state * state,struct settings * settings,struct job_list * list)1108*d83cc019SAndroid Build Coastguard Worker bool initialize_execute_state_from_resume(int dirfd,
1109*d83cc019SAndroid Build Coastguard Worker 					  struct execute_state *state,
1110*d83cc019SAndroid Build Coastguard Worker 					  struct settings *settings,
1111*d83cc019SAndroid Build Coastguard Worker 					  struct job_list *list)
1112*d83cc019SAndroid Build Coastguard Worker {
1113*d83cc019SAndroid Build Coastguard Worker 	struct job_list_entry *entry;
1114*d83cc019SAndroid Build Coastguard Worker 	int resdirfd, fd, i;
1115*d83cc019SAndroid Build Coastguard Worker 
1116*d83cc019SAndroid Build Coastguard Worker 	free_settings(settings);
1117*d83cc019SAndroid Build Coastguard Worker 	free_job_list(list);
1118*d83cc019SAndroid Build Coastguard Worker 	memset(state, 0, sizeof(*state));
1119*d83cc019SAndroid Build Coastguard Worker 	state->resuming = true;
1120*d83cc019SAndroid Build Coastguard Worker 
1121*d83cc019SAndroid Build Coastguard Worker 	if (!read_settings_from_dir(settings, dirfd) ||
1122*d83cc019SAndroid Build Coastguard Worker 	    !read_job_list(list, dirfd)) {
1123*d83cc019SAndroid Build Coastguard Worker 		close(dirfd);
1124*d83cc019SAndroid Build Coastguard Worker 		return false;
1125*d83cc019SAndroid Build Coastguard Worker 	}
1126*d83cc019SAndroid Build Coastguard Worker 
1127*d83cc019SAndroid Build Coastguard Worker 	init_time_left(state, settings);
1128*d83cc019SAndroid Build Coastguard Worker 
1129*d83cc019SAndroid Build Coastguard Worker 	for (i = list->size; i >= 0; i--) {
1130*d83cc019SAndroid Build Coastguard Worker 		char name[32];
1131*d83cc019SAndroid Build Coastguard Worker 
1132*d83cc019SAndroid Build Coastguard Worker 		snprintf(name, sizeof(name), "%d", i);
1133*d83cc019SAndroid Build Coastguard Worker 		if ((resdirfd = openat(dirfd, name, O_DIRECTORY | O_RDONLY)) >= 0)
1134*d83cc019SAndroid Build Coastguard Worker 			break;
1135*d83cc019SAndroid Build Coastguard Worker 	}
1136*d83cc019SAndroid Build Coastguard Worker 
1137*d83cc019SAndroid Build Coastguard Worker 	if (i < 0)
1138*d83cc019SAndroid Build Coastguard Worker 		/* Nothing has been executed yet, state is fine as is */
1139*d83cc019SAndroid Build Coastguard Worker 		goto success;
1140*d83cc019SAndroid Build Coastguard Worker 
1141*d83cc019SAndroid Build Coastguard Worker 	entry = &list->entries[i];
1142*d83cc019SAndroid Build Coastguard Worker 	state->next = i;
1143*d83cc019SAndroid Build Coastguard Worker 	if ((fd = openat(resdirfd, filenames[_F_JOURNAL], O_RDONLY)) >= 0) {
1144*d83cc019SAndroid Build Coastguard Worker 		if (!prune_from_journal(entry, fd)) {
1145*d83cc019SAndroid Build Coastguard Worker 			/*
1146*d83cc019SAndroid Build Coastguard Worker 			 * The test does not have subtests, or
1147*d83cc019SAndroid Build Coastguard Worker 			 * incompleted before the first subtest
1148*d83cc019SAndroid Build Coastguard Worker 			 * began. Either way, not suitable to
1149*d83cc019SAndroid Build Coastguard Worker 			 * re-run.
1150*d83cc019SAndroid Build Coastguard Worker 			 */
1151*d83cc019SAndroid Build Coastguard Worker 			state->next = i + 1;
1152*d83cc019SAndroid Build Coastguard Worker 		} else if (entry->binary[0] == '\0') {
1153*d83cc019SAndroid Build Coastguard Worker 			/* This test is fully completed */
1154*d83cc019SAndroid Build Coastguard Worker 			state->next = i + 1;
1155*d83cc019SAndroid Build Coastguard Worker 		}
1156*d83cc019SAndroid Build Coastguard Worker 
1157*d83cc019SAndroid Build Coastguard Worker 		close(fd);
1158*d83cc019SAndroid Build Coastguard Worker 	}
1159*d83cc019SAndroid Build Coastguard Worker 
1160*d83cc019SAndroid Build Coastguard Worker  success:
1161*d83cc019SAndroid Build Coastguard Worker 	close(resdirfd);
1162*d83cc019SAndroid Build Coastguard Worker 	close(dirfd);
1163*d83cc019SAndroid Build Coastguard Worker 
1164*d83cc019SAndroid Build Coastguard Worker 	return true;
1165*d83cc019SAndroid Build Coastguard Worker }
1166*d83cc019SAndroid Build Coastguard Worker 
initialize_execute_state(struct execute_state * state,struct settings * settings,struct job_list * job_list)1167*d83cc019SAndroid Build Coastguard Worker bool initialize_execute_state(struct execute_state *state,
1168*d83cc019SAndroid Build Coastguard Worker 			      struct settings *settings,
1169*d83cc019SAndroid Build Coastguard Worker 			      struct job_list *job_list)
1170*d83cc019SAndroid Build Coastguard Worker {
1171*d83cc019SAndroid Build Coastguard Worker 	memset(state, 0, sizeof(*state));
1172*d83cc019SAndroid Build Coastguard Worker 
1173*d83cc019SAndroid Build Coastguard Worker 	if (!validate_settings(settings))
1174*d83cc019SAndroid Build Coastguard Worker 		return false;
1175*d83cc019SAndroid Build Coastguard Worker 
1176*d83cc019SAndroid Build Coastguard Worker 	if (!serialize_settings(settings) ||
1177*d83cc019SAndroid Build Coastguard Worker 	    !serialize_job_list(job_list, settings))
1178*d83cc019SAndroid Build Coastguard Worker 		return false;
1179*d83cc019SAndroid Build Coastguard Worker 
1180*d83cc019SAndroid Build Coastguard Worker 	if (settings->overwrite &&
1181*d83cc019SAndroid Build Coastguard Worker 	    !clear_old_results(settings->results_path))
1182*d83cc019SAndroid Build Coastguard Worker 		return false;
1183*d83cc019SAndroid Build Coastguard Worker 
1184*d83cc019SAndroid Build Coastguard Worker 	init_time_left(state, settings);
1185*d83cc019SAndroid Build Coastguard Worker 
1186*d83cc019SAndroid Build Coastguard Worker 	state->dry = settings->dry_run;
1187*d83cc019SAndroid Build Coastguard Worker 
1188*d83cc019SAndroid Build Coastguard Worker 	return true;
1189*d83cc019SAndroid Build Coastguard Worker }
1190*d83cc019SAndroid Build Coastguard Worker 
reduce_time_left(struct settings * settings,struct execute_state * state,double time_spent)1191*d83cc019SAndroid Build Coastguard Worker static void reduce_time_left(struct settings *settings,
1192*d83cc019SAndroid Build Coastguard Worker 			     struct execute_state *state,
1193*d83cc019SAndroid Build Coastguard Worker 			     double time_spent)
1194*d83cc019SAndroid Build Coastguard Worker {
1195*d83cc019SAndroid Build Coastguard Worker 	if (state->time_left < 0)
1196*d83cc019SAndroid Build Coastguard Worker 		return;
1197*d83cc019SAndroid Build Coastguard Worker 
1198*d83cc019SAndroid Build Coastguard Worker 	if (time_spent > state->time_left)
1199*d83cc019SAndroid Build Coastguard Worker 		state->time_left = 0.0;
1200*d83cc019SAndroid Build Coastguard Worker 	else
1201*d83cc019SAndroid Build Coastguard Worker 		state->time_left -= time_spent;
1202*d83cc019SAndroid Build Coastguard Worker }
1203*d83cc019SAndroid Build Coastguard Worker 
overall_timeout_exceeded(struct execute_state * state)1204*d83cc019SAndroid Build Coastguard Worker static bool overall_timeout_exceeded(struct execute_state *state)
1205*d83cc019SAndroid Build Coastguard Worker {
1206*d83cc019SAndroid Build Coastguard Worker 	return state->time_left == 0.0;
1207*d83cc019SAndroid Build Coastguard Worker }
1208*d83cc019SAndroid Build Coastguard Worker 
write_abort_file(int resdirfd,const char * reason,const char * testbefore,const char * testafter)1209*d83cc019SAndroid Build Coastguard Worker static void write_abort_file(int resdirfd,
1210*d83cc019SAndroid Build Coastguard Worker 			     const char *reason,
1211*d83cc019SAndroid Build Coastguard Worker 			     const char *testbefore,
1212*d83cc019SAndroid Build Coastguard Worker 			     const char *testafter)
1213*d83cc019SAndroid Build Coastguard Worker {
1214*d83cc019SAndroid Build Coastguard Worker 	int abortfd;
1215*d83cc019SAndroid Build Coastguard Worker 
1216*d83cc019SAndroid Build Coastguard Worker 	if ((abortfd = openat(resdirfd, "aborted.txt", O_CREAT | O_WRONLY | O_EXCL, 0666)) >= 0) {
1217*d83cc019SAndroid Build Coastguard Worker 		/*
1218*d83cc019SAndroid Build Coastguard Worker 		 * Ignore failure to open, there's
1219*d83cc019SAndroid Build Coastguard Worker 		 * already an abort probably (if this
1220*d83cc019SAndroid Build Coastguard Worker 		 * is a resume)
1221*d83cc019SAndroid Build Coastguard Worker 		 */
1222*d83cc019SAndroid Build Coastguard Worker 		dprintf(abortfd, "Aborting.\n");
1223*d83cc019SAndroid Build Coastguard Worker 		dprintf(abortfd, "Previous test: %s\n", testbefore);
1224*d83cc019SAndroid Build Coastguard Worker 		dprintf(abortfd, "Next test: %s\n\n", testafter);
1225*d83cc019SAndroid Build Coastguard Worker 		write(abortfd, reason, strlen(reason));
1226*d83cc019SAndroid Build Coastguard Worker 		close(abortfd);
1227*d83cc019SAndroid Build Coastguard Worker 	}
1228*d83cc019SAndroid Build Coastguard Worker }
1229*d83cc019SAndroid Build Coastguard Worker 
oom_immortal(void)1230*d83cc019SAndroid Build Coastguard Worker static void oom_immortal(void)
1231*d83cc019SAndroid Build Coastguard Worker {
1232*d83cc019SAndroid Build Coastguard Worker 	int fd;
1233*d83cc019SAndroid Build Coastguard Worker 	const char never_kill[] = "-1000";
1234*d83cc019SAndroid Build Coastguard Worker 
1235*d83cc019SAndroid Build Coastguard Worker 	fd = open("/proc/self/oom_score_adj", O_WRONLY);
1236*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0) {
1237*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Warning: Cannot adjust oom score.\n");
1238*d83cc019SAndroid Build Coastguard Worker 		return;
1239*d83cc019SAndroid Build Coastguard Worker 	}
1240*d83cc019SAndroid Build Coastguard Worker 	if (write(fd, never_kill, sizeof(never_kill)) != sizeof(never_kill))
1241*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Warning: Adjusting oom score failed.\n");
1242*d83cc019SAndroid Build Coastguard Worker 
1243*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1244*d83cc019SAndroid Build Coastguard Worker }
1245*d83cc019SAndroid Build Coastguard Worker 
should_die_because_signal(int sigfd)1246*d83cc019SAndroid Build Coastguard Worker static bool should_die_because_signal(int sigfd)
1247*d83cc019SAndroid Build Coastguard Worker {
1248*d83cc019SAndroid Build Coastguard Worker 	struct signalfd_siginfo siginfo;
1249*d83cc019SAndroid Build Coastguard Worker 	int ret;
1250*d83cc019SAndroid Build Coastguard Worker 	struct pollfd sigpoll = { .fd = sigfd, .events = POLLIN | POLLRDBAND };
1251*d83cc019SAndroid Build Coastguard Worker 
1252*d83cc019SAndroid Build Coastguard Worker 	ret = poll(&sigpoll, 1, 0);
1253*d83cc019SAndroid Build Coastguard Worker 
1254*d83cc019SAndroid Build Coastguard Worker 	if (ret != 0) {
1255*d83cc019SAndroid Build Coastguard Worker 		if (ret == -1) {
1256*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Poll on signalfd failed with %s\n", strerror(errno));
1257*d83cc019SAndroid Build Coastguard Worker 			return true; /* something is wrong, let's die */
1258*d83cc019SAndroid Build Coastguard Worker 		}
1259*d83cc019SAndroid Build Coastguard Worker 
1260*d83cc019SAndroid Build Coastguard Worker 		ret = read(sigfd, &siginfo, sizeof(siginfo));
1261*d83cc019SAndroid Build Coastguard Worker 
1262*d83cc019SAndroid Build Coastguard Worker 		if (ret == -1) {
1263*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Error reading from signalfd: %s\n", strerror(errno));
1264*d83cc019SAndroid Build Coastguard Worker 			return false; /* we may want to retry later */
1265*d83cc019SAndroid Build Coastguard Worker 		}
1266*d83cc019SAndroid Build Coastguard Worker 
1267*d83cc019SAndroid Build Coastguard Worker 		if (siginfo.ssi_signo == SIGCHLD) {
1268*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Runner got stray SIGCHLD while not executing any tests.\n");
1269*d83cc019SAndroid Build Coastguard Worker 		} else {
1270*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Runner is being killed by %s\n",
1271*d83cc019SAndroid Build Coastguard Worker 				strsignal(siginfo.ssi_signo));
1272*d83cc019SAndroid Build Coastguard Worker 			return true;
1273*d83cc019SAndroid Build Coastguard Worker 		}
1274*d83cc019SAndroid Build Coastguard Worker 
1275*d83cc019SAndroid Build Coastguard Worker 	}
1276*d83cc019SAndroid Build Coastguard Worker 
1277*d83cc019SAndroid Build Coastguard Worker 	return false;
1278*d83cc019SAndroid Build Coastguard Worker }
1279*d83cc019SAndroid Build Coastguard Worker 
execute(struct execute_state * state,struct settings * settings,struct job_list * job_list)1280*d83cc019SAndroid Build Coastguard Worker bool execute(struct execute_state *state,
1281*d83cc019SAndroid Build Coastguard Worker 	     struct settings *settings,
1282*d83cc019SAndroid Build Coastguard Worker 	     struct job_list *job_list)
1283*d83cc019SAndroid Build Coastguard Worker {
1284*d83cc019SAndroid Build Coastguard Worker 	struct utsname unamebuf;
1285*d83cc019SAndroid Build Coastguard Worker 	int resdirfd, testdirfd, unamefd, timefd;
1286*d83cc019SAndroid Build Coastguard Worker 	sigset_t sigmask;
1287*d83cc019SAndroid Build Coastguard Worker 	int sigfd;
1288*d83cc019SAndroid Build Coastguard Worker 	double time_spent = 0.0;
1289*d83cc019SAndroid Build Coastguard Worker 	bool status = true;
1290*d83cc019SAndroid Build Coastguard Worker 
1291*d83cc019SAndroid Build Coastguard Worker 	if (state->dry) {
1292*d83cc019SAndroid Build Coastguard Worker 		printf("Dry run, not executing. Invoke igt_resume if you want to execute.\n");
1293*d83cc019SAndroid Build Coastguard Worker 		return true;
1294*d83cc019SAndroid Build Coastguard Worker 	}
1295*d83cc019SAndroid Build Coastguard Worker 
1296*d83cc019SAndroid Build Coastguard Worker 	if ((resdirfd = open(settings->results_path, O_DIRECTORY | O_RDONLY)) < 0) {
1297*d83cc019SAndroid Build Coastguard Worker 		/* Initialize state should have done this */
1298*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error: Failure opening results path %s\n",
1299*d83cc019SAndroid Build Coastguard Worker 			settings->results_path);
1300*d83cc019SAndroid Build Coastguard Worker 		return false;
1301*d83cc019SAndroid Build Coastguard Worker 	}
1302*d83cc019SAndroid Build Coastguard Worker 
1303*d83cc019SAndroid Build Coastguard Worker 	if ((testdirfd = open(settings->test_root, O_DIRECTORY | O_RDONLY)) < 0) {
1304*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error: Failure opening test root %s\n",
1305*d83cc019SAndroid Build Coastguard Worker 			settings->test_root);
1306*d83cc019SAndroid Build Coastguard Worker 		close(resdirfd);
1307*d83cc019SAndroid Build Coastguard Worker 		return false;
1308*d83cc019SAndroid Build Coastguard Worker 	}
1309*d83cc019SAndroid Build Coastguard Worker 
1310*d83cc019SAndroid Build Coastguard Worker 	/* TODO: On resume, don't rewrite, verify that content matches current instead */
1311*d83cc019SAndroid Build Coastguard Worker 	if ((unamefd = openat(resdirfd, "uname.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0) {
1312*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error: Failure opening uname.txt: %s\n",
1313*d83cc019SAndroid Build Coastguard Worker 			strerror(errno));
1314*d83cc019SAndroid Build Coastguard Worker 		close(testdirfd);
1315*d83cc019SAndroid Build Coastguard Worker 		close(resdirfd);
1316*d83cc019SAndroid Build Coastguard Worker 		return false;
1317*d83cc019SAndroid Build Coastguard Worker 	}
1318*d83cc019SAndroid Build Coastguard Worker 
1319*d83cc019SAndroid Build Coastguard Worker 	if ((timefd = openat(resdirfd, "starttime.txt", O_CREAT | O_WRONLY | O_EXCL, 0666)) >= 0) {
1320*d83cc019SAndroid Build Coastguard Worker 		/*
1321*d83cc019SAndroid Build Coastguard Worker 		 * Ignore failure to open. If this is a resume, we
1322*d83cc019SAndroid Build Coastguard Worker 		 * don't want to overwrite. For other errors, we
1323*d83cc019SAndroid Build Coastguard Worker 		 * ignore the start time.
1324*d83cc019SAndroid Build Coastguard Worker 		 */
1325*d83cc019SAndroid Build Coastguard Worker 		dprintf(timefd, "%f\n", timeofday_double());
1326*d83cc019SAndroid Build Coastguard Worker 		close(timefd);
1327*d83cc019SAndroid Build Coastguard Worker 	}
1328*d83cc019SAndroid Build Coastguard Worker 
1329*d83cc019SAndroid Build Coastguard Worker 	oom_immortal();
1330*d83cc019SAndroid Build Coastguard Worker 
1331*d83cc019SAndroid Build Coastguard Worker 	sigemptyset(&sigmask);
1332*d83cc019SAndroid Build Coastguard Worker 	sigaddset(&sigmask, SIGCHLD);
1333*d83cc019SAndroid Build Coastguard Worker 	sigaddset(&sigmask, SIGINT);
1334*d83cc019SAndroid Build Coastguard Worker 	sigaddset(&sigmask, SIGTERM);
1335*d83cc019SAndroid Build Coastguard Worker 	sigaddset(&sigmask, SIGQUIT);
1336*d83cc019SAndroid Build Coastguard Worker 	sigaddset(&sigmask, SIGHUP);
1337*d83cc019SAndroid Build Coastguard Worker 	sigfd = signalfd(-1, &sigmask, O_CLOEXEC);
1338*d83cc019SAndroid Build Coastguard Worker 	sigprocmask(SIG_BLOCK, &sigmask, NULL);
1339*d83cc019SAndroid Build Coastguard Worker 
1340*d83cc019SAndroid Build Coastguard Worker 	if (sigfd < 0) {
1341*d83cc019SAndroid Build Coastguard Worker 		/* TODO: Handle better */
1342*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Cannot mask signals\n");
1343*d83cc019SAndroid Build Coastguard Worker 		status = false;
1344*d83cc019SAndroid Build Coastguard Worker 		goto end;
1345*d83cc019SAndroid Build Coastguard Worker 	}
1346*d83cc019SAndroid Build Coastguard Worker 
1347*d83cc019SAndroid Build Coastguard Worker 	init_watchdogs(settings);
1348*d83cc019SAndroid Build Coastguard Worker 
1349*d83cc019SAndroid Build Coastguard Worker 	if (!uname(&unamebuf)) {
1350*d83cc019SAndroid Build Coastguard Worker 		dprintf(unamefd, "%s %s %s %s %s\n",
1351*d83cc019SAndroid Build Coastguard Worker 			unamebuf.sysname,
1352*d83cc019SAndroid Build Coastguard Worker 			unamebuf.nodename,
1353*d83cc019SAndroid Build Coastguard Worker 			unamebuf.release,
1354*d83cc019SAndroid Build Coastguard Worker 			unamebuf.version,
1355*d83cc019SAndroid Build Coastguard Worker 			unamebuf.machine);
1356*d83cc019SAndroid Build Coastguard Worker 	} else {
1357*d83cc019SAndroid Build Coastguard Worker 		dprintf(unamefd, "uname() failed\n");
1358*d83cc019SAndroid Build Coastguard Worker 	}
1359*d83cc019SAndroid Build Coastguard Worker 	close(unamefd);
1360*d83cc019SAndroid Build Coastguard Worker 
1361*d83cc019SAndroid Build Coastguard Worker 	/* Check if we're already in abort-state at bootup */
1362*d83cc019SAndroid Build Coastguard Worker 	if (!state->resuming) {
1363*d83cc019SAndroid Build Coastguard Worker 		char *reason;
1364*d83cc019SAndroid Build Coastguard Worker 
1365*d83cc019SAndroid Build Coastguard Worker 		if ((reason = need_to_abort(settings)) != NULL) {
1366*d83cc019SAndroid Build Coastguard Worker 			char *nexttest = entry_display_name(&job_list->entries[state->next]);
1367*d83cc019SAndroid Build Coastguard Worker 			write_abort_file(resdirfd, reason, "nothing", nexttest);
1368*d83cc019SAndroid Build Coastguard Worker 			free(reason);
1369*d83cc019SAndroid Build Coastguard Worker 			free(nexttest);
1370*d83cc019SAndroid Build Coastguard Worker 
1371*d83cc019SAndroid Build Coastguard Worker 			status = false;
1372*d83cc019SAndroid Build Coastguard Worker 
1373*d83cc019SAndroid Build Coastguard Worker 			goto end;
1374*d83cc019SAndroid Build Coastguard Worker 		}
1375*d83cc019SAndroid Build Coastguard Worker 	}
1376*d83cc019SAndroid Build Coastguard Worker 
1377*d83cc019SAndroid Build Coastguard Worker 	for (; state->next < job_list->size;
1378*d83cc019SAndroid Build Coastguard Worker 	     state->next++) {
1379*d83cc019SAndroid Build Coastguard Worker 		char *reason;
1380*d83cc019SAndroid Build Coastguard Worker 		int result;
1381*d83cc019SAndroid Build Coastguard Worker 
1382*d83cc019SAndroid Build Coastguard Worker 		if (should_die_because_signal(sigfd)) {
1383*d83cc019SAndroid Build Coastguard Worker 			status = false;
1384*d83cc019SAndroid Build Coastguard Worker 			goto end;
1385*d83cc019SAndroid Build Coastguard Worker 		}
1386*d83cc019SAndroid Build Coastguard Worker 
1387*d83cc019SAndroid Build Coastguard Worker 		result = execute_next_entry(state,
1388*d83cc019SAndroid Build Coastguard Worker 					    job_list->size,
1389*d83cc019SAndroid Build Coastguard Worker 					    &time_spent,
1390*d83cc019SAndroid Build Coastguard Worker 					    settings,
1391*d83cc019SAndroid Build Coastguard Worker 					    &job_list->entries[state->next],
1392*d83cc019SAndroid Build Coastguard Worker 					    testdirfd, resdirfd,
1393*d83cc019SAndroid Build Coastguard Worker 					    sigfd, &sigmask);
1394*d83cc019SAndroid Build Coastguard Worker 
1395*d83cc019SAndroid Build Coastguard Worker 		if (result < 0) {
1396*d83cc019SAndroid Build Coastguard Worker 			status = false;
1397*d83cc019SAndroid Build Coastguard Worker 			break;
1398*d83cc019SAndroid Build Coastguard Worker 		}
1399*d83cc019SAndroid Build Coastguard Worker 
1400*d83cc019SAndroid Build Coastguard Worker 		reduce_time_left(settings, state, time_spent);
1401*d83cc019SAndroid Build Coastguard Worker 
1402*d83cc019SAndroid Build Coastguard Worker 		if (overall_timeout_exceeded(state)) {
1403*d83cc019SAndroid Build Coastguard Worker 			if (settings->log_level >= LOG_LEVEL_NORMAL) {
1404*d83cc019SAndroid Build Coastguard Worker 				printf("Overall timeout time exceeded, stopping.\n");
1405*d83cc019SAndroid Build Coastguard Worker 			}
1406*d83cc019SAndroid Build Coastguard Worker 
1407*d83cc019SAndroid Build Coastguard Worker 			break;
1408*d83cc019SAndroid Build Coastguard Worker 		}
1409*d83cc019SAndroid Build Coastguard Worker 
1410*d83cc019SAndroid Build Coastguard Worker 		if ((reason = need_to_abort(settings)) != NULL) {
1411*d83cc019SAndroid Build Coastguard Worker 			char *prev = entry_display_name(&job_list->entries[state->next]);
1412*d83cc019SAndroid Build Coastguard Worker 			char *next = (state->next + 1 < job_list->size ?
1413*d83cc019SAndroid Build Coastguard Worker 				      entry_display_name(&job_list->entries[state->next + 1]) :
1414*d83cc019SAndroid Build Coastguard Worker 				      strdup("nothing"));
1415*d83cc019SAndroid Build Coastguard Worker 			write_abort_file(resdirfd, reason, prev, next);
1416*d83cc019SAndroid Build Coastguard Worker 			free(prev);
1417*d83cc019SAndroid Build Coastguard Worker 			free(next);
1418*d83cc019SAndroid Build Coastguard Worker 			free(reason);
1419*d83cc019SAndroid Build Coastguard Worker 			status = false;
1420*d83cc019SAndroid Build Coastguard Worker 			break;
1421*d83cc019SAndroid Build Coastguard Worker 		}
1422*d83cc019SAndroid Build Coastguard Worker 
1423*d83cc019SAndroid Build Coastguard Worker 		if (result > 0) {
1424*d83cc019SAndroid Build Coastguard Worker 			double time_left = state->time_left;
1425*d83cc019SAndroid Build Coastguard Worker 
1426*d83cc019SAndroid Build Coastguard Worker 			close_watchdogs(settings);
1427*d83cc019SAndroid Build Coastguard Worker 			sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
1428*d83cc019SAndroid Build Coastguard Worker 			/* make sure that we do not leave any signals unhandled */
1429*d83cc019SAndroid Build Coastguard Worker 			if (should_die_because_signal(sigfd)) {
1430*d83cc019SAndroid Build Coastguard Worker 				status = false;
1431*d83cc019SAndroid Build Coastguard Worker 				goto end_post_signal_restore;
1432*d83cc019SAndroid Build Coastguard Worker 			}
1433*d83cc019SAndroid Build Coastguard Worker 			close(sigfd);
1434*d83cc019SAndroid Build Coastguard Worker 			close(testdirfd);
1435*d83cc019SAndroid Build Coastguard Worker 			initialize_execute_state_from_resume(resdirfd, state, settings, job_list);
1436*d83cc019SAndroid Build Coastguard Worker 			state->time_left = time_left;
1437*d83cc019SAndroid Build Coastguard Worker 			return execute(state, settings, job_list);
1438*d83cc019SAndroid Build Coastguard Worker 		}
1439*d83cc019SAndroid Build Coastguard Worker 	}
1440*d83cc019SAndroid Build Coastguard Worker 
1441*d83cc019SAndroid Build Coastguard Worker 	if ((timefd = openat(resdirfd, "endtime.txt", O_CREAT | O_WRONLY | O_EXCL, 0666)) >= 0) {
1442*d83cc019SAndroid Build Coastguard Worker 		dprintf(timefd, "%f\n", timeofday_double());
1443*d83cc019SAndroid Build Coastguard Worker 		close(timefd);
1444*d83cc019SAndroid Build Coastguard Worker 	}
1445*d83cc019SAndroid Build Coastguard Worker 
1446*d83cc019SAndroid Build Coastguard Worker  end:
1447*d83cc019SAndroid Build Coastguard Worker 	close_watchdogs(settings);
1448*d83cc019SAndroid Build Coastguard Worker 	sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
1449*d83cc019SAndroid Build Coastguard Worker 	/* make sure that we do not leave any signals unhandled */
1450*d83cc019SAndroid Build Coastguard Worker 	if (should_die_because_signal(sigfd))
1451*d83cc019SAndroid Build Coastguard Worker 		status = false;
1452*d83cc019SAndroid Build Coastguard Worker  end_post_signal_restore:
1453*d83cc019SAndroid Build Coastguard Worker 	close(sigfd);
1454*d83cc019SAndroid Build Coastguard Worker 	close(testdirfd);
1455*d83cc019SAndroid Build Coastguard Worker 	close(resdirfd);
1456*d83cc019SAndroid Build Coastguard Worker 	return status;
1457*d83cc019SAndroid Build Coastguard Worker }
1458