163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang/* 263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * Copyright (c) 2014 Fujitsu Ltd. 363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com> 463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * This program is free software; you can redistribute it and/or modify 663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * it under the terms of the GNU General Public License as published by 763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * the Free Software Foundation; either version 2 of the License, or 863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * (at your option) any later version. 963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 1063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * This program is distributed in the hope that it will be useful, 1163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * but WITHOUT ANY WARRANTY; without even the implied warranty of 1263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * GNU Library General Public License for more details. 1463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 1563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * You should have received a copy of the GNU General Public License 1663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * along with this program; if not, write to the Free Software 1763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 1963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang */ 2063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang/* 2163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * Test Description: 2263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * Verify that, 2363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 1. link() fails with -1 return value and sets errno to EPERM 2463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * if oldpath is a directory. 2563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 2. link() fails with -1 return value and sets errno to EXDEV 2663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * if oldpath and newpath are not on the same mounted file system( Linux 2763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * permits a file system to be mounted at multiple points, but link() 2863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * does not work across different mount points, even if the same 2963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * file system is mounted on both. ). 3063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 3. link() fails with -1 return value and sets errno to EROFS 3163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * if the file is on a read-only file system. 3263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * 4. link() fails with -1 return value and sets errno to ELOOP 3363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang * if too many symbolic links were encountered in resolving path. 3463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang */ 3563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 3663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <stdio.h> 3763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <stdlib.h> 3863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <unistd.h> 3963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <fcntl.h> 4063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <errno.h> 4163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <string.h> 4263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <signal.h> 4363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <sys/types.h> 4463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <sys/stat.h> 4563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <pwd.h> 4663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include <sys/mount.h> 4763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 4863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include "test.h" 4963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#include "safe_macros.h" 5063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 5163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 5263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang S_IXGRP|S_IROTH|S_IXOTH) 5363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define MNT_POINT "mntpoint" 5463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define TEST_FILE "testfile" 5563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define TEST_FILE1 "testfile1" 5663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define TEST_FILE2 "mntpoint/testfile3" 5763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang#define TEST_FILE3 "mntpoint/testfile4" 5863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 5963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic char test_file4[PATH_MAX] = "."; 6063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void setup(void); 6163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void cleanup(void); 6263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 636383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubisstatic const char *device; 6463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic int mount_flag; 6563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 6663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic struct test_case_t { 6763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang char *oldpath; 6863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang char *newpath; 6963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang int exp_errno; 7063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang} test_cases[] = { 7163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang {TEST_FILE1, TEST_FILE, EPERM}, 7263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang {TEST_FILE2, TEST_FILE, EXDEV}, 7363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang {TEST_FILE2, TEST_FILE3, EROFS}, 7463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang {test_file4, TEST_FILE, ELOOP}, 7563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang}; 7663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 7763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void link_verify(const struct test_case_t *); 7863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 7963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangchar *TCID = "link08"; 8063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangint TST_TOTAL = ARRAY_SIZE(test_cases); 8163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 8263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangint main(int ac, char **av) 8363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang{ 8463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang int i, lc; 8563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 86d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis tst_parse_opts(ac, av, NULL, NULL); 8763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 8863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang setup(); 8963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 9063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang for (lc = 0; TEST_LOOPING(lc); lc++) { 9163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_count = 0; 9263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang for (i = 0; i < TST_TOTAL; i++) 9363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang link_verify(&test_cases[i]); 9463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } 9563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 9663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang cleanup(); 9763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_exit(); 9863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 9963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang} 10063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 10163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void link_verify(const struct test_case_t *tc) 10263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang{ 10363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang TEST(link(tc->oldpath, tc->newpath)); 10463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 10563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang if (TEST_RETURN != -1) { 10663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_resm(TFAIL, "link succeeded unexpectedly"); 10763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang return; 10863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } 10963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 11063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang if (TEST_ERRNO == tc->exp_errno) { 11163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_resm(TPASS | TTERRNO, "link failed as expected"); 11263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } else { 11363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_resm(TFAIL | TTERRNO, 11463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang "link failed unexpectedly; expected: %d - %s", 11563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tc->exp_errno, strerror(tc->exp_errno)); 11663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } 11763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang} 11863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 11963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 12063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void setup(void) 12163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang{ 12263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang int i; 1236383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis const char *fs_type; 12463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 125d1e794d62b1bf619df8390535e4c2a58899b1145Cyril Hrubis tst_require_root(); 12663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 12763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_sig(NOFORK, DEF_HANDLER, cleanup); 12863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 12963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang TEST_PAUSE; 13063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 13163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_tmpdir(); 13263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 1336383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis fs_type = tst_dev_fs_type(); 1346383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis device = tst_acquire_device(cleanup); 1356383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis 1366383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis if (!device) 1376383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis tst_brkm(TCONF, cleanup, "Failed to acquire device"); 1386383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis 13963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang SAFE_MKDIR(cleanup, TEST_FILE1, DIR_MODE); 14063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 14163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang SAFE_MKDIR(cleanup, "test_eloop", DIR_MODE); 14263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang SAFE_SYMLINK(cleanup, "../test_eloop", "test_eloop/test_eloop"); 14363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang for (i = 0; i < 43; i++) 14463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang strcat(test_file4, "/test_eloop"); 14563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 146d5e1788b647aca13ee89f41c08113d7b5fa1c499Zorro Lang tst_mkfs(cleanup, device, fs_type, NULL, NULL); 14763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang SAFE_MKDIR(cleanup, MNT_POINT, DIR_MODE); 1486383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis if (mount(device, MNT_POINT, fs_type, 0, NULL) < 0) { 14963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_brkm(TBROK | TERRNO, cleanup, 15063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang "mount device:%s failed", device); 15163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } 15263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang mount_flag = 1; 15363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 15463147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang SAFE_TOUCH(cleanup, TEST_FILE2, 0644, NULL); 1556383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis if (mount(device, MNT_POINT, fs_type, 15663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang MS_REMOUNT | MS_RDONLY, NULL) < 0) { 15763147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_brkm(TBROK | TERRNO, cleanup, 15863147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang "mount device:%s failed", device); 15963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang } 16063147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang} 16163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 16263147204cf7928ccbc29a784d6b9638664c6584bZeng Linggangstatic void cleanup(void) 16363147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang{ 164c60a23034267b51ba36459a605592f4d3bc4172bCyril Hrubis if (mount_flag && tst_umount(MNT_POINT) < 0) 16563147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang tst_resm(TWARN | TERRNO, "umount device:%s failed", device); 16663147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 1676383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis if (device) 168bbdb9f78378c7e038f463efa39d2470e1c51ad54Cyril Hrubis tst_release_device(device); 16963147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang 1706383fd959dd889299c63fba116c81b6f81c21e76Cyril Hrubis tst_rmdir(); 17163147204cf7928ccbc29a784d6b9638664c6584bZeng Linggang} 172