tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

rumphijack link



(I am not subscribed to this list, so please cc me in replies.)

The attached patch implements hijacking of link(2) in librumphijack
and adds some quick tests.  Can anyone put some extra eyeballs on this
before I commit?
Implement link(2) in rumphijack.  Add a couple trivial test cases.

Index: lib/librumphijack/hijack.c
===================================================================
RCS file: /cvsroot/src/lib/librumphijack/hijack.c,v
retrieving revision 1.90
diff -p -u -r1.90 hijack.c
--- lib/librumphijack/hijack.c  21 Apr 2011 13:38:14 -0000      1.90
+++ lib/librumphijack/hijack.c  19 May 2011 05:00:31 -0000
@@ -85,7 +85,7 @@ enum dualcall {
        DUALCALL_LSEEK,
        DUALCALL_GETDENTS,
        DUALCALL_UNLINK, DUALCALL_SYMLINK, DUALCALL_READLINK,
-       DUALCALL_RENAME,
+       DUALCALL_LINK, DUALCALL_RENAME,
        DUALCALL_MKDIR, DUALCALL_RMDIR,
        DUALCALL_UTIMES, DUALCALL_LUTIMES, DUALCALL_FUTIMES,
        DUALCALL_TRUNCATE, DUALCALL_FTRUNCATE,
@@ -226,6 +226,7 @@ struct sysnames {
        { DUALCALL_UNLINK,      "unlink",       RSYS_NAME(UNLINK)       },
        { DUALCALL_SYMLINK,     "symlink",      RSYS_NAME(SYMLINK)      },
        { DUALCALL_READLINK,    "readlink",     RSYS_NAME(READLINK)     },
+       { DUALCALL_LINK,        "link",         RSYS_NAME(LINK)         },
        { DUALCALL_RENAME,      "rename",       RSYS_NAME(RENAME)       },
        { DUALCALL_MKDIR,       "mkdir",        RSYS_NAME(MKDIR)        },
        { DUALCALL_RMDIR,       "rmdir",        RSYS_NAME(RMDIR)        },
@@ -1077,10 +1078,12 @@ __getcwd(char *bufp, size_t len)
        return rv;
 }
 
-int
-rename(const char *from, const char *to)
+static int
+moveish(const char *from, const char *to,
+    int (*rump_op)(const char *, const char *),
+    int (*host_op)(const char *, const char *))
 {
-       int (*op_rename)(const char *, const char *);
+       int (*op)(const char *, const char *);
        enum pathtype ptf, ptt;
 
        if ((ptf = path_isrump(from)) != PATH_HOST) {
@@ -1093,17 +1096,31 @@ rename(const char *from, const char *to)
                        from = path_host2rump(from);
                if (ptt == PATH_RUMP)
                        to = path_host2rump(to);
-               op_rename = GETSYSCALL(rump, RENAME);
+               op = rump_op;
        } else {
                if (path_isrump(to) != PATH_HOST) {
                        errno = EXDEV;
                        return -1;
                }
 
-               op_rename = GETSYSCALL(host, RENAME);
+               op = host_op;
        }
 
-       return op_rename(from, to);
+       return op(from, to);
+}
+
+int
+link(const char *from, const char *to)
+{
+       return moveish(from, to,
+           GETSYSCALL(rump, LINK), GETSYSCALL(host, LINK));
+}
+
+int
+rename(const char *from, const char *to)
+{
+       return moveish(from, to,
+           GETSYSCALL(rump, RENAME), GETSYSCALL(host, RENAME));
 }
 
 int __socket30(int, int, int);
Index: tests/lib/librumphijack/t_vfs.sh
===================================================================
RCS file: /cvsroot/src/tests/lib/librumphijack/t_vfs.sh,v
retrieving revision 1.4
diff -p -u -r1.4 t_vfs.sh
--- tests/lib/librumphijack/t_vfs.sh    8 Mar 2011 22:21:52 -0000       1.4
+++ tests/lib/librumphijack/t_vfs.sh    21 May 2011 20:11:45 -0000
@@ -90,6 +90,7 @@ test_case()
 test_case paxcopy
 test_case cpcopy
 test_case mv_nox
+test_case ln_nox
 
 #
 # use rumphijack to cp/pax stuff onto an image, unmount it, remount it
@@ -121,10 +122,10 @@ cpcopy()
 # which is not supported by rumpfs)
 #
 
-# stat default format sans changetime and filename
-statstr='%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf'
 mv_nox()
 {
+       # stat default format sans changetime and filename
+       statstr='%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf'
 
        atf_check -s exit:0 touch /rump/mnt/filename
        atf_check -s exit:0 -o save:stat.out \
@@ -135,7 +136,24 @@ mv_nox()
            stat -f "${statstr}" /rump/mnt/dir/same
 }
 
+ln_nox()
+{
+       # Omit st_nlink too, since it will increase.
+       statstr='%d %i %Sp %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf'
+
+       atf_check -s exit:0 touch /rump/mnt/filename
+       atf_check -s exit:0 -o save:stat.out \
+           stat -f "${statstr}" /rump/mnt/filename
+       atf_check -s exit:0 mkdir /rump/mnt/dir
+       atf_check -s exit:0 ln /rump/mnt/filename /rump/mnt/dir/same
+       atf_check -s exit:0 -o file:stat.out \
+           stat -f "${statstr}" /rump/mnt/filename
+       atf_check -s exit:0 -o file:stat.out \
+           stat -f "${statstr}" /rump/mnt/dir/same
+}
+
 simpletest mv_x
+simpletest ln_x
 simpletest runonprefix
 simpletest blanket
 simpletest doubleblanket
@@ -152,6 +170,15 @@ mv_x()
        atf_check -s exit:0 diff -ru ${thedir}.2 /rump/${thedir}
 }
 
+#
+# Fail to make a cross-kernel hard link.
+#
+ln_x()
+{
+       atf_check -s exit:0 touch ./loser
+       atf_check -s not-exit:0 -e ignore ln ./loser /rump/.
+}
+
 runonprefix()
 {
        atf_check -s exit:0 -o ignore stat /rump/dev
@@ -187,7 +214,9 @@ atf_init_test_cases()
        atf_add_test_case paxcopy
        atf_add_test_case cpcopy
        atf_add_test_case mv_x
+       atf_add_test_case ln_x
        atf_add_test_case mv_nox
+       atf_add_test_case ln_nox
        atf_add_test_case runonprefix
        atf_add_test_case blanket
        atf_add_test_case doubleblanket


Home | Main Index | Thread Index | Old Index