1 1.12 christos /* $NetBSD: t_vfsops.c,v 1.12 2017/01/13 21:30:40 christos Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * Redistribution and use in source and binary forms, with or without 8 1.1 pooka * modification, are permitted provided that the following conditions 9 1.1 pooka * are met: 10 1.1 pooka * 1. Redistributions of source code must retain the above copyright 11 1.1 pooka * notice, this list of conditions and the following disclaimer. 12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 pooka * notice, this list of conditions and the following disclaimer in the 14 1.1 pooka * documentation and/or other materials provided with the distribution. 15 1.1 pooka * 16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 pooka * POSSIBILITY OF SUCH DAMAGE. 27 1.1 pooka */ 28 1.1 pooka 29 1.1 pooka #include <sys/stat.h> 30 1.1 pooka #include <sys/statvfs.h> 31 1.1 pooka 32 1.1 pooka #include <atf-c.h> 33 1.4 pooka #include <dirent.h> 34 1.2 pooka #include <fcntl.h> 35 1.4 pooka #include <stdlib.h> 36 1.1 pooka #include <unistd.h> 37 1.1 pooka 38 1.1 pooka #include <rump/rump_syscalls.h> 39 1.1 pooka #include <rump/rump.h> 40 1.1 pooka 41 1.1 pooka #include "../common/h_fsmacros.h" 42 1.12 christos #include "h_macros.h" 43 1.1 pooka 44 1.1 pooka static void 45 1.1 pooka tmount(const atf_tc_t *tc, const char *path) 46 1.1 pooka { 47 1.1 pooka 48 1.1 pooka return; 49 1.1 pooka } 50 1.1 pooka 51 1.1 pooka static void 52 1.1 pooka tstatvfs(const atf_tc_t *tc, const char *path) 53 1.1 pooka { 54 1.9 pooka const char *fstype = atf_tc_get_md_var(tc, "X-fs.mntname"); 55 1.1 pooka struct statvfs svb; 56 1.1 pooka 57 1.1 pooka if (rump_sys_statvfs1(path, &svb, ST_WAIT) == -1) 58 1.1 pooka atf_tc_fail_errno("statvfs"); 59 1.3 njoly 60 1.3 njoly ATF_REQUIRE(svb.f_namemax > 0 && svb.f_namemax <= MAXNAMLEN); 61 1.9 pooka if (!(FSTYPE_PUFFS(tc) || FSTYPE_P2K_FFS(tc))) 62 1.3 njoly ATF_REQUIRE_STREQ(svb.f_fstypename, fstype); 63 1.3 njoly ATF_REQUIRE_STREQ(svb.f_mntonname, path); 64 1.1 pooka } 65 1.1 pooka 66 1.1 pooka static void 67 1.1 pooka tsync(const atf_tc_t *tc, const char *path) 68 1.1 pooka { 69 1.1 pooka 70 1.1 pooka rump_sys_sync(); 71 1.1 pooka } 72 1.1 pooka 73 1.1 pooka #define MAGICSTR "just a string, I like A" 74 1.1 pooka static void 75 1.1 pooka tfilehandle(const atf_tc_t *tc, const char *path) 76 1.1 pooka { 77 1.1 pooka char fpath[MAXPATHLEN]; 78 1.1 pooka char buf[sizeof(MAGICSTR)]; 79 1.1 pooka size_t fhsize; 80 1.1 pooka void *fhp; 81 1.1 pooka int fd; 82 1.1 pooka 83 1.1 pooka sprintf(fpath, "%s/file", path); 84 1.1 pooka fd = rump_sys_open(fpath, O_RDWR | O_CREAT, 0777); 85 1.1 pooka if (fd == -1) 86 1.1 pooka atf_tc_fail_errno("open"); 87 1.1 pooka 88 1.1 pooka if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR)) 89 1.1 pooka atf_tc_fail("write to file"); 90 1.1 pooka rump_sys_close(fd); 91 1.1 pooka 92 1.1 pooka /* 93 1.1 pooka * Get file handle size. 94 1.1 pooka * This also weeds out unsupported file systems. 95 1.1 pooka */ 96 1.1 pooka fhsize = 0; 97 1.1 pooka if (rump_sys_getfh(fpath, NULL, &fhsize) == -1) { 98 1.1 pooka if (errno == EOPNOTSUPP) { 99 1.1 pooka atf_tc_skip("file handles not supported"); 100 1.1 pooka } else if (errno != E2BIG) { 101 1.1 pooka atf_tc_fail_errno("getfh size"); 102 1.1 pooka } 103 1.1 pooka } 104 1.1 pooka 105 1.1 pooka fhp = malloc(fhsize); 106 1.1 pooka if (rump_sys_getfh(fpath, fhp, &fhsize) == -1) 107 1.1 pooka atf_tc_fail_errno("getfh"); 108 1.1 pooka 109 1.1 pooka /* open file based on file handle */ 110 1.1 pooka fd = rump_sys_fhopen(fhp, fhsize, O_RDONLY); 111 1.1 pooka if (fd == -1) { 112 1.1 pooka atf_tc_fail_errno("fhopen"); 113 1.1 pooka } 114 1.1 pooka 115 1.1 pooka /* check that we got the same file */ 116 1.1 pooka if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(MAGICSTR)) 117 1.1 pooka atf_tc_fail("read fhopened file"); 118 1.1 pooka 119 1.1 pooka ATF_REQUIRE_STREQ(buf, MAGICSTR); 120 1.1 pooka 121 1.1 pooka rump_sys_close(fd); 122 1.1 pooka } 123 1.1 pooka 124 1.5 pooka #define FNAME "a_file" 125 1.5 pooka static void 126 1.5 pooka tfhremove(const atf_tc_t *tc, const char *path) 127 1.5 pooka { 128 1.5 pooka size_t fhsize; 129 1.5 pooka void *fhp; 130 1.5 pooka int fd; 131 1.5 pooka 132 1.5 pooka RL(rump_sys_chdir(path)); 133 1.5 pooka RL(fd = rump_sys_open(FNAME, O_RDWR | O_CREAT, 0777)); 134 1.5 pooka RL(rump_sys_close(fd)); 135 1.5 pooka 136 1.5 pooka fhsize = 0; 137 1.5 pooka if (rump_sys_getfh(FNAME, NULL, &fhsize) == -1) { 138 1.5 pooka if (errno == EOPNOTSUPP) { 139 1.5 pooka atf_tc_skip("file handles not supported"); 140 1.5 pooka } else if (errno != E2BIG) { 141 1.5 pooka atf_tc_fail_errno("getfh size"); 142 1.5 pooka } 143 1.5 pooka } 144 1.5 pooka 145 1.5 pooka fhp = malloc(fhsize); 146 1.5 pooka RL(rump_sys_getfh(FNAME, fhp, &fhsize)); 147 1.5 pooka RL(rump_sys_unlink(FNAME)); 148 1.5 pooka 149 1.11 hannken if (FSTYPE_LFS(tc)) 150 1.6 pooka atf_tc_expect_fail("fhopen() for removed file succeeds " 151 1.6 pooka "(PR kern/43745)"); 152 1.5 pooka ATF_REQUIRE_ERRNO(ESTALE, rump_sys_fhopen(fhp, fhsize, O_RDONLY) == -1); 153 1.5 pooka atf_tc_expect_pass(); 154 1.5 pooka 155 1.5 pooka RL(rump_sys_chdir("/")); 156 1.5 pooka } 157 1.5 pooka #undef FNAME 158 1.5 pooka 159 1.7 pooka /* 160 1.7 pooka * This test only checks the file system doesn't crash. We *might* 161 1.7 pooka * try a valid file handle. 162 1.7 pooka */ 163 1.7 pooka static void 164 1.7 pooka tfhinval(const atf_tc_t *tc, const char *path) 165 1.7 pooka { 166 1.7 pooka size_t fhsize; 167 1.7 pooka void *fhp; 168 1.7 pooka unsigned long seed; 169 1.7 pooka int fd; 170 1.7 pooka 171 1.7 pooka srandom(seed = time(NULL)); 172 1.7 pooka printf("RNG seed %lu\n", seed); 173 1.7 pooka 174 1.7 pooka RL(rump_sys_chdir(path)); 175 1.7 pooka fhsize = 0; 176 1.7 pooka if (rump_sys_getfh(".", NULL, &fhsize) == -1) { 177 1.7 pooka if (errno == EOPNOTSUPP) { 178 1.7 pooka atf_tc_skip("file handles not supported"); 179 1.7 pooka } else if (errno != E2BIG) { 180 1.7 pooka atf_tc_fail_errno("getfh size"); 181 1.7 pooka } 182 1.7 pooka } 183 1.7 pooka 184 1.7 pooka fhp = malloc(fhsize); 185 1.7 pooka tests_makegarbage(fhp, fhsize); 186 1.7 pooka fd = rump_sys_fhopen(fhp, fhsize, O_RDWR); 187 1.7 pooka if (fd != -1) 188 1.7 pooka rump_sys_close(fd); 189 1.7 pooka 190 1.7 pooka RL(rump_sys_chdir("/")); 191 1.7 pooka } 192 1.7 pooka 193 1.1 pooka ATF_TC_FSAPPLY(tmount, "mount/unmount"); 194 1.1 pooka ATF_TC_FSAPPLY(tstatvfs, "statvfs"); 195 1.1 pooka ATF_TC_FSAPPLY(tsync, "sync"); 196 1.1 pooka ATF_TC_FSAPPLY(tfilehandle, "file handles"); 197 1.5 pooka ATF_TC_FSAPPLY(tfhremove, "fhtovp for removed file"); 198 1.7 pooka ATF_TC_FSAPPLY(tfhinval, "fhopen invalid filehandle"); 199 1.1 pooka 200 1.1 pooka ATF_TP_ADD_TCS(tp) 201 1.1 pooka { 202 1.1 pooka 203 1.1 pooka ATF_TP_FSAPPLY(tmount); 204 1.1 pooka ATF_TP_FSAPPLY(tstatvfs); 205 1.1 pooka ATF_TP_FSAPPLY(tsync); 206 1.1 pooka ATF_TP_FSAPPLY(tfilehandle); 207 1.5 pooka ATF_TP_FSAPPLY(tfhremove); 208 1.7 pooka ATF_TP_FSAPPLY(tfhinval); 209 1.1 pooka 210 1.1 pooka return atf_no_error(); 211 1.1 pooka } 212