tech-kern archive

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

[PATCH] llink(2) (was: Re: Adding linux_link(2) system call, second round)



On Sun, Jul 31, 2011 at 06:36:53PM +0000, Christos Zoulas wrote:
> I don't have an issue with it as long as:
>       - fsck does not get confused
>       - filesystems don't need to be modified to support it
>       - there is consensus that this is not harmful
>       - I am also ambivalent about exposing this in the native abi
>         because it will only cause confusion.

Attached is the patch that adds llink(2) and its documentation. The test I
ran are below (the llink program just calls llink(2)).

fsck has no probmem with it, ffs was not modified. For it
being harmful, I cannot immagine what could be done with it, but 
we could restrict it to root just in case.

On confusion, well, I think the llink name speaks by itself.

# ls -li
total 1
3648 drwxr-xr-x  2 root  wheel  512 Aug  1 11:31 dir
   3 -rw-r--r--  2 root  wheel    0 Aug  1 11:30 file
   3 -rw-r--r--  2 root  wheel    0 Aug  1 11:30 hfile
   5 lrwxr-xr-x  1 root  wheel    3 Aug  1 11:31 sdir -> dir
   4 lrwxr-xr-x  1 root  wheel    4 Aug  1 11:31 sfile -> file
   6 lrwxr-xr-x  1 root  wheel   11 Aug  1 11:32 void -> nonexistent
# /home2/manu/llink sfile hsfile
# /home2/manu/llink sdir hsdir
# /home2/manu/llink void hvoid 
# ls -li
total 1
3648 drwxr-xr-x  2 root  wheel  512 Aug  1 11:31 dir
   3 -rw-r--r--  2 root  wheel    0 Aug  1 11:30 file
   3 -rw-r--r--  2 root  wheel    0 Aug  1 11:30 hfile
   5 lrwxr-xr-x  2 root  wheel    3 Aug  1 11:31 hsdir -> dir
   4 lrwxr-xr-x  2 root  wheel    4 Aug  1 11:31 hsfile -> file
   6 lrwxr-xr-x  2 root  wheel   11 Aug  1 11:32 hvoid -> nonexistent
   5 lrwxr-xr-x  2 root  wheel    3 Aug  1 11:31 sdir -> dir
   4 lrwxr-xr-x  2 root  wheel    4 Aug  1 11:31 sfile -> file
   6 lrwxr-xr-x  2 root  wheel   11 Aug  1 11:32 void -> nonexistent

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: include/unistd.h
===================================================================
RCS file: /cvsroot/src/include/unistd.h,v
retrieving revision 1.126
diff -U4 -r1.126 unistd.h
--- include/unistd.h    26 Jun 2011 16:42:40 -0000      1.126
+++ include/unistd.h    1 Aug 2011 09:34:20 -0000
@@ -124,8 +124,9 @@
 pid_t   getppid(void);
 uid_t   getuid(void);
 int     isatty(int);
 int     link(const char *, const char *);
+int     llink(const char *, const char *);
 long    pathconf(const char *, int);
 int     pause(void);
 int     pipe(int *);
 #if __SSP_FORTIFY_LEVEL == 0
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.430
diff -U4 -r1.430 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c     17 Jun 2011 14:23:51 -0000      1.430
+++ sys/kern/vfs_syscalls.c     1 Aug 2011 09:34:20 -0000
@@ -1769,27 +1769,32 @@
 }
 
 /*
  * Make a hard file link.
+ * The flag argument can be 
+ * - FOLLOW for sys_link, to link to symlink target
+ * - NOFOLLOW for sys_llink, to link to symlink itself
  */
 /* ARGSUSED */
-int
-sys_link(struct lwp *l, const struct sys_link_args *uap, register_t *retval)
+static int
+do_sys_link(struct lwp *l, const char *path, const char *link, 
+           int flags, register_t *retval) 
 {
-       /* {
-               syscallarg(const char *) path;
-               syscallarg(const char *) link;
-       } */
        struct vnode *vp;
        struct pathbuf *linkpb;
        struct nameidata nd;
+       namei_simple_flags_t namei_simple_flags;
        int error;
 
-       error = namei_simple_user(SCARG(uap, path),
-                               NSM_FOLLOW_TRYEMULROOT, &vp);
+       if (flags & FOLLOW)
+               namei_simple_flags = NSM_FOLLOW_TRYEMULROOT;
+       else
+               namei_simple_flags =  NSM_NOFOLLOW_TRYEMULROOT;
+
+       error = namei_simple_user(path, namei_simple_flags, &vp);
        if (error != 0)
                return (error);
-       error = pathbuf_copyin(SCARG(uap, link), &linkpb);
+       error = pathbuf_copyin(link, &linkpb);
        if (error) {
                goto out1;
        }
        NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
@@ -1826,8 +1831,35 @@
        goto out2;
 }
 
 int
+sys_link(struct lwp *l, const struct sys_link_args *uap, register_t *retval)
+{
+       /* {
+               syscallarg(const char *) path;
+               syscallarg(const char *) link;
+       } */
+       const char *path = SCARG(uap, path);
+       const char *link = SCARG(uap, link);
+
+       return do_sys_link(l, path, link, FOLLOW, retval);
+}
+
+int
+sys_llink(struct lwp *l, const struct sys_llink_args *uap, register_t *retval)
+{
+       /* {
+               syscallarg(const char *) path;
+               syscallarg(const char *) link;
+       } */
+       const char *path = SCARG(uap, path);
+       const char *link = SCARG(uap, link);
+
+       return do_sys_link(l, path, link, NOFOLLOW, retval);
+}
+
+
+int
 do_sys_symlink(const char *patharg, const char *link, enum uio_seg seg)
 {
        struct proc *p = curproc;
        struct vattr vattr;
@@ -1850,8 +1882,10 @@
                        error = ENOMEM;
                        goto out1;
                }
        }
+       ktrkuser("symlink-target", path, strlen(path));
+
        NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
        if ((error = namei(&nd)) != 0)
                goto out2;
        if (nd.ni_vp) {
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/kern/syscalls.master,v
retrieving revision 1.249
diff -U4 -r1.249 syscalls.master
--- sys/kern/syscalls.master    26 Jun 2011 17:05:24 -0000      1.249
+++ sys/kern/syscalls.master    1 Aug 2011 09:34:20 -0000
@@ -892,4 +892,5 @@
 455    STD  RUMP       { int|sys||kqueue1(int flags); }
 456    STD  RUMP       { int|sys||paccept(int s, struct sockaddr *name, \
                            socklen_t *anamelen, const sigset_t *mask, \
                            int flags); }
+457    STD  RUMP       { int|sys||llink(const char *path, const char *link); }
Index: distrib/sets/lists/comp/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/mi,v
retrieving revision 1.1635
diff -U4 -r1.1635 mi
--- distrib/sets/lists/comp/mi  28 Jun 2011 04:53:51 -0000      1.1635
+++ distrib/sets/lists/comp/mi  1 Aug 2011 09:34:20 -0000
@@ -4400,8 +4400,9 @@
 ./usr/share/man/cat2/lfs_segclean.0            comp-c-catman           .cat
 ./usr/share/man/cat2/lfs_segwait.0             comp-c-catman           .cat
 ./usr/share/man/cat2/link.0                    comp-c-catman           .cat
 ./usr/share/man/cat2/listen.0                  comp-c-catman           .cat
+./usr/share/man/cat2/llink.0                   comp-c-catman           .cat
 ./usr/share/man/cat2/lseek.0                   comp-c-catman           .cat
 ./usr/share/man/cat2/lstat.0                   comp-c-catman           .cat
 ./usr/share/man/cat2/lutimes.0                 comp-c-catman           .cat
 ./usr/share/man/cat2/m68k_sync_icache.0                comp-c-catman           
.cat
@@ -10563,8 +10565,9 @@
 ./usr/share/man/html2/lfs_segclean.html                comp-c-htmlman          
html
 ./usr/share/man/html2/lfs_segwait.html         comp-c-htmlman          html
 ./usr/share/man/html2/link.html                        comp-c-htmlman          
html
 ./usr/share/man/html2/listen.html              comp-c-htmlman          html
+./usr/share/man/html2/llink.html               comp-c-htmlman          html
 ./usr/share/man/html2/lseek.html               comp-c-htmlman          html
 ./usr/share/man/html2/lstat.html               comp-c-htmlman          html
 ./usr/share/man/html2/lutimes.html             comp-c-htmlman          html
 ./usr/share/man/html2/m68k_sync_icache.html    comp-c-htmlman          html
@@ -16506,8 +16510,9 @@
 ./usr/share/man/man2/lfs_segclean.2            comp-c-man              .man
 ./usr/share/man/man2/lfs_segwait.2             comp-c-man              .man
 ./usr/share/man/man2/link.2                    comp-c-man              .man
 ./usr/share/man/man2/listen.2                  comp-c-man              .man
+./usr/share/man/man2/llink.2                   comp-c-man              .man
 ./usr/share/man/man2/lseek.2                   comp-c-man              .man
 ./usr/share/man/man2/lstat.2                   comp-c-man              .man
 ./usr/share/man/man2/lutimes.2                 comp-c-man              .man
 ./usr/share/man/man2/m68k_sync_icache.2                comp-c-man              
.man
Index: lib/libc/sys/link.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/link.2,v
retrieving revision 1.24
diff -U4 -r1.24 link.2
--- lib/libc/sys/link.2 31 May 2010 12:16:20 -0000      1.24
+++ lib/libc/sys/link.2 1 Aug 2011 09:34:20 -0000
@@ -1,7 +1,7 @@
 .\"    $NetBSD: link.2,v 1.24 2010/05/31 12:16:20 njoly Exp $
 .\"
-.\" Copyright (c) 1980, 1991, 1993
+.\" Copyright (c) 1980, 1991, 1993, 2011
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -40,8 +40,10 @@
 .Sh SYNOPSIS
 .In unistd.h
 .Ft int
 .Fn link "const char *name1" "const char *name2"
+.Ft int
+.Fn llink "const char *name1" "const char *name2"
 .Sh DESCRIPTION
 The
 .Fn link
 function call
@@ -76,8 +78,17 @@
 must be in the same file system.
 .Fa name1
 may not be a directory unless the caller is the super-user
 and the file system containing it supports linking to directories.
+.Pp 
+.Fn llink
+is like 
+.Fn link
+except in the case where the named file is a symbolic link, in which case 
+.Fn llink
+links on the symbolic link itself, while
+.Fn link
+links on the symbolic link target. 
 .Sh RETURN VALUES
 Upon successful completion, a value of 0 is returned.
 Otherwise, a value of \-1 is returned and
 .Va errno
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.207
diff -U4 -r1.207 Makefile.inc
--- lib/libc/sys/Makefile.inc   27 Jun 2011 16:39:44 -0000      1.207
+++ lib/libc/sys/Makefile.inc   1 Aug 2011 09:34:20 -0000
@@ -99,13 +99,13 @@
                _ksem_close.S _ksem_destroy.S _ksem_getvalue.S _ksem_init.S \
                _ksem_post.S _ksem_trywait.S _ksem_unlink.S _ksem_wait.S \
                _ksem_open.S \
        lchflags.S lchmod.S lchown.S lfs_bmapv.S lfs_markv.S lfs_segclean.S \
-               __lfs_segwait50.S link.S listen.S __lstat50.S __lutimes50.S \
-               _lwp_create.S _lwp_exit.S _lwp_kill.S ___lwp_park50.S \
-               _lwp_self.S _lwp_wait.S _lwp_unpark.S _lwp_unpark_all.S \
-               _lwp_suspend.S _lwp_continue.S _lwp_wakeup.S _lwp_detach.S \
-               _lwp_setprivate.S \
+               __lfs_segwait50.S link.S listen.S llink.S __lstat50.S \
+               __lutimes50.S _lwp_create.S _lwp_exit.S _lwp_kill.S \
+               ___lwp_park50.S _lwp_self.S _lwp_wait.S _lwp_unpark.S \
+               _lwp_unpark_all.S _lwp_suspend.S _lwp_continue.S \
+               _lwp_wakeup.S _lwp_detach.S _lwp_setprivate.S \
                _lwp_setname.S _lwp_getname.S _lwp_ctl.S \
        madvise.S mincore.S minherit.S mkdir.S mkfifo.S __mknod50.S \
                mlock.S mlockall.S modctl.S __mount50.S mprotect.S \
                __msgctl50.S msgget.S munlock.S munlockall.S munmap.S \
@@ -282,8 +282,9 @@
 MLINKS+=intro.2 errno.2
 MLINKS+=kqueue.2 kevent.2
 MLINKS+=ktrace.2 fktrace.2
 MLINKS+=lseek.2 seek.2
+MLINKS+=link.2 llink.2
 MLINKS+=_lwp_suspend.2 _lwp_continue.2
 MLINKS+=_lwp_getprivate.2 _lwp_setprivate.2
 MLINKS+=madvise.2 posix_madvise.2
 MLINKS+=mlock.2 munlock.2


Home | Main Index | Thread Index | Old Index