1*63d1fd59SEnji Cooper /* $NetBSD: t_vfsops.c,v 1.12 2017/01/13 21:30:40 christos Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /*- 457718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1757718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1857718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1957718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2057718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2157718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2257718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2357718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2457718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2557718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2657718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 2757718be8SEnji Cooper */ 2857718be8SEnji Cooper 2957718be8SEnji Cooper #include <sys/stat.h> 3057718be8SEnji Cooper #include <sys/statvfs.h> 3157718be8SEnji Cooper 3257718be8SEnji Cooper #include <atf-c.h> 3357718be8SEnji Cooper #include <dirent.h> 3457718be8SEnji Cooper #include <fcntl.h> 3557718be8SEnji Cooper #include <stdlib.h> 3657718be8SEnji Cooper #include <unistd.h> 3757718be8SEnji Cooper 3857718be8SEnji Cooper #include <rump/rump_syscalls.h> 3957718be8SEnji Cooper #include <rump/rump.h> 4057718be8SEnji Cooper 4157718be8SEnji Cooper #include "../common/h_fsmacros.h" 42*63d1fd59SEnji Cooper #include "h_macros.h" 4357718be8SEnji Cooper 4457718be8SEnji Cooper static void 4557718be8SEnji Cooper tmount(const atf_tc_t *tc, const char *path) 4657718be8SEnji Cooper { 4757718be8SEnji Cooper 4857718be8SEnji Cooper return; 4957718be8SEnji Cooper } 5057718be8SEnji Cooper 5157718be8SEnji Cooper static void 5257718be8SEnji Cooper tstatvfs(const atf_tc_t *tc, const char *path) 5357718be8SEnji Cooper { 5457718be8SEnji Cooper const char *fstype = atf_tc_get_md_var(tc, "X-fs.mntname"); 5557718be8SEnji Cooper struct statvfs svb; 5657718be8SEnji Cooper 5757718be8SEnji Cooper if (rump_sys_statvfs1(path, &svb, ST_WAIT) == -1) 5857718be8SEnji Cooper atf_tc_fail_errno("statvfs"); 5957718be8SEnji Cooper 6057718be8SEnji Cooper ATF_REQUIRE(svb.f_namemax > 0 && svb.f_namemax <= MAXNAMLEN); 6157718be8SEnji Cooper if (!(FSTYPE_PUFFS(tc) || FSTYPE_P2K_FFS(tc))) 6257718be8SEnji Cooper ATF_REQUIRE_STREQ(svb.f_fstypename, fstype); 6357718be8SEnji Cooper ATF_REQUIRE_STREQ(svb.f_mntonname, path); 6457718be8SEnji Cooper } 6557718be8SEnji Cooper 6657718be8SEnji Cooper static void 6757718be8SEnji Cooper tsync(const atf_tc_t *tc, const char *path) 6857718be8SEnji Cooper { 6957718be8SEnji Cooper 7057718be8SEnji Cooper rump_sys_sync(); 7157718be8SEnji Cooper } 7257718be8SEnji Cooper 7357718be8SEnji Cooper #define MAGICSTR "just a string, I like A" 7457718be8SEnji Cooper static void 7557718be8SEnji Cooper tfilehandle(const atf_tc_t *tc, const char *path) 7657718be8SEnji Cooper { 7757718be8SEnji Cooper char fpath[MAXPATHLEN]; 7857718be8SEnji Cooper char buf[sizeof(MAGICSTR)]; 7957718be8SEnji Cooper size_t fhsize; 8057718be8SEnji Cooper void *fhp; 8157718be8SEnji Cooper int fd; 8257718be8SEnji Cooper 8357718be8SEnji Cooper sprintf(fpath, "%s/file", path); 8457718be8SEnji Cooper fd = rump_sys_open(fpath, O_RDWR | O_CREAT, 0777); 8557718be8SEnji Cooper if (fd == -1) 8657718be8SEnji Cooper atf_tc_fail_errno("open"); 8757718be8SEnji Cooper 8857718be8SEnji Cooper if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR)) 8957718be8SEnji Cooper atf_tc_fail("write to file"); 9057718be8SEnji Cooper rump_sys_close(fd); 9157718be8SEnji Cooper 9257718be8SEnji Cooper /* 9357718be8SEnji Cooper * Get file handle size. 9457718be8SEnji Cooper * This also weeds out unsupported file systems. 9557718be8SEnji Cooper */ 9657718be8SEnji Cooper fhsize = 0; 9757718be8SEnji Cooper if (rump_sys_getfh(fpath, NULL, &fhsize) == -1) { 9857718be8SEnji Cooper if (errno == EOPNOTSUPP) { 9957718be8SEnji Cooper atf_tc_skip("file handles not supported"); 10057718be8SEnji Cooper } else if (errno != E2BIG) { 10157718be8SEnji Cooper atf_tc_fail_errno("getfh size"); 10257718be8SEnji Cooper } 10357718be8SEnji Cooper } 10457718be8SEnji Cooper 10557718be8SEnji Cooper fhp = malloc(fhsize); 10657718be8SEnji Cooper if (rump_sys_getfh(fpath, fhp, &fhsize) == -1) 10757718be8SEnji Cooper atf_tc_fail_errno("getfh"); 10857718be8SEnji Cooper 10957718be8SEnji Cooper /* open file based on file handle */ 11057718be8SEnji Cooper fd = rump_sys_fhopen(fhp, fhsize, O_RDONLY); 11157718be8SEnji Cooper if (fd == -1) { 11257718be8SEnji Cooper atf_tc_fail_errno("fhopen"); 11357718be8SEnji Cooper } 11457718be8SEnji Cooper 11557718be8SEnji Cooper /* check that we got the same file */ 11657718be8SEnji Cooper if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(MAGICSTR)) 11757718be8SEnji Cooper atf_tc_fail("read fhopened file"); 11857718be8SEnji Cooper 11957718be8SEnji Cooper ATF_REQUIRE_STREQ(buf, MAGICSTR); 12057718be8SEnji Cooper 12157718be8SEnji Cooper rump_sys_close(fd); 12257718be8SEnji Cooper } 12357718be8SEnji Cooper 12457718be8SEnji Cooper #define FNAME "a_file" 12557718be8SEnji Cooper static void 12657718be8SEnji Cooper tfhremove(const atf_tc_t *tc, const char *path) 12757718be8SEnji Cooper { 12857718be8SEnji Cooper size_t fhsize; 12957718be8SEnji Cooper void *fhp; 13057718be8SEnji Cooper int fd; 13157718be8SEnji Cooper 13257718be8SEnji Cooper RL(rump_sys_chdir(path)); 13357718be8SEnji Cooper RL(fd = rump_sys_open(FNAME, O_RDWR | O_CREAT, 0777)); 13457718be8SEnji Cooper RL(rump_sys_close(fd)); 13557718be8SEnji Cooper 13657718be8SEnji Cooper fhsize = 0; 13757718be8SEnji Cooper if (rump_sys_getfh(FNAME, NULL, &fhsize) == -1) { 13857718be8SEnji Cooper if (errno == EOPNOTSUPP) { 13957718be8SEnji Cooper atf_tc_skip("file handles not supported"); 14057718be8SEnji Cooper } else if (errno != E2BIG) { 14157718be8SEnji Cooper atf_tc_fail_errno("getfh size"); 14257718be8SEnji Cooper } 14357718be8SEnji Cooper } 14457718be8SEnji Cooper 14557718be8SEnji Cooper fhp = malloc(fhsize); 14657718be8SEnji Cooper RL(rump_sys_getfh(FNAME, fhp, &fhsize)); 14757718be8SEnji Cooper RL(rump_sys_unlink(FNAME)); 14857718be8SEnji Cooper 14957718be8SEnji Cooper if (FSTYPE_LFS(tc)) 15057718be8SEnji Cooper atf_tc_expect_fail("fhopen() for removed file succeeds " 15157718be8SEnji Cooper "(PR kern/43745)"); 15257718be8SEnji Cooper ATF_REQUIRE_ERRNO(ESTALE, rump_sys_fhopen(fhp, fhsize, O_RDONLY) == -1); 15357718be8SEnji Cooper atf_tc_expect_pass(); 15457718be8SEnji Cooper 15557718be8SEnji Cooper RL(rump_sys_chdir("/")); 15657718be8SEnji Cooper } 15757718be8SEnji Cooper #undef FNAME 15857718be8SEnji Cooper 15957718be8SEnji Cooper /* 16057718be8SEnji Cooper * This test only checks the file system doesn't crash. We *might* 16157718be8SEnji Cooper * try a valid file handle. 16257718be8SEnji Cooper */ 16357718be8SEnji Cooper static void 16457718be8SEnji Cooper tfhinval(const atf_tc_t *tc, const char *path) 16557718be8SEnji Cooper { 16657718be8SEnji Cooper size_t fhsize; 16757718be8SEnji Cooper void *fhp; 16857718be8SEnji Cooper unsigned long seed; 16957718be8SEnji Cooper int fd; 17057718be8SEnji Cooper 17157718be8SEnji Cooper srandom(seed = time(NULL)); 17257718be8SEnji Cooper printf("RNG seed %lu\n", seed); 17357718be8SEnji Cooper 17457718be8SEnji Cooper RL(rump_sys_chdir(path)); 17557718be8SEnji Cooper fhsize = 0; 17657718be8SEnji Cooper if (rump_sys_getfh(".", NULL, &fhsize) == -1) { 17757718be8SEnji Cooper if (errno == EOPNOTSUPP) { 17857718be8SEnji Cooper atf_tc_skip("file handles not supported"); 17957718be8SEnji Cooper } else if (errno != E2BIG) { 18057718be8SEnji Cooper atf_tc_fail_errno("getfh size"); 18157718be8SEnji Cooper } 18257718be8SEnji Cooper } 18357718be8SEnji Cooper 18457718be8SEnji Cooper fhp = malloc(fhsize); 18557718be8SEnji Cooper tests_makegarbage(fhp, fhsize); 18657718be8SEnji Cooper fd = rump_sys_fhopen(fhp, fhsize, O_RDWR); 18757718be8SEnji Cooper if (fd != -1) 18857718be8SEnji Cooper rump_sys_close(fd); 18957718be8SEnji Cooper 19057718be8SEnji Cooper RL(rump_sys_chdir("/")); 19157718be8SEnji Cooper } 19257718be8SEnji Cooper 19357718be8SEnji Cooper ATF_TC_FSAPPLY(tmount, "mount/unmount"); 19457718be8SEnji Cooper ATF_TC_FSAPPLY(tstatvfs, "statvfs"); 19557718be8SEnji Cooper ATF_TC_FSAPPLY(tsync, "sync"); 19657718be8SEnji Cooper ATF_TC_FSAPPLY(tfilehandle, "file handles"); 19757718be8SEnji Cooper ATF_TC_FSAPPLY(tfhremove, "fhtovp for removed file"); 19857718be8SEnji Cooper ATF_TC_FSAPPLY(tfhinval, "fhopen invalid filehandle"); 19957718be8SEnji Cooper 20057718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 20157718be8SEnji Cooper { 20257718be8SEnji Cooper 20357718be8SEnji Cooper ATF_TP_FSAPPLY(tmount); 20457718be8SEnji Cooper ATF_TP_FSAPPLY(tstatvfs); 20557718be8SEnji Cooper ATF_TP_FSAPPLY(tsync); 20657718be8SEnji Cooper ATF_TP_FSAPPLY(tfilehandle); 20757718be8SEnji Cooper ATF_TP_FSAPPLY(tfhremove); 20857718be8SEnji Cooper ATF_TP_FSAPPLY(tfhinval); 20957718be8SEnji Cooper 21057718be8SEnji Cooper return atf_no_error(); 21157718be8SEnji Cooper } 212