1*63d1fd59SEnji Cooper /* $NetBSD: t_basic.c,v 1.4 2017/01/13 21:30:40 christos Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper #include <sys/types.h> 457718be8SEnji Cooper #include <sys/mount.h> 557718be8SEnji Cooper 657718be8SEnji Cooper #include <atf-c.h> 757718be8SEnji Cooper #include <err.h> 857718be8SEnji Cooper #include <errno.h> 957718be8SEnji Cooper #include <fcntl.h> 1057718be8SEnji Cooper #include <stdio.h> 1157718be8SEnji Cooper #include <unistd.h> 1257718be8SEnji Cooper #include <string.h> 1357718be8SEnji Cooper #include <stdlib.h> 1457718be8SEnji Cooper 1557718be8SEnji Cooper #include <rump/rump.h> 1657718be8SEnji Cooper #include <rump/rump_syscalls.h> 1757718be8SEnji Cooper 1857718be8SEnji Cooper #include <miscfs/nullfs/null.h> 1957718be8SEnji Cooper #include <fs/tmpfs/tmpfs_args.h> 2057718be8SEnji Cooper 21*63d1fd59SEnji Cooper #include "h_macros.h" 2257718be8SEnji Cooper 2357718be8SEnji Cooper ATF_TC(basic); 2457718be8SEnji Cooper ATF_TC_HEAD(basic, tc) 2557718be8SEnji Cooper { 2657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "basic nullfs functionality"); 2757718be8SEnji Cooper } 2857718be8SEnji Cooper 2957718be8SEnji Cooper #define MSTR "magic bus" 3057718be8SEnji Cooper 3157718be8SEnji Cooper static void 3257718be8SEnji Cooper xput_tfile(const char *path, const char *mstr) 3357718be8SEnji Cooper { 3457718be8SEnji Cooper int fd; 3557718be8SEnji Cooper 3657718be8SEnji Cooper fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); 3757718be8SEnji Cooper if (fd == -1) 3857718be8SEnji Cooper atf_tc_fail_errno("create %s", path); 3957718be8SEnji Cooper if (rump_sys_write(fd, MSTR, sizeof(MSTR)) != sizeof(MSTR)) 4057718be8SEnji Cooper atf_tc_fail_errno("write to testfile"); 4157718be8SEnji Cooper rump_sys_close(fd); 4257718be8SEnji Cooper } 4357718be8SEnji Cooper 4457718be8SEnji Cooper static int 4557718be8SEnji Cooper xread_tfile(const char *path, const char *mstr) 4657718be8SEnji Cooper { 4757718be8SEnji Cooper char buf[128]; 4857718be8SEnji Cooper int fd; 4957718be8SEnji Cooper 5057718be8SEnji Cooper fd = rump_sys_open(path, O_RDONLY); 5157718be8SEnji Cooper if (fd == -1) 5257718be8SEnji Cooper return errno; 5357718be8SEnji Cooper if (rump_sys_read(fd, buf, sizeof(buf)) == -1) 5457718be8SEnji Cooper atf_tc_fail_errno("read tfile"); 5557718be8SEnji Cooper rump_sys_close(fd); 5657718be8SEnji Cooper if (strcmp(buf, MSTR) == 0) 5757718be8SEnji Cooper return 0; 5857718be8SEnji Cooper return EPROGMISMATCH; 5957718be8SEnji Cooper } 6057718be8SEnji Cooper 6157718be8SEnji Cooper static void 6257718be8SEnji Cooper mountnull(const char *what, const char *mp, int flags) 6357718be8SEnji Cooper { 6457718be8SEnji Cooper struct null_args nargs; 6557718be8SEnji Cooper 6657718be8SEnji Cooper memset(&nargs, 0, sizeof(nargs)); 6757718be8SEnji Cooper nargs.nulla_target = __UNCONST(what); 6857718be8SEnji Cooper if (rump_sys_mount(MOUNT_NULL, mp, flags, &nargs, sizeof(nargs)) == -1) 6957718be8SEnji Cooper atf_tc_fail_errno("could not mount nullfs"); 7057718be8SEnji Cooper 7157718be8SEnji Cooper } 7257718be8SEnji Cooper 7357718be8SEnji Cooper ATF_TC_BODY(basic, tc) 7457718be8SEnji Cooper { 7557718be8SEnji Cooper struct tmpfs_args targs; 7657718be8SEnji Cooper struct stat sb; 7757718be8SEnji Cooper int error; 7857718be8SEnji Cooper 7957718be8SEnji Cooper rump_init(); 8057718be8SEnji Cooper if (rump_sys_mkdir("/td1", 0777) == -1) 8157718be8SEnji Cooper atf_tc_fail_errno("mp1"); 8257718be8SEnji Cooper if (rump_sys_mkdir("/td2", 0777) == -1) 8357718be8SEnji Cooper atf_tc_fail_errno("mp1"); 8457718be8SEnji Cooper 8557718be8SEnji Cooper /* use tmpfs because rumpfs doesn't support regular files */ 8657718be8SEnji Cooper memset(&targs, 0, sizeof(targs)); 8757718be8SEnji Cooper targs.ta_version = TMPFS_ARGS_VERSION; 8857718be8SEnji Cooper targs.ta_root_mode = 0777; 8957718be8SEnji Cooper if (rump_sys_mount(MOUNT_TMPFS, "/td1", 0, &targs, sizeof(targs)) == -1) 9057718be8SEnji Cooper atf_tc_fail_errno("could not mount tmpfs td1"); 9157718be8SEnji Cooper 9257718be8SEnji Cooper mountnull("/td1", "/td2", 0); 9357718be8SEnji Cooper 9457718be8SEnji Cooper /* test unnull -> null */ 9557718be8SEnji Cooper xput_tfile("/td1/tensti", "jeppe"); 9657718be8SEnji Cooper error = xread_tfile("/td2/tensti", "jeppe"); 9757718be8SEnji Cooper if (error != 0) 9857718be8SEnji Cooper atf_tc_fail("null compare failed: %d (%s)", 9957718be8SEnji Cooper error, strerror(error)); 10057718be8SEnji Cooper 10157718be8SEnji Cooper /* test null -> unnull */ 10257718be8SEnji Cooper xput_tfile("/td2/kiekko", "keppi"); 10357718be8SEnji Cooper error = xread_tfile("/td1/kiekko", "keppi"); 10457718be8SEnji Cooper if (error != 0) 10557718be8SEnji Cooper atf_tc_fail("unnull compare failed: %d (%s)", 10657718be8SEnji Cooper error, strerror(error)); 10757718be8SEnji Cooper 10857718be8SEnji Cooper /* test unnull -> null overwrite */ 10957718be8SEnji Cooper xput_tfile("/td1/tensti", "se oolannin sota"); 11057718be8SEnji Cooper error = xread_tfile("/td2/tensti", "se oolannin sota"); 11157718be8SEnji Cooper if (error != 0) 11257718be8SEnji Cooper atf_tc_fail("unnull compare failed: %d (%s)", 11357718be8SEnji Cooper error, strerror(error)); 11457718be8SEnji Cooper 11557718be8SEnji Cooper /* test that /td2 is unaffected in "real life" */ 11657718be8SEnji Cooper if (rump_sys_unmount("/td2", 0) == -1) 11757718be8SEnji Cooper atf_tc_fail_errno("cannot unmount nullfs"); 11857718be8SEnji Cooper if ((error = rump_sys_stat("/td2/tensti", &sb)) != -1 11957718be8SEnji Cooper || errno != ENOENT) { 12057718be8SEnji Cooper atf_tc_fail("stat tensti should return ENOENT, got %d", error); 12157718be8SEnji Cooper } 12257718be8SEnji Cooper if ((error = rump_sys_stat("/td2/kiekko", &sb)) != -1 12357718be8SEnji Cooper || errno != ENOENT) { 12457718be8SEnji Cooper atf_tc_fail("stat kiekko should return ENOENT, got %d", error); 12557718be8SEnji Cooper } 12657718be8SEnji Cooper 12757718be8SEnji Cooper /* done */ 12857718be8SEnji Cooper } 12957718be8SEnji Cooper 13057718be8SEnji Cooper ATF_TC(twistymount); 13157718be8SEnji Cooper ATF_TC_HEAD(twistymount, tc) 13257718be8SEnji Cooper { 13357718be8SEnji Cooper 13457718be8SEnji Cooper /* this is expected to fail until the PR is fixed */ 13557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "\"recursive\" mounts deadlock" 13657718be8SEnji Cooper " (kern/43439)"); 13757718be8SEnji Cooper } 13857718be8SEnji Cooper 13957718be8SEnji Cooper /* 14057718be8SEnji Cooper * Mapping to identifiers in kern/43439: 14157718be8SEnji Cooper * /td = /home/current/pkgsrc 14257718be8SEnji Cooper * /td/dist = /home/current/pkgsrc/distiles 14357718be8SEnji Cooper * /mp = /usr/pkgsrc 14457718be8SEnji Cooper * /mp/dist = /usr/pkgsrc/distfiles -- "created" by first null mount 14557718be8SEnji Cooper */ 14657718be8SEnji Cooper 14757718be8SEnji Cooper ATF_TC_BODY(twistymount, tc) 14857718be8SEnji Cooper { 14957718be8SEnji Cooper int mkd = 0; 15057718be8SEnji Cooper 15157718be8SEnji Cooper rump_init(); 15257718be8SEnji Cooper 15357718be8SEnji Cooper if (rump_sys_mkdir("/td", 0777) == -1) 15457718be8SEnji Cooper atf_tc_fail_errno("mkdir %d", mkd++); 15557718be8SEnji Cooper if (rump_sys_mkdir("/td/dist", 0777) == -1) 15657718be8SEnji Cooper atf_tc_fail_errno("mkdir %d", mkd++); 15757718be8SEnji Cooper if (rump_sys_mkdir("/mp", 0777) == -1) 15857718be8SEnji Cooper atf_tc_fail_errno("mkdir %d", mkd++); 15957718be8SEnji Cooper 16057718be8SEnji Cooper /* MNT_RDONLY doesn't matter, but just for compat with the PR */ 16157718be8SEnji Cooper mountnull("/td", "/mp", MNT_RDONLY); 16257718be8SEnji Cooper mountnull("/td/dist", "/mp/dist", 0); 16357718be8SEnji Cooper 16457718be8SEnji Cooper /* if we didn't get a locking-against-meself panic, we passed */ 16557718be8SEnji Cooper } 16657718be8SEnji Cooper 16757718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 16857718be8SEnji Cooper { 16957718be8SEnji Cooper 17057718be8SEnji Cooper ATF_TP_ADD_TC(tp, basic); 17157718be8SEnji Cooper ATF_TP_ADD_TC(tp, twistymount); 17257718be8SEnji Cooper 17357718be8SEnji Cooper return atf_no_error(); 17457718be8SEnji Cooper } 175