tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lwp resource limit
Hello,
This is a new resource limit to prevent users from exhausting kernel
resources that lwps use.
- The limit is per uid
- The default is 1024 per user unless the architecture overrides it
- The kernel is never prohibited from creating threads
- Exceeding the thread limit does not prevent process creation, but
it will prevent processes from creating additional threads. So the
effective thread limit is nlwp + nproc
- The name NTHR was chosen to follow prior art
- There could be atomicity issues for setuid and lwp exits
- This diff also adds a sysctl kern.uidinfo.* to show the user the uid
limits
comments?
christos
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.442
diff -u -p -u -r1.442 init_main.c
--- kern/init_main.c 19 Feb 2012 21:06:47 -0000 1.442
+++ kern/init_main.c 23 May 2012 23:19:31 -0000
@@ -256,6 +256,7 @@ int cold = 1; /* still working on star
struct timespec boottime; /* time at system startup - will only
follow settime deltas */
int start_init_exec; /* semaphore for start_init() */
+int maxlwp;
cprng_strong_t *kern_cprng;
@@ -291,6 +292,12 @@ main(void)
#endif
l->l_pflag |= LP_RUNNING;
+#ifdef __HAVE_CPU_MAXLWP
+ maxlwp = cpu_maxlwp();
+#else
+ maxlwp = 1024;
+#endif
+
/*
* Attempt to find console and initialize
* in case of early panic or other messages.
Index: kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 init_sysctl.c
--- kern/init_sysctl.c 7 Apr 2012 05:38:49 -0000 1.189
+++ kern/init_sysctl.c 23 May 2012 23:19:31 -0000
@@ -147,6 +147,7 @@ static int sysctl_kern_trigger_panic(SYS
static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
+static int sysctl_kern_maxlwp(SYSCTLFN_PROTO);
static int sysctl_kern_hostid(SYSCTLFN_PROTO);
static int sysctl_setlen(SYSCTLFN_PROTO);
static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
@@ -234,6 +235,12 @@ SYSCTL_SETUP(sysctl_kern_setup, "sysctl
CTL_KERN, KERN_MAXPROC, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_INT, "maxlwp",
+ SYSCTL_DESCR("Maximum number of simultaneous threads"),
+ sysctl_kern_maxlwp, 0, NULL, 0,
+ CTL_KERN, KERN_MAXLWP, CTL_EOL);
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "maxfiles",
SYSCTL_DESCR("Maximum number of open files"),
NULL, 0, &maxfiles, 0,
@@ -1050,6 +1057,33 @@ sysctl_kern_maxproc(SYSCTLFN_ARGS)
}
/*
+ * sysctl helper routine for kern.maxlwp. Ensures that the new
+ * values are not too low or too high.
+ */
+static int
+sysctl_kern_maxlwp(SYSCTLFN_ARGS)
+{
+ int error, nmaxlwp;
+ struct sysctlnode node;
+
+ nmaxlwp = maxlwp;
+ node = *rnode;
+ node.sysctl_data = &nmaxlwp;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ if (nmaxlwp < 0 || nmaxlwp >= 65536)
+ return EINVAL;
+#ifdef __HAVE_CPU_MAXLWP
+ if (nmaxlwp > cpu_maxlwp())
+ return EINVAL;
+#endif
+ maxlwp = nmaxlwp;
+
+ return 0;
+}
+/*
* sysctl helper function for kern.hostid. The hostid is a long, but
* we export it as an int, so we need to give it a little help.
*/
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.352
diff -u -p -u -r1.352 kern_exec.c
--- kern/kern_exec.c 2 May 2012 23:33:11 -0000 1.352
+++ kern/kern_exec.c 23 May 2012 23:19:32 -0000
@@ -2295,7 +2295,7 @@ do_posix_spawn(struct lwp *l1, pid_t *pi
/* create LWP */
lwp_create(l1, p2, uaddr, 0, NULL, 0, spawn_return, spawn_data,
- &l2, l1->l_class);
+ &l2, l1->l_class, 0);
l2->l_ctxlink = NULL; /* reset ucontext link */
/*
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 kern_fork.c
--- kern/kern_fork.c 13 Mar 2012 18:40:52 -0000 1.189
+++ kern/kern_fork.c 23 May 2012 23:19:32 -0000
@@ -426,7 +426,7 @@ fork1(struct lwp *l1, int flags, int exi
*/
lwp_create(l1, p2, uaddr, (flags & FORK_PPWAIT) ? LWP_VFORK : 0,
stack, stacksize, (func != NULL) ? func : child_return, arg, &l2,
- l1->l_class);
+ l1->l_class, 0);
/*
* Inherit l_private from the parent.
Index: kern/kern_kthread.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_kthread.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 kern_kthread.c
--- kern/kern_kthread.c 1 Nov 2011 15:39:37 -0000 1.38
+++ kern/kern_kthread.c 23 May 2012 23:19:32 -0000
@@ -81,7 +81,7 @@ kthread_create(pri_t pri, int flag, stru
}
error = lwp_create(&lwp0, &proc0, uaddr, LWP_DETACHED, NULL,
- 0, func, arg, &l, lc);
+ 0, func, arg, &l, lc, 0);
if (error) {
uvm_uarea_system_free(uaddr);
return error;
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.168
diff -u -p -u -r1.168 kern_lwp.c
--- kern/kern_lwp.c 13 Apr 2012 15:32:43 -0000 1.168
+++ kern/kern_lwp.c 23 May 2012 23:19:32 -0000
@@ -239,6 +239,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v
#include <sys/dtrace_bsd.h>
#include <sys/sdt.h>
#include <sys/xcall.h>
+#include <sys/uidinfo.h>
#include <uvm/uvm_extern.h>
#include <uvm/uvm_object.h>
@@ -668,15 +669,32 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lw
int
lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, int flags,
void *stack, size_t stacksize, void (*func)(void *), void *arg,
- lwp_t **rnewlwpp, int sclass)
+ lwp_t **rnewlwpp, int sclass, int enforce)
{
struct lwp *l2, *isfree;
turnstile_t *ts;
lwpid_t lid;
+ uid_t uid;
+ int count;
KASSERT(l1 == curlwp || l1->l_proc == &proc0);
/*
+ * Enforce limits.
+ */
+ uid = kauth_cred_getuid(l1->l_cred);
+ count = chglwpcnt(uid, 1);
+ if (enforce &&
+ __predict_false(count > p2->p_rlimit[RLIMIT_NTHR].rlim_cur)) {
+ if (kauth_authorize_process(l1->l_cred, KAUTH_PROCESS_RLIMIT,
+ p2, KAUTH_ARG(KAUTH_REQ_PROCESS_RLIMIT_BYPASS),
+ &p2->p_rlimit[RLIMIT_NTHR], KAUTH_ARG(RLIMIT_NTHR)) != 0) {
+ (void)chglwpcnt(uid, -1);
+ return EAGAIN;
+ }
+ }
+
+ /*
* First off, reap any detached LWP waiting to be collected.
* We can re-use its LWP structure and turnstile.
*/
@@ -898,6 +916,7 @@ lwp_exit(struct lwp *l)
SDT_PROBE(proc,,,lwp_exit, l, 0,0,0,0);
+ chglwpcnt(kauth_cred_getuid(l->l_cred), -1);
/*
* Verify that we hold no locks other than the kernel lock.
*/
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.183
diff -u -p -u -r1.183 kern_proc.c
--- kern/kern_proc.c 13 Apr 2012 15:32:15 -0000 1.183
+++ kern/kern_proc.c 23 May 2012 23:19:33 -0000
@@ -460,6 +460,9 @@ proc0_init(void)
rlim[RLIMIT_MEMLOCK].rlim_max = lim;
rlim[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
+ rlim[RLIMIT_NTHR].rlim_max = maxlwp;
+ rlim[RLIMIT_NTHR].rlim_cur = maxlwp < maxuprc ? maxlwp : maxuprc;
+
/* Note that default core name has zero length. */
limit0.pl_corename = defcorename;
limit0.pl_cnlen = 0;
Index: kern/kern_prot.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_prot.c,v
retrieving revision 1.114
diff -u -p -u -r1.114 kern_prot.c
--- kern/kern_prot.c 19 Mar 2012 06:04:19 -0000 1.114
+++ kern/kern_prot.c 23 May 2012 23:19:33 -0000
@@ -346,6 +346,11 @@ do_setresuid(struct lwp *l, uid_t r, uid
/* Update count of processes for this user */
(void)chgproccnt(kauth_cred_getuid(ncred), -1);
(void)chgproccnt(r, 1);
+
+ int nlwps = p->p_nlwps;
+ (void)chglwpcnt(kauth_cred_getuid(ncred), -nlwps);
+ (void)chglwpcnt(r, nlwps);
+
kauth_cred_setuid(ncred, r);
}
if (sv != -1)
Index: kern/kern_resource.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_resource.c,v
retrieving revision 1.168
diff -u -p -u -r1.168 kern_resource.c
--- kern/kern_resource.c 2 Dec 2011 12:33:12 -0000 1.168
+++ kern/kern_resource.c 23 May 2012 23:19:33 -0000
@@ -439,6 +439,13 @@ dosetrlimit(struct lwp *l, struct proc *
if (limp->rlim_max > maxproc)
limp->rlim_max = maxproc;
break;
+
+ case RLIMIT_NTHR:
+ if (limp->rlim_cur > maxlwp)
+ limp->rlim_cur = maxlwp;
+ if (limp->rlim_max > maxlwp)
+ limp->rlim_max = maxlwp;
+ break;
}
mutex_enter(&p->p_limit->pl_lock);
@@ -1082,6 +1089,7 @@ sysctl_proc_setup(void)
create_proc_plimit("descriptors", PROC_PID_LIMIT_NOFILE);
create_proc_plimit("sbsize", PROC_PID_LIMIT_SBSIZE);
create_proc_plimit("vmemoryuse", PROC_PID_LIMIT_AS);
+ create_proc_plimit("maxlwp", PROC_PID_LIMIT_NTHR);
#undef create_proc_plimit
Index: kern/kern_synch.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
retrieving revision 1.301
diff -u -p -u -r1.301 kern_synch.c
--- kern/kern_synch.c 21 Apr 2012 22:38:25 -0000 1.301
+++ kern/kern_synch.c 23 May 2012 23:19:34 -0000
@@ -96,6 +96,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_synch.c
#include <sys/lwpctl.h>
#include <sys/atomic.h>
#include <sys/simplelock.h>
+#include <sys/uidinfo.h>
+#include <sys/kauth.h>
#include <sys/syslog.h>
#include <uvm/uvm_extern.h>
@@ -805,6 +807,7 @@ lwp_exit_switchaway(lwp_t *l)
LOCKDEBUG_BARRIER(NULL, 0);
kstack_check_magic(l);
+ chglwpcnt(kauth_cred_geteuid(l->l_cred), -1);
/* Count time spent in current system call */
SYSCALL_TIME_SLEEP(l);
Index: kern/kern_uidinfo.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_uidinfo.c,v
retrieving revision 1.5
diff -u -p -u -r1.5 kern_uidinfo.c
--- kern/kern_uidinfo.c 22 Mar 2009 00:49:13 -0000 1.5
+++ kern/kern_uidinfo.c 23 May 2012 23:19:34 -0000
@@ -43,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_uidinfo
#include <sys/proc.h>
#include <sys/atomic.h>
#include <sys/uidinfo.h>
+#include <sys/sysctl.h>
+#include <sys/kauth.h>
#include <sys/cpu.h>
static SLIST_HEAD(uihashhead, uidinfo) *uihashtbl;
@@ -50,6 +52,79 @@ static u_long uihash;
#define UIHASH(uid) (&uihashtbl[(uid) & uihash])
+static int
+sysctl_kern_uidinfo_cnt(SYSCTLFN_ARGS)
+{
+ static const struct {
+ const char *name;
+ u_int value;
+ } nv[] = {
+#define _MEM(n) { # n, offsetof(struct uidinfo, ui_ ## n) }
+ _MEM(proccnt),
+ _MEM(lwpcnt),
+ _MEM(lockcnt),
+ _MEM(sbsize),
+#undef _MEM
+ };
+
+ for (size_t i = 0; i < __arraycount(nv); i++)
+ if (strcmp(nv[i].name, rnode->sysctl_name) == 0) {
+ uint64_t cnt;
+ struct sysctlnode node = *rnode;
+ struct uidinfo *uip;
+
+ node.sysctl_data = &cnt;
+ uip = uid_find(kauth_cred_geteuid(l->l_cred));
+
+ *(uint64_t *)node.sysctl_data =
+ *(u_long *)((char *)uip + nv[i].value);
+
+ return sysctl_lookup(SYSCTLFN_CALL(&node));
+ }
+
+ return EINVAL;
+}
+
+static void
+sysctl_kern_uidinfo_setup(void)
+{
+ const struct sysctlnode *rnode, *cnode;
+ struct sysctllog *kern_uidinfo_sysctllog;
+
+ kern_uidinfo_sysctllog = NULL;
+ sysctl_createv(&kern_uidinfo_sysctllog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "uidinfo",
+ SYSCTL_DESCR("Resource usage per uid"),
+ NULL, 0, NULL, 0,
+ CTL_KERN, CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_QUAD, "proccnt",
+ SYSCTL_DESCR("Number of processes for the current user"),
+ sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_QUAD, "lwpcnt",
+ SYSCTL_DESCR("Number of lwps for the current user"),
+ sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_QUAD, "lockcnt",
+ SYSCTL_DESCR("Number of locks for the current user"),
+ sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+ sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_QUAD, "sbsize",
+ SYSCTL_DESCR("Socket buffers used for the current user"),
+ sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+}
+
void
uid_init(void)
{
@@ -68,6 +143,7 @@ uid_init(void)
* sbreserve() expects it available from interrupt context.
*/
(void)uid_find(0);
+ sysctl_kern_uidinfo_setup();
}
struct uidinfo *
@@ -126,6 +202,22 @@ chgproccnt(uid_t uid, int diff)
return proccnt;
}
+/*
+ * Change the count associated with number of lwps
+ * a given user is using.
+ */
+int
+chglwpcnt(uid_t uid, int diff)
+{
+ struct uidinfo *uip;
+ long lwpcnt;
+
+ uip = uid_find(uid);
+ lwpcnt = atomic_add_long_nv(&uip->ui_lwpcnt, diff);
+ KASSERT(lwpcnt >= 0);
+ return lwpcnt;
+}
+
int
chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t xmax)
{
Index: kern/sys_aio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_aio.c,v
retrieving revision 1.37
diff -u -p -u -r1.37 sys_aio.c
--- kern/sys_aio.c 17 Feb 2011 19:02:50 -0000 1.37
+++ kern/sys_aio.c 23 May 2012 23:19:34 -0000
@@ -211,7 +211,7 @@ aio_procinit(struct proc *p)
return EAGAIN;
}
error = lwp_create(curlwp, p, uaddr, 0, NULL, 0, aio_worker,
- NULL, &l, curlwp->l_class);
+ NULL, &l, curlwp->l_class, 1);
if (error != 0) {
uvm_uarea_free(uaddr);
aio_exit(p, aio);
Index: kern/sys_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_lwp.c,v
retrieving revision 1.53
diff -u -p -u -r1.53 sys_lwp.c
--- kern/sys_lwp.c 19 Feb 2012 21:06:56 -0000 1.53
+++ kern/sys_lwp.c 23 May 2012 23:19:34 -0000
@@ -101,7 +101,7 @@ sys__lwp_create(struct lwp *l, const str
}
error = lwp_create(l, p, uaddr, SCARG(uap, flags) & LWP_DETACHED,
- NULL, 0, p->p_emul->e_startlwp, newuc, &l2, l->l_class);
+ NULL, 0, p->p_emul->e_startlwp, newuc, &l2, l->l_class, 1);
if (__predict_false(error)) {
uvm_uarea_free(uaddr);
kmem_free(newuc, sizeof(ucontext_t));
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.160
diff -u -p -u -r1.160 lwp.h
--- sys/lwp.h 19 Feb 2012 21:06:58 -0000 1.160
+++ sys/lwp.h 23 May 2012 23:19:35 -0000
@@ -210,6 +210,7 @@ LIST_HEAD(lwplist, lwp); /* A list of L
#ifdef _KERNEL
extern struct lwplist alllwp; /* List of all LWPs. */
extern lwp_t lwp0; /* LWP for proc0. */
+extern int maxlwp; /* max number of lwps */
#endif
/* These flags are kept in l_flag. */
@@ -409,7 +410,7 @@ lwp_eprio(lwp_t *l)
}
int lwp_create(lwp_t *, struct proc *, vaddr_t, int,
- void *, size_t, void (*)(void *), void *, lwp_t **, int);
+ void *, size_t, void (*)(void *), void *, lwp_t **, int, int);
/*
* XXX _MODULE
Index: sys/resource.h
===================================================================
RCS file: /cvsroot/src/sys/sys/resource.h,v
retrieving revision 1.32
diff -u -p -u -r1.32 resource.h
--- sys/resource.h 14 May 2011 17:57:05 -0000 1.32
+++ sys/resource.h 23 May 2012 23:19:35 -0000
@@ -90,9 +90,10 @@ struct rusage {
#define RLIMIT_SBSIZE 9 /* maximum size of all socket
buffers */
#define RLIMIT_AS 10 /* virtual process size
(inclusive of mmap) */
#define RLIMIT_VMEM RLIMIT_AS /* common alias */
+#define RLIMIT_NTHR 11 /* number of threads */
#if defined(_NETBSD_SOURCE)
-#define RLIM_NLIMITS 11 /* number of resource limits */
+#define RLIM_NLIMITS 12 /* number of resource limits */
#endif
#define RLIM_INFINITY (~((u_quad_t)1 << 63)) /* no limit */
Index: sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.199
diff -u -p -u -r1.199 sysctl.h
--- sys/sysctl.h 27 Jan 2012 19:48:41 -0000 1.199
+++ sys/sysctl.h 23 May 2012 23:19:36 -0000
@@ -266,7 +266,8 @@ struct ctlname {
#define KERN_SYSVIPC 82 /* node: SysV IPC parameters */
#define KERN_BOOTTIME 83 /* struct: time kernel was
booted */
#define KERN_EVCNT 84 /* struct: evcnts */
-#define KERN_MAXID 85 /* number of valid kern ids */
+#define KERN_MAXLWP 85 /* int: maxlwp */
+#define KERN_MAXID 86 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
@@ -355,6 +356,7 @@ struct ctlname {
{ "sysvipc", CTLTYPE_STRUCT }, \
{ "boottime", CTLTYPE_STRUCT }, \
{ "evcnt", CTLTYPE_STRUCT }, \
+ { "maxlwp", CTLTYPE_INT }, \
}
/*
@@ -975,6 +977,7 @@ struct evcnt_sysctl {
#define PROC_PID_LIMIT_NOFILE (RLIMIT_NOFILE+1)
#define PROC_PID_LIMIT_SBSIZE (RLIMIT_SBSIZE+1)
#define PROC_PID_LIMIT_AS (RLIMIT_AS+1)
+#define PROC_PID_LIMIT_NTHR (RLIMIT_NTHR+1)
#define PROC_PID_LIMIT_MAXID (RLIM_NLIMITS+1)
#define PROC_PID_LIMIT_NAMES { \
@@ -990,6 +993,7 @@ struct evcnt_sysctl {
{ "descriptors", CTLTYPE_NODE }, \
{ "sbsize", CTLTYPE_NODE }, \
{ "vmemoryuse", CTLTYPE_NODE }, \
+ { "maxlwp", CTLTYPE_NODE }, \
}
/* for each type, either hard or soft value */
#define PROC_PID_LIMIT_TYPE_SOFT 1
Index: sys/uidinfo.h
===================================================================
RCS file: /cvsroot/src/sys/sys/uidinfo.h,v
retrieving revision 1.2
diff -u -p -u -r1.2 uidinfo.h
--- sys/uidinfo.h 14 Oct 2008 09:16:32 -0000 1.2
+++ sys/uidinfo.h 23 May 2012 23:19:36 -0000
@@ -43,11 +43,13 @@ struct uidinfo {
SLIST_ENTRY(uidinfo) ui_hash;
uid_t ui_uid;
u_long ui_proccnt; /* Number of processes */
+ u_long ui_lwpcnt; /* Number of lwps */
u_long ui_lockcnt; /* Number of locks */
u_long ui_sbsize; /* Socket buffer size */
};
int chgproccnt(uid_t, int);
+int chglwpcnt(uid_t, int);
int chgsbsize(struct uidinfo *, u_long *, u_long, rlim_t);
struct uidinfo *uid_find(uid_t);
void uid_init(void);
Home |
Main Index |
Thread Index |
Old Index