diff options
author | phk <phk@FreeBSD.org> | 1999-11-16 20:31:58 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-11-16 20:31:58 +0000 |
commit | cc6b664e2eb821b39837e7bb980e5ee87e201491 (patch) | |
tree | 65eeb4add32e588f36f28e2a0bb819c17a67ff70 /sys/kern/kern_proc.c | |
parent | 47e5f46c7642e6d8e2ed20c8afca59596d3c2dc1 (diff) | |
download | FreeBSD-src-cc6b664e2eb821b39837e7bb980e5ee87e201491.zip FreeBSD-src-cc6b664e2eb821b39837e7bb980e5ee87e201491.tar.gz |
Introduce commandline caching in the kernel.
This fixes some nasty procfs problems for SMP, makes ps(1) run much faster,
and makes ps(1) even less dependent on /proc which will aid chroot and
jails alike.
To disable this facility and revert to previous behaviour:
sysctl -w kern.ps_arg_cache_limit=0
For full details see the current@FreeBSD.org mail-archives.
Diffstat (limited to 'sys/kern/kern_proc.c')
-rw-r--r-- | sys/kern/kern_proc.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index d420821..4c3ee1c 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -38,8 +38,8 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/sysctl.h> -#include <sys/proc.h> #include <sys/malloc.h> +#include <sys/proc.h> #include <sys/filedesc.h> #include <sys/tty.h> #include <sys/signalvar.h> @@ -609,6 +609,57 @@ sysctl_kern_proc SYSCTL_HANDLER_ARGS return (0); } +/* + * This sysctl allows a process to retrieve the argument list or process + * title for another process without groping around in the address space + * of the other process. It also allow a process to set its own "process + * title to a string of its own choice. + */ +static int +sysctl_kern_proc_args SYSCTL_HANDLER_ARGS +{ + int *name = (int*) arg1; + u_int namelen = arg2; + struct proc *p; + struct pargs *pa; + int error = 0; + + if (namelen != 1) + return (EINVAL); + + p = pfind((pid_t)name[0]); + if (!p) + return (0); + + if (!PRISON_CHECK(curproc, p)) + return (0); + + if (req->newptr && curproc != p) + return (EPERM); + + if (req->oldptr && p->p_args != NULL) + error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length); + if (req->newptr == NULL) + return (error); + + if (p->p_args && --p->p_args->ar_ref == 0) + FREE(p->p_args, M_PARGS); + p->p_args = NULL; + + if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit) + return (error); + + MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen, + M_PARGS, M_WAITOK); + pa->ar_ref = 1; + pa->ar_length = req->newlen; + error = SYSCTL_IN(req, pa->ar_args, req->newlen); + if (!error) + p->p_args = pa; + else + FREE(pa, M_PARGS); + return (error); +} SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); @@ -629,3 +680,6 @@ SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, sysctl_kern_proc, "Process table"); + +SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW, + sysctl_kern_proc_args, "Return process argument"); |