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