1 /* $NetBSD: t_basic.c,v 1.1 2010/03/30 01:02:47 pooka Exp $ */ 2 3 #include <sys/types.h> 4 #include <sys/mount.h> 5 6 #include <atf-c.h> 7 #include <err.h> 8 #include <errno.h> 9 #include <fcntl.h> 10 #include <stdio.h> 11 #include <unistd.h> 12 #include <string.h> 13 #include <stdlib.h> 14 15 #include <rump/rump.h> 16 #include <rump/rump_syscalls.h> 17 18 #include <miscfs/nullfs/null.h> 19 #include <fs/tmpfs/tmpfs_args.h> 20 21 #define USE_ATF 22 #include "../../h_macros.h" 23 24 #ifdef USE_ATF 25 ATF_TC(basic); 26 ATF_TC_HEAD(basic, tc) 27 { 28 atf_tc_set_md_var(tc, "descr", "basic nullfs functionality"); 29 } 30 #else 31 #define atf_tc_fail(...) errx(1, __VA_ARGS__) 32 #endif 33 34 #define MSTR "magic bus" 35 36 static void 37 xput_tfile(const char *path, const char *mstr) 38 { 39 int fd; 40 41 fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); 42 if (fd == -1) 43 atf_tc_fail_errno("create %s", path); 44 if (rump_sys_write(fd, MSTR, sizeof(MSTR)) != sizeof(MSTR)) 45 atf_tc_fail_errno("write to testfile"); 46 rump_sys_close(fd); 47 } 48 49 static int 50 xread_tfile(const char *path, const char *mstr) 51 { 52 char buf[128]; 53 int fd; 54 55 fd = rump_sys_open(path, O_RDONLY); 56 if (fd == -1) 57 return errno; 58 if (rump_sys_read(fd, buf, sizeof(buf)) == -1) 59 atf_tc_fail_errno("read tfile"); 60 rump_sys_close(fd); 61 if (strcmp(buf, MSTR) == 0) 62 return 0; 63 return EPROGMISMATCH; 64 } 65 66 #ifdef USE_ATF 67 ATF_TC_BODY(basic, tc) 68 #else 69 int main(int argc, char *argv[]) 70 #endif 71 { 72 struct null_args nargs; 73 struct tmpfs_args targs; 74 struct stat sb; 75 int error; 76 77 rump_init(); 78 if (rump_sys_mkdir("/td1", 0777) == -1) 79 atf_tc_fail_errno("mp1"); 80 if (rump_sys_mkdir("/td2", 0777) == -1) 81 atf_tc_fail_errno("mp1"); 82 83 /* use tmpfs because rumpfs doesn't support regular files */ 84 memset(&targs, 0, sizeof(targs)); 85 targs.ta_version = TMPFS_ARGS_VERSION; 86 targs.ta_root_mode = 0777; 87 if (rump_sys_mount(MOUNT_TMPFS, "/td1", 0, &targs, sizeof(targs)) == -1) 88 atf_tc_fail_errno("could not mount tmpfs td1"); 89 90 memset(&nargs, 0, sizeof(nargs)); 91 nargs.nulla_target = __UNCONST("/td1"); 92 if (rump_sys_mount(MOUNT_NULL, "/td2", 0, &nargs, sizeof(nargs)) == -1) 93 atf_tc_fail_errno("could not mount nullfs"); 94 95 /* test unnull -> null */ 96 xput_tfile("/td1/tensti", "jeppe"); 97 error = xread_tfile("/td2/tensti", "jeppe"); 98 if (error != 0) 99 atf_tc_fail("null compare failed: %d (%s)", 100 error, strerror(error)); 101 102 /* test null -> unnull */ 103 xput_tfile("/td2/kiekko", "keppi"); 104 error = xread_tfile("/td1/kiekko", "keppi"); 105 if (error != 0) 106 atf_tc_fail("unnull compare failed: %d (%s)", 107 error, strerror(error)); 108 109 /* test unnull -> null overwrite */ 110 xput_tfile("/td1/tensti", "se oolannin sota"); 111 error = xread_tfile("/td2/tensti", "se oolannin sota"); 112 if (error != 0) 113 atf_tc_fail("unnull compare failed: %d (%s)", 114 error, strerror(error)); 115 116 /* test that /td2 is unaffected in "real life" */ 117 if (rump_sys_unmount("/td2", 0) == -1) 118 atf_tc_fail_errno("cannot unmount nullfs"); 119 if ((error = rump_sys_stat("/td2/tensti", &sb)) != -1 120 || errno != ENOENT) { 121 atf_tc_fail("stat tensti should return ENOENT, got %d", error); 122 } 123 if ((error = rump_sys_stat("/td2/kiekko", &sb)) != -1 124 || errno != ENOENT) { 125 atf_tc_fail("stat kiekko should return ENOENT, got %d", error); 126 } 127 128 /* done */ 129 } 130 131 #ifdef USE_ATF 132 ATF_TP_ADD_TCS(tp) 133 { 134 ATF_TP_ADD_TC(tp, basic); 135 return 0; /*XXX?*/ 136 } 137 #endif 138