1*d83cc019SAndroid Build Coastguard Worker #include "settings.h"
2*d83cc019SAndroid Build Coastguard Worker
3*d83cc019SAndroid Build Coastguard Worker #include <ctype.h>
4*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
5*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
6*d83cc019SAndroid Build Coastguard Worker #include <getopt.h>
7*d83cc019SAndroid Build Coastguard Worker #include <libgen.h>
8*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
9*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
10*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
11*d83cc019SAndroid Build Coastguard Worker #include <string.h>
12*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
13*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
14*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
15*d83cc019SAndroid Build Coastguard Worker
16*d83cc019SAndroid Build Coastguard Worker enum {
17*d83cc019SAndroid Build Coastguard Worker OPT_ABORT_ON_ERROR,
18*d83cc019SAndroid Build Coastguard Worker OPT_TEST_LIST,
19*d83cc019SAndroid Build Coastguard Worker OPT_IGNORE_MISSING,
20*d83cc019SAndroid Build Coastguard Worker OPT_PIGLIT_DMESG,
21*d83cc019SAndroid Build Coastguard Worker OPT_DMESG_WARN_LEVEL,
22*d83cc019SAndroid Build Coastguard Worker OPT_OVERALL_TIMEOUT,
23*d83cc019SAndroid Build Coastguard Worker OPT_HELP = 'h',
24*d83cc019SAndroid Build Coastguard Worker OPT_NAME = 'n',
25*d83cc019SAndroid Build Coastguard Worker OPT_DRY_RUN = 'd',
26*d83cc019SAndroid Build Coastguard Worker OPT_INCLUDE = 't',
27*d83cc019SAndroid Build Coastguard Worker OPT_EXCLUDE = 'x',
28*d83cc019SAndroid Build Coastguard Worker OPT_SYNC = 's',
29*d83cc019SAndroid Build Coastguard Worker OPT_LOG_LEVEL = 'l',
30*d83cc019SAndroid Build Coastguard Worker OPT_OVERWRITE = 'o',
31*d83cc019SAndroid Build Coastguard Worker OPT_MULTIPLE = 'm',
32*d83cc019SAndroid Build Coastguard Worker OPT_TIMEOUT = 'c',
33*d83cc019SAndroid Build Coastguard Worker OPT_WATCHDOG = 'g',
34*d83cc019SAndroid Build Coastguard Worker OPT_BLACKLIST = 'b',
35*d83cc019SAndroid Build Coastguard Worker OPT_LIST_ALL = 'L',
36*d83cc019SAndroid Build Coastguard Worker };
37*d83cc019SAndroid Build Coastguard Worker
38*d83cc019SAndroid Build Coastguard Worker static struct {
39*d83cc019SAndroid Build Coastguard Worker int level;
40*d83cc019SAndroid Build Coastguard Worker const char *name;
41*d83cc019SAndroid Build Coastguard Worker } log_levels[] = {
42*d83cc019SAndroid Build Coastguard Worker { LOG_LEVEL_NORMAL, "normal" },
43*d83cc019SAndroid Build Coastguard Worker { LOG_LEVEL_QUIET, "quiet" },
44*d83cc019SAndroid Build Coastguard Worker { LOG_LEVEL_VERBOSE, "verbose" },
45*d83cc019SAndroid Build Coastguard Worker { 0, 0 },
46*d83cc019SAndroid Build Coastguard Worker };
47*d83cc019SAndroid Build Coastguard Worker
48*d83cc019SAndroid Build Coastguard Worker static struct {
49*d83cc019SAndroid Build Coastguard Worker int value;
50*d83cc019SAndroid Build Coastguard Worker const char *name;
51*d83cc019SAndroid Build Coastguard Worker } abort_conditions[] = {
52*d83cc019SAndroid Build Coastguard Worker { ABORT_TAINT, "taint" },
53*d83cc019SAndroid Build Coastguard Worker { ABORT_LOCKDEP, "lockdep" },
54*d83cc019SAndroid Build Coastguard Worker { ABORT_ALL, "all" },
55*d83cc019SAndroid Build Coastguard Worker { 0, 0 },
56*d83cc019SAndroid Build Coastguard Worker };
57*d83cc019SAndroid Build Coastguard Worker
set_log_level(struct settings * settings,const char * level)58*d83cc019SAndroid Build Coastguard Worker static bool set_log_level(struct settings* settings, const char *level)
59*d83cc019SAndroid Build Coastguard Worker {
60*d83cc019SAndroid Build Coastguard Worker typeof(*log_levels) *it;
61*d83cc019SAndroid Build Coastguard Worker
62*d83cc019SAndroid Build Coastguard Worker for (it = log_levels; it->name; it++) {
63*d83cc019SAndroid Build Coastguard Worker if (!strcmp(level, it->name)) {
64*d83cc019SAndroid Build Coastguard Worker settings->log_level = it->level;
65*d83cc019SAndroid Build Coastguard Worker return true;
66*d83cc019SAndroid Build Coastguard Worker }
67*d83cc019SAndroid Build Coastguard Worker }
68*d83cc019SAndroid Build Coastguard Worker
69*d83cc019SAndroid Build Coastguard Worker return false;
70*d83cc019SAndroid Build Coastguard Worker }
71*d83cc019SAndroid Build Coastguard Worker
set_abort_condition(struct settings * settings,const char * cond)72*d83cc019SAndroid Build Coastguard Worker static bool set_abort_condition(struct settings* settings, const char *cond)
73*d83cc019SAndroid Build Coastguard Worker {
74*d83cc019SAndroid Build Coastguard Worker typeof(*abort_conditions) *it;
75*d83cc019SAndroid Build Coastguard Worker
76*d83cc019SAndroid Build Coastguard Worker if (!cond) {
77*d83cc019SAndroid Build Coastguard Worker settings->abort_mask = ABORT_ALL;
78*d83cc019SAndroid Build Coastguard Worker return true;
79*d83cc019SAndroid Build Coastguard Worker }
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker if (strlen(cond) == 0) {
82*d83cc019SAndroid Build Coastguard Worker settings->abort_mask = 0;
83*d83cc019SAndroid Build Coastguard Worker return true;
84*d83cc019SAndroid Build Coastguard Worker }
85*d83cc019SAndroid Build Coastguard Worker
86*d83cc019SAndroid Build Coastguard Worker for (it = abort_conditions; it->name; it++) {
87*d83cc019SAndroid Build Coastguard Worker if (!strcmp(cond, it->name)) {
88*d83cc019SAndroid Build Coastguard Worker settings->abort_mask |= it->value;
89*d83cc019SAndroid Build Coastguard Worker return true;
90*d83cc019SAndroid Build Coastguard Worker }
91*d83cc019SAndroid Build Coastguard Worker }
92*d83cc019SAndroid Build Coastguard Worker
93*d83cc019SAndroid Build Coastguard Worker return false;
94*d83cc019SAndroid Build Coastguard Worker }
95*d83cc019SAndroid Build Coastguard Worker
parse_abort_conditions(struct settings * settings,const char * optarg)96*d83cc019SAndroid Build Coastguard Worker static bool parse_abort_conditions(struct settings *settings, const char *optarg)
97*d83cc019SAndroid Build Coastguard Worker {
98*d83cc019SAndroid Build Coastguard Worker char *dup, *origdup, *p;
99*d83cc019SAndroid Build Coastguard Worker if (!optarg)
100*d83cc019SAndroid Build Coastguard Worker return set_abort_condition(settings, NULL);
101*d83cc019SAndroid Build Coastguard Worker
102*d83cc019SAndroid Build Coastguard Worker origdup = dup = strdup(optarg);
103*d83cc019SAndroid Build Coastguard Worker while (dup) {
104*d83cc019SAndroid Build Coastguard Worker if ((p = strchr(dup, ',')) != NULL) {
105*d83cc019SAndroid Build Coastguard Worker *p = '\0';
106*d83cc019SAndroid Build Coastguard Worker p++;
107*d83cc019SAndroid Build Coastguard Worker }
108*d83cc019SAndroid Build Coastguard Worker
109*d83cc019SAndroid Build Coastguard Worker if (!set_abort_condition(settings, dup)) {
110*d83cc019SAndroid Build Coastguard Worker free(origdup);
111*d83cc019SAndroid Build Coastguard Worker return false;
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker
114*d83cc019SAndroid Build Coastguard Worker dup = p;
115*d83cc019SAndroid Build Coastguard Worker }
116*d83cc019SAndroid Build Coastguard Worker
117*d83cc019SAndroid Build Coastguard Worker free(origdup);
118*d83cc019SAndroid Build Coastguard Worker
119*d83cc019SAndroid Build Coastguard Worker return true;
120*d83cc019SAndroid Build Coastguard Worker }
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker static const char *usage_str =
123*d83cc019SAndroid Build Coastguard Worker "usage: runner [options] [test_root] results-path\n"
124*d83cc019SAndroid Build Coastguard Worker " or: runner --list-all [options] [test_root]\n\n"
125*d83cc019SAndroid Build Coastguard Worker "Options:\n"
126*d83cc019SAndroid Build Coastguard Worker " Piglit compatible:\n"
127*d83cc019SAndroid Build Coastguard Worker " -h, --help Show this help message and exit\n"
128*d83cc019SAndroid Build Coastguard Worker " -n <test name>, --name <test name>\n"
129*d83cc019SAndroid Build Coastguard Worker " Name of this test run\n"
130*d83cc019SAndroid Build Coastguard Worker " -d, --dry-run Do not execute the tests\n"
131*d83cc019SAndroid Build Coastguard Worker " -t <regex>, --include-tests <regex>\n"
132*d83cc019SAndroid Build Coastguard Worker " Run only matching tests (can be used more than once)\n"
133*d83cc019SAndroid Build Coastguard Worker " -x <regex>, --exclude-tests <regex>\n"
134*d83cc019SAndroid Build Coastguard Worker " Exclude matching tests (can be used more than once)\n"
135*d83cc019SAndroid Build Coastguard Worker " --abort-on-monitored-error[=list]\n"
136*d83cc019SAndroid Build Coastguard Worker " Abort execution when a fatal condition is detected.\n"
137*d83cc019SAndroid Build Coastguard Worker " A comma-separated list of conditions to check can be\n"
138*d83cc019SAndroid Build Coastguard Worker " given. If not given, all conditions are checked. An\n"
139*d83cc019SAndroid Build Coastguard Worker " empty string as a condition disables aborting\n"
140*d83cc019SAndroid Build Coastguard Worker " Possible conditions:\n"
141*d83cc019SAndroid Build Coastguard Worker " lockdep - abort when kernel lockdep has been angered.\n"
142*d83cc019SAndroid Build Coastguard Worker " taint - abort when kernel becomes fatally tainted.\n"
143*d83cc019SAndroid Build Coastguard Worker " all - abort for all of the above.\n"
144*d83cc019SAndroid Build Coastguard Worker " -s, --sync Sync results to disk after every test\n"
145*d83cc019SAndroid Build Coastguard Worker " -l {quiet,verbose,dummy}, --log-level {quiet,verbose,dummy}\n"
146*d83cc019SAndroid Build Coastguard Worker " Set the logger verbosity level\n"
147*d83cc019SAndroid Build Coastguard Worker " --test-list TEST_LIST\n"
148*d83cc019SAndroid Build Coastguard Worker " A file containing a list of tests to run\n"
149*d83cc019SAndroid Build Coastguard Worker " -o, --overwrite If the results-path already exists, delete it\n"
150*d83cc019SAndroid Build Coastguard Worker " --ignore-missing Ignored but accepted, for piglit compatibility\n"
151*d83cc019SAndroid Build Coastguard Worker "\n"
152*d83cc019SAndroid Build Coastguard Worker " Incompatible options:\n"
153*d83cc019SAndroid Build Coastguard Worker " -m, --multiple-mode Run multiple subtests in the same binary execution.\n"
154*d83cc019SAndroid Build Coastguard Worker " If a testlist file is given, consecutive subtests are\n"
155*d83cc019SAndroid Build Coastguard Worker " run in the same execution if they are from the same\n"
156*d83cc019SAndroid Build Coastguard Worker " binary. Note that in that case relative ordering of the\n"
157*d83cc019SAndroid Build Coastguard Worker " subtest execution is dictated by the test binary, not\n"
158*d83cc019SAndroid Build Coastguard Worker " the testlist\n"
159*d83cc019SAndroid Build Coastguard Worker " --inactivity-timeout <seconds>\n"
160*d83cc019SAndroid Build Coastguard Worker " Kill the running test after <seconds> of inactivity in\n"
161*d83cc019SAndroid Build Coastguard Worker " the test's stdout, stderr, or dmesg\n"
162*d83cc019SAndroid Build Coastguard Worker " --overall-timeout <seconds>\n"
163*d83cc019SAndroid Build Coastguard Worker " Don't execute more tests after <seconds> has elapsed\n"
164*d83cc019SAndroid Build Coastguard Worker " --use-watchdog Use hardware watchdog for lethal enforcement of the\n"
165*d83cc019SAndroid Build Coastguard Worker " above timeout. Killing the test process is still\n"
166*d83cc019SAndroid Build Coastguard Worker " attempted at timeout trigger.\n"
167*d83cc019SAndroid Build Coastguard Worker " --dmesg-warn-level <level>\n"
168*d83cc019SAndroid Build Coastguard Worker " Messages with log level equal or lower (more serious)\n"
169*d83cc019SAndroid Build Coastguard Worker " to the given one will override the test result to\n"
170*d83cc019SAndroid Build Coastguard Worker " dmesg-warn/dmesg-fail, assuming they go through filtering.\n"
171*d83cc019SAndroid Build Coastguard Worker " Defaults to 4 (KERN_WARNING).\n"
172*d83cc019SAndroid Build Coastguard Worker " --piglit-style-dmesg Filter dmesg like piglit does. Piglit considers matches\n"
173*d83cc019SAndroid Build Coastguard Worker " against a short filter list to mean the test result\n"
174*d83cc019SAndroid Build Coastguard Worker " should be changed to dmesg-warn/dmesg-fail. Without\n"
175*d83cc019SAndroid Build Coastguard Worker " this option everything except matches against a\n"
176*d83cc019SAndroid Build Coastguard Worker " (longer) filter list means the test result should\n"
177*d83cc019SAndroid Build Coastguard Worker " change. KERN_NOTICE dmesg level is treated as warn,\n"
178*d83cc019SAndroid Build Coastguard Worker " unless overridden with --dmesg-warn-level.\n"
179*d83cc019SAndroid Build Coastguard Worker " -b, --blacklist FILENAME\n"
180*d83cc019SAndroid Build Coastguard Worker " Exclude all test matching to regexes from FILENAME\n"
181*d83cc019SAndroid Build Coastguard Worker " (can be used more than once)\n"
182*d83cc019SAndroid Build Coastguard Worker " -L, --list-all List all matching subtests instead of running\n"
183*d83cc019SAndroid Build Coastguard Worker " [test_root] Directory that contains the IGT tests. The environment\n"
184*d83cc019SAndroid Build Coastguard Worker " variable IGT_TEST_ROOT will be used if set, overriding\n"
185*d83cc019SAndroid Build Coastguard Worker " this option if given.\n"
186*d83cc019SAndroid Build Coastguard Worker ;
187*d83cc019SAndroid Build Coastguard Worker
usage(const char * extra_message,FILE * f)188*d83cc019SAndroid Build Coastguard Worker static void usage(const char *extra_message, FILE *f)
189*d83cc019SAndroid Build Coastguard Worker {
190*d83cc019SAndroid Build Coastguard Worker if (extra_message)
191*d83cc019SAndroid Build Coastguard Worker fprintf(f, "%s\n\n", extra_message);
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker fputs(usage_str, f);
194*d83cc019SAndroid Build Coastguard Worker }
195*d83cc019SAndroid Build Coastguard Worker
add_regex(struct regex_list * list,char * new)196*d83cc019SAndroid Build Coastguard Worker static bool add_regex(struct regex_list *list, char *new)
197*d83cc019SAndroid Build Coastguard Worker {
198*d83cc019SAndroid Build Coastguard Worker GRegex *regex;
199*d83cc019SAndroid Build Coastguard Worker GError *error = NULL;
200*d83cc019SAndroid Build Coastguard Worker
201*d83cc019SAndroid Build Coastguard Worker regex = g_regex_new(new, G_REGEX_OPTIMIZE, 0, &error);
202*d83cc019SAndroid Build Coastguard Worker if (error) {
203*d83cc019SAndroid Build Coastguard Worker char *buf = malloc(snprintf(NULL, 0, "Invalid regex '%s': %s", new, error->message) + 1);
204*d83cc019SAndroid Build Coastguard Worker
205*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "Invalid regex '%s': %s", new, error->message);
206*d83cc019SAndroid Build Coastguard Worker usage(buf, stderr);
207*d83cc019SAndroid Build Coastguard Worker
208*d83cc019SAndroid Build Coastguard Worker free(buf);
209*d83cc019SAndroid Build Coastguard Worker g_error_free(error);
210*d83cc019SAndroid Build Coastguard Worker return false;
211*d83cc019SAndroid Build Coastguard Worker }
212*d83cc019SAndroid Build Coastguard Worker
213*d83cc019SAndroid Build Coastguard Worker list->regexes = realloc(list->regexes,
214*d83cc019SAndroid Build Coastguard Worker (list->size + 1) * sizeof(*list->regexes));
215*d83cc019SAndroid Build Coastguard Worker list->regex_strings = realloc(list->regex_strings,
216*d83cc019SAndroid Build Coastguard Worker (list->size + 1) * sizeof(*list->regex_strings));
217*d83cc019SAndroid Build Coastguard Worker list->regexes[list->size] = regex;
218*d83cc019SAndroid Build Coastguard Worker list->regex_strings[list->size] = new;
219*d83cc019SAndroid Build Coastguard Worker list->size++;
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker return true;
222*d83cc019SAndroid Build Coastguard Worker }
223*d83cc019SAndroid Build Coastguard Worker
parse_blacklist(struct regex_list * exclude_regexes,char * blacklist_filename)224*d83cc019SAndroid Build Coastguard Worker static bool parse_blacklist(struct regex_list *exclude_regexes,
225*d83cc019SAndroid Build Coastguard Worker char *blacklist_filename)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker FILE *f;
228*d83cc019SAndroid Build Coastguard Worker char *line = NULL;
229*d83cc019SAndroid Build Coastguard Worker size_t line_len = 0;
230*d83cc019SAndroid Build Coastguard Worker bool status = false;
231*d83cc019SAndroid Build Coastguard Worker
232*d83cc019SAndroid Build Coastguard Worker if ((f = fopen(blacklist_filename, "r")) == NULL) {
233*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Cannot open blacklist file %s\n", blacklist_filename);
234*d83cc019SAndroid Build Coastguard Worker return false;
235*d83cc019SAndroid Build Coastguard Worker }
236*d83cc019SAndroid Build Coastguard Worker while (1) {
237*d83cc019SAndroid Build Coastguard Worker size_t str_size = 0, idx = 0;
238*d83cc019SAndroid Build Coastguard Worker
239*d83cc019SAndroid Build Coastguard Worker if (getline(&line, &line_len, f) == -1) {
240*d83cc019SAndroid Build Coastguard Worker if (errno == EINTR)
241*d83cc019SAndroid Build Coastguard Worker continue;
242*d83cc019SAndroid Build Coastguard Worker else
243*d83cc019SAndroid Build Coastguard Worker break;
244*d83cc019SAndroid Build Coastguard Worker }
245*d83cc019SAndroid Build Coastguard Worker
246*d83cc019SAndroid Build Coastguard Worker while (true) {
247*d83cc019SAndroid Build Coastguard Worker if (line[idx] == '\n' ||
248*d83cc019SAndroid Build Coastguard Worker line[idx] == '\0' ||
249*d83cc019SAndroid Build Coastguard Worker line[idx] == '#') /* # starts a comment */
250*d83cc019SAndroid Build Coastguard Worker break;
251*d83cc019SAndroid Build Coastguard Worker if (!isspace(line[idx]))
252*d83cc019SAndroid Build Coastguard Worker str_size = idx + 1;
253*d83cc019SAndroid Build Coastguard Worker idx++;
254*d83cc019SAndroid Build Coastguard Worker }
255*d83cc019SAndroid Build Coastguard Worker if (str_size > 0) {
256*d83cc019SAndroid Build Coastguard Worker char *test_regex = strndup(line, str_size);
257*d83cc019SAndroid Build Coastguard Worker
258*d83cc019SAndroid Build Coastguard Worker status = add_regex(exclude_regexes, test_regex);
259*d83cc019SAndroid Build Coastguard Worker if (!status)
260*d83cc019SAndroid Build Coastguard Worker break;
261*d83cc019SAndroid Build Coastguard Worker }
262*d83cc019SAndroid Build Coastguard Worker }
263*d83cc019SAndroid Build Coastguard Worker
264*d83cc019SAndroid Build Coastguard Worker free(line);
265*d83cc019SAndroid Build Coastguard Worker fclose(f);
266*d83cc019SAndroid Build Coastguard Worker return status;
267*d83cc019SAndroid Build Coastguard Worker }
268*d83cc019SAndroid Build Coastguard Worker
free_regexes(struct regex_list * regexes)269*d83cc019SAndroid Build Coastguard Worker static void free_regexes(struct regex_list *regexes)
270*d83cc019SAndroid Build Coastguard Worker {
271*d83cc019SAndroid Build Coastguard Worker size_t i;
272*d83cc019SAndroid Build Coastguard Worker
273*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < regexes->size; i++) {
274*d83cc019SAndroid Build Coastguard Worker free(regexes->regex_strings[i]);
275*d83cc019SAndroid Build Coastguard Worker g_regex_unref(regexes->regexes[i]);
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker free(regexes->regex_strings);
278*d83cc019SAndroid Build Coastguard Worker free(regexes->regexes);
279*d83cc019SAndroid Build Coastguard Worker }
280*d83cc019SAndroid Build Coastguard Worker
readable_file(char * filename)281*d83cc019SAndroid Build Coastguard Worker static bool readable_file(char *filename)
282*d83cc019SAndroid Build Coastguard Worker {
283*d83cc019SAndroid Build Coastguard Worker return !access(filename, R_OK);
284*d83cc019SAndroid Build Coastguard Worker }
285*d83cc019SAndroid Build Coastguard Worker
init_settings(struct settings * settings)286*d83cc019SAndroid Build Coastguard Worker void init_settings(struct settings *settings)
287*d83cc019SAndroid Build Coastguard Worker {
288*d83cc019SAndroid Build Coastguard Worker memset(settings, 0, sizeof(*settings));
289*d83cc019SAndroid Build Coastguard Worker }
290*d83cc019SAndroid Build Coastguard Worker
free_settings(struct settings * settings)291*d83cc019SAndroid Build Coastguard Worker void free_settings(struct settings *settings)
292*d83cc019SAndroid Build Coastguard Worker {
293*d83cc019SAndroid Build Coastguard Worker free(settings->test_list);
294*d83cc019SAndroid Build Coastguard Worker free(settings->name);
295*d83cc019SAndroid Build Coastguard Worker free(settings->test_root);
296*d83cc019SAndroid Build Coastguard Worker free(settings->results_path);
297*d83cc019SAndroid Build Coastguard Worker
298*d83cc019SAndroid Build Coastguard Worker free_regexes(&settings->include_regexes);
299*d83cc019SAndroid Build Coastguard Worker free_regexes(&settings->exclude_regexes);
300*d83cc019SAndroid Build Coastguard Worker
301*d83cc019SAndroid Build Coastguard Worker init_settings(settings);
302*d83cc019SAndroid Build Coastguard Worker }
303*d83cc019SAndroid Build Coastguard Worker
parse_options(int argc,char ** argv,struct settings * settings)304*d83cc019SAndroid Build Coastguard Worker bool parse_options(int argc, char **argv,
305*d83cc019SAndroid Build Coastguard Worker struct settings *settings)
306*d83cc019SAndroid Build Coastguard Worker {
307*d83cc019SAndroid Build Coastguard Worker int c;
308*d83cc019SAndroid Build Coastguard Worker char *env_test_root;
309*d83cc019SAndroid Build Coastguard Worker
310*d83cc019SAndroid Build Coastguard Worker static struct option long_options[] = {
311*d83cc019SAndroid Build Coastguard Worker {"help", no_argument, NULL, OPT_HELP},
312*d83cc019SAndroid Build Coastguard Worker {"name", required_argument, NULL, OPT_NAME},
313*d83cc019SAndroid Build Coastguard Worker {"dry-run", no_argument, NULL, OPT_DRY_RUN},
314*d83cc019SAndroid Build Coastguard Worker {"include-tests", required_argument, NULL, OPT_INCLUDE},
315*d83cc019SAndroid Build Coastguard Worker {"exclude-tests", required_argument, NULL, OPT_EXCLUDE},
316*d83cc019SAndroid Build Coastguard Worker {"abort-on-monitored-error", optional_argument, NULL, OPT_ABORT_ON_ERROR},
317*d83cc019SAndroid Build Coastguard Worker {"sync", no_argument, NULL, OPT_SYNC},
318*d83cc019SAndroid Build Coastguard Worker {"log-level", required_argument, NULL, OPT_LOG_LEVEL},
319*d83cc019SAndroid Build Coastguard Worker {"test-list", required_argument, NULL, OPT_TEST_LIST},
320*d83cc019SAndroid Build Coastguard Worker {"overwrite", no_argument, NULL, OPT_OVERWRITE},
321*d83cc019SAndroid Build Coastguard Worker {"ignore-missing", no_argument, NULL, OPT_IGNORE_MISSING},
322*d83cc019SAndroid Build Coastguard Worker {"multiple-mode", no_argument, NULL, OPT_MULTIPLE},
323*d83cc019SAndroid Build Coastguard Worker {"inactivity-timeout", required_argument, NULL, OPT_TIMEOUT},
324*d83cc019SAndroid Build Coastguard Worker {"overall-timeout", required_argument, NULL, OPT_OVERALL_TIMEOUT},
325*d83cc019SAndroid Build Coastguard Worker {"use-watchdog", no_argument, NULL, OPT_WATCHDOG},
326*d83cc019SAndroid Build Coastguard Worker {"piglit-style-dmesg", no_argument, NULL, OPT_PIGLIT_DMESG},
327*d83cc019SAndroid Build Coastguard Worker {"dmesg-warn-level", required_argument, NULL, OPT_DMESG_WARN_LEVEL},
328*d83cc019SAndroid Build Coastguard Worker {"blacklist", required_argument, NULL, OPT_BLACKLIST},
329*d83cc019SAndroid Build Coastguard Worker {"list-all", no_argument, NULL, OPT_LIST_ALL},
330*d83cc019SAndroid Build Coastguard Worker { 0, 0, 0, 0},
331*d83cc019SAndroid Build Coastguard Worker };
332*d83cc019SAndroid Build Coastguard Worker
333*d83cc019SAndroid Build Coastguard Worker free_settings(settings);
334*d83cc019SAndroid Build Coastguard Worker
335*d83cc019SAndroid Build Coastguard Worker optind = 1;
336*d83cc019SAndroid Build Coastguard Worker
337*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = -1;
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker while ((c = getopt_long(argc, argv, "hn:dt:x:sl:omb:L",
340*d83cc019SAndroid Build Coastguard Worker long_options, NULL)) != -1) {
341*d83cc019SAndroid Build Coastguard Worker switch (c) {
342*d83cc019SAndroid Build Coastguard Worker case OPT_HELP:
343*d83cc019SAndroid Build Coastguard Worker usage(NULL, stdout);
344*d83cc019SAndroid Build Coastguard Worker goto error;
345*d83cc019SAndroid Build Coastguard Worker case OPT_NAME:
346*d83cc019SAndroid Build Coastguard Worker settings->name = strdup(optarg);
347*d83cc019SAndroid Build Coastguard Worker break;
348*d83cc019SAndroid Build Coastguard Worker case OPT_DRY_RUN:
349*d83cc019SAndroid Build Coastguard Worker settings->dry_run = true;
350*d83cc019SAndroid Build Coastguard Worker break;
351*d83cc019SAndroid Build Coastguard Worker case OPT_INCLUDE:
352*d83cc019SAndroid Build Coastguard Worker if (!add_regex(&settings->include_regexes, strdup(optarg)))
353*d83cc019SAndroid Build Coastguard Worker goto error;
354*d83cc019SAndroid Build Coastguard Worker break;
355*d83cc019SAndroid Build Coastguard Worker case OPT_EXCLUDE:
356*d83cc019SAndroid Build Coastguard Worker if (!add_regex(&settings->exclude_regexes, strdup(optarg)))
357*d83cc019SAndroid Build Coastguard Worker goto error;
358*d83cc019SAndroid Build Coastguard Worker break;
359*d83cc019SAndroid Build Coastguard Worker case OPT_ABORT_ON_ERROR:
360*d83cc019SAndroid Build Coastguard Worker if (!parse_abort_conditions(settings, optarg))
361*d83cc019SAndroid Build Coastguard Worker goto error;
362*d83cc019SAndroid Build Coastguard Worker break;
363*d83cc019SAndroid Build Coastguard Worker case OPT_SYNC:
364*d83cc019SAndroid Build Coastguard Worker settings->sync = true;
365*d83cc019SAndroid Build Coastguard Worker break;
366*d83cc019SAndroid Build Coastguard Worker case OPT_LOG_LEVEL:
367*d83cc019SAndroid Build Coastguard Worker if (!set_log_level(settings, optarg)) {
368*d83cc019SAndroid Build Coastguard Worker usage("Cannot parse log level", stderr);
369*d83cc019SAndroid Build Coastguard Worker goto error;
370*d83cc019SAndroid Build Coastguard Worker }
371*d83cc019SAndroid Build Coastguard Worker break;
372*d83cc019SAndroid Build Coastguard Worker case OPT_TEST_LIST:
373*d83cc019SAndroid Build Coastguard Worker settings->test_list = absolute_path(optarg);
374*d83cc019SAndroid Build Coastguard Worker break;
375*d83cc019SAndroid Build Coastguard Worker case OPT_OVERWRITE:
376*d83cc019SAndroid Build Coastguard Worker settings->overwrite = true;
377*d83cc019SAndroid Build Coastguard Worker break;
378*d83cc019SAndroid Build Coastguard Worker case OPT_IGNORE_MISSING:
379*d83cc019SAndroid Build Coastguard Worker /* Ignored, piglit compatibility */
380*d83cc019SAndroid Build Coastguard Worker break;
381*d83cc019SAndroid Build Coastguard Worker case OPT_MULTIPLE:
382*d83cc019SAndroid Build Coastguard Worker settings->multiple_mode = true;
383*d83cc019SAndroid Build Coastguard Worker break;
384*d83cc019SAndroid Build Coastguard Worker case OPT_TIMEOUT:
385*d83cc019SAndroid Build Coastguard Worker settings->inactivity_timeout = atoi(optarg);
386*d83cc019SAndroid Build Coastguard Worker break;
387*d83cc019SAndroid Build Coastguard Worker case OPT_OVERALL_TIMEOUT:
388*d83cc019SAndroid Build Coastguard Worker settings->overall_timeout = atoi(optarg);
389*d83cc019SAndroid Build Coastguard Worker break;
390*d83cc019SAndroid Build Coastguard Worker case OPT_WATCHDOG:
391*d83cc019SAndroid Build Coastguard Worker settings->use_watchdog = true;
392*d83cc019SAndroid Build Coastguard Worker break;
393*d83cc019SAndroid Build Coastguard Worker case OPT_PIGLIT_DMESG:
394*d83cc019SAndroid Build Coastguard Worker settings->piglit_style_dmesg = true;
395*d83cc019SAndroid Build Coastguard Worker if (settings->dmesg_warn_level < 0)
396*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = 5; /* KERN_NOTICE */
397*d83cc019SAndroid Build Coastguard Worker break;
398*d83cc019SAndroid Build Coastguard Worker case OPT_DMESG_WARN_LEVEL:
399*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = atoi(optarg);
400*d83cc019SAndroid Build Coastguard Worker break;
401*d83cc019SAndroid Build Coastguard Worker case OPT_BLACKLIST:
402*d83cc019SAndroid Build Coastguard Worker if (!parse_blacklist(&settings->exclude_regexes,
403*d83cc019SAndroid Build Coastguard Worker absolute_path(optarg)))
404*d83cc019SAndroid Build Coastguard Worker goto error;
405*d83cc019SAndroid Build Coastguard Worker break;
406*d83cc019SAndroid Build Coastguard Worker case OPT_LIST_ALL:
407*d83cc019SAndroid Build Coastguard Worker settings->list_all = true;
408*d83cc019SAndroid Build Coastguard Worker break;
409*d83cc019SAndroid Build Coastguard Worker case '?':
410*d83cc019SAndroid Build Coastguard Worker usage(NULL, stderr);
411*d83cc019SAndroid Build Coastguard Worker goto error;
412*d83cc019SAndroid Build Coastguard Worker default:
413*d83cc019SAndroid Build Coastguard Worker usage("Cannot parse options", stderr);
414*d83cc019SAndroid Build Coastguard Worker goto error;
415*d83cc019SAndroid Build Coastguard Worker }
416*d83cc019SAndroid Build Coastguard Worker }
417*d83cc019SAndroid Build Coastguard Worker
418*d83cc019SAndroid Build Coastguard Worker if (settings->dmesg_warn_level < 0)
419*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = 4; /* KERN_WARN */
420*d83cc019SAndroid Build Coastguard Worker
421*d83cc019SAndroid Build Coastguard Worker if (settings->list_all) { /* --list-all doesn't require results path */
422*d83cc019SAndroid Build Coastguard Worker switch (argc - optind) {
423*d83cc019SAndroid Build Coastguard Worker case 1:
424*d83cc019SAndroid Build Coastguard Worker settings->test_root = absolute_path(argv[optind]);
425*d83cc019SAndroid Build Coastguard Worker ++optind;
426*d83cc019SAndroid Build Coastguard Worker /* fallthrough */
427*d83cc019SAndroid Build Coastguard Worker case 0:
428*d83cc019SAndroid Build Coastguard Worker break;
429*d83cc019SAndroid Build Coastguard Worker default:
430*d83cc019SAndroid Build Coastguard Worker usage("Too many arguments for --list-all", stderr);
431*d83cc019SAndroid Build Coastguard Worker goto error;
432*d83cc019SAndroid Build Coastguard Worker }
433*d83cc019SAndroid Build Coastguard Worker } else {
434*d83cc019SAndroid Build Coastguard Worker switch (argc - optind) {
435*d83cc019SAndroid Build Coastguard Worker case 2:
436*d83cc019SAndroid Build Coastguard Worker settings->test_root = absolute_path(argv[optind]);
437*d83cc019SAndroid Build Coastguard Worker ++optind;
438*d83cc019SAndroid Build Coastguard Worker /* fallthrough */
439*d83cc019SAndroid Build Coastguard Worker case 1:
440*d83cc019SAndroid Build Coastguard Worker settings->results_path = absolute_path(argv[optind]);
441*d83cc019SAndroid Build Coastguard Worker break;
442*d83cc019SAndroid Build Coastguard Worker case 0:
443*d83cc019SAndroid Build Coastguard Worker usage("Results-path missing", stderr);
444*d83cc019SAndroid Build Coastguard Worker goto error;
445*d83cc019SAndroid Build Coastguard Worker default:
446*d83cc019SAndroid Build Coastguard Worker usage("Extra arguments after results-path", stderr);
447*d83cc019SAndroid Build Coastguard Worker goto error;
448*d83cc019SAndroid Build Coastguard Worker }
449*d83cc019SAndroid Build Coastguard Worker if (!settings->name) {
450*d83cc019SAndroid Build Coastguard Worker char *name = strdup(settings->results_path);
451*d83cc019SAndroid Build Coastguard Worker
452*d83cc019SAndroid Build Coastguard Worker settings->name = strdup(basename(name));
453*d83cc019SAndroid Build Coastguard Worker free(name);
454*d83cc019SAndroid Build Coastguard Worker }
455*d83cc019SAndroid Build Coastguard Worker }
456*d83cc019SAndroid Build Coastguard Worker
457*d83cc019SAndroid Build Coastguard Worker if ((env_test_root = getenv("IGT_TEST_ROOT")) != NULL) {
458*d83cc019SAndroid Build Coastguard Worker free(settings->test_root);
459*d83cc019SAndroid Build Coastguard Worker settings->test_root = absolute_path(env_test_root);
460*d83cc019SAndroid Build Coastguard Worker }
461*d83cc019SAndroid Build Coastguard Worker
462*d83cc019SAndroid Build Coastguard Worker if (!settings->test_root) {
463*d83cc019SAndroid Build Coastguard Worker usage("Test root not set", stderr);
464*d83cc019SAndroid Build Coastguard Worker goto error;
465*d83cc019SAndroid Build Coastguard Worker }
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker
468*d83cc019SAndroid Build Coastguard Worker return true;
469*d83cc019SAndroid Build Coastguard Worker
470*d83cc019SAndroid Build Coastguard Worker error:
471*d83cc019SAndroid Build Coastguard Worker free_settings(settings);
472*d83cc019SAndroid Build Coastguard Worker return false;
473*d83cc019SAndroid Build Coastguard Worker }
474*d83cc019SAndroid Build Coastguard Worker
validate_settings(struct settings * settings)475*d83cc019SAndroid Build Coastguard Worker bool validate_settings(struct settings *settings)
476*d83cc019SAndroid Build Coastguard Worker {
477*d83cc019SAndroid Build Coastguard Worker int dirfd, fd;
478*d83cc019SAndroid Build Coastguard Worker
479*d83cc019SAndroid Build Coastguard Worker if (settings->test_list && !readable_file(settings->test_list)) {
480*d83cc019SAndroid Build Coastguard Worker usage("Cannot open test-list file", stderr);
481*d83cc019SAndroid Build Coastguard Worker return false;
482*d83cc019SAndroid Build Coastguard Worker }
483*d83cc019SAndroid Build Coastguard Worker
484*d83cc019SAndroid Build Coastguard Worker if (!settings->results_path) {
485*d83cc019SAndroid Build Coastguard Worker usage("No results-path set; this shouldn't happen", stderr);
486*d83cc019SAndroid Build Coastguard Worker return false;
487*d83cc019SAndroid Build Coastguard Worker }
488*d83cc019SAndroid Build Coastguard Worker
489*d83cc019SAndroid Build Coastguard Worker if (!settings->test_root) {
490*d83cc019SAndroid Build Coastguard Worker usage("No test root set; this shouldn't happen", stderr);
491*d83cc019SAndroid Build Coastguard Worker return false;
492*d83cc019SAndroid Build Coastguard Worker }
493*d83cc019SAndroid Build Coastguard Worker
494*d83cc019SAndroid Build Coastguard Worker dirfd = open(settings->test_root, O_DIRECTORY | O_RDONLY);
495*d83cc019SAndroid Build Coastguard Worker if (dirfd < 0) {
496*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Test directory %s cannot be opened\n", settings->test_root);
497*d83cc019SAndroid Build Coastguard Worker return false;
498*d83cc019SAndroid Build Coastguard Worker }
499*d83cc019SAndroid Build Coastguard Worker
500*d83cc019SAndroid Build Coastguard Worker fd = openat(dirfd, "test-list.txt", O_RDONLY);
501*d83cc019SAndroid Build Coastguard Worker if (fd < 0) {
502*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Cannot open %s/test-list.txt\n", settings->test_root);
503*d83cc019SAndroid Build Coastguard Worker close(dirfd);
504*d83cc019SAndroid Build Coastguard Worker return false;
505*d83cc019SAndroid Build Coastguard Worker }
506*d83cc019SAndroid Build Coastguard Worker
507*d83cc019SAndroid Build Coastguard Worker close(fd);
508*d83cc019SAndroid Build Coastguard Worker close(dirfd);
509*d83cc019SAndroid Build Coastguard Worker
510*d83cc019SAndroid Build Coastguard Worker return true;
511*d83cc019SAndroid Build Coastguard Worker }
512*d83cc019SAndroid Build Coastguard Worker
_dirname(const char * path)513*d83cc019SAndroid Build Coastguard Worker static char *_dirname(const char *path)
514*d83cc019SAndroid Build Coastguard Worker {
515*d83cc019SAndroid Build Coastguard Worker char *tmppath = strdup(path);
516*d83cc019SAndroid Build Coastguard Worker char *tmpname = dirname(tmppath);
517*d83cc019SAndroid Build Coastguard Worker tmpname = strdup(tmpname);
518*d83cc019SAndroid Build Coastguard Worker free(tmppath);
519*d83cc019SAndroid Build Coastguard Worker return tmpname;
520*d83cc019SAndroid Build Coastguard Worker }
521*d83cc019SAndroid Build Coastguard Worker
_basename(const char * path)522*d83cc019SAndroid Build Coastguard Worker static char *_basename(const char *path)
523*d83cc019SAndroid Build Coastguard Worker {
524*d83cc019SAndroid Build Coastguard Worker char *tmppath = strdup(path);
525*d83cc019SAndroid Build Coastguard Worker char *tmpname = basename(tmppath);
526*d83cc019SAndroid Build Coastguard Worker tmpname = strdup(tmpname);
527*d83cc019SAndroid Build Coastguard Worker free(tmppath);
528*d83cc019SAndroid Build Coastguard Worker return tmpname;
529*d83cc019SAndroid Build Coastguard Worker }
530*d83cc019SAndroid Build Coastguard Worker
absolute_path(char * path)531*d83cc019SAndroid Build Coastguard Worker char *absolute_path(char *path)
532*d83cc019SAndroid Build Coastguard Worker {
533*d83cc019SAndroid Build Coastguard Worker char *result = NULL;
534*d83cc019SAndroid Build Coastguard Worker char *base, *dir;
535*d83cc019SAndroid Build Coastguard Worker char *ret;
536*d83cc019SAndroid Build Coastguard Worker
537*d83cc019SAndroid Build Coastguard Worker result = realpath(path, NULL);
538*d83cc019SAndroid Build Coastguard Worker if (result != NULL)
539*d83cc019SAndroid Build Coastguard Worker return result;
540*d83cc019SAndroid Build Coastguard Worker
541*d83cc019SAndroid Build Coastguard Worker dir = _dirname(path);
542*d83cc019SAndroid Build Coastguard Worker ret = absolute_path(dir);
543*d83cc019SAndroid Build Coastguard Worker free(dir);
544*d83cc019SAndroid Build Coastguard Worker
545*d83cc019SAndroid Build Coastguard Worker base = _basename(path);
546*d83cc019SAndroid Build Coastguard Worker asprintf(&result, "%s/%s", ret, base);
547*d83cc019SAndroid Build Coastguard Worker free(base);
548*d83cc019SAndroid Build Coastguard Worker free(ret);
549*d83cc019SAndroid Build Coastguard Worker
550*d83cc019SAndroid Build Coastguard Worker return result;
551*d83cc019SAndroid Build Coastguard Worker }
552*d83cc019SAndroid Build Coastguard Worker
553*d83cc019SAndroid Build Coastguard Worker static char settings_filename[] = "metadata.txt";
serialize_settings(struct settings * settings)554*d83cc019SAndroid Build Coastguard Worker bool serialize_settings(struct settings *settings)
555*d83cc019SAndroid Build Coastguard Worker {
556*d83cc019SAndroid Build Coastguard Worker #define SERIALIZE_LINE(f, s, name, format) fprintf(f, "%s : " format "\n", #name, s->name)
557*d83cc019SAndroid Build Coastguard Worker
558*d83cc019SAndroid Build Coastguard Worker int dirfd, fd;
559*d83cc019SAndroid Build Coastguard Worker FILE *f;
560*d83cc019SAndroid Build Coastguard Worker
561*d83cc019SAndroid Build Coastguard Worker if (!settings->results_path) {
562*d83cc019SAndroid Build Coastguard Worker usage("No results-path set; this shouldn't happen", stderr);
563*d83cc019SAndroid Build Coastguard Worker return false;
564*d83cc019SAndroid Build Coastguard Worker }
565*d83cc019SAndroid Build Coastguard Worker
566*d83cc019SAndroid Build Coastguard Worker if ((dirfd = open(settings->results_path, O_DIRECTORY | O_RDONLY)) < 0) {
567*d83cc019SAndroid Build Coastguard Worker mkdir(settings->results_path, 0755);
568*d83cc019SAndroid Build Coastguard Worker if ((dirfd = open(settings->results_path, O_DIRECTORY | O_RDONLY)) < 0) {
569*d83cc019SAndroid Build Coastguard Worker usage("Creating results-path failed", stderr);
570*d83cc019SAndroid Build Coastguard Worker return false;
571*d83cc019SAndroid Build Coastguard Worker }
572*d83cc019SAndroid Build Coastguard Worker }
573*d83cc019SAndroid Build Coastguard Worker
574*d83cc019SAndroid Build Coastguard Worker if (!settings->overwrite &&
575*d83cc019SAndroid Build Coastguard Worker faccessat(dirfd, settings_filename, F_OK, 0) == 0) {
576*d83cc019SAndroid Build Coastguard Worker usage("Settings metadata already exists and not overwriting", stderr);
577*d83cc019SAndroid Build Coastguard Worker return false;
578*d83cc019SAndroid Build Coastguard Worker }
579*d83cc019SAndroid Build Coastguard Worker
580*d83cc019SAndroid Build Coastguard Worker if (settings->overwrite &&
581*d83cc019SAndroid Build Coastguard Worker unlinkat(dirfd, settings_filename, 0) != 0 &&
582*d83cc019SAndroid Build Coastguard Worker errno != ENOENT) {
583*d83cc019SAndroid Build Coastguard Worker usage("Error removing old settings metadata", stderr);
584*d83cc019SAndroid Build Coastguard Worker return false;
585*d83cc019SAndroid Build Coastguard Worker }
586*d83cc019SAndroid Build Coastguard Worker
587*d83cc019SAndroid Build Coastguard Worker if ((fd = openat(dirfd, settings_filename, O_CREAT | O_EXCL | O_WRONLY, 0666)) < 0) {
588*d83cc019SAndroid Build Coastguard Worker char *msg;
589*d83cc019SAndroid Build Coastguard Worker
590*d83cc019SAndroid Build Coastguard Worker asprintf(&msg, "Creating settings serialization file failed: %s", strerror(errno));
591*d83cc019SAndroid Build Coastguard Worker usage(msg, stderr);
592*d83cc019SAndroid Build Coastguard Worker
593*d83cc019SAndroid Build Coastguard Worker free(msg);
594*d83cc019SAndroid Build Coastguard Worker close(dirfd);
595*d83cc019SAndroid Build Coastguard Worker return false;
596*d83cc019SAndroid Build Coastguard Worker }
597*d83cc019SAndroid Build Coastguard Worker
598*d83cc019SAndroid Build Coastguard Worker f = fdopen(fd, "w");
599*d83cc019SAndroid Build Coastguard Worker if (!f) {
600*d83cc019SAndroid Build Coastguard Worker close(fd);
601*d83cc019SAndroid Build Coastguard Worker close(dirfd);
602*d83cc019SAndroid Build Coastguard Worker return false;
603*d83cc019SAndroid Build Coastguard Worker }
604*d83cc019SAndroid Build Coastguard Worker
605*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, abort_mask, "%d");
606*d83cc019SAndroid Build Coastguard Worker if (settings->test_list)
607*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, test_list, "%s");
608*d83cc019SAndroid Build Coastguard Worker if (settings->name)
609*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, name, "%s");
610*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, dry_run, "%d");
611*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, sync, "%d");
612*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, log_level, "%d");
613*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, overwrite, "%d");
614*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, multiple_mode, "%d");
615*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, inactivity_timeout, "%d");
616*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, overall_timeout, "%d");
617*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, use_watchdog, "%d");
618*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, piglit_style_dmesg, "%d");
619*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, dmesg_warn_level, "%d");
620*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, test_root, "%s");
621*d83cc019SAndroid Build Coastguard Worker SERIALIZE_LINE(f, settings, results_path, "%s");
622*d83cc019SAndroid Build Coastguard Worker
623*d83cc019SAndroid Build Coastguard Worker if (settings->sync) {
624*d83cc019SAndroid Build Coastguard Worker fsync(fd);
625*d83cc019SAndroid Build Coastguard Worker fsync(dirfd);
626*d83cc019SAndroid Build Coastguard Worker }
627*d83cc019SAndroid Build Coastguard Worker
628*d83cc019SAndroid Build Coastguard Worker fclose(f);
629*d83cc019SAndroid Build Coastguard Worker close(dirfd);
630*d83cc019SAndroid Build Coastguard Worker return true;
631*d83cc019SAndroid Build Coastguard Worker
632*d83cc019SAndroid Build Coastguard Worker #undef SERIALIZE_LINE
633*d83cc019SAndroid Build Coastguard Worker }
634*d83cc019SAndroid Build Coastguard Worker
read_settings_from_file(struct settings * settings,FILE * f)635*d83cc019SAndroid Build Coastguard Worker bool read_settings_from_file(struct settings *settings, FILE *f)
636*d83cc019SAndroid Build Coastguard Worker {
637*d83cc019SAndroid Build Coastguard Worker #define PARSE_LINE(s, name, val, field, write) \
638*d83cc019SAndroid Build Coastguard Worker if (!strcmp(name, #field)) { \
639*d83cc019SAndroid Build Coastguard Worker s->field = write; \
640*d83cc019SAndroid Build Coastguard Worker free(name); \
641*d83cc019SAndroid Build Coastguard Worker free(val); \
642*d83cc019SAndroid Build Coastguard Worker name = val = NULL; \
643*d83cc019SAndroid Build Coastguard Worker continue; \
644*d83cc019SAndroid Build Coastguard Worker }
645*d83cc019SAndroid Build Coastguard Worker
646*d83cc019SAndroid Build Coastguard Worker char *name = NULL, *val = NULL;
647*d83cc019SAndroid Build Coastguard Worker
648*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = -1;
649*d83cc019SAndroid Build Coastguard Worker
650*d83cc019SAndroid Build Coastguard Worker while (fscanf(f, "%ms : %ms", &name, &val) == 2) {
651*d83cc019SAndroid Build Coastguard Worker int numval = atoi(val);
652*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, abort_mask, numval);
653*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, test_list, val ? strdup(val) : NULL);
654*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, name, val ? strdup(val) : NULL);
655*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, dry_run, numval);
656*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, sync, numval);
657*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, log_level, numval);
658*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, overwrite, numval);
659*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, multiple_mode, numval);
660*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, inactivity_timeout, numval);
661*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, overall_timeout, numval);
662*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, use_watchdog, numval);
663*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, piglit_style_dmesg, numval);
664*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, dmesg_warn_level, numval);
665*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, test_root, val ? strdup(val) : NULL);
666*d83cc019SAndroid Build Coastguard Worker PARSE_LINE(settings, name, val, results_path, val ? strdup(val) : NULL);
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker printf("Warning: Unknown field in settings file: %s = %s\n",
669*d83cc019SAndroid Build Coastguard Worker name, val);
670*d83cc019SAndroid Build Coastguard Worker free(name);
671*d83cc019SAndroid Build Coastguard Worker free(val);
672*d83cc019SAndroid Build Coastguard Worker name = val = NULL;
673*d83cc019SAndroid Build Coastguard Worker }
674*d83cc019SAndroid Build Coastguard Worker
675*d83cc019SAndroid Build Coastguard Worker if (settings->dmesg_warn_level < 0) {
676*d83cc019SAndroid Build Coastguard Worker if (settings->piglit_style_dmesg)
677*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = 5;
678*d83cc019SAndroid Build Coastguard Worker else
679*d83cc019SAndroid Build Coastguard Worker settings->dmesg_warn_level = 4;
680*d83cc019SAndroid Build Coastguard Worker }
681*d83cc019SAndroid Build Coastguard Worker
682*d83cc019SAndroid Build Coastguard Worker free(name);
683*d83cc019SAndroid Build Coastguard Worker free(val);
684*d83cc019SAndroid Build Coastguard Worker
685*d83cc019SAndroid Build Coastguard Worker return true;
686*d83cc019SAndroid Build Coastguard Worker
687*d83cc019SAndroid Build Coastguard Worker #undef PARSE_LINE
688*d83cc019SAndroid Build Coastguard Worker }
689*d83cc019SAndroid Build Coastguard Worker
read_settings_from_dir(struct settings * settings,int dirfd)690*d83cc019SAndroid Build Coastguard Worker bool read_settings_from_dir(struct settings *settings, int dirfd)
691*d83cc019SAndroid Build Coastguard Worker {
692*d83cc019SAndroid Build Coastguard Worker int fd;
693*d83cc019SAndroid Build Coastguard Worker FILE *f;
694*d83cc019SAndroid Build Coastguard Worker
695*d83cc019SAndroid Build Coastguard Worker free_settings(settings);
696*d83cc019SAndroid Build Coastguard Worker
697*d83cc019SAndroid Build Coastguard Worker if ((fd = openat(dirfd, settings_filename, O_RDONLY)) < 0)
698*d83cc019SAndroid Build Coastguard Worker return false;
699*d83cc019SAndroid Build Coastguard Worker
700*d83cc019SAndroid Build Coastguard Worker f = fdopen(fd, "r");
701*d83cc019SAndroid Build Coastguard Worker if (!f) {
702*d83cc019SAndroid Build Coastguard Worker close(fd);
703*d83cc019SAndroid Build Coastguard Worker return false;
704*d83cc019SAndroid Build Coastguard Worker }
705*d83cc019SAndroid Build Coastguard Worker
706*d83cc019SAndroid Build Coastguard Worker if (!read_settings_from_file(settings, f)) {
707*d83cc019SAndroid Build Coastguard Worker fclose(f);
708*d83cc019SAndroid Build Coastguard Worker return false;
709*d83cc019SAndroid Build Coastguard Worker }
710*d83cc019SAndroid Build Coastguard Worker
711*d83cc019SAndroid Build Coastguard Worker fclose(f);
712*d83cc019SAndroid Build Coastguard Worker
713*d83cc019SAndroid Build Coastguard Worker return true;
714*d83cc019SAndroid Build Coastguard Worker }
715