• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2015-2016 Cyril Hrubis <chrubis@suse.cz>
4  * Copyright (c) Linux Test Project, 2016-2024
5  */
6 
7 #define _GNU_SOURCE
8 
9 #include <limits.h>
10 #include <stdio.h>
11 #include <stdarg.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 #include <sys/mount.h>
17 #include <sys/types.h>
18 #include <sys/utsname.h>
19 #include <sys/wait.h>
20 #include <math.h>
21 
22 #define TST_NO_DEFAULT_MAIN
23 #include "tst_test.h"
24 #include "tst_device.h"
25 #include "lapi/abisize.h"
26 #include "lapi/futex.h"
27 #include "lapi/syscalls.h"
28 #include "tst_ansi_color.h"
29 #include "tst_safe_stdio.h"
30 #include "tst_timer_test.h"
31 #include "tst_clocks.h"
32 #include "tst_timer.h"
33 #include "tst_wallclock.h"
34 #include "tst_sys_conf.h"
35 #include "tst_kconfig.h"
36 #include "tst_private.h"
37 #include "old_resource.h"
38 #include "old_device.h"
39 #include "old_tmpdir.h"
40 #include "ltp-version.h"
41 
42 /*
43  * Hack to get TCID defined in newlib tests
44  */
45 const char *TCID __attribute__((weak));
46 
47 /* update also docparse/testinfo.pl */
48 #define LINUX_GIT_URL "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id="
49 #define LINUX_STABLE_GIT_URL "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id="
50 #define GLIBC_GIT_URL "https://sourceware.org/git/?p=glibc.git;a=commit;h="
51 #define MUSL_GIT_URL "https://git.musl-libc.org/cgit/musl/commit/src/linux/clone.c?id="
52 #define CVE_DB_URL "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-"
53 
54 #define DEFAULT_TIMEOUT 30
55 
56 struct tst_test *tst_test;
57 
58 static const char *tid;
59 static int iterations = 1;
60 static float duration = -1;
61 static float timeout_mul = -1;
62 static pid_t main_pid, lib_pid;
63 static int mntpoint_mounted;
64 static int ovl_mounted;
65 static struct timespec tst_start_time; /* valid only for test pid */
66 static int tdebug;
67 
68 struct results {
69 	int passed;
70 	int skipped;
71 	int failed;
72 	int warnings;
73 	int broken;
74 	unsigned int runtime;
75 	unsigned int overall_time;
76 };
77 
78 static struct results *results;
79 
80 static int ipc_fd;
81 
82 extern void *tst_futexes;
83 extern unsigned int tst_max_futexes;
84 
85 static char ipc_path[1064];
86 const char *tst_ipc_path = ipc_path;
87 
88 static char shm_path[1024];
89 
90 int TST_ERR;
91 int TST_PASS;
92 long TST_RET;
93 
94 static void do_cleanup(void);
95 static void do_exit(int ret) __attribute__ ((noreturn));
96 
setup_ipc(void)97 static void setup_ipc(void)
98 {
99 	size_t size = getpagesize();
100 
101 	if (access("/dev/shm", F_OK) == 0) {
102 		snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d",
103 			 tid, getpid());
104 	} else {
105 		char *tmpdir;
106 
107 		if (!tst_tmpdir_created())
108 			tst_tmpdir();
109 
110 		tmpdir = tst_get_tmpdir();
111 		snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d",
112 			 tmpdir, tid, getpid());
113 		free(tmpdir);
114 	}
115 
116 	ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600);
117 	if (ipc_fd < 0)
118 		tst_brk(TBROK | TERRNO, "open(%s)", shm_path);
119 	SAFE_CHMOD(shm_path, 0666);
120 
121 	SAFE_FTRUNCATE(ipc_fd, size);
122 
123 	results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0);
124 
125 	/* Checkpoints needs to be accessible from processes started by exec() */
126 	if (tst_test->needs_checkpoints || tst_test->child_needs_reinit) {
127 		sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path);
128 		putenv(ipc_path);
129 	} else {
130 		SAFE_UNLINK(shm_path);
131 	}
132 
133 	SAFE_CLOSE(ipc_fd);
134 
135 	if (tst_test->needs_checkpoints) {
136 		tst_futexes = (char *)results + sizeof(struct results);
137 		tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t);
138 	}
139 }
140 
cleanup_ipc(void)141 static void cleanup_ipc(void)
142 {
143 	size_t size = getpagesize();
144 
145 	if (ipc_fd > 0 && close(ipc_fd))
146 		tst_res(TWARN | TERRNO, "close(ipc_fd) failed");
147 
148 	if (shm_path[0] && !access(shm_path, F_OK) && unlink(shm_path))
149 		tst_res(TWARN | TERRNO, "unlink(%s) failed", shm_path);
150 
151 	if (results) {
152 		msync((void *)results, size, MS_SYNC);
153 		munmap((void *)results, size);
154 		results = NULL;
155 	}
156 }
157 
tst_reinit(void)158 void tst_reinit(void)
159 {
160 	const char *path = getenv(IPC_ENV_VAR);
161 	size_t size = getpagesize();
162 	int fd;
163 
164 	if (!path)
165 		tst_brk(TBROK, IPC_ENV_VAR" is not defined");
166 
167 	if (access(path, F_OK))
168 		tst_brk(TBROK, "File %s does not exist!", path);
169 
170 	fd = SAFE_OPEN(path, O_RDWR);
171 
172 	results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
173 	tst_futexes = (char *)results + sizeof(struct results);
174 	tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t);
175 
176 	SAFE_CLOSE(fd);
177 }
178 
179 extern char **environ;
180 
params_array_len(char * const array[])181 static unsigned int params_array_len(char *const array[])
182 {
183 	unsigned int ret = 0;
184 
185 	if (!array)
186 		return 0;
187 
188 	while (*(array++))
189 		ret++;
190 
191 	return ret;
192 }
193 
tst_run_script(const char * script_name,char * const params[])194 int tst_run_script(const char *script_name, char *const params[])
195 {
196 	int pid;
197 	unsigned int i, params_len = params_array_len(params);
198 	char *argv[params_len + 2];
199 
200 	if (!tst_test->runs_script)
201 		tst_brk(TBROK, "runs_script flag must be set!");
202 
203 	argv[0] = (char*)script_name;
204 
205 	if (params) {
206 		for (i = 0; i < params_len; i++)
207 			argv[i+1] = params[i];
208 	}
209 
210 	argv[params_len+1] = NULL;
211 
212 	pid = SAFE_FORK();
213 	if (pid)
214 		return pid;
215 
216 	execvpe(script_name, argv, environ);
217 
218 	tst_brk(TBROK | TERRNO, "execvpe(%s, ...) failed!", script_name);
219 
220 	return -1;
221 }
222 
update_results(int ttype)223 static void update_results(int ttype)
224 {
225 	if (!results)
226 		return;
227 
228 	switch (ttype) {
229 	case TCONF:
230 		tst_atomic_inc(&results->skipped);
231 	break;
232 	case TPASS:
233 		tst_atomic_inc(&results->passed);
234 	break;
235 	case TWARN:
236 		tst_atomic_inc(&results->warnings);
237 	break;
238 	case TFAIL:
239 		tst_atomic_inc(&results->failed);
240 	break;
241 	case TBROK:
242 		tst_atomic_inc(&results->broken);
243 	break;
244 	}
245 }
246 
print_result(const char * file,const int lineno,int ttype,const char * fmt,va_list va)247 static void print_result(const char *file, const int lineno, int ttype,
248 			 const char *fmt, va_list va)
249 {
250 	char buf[1024];
251 	char *str = buf;
252 	int ret, size = sizeof(buf), ssize, int_errno, buflen;
253 	const char *str_errno = NULL;
254 	const char *res;
255 
256 	switch (TTYPE_RESULT(ttype)) {
257 	case TPASS:
258 		res = "TPASS";
259 	break;
260 	case TFAIL:
261 		res = "TFAIL";
262 	break;
263 	case TBROK:
264 		res = "TBROK";
265 	break;
266 	case TCONF:
267 		res = "TCONF";
268 	break;
269 	case TWARN:
270 		res = "TWARN";
271 	break;
272 	case TINFO:
273 		res = "TINFO";
274 	break;
275 	case TDEBUG:
276 		res = "TDEBUG";
277 	break;
278 	default:
279 		tst_brk(TBROK, "Invalid ttype value %i", ttype);
280 		abort();
281 	}
282 
283 	if (ttype & TERRNO) {
284 		str_errno = tst_strerrno(errno);
285 		int_errno = errno;
286 	}
287 
288 	if (ttype & TTERRNO) {
289 		str_errno = tst_strerrno(TST_ERR);
290 		int_errno = TST_ERR;
291 	}
292 
293 	if (ttype & TRERRNO) {
294 		int_errno = TST_RET < 0 ? -(int)TST_RET : (int)TST_RET;
295 		str_errno = tst_strerrno(int_errno);
296 	}
297 
298 	ret = snprintf(str, size, "%s:%i: ", file, lineno);
299 	str += ret;
300 	size -= ret;
301 
302 	if (tst_color_enabled(STDERR_FILENO))
303 		ret = snprintf(str, size, "%s%s: %s", tst_ttype2color(ttype),
304 			       res, ANSI_COLOR_RESET);
305 	else
306 		ret = snprintf(str, size, "%s: ", res);
307 	str += ret;
308 	size -= ret;
309 
310 	ssize = size - 2;
311 	ret = vsnprintf(str, size, fmt, va);
312 	str += MIN(ret, ssize);
313 	size -= MIN(ret, ssize);
314 	if (ret >= ssize) {
315 		tst_res_(file, lineno, TWARN,
316 				"Next message is too long and truncated:");
317 	} else if (str_errno) {
318 		ssize = size - 2;
319 		ret = snprintf(str, size, ": %s (%d)", str_errno, int_errno);
320 		str += MIN(ret, ssize);
321 		size -= MIN(ret, ssize);
322 		if (ret >= ssize)
323 			tst_res_(file, lineno, TWARN,
324 				"Next message is too long and truncated:");
325 	}
326 
327 	snprintf(str, size, "\n");
328 
329 	/* we might be called from signal handler, so use write() */
330 	buflen = str - buf + 1;
331 	str = buf;
332 	while (buflen) {
333 		ret = write(STDERR_FILENO, str, buflen);
334 		if (ret <= 0)
335 			break;
336 
337 		str += ret;
338 		buflen -= ret;
339 	}
340 }
341 
tst_vres_(const char * file,const int lineno,int ttype,const char * fmt,va_list va)342 void tst_vres_(const char *file, const int lineno, int ttype, const char *fmt,
343 	       va_list va)
344 {
345 	print_result(file, lineno, ttype, fmt, va);
346 
347 	update_results(TTYPE_RESULT(ttype));
348 }
349 
350 void tst_vbrk_(const char *file, const int lineno, int ttype, const char *fmt,
351 	       va_list va);
352 
353 static void (*tst_brk_handler)(const char *file, const int lineno, int ttype,
354 			       const char *fmt, va_list va) = tst_vbrk_;
355 
tst_cvres(const char * file,const int lineno,int ttype,const char * fmt,va_list va)356 static void tst_cvres(const char *file, const int lineno, int ttype,
357 		      const char *fmt, va_list va)
358 {
359 	if (TTYPE_RESULT(ttype) == TBROK) {
360 		ttype &= ~TTYPE_MASK;
361 		ttype |= TWARN;
362 	}
363 
364 	print_result(file, lineno, ttype, fmt, va);
365 	update_results(TTYPE_RESULT(ttype));
366 }
367 
do_test_cleanup(void)368 static void do_test_cleanup(void)
369 {
370 	tst_brk_handler = tst_cvres;
371 
372 	if (tst_test->cleanup)
373 		tst_test->cleanup();
374 
375 	tst_free_all();
376 
377 	tst_brk_handler = tst_vbrk_;
378 }
379 
tst_vbrk_(const char * file,const int lineno,int ttype,const char * fmt,va_list va)380 void tst_vbrk_(const char *file, const int lineno, int ttype, const char *fmt,
381 	       va_list va)
382 {
383 	print_result(file, lineno, ttype, fmt, va);
384 	update_results(TTYPE_RESULT(ttype));
385 
386 	/*
387 	 * The getpid implementation in some C library versions may cause cloned
388 	 * test threads to show the same pid as their parent when CLONE_VM is
389 	 * specified but CLONE_THREAD is not. Use direct syscall to avoid
390 	 * cleanup running in the child.
391 	 */
392 	if (tst_getpid() == main_pid)
393 		do_test_cleanup();
394 
395 	if (getpid() == lib_pid)
396 		do_exit(TTYPE_RESULT(ttype));
397 
398 	exit(TTYPE_RESULT(ttype));
399 }
400 
tst_res_(const char * file,const int lineno,int ttype,const char * fmt,...)401 void tst_res_(const char *file, const int lineno, int ttype,
402 	      const char *fmt, ...)
403 {
404 	va_list va;
405 
406 	if (ttype == TDEBUG && !tdebug)
407 		return;
408 
409 	va_start(va, fmt);
410 	tst_vres_(file, lineno, ttype, fmt, va);
411 	va_end(va);
412 }
413 
tst_brk_(const char * file,const int lineno,int ttype,const char * fmt,...)414 void tst_brk_(const char *file, const int lineno, int ttype,
415 	      const char *fmt, ...)
416 {
417 	va_list va;
418 
419 	va_start(va, fmt);
420 	tst_brk_handler(file, lineno, ttype, fmt, va);
421 	va_end(va);
422 }
423 
tst_printf(const char * const fmt,...)424 void tst_printf(const char *const fmt, ...)
425 {
426 	va_list va;
427 
428 	va_start(va, fmt);
429 	vdprintf(STDERR_FILENO, fmt, va);
430 	va_end(va);
431 }
432 
check_child_status(pid_t pid,int status)433 static void check_child_status(pid_t pid, int status)
434 {
435 	int ret;
436 
437 	if (WIFSIGNALED(status)) {
438 		tst_brk(TBROK, "Child (%i) killed by signal %s", pid,
439 			tst_strsig(WTERMSIG(status)));
440 	}
441 
442 	if (!(WIFEXITED(status)))
443 		tst_brk(TBROK, "Child (%i) exited abnormally", pid);
444 
445 	ret = WEXITSTATUS(status);
446 	switch (ret) {
447 	case TPASS:
448 	case TBROK:
449 	case TCONF:
450 	break;
451 	default:
452 		tst_brk(TBROK, "Invalid child (%i) exit value %i", pid, ret);
453 	}
454 }
455 
tst_reap_children(void)456 void tst_reap_children(void)
457 {
458 	int status;
459 	pid_t pid;
460 
461 	for (;;) {
462 		pid = wait(&status);
463 
464 		if (pid > 0) {
465 			check_child_status(pid, status);
466 			continue;
467 		}
468 
469 		if (errno == ECHILD)
470 			break;
471 
472 		if (errno == EINTR)
473 			continue;
474 
475 		tst_brk(TBROK | TERRNO, "wait() failed");
476 	}
477 }
478 
479 
safe_fork(const char * filename,unsigned int lineno)480 pid_t safe_fork(const char *filename, unsigned int lineno)
481 {
482 	pid_t pid;
483 
484 	if (!tst_test->forks_child)
485 		tst_brk(TBROK, "test.forks_child must be set!");
486 
487 	tst_flush();
488 
489 	pid = fork();
490 	if (pid < 0)
491 		tst_brk_(filename, lineno, TBROK | TERRNO, "fork() failed");
492 
493 	if (!pid)
494 		atexit(tst_free_all);
495 
496 	return pid;
497 }
498 
499 /* too fast creating namespaces => retrying */
500 #define TST_CHECK_ENOSPC(x) ((x) >= 0 || !(errno == ENOSPC))
501 
safe_clone(const char * file,const int lineno,const struct tst_clone_args * args)502 pid_t safe_clone(const char *file, const int lineno,
503 		 const struct tst_clone_args *args)
504 {
505 	pid_t pid;
506 
507 	if (!tst_test->forks_child)
508 		tst_brk(TBROK, "test.forks_child must be set!");
509 
510 	pid = TST_RETRY_FUNC(tst_clone(args), TST_CHECK_ENOSPC);
511 
512 	switch (pid) {
513 	case -1:
514 		tst_brk_(file, lineno, TBROK | TERRNO, "clone3 failed");
515 		break;
516 	case -2:
517 		tst_brk_(file, lineno, TBROK | TERRNO, "clone failed");
518 		return -1;
519 	}
520 
521 	if (!pid)
522 		atexit(tst_free_all);
523 
524 	return pid;
525 }
526 
parse_mul(float * mul,const char * env_name,float min,float max)527 static void parse_mul(float *mul, const char *env_name, float min, float max)
528 {
529 	char *str_mul;
530 	int ret;
531 
532 	if (*mul > 0)
533 		return;
534 
535 	str_mul = getenv(env_name);
536 
537 	if (!str_mul) {
538 		*mul = 1;
539 		return;
540 	}
541 
542 	ret = tst_parse_float(str_mul, mul, min, max);
543 	if (ret) {
544 		tst_brk(TBROK, "Failed to parse %s: %s",
545 			env_name, tst_strerrno(ret));
546 	}
547 }
548 
multiply_runtime(unsigned int runtime)549 static int multiply_runtime(unsigned int runtime)
550 {
551 	static float runtime_mul = -1;
552 
553 	parse_mul(&runtime_mul, "LTP_RUNTIME_MUL", 0.0099, 100);
554 
555 	return runtime * runtime_mul;
556 }
557 
558 static struct option {
559 	char *optstr;
560 	char *help;
561 } options[] = {
562 	{"h",  "-h       Prints this help"},
563 	{"i:", "-i n     Execute test n times"},
564 	{"I:", "-I x     Execute test for n seconds"},
565 	{"D",  "-D       Prints debug information"},
566 	{"V",  "-V       Prints LTP version"},
567 };
568 
print_help(void)569 static void print_help(void)
570 {
571 	unsigned int i;
572 	int timeout, runtime;
573 
574 	/* see doc/User-Guidelines.asciidoc, which lists also shell API variables */
575 	fprintf(stderr, "Environment Variables\n");
576 	fprintf(stderr, "---------------------\n");
577 	fprintf(stderr, "KCONFIG_PATH         Specify kernel config file\n");
578 	fprintf(stderr, "KCONFIG_SKIP_CHECK   Skip kernel config check if variable set (not set by default)\n");
579 	fprintf(stderr, "LTPROOT              Prefix for installed LTP (default: /opt/ltp)\n");
580 	fprintf(stderr, "LTP_COLORIZE_OUTPUT  Force colorized output behaviour (y/1 always, n/0: never)\n");
581 	fprintf(stderr, "LTP_DEV              Path to the block device to be used (for .needs_device)\n");
582 	fprintf(stderr, "LTP_DEV_FS_TYPE      Filesystem used for testing (default: %s)\n", DEFAULT_FS_TYPE);
583 	fprintf(stderr, "LTP_SINGLE_FS_TYPE   Testing only - specifies filesystem instead all supported (for .all_filesystems)\n");
584 	fprintf(stderr, "LTP_TIMEOUT_MUL      Timeout multiplier (must be a number >=1)\n");
585 	fprintf(stderr, "LTP_RUNTIME_MUL      Runtime multiplier (must be a number >=1)\n");
586 	fprintf(stderr, "LTP_VIRT_OVERRIDE    Overrides virtual machine detection (values: \"\"|kvm|microsoft|xen|zvm)\n");
587 	fprintf(stderr, "TMPDIR               Base directory for template directory (for .needs_tmpdir, default: %s)\n", TEMPDIR);
588 	fprintf(stderr, "\n");
589 
590 	fprintf(stderr, "Timeout and runtime\n");
591 	fprintf(stderr, "-------------------\n");
592 
593 	if (tst_test->timeout == TST_UNLIMITED_TIMEOUT) {
594 		fprintf(stderr, "Test timeout is not limited\n");
595 	} else {
596 		timeout = tst_multiply_timeout(DEFAULT_TIMEOUT + tst_test->timeout);
597 
598 		fprintf(stderr, "Test timeout (not including runtime) %ih %im %is\n",
599 				timeout/3600, (timeout%3600)/60, timeout % 60);
600 	}
601 
602 	if (tst_test->runtime) {
603 		runtime = multiply_runtime(tst_test->runtime);
604 
605 		fprintf(stderr, "Test iteration runtime cap %ih %im %is\n",
606 				runtime/3600, (runtime%3600)/60, runtime % 60);
607 	}
608 
609 	fprintf(stderr, "\n");
610 
611 	fprintf(stderr, "Options\n");
612 	fprintf(stderr, "-------\n");
613 
614 	for (i = 0; i < ARRAY_SIZE(options); i++)
615 		fprintf(stderr, "%s\n", options[i].help);
616 
617 	if (!tst_test->options)
618 		return;
619 
620 	for (i = 0; tst_test->options[i].optstr; i++) {
621 		fprintf(stderr, "-%c\t %s\n",
622 			tst_test->options[i].optstr[0],
623 			tst_test->options[i].help);
624 	}
625 }
626 
print_test_tags(void)627 static void print_test_tags(void)
628 {
629 	unsigned int i;
630 	const struct tst_tag *tags = tst_test->tags;
631 
632 	if (!tags)
633 		return;
634 
635 	fprintf(stderr, "\nTags\n");
636 	fprintf(stderr, "----\n");
637 
638 	for (i = 0; tags[i].name; i++) {
639 		if (!strcmp(tags[i].name, "CVE"))
640 			fprintf(stderr, CVE_DB_URL "%s\n", tags[i].value);
641 		else if (!strcmp(tags[i].name, "linux-git"))
642 			fprintf(stderr, LINUX_GIT_URL "%s\n", tags[i].value);
643 		else if (!strcmp(tags[i].name, "linux-stable-git"))
644 			fprintf(stderr, LINUX_STABLE_GIT_URL "%s\n", tags[i].value);
645 		else if (!strcmp(tags[i].name, "glibc-git"))
646 			fprintf(stderr, GLIBC_GIT_URL "%s\n", tags[i].value);
647 		else if (!strcmp(tags[i].name, "musl-git"))
648 			fprintf(stderr, MUSL_GIT_URL "%s\n", tags[i].value);
649 		else
650 			fprintf(stderr, "%s: %s\n", tags[i].name, tags[i].value);
651 	}
652 
653 	fprintf(stderr, "\n");
654 }
655 
check_option_collision(void)656 static void check_option_collision(void)
657 {
658 	unsigned int i, j;
659 	struct tst_option *toptions = tst_test->options;
660 
661 	if (!toptions)
662 		return;
663 
664 	for (i = 0; toptions[i].optstr; i++) {
665 		for (j = 0; j < ARRAY_SIZE(options); j++) {
666 			if (toptions[i].optstr[0] == options[j].optstr[0]) {
667 				tst_brk(TBROK, "Option collision '%s'",
668 					options[j].help);
669 			}
670 		}
671 	}
672 }
673 
count_options(void)674 static unsigned int count_options(void)
675 {
676 	unsigned int i;
677 
678 	if (!tst_test->options)
679 		return 0;
680 
681 	for (i = 0; tst_test->options[i].optstr; i++)
682 		;
683 
684 	return i;
685 }
686 
parse_topt(unsigned int topts_len,int opt,char * optarg)687 static void parse_topt(unsigned int topts_len, int opt, char *optarg)
688 {
689 	unsigned int i;
690 	struct tst_option *toptions = tst_test->options;
691 
692 	for (i = 0; i < topts_len; i++) {
693 		if (toptions[i].optstr[0] == opt)
694 			break;
695 	}
696 
697 	if (i >= topts_len)
698 		tst_brk(TBROK, "Invalid option '%c' (should not happen)", opt);
699 
700 	if (*toptions[i].arg)
701 		tst_res(TWARN, "Option -%c passed multiple times", opt);
702 
703 	*(toptions[i].arg) = optarg ? optarg : "";
704 }
705 
parse_opts(int argc,char * argv[])706 static void parse_opts(int argc, char *argv[])
707 {
708 	unsigned int i, topts_len = count_options();
709 	char optstr[2 * ARRAY_SIZE(options) + 2 * topts_len];
710 	int opt;
711 
712 	check_option_collision();
713 
714 	optstr[0] = 0;
715 
716 	for (i = 0; i < ARRAY_SIZE(options); i++)
717 		strcat(optstr, options[i].optstr);
718 
719 	for (i = 0; i < topts_len; i++)
720 		strcat(optstr, tst_test->options[i].optstr);
721 
722 	while ((opt = getopt(argc, argv, optstr)) > 0) {
723 		switch (opt) {
724 		case '?':
725 			print_help();
726 			tst_brk(TBROK, "Invalid option");
727 		break;
728 		case 'D':
729 			tst_res(TINFO, "Enabling debug info");
730 			tdebug = 1;
731 		break;
732 		case 'h':
733 			print_help();
734 			print_test_tags();
735 			exit(0);
736 		case 'i':
737 			iterations = SAFE_STRTOL(optarg, 0, INT_MAX);
738 		break;
739 		case 'I':
740 			if (tst_test->runtime > 0)
741 				tst_test->runtime = SAFE_STRTOL(optarg, 1, INT_MAX);
742 			else
743 				duration = SAFE_STRTOF(optarg, 0.1, HUGE_VALF);
744 		break;
745 		case 'V':
746 			fprintf(stderr, "LTP version: " LTP_VERSION "\n");
747 			exit(0);
748 		break;
749 		default:
750 			parse_topt(topts_len, opt, optarg);
751 		}
752 	}
753 
754 	if (optind < argc)
755 		tst_brk(TBROK, "Unexpected argument(s) '%s'...", argv[optind]);
756 }
757 
tst_parse_int(const char * str,int * val,int min,int max)758 int tst_parse_int(const char *str, int *val, int min, int max)
759 {
760 	long rval;
761 
762 	if (!str)
763 		return 0;
764 
765 	int ret = tst_parse_long(str, &rval, min, max);
766 
767 	if (ret)
768 		return ret;
769 
770 	*val = (int)rval;
771 	return 0;
772 }
773 
tst_parse_long(const char * str,long * val,long min,long max)774 int tst_parse_long(const char *str, long *val, long min, long max)
775 {
776 	long rval;
777 	char *end;
778 
779 	if (!str)
780 		return 0;
781 
782 	errno = 0;
783 	rval = strtol(str, &end, 10);
784 
785 	if (str == end || *end != '\0')
786 		return EINVAL;
787 
788 	if (errno)
789 		return errno;
790 
791 	if (rval > max || rval < min)
792 		return ERANGE;
793 
794 	*val = rval;
795 	return 0;
796 }
797 
tst_parse_float(const char * str,float * val,float min,float max)798 int tst_parse_float(const char *str, float *val, float min, float max)
799 {
800 	double rval;
801 	char *end;
802 
803 	if (!str)
804 		return 0;
805 
806 	errno = 0;
807 	rval = strtod(str, &end);
808 
809 	if (str == end || *end != '\0')
810 		return EINVAL;
811 
812 	if (errno)
813 		return errno;
814 
815 	if (rval > (double)max || rval < (double)min)
816 		return ERANGE;
817 
818 	*val = (float)rval;
819 	return 0;
820 }
821 
tst_parse_filesize(const char * str,long long * val,long long min,long long max)822 int tst_parse_filesize(const char *str, long long *val, long long min, long long max)
823 {
824 	long long rval;
825 	char *end;
826 
827 	if (!str)
828 		return 0;
829 
830 	errno = 0;
831 	rval = strtoll(str, &end, 0);
832 
833 	if (str == end || (end[0] && end[1]))
834 		return EINVAL;
835 
836 	if (errno)
837 		return errno;
838 
839 	switch (*end) {
840 	case 'g':
841 	case 'G':
842 		rval *= (1024 * 1024 * 1024);
843 		break;
844 	case 'm':
845 	case 'M':
846 		rval *= (1024 * 1024);
847 		break;
848 	case 'k':
849 	case 'K':
850 		rval *= 1024;
851 		break;
852 	default:
853 		break;
854 	}
855 
856 	if (rval > max || rval < min)
857 		return ERANGE;
858 
859 	*val = rval;
860 	return 0;
861 }
862 
print_colored(const char * str)863 static void print_colored(const char *str)
864 {
865 	if (tst_color_enabled(STDOUT_FILENO))
866 		fprintf(stderr, "%s%s%s", ANSI_COLOR_YELLOW, str, ANSI_COLOR_RESET);
867 	else
868 		fprintf(stderr, "%s", str);
869 }
870 
print_failure_hint(const char * tag,const char * hint,const char * url)871 static void print_failure_hint(const char *tag, const char *hint,
872 			       const char *url)
873 {
874 	const struct tst_tag *tags = tst_test->tags;
875 
876 	if (!tags)
877 		return;
878 
879 	unsigned int i;
880 	int hint_printed = 0;
881 
882 	for (i = 0; tags[i].name; i++) {
883 		if (!strcmp(tags[i].name, tag)) {
884 			if (!hint_printed) {
885 				hint_printed = 1;
886 				fprintf(stderr, "\n");
887 				print_colored("HINT: ");
888 				fprintf(stderr, "You _MAY_ be %s:\n\n", hint);
889 			}
890 
891 			if (url)
892 				fprintf(stderr, "%s%s\n", url, tags[i].value);
893 			else
894 				fprintf(stderr, "%s\n", tags[i].value);
895 		}
896 	}
897 }
898 
899 static int show_failure_hints;
900 
901 /* update also docparse/testinfo.pl */
print_failure_hints(void)902 static void print_failure_hints(void)
903 {
904 	print_failure_hint("linux-git", "missing kernel fixes", LINUX_GIT_URL);
905 	print_failure_hint("linux-stable-git", "missing stable kernel fixes",
906 					   LINUX_STABLE_GIT_URL);
907 	print_failure_hint("glibc-git", "missing glibc fixes", GLIBC_GIT_URL);
908 	print_failure_hint("musl-git", "missing musl fixes", MUSL_GIT_URL);
909 	print_failure_hint("CVE", "vulnerable to CVE(s)", CVE_DB_URL);
910 	print_failure_hint("known-fail", "hit by known kernel failures", NULL);
911 
912 	show_failure_hints = 0;
913 }
914 
do_exit(int ret)915 static void do_exit(int ret)
916 {
917 	if (results) {
918 		if (results->passed && ret == TCONF)
919 			ret = 0;
920 
921 		if (results->failed) {
922 			ret |= TFAIL;
923 			if (show_failure_hints)
924 				print_failure_hints();
925 		}
926 
927 		if (results->skipped && !results->passed)
928 			ret |= TCONF;
929 
930 		if (results->warnings)
931 			ret |= TWARN;
932 
933 		if (results->broken) {
934 			ret |= TBROK;
935 			if (show_failure_hints)
936 				print_failure_hints();
937 		}
938 
939 		fprintf(stderr, "\nSummary:\n");
940 		fprintf(stderr, "passed   %d\n", results->passed);
941 		fprintf(stderr, "failed   %d\n", results->failed);
942 		fprintf(stderr, "broken   %d\n", results->broken);
943 		fprintf(stderr, "skipped  %d\n", results->skipped);
944 		fprintf(stderr, "warnings %d\n", results->warnings);
945 	}
946 
947 	do_cleanup();
948 
949 	exit(ret);
950 }
951 
check_kver(const char * min_kver,const int brk_nosupp)952 int check_kver(const char *min_kver, const int brk_nosupp)
953 {
954 	char *msg;
955 	int v1, v2, v3;
956 
957 	if (tst_parse_kver(min_kver, &v1, &v2, &v3)) {
958 		tst_res(TWARN,
959 			"Invalid kernel version %s, expected %%d.%%d.%%d",
960 			min_kver);
961 	}
962 
963 	if (tst_kvercmp(v1, v2, v3) < 0) {
964 		msg = "The test requires kernel %s or newer";
965 
966 		if (brk_nosupp)
967 			tst_brk(TCONF, msg, min_kver);
968 		else
969 			tst_res(TCONF, msg, min_kver);
970 
971 		return 1;
972 	}
973 
974 	return 0;
975 }
976 
results_equal(struct results * a,struct results * b)977 static int results_equal(struct results *a, struct results *b)
978 {
979 	if (a->passed != b->passed)
980 		return 0;
981 
982 	if (a->failed != b->failed)
983 		return 0;
984 
985 	if (a->skipped != b->skipped)
986 		return 0;
987 
988 	if (a->broken != b->broken)
989 		return 0;
990 
991 	return 1;
992 }
993 
needs_tmpdir(void)994 static int needs_tmpdir(void)
995 {
996 	return tst_test->needs_tmpdir ||
997 	       tst_test->needs_device ||
998 	       tst_test->mntpoint ||
999 	       tst_test->resource_files ||
1000 	       tst_test->needs_checkpoints;
1001 }
1002 
copy_resources(void)1003 static void copy_resources(void)
1004 {
1005 	unsigned int i;
1006 
1007 	for (i = 0; tst_test->resource_files[i]; i++)
1008 		TST_RESOURCE_COPY(NULL, tst_test->resource_files[i], NULL);
1009 }
1010 
get_tid(char * argv[])1011 static const char *get_tid(char *argv[])
1012 {
1013 	char *p;
1014 
1015 	if (!argv[0] || !argv[0][0]) {
1016 		tst_res(TINFO, "argv[0] is empty!");
1017 		return "ltp_empty_argv";
1018 	}
1019 
1020 	p = strrchr(argv[0], '/');
1021 	if (p)
1022 		return p+1;
1023 
1024 	return argv[0];
1025 }
1026 
1027 static struct tst_device tdev;
1028 struct tst_device *tst_device;
1029 
assert_test_fn(void)1030 static void assert_test_fn(void)
1031 {
1032 	int cnt = 0;
1033 
1034 	if (tst_test->test)
1035 		cnt++;
1036 
1037 	if (tst_test->test_all)
1038 		cnt++;
1039 
1040 	if (tst_test->sample)
1041 		cnt++;
1042 
1043 	if (!cnt)
1044 		tst_brk(TBROK, "No test function specified");
1045 
1046 	if (cnt != 1)
1047 		tst_brk(TBROK, "You can define only one test function");
1048 
1049 	if (tst_test->test && !tst_test->tcnt)
1050 		tst_brk(TBROK, "Number of tests (tcnt) must be > 0");
1051 
1052 	if (!tst_test->test && tst_test->tcnt)
1053 		tst_brk(TBROK, "You can define tcnt only for test()");
1054 }
1055 
prepare_and_mount_ro_fs(const char * dev,const char * mntpoint,const char * fs_type)1056 static int prepare_and_mount_ro_fs(const char *dev, const char *mntpoint,
1057 				   const char *fs_type)
1058 {
1059 	char buf[PATH_MAX];
1060 
1061 	if (mount(dev, mntpoint, fs_type, 0, NULL)) {
1062 		tst_res(TINFO | TERRNO, "Can't mount %s at %s (%s)",
1063 			dev, mntpoint, fs_type);
1064 		return 1;
1065 	}
1066 
1067 	mntpoint_mounted = 1;
1068 
1069 	snprintf(buf, sizeof(buf), "%s/dir/", mntpoint);
1070 	SAFE_MKDIR(buf, 0777);
1071 
1072 	snprintf(buf, sizeof(buf), "%s/file", mntpoint);
1073 	SAFE_FILE_PRINTF(buf, "file content");
1074 	SAFE_CHMOD(buf, 0777);
1075 
1076 	SAFE_MOUNT(dev, mntpoint, fs_type, MS_REMOUNT | MS_RDONLY, NULL);
1077 
1078 	return 0;
1079 }
1080 
prepare_and_mount_dev_fs(const char * mntpoint)1081 static void prepare_and_mount_dev_fs(const char *mntpoint)
1082 {
1083 	const char *flags[] = {"nodev", NULL};
1084 	int mounted_nodev;
1085 
1086 	mounted_nodev = tst_path_has_mnt_flags(NULL, flags);
1087 	if (mounted_nodev) {
1088 		tst_res(TINFO, "tmpdir isn't suitable for creating devices, "
1089 			"mounting tmpfs without nodev on %s", mntpoint);
1090 		SAFE_MOUNT(NULL, mntpoint, "tmpfs", 0, NULL);
1091 		mntpoint_mounted = 1;
1092 	}
1093 }
1094 
prepare_and_mount_hugetlb_fs(void)1095 static void prepare_and_mount_hugetlb_fs(void)
1096 {
1097 	SAFE_MOUNT("none", tst_test->mntpoint, "hugetlbfs", 0, NULL);
1098 	mntpoint_mounted = 1;
1099 }
1100 
tst_creat_unlinked(const char * path,int flags,mode_t mode)1101 int tst_creat_unlinked(const char *path, int flags, mode_t mode)
1102 {
1103 	char template[PATH_MAX];
1104 	int len, c, range;
1105 	int fd;
1106 	int start[3] = {'0', 'a', 'A'};
1107 
1108 	snprintf(template, PATH_MAX, "%s/ltp_%.3sXXXXXX",
1109 			path, tid);
1110 
1111 	len = strlen(template) - 1;
1112 	while (template[len] == 'X') {
1113 		c = rand() % 3;
1114 		range = start[c] == '0' ? 10 : 26;
1115 		c = start[c] + (rand() % range);
1116 		template[len--] = (char)c;
1117 	}
1118 
1119 	flags |= O_CREAT|O_EXCL|O_RDWR;
1120 	fd = SAFE_OPEN(template, flags, mode);
1121 	SAFE_UNLINK(template);
1122 	return fd;
1123 }
1124 
limit_tmpfs_mount_size(const char * mnt_data,char * buf,size_t buf_size,const char * fs_type)1125 static const char *limit_tmpfs_mount_size(const char *mnt_data,
1126 		char *buf, size_t buf_size, const char *fs_type)
1127 {
1128 	unsigned int tmpfs_size;
1129 
1130 	if (strcmp(fs_type, "tmpfs"))
1131 		return mnt_data;
1132 
1133 	if (!tst_test->dev_min_size)
1134 		tmpfs_size = 32;
1135 	else
1136 		tmpfs_size = tdev.size;
1137 
1138 	if ((tst_available_mem() / 1024) < (tmpfs_size * 2))
1139 		tst_brk(TCONF, "No enough memory for tmpfs use");
1140 
1141 	if (mnt_data)
1142 		snprintf(buf, buf_size, "%s,size=%uM", mnt_data, tmpfs_size);
1143 	else
1144 		snprintf(buf, buf_size, "size=%uM", tmpfs_size);
1145 
1146 	tst_res(TINFO, "Limiting tmpfs size to %uMB", tmpfs_size);
1147 
1148 	return buf;
1149 }
1150 
get_device_name(const char * fs_type)1151 static const char *get_device_name(const char *fs_type)
1152 {
1153 	if (!strcmp(fs_type, "tmpfs"))
1154 		return "ltp-tmpfs";
1155 	else
1156 		return tdev.dev;
1157 }
1158 
prepare_device(struct tst_fs * fs)1159 static void prepare_device(struct tst_fs *fs)
1160 {
1161 	const char *mnt_data;
1162 	char buf[1024];
1163 	struct tst_fs dummy = {};
1164 
1165 	fs = fs ?: &dummy;
1166 
1167 	const char *const extra[] = {fs->mkfs_size_opt, NULL};
1168 
1169 	if (tst_test->format_device)
1170 		SAFE_MKFS(tdev.dev, tdev.fs_type, fs->mkfs_opts, extra);
1171 
1172 	if (tst_test->needs_rofs) {
1173 		prepare_and_mount_ro_fs(tdev.dev, tst_test->mntpoint,
1174 					tdev.fs_type);
1175 		return;
1176 	}
1177 
1178 	if (tst_test->mount_device) {
1179 		mnt_data = limit_tmpfs_mount_size(fs->mnt_data,
1180 				buf, sizeof(buf), tdev.fs_type);
1181 
1182 		SAFE_MOUNT(get_device_name(tdev.fs_type), tst_test->mntpoint,
1183 				tdev.fs_type, fs->mnt_flags, mnt_data);
1184 		mntpoint_mounted = 1;
1185 	}
1186 }
1187 
do_cgroup_requires(void)1188 static void do_cgroup_requires(void)
1189 {
1190 	const struct tst_cg_opts cg_opts = {
1191 		.needs_ver = tst_test->needs_cgroup_ver,
1192 		.needs_nsdelegate = tst_test->needs_cgroup_nsdelegate,
1193 	};
1194 	const char *const *ctrl_names = tst_test->needs_cgroup_ctrls;
1195 
1196 	for (; *ctrl_names; ctrl_names++)
1197 		tst_cg_require(*ctrl_names, &cg_opts);
1198 
1199 	tst_cg_init();
1200 }
1201 
1202 #define tst_set_ulimit(conf) \
1203 	set_ulimit_(__FILE__, __LINE__, (conf))
1204 
1205 /*
1206  * Set resource limits.
1207  */
set_ulimit_(const char * file,const int lineno,const struct tst_ulimit_val * conf)1208 static void set_ulimit_(const char *file, const int lineno, const struct tst_ulimit_val *conf)
1209 {
1210 	struct rlimit rlim;
1211 
1212 	safe_getrlimit(file, lineno, conf->resource, &rlim);
1213 
1214 	rlim.rlim_cur = conf->rlim_cur;
1215 
1216 	if (conf->rlim_cur > rlim.rlim_max)
1217 		rlim.rlim_max = conf->rlim_cur;
1218 
1219 	tst_res_(file, lineno, TINFO, "Set ulimit resource: %d rlim_cur: %llu rlim_max: %llu",
1220 		conf->resource, (long long unsigned int)rlim.rlim_cur,
1221 		(long long unsigned int)rlim.rlim_max);
1222 
1223 	safe_setrlimit(file, lineno, conf->resource, &rlim);
1224 }
1225 
count_fs_descs(void)1226 static unsigned int count_fs_descs(void)
1227 {
1228 	unsigned int ret = 0;
1229 
1230 	if (!tst_test->filesystems)
1231 		return 0;
1232 
1233 	/*
1234 	 * First entry is special, if it has zero type it's the default entry
1235 	 * and is either followed by a terminating entry or by filesystem
1236 	 * description(s) plus terminating entry.
1237 	 */
1238 	if (!tst_test->filesystems[0].type)
1239 		ret = 1;
1240 
1241 	while (tst_test->filesystems[ret].type)
1242 		ret++;
1243 
1244 	return ret;
1245 }
1246 
default_fs_type(void)1247 static const char *default_fs_type(void)
1248 {
1249 	if (!tst_test->filesystems)
1250 		return tst_dev_fs_type();
1251 
1252 	if (tst_test->filesystems[0].type)
1253 		return tst_test->filesystems[0].type;
1254 
1255 	return tst_dev_fs_type();
1256 }
1257 
do_setup(int argc,char * argv[])1258 static void do_setup(int argc, char *argv[])
1259 {
1260 	char *tdebug_env = getenv("LTP_ENABLE_DEBUG");
1261 
1262 	if (!tst_test)
1263 		tst_brk(TBROK, "No tests to run");
1264 
1265 	if (tst_test->timeout < -1) {
1266 		tst_brk(TBROK, "Invalid timeout value %i",
1267 			tst_test->timeout);
1268 	}
1269 
1270 	if (tst_test->runtime < 0) {
1271 		tst_brk(TBROK, "Invalid runtime value %i",
1272 			results->runtime);
1273 	}
1274 
1275 	if (tst_test->tconf_msg)
1276 		tst_brk(TCONF, "%s", tst_test->tconf_msg);
1277 
1278 	assert_test_fn();
1279 
1280 	TCID = tid = get_tid(argv);
1281 
1282 	if (tst_test->sample)
1283 		tst_test = tst_timer_test_setup(tst_test);
1284 
1285 	parse_opts(argc, argv);
1286 
1287 	if (tdebug_env && (!strcmp(tdebug_env, "1") || !strcmp(tdebug_env, "y"))) {
1288 		tst_res(TINFO, "Enabling debug info");
1289 		tdebug = 1;
1290 	}
1291 
1292 	if (tst_test->runs_script) {
1293 		tst_test->child_needs_reinit = 1;
1294 		tst_test->forks_child = 1;
1295 	}
1296 
1297 	if (tst_test->needs_kconfigs && tst_kconfig_check(tst_test->needs_kconfigs))
1298 		tst_brk(TCONF, "Aborting due to unsuitable kernel config, see above!");
1299 
1300 	if (tst_test->needs_root && geteuid() != 0)
1301 		tst_brk(TCONF, "Test needs to be run as root");
1302 
1303 	if (tst_test->min_kver)
1304 		check_kver(tst_test->min_kver, 1);
1305 
1306 	if (tst_test->supported_archs && !tst_is_on_arch(tst_test->supported_archs))
1307 		tst_brk(TCONF, "This arch '%s' is not supported for test!", tst_arch.name);
1308 
1309 	if (tst_test->skip_in_lockdown && tst_lockdown_enabled() > 0)
1310 		tst_brk(TCONF, "Kernel is locked down, skipping test");
1311 
1312 	if (tst_test->skip_in_secureboot && tst_secureboot_enabled() > 0)
1313 		tst_brk(TCONF, "SecureBoot enabled, skipping test");
1314 
1315 	if (tst_test->skip_in_compat && tst_is_compat_mode())
1316 		tst_brk(TCONF, "Not supported in 32-bit compat mode");
1317 
1318 	if (tst_test->needs_abi_bits && !tst_abi_bits(tst_test->needs_abi_bits))
1319 		tst_brk(TCONF, "%dbit ABI is not supported", tst_test->needs_abi_bits);
1320 
1321 	if (tst_test->needs_cmds) {
1322 		const char *cmd;
1323 		int i;
1324 
1325 		for (i = 0; (cmd = tst_test->needs_cmds[i]); ++i)
1326 			tst_check_cmd(cmd, 1);
1327 	}
1328 
1329 	if (tst_test->needs_drivers) {
1330 		const char *name;
1331 		int i;
1332 
1333 		for (i = 0; (name = tst_test->needs_drivers[i]); ++i)
1334 			if (tst_check_driver(name))
1335 				tst_brk(TCONF, "%s driver not available", name);
1336 	}
1337 
1338 	if (tst_test->mount_device)
1339 		tst_test->format_device = 1;
1340 
1341 	if (tst_test->format_device)
1342 		tst_test->needs_device = 1;
1343 
1344 	if (tst_test->all_filesystems)
1345 		tst_test->needs_device = 1;
1346 
1347 	if (tst_test->min_cpus > (unsigned long)tst_ncpus())
1348 		tst_brk(TCONF, "Test needs at least %lu CPUs online", tst_test->min_cpus);
1349 
1350 	if (tst_test->min_mem_avail > (unsigned long)(tst_available_mem() / 1024))
1351 		tst_brk(TCONF, "Test needs at least %luMB MemAvailable", tst_test->min_mem_avail);
1352 
1353 	if (tst_test->min_swap_avail > (unsigned long)(tst_available_swap() / 1024))
1354 		tst_brk(TCONF, "Test needs at least %luMB SwapFree", tst_test->min_swap_avail);
1355 
1356 	if (tst_test->hugepages.number)
1357 		tst_reserve_hugepages(&tst_test->hugepages);
1358 
1359 	setup_ipc();
1360 
1361 	if (tst_test->bufs)
1362 		tst_buffers_alloc(tst_test->bufs);
1363 
1364 	if (needs_tmpdir() && !tst_tmpdir_created())
1365 		tst_tmpdir();
1366 
1367 	if (tst_test->save_restore) {
1368 		const struct tst_path_val *pvl = tst_test->save_restore;
1369 
1370 		while (pvl->path) {
1371 			tst_sys_conf_save(pvl);
1372 			pvl++;
1373 		}
1374 	}
1375 
1376 	if (tst_test->ulimit) {
1377 		const struct tst_ulimit_val *pvl = tst_test->ulimit;
1378 
1379 		while (pvl->resource) {
1380 			tst_set_ulimit(pvl);
1381 			pvl++;
1382 		}
1383 	}
1384 
1385 	if (tst_test->mntpoint)
1386 		SAFE_MKDIR(tst_test->mntpoint, 0777);
1387 
1388 	if ((tst_test->needs_devfs || tst_test->needs_rofs ||
1389 	     tst_test->mount_device || tst_test->all_filesystems ||
1390 		 tst_test->needs_hugetlbfs) &&
1391 	     !tst_test->mntpoint) {
1392 		tst_brk(TBROK, "tst_test->mntpoint must be set!");
1393 	}
1394 
1395 	if (!!tst_test->needs_rofs + !!tst_test->needs_devfs +
1396 	    !!tst_test->needs_device + !!tst_test->needs_hugetlbfs > 1) {
1397 		tst_brk(TBROK,
1398 			"Two or more of needs_{rofs, devfs, device, hugetlbfs} are set");
1399 	}
1400 
1401 	if (tst_test->needs_devfs)
1402 		prepare_and_mount_dev_fs(tst_test->mntpoint);
1403 
1404 	if (tst_test->needs_rofs) {
1405 		/* If we failed to mount read-only tmpfs. Fallback to
1406 		 * using a device with read-only filesystem.
1407 		 */
1408 		if (prepare_and_mount_ro_fs(NULL, tst_test->mntpoint, "tmpfs")) {
1409 			tst_res(TINFO, "Can't mount tmpfs read-only, "
1410 				"falling back to block device...");
1411 			tst_test->needs_device = 1;
1412 			tst_test->format_device = 1;
1413 		}
1414 	}
1415 
1416 	if (tst_test->needs_hugetlbfs)
1417 		prepare_and_mount_hugetlb_fs();
1418 
1419 	if (tst_test->needs_device && !mntpoint_mounted) {
1420 		tdev.dev = tst_acquire_device_(NULL, tst_test->dev_min_size);
1421 
1422 		if (!tdev.dev)
1423 			tst_brk(TCONF, "Failed to acquire device");
1424 
1425 		tdev.size = tst_get_device_size(tdev.dev);
1426 
1427 		tst_device = &tdev;
1428 
1429 		tdev.fs_type = default_fs_type();
1430 
1431 		if (!tst_test->all_filesystems && count_fs_descs() <= 1) {
1432 			if (tst_test->filesystems && tst_test->filesystems->mkfs_ver)
1433 				tst_check_cmd(tst_test->filesystems->mkfs_ver, 1);
1434 
1435 			if (tst_test->filesystems && tst_test->filesystems->min_kver)
1436 				check_kver(tst_test->filesystems->min_kver, 1);
1437 
1438 			prepare_device(tst_test->filesystems);
1439 		}
1440 	}
1441 
1442 	if (tst_test->needs_overlay && !tst_test->mount_device)
1443 		tst_brk(TBROK, "tst_test->mount_device must be set");
1444 
1445 	if (tst_test->needs_overlay && !mntpoint_mounted)
1446 		tst_brk(TBROK, "tst_test->mntpoint must be mounted");
1447 
1448 	if (tst_test->needs_overlay && !ovl_mounted) {
1449 		SAFE_MOUNT_OVERLAY();
1450 		ovl_mounted = 1;
1451 	}
1452 
1453 	if (tst_test->resource_files)
1454 		copy_resources();
1455 
1456 	if (tst_test->restore_wallclock)
1457 		tst_wallclock_save();
1458 
1459 	if (tst_test->taint_check)
1460 		tst_taint_init(tst_test->taint_check);
1461 
1462 	if (tst_test->needs_cgroup_ctrls)
1463 		do_cgroup_requires();
1464 	else if (tst_test->needs_cgroup_ver)
1465 		tst_brk(TBROK, "tst_test->needs_cgroup_ctrls must be set");
1466 }
1467 
do_test_setup(void)1468 static void do_test_setup(void)
1469 {
1470 	main_pid = getpid();
1471 
1472 	if (!tst_test->all_filesystems && tst_test->skip_filesystems) {
1473 		long fs_type = tst_fs_type(".");
1474 		const char *fs_name = tst_fs_type_name(fs_type);
1475 
1476 		if (tst_fs_in_skiplist(fs_name, tst_test->skip_filesystems)) {
1477 			tst_brk(TCONF, "%s is not supported by the test",
1478 				fs_name);
1479 		}
1480 
1481 		tst_res(TINFO, "%s is supported by the test", fs_name);
1482 	}
1483 
1484 	if (tst_test->caps)
1485 		tst_cap_setup(tst_test->caps, TST_CAP_REQ);
1486 
1487 	if (tst_test->setup)
1488 		tst_test->setup();
1489 
1490 	if (main_pid != tst_getpid())
1491 		tst_brk(TBROK, "Runaway child in setup()!");
1492 
1493 	if (tst_test->caps)
1494 		tst_cap_setup(tst_test->caps, TST_CAP_DROP);
1495 }
1496 
do_cleanup(void)1497 static void do_cleanup(void)
1498 {
1499 	if (tst_test->needs_cgroup_ctrls)
1500 		tst_cg_cleanup();
1501 
1502 	if (ovl_mounted)
1503 		SAFE_UMOUNT(OVL_MNT);
1504 
1505 	if (mntpoint_mounted)
1506 		tst_umount(tst_test->mntpoint);
1507 
1508 	if (tst_test->needs_device && tdev.dev)
1509 		tst_release_device(tdev.dev);
1510 
1511 	if (tst_tmpdir_created()) {
1512 		/* avoid munmap() on wrong pointer in tst_rmdir() */
1513 		tst_futexes = NULL;
1514 		tst_rmdir();
1515 	}
1516 
1517 	tst_sys_conf_restore(0);
1518 
1519 	if (tst_test->restore_wallclock)
1520 		tst_wallclock_restore();
1521 
1522 	cleanup_ipc();
1523 }
1524 
heartbeat(void)1525 static void heartbeat(void)
1526 {
1527 	if (tst_clock_gettime(CLOCK_MONOTONIC, &tst_start_time))
1528 		tst_res(TWARN | TERRNO, "tst_clock_gettime() failed");
1529 
1530 	if (getppid() == 1) {
1531 		tst_res(TFAIL, "Main test process might have exit!");
1532 		/*
1533 		 * We need kill the task group immediately since the
1534 		 * main process has exit.
1535 		 */
1536 		kill(0, SIGKILL);
1537 		exit(TBROK);
1538 	}
1539 
1540 	kill(getppid(), SIGUSR1);
1541 }
1542 
run_tests(void)1543 static void run_tests(void)
1544 {
1545 	unsigned int i;
1546 	struct results saved_results;
1547 
1548 	if (!tst_test->test) {
1549 		saved_results = *results;
1550 		heartbeat();
1551 		tst_test->test_all();
1552 
1553 		if (tst_getpid() != main_pid)
1554 			exit(0);
1555 
1556 		tst_reap_children();
1557 
1558 		if (results_equal(&saved_results, results))
1559 			tst_brk(TBROK, "Test haven't reported results!");
1560 		return;
1561 	}
1562 
1563 	for (i = 0; i < tst_test->tcnt; i++) {
1564 		saved_results = *results;
1565 		heartbeat();
1566 		tst_test->test(i);
1567 
1568 		if (tst_getpid() != main_pid)
1569 			exit(0);
1570 
1571 		tst_reap_children();
1572 
1573 		if (results_equal(&saved_results, results))
1574 			tst_brk(TBROK, "Test %i haven't reported results!", i);
1575 	}
1576 }
1577 
get_time_ms(void)1578 static unsigned long long get_time_ms(void)
1579 {
1580 	struct timespec ts;
1581 
1582 	if (tst_clock_gettime(CLOCK_MONOTONIC, &ts))
1583 		tst_brk(TBROK | TERRNO, "tst_clock_gettime()");
1584 
1585 	return tst_timespec_to_ms(ts);
1586 }
1587 
add_paths(void)1588 static void add_paths(void)
1589 {
1590 	char *old_path = getenv("PATH");
1591 	const char *start_dir;
1592 	char *new_path;
1593 
1594 	start_dir = tst_get_startwd();
1595 
1596 	if (old_path)
1597 		SAFE_ASPRINTF(&new_path, "%s::%s", old_path, start_dir);
1598 	else
1599 		SAFE_ASPRINTF(&new_path, "::%s", start_dir);
1600 
1601 	SAFE_SETENV("PATH", new_path, 1);
1602 	free(new_path);
1603 }
1604 
testrun(void)1605 static void testrun(void)
1606 {
1607 	unsigned int i = 0;
1608 	unsigned long long stop_time = 0;
1609 	int cont = 1;
1610 
1611 	heartbeat();
1612 	add_paths();
1613 	do_test_setup();
1614 
1615 	if (duration > 0)
1616 		stop_time = get_time_ms() + (unsigned long long)(duration * 1000);
1617 
1618 	for (;;) {
1619 		cont = 0;
1620 
1621 		if (i < (unsigned int)iterations) {
1622 			i++;
1623 			cont = 1;
1624 		}
1625 
1626 		if (stop_time && get_time_ms() < stop_time)
1627 			cont = 1;
1628 
1629 		if (!cont)
1630 			break;
1631 
1632 		run_tests();
1633 		heartbeat();
1634 	}
1635 
1636 	do_test_cleanup();
1637 	exit(0);
1638 }
1639 
1640 static pid_t test_pid;
1641 
1642 
1643 static volatile sig_atomic_t sigkill_retries;
1644 
1645 #define WRITE_MSG(msg) do { \
1646 	if (write(2, msg, sizeof(msg) - 1)) { \
1647 		/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 */ \
1648 	} \
1649 } while (0)
1650 
alarm_handler(int sig LTP_ATTRIBUTE_UNUSED)1651 static void alarm_handler(int sig LTP_ATTRIBUTE_UNUSED)
1652 {
1653 	WRITE_MSG("Test timeouted, sending SIGKILL!\n");
1654 	kill(-test_pid, SIGKILL);
1655 	alarm(5);
1656 
1657 	if (++sigkill_retries > 10) {
1658 		WRITE_MSG("Cannot kill test processes!\n");
1659 		WRITE_MSG("Congratulation, likely test hit a kernel bug.\n");
1660 		WRITE_MSG("Exiting uncleanly...\n");
1661 		_exit(TFAIL);
1662 	}
1663 }
1664 
heartbeat_handler(int sig LTP_ATTRIBUTE_UNUSED)1665 static void heartbeat_handler(int sig LTP_ATTRIBUTE_UNUSED)
1666 {
1667 	alarm(results->overall_time);
1668 	sigkill_retries = 0;
1669 }
1670 
sigint_handler(int sig LTP_ATTRIBUTE_UNUSED)1671 static void sigint_handler(int sig LTP_ATTRIBUTE_UNUSED)
1672 {
1673 	if (test_pid > 0) {
1674 		WRITE_MSG("Sending SIGKILL to test process...\n");
1675 		kill(-test_pid, SIGKILL);
1676 	}
1677 }
1678 
tst_remaining_runtime(void)1679 unsigned int tst_remaining_runtime(void)
1680 {
1681 	static struct timespec now;
1682 	int elapsed;
1683 
1684 	if (results->runtime == 0)
1685 		tst_brk(TBROK, "Runtime not set!");
1686 
1687 	if (tst_clock_gettime(CLOCK_MONOTONIC, &now))
1688 		tst_res(TWARN | TERRNO, "tst_clock_gettime() failed");
1689 
1690 	elapsed = tst_timespec_diff_ms(now, tst_start_time) / 1000;
1691 	if (results->runtime > (unsigned int) elapsed)
1692 		return results->runtime - elapsed;
1693 
1694 	return 0;
1695 }
1696 
1697 
tst_multiply_timeout(unsigned int timeout)1698 unsigned int tst_multiply_timeout(unsigned int timeout)
1699 {
1700 	parse_mul(&timeout_mul, "LTP_TIMEOUT_MUL", 0.099, 10000);
1701 
1702 	if (timeout < 1)
1703 		tst_brk(TBROK, "timeout must to be >= 1! (%d)", timeout);
1704 
1705 	if (tst_has_slow_kconfig())
1706 		timeout *= 4;
1707 
1708 	return timeout * timeout_mul;
1709 }
1710 
set_overall_timeout(void)1711 static void set_overall_timeout(void)
1712 {
1713 	unsigned int timeout = DEFAULT_TIMEOUT + tst_test->timeout;
1714 
1715 	if (tst_test->timeout == TST_UNLIMITED_TIMEOUT) {
1716 		tst_res(TINFO, "Test timeout is not limited");
1717 		return;
1718 	}
1719 
1720 	results->overall_time = tst_multiply_timeout(timeout) + results->runtime;
1721 
1722 	tst_res(TINFO, "Overall timeout per run is %uh %02um %02us",
1723 		results->overall_time/3600, (results->overall_time%3600)/60,
1724 		results->overall_time % 60);
1725 }
1726 
tst_set_timeout(int timeout)1727 void tst_set_timeout(int timeout)
1728 {
1729 	int timeout_adj = DEFAULT_TIMEOUT + timeout;
1730 
1731 	results->overall_time = tst_multiply_timeout(timeout_adj) + results->runtime;
1732 
1733 	tst_res(TINFO, "Overall timeout per run is %uh %02um %02us",
1734 		results->overall_time/3600, (results->overall_time%3600)/60,
1735 		results->overall_time % 60);
1736 
1737 	heartbeat();
1738 }
1739 
tst_set_runtime(int runtime)1740 void tst_set_runtime(int runtime)
1741 {
1742 	results->runtime = multiply_runtime(runtime);
1743 	tst_res(TINFO, "Updating runtime to %uh %02um %02us",
1744 		runtime/3600, (runtime%3600)/60, runtime % 60);
1745 	set_overall_timeout();
1746 	heartbeat();
1747 }
1748 
fork_testrun(void)1749 static int fork_testrun(void)
1750 {
1751 	int status;
1752 
1753 	SAFE_SIGNAL(SIGINT, sigint_handler);
1754 	SAFE_SIGNAL(SIGTERM, sigint_handler);
1755 
1756 	alarm(results->overall_time);
1757 
1758 	show_failure_hints = 1;
1759 
1760 	test_pid = fork();
1761 	if (test_pid < 0)
1762 		tst_brk(TBROK | TERRNO, "fork()");
1763 
1764 	if (!test_pid) {
1765 		tst_disable_oom_protection(0);
1766 		SAFE_SIGNAL(SIGALRM, SIG_DFL);
1767 		SAFE_SIGNAL(SIGUSR1, SIG_DFL);
1768 		SAFE_SIGNAL(SIGTERM, SIG_DFL);
1769 		SAFE_SIGNAL(SIGINT, SIG_DFL);
1770 		SAFE_SETPGID(0, 0);
1771 		testrun();
1772 	}
1773 
1774 	SAFE_WAITPID(test_pid, &status, 0);
1775 	alarm(0);
1776 	SAFE_SIGNAL(SIGTERM, SIG_DFL);
1777 	SAFE_SIGNAL(SIGINT, SIG_DFL);
1778 
1779 	if (tst_test->taint_check && tst_taint_check()) {
1780 		tst_res(TFAIL, "Kernel is now tainted.");
1781 		return TFAIL;
1782 	}
1783 
1784 	if (tst_test->forks_child && kill(-test_pid, SIGKILL) == 0)
1785 		tst_res(TINFO, "Killed the leftover descendant processes");
1786 
1787 	if (WIFEXITED(status) && WEXITSTATUS(status))
1788 		return WEXITSTATUS(status);
1789 
1790 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) {
1791 		tst_res(TINFO, "If you are running on slow machine, "
1792 			       "try exporting LTP_TIMEOUT_MUL > 1");
1793 		tst_brk(TBROK, "Test killed! (timeout?)");
1794 	}
1795 
1796 	if (WIFSIGNALED(status))
1797 		tst_brk(TBROK, "Test killed by %s!", tst_strsig(WTERMSIG(status)));
1798 
1799 	return 0;
1800 }
1801 
lookup_fs_desc(const char * fs_type,int all_filesystems)1802 static struct tst_fs *lookup_fs_desc(const char *fs_type, int all_filesystems)
1803 {
1804 	struct tst_fs *fs = tst_test->filesystems;
1805 	static struct tst_fs empty;
1806 
1807 	if (!fs)
1808 		goto ret;
1809 
1810 	for (; fs->type; fs++) {
1811 
1812 		if (!fs->type)
1813 			continue;
1814 
1815 		if (!strcmp(fs_type, fs->type))
1816 			return fs;
1817 	}
1818 
1819 ret:
1820 	if (!all_filesystems)
1821 		return NULL;
1822 
1823 	if (!tst_test->filesystems || tst_test->filesystems[0].type)
1824 		return &empty;
1825 
1826 	return &tst_test->filesystems[0];
1827 }
1828 
run_tcase_on_fs(struct tst_fs * fs,const char * fs_type)1829 static int run_tcase_on_fs(struct tst_fs *fs, const char *fs_type)
1830 {
1831 	int ret;
1832 
1833 	tst_res(TINFO, "=== Testing on %s ===", fs_type);
1834 	tdev.fs_type = fs_type;
1835 
1836 	if (fs->mkfs_ver && tst_check_cmd(fs->mkfs_ver, 0))
1837 		return TCONF;
1838 
1839 	if (fs->min_kver && check_kver(fs->min_kver, 0))
1840 		return TCONF;
1841 
1842 	prepare_device(fs);
1843 
1844 	ret = fork_testrun();
1845 
1846 	if (mntpoint_mounted) {
1847 		tst_umount(tst_test->mntpoint);
1848 		mntpoint_mounted = 0;
1849 	}
1850 
1851 	return ret;
1852 }
1853 
run_tcases_per_fs(void)1854 static int run_tcases_per_fs(void)
1855 {
1856 	int ret = 0;
1857 	unsigned int i;
1858 	const char *const *filesystems = tst_get_supported_fs_types(tst_test->skip_filesystems);
1859 
1860 	if (!filesystems[0])
1861 		tst_brk(TCONF, "There are no supported filesystems");
1862 
1863 	for (i = 0; filesystems[i]; i++) {
1864 		struct tst_fs *fs = lookup_fs_desc(filesystems[i], tst_test->all_filesystems);
1865 
1866 		if (!fs)
1867 			continue;
1868 
1869 		ret = run_tcase_on_fs(fs, filesystems[i]);
1870 
1871 		if (ret == TCONF)
1872 			continue;
1873 
1874 		if (ret == 0)
1875 			continue;
1876 
1877 		do_exit(ret);
1878 	}
1879 
1880 	return ret;
1881 }
1882 
1883 unsigned int tst_variant;
1884 
tst_run_tcases(int argc,char * argv[],struct tst_test * self)1885 void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
1886 {
1887 	int ret = 0;
1888 	unsigned int test_variants = 1;
1889 	struct utsname uval;
1890 
1891 	lib_pid = getpid();
1892 	tst_test = self;
1893 
1894 	do_setup(argc, argv);
1895 	tst_enable_oom_protection(lib_pid);
1896 
1897 	SAFE_SIGNAL(SIGALRM, alarm_handler);
1898 	SAFE_SIGNAL(SIGUSR1, heartbeat_handler);
1899 
1900 	tst_res(TINFO, "LTP version: "LTP_VERSION);
1901 
1902 
1903 	uname(&uval);
1904 	tst_res(TINFO, "Tested kernel: %s %s %s", uval.release, uval.version, uval.machine);
1905 
1906 	if (tst_test->runtime)
1907 		results->runtime = multiply_runtime(tst_test->runtime);
1908 
1909 	set_overall_timeout();
1910 
1911 	if (tst_test->test_variants)
1912 		test_variants = tst_test->test_variants;
1913 
1914 	for (tst_variant = 0; tst_variant < test_variants; tst_variant++) {
1915 		if (tst_test->all_filesystems || count_fs_descs() > 1)
1916 			ret |= run_tcases_per_fs();
1917 		else
1918 			ret |= fork_testrun();
1919 
1920 		if (ret & ~(TCONF))
1921 			goto exit;
1922 	}
1923 
1924 exit:
1925 	do_exit(ret);
1926 }
1927 
1928 
tst_flush(void)1929 void tst_flush(void)
1930 {
1931 	int rval;
1932 
1933 	rval = fflush(stderr);
1934 	if (rval != 0)
1935 		tst_brk(TBROK | TERRNO, "fflush(stderr) failed");
1936 
1937 	rval = fflush(stdout);
1938 	if (rval != 0)
1939 		tst_brk(TBROK | TERRNO, "fflush(stdout) failed");
1940 
1941 }
1942