void testoom(int mempolicy, int lite, int retcode, int allow_sigkill) { int ksm_run_orig; set_global_mempolicy(mempolicy); tst_res(TINFO, "start normal OOM testing."); oom(NORMAL, lite, retcode, allow_sigkill); tst_res(TINFO, "start OOM testing for mlocked pages."); oom(MLOCK, lite, retcode, allow_sigkill); /* * Skip oom(KSM) if lite == 1, since limit_in_bytes may vary from * run to run, which isn't reliable for oom03 cgroup test. */ if (access(PATH_KSM, F_OK) == -1 || lite == 1) { tst_res(TINFO, "KSM is not configed or lite == 1, " "skip OOM test for KSM pags"); } else { tst_res(TINFO, "start OOM testing for KSM pages."); SAFE_FILE_SCANF(PATH_KSM "run", "%d", &ksm_run_orig); SAFE_FILE_PRINTF(PATH_KSM "run", "1"); oom(KSM, lite, retcode, allow_sigkill); SAFE_FILE_PRINTF(PATH_KSM "run", "%d", ksm_run_orig); } }
static void ksm_child_memset(int child_num, int size, int total_unit, struct ksm_merge_data ksm_merge_data, char **memory) { int i = 0, j; int unit = size / total_unit; tst_res(TINFO, "child %d continues...", child_num); if (ksm_merge_data.mergeable_size == size * MB) { tst_res(TINFO, "child %d allocates %d MB filled with '%c'", child_num, size, ksm_merge_data.data); } else { tst_res(TINFO, "child %d allocates %d MB filled with '%c'" " except one page with 'e'", child_num, size, ksm_merge_data.data); } for (j = 0; j < total_unit; j++) { for (i = 0; (unsigned int)i < unit * MB; i++) memory[j][i] = ksm_merge_data.data; } /* if it contains unshared page, then set 'e' char * at the end of the last page */ if (ksm_merge_data.mergeable_size < size * MB) memory[j-1][i-1] = 'e'; }
static void verify_quota(void) { struct fs_disk_quota res_dquota; res_dquota.d_id = 1; TEST(quotactl(QCMD(Q_XGETNEXTQUOTA, USRQUOTA), tst_device->dev, test_id, (void *)&res_dquota)); if (TST_RET != -1) { tst_res(TFAIL, "quotactl() found the next active ID:" " %u unexpectedly", res_dquota.d_id); return; } if (TST_ERR == EINVAL) { tst_brk(TCONF | TTERRNO, "Q_XGETNEXTQUOTA wasn't supported in quotactl()"); } if (TST_ERR != ENOENT) { tst_res(TFAIL | TTERRNO, "quotactl() failed unexpectedly with" " %s expected ENOENT", tst_strerrno(TST_ERR)); } else { tst_res(TPASS, "quotactl() failed with ENOENT as expected"); } }
static void verify_socketpair(unsigned int n) { int res, i; struct tcase *tc = &tcases[n]; TEST(socketpair(PF_UNIX, tc->type, 0, fds)); if (TEST_RETURN == -1) tst_brk(TFAIL | TTERRNO, "socketpair() failed"); for (i = 0; i < 2; i++) { res = SAFE_FCNTL(fds[i], tc->fl_flag); if (tc->flag != 0 && (res & tc->flag) == 0) { tst_res(TFAIL, "socketpair() failed to set %s flag for fds[%d]", tc->des, i); goto ret; } if (tc->flag == 0 && (res & tc->flag) != 0) { tst_res(TFAIL, "socketpair() failed to set %s flag for fds[%d]", tc->des, i); goto ret; } } tst_res(TPASS, "socketpair() passed to set %s flag", tc->des); ret: SAFE_CLOSE(fds[0]); SAFE_CLOSE(fds[1]); }
static void test_hugemmap(void) { long page_sz = 0; fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666); beforetest = SAFE_READ_MEMINFO("HugePages_Free:"); page_sz = SAFE_READ_MEMINFO("Hugepagesize:") * 1024; addr = mmap(NULL, page_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fildes, 0); if (addr == MAP_FAILED) { tst_res(TFAIL | TERRNO, "mmap() Failed on %s", TEMPFILE); } else { tst_res(TPASS, "call succeeded"); /* force to allocate page and change HugePages_Free */ *(int *)addr = 0; /* Make sure the number of free huge pages AFTER testing decreased */ aftertest = SAFE_READ_MEMINFO("HugePages_Free:"); hugepagesmapped = beforetest - aftertest; if (hugepagesmapped < 1) tst_res(TWARN, "Number of HUGEPAGES_FREE stayed the" " same. Okay if multiple copies running due" " to test collision."); munmap(addr, page_sz); } close(fildes); }
static void verify_socketpair(unsigned int n) { struct test_case_t *tc = &tdat[n]; TEST(socketpair(tc->domain, tc->type, tc->proto, tc->sv)); if (TST_RET == 0) { SAFE_CLOSE(fds[0]); SAFE_CLOSE(fds[1]); } if (TST_RET != tc->retval) { tst_res(TFAIL, "%s returned %ld (expected %d)", tc->desc, TST_RET, tc->retval); return; } if (TST_ERR != tc->experrno) { tst_res(TFAIL | TTERRNO, "expected %s(%d)", tst_strerrno(tc->experrno), tc->experrno); return; } tst_res(TPASS, "%s successful", tc->desc); }
static void verify_event(int group, struct fanotify_event_metadata *event, uint32_t expect) { if (event->mask != expect) { tst_res(TFAIL, "group %d got event: mask %llx (expected %llx) " "pid=%u fd=%d", group, (unsigned long long)event->mask, (unsigned long long)expect, (unsigned)event->pid, event->fd); } else if (event->pid != getpid()) { tst_res(TFAIL, "group %d got event: mask %llx pid=%u " "(expected %u) fd=%d", group, (unsigned long long)event->mask, (unsigned)event->pid, (unsigned)getpid(), event->fd); } else { int len; sprintf(symlnk, "/proc/self/fd/%d", event->fd); len = readlink(symlnk, fdpath, sizeof(fdpath)); if (len < 0) len = 0; fdpath[len] = 0; tst_res(TPASS, "group %d got event: mask %llx pid=%u fd=%d path=%s", group, (unsigned long long)event->mask, (unsigned)event->pid, event->fd, fdpath); } }
void tst_set_timeout(int timeout) { char *mul = getenv("LTP_TIMEOUT_MUL"); if (timeout == -1) { tst_res(TINFO, "Timeout per run is disabled"); return; } results->timeout = timeout; if (mul) { float m = atof(mul); if (m < 1) tst_brk(TBROK, "Invalid timeout multiplier '%s'", mul); results->timeout = results->timeout * m + 0.5; } tst_res(TINFO, "Timeout per run is %uh %02um %02us", results->timeout/3600, (results->timeout%3600)/60, results->timeout % 60); if (getpid() == lib_pid) alarm(results->timeout); else heartbeat(); }
static void verify_pipe(void) { char buf[2]; TEST(pipe(fd)); if (TEST_RETURN == -1) { tst_res(TFAIL | TTERRNO, "pipe() failed unexpectedly"); return; } TEST(write(fd[0], "A", 1)); if (TEST_RETURN == -1 && errno == EBADF) { tst_res(TPASS | TTERRNO, "expected failure writing " "to read end of pipe"); } else { tst_res(TFAIL | TTERRNO, "unexpected failure writing " "to read end of pipe"); } TEST(read(fd[1], buf, 1)); if (TEST_RETURN == -1 && errno == EBADF) { tst_res(TPASS | TTERRNO, "expected failure reading " "from write end of pipe"); } else { tst_res(TFAIL | TTERRNO, "unexpected failure reading " "from write end of pipe"); } SAFE_CLOSE(fd[0]); SAFE_CLOSE(fd[1]); }
static void visit_dir(const char *path) { DIR *dir; struct dirent *dent; struct stat dent_st; char dent_path[MAX_PATH]; enum dent_action act; dir = opendir(path); if (!dir) { tst_res(TINFO | TERRNO, "opendir(%s)", path); return; } while (1) { errno = 0; dent = readdir(dir); if (!dent && errno) { tst_res(TINFO | TERRNO, "readdir(%s)", path); break; } else if (!dent) { break; } if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; if (dent->d_type == DT_DIR) act = DA_VISIT; else if (dent->d_type == DT_LNK) act = DA_IGNORE; else if (dent->d_type == DT_UNKNOWN) act = DA_UNKNOWN; else act = DA_READ; snprintf(dent_path, MAX_PATH, "%s/%s", path, dent->d_name); if (act == DA_UNKNOWN) { if (lstat(dent_path, &dent_st)) tst_res(TINFO | TERRNO, "lstat(%s)", path); else if ((dent_st.st_mode & S_IFMT) == S_IFDIR) act = DA_VISIT; else if ((dent_st.st_mode & S_IFMT) == S_IFLNK) act = DA_IGNORE; else act = DA_READ; } if (act == DA_VISIT) visit_dir(dent_path); else if (act == DA_READ) rep_sched_work(dent_path, reads); } if (closedir(dir)) tst_res(TINFO | TERRNO, "closedir(%s)", path); }
static void verify_creat(void) { pid_t pid; pid = SAFE_FORK(); if (pid == 0) { char *av[] = {TEST_APP, NULL}; (void)execve(TEST_APP, av, tst_ipc_envp); perror("execve failed"); exit(1); } TST_CHECKPOINT_WAIT(0); TEST(creat(TEST_APP, O_WRONLY)); if (TEST_RETURN != -1) { tst_res(TFAIL, "creat() succeeded unexpectedly"); return; } if (TEST_ERRNO == ETXTBSY) tst_res(TPASS, "creat() received EXTBSY"); else tst_res(TFAIL | TTERRNO, "creat() failed unexpectedly"); SAFE_KILL(pid, SIGKILL); SAFE_WAITPID(pid, NULL, 0); }
static void check_mark(char *file, unsigned long long flag, char *flagstr, int expect, void (*test_event)(char *)) { if (fanotify_mark(fd_notify, FAN_MARK_ADD | flag, FAN_OPEN, AT_FDCWD, file) != expect) { tst_res(TFAIL, "fanotify_mark (%d, FAN_MARK_ADD | %s, FAN_OPEN, AT_FDCWD, " "'%s') %s", fd_notify, flagstr, file, expect_str_fail(expect)); } else { tst_res(TPASS, "fanotify_mark (%d, FAN_MARK_ADD | %s, FAN_OPEN, AT_FDCWD, " "'%s') %s", fd_notify, flagstr, file, expect_str_pass(expect)); /* If we expected failure there's nothing to clean up */ if (expect == -1) return; if (test_event) test_event(file); if (fanotify_mark(fd_notify, FAN_MARK_REMOVE | flag, FAN_OPEN, AT_FDCWD, file) < 0) { tst_brk(TBROK | TERRNO, "fanotify_mark (%d, FAN_MARK_REMOVE | %s, " "FAN_OPEN, AT_FDCWD, '%s') failed", fd_notify, flagstr, file); } } }
static void test_hugeshmget(unsigned int i) { int shm_id_2 = -1; if (*tcases[i].skey == -1) { shm_id_2 = shmget(*(tcases[i].skey), 0, 0); if (shm_id_2 != -1) shmctl(shm_id_2, IPC_RMID, NULL); } TEST(shmget(*(tcases[i].skey), tcases[i].size_coe * shm_size, tcases[i].flags)); if (TST_RET != -1) { tst_res(TFAIL, "shmget succeeded unexpectedly"); return; } if (TST_ERR != tcases[i].error) { tst_res(TFAIL | TTERRNO, "shmget failed unexpectedly, expected %s", tst_strerrno(tcases[i].error)); return; } tst_res(TPASS | TTERRNO, "shmget failed as expected"); }
static void cleanup(void) { if (opt_shmid && shmid != -1) SAFE_SHMCTL(shmid, IPC_RMID, NULL); if (!opt_shmid && fd != -1) { SAFE_CLOSE(fd); SAFE_UNLINK(TEST_FILE); } if (mounted) tst_umount(MOUNT_DIR); if (restore_nr_hgpgs) { tst_res(TINFO, "restore nr_hugepages to %ld.", nr_hugepages); SAFE_FILE_PRINTF(path, "%ld", nr_hugepages); } if (restore_shmmax) SAFE_FILE_PRINTF(PATH_SHMMAX, "%llu", shmmax); if (restore_overcomm_hgpgs) { tst_res(TINFO, "restore nr_overcommit_hugepages to %ld.", nr_overcommit_hugepages); SAFE_FILE_PRINTF(pathover, "%ld", nr_overcommit_hugepages); } }
static void run(void) { pthread_t thid[2]; int remaining = tst_timeout_remaining(); int elapsed = 0; while (tst_timeout_remaining() > STOP_THRESHOLD) { int fd = mkfile(file_size); tst_atomic_store(0, &mapcnt); tst_atomic_store(0, &unmapcnt); SAFE_PTHREAD_CREATE(&thid[0], NULL, map_write_unmap, &fd); SAFE_PTHREAD_CREATE(&thid[1], NULL, read_mem, &fd); threads_spawned += 2; SAFE_PTHREAD_JOIN(thid[0], NULL); SAFE_PTHREAD_JOIN(thid[1], NULL); close(fd); if (remaining - tst_timeout_remaining() > PROGRESS_SEC) { remaining = tst_timeout_remaining(); elapsed += PROGRESS_SEC; tst_res(TINFO, "[%d] mapped: %lu, sigsegv hit: %lu, " "threads spawned: %lu", elapsed, map_count, mapped_sigsegv_count, threads_spawned); tst_res(TINFO, "[%d] repeated_reads: %ld, " "data_matched: %lu", elapsed, repeated_reads, data_matched); } } tst_res(TPASS, "System survived."); }
static void verify_read(unsigned int n) { struct tcase *tc = &tcases[n]; if (tc->fd == &fd4 && *tc->fd == -1) { tst_res(TCONF, "O_DIRECT not supported on %s filesystem", tst_fs_type_name(fs_type)); return; } TEST(read(*tc->fd, *tc->buf, tc->count)); if (*tc->fd == fd4 && TEST_RETURN >= 0) { tst_res(TPASS, "O_DIRECT unaligned reads fallbacks to buffered I/O"); return; } if (TEST_RETURN != -1) { tst_res(TFAIL, "read() succeeded unexpectedly"); return; } if (TEST_ERRNO == tc->exp_error) { tst_res(TPASS | TTERRNO, "read() failed as expected"); } else { tst_res(TFAIL | TTERRNO, "read() failed unexpectedly, " "expected %s", tst_strerrno(tc->exp_error)); } }
static void alloc_and_check(long size, int expect_result) { int result; /* try to alloc size kB memory */ result = heavy_malloc(size); switch (expect_result) { case EXPECT_PASS: if (result == 0) tst_res(TPASS, "alloc passed as expected"); else tst_res(TFAIL, "alloc failed, expected to pass"); break; case EXPECT_FAIL: if (result != 0) tst_res(TPASS, "alloc failed as expected"); else tst_res(TFAIL, "alloc passed, expected to fail"); break; default: tst_brk(TBROK, "Invaild numbler parameter: %d", expect_result); } }
static void child_loop_alloc(unsigned long long alloc_bytes) { unsigned long bytecount = 0; char *mem; tst_res(TINFO, "... child %d starting", getpid()); while (1) { mem = SAFE_MALLOC(chunksize); if (dowrite) do_write_mem(mem, chunksize); if (verbose) tst_res(TINFO, "child %d allocated %lu bytes chunksize is %d", getpid(), bytecount, chunksize); bytecount += chunksize; if (bytecount >= alloc_bytes) break; } if (dowrite) tst_res(TINFO, "... [t=%d] %lu bytes allocated and used in child %d", tst_timeout_remaining(), bytecount, getpid()); else tst_res(TINFO, "... [t=%d] %lu bytes allocated only in child %d", tst_timeout_remaining(), bytecount, getpid()); kill(getppid(), SIGRTMIN); raise(SIGSTOP); exit(0); }
static void verify_event(int mask) { int ret; struct fanotify_event_metadata *event; struct stat st; /* Read the event */ ret = SAFE_READ(0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); event = (struct fanotify_event_metadata *)&event_buf[len]; len += ret; if (event->mask != FAN_OPEN) { tst_res(TFAIL, "got unexpected event %llx", (unsigned long long)event->mask); } else if (fstat(event->fd, &st) < 0) { tst_res(TFAIL, "failed to stat event->fd (%s)", strerror(errno)); } else if ((int)(st.st_mode & S_IFMT) != mask) { tst_res(TFAIL, "event->fd points to object of different type " "(%o != %o)", st.st_mode & S_IFMT, mask); } else { tst_res(TPASS, "event generated properly for type %o", mask); } close(event->fd); }
static void check_qlim(int subcmd, char *desp) { int res; static struct fs_disk_quota res_dquota; res_dquota.d_rtb_softlimit = 0; res = quotactl(QCMD(subcmd, USRQUOTA), tst_device->dev, test_id, (void*) &res_dquota); if (res == -1) { if (errno == EINVAL) { tst_brk(TCONF | TERRNO, "%s wasn't supported in quotactl()", desp); } tst_res(TFAIL | TERRNO, "quotactl() failed to get xfs disk quota limits"); return; } if (res_dquota.d_id != test_id) { tst_res(TFAIL, "quotactl() got unexpected user id %u," " expected %u", res_dquota.d_id, test_id); return; } if (res_dquota.d_rtb_hardlimit != set_dquota.d_rtb_hardlimit) { tst_res(TFAIL, "quotactl() got unexpected rtb soft limit %llu," " expected %llu", res_dquota.d_rtb_hardlimit, set_dquota.d_rtb_hardlimit); return; } tst_res(TPASS, "quoactl() succeeded to set and use %s to get xfs disk " "quota limits", desp); }
static void verify_socket(unsigned int n) { int fd; struct test_case_t *tc = &tdat[n]; TEST(fd = socket(tc->domain, tc->type, tc->proto)); if (TEST_RETURN >= 0) TEST_RETURN = 0; if (fd > 0) SAFE_CLOSE(fd); if (TEST_RETURN != tc->retval) { tst_res(TFAIL, "%s returned %d (expected %d)", tc->desc, fd, tc->retval); return; } if (TEST_ERRNO != tc->experrno) { tst_res(TFAIL | TTERRNO, "expected %s(%d)", tst_strerrno(tc->experrno), tc->experrno); return; } tst_res(TPASS, "%s successful", tc->desc); }
void test_chmod(void) { struct stat stat_buf; /* * Call chmod(2) with specified mode argument * (sticky-bit set) on testfile. */ TEST(chmod(TESTFILE, PERMS)); if (TST_RET == -1) { tst_brk(TFAIL | TTERRNO, "chmod(%s, %#o) failed", TESTFILE, PERMS); } if (stat(TESTFILE, &stat_buf) == -1) { tst_brk(TFAIL | TTERRNO, "stat failed"); } /* Check for expected mode permissions */ if ((stat_buf.st_mode & PERMS) == PERMS) { tst_res(TPASS, "Functionality of chmod(%s, %#o) successful", TESTFILE, PERMS); } else { tst_res(TFAIL, "%s: Incorrect modes 0%03o; expected 0%03o", TESTFILE, stat_buf.st_mode, PERMS); } }
static void setup(void) { check_hugepage(); hugepagesize = SAFE_READ_MEMINFO("Hugepagesize:") * 1024; init_sys_sz_paths(); if (opt_sysfs) { path = path_sys_sz_huge; pathover = path_sys_sz_over; } else { path = PATH_PROC_HUGE; pathover = PATH_PROC_OVER; } if (opt_alloc) { size = atoi(opt_alloc); length = (size + size * 0.5) * 2; } if (opt_shmid) { SAFE_FILE_SCANF(PATH_SHMMAX, "%llu", &shmmax); if (shmmax < (unsigned long long)(length / 2 * hugepagesize)) { restore_shmmax = 1; SAFE_FILE_PRINTF(PATH_SHMMAX, "%ld", (length / 2 * hugepagesize)); } } SAFE_FILE_SCANF(path, "%ld", &nr_hugepages); tst_res(TINFO, "original nr_hugepages is %ld", nr_hugepages); /* Reset. */ SAFE_FILE_PRINTF(path, "%ld", size); restore_nr_hgpgs = 1; if (access(pathover, F_OK)) { tst_brk(TCONF, "file %s does not exist in the system", pathover); } SAFE_FILE_SCANF(pathover, "%ld", &nr_overcommit_hugepages); tst_res(TINFO, "original nr_overcommit_hugepages is %ld", nr_overcommit_hugepages); /* Reset. */ SAFE_FILE_PRINTF(pathover, "%ld", size); restore_overcomm_hgpgs = 1; SAFE_MKDIR(MOUNT_DIR, 0700); SAFE_MOUNT(NULL, MOUNT_DIR, "hugetlbfs", 0, NULL); mounted = 1; if (opt_shmid) { /* Use /proc/meminfo to generate an IPC key. */ key = ftok(PATH_MEMINFO, strlen(PATH_MEMINFO)); if (key == -1) tst_brk(TBROK | TERRNO, "ftok"); } }
static void cleanup(void) { if (fds[0] > 0 && close(fds[0])) tst_res(TWARN | TERRNO, "failed to close file"); if (fds[1] > 0 && close(fds[1])) tst_res(TWARN | TERRNO, "failed to close file"); }
static int checkproc(long act_val, char *pattern, long exp_val) { tst_res(TINFO, "%s is %ld.", pattern, act_val); if (act_val != exp_val) { tst_res(TFAIL, "%s is not %ld but %ld.", pattern, exp_val, act_val); return 1; } return 0; }
static void bad_size(void) { TEST(create_skbuf(3U << 30)); if (TST_RET && TST_ERR != EINVAL) tst_brk(TBROK | TTERRNO, "Unexpected setsockopt() error"); if (TST_RET) tst_res(TPASS | TTERRNO, "Refused bad tp_sizeof_priv value"); else tst_res(TFAIL, "Allowed bad tp_sizeof_priv value"); }
static void test_unflagged(void) { struct statx buf; TEST(statx(AT_FDCWD, TESTDIR_UNFLAGGED, 0, 0, &buf)); if (TST_RET == 0) tst_res(TPASS, "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_UNFLAGGED); else tst_brk(TFAIL | TTERRNO, "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_UNFLAGGED); if ((buf.stx_attributes & STATX_ATTR_COMPRESSED) == 0) tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is not set"); else tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is set"); if ((buf.stx_attributes & STATX_ATTR_APPEND) == 0) tst_res(TPASS, "STATX_ATTR_APPEND flag is not set"); else tst_res(TFAIL, "STATX_ATTR_APPEND flag is set"); if ((buf.stx_attributes & STATX_ATTR_IMMUTABLE) == 0) tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is not set"); else tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is set"); if ((buf.stx_attributes & STATX_ATTR_NODUMP) == 0) tst_res(TPASS, "STATX_ATTR_NODUMP flag is not set"); else tst_res(TFAIL, "STATX_ATTR_NODUMP flag is set"); }
void run(unsigned int test) { TEST(tst_syscall(__NR_ustat, *tc[test].dev, tc[test].buf)); if ((TST_RET == -1) && (TST_ERR == tc[test].exp_errno)) tst_res(TPASS | TTERRNO, "ustat(2) expected failure"); else tst_res(TFAIL | TTERRNO, "ustat(2) failed to produce expected error; %d, errno" ": %s", tc[test].exp_errno, tc[test].exp_errval); }
static void verify_fgetxattr(void) { TEST(fgetxattr(fd, XATTR_TEST_KEY, NULL, 0)); if (TST_RET == XATTR_TEST_VALUE_SIZE) { tst_res(TPASS, "fgetxattr(2) returned correct value"); return; } tst_res(TFAIL | TTERRNO, "fgetxattr(2) failed with %li", TST_RET); }
static void verify_read(void) { SAFE_LSEEK(fd, 0, SEEK_SET); TEST(read(fd, buf, SIZE)); if (TEST_RETURN == -1) tst_res(TFAIL | TTERRNO, "read(2) failed"); else tst_res(TPASS, "read(2) returned %ld", TEST_RETURN); }