1*c54cb811Schristos /* $NetBSD: t_vfsops.c,v 1.12 2017/01/13 21:30:40 christos Exp $ */
26463b412Spooka
36463b412Spooka /*-
46463b412Spooka * Copyright (c) 2010 The NetBSD Foundation, Inc.
56463b412Spooka * All rights reserved.
66463b412Spooka *
76463b412Spooka * Redistribution and use in source and binary forms, with or without
86463b412Spooka * modification, are permitted provided that the following conditions
96463b412Spooka * are met:
106463b412Spooka * 1. Redistributions of source code must retain the above copyright
116463b412Spooka * notice, this list of conditions and the following disclaimer.
126463b412Spooka * 2. Redistributions in binary form must reproduce the above copyright
136463b412Spooka * notice, this list of conditions and the following disclaimer in the
146463b412Spooka * documentation and/or other materials provided with the distribution.
156463b412Spooka *
166463b412Spooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
176463b412Spooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
186463b412Spooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
196463b412Spooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
206463b412Spooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
216463b412Spooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
226463b412Spooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
236463b412Spooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
246463b412Spooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
256463b412Spooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
266463b412Spooka * POSSIBILITY OF SUCH DAMAGE.
276463b412Spooka */
286463b412Spooka
296463b412Spooka #include <sys/stat.h>
306463b412Spooka #include <sys/statvfs.h>
316463b412Spooka
326463b412Spooka #include <atf-c.h>
3395cbf373Spooka #include <dirent.h>
34e9ce0fb0Spooka #include <fcntl.h>
3595cbf373Spooka #include <stdlib.h>
366463b412Spooka #include <unistd.h>
376463b412Spooka
386463b412Spooka #include <rump/rump_syscalls.h>
396463b412Spooka #include <rump/rump.h>
406463b412Spooka
416463b412Spooka #include "../common/h_fsmacros.h"
42*c54cb811Schristos #include "h_macros.h"
436463b412Spooka
446463b412Spooka static void
tmount(const atf_tc_t * tc,const char * path)456463b412Spooka tmount(const atf_tc_t *tc, const char *path)
466463b412Spooka {
476463b412Spooka
486463b412Spooka return;
496463b412Spooka }
506463b412Spooka
516463b412Spooka static void
tstatvfs(const atf_tc_t * tc,const char * path)526463b412Spooka tstatvfs(const atf_tc_t *tc, const char *path)
536463b412Spooka {
546bafd757Spooka const char *fstype = atf_tc_get_md_var(tc, "X-fs.mntname");
556463b412Spooka struct statvfs svb;
566463b412Spooka
576463b412Spooka if (rump_sys_statvfs1(path, &svb, ST_WAIT) == -1)
586463b412Spooka atf_tc_fail_errno("statvfs");
5913918916Snjoly
6013918916Snjoly ATF_REQUIRE(svb.f_namemax > 0 && svb.f_namemax <= MAXNAMLEN);
616bafd757Spooka if (!(FSTYPE_PUFFS(tc) || FSTYPE_P2K_FFS(tc)))
6213918916Snjoly ATF_REQUIRE_STREQ(svb.f_fstypename, fstype);
6313918916Snjoly ATF_REQUIRE_STREQ(svb.f_mntonname, path);
646463b412Spooka }
656463b412Spooka
666463b412Spooka static void
tsync(const atf_tc_t * tc,const char * path)676463b412Spooka tsync(const atf_tc_t *tc, const char *path)
686463b412Spooka {
696463b412Spooka
706463b412Spooka rump_sys_sync();
716463b412Spooka }
726463b412Spooka
736463b412Spooka #define MAGICSTR "just a string, I like A"
746463b412Spooka static void
tfilehandle(const atf_tc_t * tc,const char * path)756463b412Spooka tfilehandle(const atf_tc_t *tc, const char *path)
766463b412Spooka {
776463b412Spooka char fpath[MAXPATHLEN];
786463b412Spooka char buf[sizeof(MAGICSTR)];
796463b412Spooka size_t fhsize;
806463b412Spooka void *fhp;
816463b412Spooka int fd;
826463b412Spooka
836463b412Spooka sprintf(fpath, "%s/file", path);
846463b412Spooka fd = rump_sys_open(fpath, O_RDWR | O_CREAT, 0777);
856463b412Spooka if (fd == -1)
866463b412Spooka atf_tc_fail_errno("open");
876463b412Spooka
886463b412Spooka if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR))
896463b412Spooka atf_tc_fail("write to file");
906463b412Spooka rump_sys_close(fd);
916463b412Spooka
926463b412Spooka /*
936463b412Spooka * Get file handle size.
946463b412Spooka * This also weeds out unsupported file systems.
956463b412Spooka */
966463b412Spooka fhsize = 0;
976463b412Spooka if (rump_sys_getfh(fpath, NULL, &fhsize) == -1) {
986463b412Spooka if (errno == EOPNOTSUPP) {
996463b412Spooka atf_tc_skip("file handles not supported");
1006463b412Spooka } else if (errno != E2BIG) {
1016463b412Spooka atf_tc_fail_errno("getfh size");
1026463b412Spooka }
1036463b412Spooka }
1046463b412Spooka
1056463b412Spooka fhp = malloc(fhsize);
1066463b412Spooka if (rump_sys_getfh(fpath, fhp, &fhsize) == -1)
1076463b412Spooka atf_tc_fail_errno("getfh");
1086463b412Spooka
1096463b412Spooka /* open file based on file handle */
1106463b412Spooka fd = rump_sys_fhopen(fhp, fhsize, O_RDONLY);
1116463b412Spooka if (fd == -1) {
1126463b412Spooka atf_tc_fail_errno("fhopen");
1136463b412Spooka }
1146463b412Spooka
1156463b412Spooka /* check that we got the same file */
1166463b412Spooka if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(MAGICSTR))
1176463b412Spooka atf_tc_fail("read fhopened file");
1186463b412Spooka
1196463b412Spooka ATF_REQUIRE_STREQ(buf, MAGICSTR);
1206463b412Spooka
1216463b412Spooka rump_sys_close(fd);
1226463b412Spooka }
1236463b412Spooka
124d66cb1b1Spooka #define FNAME "a_file"
125d66cb1b1Spooka static void
tfhremove(const atf_tc_t * tc,const char * path)126d66cb1b1Spooka tfhremove(const atf_tc_t *tc, const char *path)
127d66cb1b1Spooka {
128d66cb1b1Spooka size_t fhsize;
129d66cb1b1Spooka void *fhp;
130d66cb1b1Spooka int fd;
131d66cb1b1Spooka
132d66cb1b1Spooka RL(rump_sys_chdir(path));
133d66cb1b1Spooka RL(fd = rump_sys_open(FNAME, O_RDWR | O_CREAT, 0777));
134d66cb1b1Spooka RL(rump_sys_close(fd));
135d66cb1b1Spooka
136d66cb1b1Spooka fhsize = 0;
137d66cb1b1Spooka if (rump_sys_getfh(FNAME, NULL, &fhsize) == -1) {
138d66cb1b1Spooka if (errno == EOPNOTSUPP) {
139d66cb1b1Spooka atf_tc_skip("file handles not supported");
140d66cb1b1Spooka } else if (errno != E2BIG) {
141d66cb1b1Spooka atf_tc_fail_errno("getfh size");
142d66cb1b1Spooka }
143d66cb1b1Spooka }
144d66cb1b1Spooka
145d66cb1b1Spooka fhp = malloc(fhsize);
146d66cb1b1Spooka RL(rump_sys_getfh(FNAME, fhp, &fhsize));
147d66cb1b1Spooka RL(rump_sys_unlink(FNAME));
148d66cb1b1Spooka
149fff1c84cShannken if (FSTYPE_LFS(tc))
1505e33baafSpooka atf_tc_expect_fail("fhopen() for removed file succeeds "
1515e33baafSpooka "(PR kern/43745)");
152d66cb1b1Spooka ATF_REQUIRE_ERRNO(ESTALE, rump_sys_fhopen(fhp, fhsize, O_RDONLY) == -1);
153d66cb1b1Spooka atf_tc_expect_pass();
154d66cb1b1Spooka
155d66cb1b1Spooka RL(rump_sys_chdir("/"));
156d66cb1b1Spooka }
157d66cb1b1Spooka #undef FNAME
158d66cb1b1Spooka
159d8a94b75Spooka /*
160d8a94b75Spooka * This test only checks the file system doesn't crash. We *might*
161d8a94b75Spooka * try a valid file handle.
162d8a94b75Spooka */
163d8a94b75Spooka static void
tfhinval(const atf_tc_t * tc,const char * path)164d8a94b75Spooka tfhinval(const atf_tc_t *tc, const char *path)
165d8a94b75Spooka {
166d8a94b75Spooka size_t fhsize;
167d8a94b75Spooka void *fhp;
168d8a94b75Spooka unsigned long seed;
169d8a94b75Spooka int fd;
170d8a94b75Spooka
171d8a94b75Spooka srandom(seed = time(NULL));
172d8a94b75Spooka printf("RNG seed %lu\n", seed);
173d8a94b75Spooka
174d8a94b75Spooka RL(rump_sys_chdir(path));
175d8a94b75Spooka fhsize = 0;
176d8a94b75Spooka if (rump_sys_getfh(".", NULL, &fhsize) == -1) {
177d8a94b75Spooka if (errno == EOPNOTSUPP) {
178d8a94b75Spooka atf_tc_skip("file handles not supported");
179d8a94b75Spooka } else if (errno != E2BIG) {
180d8a94b75Spooka atf_tc_fail_errno("getfh size");
181d8a94b75Spooka }
182d8a94b75Spooka }
183d8a94b75Spooka
184d8a94b75Spooka fhp = malloc(fhsize);
185d8a94b75Spooka tests_makegarbage(fhp, fhsize);
186d8a94b75Spooka fd = rump_sys_fhopen(fhp, fhsize, O_RDWR);
187d8a94b75Spooka if (fd != -1)
188d8a94b75Spooka rump_sys_close(fd);
189d8a94b75Spooka
190d8a94b75Spooka RL(rump_sys_chdir("/"));
191d8a94b75Spooka }
192d8a94b75Spooka
1936463b412Spooka ATF_TC_FSAPPLY(tmount, "mount/unmount");
1946463b412Spooka ATF_TC_FSAPPLY(tstatvfs, "statvfs");
1956463b412Spooka ATF_TC_FSAPPLY(tsync, "sync");
1966463b412Spooka ATF_TC_FSAPPLY(tfilehandle, "file handles");
197d66cb1b1Spooka ATF_TC_FSAPPLY(tfhremove, "fhtovp for removed file");
198d8a94b75Spooka ATF_TC_FSAPPLY(tfhinval, "fhopen invalid filehandle");
1996463b412Spooka
ATF_TP_ADD_TCS(tp)2006463b412Spooka ATF_TP_ADD_TCS(tp)
2016463b412Spooka {
2026463b412Spooka
2036463b412Spooka ATF_TP_FSAPPLY(tmount);
2046463b412Spooka ATF_TP_FSAPPLY(tstatvfs);
2056463b412Spooka ATF_TP_FSAPPLY(tsync);
2066463b412Spooka ATF_TP_FSAPPLY(tfilehandle);
207d66cb1b1Spooka ATF_TP_FSAPPLY(tfhremove);
208d8a94b75Spooka ATF_TP_FSAPPLY(tfhinval);
2096463b412Spooka
2106463b412Spooka return atf_no_error();
2116463b412Spooka }
212