Source-Changes-HG archive

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

[src/trunk]: src/sys Store full executable path in p->p_path as discussed in ...



details:   https://anonhg.NetBSD.org/src/rev/ee5032074427
branches:  trunk
changeset: 827671:ee5032074427
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Nov 07 19:44:04 2017 +0000

description:
Store full executable path in p->p_path as discussed in tech-kern.
This means that the full executable path is always available.

- exec_elf.c: use p->path to set AT_SUN_EXECNAME, and since this is
  always set, do so unconditionally.
- kern_exec.c: simplify pathexec, use kmem_strfree where appropriate
  and set p->p_path
- kern_exit.c: free p->p_path
- kern_fork.c: set p->p_path for the child.
- kern_proc.c: use p->p_path to return the executable pathname; the
  NULL check for p->p_path, should be a KASSERT?
- exec.h: gc ep_path, it is not used anymore
- param.h: bump version, 'struct proc' size change

TODO:
1. reference count the path string, to save copy at fork and free
   just before exec?
2. canonicalize the pathname by changing namei() to LOCKPARENT
   vnode and then using getcwd() on the parent directory?

diffstat:

 sys/kern/exec_elf.c  |  27 +++++++++-------------
 sys/kern/kern_exec.c |  62 +++++++--------------------------------------------
 sys/kern/kern_exit.c |   5 ++-
 sys/kern/kern_fork.c |   8 +++++-
 sys/kern/kern_proc.c |  23 ++++---------------
 sys/sys/exec.h       |   3 +-
 sys/sys/param.h      |   4 +-
 sys/sys/proc.h       |   3 +-
 8 files changed, 39 insertions(+), 96 deletions(-)

diffs (truncated from 333 to 300 lines):

diff -r c502ad28a381 -r ee5032074427 sys/kern/exec_elf.c
--- a/sys/kern/exec_elf.c       Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/kern/exec_elf.c       Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_elf.c,v 1.92 2017/10/16 01:50:55 christos Exp $   */
+/*     $NetBSD: exec_elf.c,v 1.93 2017/11/07 19:44:04 christos Exp $   */
 
 /*-
  * Copyright (c) 1994, 2000, 2005, 2015 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.92 2017/10/16 01:50:55 christos Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.93 2017/11/07 19:44:04 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -226,11 +226,9 @@
                a->a_v = l->l_proc->p_stackbase;
                a++;
 
-               if (pack->ep_path) {
-                       execname = a;
-                       a->a_type = AT_SUN_EXECNAME;
-                       a++;
-               }
+               execname = a;
+               a->a_type = AT_SUN_EXECNAME;
+               a++;
 
                exec_free_emul_arg(pack);
        }
@@ -243,15 +241,12 @@
 
        KASSERT(vlen <= sizeof(ai));
 
-       if (execname) {
-               char *path = pack->ep_path;
-               execname->a_v = (uintptr_t)(*stackp + vlen);
-               len = strlen(path) + 1;
-               if ((error = copyout(path, (*stackp + vlen), len)) != 0)
-                       return error;
-               len = ALIGN(len);
-       } else
-               len = 0;
+       char *path = l->l_proc->p_path;
+       execname->a_v = (uintptr_t)(*stackp + vlen);
+       len = strlen(path) + 1;
+       if ((error = copyout(path, (*stackp + vlen), len)) != 0)
+               return error;
+       len = ALIGN(len);
 
        if ((error = copyout(ai, *stackp, vlen)) != 0)
                return error;
diff -r c502ad28a381 -r ee5032074427 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/kern/kern_exec.c      Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.449 2017/10/20 19:06:46 riastradh Exp $        */
+/*     $NetBSD: kern_exec.c,v 1.450 2017/11/07 19:44:04 christos Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.449 2017/10/20 19:06:46 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.450 2017/11/07 19:44:04 christos Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -925,55 +925,15 @@
 }
 
 static void
-pathexec(struct exec_package *epp, struct lwp *l, const char *pathstring)
+pathexec(struct proc *p, const char *resolvedname)
 {
-       const char              *commandname;
-       size_t                  commandlen;
-       char                    *path;
-       struct proc             *p = l->l_proc;
+       KASSERT(resolvedname[0] == '/');
 
        /* set command name & other accounting info */
-       commandname = strrchr(epp->ep_resolvedname, '/');
-       if (commandname != NULL) {
-               commandname++;
-       } else {
-               commandname = epp->ep_resolvedname;
-       }
-       commandlen = min(strlen(commandname), MAXCOMLEN);
-       (void)memcpy(p->p_comm, commandname, commandlen);
-       p->p_comm[commandlen] = '\0';
-
+       strlcpy(p->p_comm, strrchr(resolvedname, '/') + 1, sizeof(p->p_comm));
 
-       /*
-        * If the path starts with /, we don't need to do any work.
-        * This handles the majority of the cases.
-        * In the future perhaps we could canonicalize it?
-        */
-       path = PNBUF_GET();
-       if (pathstring[0] == '/') {
-               (void)strlcpy(path, pathstring, MAXPATHLEN);
-               epp->ep_path = path;
-       }
-#ifdef notyet
-       /*
-        * Although this works most of the time [since the entry was just
-        * entered in the cache] we don't use it because it will fail for
-        * entries that are not placed in the cache because their name is
-        * longer than NCHNAMLEN and it is not the cleanest interface,
-        * because there could be races. When the namei cache is re-written,
-        * this can be changed to use the appropriate function.
-        */
-       else if (!(error = vnode_to_path(path, MAXPATHLEN, p->p_textvp, l, p)))
-               epp->ep_path = path;
-#endif
-       else {
-#ifdef notyet
-               printf("Cannot get path for pid %d [%s] (error %d)\n",
-                   (int)p->p_pid, p->p_comm, error);
-#endif
-               PNBUF_PUT(path);
-               epp->ep_path = NULL;
-       }
+       kmem_strfree(p->p_path);
+       p->p_path = kmem_strdupsize(resolvedname, NULL, KM_SLEEP);
 }
 
 /* XXX elsewhere */
@@ -1194,7 +1154,7 @@
        if (error != 0)
                goto exec_abort;
 
-       pathexec(epp, l, data->ed_pathstring);
+       pathexec(p, epp->ep_resolvedname);
 
        char * const newstack = STACK_GROW(vm->vm_minsaddr, epp->ep_ssize);
 
@@ -1463,10 +1423,6 @@
        error = (*epp->ep_esch->es_copyargs)(l, epp,
            &data->ed_arginfo, &newargs, data->ed_argp);
 
-       if (epp->ep_path) {
-               PNBUF_PUT(epp->ep_path);
-               epp->ep_path = NULL;
-       }
        if (error) {
                DPRINTF(("%s: copyargs failed %d\n", __func__, error));
                return error;
@@ -2258,7 +2214,7 @@
                struct posix_spawn_file_actions_entry *fae = &fa->fae[i];
                if (fae->fae_action != FAE_OPEN)
                        continue;
-               kmem_free(fae->fae_path, strlen(fae->fae_path) + 1);
+               kmem_strfree(fae->fae_path);
        }
        if (fa->len > 0)
                kmem_free(fa->fae, sizeof(*fa->fae) * fa->len);
diff -r c502ad28a381 -r ee5032074427 sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c      Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/kern/kern_exit.c      Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exit.c,v 1.269 2017/08/28 00:46:07 kamil Exp $    */
+/*     $NetBSD: kern_exit.c,v 1.270 2017/11/07 19:44:04 christos Exp $ */
 
 /*-
  * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.269 2017/08/28 00:46:07 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.270 2017/11/07 19:44:04 christos Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_dtrace.h"
@@ -1250,6 +1250,7 @@
         */
        if (p->p_textvp)
                vrele(p->p_textvp);
+       kmem_strfree(p->p_path);
 
        mutex_destroy(&p->p_auxlock);
        mutex_obj_free(p->p_lock);
diff -r c502ad28a381 -r ee5032074427 sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c      Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/kern/kern_fork.c      Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_fork.c,v 1.202 2017/04/21 15:10:34 christos Exp $ */
+/*     $NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $ */
 
 /*-
  * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.202 2017/04/21 15:10:34 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_dtrace.h"
@@ -346,6 +346,10 @@
        p2->p_textvp = p1->p_textvp;
        if (p2->p_textvp)
                vref(p2->p_textvp);
+       if (p1->p_path)
+               p2->p_path = kmem_strdupsize(p1->p_path, NULL, KM_SLEEP);
+       else
+               p2->p_path = NULL;
 
        if (flags & FORK_SHAREFILES)
                fd_share(p2);
diff -r c502ad28a381 -r ee5032074427 sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c      Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/kern/kern_proc.c      Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_proc.c,v 1.207 2017/08/28 00:46:07 kamil Exp $    */
+/*     $NetBSD: kern_proc.c,v 1.208 2017/11/07 19:44:04 christos Exp $ */
 
 /*-
  * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.207 2017/08/28 00:46:07 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.208 2017/11/07 19:44:04 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_kstack.h"
@@ -2433,41 +2433,28 @@
 static int
 fill_pathname(struct lwp *l, pid_t pid, void *oldp, size_t *oldlenp)
 {
-#ifndef _RUMPKERNEL
        int error;
        struct proc *p;
-       char *path;
-       size_t len;
 
        if ((error = proc_find_locked(l, &p, pid)) != 0)
                return error;
 
-       if (p->p_textvp == NULL) {
+       if (p->p_path == NULL) {
                if (pid != -1)
                        mutex_exit(p->p_lock);
                return ENOENT;
        }
 
-       path = PNBUF_GET();
-       error = vnode_to_path(path, MAXPATHLEN / 2, p->p_textvp, l, p);
-       if (error)
-               goto out;
-
-       len = strlen(path) + 1;
+       size_t len = strlen(p->p_path) + 1;
        if (oldp != NULL) {
-               error = sysctl_copyout(l, path, oldp, *oldlenp);
+               error = sysctl_copyout(l, p->p_path, oldp, *oldlenp);
                if (error == 0 && *oldlenp < len)
                        error = ENOSPC;
        }
        *oldlenp = len;
-out:
-       PNBUF_PUT(path);
        if (pid != -1)
                mutex_exit(p->p_lock);
        return error;
-#else
-       return 0;
-#endif
 }
 
 int
diff -r c502ad28a381 -r ee5032074427 sys/sys/exec.h
--- a/sys/sys/exec.h    Tue Nov 07 18:37:00 2017 +0000
+++ b/sys/sys/exec.h    Tue Nov 07 19:44:04 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec.h,v 1.151 2016/08/06 15:13:14 maxv Exp $  */
+/*     $NetBSD: exec.h,v 1.152 2017/11/07 19:44:05 christos Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -215,7 +215,6 @@
        struct vnode *ep_emul_root;     /* base of emulation filesystem */
        struct vnode *ep_interp;        /* vnode of (elf) interpeter */
        uint32_t ep_pax_flags;          /* pax flags */
-       char    *ep_path;               /* absolute path of executable */
        void    (*ep_emul_arg_free)(void *);
                                        /* free ep_emul_arg */
        uint32_t ep_osversion;          /* OS version */
diff -r c502ad28a381 -r ee5032074427 sys/sys/param.h
--- a/sys/sys/param.h   Tue Nov 07 18:37:00 2017 +0000



Home | Main Index | Thread Index | Old Index