xref: /netbsd-src/tests/fs/vfs/t_vfsops.c (revision c54cb81102ced2313cb40993fe05548aca9933a1)
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