1986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang/* 2986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * Copyright (c) 2014 Fujitsu Ltd. 3986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> 4986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 5986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * This program is free software; you can redistribute it and/or modify 6986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * it under the terms of the GNU General Public License as published by 7986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * the Free Software Foundation; either version 2 of the License, or 8986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * (at your option) any later version. 9986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 10986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * This program is distributed in the hope that it will be useful, 11986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * but WITHOUT ANY WARRANTY; without even the implied warranty of 12986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * the GNU General Public License for more details. 14986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 15986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * You should have received a copy of the GNU General Public License 16986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * along with this program; if not, write to the Free Software 17986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang */ 19986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 20986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang/* 21986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * Test Description: 22986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * Verify that, 23986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 1. rename() fails with -1 return value and sets errno to ELOOP, if too 24986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * many symbolic links were encountered in resolving oldpath or newpath. 25986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 2. rename() fails with -1 return value and sets errno to EROFS, 26986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * if the file is on a read-only file system. 27986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * 3. rename() fails with -1 return value and sets errno to EMLINK, 28986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * if the file named by old is a directory and the link count of 29986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * the parent directory of new would exceed {LINK_MAX}. 30986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang */ 31986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 32986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <stdio.h> 33986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <errno.h> 34986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <sys/types.h> 35986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <sys/stat.h> 36986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <fcntl.h> 37986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include <sys/mount.h> 38986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 39986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include "test.h" 40986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#include "safe_macros.h" 41986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 42986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangchar *TCID = "rename11"; 43986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 44986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define MNTPOINT "mntpoint" 45986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define TEST_EROFS "mntpoint/test_erofs" 46986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define TEST_NEW_EROFS "mntpoint/new_test_erofs" 47986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 48986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define TEST_EMLINK "test_emlink" 49986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define TEST_NEW_EMLINK "emlink_dir/testdir" 50986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 51986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define TEST_NEW_ELOOP "new_test_eloop" 52986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang#define ELOPFILE "/test_eloop" 53986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic char elooppathname[sizeof(ELOPFILE) * 43] = "."; 54986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic int max_subdirs; 55986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 56986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic const char *device; 57986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic const char *fs_type; 58986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic int mount_flag; 59986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 60986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void cleanup(void); 61986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void setup(void); 62986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_eloop(void); 63986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_erofs(void); 64986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_emlink(void); 65986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 66986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void (*testfunc[])(void) = { test_eloop, test_erofs, test_emlink }; 67986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 68986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangint TST_TOTAL = ARRAY_SIZE(testfunc); 69986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 70986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangint main(int ac, char **av) 71986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 72986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang int lc, i; 73986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 74d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis tst_parse_opts(ac, av, NULL, NULL); 75986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 76986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang setup(); 77986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 78986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang for (lc = 0; TEST_LOOPING(lc); lc++) { 79986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_count = 0; 80986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 81986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang for (i = 0; i < TST_TOTAL; i++) 82986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang (*testfunc[i])(); 83986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 84986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 85986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang cleanup(); 86986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_exit(); 87986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 88986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 89986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void setup(void) 90986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 91986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang int i; 92986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 93986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_sig(NOFORK, DEF_HANDLER, cleanup); 94986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 95d1e794d62b1bf619df8390535e4c2a58899b1145Cyril Hrubis tst_require_root(); 96986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 97986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_tmpdir(); 98986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 99986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang TEST_PAUSE; 100986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 101986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang fs_type = tst_dev_fs_type(); 102986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang device = tst_acquire_device(cleanup); 103986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 104986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (!device) 105986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_brkm(TCONF, cleanup, "Failed to obtain block device"); 106986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 107d5e1788b647aca13ee89f41c08113d7b5fa1c499Zorro Lang tst_mkfs(cleanup, device, fs_type, NULL, NULL); 108986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 109986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_MKDIR(cleanup, MNTPOINT, 0755); 110986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (mount(device, MNTPOINT, fs_type, 0, NULL) < 0) { 111986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_brkm(TBROK | TERRNO, cleanup, 112986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang "mount device:%s failed", device); 113986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 114986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang mount_flag = 1; 115986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_TOUCH(cleanup, TEST_EROFS, 0644, NULL); 116986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 117986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_MKDIR(cleanup, TEST_EMLINK, 0755); 118986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang max_subdirs = tst_fs_fill_subdirs(cleanup, "emlink_dir"); 119986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang /* 120986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * NOTE: the ELOOP test is written based on that the consecutive 121986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang * symlinks limits in kernel is hardwired to 40. 122986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang */ 123986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_MKDIR(cleanup, "test_eloop", 0644); 124986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_SYMLINK(cleanup, "../test_eloop", "test_eloop/test_eloop"); 125986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang for (i = 0; i < 43; i++) 126986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang strcat(elooppathname, ELOPFILE); 127986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 128986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 129986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void check_and_print(int expected_errno) 130986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 131986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (TEST_RETURN == -1) { 132986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (TEST_ERRNO == expected_errno) { 133986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_resm(TPASS | TTERRNO, "failed as expected"); 134986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } else { 135986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_resm(TFAIL | TTERRNO, 136986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang "failed unexpectedly; expected - %d : %s", 137986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang expected_errno, strerror(expected_errno)); 138986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 139986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } else { 140986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_resm(TFAIL, "rename succeeded unexpectedly"); 141986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 142986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 143986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 144986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_eloop(void) 145986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 146986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang TEST(rename(elooppathname, TEST_NEW_ELOOP)); 147986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang check_and_print(ELOOP); 148986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 149986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (TEST_RETURN == 0) 150986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_UNLINK(cleanup, TEST_NEW_ELOOP); 151986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 152986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 153986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_erofs(void) 154986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 155986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (mount(device, MNTPOINT, fs_type, MS_REMOUNT | MS_RDONLY, NULL) < 0) { 156986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_brkm(TBROK | TERRNO, cleanup, 157986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang "mount device:%s failed", device); 158986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 159986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 160986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang TEST(rename(TEST_EROFS, TEST_NEW_EROFS)); 161986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang check_and_print(EROFS); 162986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 163986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (TEST_RETURN == 0) 164986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_UNLINK(cleanup, TEST_NEW_EROFS); 165986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 166986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (mount(device, MNTPOINT, fs_type, MS_REMOUNT, NULL) < 0) { 167986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_brkm(TBROK | TERRNO, cleanup, 168986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang "remount device:%s failed", device); 169986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 170986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 171986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 172986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void test_emlink(void) 173986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 174986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (max_subdirs == 0) { 175986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_resm(TCONF, "EMLINK test is not appropriate"); 176986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang return; 177986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang } 178986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 179986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang TEST(rename(TEST_EMLINK, TEST_NEW_EMLINK)); 180986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang check_and_print(EMLINK); 181986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 182986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (TEST_RETURN == 0) 183986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang SAFE_RMDIR(cleanup, TEST_NEW_EMLINK); 184986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 185986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 186986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wangstatic void cleanup(void) 187986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang{ 188c60a23034267b51ba36459a605592f4d3bc4172bCyril Hrubis if (mount_flag && tst_umount(MNTPOINT) < 0) 189986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_resm(TWARN | TERRNO, "umount device:%s failed", device); 190986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 191986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang if (device) 192bbdb9f78378c7e038f463efa39d2470e1c51ad54Cyril Hrubis tst_release_device(device); 193986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang 194986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang tst_rmdir(); 195986ff2f70acf322a5206dbac37ad969126250d6eXiaoguang Wang} 196