Module Name:    src
Committed By:   christos
Date:           Tue Nov  7 19:44:05 UTC 2017

Modified Files:
        src/sys/kern: exec_elf.c kern_exec.c kern_exit.c kern_fork.c
            kern_proc.c
        src/sys/sys: exec.h param.h proc.h

Log Message:
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?


To generate a diff of this commit:
cvs rdiff -u -r1.92 -r1.93 src/sys/kern/exec_elf.c
cvs rdiff -u -r1.449 -r1.450 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.269 -r1.270 src/sys/kern/kern_exit.c
cvs rdiff -u -r1.202 -r1.203 src/sys/kern/kern_fork.c
cvs rdiff -u -r1.207 -r1.208 src/sys/kern/kern_proc.c
cvs rdiff -u -r1.151 -r1.152 src/sys/sys/exec.h
cvs rdiff -u -r1.549 -r1.550 src/sys/sys/param.h
cvs rdiff -u -r1.342 -r1.343 src/sys/sys/proc.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/exec_elf.c
diff -u src/sys/kern/exec_elf.c:1.92 src/sys/kern/exec_elf.c:1.93
--- src/sys/kern/exec_elf.c:1.92	Sun Oct 15 21:50:55 2017
+++ src/sys/kern/exec_elf.c	Tue Nov  7 14:44:04 2017
@@ -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 @@ elf_copyargs(struct lwp *l, struct exec_
 		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 @@ elf_copyargs(struct lwp *l, struct exec_
 
 	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;

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.449 src/sys/kern/kern_exec.c:1.450
--- src/sys/kern/kern_exec.c:1.449	Fri Oct 20 15:06:46 2017
+++ src/sys/kern/kern_exec.c	Tue Nov  7 14:44:04 2017
@@ -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 @@ execve_free_data(struct execve_data *dat
 }
 
 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 @@ execve_runproc(struct lwp *l, struct exe
 	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 @@ copyoutargs(struct execve_data * restric
 	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 @@ posix_spawn_fa_free(struct posix_spawn_f
 		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);

Index: src/sys/kern/kern_exit.c
diff -u src/sys/kern/kern_exit.c:1.269 src/sys/kern/kern_exit.c:1.270
--- src/sys/kern/kern_exit.c:1.269	Sun Aug 27 20:46:07 2017
+++ src/sys/kern/kern_exit.c	Tue Nov  7 14:44:04 2017
@@ -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 @@ proc_free(struct proc *p, struct wrusage
 	 */
 	if (p->p_textvp)
 		vrele(p->p_textvp);
+	kmem_strfree(p->p_path);
 
 	mutex_destroy(&p->p_auxlock);
 	mutex_obj_free(p->p_lock);

Index: src/sys/kern/kern_fork.c
diff -u src/sys/kern/kern_fork.c:1.202 src/sys/kern/kern_fork.c:1.203
--- src/sys/kern/kern_fork.c:1.202	Fri Apr 21 11:10:34 2017
+++ src/sys/kern/kern_fork.c	Tue Nov  7 14:44:04 2017
@@ -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 @@ fork1(struct lwp *l1, int flags, int exi
 	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);

Index: src/sys/kern/kern_proc.c
diff -u src/sys/kern/kern_proc.c:1.207 src/sys/kern/kern_proc.c:1.208
--- src/sys/kern/kern_proc.c:1.207	Sun Aug 27 20:46:07 2017
+++ src/sys/kern/kern_proc.c	Tue Nov  7 14:44:04 2017
@@ -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 @@ proc_find_locked(struct lwp *l, struct p
 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

Index: src/sys/sys/exec.h
diff -u src/sys/sys/exec.h:1.151 src/sys/sys/exec.h:1.152
--- src/sys/sys/exec.h:1.151	Sat Aug  6 11:13:14 2016
+++ src/sys/sys/exec.h	Tue Nov  7 14:44:05 2017
@@ -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 exec_package {
 	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 */

Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.549 src/sys/sys/param.h:1.550
--- src/sys/sys/param.h:1.549	Mon Oct 23 07:21:56 2017
+++ src/sys/sys/param.h	Tue Nov  7 14:44:05 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.549 2017/10/23 11:21:56 martin Exp $	*/
+/*	$NetBSD: param.h,v 1.550 2017/11/07 19:44:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -67,7 +67,7 @@
  *	2.99.9		(299000900)
  */
 
-#define	__NetBSD_Version__	899000500	/* NetBSD 8.99.5 */
+#define	__NetBSD_Version__	899000600	/* NetBSD 8.99.6 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.342 src/sys/sys/proc.h:1.343
--- src/sys/sys/proc.h:1.342	Sun Aug 27 20:46:07 2017
+++ src/sys/sys/proc.h	Tue Nov  7 14:44:05 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: proc.h,v 1.342 2017/08/28 00:46:07 kamil Exp $	*/
+/*	$NetBSD: proc.h,v 1.343 2017/11/07 19:44:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -315,6 +315,7 @@ struct proc {
 	lwpid_t		p_lwp_created;	/* :: lwp created */
 	lwpid_t		p_lwp_exited;	/* :: lwp exited */
 	u_int		p_nsems;	/* Count of semaphores */
+	char		*p_path;	/* :: full pathname of executable */
 
 /*
  * End area that is zeroed on creation

Reply via email to