Subject: Re: core file name format: diffs
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 09/22/1999 18:23:12
--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Hi,
here is a new diff file, which include suggestions from der Mouse and fixes
for the problems he pointed out, and:
- honnor PL_SHAREMOD in p_sugid
- don't call limcopy() if no data change
- proc_sysctl(): always copyin(), don't use newp directly
- add support to /etc/rc, /etc/rc.conf and document it
- move description of the core file name format to core(5) and xref it from
other places
- a few more man pages update (shells, ...)
I all goes well my plan is to commit this friday.
--
Manuel Bouyer, LIP6, Universite Paris VI. Manuel.Bouyer@lip6.fr
--
--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sysctl.diff3"
Index: bin/csh/csh.1
===================================================================
RCS file: /cvsroot/basesrc/bin/csh/csh.1,v
retrieving revision 1.25
diff -u -r1.25 csh.1
--- csh.1 1999/07/30 01:08:12 1.25
+++ csh.1 1999/09/22 15:11:13
@@ -1408,6 +1408,10 @@
names and scale factors, unambiguous prefixes
of the names suffice.
.Pp
+Limits of an arbitrary process can be displayed or set using the
+.Xr sysctl(8)
+utility.
+.Pp
.It Ic login
Terminate a login shell, replacing it with an instance of
.Pa /usr/bin/login.
@@ -2133,6 +2137,7 @@
.Xr tty 4 ,
.Xr a.out 5 ,
.Xr environ 7 ,
+.Xr sysctl 8 ,
.br
.Em "An introduction to the C shell"
.Sh HISTORY
Index: bin/sh/sh.1
===================================================================
RCS file: /cvsroot/basesrc/bin/sh/sh.1,v
retrieving revision 1.30
diff -u -r1.30 sh.1
--- sh.1 1999/07/06 14:01:01 1.30
+++ sh.1 1999/09/22 15:11:23
@@ -1389,6 +1389,10 @@
or set. If value is specified, the limit is set to that number; otherwise
the current limit is displayed.
.Pp
+Limits of an arbitrary process can be displayed or set using the
+.Xr sysctl 8
+utility.
+.Pp
.It umask Op Ar mask
Set the value of umask (see
.Xr umask 2 )
@@ -1500,6 +1504,7 @@
.Xr passwd 4 ,
.Xr profile 4 ,
.Xr environ 5
+.Xr sysctl 8
.Sh HISTORY
A
.Nm
Index: etc/rc
===================================================================
RCS file: /cvsroot/basesrc/etc/rc,v
retrieving revision 1.131
diff -u -r1.131 rc
--- rc 1999/09/16 11:00:44 1.131
+++ rc 1999/09/22 15:11:24
@@ -316,6 +316,12 @@
. /etc/rc.lkm
fi
+# if $defcorename is set, change it here.
+if [ -n "$defcorename" ]; then
+ echo -n 'setting default core name template: '
+ sysctl -w kern.defcorename=$defcorename
+fi
+
# if $securelevel is set, change it here, else if it is 0, change
# it to 1 here, before we start login services.
if [ -n "$securelevel" ]; then
Index: etc/rc.conf
===================================================================
RCS file: /cvsroot/basesrc/etc/rc.conf,v
retrieving revision 1.57
diff -u -r1.57 rc.conf
--- rc.conf 1999/09/03 13:40:16 1.57
+++ rc.conf 1999/09/22 15:11:24
@@ -41,6 +41,11 @@
update_motd=YES # updates /etc/motd
dmesg=YES dmesg_flags="" # write /var/run/dmesg.boot
+# default core name template. If $defcorename is non-empty, this value will be
+# used for core dumps names for programs that didn't get their per-process
+# template set (see sysctl(3) and sysctl(8)).
+defcorename=""
+
# Security setting. If $securelevel is non-empty, the system securelevel
# is set to this value early in the boot sequence. Otherwise the default
# action is taken (see init(8)).
Index: lib/libc/gen/sysctl.3
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/gen/sysctl.3,v
retrieving revision 1.36
diff -u -r1.36 sysctl.3
--- sysctl.3 1999/06/24 14:18:10 1.36
+++ sysctl.3 1999/09/22 15:11:56
@@ -127,6 +127,7 @@
.It CTL\_KERN sys/sysctl.h High kernel limits
.It CTL\_MACHDEP sys/sysctl.h Machine dependent
.It CTL\_NET sys/socket.h Networking
+.It CTL\_PROC sys/sysctl.h Per-process
.It CTL\_USER sys/sysctl.h User-level
.It CTL\_VM vm/vm_param.h Virtual memory
.El
@@ -255,6 +256,7 @@
.It KERN\_BOOTTIME struct timeval no
.It KERN\_CHOWN\_RESTRICTED integer no
.It KERN\_CLOCKRATE struct clockinfo no
+.It KERN\_DEFCORENAME string yes
.It KERN\_DOMAINNAME string yes
.It KERN\_FILE struct file no
.It KERN\_FSYNC integer no
@@ -288,7 +290,6 @@
.It KERN\_RAWPARTITION integer no
.It KERN\_SAVED\_IDS integer no
.It KERN\_SECURELVL integer raise only
-.It KERN\_SHORTCORENAME integer yes
.It KERN\_SYNCHRONIZED\_IO integer no
.It KERN\_SYSVMSG integer no
.It KERN\_SYSVSEM integer no
@@ -326,6 +327,17 @@
This structure contains the clock, statistics clock and profiling clock
frequencies, the number of micro-seconds per hz tick, and the clock
skew rate.
+.It Li KERN_DEFCORENAME
+Default template for the name of core dump files (see also PROC_PID_CORENAME
+in the per-process variables CTL_PROC, and
+.Xr core 5
+for format of this template). The default value is
+.Nm %n.core
+and can be changed with the kernel configuration option
+.Cd options DEFCORENAME
+(see
+.Xr options 4
+).
.It Li KERN_DOMAINNAME
Get or set the YP domain name.
.It Li KERN_FILE
@@ -466,17 +478,6 @@
The system security level.
This level may be raised by processes with appropriate privilege.
It may only be lowered by process 1.
-.It Li KERN_SHORTCORENAME
-Whether core dumps are named
-.Nm programname.core
-(default, value 0) or
-.Nm core
-(value 1).
-The default value can be changed to 1 with the kernel configuration option
-.Cd options SHORTCORENAME
-(see
-.Xr options 4 ,
-.Xr core 5 ).
.It Li KERN_SYNCHRONIZED_IO
Returns 1 if the POSIX 1003.1b Synchronized I/O Option is available
on this system,
@@ -717,6 +718,79 @@
Returns the default UDP receive buffer size.
.El
.El
+.Sh CTL_PROC
+The string and integer information available for the CTL_PROC
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+These values are per-process, and as such may change from one process
+to another. When a process is created, the default values are inherited from
+its parent. When a set-user-ID or set-group-ID binary is executed, the
+value of PROC_PID_CORENAME is reset to the system default value.
+The second level name is either the magic value PROC_CURPROC, which
+points to the current process, or the PID of the target process.
+.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" "yes" -offset indent
+.It Sy Pa Third level name Type Changeable
+.It PROC\_PID\_CORENAME string yes
+.It PROC\_PID\_LIMIT node not applicable
+.El
+.Bl -tag -width "123456"
+.Pp
+.It Li PROC_PID_CORENAME
+The template used for the core dump file name (see
+.Xr core 5
+for details). The base name must either be
+.Nm core
+or end with the suffix ``.core'' (the super-user may set arbitrary names). By
+default it points to KERN_DEFCORENAME.
+.It Li PROC_PID_LIMIT
+Return resources limits, as defined for the
+.Xr getrlimit 2
+and
+.Xr setrlimit 2
+system calls.
+The fourth level name is one of:
+.Bl -tag -width PROC_PID_LIMIT_MEMLOCKAA
+.It Li PROC_PID_LIMIT_CPU
+The maximum amount of cpu time (in seconds) to be used by each process.
+.It Li PROC_PID_LIMIT_FSIZE
+The largest size (in bytes) file that may be created.
+.It Li PROC_PID_LIMIT_DATA
+The maximum size (in bytes) of the data segment for a process;
+this defines how far a program may extend its break with the
+.Xr sbrk 2
+system call.
+.It Li PROC_PID_LIMIT_STACK
+The maximum size (in bytes) of the stack segment for a process;
+this defines how far a program's stack segment may be extended.
+Stack extension is performed automatically by the system.
+.It Li PROC_PID_LIMIT_CORE
+The largest size (in bytes)
+.Pa core
+file that may be created.
+.It Li PROC_PID_LIMIT_RSS
+The maximum size (in bytes) to which a process's resident set size may
+grow.
+This imposes a limit on the amount of physical memory to be given to
+a process; if memory is tight, the system will prefer to take memory
+from processes that are exceeding their declared resident set size.
+.It Li PROC_PID_LIMIT_MEMLOCK
+The maximum size (in bytes) which a process may lock into memory
+using the
+.Xr mlock 2
+function.
+.It Li PROC_PID_LIMIT_NPROC
+The maximum number of simultaneous processes for this user id.
+.It Li PROC_PID_LIMIT_NOFILE
+The maximum number of open files for this process.
+.El
+.Pp
+The fifth level name is one of PROC_PID_LIMIT_TYPE_SOFT or
+PROC_PID_LIMIT_TYPE_HARD, to select respectively the soft or hard limit.
+Both are of type integer.
+.El
+.Pp
+
.Sh CTL_USER
The string and integer information available for the CTL_USER level
is detailed below.
Index: lib/libc/sys/getrlimit.2
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/sys/getrlimit.2,v
retrieving revision 1.13
diff -u -r1.13 getrlimit.2
--- getrlimit.2 1999/03/22 19:45:04 1.13
+++ getrlimit.2 1999/09/22 15:11:57
@@ -54,7 +54,9 @@
.Fn getrlimit
call, and set with the
.Fn setrlimit
-call.
+call. Resources of an arbitrary process can be obtained/changed using
+.Xr sysctl 3 .
+..
.Pp
The
.Fa resource
Index: sbin/init/init.8
===================================================================
RCS file: /cvsroot/basesrc/sbin/init/init.8,v
retrieving revision 1.18
diff -u -r1.18 init.8
--- init.8 1998/11/14 07:47:36 1.18
+++ init.8 1999/09/22 15:12:00
@@ -116,6 +116,9 @@
.Xr ipf 8
(the in-kernel IP filtering facility) may not be changed.
+Users may not change the per-process core name template format, only the
+default can be changed.
+
Downgrading from highly secure mode to insecure mode (that is, to single-user
mode) always requires the root password to be entered on the console, whether
the console is marked as 'secure' in
Index: share/man/man4/options.4
===================================================================
RCS file: /cvsroot/sharesrc/share/man/man4/options.4,v
retrieving revision 1.86
diff -u -r1.86 options.4
--- options.4 1999/08/05 15:47:07 1.86
+++ options.4 1999/09/22 15:12:15
@@ -837,18 +837,16 @@
.Em CHILD_MAX
is not permitted, as this would result in a violation of the semantics of
.St -p1003.1-90 .
-.It Cd options SHORTCORENAME
-If set, process core dumps are named
-.Nm core .
-If not specified, they are named
-.Nm programname.core
-(the default in 4.4BSD). Note that this changes the value of the
-.Em kern.shortcorename
-sysctl variable which may be changed at run time. See
+.It Cd options DEFCORENAME=string
+Sets the default value of the
+.Em kern.defcorename
+sysctl variable, otherwise it is set to
+.Nm %n.core .
+See
.Xr sysctl 8
and
.Xr sysctl 3
-for details.
+for details.
.El
.Ss Networking Options
.Bl -ohang
Index: share/man/man5/core.5
===================================================================
RCS file: /cvsroot/sharesrc/share/man/man5/core.5,v
retrieving revision 1.8
diff -u -r1.8 core.5
--- core.5 1999/03/17 20:19:44 1.8
+++ core.5 1999/09/22 15:12:15
@@ -47,33 +47,49 @@
to disk for later examination by one of the available debuggers.
(See
.Xr sigaction 2 . )
-This memory image is written to a file
-in the working directory;
-provided the terminated process had write permission in the directory,
-and provided the abnormality did not cause
-a system crash.
+This memory image is written to a file named from a per-process template;
+provided the terminated process had write permission, and provided the
+abnormality did not cause a system crash.
(In this event, the decision to save the core file is arbitrary, see
.Xr savecore 8 . )
-The file is normally named
-.Nm programname.core ,
-but is called
-.Nm core
-if the
-kernel configuration option
-.Cd options SHORTCORENAME
-is defined or the sysctl variable
-.Em kern.shortcorename
-is set to 1.
+The file is named from a per-process template, mapped to the sysctl
+variable
+.Em proc.<pid>.corename
+(where <pid> has to be remplaced by the pid in decimal format of the
+process).
+This template is either an absolute or relative path name, in which format
+characters can be used, preceeded by the percent character (``%'').
+The following characters are recognised as format and subsitued:
+.Bl -column "cAA" "The process's creation date (in seconds)xxx" -offset indent
+.It Li n The process's name
+.It Li p The PID of the process (in decimal)
+.It Li t The process's creation date (a la
+.Xr time 3 ,
+in decimal)
+.It Li u The login name, as returned by
+.Xr getlogin 2
+.El
+.Pp
+By default, the per-process template string points to the default core name
+template, which is mapped to the sysctl variable
+.Em kern.defcorename .
+Changing this value on a live system will change the core name template for
+all processes which didn't have a per-process template set.
+The default value of the default core name template is
+.Nm %n.core
+and can be changed at compile-time with the kernel configuration option
+.Cd options DEFCORENAME
+(see
+.Xr options 4 )
+.Pp
+The per-process template string is inherited on process creation, but is reset
+to point to the default core name template on execution of a set-id binary.
.Pp
-The maximum size of a
-.Nm programname.core
-file is limited by
+The maximum size of a core file is limited by
.Xr setrlimit 2 .
Files which would be larger than the limit are not created.
.Pp
-The
-.Nm programname.core
-file consists of the
+The core file consists of the
.Fa u. area ,
whose size (in pages) is defined by the
.Dv UPAGES
@@ -85,13 +101,9 @@
.Fa user
structure as given in
.Aq Pa sys/user.h .
-The remainder of the
-.Nm programname.core
-file consists of the data pages followed by
+The remainder of the core file consists of the data pages followed by
the stack pages of the process image.
-The amount of data space image in the
-.Nm programname.core
-file is given (in pages) by the
+The amount of data space image in the core file is given (in pages) by the
variable
.Fa u_dsize
in the
@@ -109,6 +121,8 @@
.Xr gdb 1 ,
.Xr sigaction 2 ,
.Xr setrlimit 2
+.Xr sysctl 3 ,
+.Xr sysctl 8
.Sh HISTORY
A
.Nm core
Index: share/man/man5/rc.conf.5
===================================================================
RCS file: /cvsroot/sharesrc/share/man/man5/rc.conf.5,v
retrieving revision 1.25
diff -u -r1.25 rc.conf.5
--- rc.conf.5 1999/09/03 14:36:43 1.25
+++ rc.conf.5 1999/09/22 15:12:16
@@ -170,6 +170,17 @@
file to reflect the version of the running kernel.
See
.Xr motd 5 .
+.It Sy defcorename
+A string.
+This sets the default core name template, from which are derived core dump
+files names. The template can include format charaters which are dynamically
+interpreted. See
+.Xr core 5
+for details of the format.
+If set to nothing, the default compiled-in value is keept (see
+.Xr options 4 ,
+.Xr sysctl 3
+).
.El
.Pp
.Ss System security setting:
Index: sys/compat/common/kern_resource_43.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/common/kern_resource_43.c,v
retrieving revision 1.5
diff -u -r1.5 kern_resource_43.c
--- kern_resource_43.c 1997/10/15 17:03:52 1.5
+++ kern_resource_43.c 1999/09/22 15:12:29
@@ -101,5 +101,5 @@
return (error);
lim.rlim_cur = olim.rlim_cur;
lim.rlim_max = olim.rlim_max;
- return (dosetrlimit(p, which, &lim));
+ return (dosetrlimit(p, p->p_cred, which, &lim));
}
Index: sys/compat/netbsd32/netbsd32_netbsd.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.17
diff -u -r1.17 netbsd32_netbsd.c
--- netbsd32_netbsd.c 1999/08/05 18:08:15 1.17
+++ netbsd32_netbsd.c 1999/09/22 15:12:30
@@ -3591,7 +3591,7 @@
error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
if (error)
return (error);
- return (dosetrlimit(p, which, &alim));
+ return (dosetrlimit(p, p->p_cred, which, &alim));
}
int
Index: sys/compat/svr4/svr4_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4/svr4_resource.c,v
retrieving revision 1.4
diff -u -r1.4 svr4_resource.c
--- svr4_resource.c 1999/09/07 18:20:19 1.4
+++ svr4_resource.c 1999/09/22 15:12:31
@@ -185,7 +185,7 @@
else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
blim.rlim_cur = limp->rlim_cur;
- return dosetrlimit(p, rl, &blim);
+ return dosetrlimit(p, p->p_cred, rl, &blim);
}
@@ -283,5 +283,5 @@
else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
blim.rlim_cur = limp->rlim_cur;
- return dosetrlimit(p, rl, &blim);
+ return dosetrlimit(p, p->p_cred, rl, &blim);
}
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/files,v
retrieving revision 1.316
diff -u -r1.316 files
--- files 1999/09/19 21:48:09 1.316
+++ files 1999/09/22 15:12:31
@@ -9,7 +9,7 @@
defopt KTRACE
defopt LOCKDEBUG
defopt RTC_OFFSET
-defopt SHORTCORENAME
+defopt DEFCORENAME
defopt UCONSOLE
defopt MULTIPROCESSOR
Index: sys/kern/init_main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/init_main.c,v
retrieving revision 1.156
diff -u -r1.156 init_main.c
--- init_main.c 1999/09/17 20:11:56 1.156
+++ init_main.c 1999/09/22 15:12:32
@@ -182,6 +182,7 @@
#if defined(NFSSERVER) || defined(NFS)
extern void nfs_init __P((void));
#endif
+ extern char defcorename[];
/*
* Initialize the current process pointer (curproc) before
@@ -286,6 +287,7 @@
limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
+ limit0.pl_corename = defcorename;
limit0.p_refcnt = 1;
/*
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.102
diff -u -r1.102 kern_exec.c
--- kern_exec.c 1999/08/09 02:42:20 1.102
+++ kern_exec.c 1999/09/22 15:12:32
@@ -457,7 +457,7 @@
p->p_ucred->cr_uid = attr.va_uid;
if (attr.va_mode & S_ISGID)
p->p_ucred->cr_gid = attr.va_gid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
} else
p->p_flag &= ~P_SUGID;
p->p_cred->p_svuid = p->p_ucred->cr_uid;
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_proc.c,v
retrieving revision 1.34
diff -u -r1.34 kern_proc.c
--- kern_proc.c 1999/07/25 06:30:34 1.34
+++ kern_proc.c 1999/09/22 15:12:32
@@ -519,6 +519,28 @@
}
}
+/* mark process as suid/sgid, reset some values do defaults */
+void
+p_sugid(p)
+ struct proc *p;
+{
+ extern char defcorename[];
+
+ p->p_flag |= P_SUGID;
+ /* reset what needs to be reset in plimit */
+ if (p->p_limit->pl_corename != defcorename) {
+ if (p->p_limit->p_refcnt > 1 &&
+ (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
+ p->p_limit->p_refcnt--;
+ p->p_limit = limcopy(p->p_limit);
+ } else {
+ free(p->p_limit->pl_corename, M_TEMP);
+ }
+ p->p_limit->pl_corename = defcorename;
+ }
+}
+
+
#ifdef DEBUG
void
pgrpdump()
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_prot.c,v
retrieving revision 1.54
diff -u -r1.54 kern_prot.c
--- kern_prot.c 1999/04/30 05:30:32 1.54
+++ kern_prot.c 1999/09/22 15:12:33
@@ -335,7 +335,7 @@
pc->pc_ucred->cr_uid = uid;
pc->p_ruid = uid;
pc->p_svuid = uid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -363,7 +363,7 @@
*/
pc->pc_ucred = crcopy(pc->pc_ucred);
pc->pc_ucred->cr_uid = euid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -408,7 +408,7 @@
}
if (euid != (uid_t)-1 && ruid != (uid_t)-1)
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -434,7 +434,7 @@
pc->pc_ucred->cr_gid = gid;
pc->p_rgid = gid;
pc->p_svgid = gid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -458,7 +458,7 @@
return (error);
pc->pc_ucred = crcopy(pc->pc_ucred);
pc->pc_ucred->cr_gid = egid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -501,7 +501,7 @@
}
if (egid != (gid_t)-1 && rgid != (gid_t)-1)
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -531,7 +531,7 @@
if (error)
return (error);
pc->pc_ucred->cr_ngroups = ngrp;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_resource.c,v
retrieving revision 1.52
diff -u -r1.52 kern_resource.c
--- kern_resource.c 1999/07/25 06:30:34 1.52
+++ kern_resource.c 1999/09/22 15:12:33
@@ -225,12 +225,13 @@
error = copyin(SCARG(uap, rlp), &alim, sizeof(struct rlimit));
if (error)
return (error);
- return (dosetrlimit(p, which, &alim));
+ return (dosetrlimit(p, p->p_cred, which, &alim));
}
int
-dosetrlimit(p, which, limp)
+dosetrlimit(p, cred, which, limp)
struct proc *p;
+ struct pcred *cred;
int which;
struct rlimit *limp;
{
@@ -245,9 +246,14 @@
return (EINVAL);
alimp = &p->p_rlimit[which];
+ /* if we don't change the value, no need to limcopy() */
+ if (limp->rlim_cur == alimp->rlim_cur &&
+ limp->rlim_max == alimp->rlim_max)
+ return 0;
+
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ if ((error = suser(cred->pc_ucred, &p->p_acflag)) != 0)
return (error);
if (limp->rlim_cur > limp->rlim_max)
limp->rlim_cur = limp->rlim_max;
@@ -454,10 +460,18 @@
struct plimit *lim;
{
register struct plimit *newlim;
+ extern char *defcorename;
newlim = pool_get(&plimit_pool, PR_WAITOK);
memcpy(newlim->pl_rlimit, lim->pl_rlimit,
sizeof(struct rlimit) * RLIM_NLIMITS);
+ if (lim->pl_corename == defcorename) {
+ newlim->pl_corename = lim->pl_corename;
+ } else {
+ newlim->pl_corename = malloc(strlen(lim->pl_corename)+1,
+ M_TEMP, M_WAITOK);
+ strcpy(newlim->pl_corename, lim->pl_corename);
+ }
newlim->p_lflags = 0;
newlim->p_refcnt = 1;
return (newlim);
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sig.c,v
retrieving revision 1.93
diff -u -r1.93 kern_sig.c
--- kern_sig.c 1999/08/31 12:30:35 1.93
+++ kern_sig.c 1999/09/22 15:12:34
@@ -79,6 +79,7 @@
void stop __P((struct proc *p));
void killproc __P((struct proc *, char *));
+static int build_corename __P((char *));
sigset_t contsigmask, stopsigmask, sigcantmask;
@@ -1264,9 +1265,8 @@
struct nameidata nd;
struct vattr vattr;
int error, error1;
- char name[MAXCOMLEN+6]; /* progname.core */
+ char name[MAXPATHLEN];
struct core core;
- extern int shortcorename;
/*
* Make sure the process has not set-id, to prevent data leaks.
@@ -1293,11 +1293,10 @@
(vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
return (EPERM);
- if (shortcorename)
- sprintf(name, "core");
- else
- sprintf(name, "%s.core", p->p_comm);
-
+ error = build_corename(name);
+ if (error)
+ return error;
+
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
if (error)
@@ -1393,4 +1392,52 @@
psignal(p, SIGSYS);
return (ENOSYS);
+}
+
+static int
+build_corename(dst)
+ char *dst;
+{
+ const char *s;
+ char *d;
+ int len, i;
+
+ for (s = curproc->p_limit->pl_corename, len = 0, d = dst;
+ *s != '\0'; s++) {
+ if (*s == '%') {
+ switch (*(s+1)) {
+ case 'n':
+ i = snprintf(d,MAXPATHLEN - 1 - len, "%s",
+ curproc->p_comm);
+ break;
+ case 'p':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%d",
+ curproc->p_pid);
+ break;
+ case 'u':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%s",
+ curproc->p_pgrp->pg_session->s_login);
+ break;
+ case 't':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%ld",
+ curproc->p_stats->p_start.tv_sec);
+ break;
+ default:
+ goto copy;
+ }
+ if (i >= MAXPATHLEN - 1 - len)
+ return ENAMETOOLONG;
+ len += i;
+ d += i;
+ s++;
+ } else {
+copy: *d = *s;
+ d++;
+ len++;
+ if (len >= MAXPATHLEN - 1)
+ return ENAMETOOLONG;
+ }
+ }
+ *d = '\0';
+ return 0;
}
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.50
diff -u -r1.50 kern_sysctl.c
--- kern_sysctl.c 1999/07/25 06:30:35 1.50
+++ kern_sysctl.c 1999/09/22 15:12:34
@@ -44,7 +44,7 @@
#include "opt_ddb.h"
#include "opt_insecure.h"
-#include "opt_shortcorename.h"
+#include "opt_defcorename.h"
#include "opt_sysv.h"
#include <sys/param.h>
@@ -68,6 +68,8 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
#if defined(DDB)
@@ -102,9 +104,6 @@
sysctlfn *fn;
int name[CTL_MAXNAME];
- if (SCARG(uap, new) != NULL &&
- (error = suser(p->p_ucred, &p->p_acflag)))
- return (error);
/*
* all top-level sysctl names are non-terminal
*/
@@ -115,6 +114,15 @@
if (error)
return (error);
+ /*
+ * For all but CTL_PROC, must be root to change a value.
+ * For CTL_PROC, must be root, or owner of the proc (and not suid),
+ * this is checked in proc_sysctl() (once we know the targer proc).
+ */
+ if (SCARG(uap, new) != NULL && name[0] != CTL_PROC &&
+ (error = suser(p->p_ucred, &p->p_acflag)))
+ return error;
+
switch (name[0]) {
case CTL_KERN:
fn = kern_sysctl;
@@ -146,6 +154,9 @@
fn = ddb_sysctl;
break;
#endif
+ case CTL_PROC:
+ fn = proc_sysctl;
+ break;
default:
return (EOPNOTSUPP);
}
@@ -210,10 +221,12 @@
#else
int securelevel = 0;
#endif
-#ifdef SHORTCORENAME
-int shortcorename = 1;
+#ifdef DEFCORENAME
+char defcorename[MAXPATHLEN] = DEFCORENAME;
+int defcorenamelen = sizeof(DEFCORENAME);
#else
-int shortcorename = 0;
+char defcorename[MAXPATHLEN] = "%n.core";
+int defcorenamelen = sizeof("%n.core");
#endif
/*
@@ -232,7 +245,6 @@
int error, level, inthostid;
int old_autonicetime;
int old_vnodes;
- int old_shortcorename;
extern char ostype[], osrelease[], version[];
/* All sysctl names at this level, except for a few, are terminal. */
@@ -304,7 +316,7 @@
case KERN_VNODE:
return (sysctl_vnode(oldp, oldlenp, p));
case KERN_PROC:
- return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
+ return (sysctl_doeproc(name + 1, namelen - 1, oldp, oldlenp));
case KERN_FILE:
return (sysctl_file(oldp, oldlenp));
#ifdef GPROF
@@ -380,16 +392,14 @@
#else
return (sysctl_rdint(oldp, oldlenp, newp, 0));
#endif
- case KERN_SHORTCORENAME:
- /* Only allow values of zero or one. */
- old_shortcorename = shortcorename;
- error = sysctl_int(oldp, oldlenp, newp, newlen,
- &shortcorename);
- if (shortcorename != 0 && shortcorename != 1) {
- shortcorename = old_shortcorename;
- return (EINVAL);
- }
- return (error);
+ case KERN_DEFCORENAME:
+ if (newp && newlen < 1)
+ return (EINVAL);
+ error = sysctl_string(oldp, oldlenp, newp, newlen,
+ defcorename, sizeof(defcorename));
+ if (newp && !error)
+ defcorenamelen = newlen;
+ return (error);
case KERN_SYNCHRONIZED_IO:
return (sysctl_rdint(oldp, oldlenp, newp, 1));
case KERN_IOV_MAX:
@@ -498,6 +508,150 @@
}
#endif /* DEBUG */
+int
+proc_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ struct proc *ptmp;
+ const struct proclist_desc *pd;
+ int error = 0;
+ struct rlimit alim;
+ char *tmps = NULL;
+ int i, curlen, len;
+
+ if (namelen < 2)
+ return EINVAL;
+
+ if (name[0] == PROC_CURPROC) {
+ ptmp = p;
+ } else {
+ proclist_lock_read();
+ for (pd = proclists; pd->pd_list != NULL; pd++) {
+ for (ptmp = LIST_FIRST(pd->pd_list); ptmp != NULL;
+ ptmp = LIST_NEXT(ptmp, p_list)) {
+ /* Skip embryonic processes. */
+ if (ptmp->p_stat == SIDL)
+ continue;
+ if (ptmp->p_pid == (pid_t)name[0])
+ break;
+ }
+ if (ptmp != NULL)
+ break;
+ }
+ proclist_unlock_read();
+ if (ptmp == NULL)
+ return(ESRCH);
+ if (p->p_ucred->cr_uid != 0) {
+ if(p->p_cred->p_ruid != ptmp->p_cred->p_ruid ||
+ p->p_cred->p_ruid != ptmp->p_cred->p_svuid)
+ return EPERM;
+ if (ptmp->p_cred->p_rgid != ptmp->p_cred->p_svgid)
+ return EPERM; /* sgid proc */
+ for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
+ if (p->p_ucred->cr_groups[i] ==
+ ptmp->p_cred->p_rgid)
+ break;
+ }
+ if (i == p->p_ucred->cr_ngroups)
+ return EPERM;
+ }
+ }
+ if (name[1] == PROC_PID_CORENAME) {
+ if (namelen != 2)
+ return EINVAL;
+ /*
+ * Can't use sysctl_string() here because we may malloc a new
+ * area during the process, so we have to do it by hand.
+ */
+ curlen = strlen(ptmp->p_limit->pl_corename) + 1;
+ if (oldp && *oldlenp < curlen)
+ return (ENOMEM);
+ if (newp) {
+ if (securelevel > 2)
+ return EPERM;
+ if (newlen > MAXPATHLEN)
+ return ENAMETOOLONG;
+ tmps = malloc(newlen + 1, M_TEMP, M_WAITOK);
+ if (tmps == NULL)
+ return ENOMEM;
+ error = copyin(newp, tmps, newlen + 1);
+ tmps[newlen] = '\0';
+ if (error)
+ goto cleanup;
+ /* Enforce to be either 'core' for end with '.core' */
+ if (newlen < 4) { /* c.o.r.e */
+ error = EINVAL;
+ goto cleanup;
+ }
+ len = newlen - 4;
+ if (len > 0) {
+ if (tmps[len - 1] != '.' &&
+ tmps[len - 1] != '/') {
+ error = EINVAL;
+ goto cleanup;
+ }
+ }
+ if (strcmp(&tmps[len], "core") != 0) {
+ error = EINVAL;
+ goto cleanup;
+ }
+ }
+ if (oldp) {
+ *oldlenp = curlen;
+ error = copyout(ptmp->p_limit->pl_corename, oldp,
+ curlen);
+ }
+ if (newp && error == 0) {
+ /* if the 2 strings are identical, don't limcopy() */
+ if (strcmp(tmps, ptmp->p_limit->pl_corename) == 0) {
+ error = 0;
+ goto cleanup;
+ }
+ if (ptmp->p_limit->p_refcnt > 1 &&
+ (ptmp->p_limit->p_lflags & PL_SHAREMOD) == 0) {
+ ptmp->p_limit->p_refcnt--;
+ ptmp->p_limit = limcopy(ptmp->p_limit);
+ } else if (ptmp->p_limit->pl_corename != defcorename) {
+ free(ptmp->p_limit->pl_corename, M_TEMP);
+ }
+ ptmp->p_limit->pl_corename = tmps;
+ return (0);
+ }
+cleanup:
+ if (tmps)
+ free(tmps, M_TEMP);
+ return (error);
+ }
+ if (name[1] == PROC_PID_LIMIT) {
+ if (namelen != 4 || name[2] >= PROC_PID_LIMIT_MAXID)
+ return EINVAL;
+ memcpy(&alim, &ptmp->p_rlimit[name[2] - 1], sizeof(alim));
+ if (name[3] == PROC_PID_LIMIT_TYPE_HARD)
+ error = sysctl_quad(oldp, oldlenp, newp, newlen,
+ &alim.rlim_max);
+ else if (name[3] == PROC_PID_LIMIT_TYPE_SOFT)
+ error = sysctl_quad(oldp, oldlenp, newp, newlen,
+ &alim.rlim_cur);
+ else
+ error = EINVAL;
+
+ if (error)
+ return error;
+
+ if (newp)
+ error = dosetrlimit(ptmp, p->p_cred,
+ name[2] - 1, &alim);
+ return error;
+ }
+ return (EINVAL);
+}
+
/*
* Validate parameters and get old / set new parameters
* for an integer-valued sysctl function.
@@ -548,6 +702,55 @@
/*
* Validate parameters and get old / set new parameters
+ * for an quad-valued sysctl function.
+ */
+int
+sysctl_quad(oldp, oldlenp, newp, newlen, valp)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ quad_t *valp;
+{
+ int error = 0;
+
+ if (oldp && *oldlenp < sizeof(quad_t))
+ return (ENOMEM);
+ if (newp && newlen != sizeof(quad_t))
+ return (EINVAL);
+ *oldlenp = sizeof(quad_t);
+ if (oldp)
+ error = copyout(valp, oldp, sizeof(quad_t));
+ if (error == 0 && newp)
+ error = copyin(newp, valp, sizeof(quad_t));
+ return (error);
+}
+
+/*
+ * As above, but read-only.
+ */
+int
+sysctl_rdquad(oldp, oldlenp, newp, val)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ quad_t val;
+{
+ int error = 0;
+
+ if (oldp && *oldlenp < sizeof(quad_t))
+ return (ENOMEM);
+ if (newp)
+ return (EPERM);
+ *oldlenp = sizeof(quad_t);
+ if (oldp)
+ error = copyout((caddr_t)&val, oldp, sizeof(quad_t));
+ return (error);
+}
+
+
+/*
+ * Validate parameters and get old / set new parameters
* for a string-valued sysctl function.
*/
int
@@ -709,7 +912,7 @@
#define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
int
-sysctl_doproc(name, namelen, where, sizep)
+sysctl_doeproc(name, namelen, where, sizep)
int *name;
u_int namelen;
char *where;
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.83
diff -u -r1.83 proc.h
--- proc.h 1999/08/10 23:33:27 1.83
+++ proc.h 1999/09/22 15:12:54
@@ -392,5 +392,6 @@
void proclist_unlock_read __P((void));
int proclist_lock_write __P((void));
void proclist_unlock_write __P((int));
+void p_sugid __P((struct proc*));
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */
Index: sys/sys/resource.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resource.h,v
retrieving revision 1.19
diff -u -r1.19 resource.h
--- resource.h 1998/12/09 14:39:09 1.19
+++ resource.h 1999/09/22 15:12:54
@@ -120,7 +120,8 @@
#ifdef _KERNEL
extern struct loadavg averunnable;
-int dosetrlimit __P((struct proc *, int, struct rlimit *));
+struct pcred;
+int dosetrlimit __P((struct proc *, struct pcred *, int, struct rlimit *));
int donice __P((struct proc *, struct proc *, int));
#else
Index: sys/sys/resourcevar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resourcevar.h,v
retrieving revision 1.13
diff -u -r1.13 resourcevar.h
--- resourcevar.h 1998/03/01 02:24:14 1.13
+++ resourcevar.h 1999/09/22 15:12:54
@@ -73,6 +73,7 @@
*/
struct plimit {
struct rlimit pl_rlimit[RLIM_NLIMITS];
+ char *pl_corename;
#define PL_SHAREMOD 0x01 /* modifications are shared */
int p_lflags;
int p_refcnt; /* number of references */
@@ -88,8 +89,7 @@
void addupc_task __P((struct proc *p, u_long pc, u_int ticks));
void calcru __P((struct proc *p, struct timeval *up, struct timeval *sp,
struct timeval *ip));
-struct plimit
- *limcopy __P((struct plimit *lim));
+struct plimit *limcopy __P((struct plimit *lim));
void ruadd __P((struct rusage *ru, struct rusage *ru2));
#endif
#endif /* !_SYS_RESOURCEVAR_H_ */
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/sysctl.h,v
retrieving revision 1.35
diff -u -r1.35 sysctl.h
--- sysctl.h 1999/06/24 14:18:12 1.35
+++ sysctl.h 1999/09/22 15:12:55
@@ -92,7 +92,8 @@
#define CTL_MACHDEP 7 /* machine dependent */
#define CTL_USER 8 /* user-level */
#define CTL_DDB 9 /* in-kernel debugger */
-#define CTL_MAXID 10 /* number of valid top-level ids */
+#define CTL_PROC 10 /* per-proc attr */
+#define CTL_MAXID 11 /* number of valid top-level ids */
#define CTL_NAMES { \
{ 0, 0 }, \
@@ -105,6 +106,7 @@
{ "machdep", CTLTYPE_NODE }, \
{ "user", CTLTYPE_NODE }, \
{ "ddb", CTLTYPE_NODE }, \
+ { "proc", CTLTYPE_NODE }, \
}
/*
@@ -145,7 +147,7 @@
#define KERN_SYSVMSG 33 /* int: SysV message queue suppoprt */
#define KERN_SYSVSEM 34 /* int: SysV semaphore support */
#define KERN_SYSVSHM 35 /* int: SysV shared memory support */
-#define KERN_SHORTCORENAME 36 /* int: programs dump core as "core" */
+#define KERN_DEFCORENAME 36 /* string: default corename format */
#define KERN_SYNCHRONIZED_IO 37 /* int: POSIX synchronized I/O */
#define KERN_IOV_MAX 38 /* int: max iovec's for readv(2) etc. */
#define KERN_MBUF 39 /* node: mbuf parameters */
@@ -192,7 +194,7 @@
{ "sysvmsg", CTLTYPE_INT }, \
{ "sysvsem", CTLTYPE_INT }, \
{ "sysvshm", CTLTYPE_INT }, \
- { "shortcorename", CTLTYPE_INT }, \
+ { "defcorename", CTLTYPE_STRING }, \
{ "synchronized_io", CTLTYPE_INT }, \
{ "iov_max", CTLTYPE_INT }, \
{ "mbuf", CTLTYPE_NODE }, \
@@ -356,6 +358,61 @@
#define CTL_DEBUG_VALUE 1 /* int: variable value */
#define CTL_DEBUG_MAXID 20
+/*
+ * CTL_PROC subtype. Either a PID, or a magic value for the current proc.
+ */
+
+#define PROC_CURPROC (~((u_int)1 << 31))
+
+/*
+ * CTL_PROC tree: either corename (string), or a limit
+ * (rlimit.<type>.{hard,soft}, int).
+ */
+#define PROC_PID_CORENAME 1
+#define PROC_PID_LIMIT 2
+#define PROC_PID_MAXID 3
+
+#define PROC_PID_NAMES { \
+ { 0, 0 }, \
+ { "corename", CTLTYPE_STRING }, \
+ { "rlimit", CTLTYPE_NODE }, \
+}
+
+/* Limit types from <sys/resources.h> */
+#define PROC_PID_LIMIT_CPU (RLIMIT_CPU+1)
+#define PROC_PID_LIMIT_FSIZE (RLIMIT_FSIZE+1)
+#define PROC_PID_LIMIT_DATA (RLIMIT_DATA+1)
+#define PROC_PID_LIMIT_STACK (RLIMIT_STACK+1)
+#define PROC_PID_LIMIT_CORE (RLIMIT_CORE+1)
+#define PROC_PID_LIMIT_RSS (RLIMIT_RSS+1)
+#define PROC_PID_LIMIT_MEMLOCK (RLIMIT_MEMLOCK+1)
+#define PROC_PID_LIMIT_NPROC (RLIMIT_NPROC+1)
+#define PROC_PID_LIMIT_NOFILE (RLIMIT_NOFILE+1)
+#define PROC_PID_LIMIT_MAXID 10
+
+#define PROC_PID_LIMIT_NAMES { \
+ { 0, 0 }, \
+ { "cputime", CTLTYPE_NODE }, \
+ { "filesize", CTLTYPE_NODE }, \
+ { "datasize", CTLTYPE_NODE }, \
+ { "stacksize", CTLTYPE_NODE }, \
+ { "coredumpsize", CTLTYPE_NODE }, \
+ { "memoryuse", CTLTYPE_NODE }, \
+ { "memorylocked", CTLTYPE_NODE }, \
+ { "maxproc", CTLTYPE_NODE }, \
+ { "descriptors", CTLTYPE_NODE }, \
+}
+/* for each type, either hard or soft value */
+#define PROC_PID_LIMIT_TYPE_SOFT 1
+#define PROC_PID_LIMIT_TYPE_HARD 2
+#define PROC_PID_LIMIT_TYPE_MAXID 3
+
+#define PROC_PID_LIMIT_TYPE_NAMES { \
+ {0, 0}, \
+ { "soft", CTLTYPE_QUAD }, \
+ { "hard", CTLTYPE_QUAD }, \
+}
+
#ifdef _KERNEL
/*
* CTL_DEBUG variables.
@@ -394,12 +451,14 @@
int sysctl_int __P((void *, size_t *, void *, size_t, int *));
int sysctl_rdint __P((void *, size_t *, void *, int));
+int sysctl_quad __P((void *, size_t *, void *, size_t, quad_t *));
+int sysctl_rdquad __P((void *, size_t *, void *, quad_t));
int sysctl_string __P((void *, size_t *, void *, size_t, char *, int));
int sysctl_rdstring __P((void *, size_t *, void *, char *));
int sysctl_rdstruct __P((void *, size_t *, void *, void *, int));
int sysctl_struct __P((void *, size_t *, void *, size_t, void *, int));
int sysctl_file __P((char *, size_t *));
-int sysctl_doproc __P((int *, u_int, char *, size_t *));
+int sysctl_doeproc __P((int *, u_int, char *, size_t *));
struct radix_node;
struct walkarg;
int sysctl_dumpentry __P((struct radix_node *, void *));
@@ -421,6 +480,8 @@
struct proc *));
int hw_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
+int proc_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
+ struct proc *));
#ifdef DEBUG
int debug_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
Index: usr.sbin/sysctl/sysctl.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/sysctl/sysctl.8,v
retrieving revision 1.30
diff -u -r1.30 sysctl.8
--- sysctl.8 1999/07/02 08:58:22 1.30
+++ sysctl.8 1999/09/22 15:13:03
@@ -86,6 +86,13 @@
flag must be specified and the MIB name followed
by an equal sign and the new value to be used.
.Pp
+The proc top-level MIB has a special semantic: it represent per-process values
+and as such may differ from one process to another. The second-level name
+is the pid of the process (in decimal form), or the special word 'curproc'.
+For variables below 'proc.<pid>.rlimit', the integer value may be remplaced
+with the string 'unlimited' if it matches the magic value used to disable
+a limit.
+.Pp
The information available from
.Nm sysctl
consists of integers, strings, and tables.
@@ -137,7 +144,7 @@
.It kern.sysvmsg integer no
.It kern.sysvsem integer no
.It kern.sysvshm integer no
-.It kern.shortcorename integer yes
+.It kern.defcorename string yes
.It kern.synchronized_io integer no
.It kern.iov_max integer no
.It kern.mbuf.msize integer no
@@ -281,6 +288,23 @@
.It ddb.tabstops integer yes
.It ddb.lines integer yes
.It ddb.onpanic integer yes
+.It proc.<pid>.corename string yes
+.It proc.<pid>.rlimit.cputime.soft integer yes
+.It proc.<pid>.rlimit.cputime.hard integer yes
+.It proc.<pid>.rlimit.filesize.soft integer yes
+.It proc.<pid>.rlimit.filesize.hard integer yes
+.It proc.<pid>.rlimit.datasize.soft integer yes
+.It proc.<pid>.rlimit.datasize.hard integer yes
+.It proc.<pid>.rlimit.stacksize.soft integer yes
+.It proc.<pid>.rlimit.stacksize.hard integer yes
+.It proc.<pid>.rlimit.coredumpsize.soft integer yes
+.It proc.<pid>.rlimit.coredumpsize.hard integer yes
+.It proc.<pid>.rlimit.memoryuse.soft integer yes
+.It proc.<pid>.rlimit.memoryuse.hard integer yes
+.It proc.<pid>.rlimit.memorylocked.soft integer yes
+.It proc.<pid>.rlimit.memorylocked.hard integer yes
+.It proc.<pid>.rlimit.maxproc.soft integer yes
+.It proc.<pid>.rlimit.maxproc.hard integer yes
.El
.Sh EXAMPLES
.Pp
@@ -305,6 +329,26 @@
.Bd -literal -offset indent -compact
sysctl vm.loadavg
.Ed
+.Pp
+To view the values of the per-process variables of the current shell,
+the request:
+.Bd -literal -offset indent -compact
+sysctl proc.$$
+.Ed
+can be used if the shell interpreter remplaces $$ with it's pid (this is true
+for most shells).
+.Pp
+To redirect core dumps to the /var/tmp/<username> directory,
+.Bd -literal -offset indent -compact
+sysctl -w proc.$$.corename=/var/tmp/%u/%n.core
+.Ed
+Shall be used.
+.Bd -literal -offset indent -compact
+sysctl -w proc.curproc.corename=/var/tmp/%u/%n.core
+.Ed
+changes the value for the sysctl process itself, and will not have the desired
+effect.
+
.Sh FILES
.Bl -tag -width <netinet/icmpXvar.h> -compact
.It Pa <sys/sysctl.h>
Index: usr.sbin/sysctl/sysctl.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/sysctl/sysctl.c,v
retrieving revision 1.21
diff -u -r1.21 sysctl.c
--- sysctl.c 1999/07/30 10:29:35 1.21
+++ sysctl.c 1999/09/22 15:13:04
@@ -55,6 +55,7 @@
#include <sys/socket.h>
#include <sys/mount.h>
#include <sys/mbuf.h>
+#include <sys/resource.h>
#include <vm/vm_param.h>
#include <machine/cpu.h>
@@ -119,6 +120,9 @@
#ifdef CTL_MACHDEP_NAMES
struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
#endif
+/* this one is dummy, it's used only for '-a' or '-A' */
+struct ctlname procname[] = { {0, 0}, {"curproc", CTLTYPE_NODE} };
+
char names[BUFSIZ];
struct list {
@@ -141,6 +145,7 @@
#endif
{ username, USER_MAXID }, /* CTL_USER_NAMES */
{ ddbname, DDBCTL_MAXID }, /* CTL_DDB_NAMES */
+ { procname, 2 }, /* dummy name */
};
int Aflag, aflag, nflag, wflag;
@@ -152,6 +157,11 @@
#define BOOTTIME 0x00000002
#define CONSDEV 0x00000004
+/*
+ * A dummy type for limits, which requires special parsing
+ */
+#define CTLTYPE_LIMIT ((~0x1) << 31)
+
int main __P((int, char *[]));
static void listall __P((char *, struct list *));
@@ -167,6 +177,7 @@
static int sysctl_vfs __P((char *, char **, int[], int, int *));
static int sysctl_vfsgen __P((char *, char **, int[], int, int *));
static int sysctl_mbuf __P((char *, char **, int[], int, int *));
+static int sysctl_proc __P((char *, char **, int[], int, int *));
static int findname __P((char *, char *, char **, struct list *));
static void usage __P((void));
@@ -279,21 +290,26 @@
mib[0] = indx;
if (indx == CTL_DEBUG)
debuginit();
- lp = &secondlevel[indx];
- if (lp->list == 0) {
- warnx("Class `%s' is not implemented",
- topname[indx].ctl_name);
- return;
- }
- if (bufp == NULL) {
- listall(topname[indx].ctl_name, lp);
- return;
+ if (mib[0] == CTL_PROC) {
+ type = CTLTYPE_NODE;
+ len = 1;
+ } else {
+ lp = &secondlevel[indx];
+ if (lp->list == 0) {
+ warnx("Class `%s' is not implemented",
+ topname[indx].ctl_name);
+ return;
+ }
+ if (bufp == NULL) {
+ listall(topname[indx].ctl_name, lp);
+ return;
+ }
+ if ((indx = findname(string, "second", &bufp, lp)) == -1)
+ return;
+ mib[1] = indx;
+ type = lp->list[indx].ctl_type;
+ len = 2;
}
- if ((indx = findname(string, "second", &bufp, lp)) == -1)
- return;
- mib[1] = indx;
- type = lp->list[indx].ctl_type;
- len = 2;
switch (mib[0]) {
case CTL_KERN:
@@ -423,7 +439,11 @@
case CTL_USER:
case CTL_DDB:
break;
-
+ case CTL_PROC:
+ len = sysctl_proc(string, &bufp, mib, flags, &type);
+ if (len < 0)
+ return;
+ break;
default:
warnx("Illegal top level value: %d", mib[0]);
return;
@@ -441,6 +461,14 @@
newsize = sizeof intval;
break;
+ case CTLTYPE_LIMIT:
+ if (strcmp(newval, "unlimited") == 0) {
+ quadval = RLIM_INFINITY;
+ newval = &quadval;
+ newsize = sizeof quadval;
+ break;
+ }
+ /* FALLTHROUGH */
case CTLTYPE_QUAD:
sscanf(newval, "%qd", (long long *)&quadval);
newval = &quadval;
@@ -526,6 +554,30 @@
}
return;
+ case CTLTYPE_LIMIT:
+#define PRINTF_LIMIT(lim) { \
+if ((lim) == RLIM_INFINITY) \
+ fprintf(stdout, "unlimited");\
+else \
+ fprintf(stdout, "%qd", (lim)); \
+}
+
+ if (newsize == 0) {
+ if (!nflag)
+ fprintf(stdout, "%s = ", string);
+ PRINTF_LIMIT((long long)(*(quad_t *)buf));
+ } else {
+ if (!nflag) {
+ fprintf(stdout, "%s: ", string);
+ PRINTF_LIMIT((long long)(*(quad_t *)buf));
+ fprintf(stdout, " -> ");
+ }
+ PRINTF_LIMIT((long long)(*(quad_t *)newval));
+ }
+ fprintf(stdout, "\n");
+ return;
+#undef PRINTF_LIMIT
+
case CTLTYPE_QUAD:
if (newsize == 0) {
if (!nflag)
@@ -897,9 +949,85 @@
return (3);
}
+struct ctlname procnames[] = PROC_PID_NAMES;
+struct list procvars = {procnames, PROC_PID_MAXID};
+struct ctlname proclimitnames[] = PROC_PID_LIMIT_NAMES;
+struct list proclimitvars = {proclimitnames, PROC_PID_LIMIT_MAXID};
+struct ctlname proclimittypenames[] = PROC_PID_LIMIT_TYPE_NAMES;
+struct list proclimittypevars = {proclimittypenames,
+ PROC_PID_LIMIT_TYPE_MAXID};
+/*
+ * handle kern.proc requests
+ */
+static int
+sysctl_proc(string, bufpp, mib, flags, typep)
+ char *string;
+ char **bufpp;
+ int mib[];
+ int flags;
+ int *typep;
+{
+ char *cp, name[BUFSIZ];
+ struct list *lp;
+ int indx;
+
+ if (*bufpp == NULL) {
+ strcpy(name, string);
+ cp = &name[strlen(name)];
+ *cp++ = '.';
+ strcpy(cp, "curproc");
+ parse (name, Aflag);
+ return (-1);
+ }
+ cp = strsep(bufpp, ".");
+ if (cp == NULL) {
+ warnx("%s: incomplete specification", string);
+ return (-1);
+ }
+ if (strcmp(cp, "curproc") == 0) {
+ mib[1] = PROC_CURPROC;
+ } else {
+ mib[1] = atoi(cp);
+ if (mib[1] == 0) {
+ warnx("second level name %s in %s is invalid", cp,
+ string);
+ return (-1);
+ }
+ }
+ *typep = CTLTYPE_NODE;
+ lp = &procvars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "third", bufpp, lp)) == -1)
+ return (-1);
+ mib[2] = indx;
+ *typep = lp->list[indx].ctl_type;
+ if (*typep != CTLTYPE_NODE)
+ return(3);
+ lp = &proclimitvars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
+ return (-1);
+ mib[3] = indx;
+ lp = &proclimittypevars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "fifth", bufpp, lp)) == -1)
+ return (-1);
+ mib[4] = indx;
+ *typep = CTLTYPE_LIMIT;
+ return(5);
+}
+
struct ctlname mbufnames[] = CTL_MBUF_NAMES;
struct list mbufvars = { mbufnames, MBUF_MAXID };
-
/*
* handle kern.mbuf requests
*/
--bp/iNruPH9dso1Pn--