1/* 2 * Copyright (c) 2015 Fujitsu Ltd. 3 * Author: Guangwen Feng <fenggw-fnst@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 27#include "test.h" 28#include "safe_macros.h" 29#include "lapi/mount.h" 30 31static void setup(void); 32static void umount2_verify(void); 33static void cleanup(void); 34 35char *TCID = "umount2_01"; 36int TST_TOTAL = 1; 37 38#define DIR_MODE (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) 39#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID) 40#define MNTPOINT "mntpoint" 41 42static int fd; 43static int mount_flag; 44 45static const char *device; 46static const char *fs_type; 47 48int main(int ac, char **av) 49{ 50 int lc; 51 52 tst_parse_opts(ac, av, NULL, NULL); 53 54 setup(); 55 56 for (lc = 0; TEST_LOOPING(lc); lc++) { 57 tst_count = 0; 58 59 umount2_verify(); 60 } 61 62 cleanup(); 63 tst_exit(); 64} 65 66static void setup(void) 67{ 68 tst_require_root(); 69 70 tst_sig(NOFORK, DEF_HANDLER, NULL); 71 72 tst_tmpdir(); 73 74 fs_type = tst_dev_fs_type(); 75 device = tst_acquire_device(cleanup); 76 77 if (!device) 78 tst_brkm(TCONF, cleanup, "Failed to obtain block device"); 79 80 tst_mkfs(cleanup, device, fs_type, NULL, NULL); 81 82 SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE); 83 84 TEST_PAUSE; 85} 86 87static void umount2_verify(void) 88{ 89 int ret; 90 char buf[256]; 91 const char *str = "abcdefghijklmnopqrstuvwxyz"; 92 93 SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, 0, NULL); 94 mount_flag = 1; 95 96 fd = SAFE_CREAT(cleanup, MNTPOINT "/file", FILE_MODE); 97 98 TEST(umount2(MNTPOINT, MNT_DETACH)); 99 100 if (TEST_RETURN != 0) { 101 tst_resm(TFAIL | TTERRNO, "umount2(2) Failed"); 102 goto EXIT; 103 } 104 105 mount_flag = 0; 106 107 /* check the unavailability for new access */ 108 ret = access(MNTPOINT "/file", F_OK); 109 110 if (ret != -1) { 111 tst_resm(TFAIL, "umount2(2) MNT_DETACH flag " 112 "performed abnormally"); 113 goto EXIT; 114 } 115 116 /* 117 * check the old fd still points to the file 118 * in previous mount point and is available 119 */ 120 SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fd, str, strlen(str)); 121 122 SAFE_CLOSE(cleanup, fd); 123 124 SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, 0, NULL); 125 mount_flag = 1; 126 127 fd = SAFE_OPEN(cleanup, MNTPOINT "/file", O_RDONLY); 128 129 memset(buf, 0, sizeof(buf)); 130 131 SAFE_READ(cleanup, 1, fd, buf, strlen(str)); 132 133 if (strcmp(str, buf)) { 134 tst_resm(TFAIL, "umount2(2) MNT_DETACH flag " 135 "performed abnormally"); 136 goto EXIT; 137 } 138 139 tst_resm(TPASS, "umount2(2) Passed"); 140 141EXIT: 142 SAFE_CLOSE(cleanup, fd); 143 fd = 0; 144 145 if (mount_flag) { 146 if (tst_umount(MNTPOINT)) 147 tst_brkm(TBROK, cleanup, "umount() failed"); 148 mount_flag = 0; 149 } 150} 151 152static void cleanup(void) 153{ 154 if (fd > 0 && close(fd)) 155 tst_resm(TWARN | TERRNO, "Failed to close file"); 156 157 if (mount_flag && tst_umount(MNTPOINT)) 158 tst_resm(TWARN | TERRNO, "Failed to unmount"); 159 160 if (device) 161 tst_release_device(device); 162 163 tst_rmdir(); 164} 165