Signed-off-by: Xing Gu <gux.f...@cn.fujitsu.com>
---
 runtest/syscalls                                |  2 +-
 testcases/kernel/syscalls/renameat/renameat01.c | 88 ++++++++++++++++++++++++-
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/runtest/syscalls b/runtest/syscalls
index c132a69..abb7906 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -850,7 +850,7 @@ rename13 rename13
 rename14 rename14
 
 #renameat test cases
-renameat01 renameat01
+renameat01 renameat01 -D $LTP_DEV -T $LTP_DEV_FS_TYPE
 
 rmdir01 rmdir01
 rmdir02 rmdir02 -D $LTP_DEV -T $LTP_DEV_FS_TYPE
diff --git a/testcases/kernel/syscalls/renameat/renameat01.c 
b/testcases/kernel/syscalls/renameat/renameat01.c
index 8632950..ce1e146 100644
--- a/testcases/kernel/syscalls/renameat/renameat01.c
+++ b/testcases/kernel/syscalls/renameat/renameat01.c
@@ -24,6 +24,15 @@
  *      is relative and olddirfd is a file descriptor referring to
  *      a file other than a directory, or similar for newpath and
  *      newdirfd.
+ *   3) renameat(2) returns -1 and sets errno to ELOOP if too many
+ *      symbolic links were encountered in resolving oldpath or
+ *      newpath.
+ *   4) renameat(2) returns -1 and sets errno to EROFS if the file
+ *      is on a read-only file system.
+ *   5) renameat(2) returns -1 and sets errno to EMLINK if oldpath
+ *      already has the maximum number of links to it, or it is a
+ *      directory and the directory containing newpath has the
+ *      maximum number of links.
  */
 
 #define _GNU_SOURCE
@@ -37,6 +46,7 @@
 #include <errno.h>
 #include <string.h>
 #include <signal.h>
+#include <sys/mount.h>
 
 #include "test.h"
 #include "usctest.h"
@@ -44,14 +54,21 @@
 #include "lapi/fcntl.h"
 #include "lapi/renameat.h"
 
+#define MNTPOINT "mntpoint"
 #define TESTDIR "testdir"
 #define NEW_TESTDIR "new_testdir"
+#define TESTDIR2 "/loopdir"
+#define NEW_TESTDIR2 "newloopdir"
+#define TESTDIR3 "emlinkdir"
+#define NEW_TESTDIR3 "testemlinkdir/new_emlinkdir"
 #define TESTFILE "testfile"
 #define NEW_TESTFILE "new_testfile"
 #define TESTFILE2 "testfile2"
 #define NEW_TESTFILE2 "new_testfile2"
 #define TESTFILE3 "testdir/testfile"
 #define TESTFILE4 "testfile4"
+#define TESTFILE5 "mntpoint/rofile"
+#define NEW_TESTFILE5 "mntpoint/newrofile"
 
 #define DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO)
 #define FILEMODE (S_IRWXU | S_IRWXG | S_IRWXO)
@@ -63,6 +80,18 @@ static int badfd = 100;
 static int filefd;
 static char absoldpath[256];
 static char absnewpath[256];
+static char looppathname[sizeof(TESTDIR2) * 43] = ".";
+static int max_subdirs;
+
+static char *fstype = "ext2";
+static char *device;
+static int mount_flag;
+
+static option_t options[] = {
+       {"T:", NULL, &fstype},
+       {"D:", NULL, &device},
+       {NULL, NULL, NULL},
+};
 
 static struct test_case_t {
        int *oldfdptr;
@@ -76,25 +105,35 @@ static struct test_case_t {
        { &olddirfd, absoldpath, &newdirfd, absnewpath, 0 },
        { &badfd, TESTFILE, &badfd, NEW_TESTFILE, EBADF },
        { &filefd, TESTFILE, &filefd, NEW_TESTFILE, ENOTDIR },
+       { &curfd, looppathname, &curfd, NEW_TESTDIR2, ELOOP },
+       { &curfd, TESTFILE5, &curfd, NEW_TESTFILE5, EROFS },
+       { &curfd, TESTDIR3, &curfd, NEW_TESTDIR3, EMLINK },
 };
 
 static void setup(void);
 static void cleanup(void);
 static void renameat_verify(const struct test_case_t *);
+static void help(void);
 
 char *TCID = "renameat01";
 int TST_TOTAL = ARRAY_SIZE(test_cases);
-static int exp_enos[] = { EBADF, ENOTDIR, 0 };
+static int exp_enos[] = { EBADF, ENOTDIR, ELOOP, EROFS,
+                                                       EMLINK, 0 };
 
 int main(int ac, char **av)
 {
        int i, lc;
        const char *msg;
 
-       msg = parse_opts(ac, av, NULL, NULL);
+       msg = parse_opts(ac, av, options, help);
        if (msg != NULL)
                tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
 
+       if (!device) {
+               tst_brkm(TCONF, NULL, "you must specify the device "
+                       "used for mounting with -D option");
+       }
+
        setup();
 
        TEST_EXP_ENOS(exp_enos);
@@ -113,6 +152,7 @@ int main(int ac, char **av)
 static void setup(void)
 {
        char *tmpdir;
+       int i;
 
        if ((tst_kvercmp(2, 6, 16)) < 0) {
                tst_brkm(TCONF, NULL,
@@ -120,6 +160,8 @@ static void setup(void)
                        "2.6.16 and higher");
        }
 
+       tst_require_root(NULL);
+
        tst_sig(NOFORK, DEF_HANDLER, cleanup);
 
        tst_tmpdir();
@@ -143,10 +185,42 @@ static void setup(void)
 
        filefd = SAFE_OPEN(cleanup, TESTFILE4,
                                O_RDWR | O_CREAT, FILEMODE);
+
+       /*
+        * NOTE: the ELOOP test is written based on that the
+        * consecutive symlinks limit in kernel is hardwired
+        * to 40.
+        */
+       SAFE_MKDIR(cleanup, "loopdir", DIRMODE);
+       SAFE_SYMLINK(cleanup, "../loopdir", "loopdir/loopdir");
+       for (i = 0; i < 43; i++)
+               strcat(looppathname, TESTDIR2);
+
+       tst_mkfs(NULL, device, fstype, NULL);
+       SAFE_MKDIR(cleanup, MNTPOINT, DIRMODE);
+       if (mount(device, MNTPOINT, fstype, 0, NULL) < 0) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                       "mount device:%s failed", device);
+       }
+       mount_flag = 1;
+       SAFE_TOUCH(cleanup, TESTFILE5, FILEMODE, NULL);
+       if (mount(device, MNTPOINT, fstype,
+                       MS_REMOUNT | MS_RDONLY, NULL) < 0) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                       "mount device:%s failed", device);
+       }
+
+       SAFE_MKDIR(cleanup, TESTDIR3, DIRMODE);
+       max_subdirs = tst_fs_fill_subdirs(cleanup, "testemlinkdir");
 }
 
 static void renameat_verify(const struct test_case_t *tc)
 {
+       if (tc->exp_errno == EMLINK && max_subdirs == 0) {
+               tst_resm(TCONF, "EMLINK test is not appropriate");
+               return;
+       }
+
        TEST(renameat(*(tc->oldfdptr), tc->oldpath,
                        *(tc->newfdptr), tc->newpath));
 
@@ -181,5 +255,15 @@ static void cleanup(void)
        if (filefd && close(filefd) < 0)
                tst_resm(TWARN | TERRNO, "close filefd failed");
 
+       if (mount_flag && umount(MNTPOINT) < 0)
+               tst_resm(TWARN | TERRNO, "umount %s failed", MNTPOINT);
+
        tst_rmdir();
 }
+
+static void help(void)
+{
+       printf("-T type   : specifies the type of filesystem to be mounted. "
+               "Default ext2.\n");
+       printf("-D device : device used for mounting.\n");
+}
-- 
1.9.3


------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to