const char *tst_acquire_device(void (cleanup_fn)(void)) { char *dev; struct stat st; if (device_acquired) tst_brkm(TBROK, cleanup_fn, "Device allready acquired"); if (!tst_tmpdir_created()) { tst_brkm(TBROK, cleanup_fn, "Cannot acquire device without tmpdir() created"); } dev = getenv("LTP_DEV"); if (dev) { tst_resm(TINFO, "Using test device LTP_DEV='%s'", dev); SAFE_STAT(cleanup_fn, dev, &st); if (!S_ISBLK(st.st_mode)) { tst_brkm(TBROK, cleanup_fn, "%s is not a block device", dev); } if (tst_fill_file(dev, 0, 1024, 512)) { tst_brkm(TBROK | TERRNO, cleanup_fn, "Failed to clear the first 512k of %s", dev); } return dev; } if (tst_fill_file(DEV_FILE, 0, 1024, 102400)) { tst_brkm(TBROK | TERRNO, cleanup_fn, "Failed to create " DEV_FILE); } if (find_free_loopdev()) return NULL; attach_device(cleanup_fn, dev_path, DEV_FILE); device_acquired = 1; return dev_path; }
static void do_cleanup(void) { if (mntpoint_mounted) tst_umount(tst_test->mntpoint); if (tst_test->needs_device && tdev.dev) tst_release_device(tdev.dev); if (tst_tmpdir_created()) { /* avoid munmap() on wrong pointer in tst_rmdir() */ tst_futexes = NULL; tst_rmdir(); } cleanup_ipc(); }
void tst_checkpoint_init(const char *file, const int lineno, void (*cleanup_fn)(void)) { int fd; unsigned int page_size; if (tst_futexes) { tst_brkm(TBROK, cleanup_fn, "%s: %d checkpoints already initialized", file, lineno); return; } /* * The parent test process is responsible for creating the temporary * directory and therefore must pass non-zero cleanup (to remove the * directory if something went wrong). * * We cannot do this check unconditionally because if we need to init * the checkpoint from a binary that was started by exec() the * tst_tmpdir_created() will return false because the tmpdir was * created by parent. In this case we expect the subprogram can call * the init as a first function with NULL as cleanup function. */ if (cleanup_fn && !tst_tmpdir_created()) { tst_brkm(TBROK, cleanup_fn, "%s:%d You have to create test temporary directory " "first (call tst_tmpdir())", file, lineno); return; } page_size = getpagesize(); fd = SAFE_OPEN(cleanup_fn, "checkpoint_futex_base_file", O_RDWR | O_CREAT, 0666); SAFE_FTRUNCATE(cleanup_fn, fd, page_size); tst_futexes = SAFE_MMAP(cleanup_fn, NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); tst_max_futexes = page_size / sizeof(uint32_t); SAFE_CLOSE(cleanup_fn, fd); }
static void setup_ipc(void) { size_t size = getpagesize(); if (access("/dev/shm", F_OK) == 0) { snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d", tid, getpid()); } else { char *tmpdir; if (!tst_tmpdir_created()) tst_tmpdir(); tmpdir = tst_get_tmpdir(); snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d", tmpdir, tid, getpid()); free(tmpdir); } ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600); if (ipc_fd < 0) tst_brk(TBROK | TERRNO, "open(%s)", shm_path); SAFE_CHMOD(shm_path, 0666); SAFE_FTRUNCATE(ipc_fd, size); results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0); /* Checkpoints needs to be accessible from processes started by exec() */ if (tst_test->needs_checkpoints) { sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path); putenv(ipc_path); } else { SAFE_UNLINK(shm_path); } SAFE_CLOSE(ipc_fd); if (tst_test->needs_checkpoints) { tst_futexes = (char*)results + sizeof(struct results); tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); } }
const char *tst_acquire_device_(void (cleanup_fn)(void), unsigned int size) { int fd; char *dev; struct stat st; unsigned int acq_dev_size; uint64_t ltp_dev_size; acq_dev_size = size > 150 ? size : 150; if (device_acquired) tst_brkm(TBROK, cleanup_fn, "Device allready acquired"); if (!tst_tmpdir_created()) { tst_brkm(TBROK, cleanup_fn, "Cannot acquire device without tmpdir() created"); } dev = getenv("LTP_DEV"); if (dev) { tst_resm(TINFO, "Using test device LTP_DEV='%s'", dev); SAFE_STAT(cleanup_fn, dev, &st); if (!S_ISBLK(st.st_mode)) { tst_brkm(TBROK, cleanup_fn, "%s is not a block device", dev); } fd = SAFE_OPEN(cleanup_fn, dev, O_RDONLY); SAFE_IOCTL(cleanup_fn, fd, BLKGETSIZE64, <p_dev_size); SAFE_CLOSE(cleanup_fn, fd); ltp_dev_size = ltp_dev_size/1024/1024; if (acq_dev_size <= ltp_dev_size) { if (tst_fill_file(dev, 0, 1024, 512)) { tst_brkm(TBROK | TERRNO, cleanup_fn, "Failed to clear the first 512k of %s", dev); } return dev; } tst_resm(TINFO, "Skipping $LTP_DEV size %"PRIu64"MB, requested size %uMB", ltp_dev_size, acq_dev_size); } if (tst_fill_file(DEV_FILE, 0, 1024, 1024 * acq_dev_size)) { tst_brkm(TBROK | TERRNO, cleanup_fn, "Failed to create " DEV_FILE); } if (find_free_loopdev()) return NULL; attach_device(cleanup_fn, dev_path, DEV_FILE); device_acquired = 1; return dev_path; }
static void do_setup(int argc, char *argv[]) { if (!tst_test) tst_brk(TBROK, "No tests to run"); if (tst_test->tconf_msg) tst_brk(TCONF, "%s", tst_test->tconf_msg); assert_test_fn(); tid = get_tid(argv); if (tst_test->sample) tst_test = tst_timer_test_setup(tst_test); parse_opts(argc, argv); if (tst_test->needs_root && geteuid() != 0) tst_brk(TCONF, "Test needs to be run as root"); if (tst_test->min_kver) check_kver(); if (tst_test->format_device) tst_test->needs_device = 1; if (tst_test->mount_device) { tst_test->needs_device = 1; tst_test->format_device = 1; } if (tst_test->all_filesystems) tst_test->needs_device = 1; setup_ipc(); if (needs_tmpdir() && !tst_tmpdir_created()) tst_tmpdir(); if (tst_test->mntpoint) SAFE_MKDIR(tst_test->mntpoint, 0777); if ((tst_test->needs_rofs || tst_test->mount_device || tst_test->all_filesystems) && !tst_test->mntpoint) { tst_brk(TBROK, "tst_test->mntpoint must be set!"); } if (tst_test->needs_rofs) { /* If we failed to mount read-only tmpfs. Fallback to * using a device with empty read-only filesystem. */ if (mount(NULL, tst_test->mntpoint, "tmpfs", MS_RDONLY, NULL)) { tst_res(TINFO | TERRNO, "Can't mount tmpfs read-only" " at %s, setting up a device instead\n", tst_test->mntpoint); tst_test->mount_device = 1; tst_test->needs_device = 1; tst_test->format_device = 1; tst_test->mnt_flags = MS_RDONLY; } else { mntpoint_mounted = 1; } } if (tst_test->needs_device && !mntpoint_mounted) { tdev.dev = tst_acquire_device_(NULL, tst_test->dev_min_size); if (!tdev.dev) tst_brk(TCONF, "Failed to acquire device"); tst_device = &tdev; if (tst_test->dev_fs_type) tdev.fs_type = tst_test->dev_fs_type; else tdev.fs_type = tst_dev_fs_type(); if (!tst_test->all_filesystems) prepare_device(); } if (tst_test->resource_files) copy_resources(); }