1 /* 2 * Copyright (c) 2015 Fujitsu Ltd. 3 * Author: Guangwen Feng <fenggw-fnst (at) cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License 14 * alone with this program. 15 */ 16 17 /* 18 * DESCRIPTION 19 * Test for feature MNT_DETACH of umount2(). 20 * "Perform a lazy unmount: make the mount point unavailable for 21 * new accesses, and actually perform the unmount when the mount 22 * point ceases to be busy." 23 */ 24 25 #include <errno.h> 26 #include <sys/mount.h> 27 28 #include "test.h" 29 #include "safe_macros.h" 30 #include "lapi/mount.h" 31 32 static void setup(void); 33 static void umount2_verify(void); 34 static void cleanup(void); 35 36 char *TCID = "umount2_01"; 37 int TST_TOTAL = 1; 38 39 #define DIR_MODE (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) 40 #define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID) 41 #define MNTPOINT "mntpoint" 42 43 static int fd; 44 static int mount_flag; 45 46 static const char *device; 47 static const char *fs_type; 48 49 int main(int ac, char **av) 50 { 51 int lc; 52 53 tst_parse_opts(ac, av, NULL, NULL); 54 55 setup(); 56 57 for (lc = 0; TEST_LOOPING(lc); lc++) { 58 tst_count = 0; 59 60 umount2_verify(); 61 } 62 63 cleanup(); 64 tst_exit(); 65 } 66 67 static void setup(void) 68 { 69 tst_require_root(); 70 71 tst_sig(NOFORK, DEF_HANDLER, NULL); 72 73 tst_tmpdir(); 74 75 fs_type = tst_dev_fs_type(); 76 device = tst_acquire_device(cleanup); 77 78 if (!device) 79 tst_brkm(TCONF, cleanup, "Failed to obtain block device"); 80 81 tst_mkfs(cleanup, device, fs_type, NULL, NULL); 82 83 SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE); 84 85 TEST_PAUSE; 86 } 87 88 static void umount2_verify(void) 89 { 90 int ret; 91 char buf[256]; 92 const char *str = "abcdefghijklmnopqrstuvwxyz"; 93 94 SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, 0, NULL); 95 mount_flag = 1; 96 97 fd = SAFE_CREAT(cleanup, MNTPOINT "/file", FILE_MODE); 98 99 TEST(umount2(MNTPOINT, MNT_DETACH)); 100 101 if (TEST_RETURN != 0) { 102 tst_resm(TFAIL | TTERRNO, "umount2(2) Failed"); 103 goto EXIT; 104 } 105 106 mount_flag = 0; 107 108 /* check the unavailability for new access */ 109 ret = access(MNTPOINT "/file", F_OK); 110 111 if (ret != -1) { 112 tst_resm(TFAIL, "umount2(2) MNT_DETACH flag " 113 "performed abnormally"); 114 goto EXIT; 115 } 116 117 /* 118 * check the old fd still points to the file 119 * in previous mount point and is available 120 */ 121 SAFE_WRITE(cleanup, 1, fd, str, strlen(str)); 122 123 SAFE_CLOSE(cleanup, fd); 124 125 SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, 0, NULL); 126 mount_flag = 1; 127 128 fd = SAFE_OPEN(cleanup, MNTPOINT "/file", O_RDONLY); 129 130 memset(buf, 0, sizeof(buf)); 131 132 SAFE_READ(cleanup, 1, fd, buf, strlen(str)); 133 134 if (strcmp(str, buf)) { 135 tst_resm(TFAIL, "umount2(2) MNT_DETACH flag " 136 "performed abnormally"); 137 goto EXIT; 138 } 139 140 tst_resm(TPASS, "umount2(2) Passed"); 141 142 EXIT: 143 SAFE_CLOSE(cleanup, fd); 144 fd = 0; 145 146 if (mount_flag) { 147 if (tst_umount(MNTPOINT)) 148 tst_brkm(TBROK, cleanup, "umount() failed"); 149 mount_flag = 0; 150 } 151 } 152 153 static void cleanup(void) 154 { 155 if (fd > 0 && close(fd)) 156 tst_resm(TWARN | TERRNO, "Failed to close file"); 157 158 if (mount_flag && tst_umount(MNTPOINT)) 159 tst_resm(TWARN | TERRNO, "Failed to unmount"); 160 161 if (device) 162 tst_release_device(device); 163 164 tst_rmdir(); 165 } 166