xref: /illumos-gate/usr/src/test/os-tests/tests/syscall/open.c (revision edd580643f2cf1434e252cd7779e83182ea84945)
1*edd58064SJerry Jelinek /*
2*edd58064SJerry Jelinek  * This file and its contents are supplied under the terms of the
3*edd58064SJerry Jelinek  * Common Development and Distribution License ("CDDL"), version 1.0.
4*edd58064SJerry Jelinek  * You may only use this file in accordance with the terms of version
5*edd58064SJerry Jelinek  * 1.0 of the CDDL.
6*edd58064SJerry Jelinek  *
7*edd58064SJerry Jelinek  * A full copy of the text of the CDDL should have accompanied this
8*edd58064SJerry Jelinek  * source.  A copy of the CDDL is also available via the Internet at
9*edd58064SJerry Jelinek  * http://www.illumos.org/license/CDDL.
10*edd58064SJerry Jelinek  */
11*edd58064SJerry Jelinek 
12*edd58064SJerry Jelinek /*
13*edd58064SJerry Jelinek  * Copyright 2020 Joyent, Inc.
14*edd58064SJerry Jelinek  */
15*edd58064SJerry Jelinek 
16*edd58064SJerry Jelinek /*
17*edd58064SJerry Jelinek  * Test the open(2) syscall.
18*edd58064SJerry Jelinek  *
19*edd58064SJerry Jelinek  * Currently only tests O_DIRECT pass/fail based on the known support in the
20*edd58064SJerry Jelinek  * underlying file system.
21*edd58064SJerry Jelinek  *
22*edd58064SJerry Jelinek  * Note: there is a test for the O_DIRECTORY flag in the directory above this
23*edd58064SJerry Jelinek  * which could be consolidated into this code at some point.
24*edd58064SJerry Jelinek  */
25*edd58064SJerry Jelinek 
26*edd58064SJerry Jelinek #include <stdio.h>
27*edd58064SJerry Jelinek #include <sys/types.h>
28*edd58064SJerry Jelinek #include <sys/stat.h>
29*edd58064SJerry Jelinek #include <sys/statvfs.h>
30*edd58064SJerry Jelinek #include <sys/param.h>
31*edd58064SJerry Jelinek #include <fcntl.h>
32*edd58064SJerry Jelinek #include <errno.h>
33*edd58064SJerry Jelinek #include <unistd.h>
34*edd58064SJerry Jelinek #include <stdlib.h>
35*edd58064SJerry Jelinek #include <string.h>
36*edd58064SJerry Jelinek 
37*edd58064SJerry Jelinek static void
o_direct_test(const char * dir)38*edd58064SJerry Jelinek o_direct_test(const char *dir)
39*edd58064SJerry Jelinek {
40*edd58064SJerry Jelinek 	int fd;
41*edd58064SJerry Jelinek 	struct statvfs64 buf;
42*edd58064SJerry Jelinek 	char tmpname[MAXPATHLEN];
43*edd58064SJerry Jelinek 	char *path;
44*edd58064SJerry Jelinek 
45*edd58064SJerry Jelinek 	boolean_t pass;
46*edd58064SJerry Jelinek 
47*edd58064SJerry Jelinek 	(void) snprintf(tmpname, sizeof (tmpname), "%s/otstXXXXXX", dir);
48*edd58064SJerry Jelinek 	if ((path = mktemp(tmpname)) == NULL) {
49*edd58064SJerry Jelinek 		(void) printf("FAILED: unable to create temp file name\n");
50*edd58064SJerry Jelinek 		exit(1);
51*edd58064SJerry Jelinek 	}
52*edd58064SJerry Jelinek 
53*edd58064SJerry Jelinek 	if (statvfs64(dir, &buf) == -1) {
54*edd58064SJerry Jelinek 		perror("statvfs failed");
55*edd58064SJerry Jelinek 		exit(1);
56*edd58064SJerry Jelinek 	}
57*edd58064SJerry Jelinek 
58*edd58064SJerry Jelinek 	if (strcmp(buf.f_basetype, "zfs") == 0) {
59*edd58064SJerry Jelinek 		pass = B_TRUE;
60*edd58064SJerry Jelinek 	} else if (strcmp(buf.f_basetype, "tmpfs") == 0) {
61*edd58064SJerry Jelinek 		pass = B_FALSE;
62*edd58064SJerry Jelinek 	} else {
63*edd58064SJerry Jelinek 		(void) printf("SKIP: expected 'zfs' or 'tmpfs'\n");
64*edd58064SJerry Jelinek 		return;
65*edd58064SJerry Jelinek 	}
66*edd58064SJerry Jelinek 
67*edd58064SJerry Jelinek 	fd = open(path, O_WRONLY | O_CREAT | O_EXCL | O_DIRECT, 0644);
68*edd58064SJerry Jelinek 	if (fd >= 0) {
69*edd58064SJerry Jelinek 		(void) close(fd);
70*edd58064SJerry Jelinek 		(void) unlink(path);
71*edd58064SJerry Jelinek 		if (!pass) {
72*edd58064SJerry Jelinek 			(void) printf("FAILED: O_DIRECT on %s/tst_open is "
73*edd58064SJerry Jelinek 			    "expected to fail\n", dir);
74*edd58064SJerry Jelinek 			exit(1);
75*edd58064SJerry Jelinek 		}
76*edd58064SJerry Jelinek 	} else {
77*edd58064SJerry Jelinek 		if (pass) {
78*edd58064SJerry Jelinek 			(void) printf("FAILED: O_DIRECT on %s/tst_open is "
79*edd58064SJerry Jelinek 			    "expected to succeed\n", dir);
80*edd58064SJerry Jelinek 			exit(1);
81*edd58064SJerry Jelinek 		}
82*edd58064SJerry Jelinek 
83*edd58064SJerry Jelinek 		if (errno != EINVAL) {
84*edd58064SJerry Jelinek 			(void) printf("FAILED: expected EINVAL, got %d\n",
85*edd58064SJerry Jelinek 			    errno);
86*edd58064SJerry Jelinek 			exit(1);
87*edd58064SJerry Jelinek 		}
88*edd58064SJerry Jelinek 	}
89*edd58064SJerry Jelinek }
90*edd58064SJerry Jelinek 
91*edd58064SJerry Jelinek int
main(void)92*edd58064SJerry Jelinek main(void)
93*edd58064SJerry Jelinek {
94*edd58064SJerry Jelinek 	/* On typical illumos distros, /tmp is tmpfs, O_DIRECT should fail */
95*edd58064SJerry Jelinek 	o_direct_test("/tmp");
96*edd58064SJerry Jelinek 
97*edd58064SJerry Jelinek 	/* On typical illumos distros, /var is zfs, O_DIRECT should pass */
98*edd58064SJerry Jelinek 	o_direct_test("/var/tmp");
99*edd58064SJerry Jelinek 
100*edd58064SJerry Jelinek 	(void) printf("PASS\n");
101*edd58064SJerry Jelinek 	return (0);
102*edd58064SJerry Jelinek }
103