1314817Sngie/* $NetBSD: t_basic.c,v 1.4 2017/01/13 21:30:40 christos Exp $ */ 2272343Sngie 3272343Sngie#include <sys/types.h> 4272343Sngie#include <sys/mount.h> 5272343Sngie 6272343Sngie#include <atf-c.h> 7272343Sngie#include <err.h> 8272343Sngie#include <errno.h> 9272343Sngie#include <fcntl.h> 10272343Sngie#include <stdio.h> 11272343Sngie#include <unistd.h> 12272343Sngie#include <string.h> 13272343Sngie#include <stdlib.h> 14272343Sngie 15272343Sngie#include <rump/rump.h> 16272343Sngie#include <rump/rump_syscalls.h> 17272343Sngie 18272343Sngie#include <miscfs/nullfs/null.h> 19272343Sngie#include <fs/tmpfs/tmpfs_args.h> 20272343Sngie 21314817Sngie#include "h_macros.h" 22272343Sngie 23272343SngieATF_TC(basic); 24272343SngieATF_TC_HEAD(basic, tc) 25272343Sngie{ 26272343Sngie atf_tc_set_md_var(tc, "descr", "basic nullfs functionality"); 27272343Sngie} 28272343Sngie 29272343Sngie#define MSTR "magic bus" 30272343Sngie 31272343Sngiestatic void 32272343Sngiexput_tfile(const char *path, const char *mstr) 33272343Sngie{ 34272343Sngie int fd; 35272343Sngie 36272343Sngie fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); 37272343Sngie if (fd == -1) 38272343Sngie atf_tc_fail_errno("create %s", path); 39272343Sngie if (rump_sys_write(fd, MSTR, sizeof(MSTR)) != sizeof(MSTR)) 40272343Sngie atf_tc_fail_errno("write to testfile"); 41272343Sngie rump_sys_close(fd); 42272343Sngie} 43272343Sngie 44272343Sngiestatic int 45272343Sngiexread_tfile(const char *path, const char *mstr) 46272343Sngie{ 47272343Sngie char buf[128]; 48272343Sngie int fd; 49272343Sngie 50272343Sngie fd = rump_sys_open(path, O_RDONLY); 51272343Sngie if (fd == -1) 52272343Sngie return errno; 53272343Sngie if (rump_sys_read(fd, buf, sizeof(buf)) == -1) 54272343Sngie atf_tc_fail_errno("read tfile"); 55272343Sngie rump_sys_close(fd); 56272343Sngie if (strcmp(buf, MSTR) == 0) 57272343Sngie return 0; 58272343Sngie return EPROGMISMATCH; 59272343Sngie} 60272343Sngie 61272343Sngiestatic void 62272343Sngiemountnull(const char *what, const char *mp, int flags) 63272343Sngie{ 64272343Sngie struct null_args nargs; 65272343Sngie 66272343Sngie memset(&nargs, 0, sizeof(nargs)); 67272343Sngie nargs.nulla_target = __UNCONST(what); 68272343Sngie if (rump_sys_mount(MOUNT_NULL, mp, flags, &nargs, sizeof(nargs)) == -1) 69272343Sngie atf_tc_fail_errno("could not mount nullfs"); 70272343Sngie 71272343Sngie} 72272343Sngie 73272343SngieATF_TC_BODY(basic, tc) 74272343Sngie{ 75272343Sngie struct tmpfs_args targs; 76272343Sngie struct stat sb; 77272343Sngie int error; 78272343Sngie 79272343Sngie rump_init(); 80272343Sngie if (rump_sys_mkdir("/td1", 0777) == -1) 81272343Sngie atf_tc_fail_errno("mp1"); 82272343Sngie if (rump_sys_mkdir("/td2", 0777) == -1) 83272343Sngie atf_tc_fail_errno("mp1"); 84272343Sngie 85272343Sngie /* use tmpfs because rumpfs doesn't support regular files */ 86272343Sngie memset(&targs, 0, sizeof(targs)); 87272343Sngie targs.ta_version = TMPFS_ARGS_VERSION; 88272343Sngie targs.ta_root_mode = 0777; 89272343Sngie if (rump_sys_mount(MOUNT_TMPFS, "/td1", 0, &targs, sizeof(targs)) == -1) 90272343Sngie atf_tc_fail_errno("could not mount tmpfs td1"); 91272343Sngie 92272343Sngie mountnull("/td1", "/td2", 0); 93272343Sngie 94272343Sngie /* test unnull -> null */ 95272343Sngie xput_tfile("/td1/tensti", "jeppe"); 96272343Sngie error = xread_tfile("/td2/tensti", "jeppe"); 97272343Sngie if (error != 0) 98272343Sngie atf_tc_fail("null compare failed: %d (%s)", 99272343Sngie error, strerror(error)); 100272343Sngie 101272343Sngie /* test null -> unnull */ 102272343Sngie xput_tfile("/td2/kiekko", "keppi"); 103272343Sngie error = xread_tfile("/td1/kiekko", "keppi"); 104272343Sngie if (error != 0) 105272343Sngie atf_tc_fail("unnull compare failed: %d (%s)", 106272343Sngie error, strerror(error)); 107272343Sngie 108272343Sngie /* test unnull -> null overwrite */ 109272343Sngie xput_tfile("/td1/tensti", "se oolannin sota"); 110272343Sngie error = xread_tfile("/td2/tensti", "se oolannin sota"); 111272343Sngie if (error != 0) 112272343Sngie atf_tc_fail("unnull compare failed: %d (%s)", 113272343Sngie error, strerror(error)); 114272343Sngie 115272343Sngie /* test that /td2 is unaffected in "real life" */ 116272343Sngie if (rump_sys_unmount("/td2", 0) == -1) 117272343Sngie atf_tc_fail_errno("cannot unmount nullfs"); 118272343Sngie if ((error = rump_sys_stat("/td2/tensti", &sb)) != -1 119272343Sngie || errno != ENOENT) { 120272343Sngie atf_tc_fail("stat tensti should return ENOENT, got %d", error); 121272343Sngie } 122272343Sngie if ((error = rump_sys_stat("/td2/kiekko", &sb)) != -1 123272343Sngie || errno != ENOENT) { 124272343Sngie atf_tc_fail("stat kiekko should return ENOENT, got %d", error); 125272343Sngie } 126272343Sngie 127272343Sngie /* done */ 128272343Sngie} 129272343Sngie 130272343SngieATF_TC(twistymount); 131272343SngieATF_TC_HEAD(twistymount, tc) 132272343Sngie{ 133272343Sngie 134272343Sngie /* this is expected to fail until the PR is fixed */ 135272343Sngie atf_tc_set_md_var(tc, "descr", "\"recursive\" mounts deadlock" 136272343Sngie " (kern/43439)"); 137272343Sngie} 138272343Sngie 139272343Sngie/* 140272343Sngie * Mapping to identifiers in kern/43439: 141272343Sngie * /td = /home/current/pkgsrc 142272343Sngie * /td/dist = /home/current/pkgsrc/distiles 143272343Sngie * /mp = /usr/pkgsrc 144272343Sngie * /mp/dist = /usr/pkgsrc/distfiles -- "created" by first null mount 145272343Sngie */ 146272343Sngie 147272343SngieATF_TC_BODY(twistymount, tc) 148272343Sngie{ 149272343Sngie int mkd = 0; 150272343Sngie 151272343Sngie rump_init(); 152272343Sngie 153272343Sngie if (rump_sys_mkdir("/td", 0777) == -1) 154272343Sngie atf_tc_fail_errno("mkdir %d", mkd++); 155272343Sngie if (rump_sys_mkdir("/td/dist", 0777) == -1) 156272343Sngie atf_tc_fail_errno("mkdir %d", mkd++); 157272343Sngie if (rump_sys_mkdir("/mp", 0777) == -1) 158272343Sngie atf_tc_fail_errno("mkdir %d", mkd++); 159272343Sngie 160272343Sngie /* MNT_RDONLY doesn't matter, but just for compat with the PR */ 161272343Sngie mountnull("/td", "/mp", MNT_RDONLY); 162272343Sngie mountnull("/td/dist", "/mp/dist", 0); 163272343Sngie 164272343Sngie /* if we didn't get a locking-against-meself panic, we passed */ 165272343Sngie} 166272343Sngie 167272343SngieATF_TP_ADD_TCS(tp) 168272343Sngie{ 169272343Sngie 170272343Sngie ATF_TP_ADD_TC(tp, basic); 171272343Sngie ATF_TP_ADD_TC(tp, twistymount); 172272343Sngie 173272343Sngie return atf_no_error(); 174272343Sngie} 175