Module Name:    src
Committed By:   christos
Date:           Sat Jun  9 02:31:15 UTC 2012

Modified Files:
        src/sys/conf: param.c
        src/sys/kern: kern_lwp.c kern_proc.c kern_prot.c kern_resource.c
            kern_uidinfo.c
        src/sys/sys: lwp.h resource.h sysctl.h uidinfo.h

Log Message:
Add a new resource to limit the number of lwps per user, RLIMIT_NTHR. There
is a global sysctl kern.maxlwp to control this, which is by default 2048.
The first lwp of each process or kernel threads are not counted against the
limit. To show the current resource usage per user, I added a new sysctl
that dumps the uidinfo structure fields.


To generate a diff of this commit:
cvs rdiff -u -r1.63 -r1.64 src/sys/conf/param.c
cvs rdiff -u -r1.168 -r1.169 src/sys/kern/kern_lwp.c \
    src/sys/kern/kern_resource.c
cvs rdiff -u -r1.185 -r1.186 src/sys/kern/kern_proc.c
cvs rdiff -u -r1.114 -r1.115 src/sys/kern/kern_prot.c
cvs rdiff -u -r1.5 -r1.6 src/sys/kern/kern_uidinfo.c
cvs rdiff -u -r1.161 -r1.162 src/sys/sys/lwp.h
cvs rdiff -u -r1.32 -r1.33 src/sys/sys/resource.h
cvs rdiff -u -r1.200 -r1.201 src/sys/sys/sysctl.h
cvs rdiff -u -r1.2 -r1.3 src/sys/sys/uidinfo.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/conf/param.c
diff -u src/sys/conf/param.c:1.63 src/sys/conf/param.c:1.64
--- src/sys/conf/param.c:1.63	Mon Feb  8 14:02:33 2010
+++ src/sys/conf/param.c	Fri Jun  8 22:31:14 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.c,v 1.63 2010/02/08 19:02:33 joerg Exp $	*/
+/*	$NetBSD: param.c,v 1.64 2012/06/09 02:31:14 christos Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1989 Regents of the University of California.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: param.c,v 1.63 2010/02/08 19:02:33 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: param.c,v 1.64 2012/06/09 02:31:14 christos Exp $");
 
 #include "opt_hz.h"
 #include "opt_rtc_offset.h"
@@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: param.c,v 1.
 #include <sys/kernel.h>
 #include <sys/utsname.h>
 #include <sys/ksem.h>
+#include <sys/lwp.h>
 #ifdef SYSVSHM
 #include <machine/vmparam.h>
 #include <sys/shm.h>
@@ -117,6 +118,7 @@ int	tick = 1000000 / HZ;
 int	tickadj = (240000 / (60 * HZ)) ? (240000 / (60 * HZ)) : 1;
 int	rtc_offset = RTC_OFFSET;
 int	maxproc = NPROC;
+int	maxlwp = MAXLWP;
 int	desiredvnodes = NVNODE;
 u_int	maxfiles = MAXFILES;
 int	fscale = FSCALE;	/* kernel uses `FSCALE', user uses `fscale' */

Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.168 src/sys/kern/kern_lwp.c:1.169
--- src/sys/kern/kern_lwp.c:1.168	Fri Apr 13 11:32:43 2012
+++ src/sys/kern/kern_lwp.c	Fri Jun  8 22:31:14 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lwp.c,v 1.168 2012/04/13 15:32:43 yamt Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.169 2012/06/09 02:31:14 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.168 2012/04/13 15:32:43 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.169 2012/06/09 02:31:14 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -239,6 +239,8 @@ __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 <sys/sysctl.h>
 
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
@@ -286,6 +288,47 @@ struct lwp lwp0 __aligned(MIN_LWP_ALIGNM
 	.l_fd = &filedesc0,
 };
 
+static int sysctl_kern_maxlwp(SYSCTLFN_PROTO);
+
+/*
+ * 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;
+	if (nmaxlwp > cpu_maxlwp())
+		return EINVAL;
+	maxlwp = nmaxlwp;
+
+	return 0;
+}
+
+static void
+sysctl_kern_lwp_setup(void)
+{
+	struct sysctllog *clog = NULL;
+
+	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, CTL_CREATE, CTL_EOL);
+}
+
 void
 lwpinit(void)
 {
@@ -295,6 +338,9 @@ lwpinit(void)
 	lwp_sys_init();
 	lwp_cache = pool_cache_init(sizeof(lwp_t), MIN_LWP_ALIGNMENT, 0, 0,
 	    "lwppl", NULL, IPL_NONE, NULL, lwp_dtor, NULL);
+
+	maxlwp = cpu_maxlwp();
+	sysctl_kern_lwp_setup();
 }
 
 void
@@ -677,6 +723,28 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_
 	KASSERT(l1 == curlwp || l1->l_proc == &proc0);
 
 	/*
+	 * Enforce limits, excluding the first lwp and kthreads.
+	 */
+	if (p2->p_nlwps != 0 && p2 != &proc0) {
+		uid_t uid = kauth_cred_getuid(l1->l_cred);
+		int count = chglwpcnt(uid, 1);
+		if (__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) {
+				if ((count = chglwpcnt(uid, -1)) < 0)
+					printf("%s, %d: %s, %d, %d\n", __FILE__,
+					    __LINE__, l1->l_proc->p_comm,
+					    l1->l_proc->p_pid, count);
+				// return EAGAIN;
+			}
+		}
+	}
+
+	/*
 	 * First off, reap any detached LWP waiting to be collected.
 	 * We can re-use its LWP structure and turnstile.
 	 */
@@ -1041,6 +1109,10 @@ lwp_free(struct lwp *l, bool recycle, bo
 	KASSERT(l != curlwp);
 	KASSERT(last || mutex_owned(p->p_lock));
 
+	if (p != &proc0 && p->p_nlwps != 1)
+		if (chglwpcnt(kauth_cred_getuid(l->l_cred), -1) < 0)
+			printf("%s, %d: %d, %s\n", __FILE__, __LINE__,
+			    p->p_pid, p->p_comm);
 	/*
 	 * If this was not the last LWP in the process, then adjust
 	 * counters and unlock.
Index: src/sys/kern/kern_resource.c
diff -u src/sys/kern/kern_resource.c:1.168 src/sys/kern/kern_resource.c:1.169
--- src/sys/kern/kern_resource.c:1.168	Fri Dec  2 07:33:12 2011
+++ src/sys/kern/kern_resource.c	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_resource.c,v 1.168 2011/12/02 12:33:12 yamt Exp $	*/
+/*	$NetBSD: kern_resource.c,v 1.169 2012/06/09 02:31:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1991, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.168 2011/12/02 12:33:12 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.169 2012/06/09 02:31:15 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -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: src/sys/kern/kern_proc.c
diff -u src/sys/kern/kern_proc.c:1.185 src/sys/kern/kern_proc.c:1.186
--- src/sys/kern/kern_proc.c:1.185	Wed Jun  6 07:20:21 2012
+++ src/sys/kern/kern_proc.c	Fri Jun  8 22:31:14 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_proc.c,v 1.185 2012/06/06 11:20:21 martin Exp $	*/
+/*	$NetBSD: kern_proc.c,v 1.186 2012/06/09 02:31:14 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.185 2012/06/06 11:20:21 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.186 2012/06/09 02:31:14 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_kstack.h"
@@ -459,6 +459,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: src/sys/kern/kern_prot.c
diff -u src/sys/kern/kern_prot.c:1.114 src/sys/kern/kern_prot.c:1.115
--- src/sys/kern/kern_prot.c:1.114	Mon Mar 19 02:04:19 2012
+++ src/sys/kern/kern_prot.c	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_prot.c,v 1.114 2012/03/19 06:04:19 matt Exp $	*/
+/*	$NetBSD: kern_prot.c,v 1.115 2012/06/09 02:31:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.114 2012/03/19 06:04:19 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.115 2012/06/09 02:31:15 christos Exp $");
 
 #include "opt_compat_43.h"
 
@@ -346,6 +346,14 @@ 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);
+
+		/* The first lwp of a process is not counted */
+		int nlwps = p->p_nlwps - 1;
+		if (chglwpcnt(kauth_cred_getuid(ncred), -nlwps) < 0)
+		    printf("%s, %d: %d, %s %d\n", __FILE__, __LINE__,
+			p->p_pid, p->p_comm, nlwps);
+		(void)chglwpcnt(r, nlwps);
+
 		kauth_cred_setuid(ncred, r);
 	}
 	if (sv != -1)

Index: src/sys/kern/kern_uidinfo.c
diff -u src/sys/kern/kern_uidinfo.c:1.5 src/sys/kern/kern_uidinfo.c:1.6
--- src/sys/kern/kern_uidinfo.c:1.5	Sat Mar 21 20:49:13 2009
+++ src/sys/kern/kern_uidinfo.c	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_uidinfo.c,v 1.5 2009/03/22 00:49:13 ad Exp $	*/
+/*	$NetBSD: kern_uidinfo.c,v 1.6 2012/06/09 02:31:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1991, 1993
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_uidinfo.c,v 1.5 2009/03/22 00:49:13 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_uidinfo.c,v 1.6 2012/06/09 02:31:15 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -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,27 @@ 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);
+#if 0
+	KASSERT(lwpcnt >= 0);
+#else
+	if (lwpcnt < 0)
+		printf("pid=%d lwpcnt=%ld\n", uid, lwpcnt);
+#endif
+	return lwpcnt;
+}
+
 int
 chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t xmax)
 {

Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.161 src/sys/sys/lwp.h:1.162
--- src/sys/sys/lwp.h:1.161	Mon May 21 10:15:19 2012
+++ src/sys/sys/lwp.h	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: lwp.h,v 1.161 2012/05/21 14:15:19 martin Exp $	*/
+/*	$NetBSD: lwp.h,v 1.162 2012/06/09 02:31:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010
@@ -210,6 +210,13 @@ 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 __read_mostly;	/* max number of lwps */
+#ifndef MAXLWP
+#define	MAXLWP		2048
+#endif
+#ifndef	__HAVE_CPU_MAXLWP
+#define	cpu_maxlwp()	MAXLWP
+#endif
 #endif
 
 /* These flags are kept in l_flag. */

Index: src/sys/sys/resource.h
diff -u src/sys/sys/resource.h:1.32 src/sys/sys/resource.h:1.33
--- src/sys/sys/resource.h:1.32	Sat May 14 13:57:05 2011
+++ src/sys/sys/resource.h	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: resource.h,v 1.32 2011/05/14 17:57:05 rmind Exp $	*/
+/*	$NetBSD: resource.h,v 1.33 2012/06/09 02:31:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -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: src/sys/sys/sysctl.h
diff -u src/sys/sys/sysctl.h:1.200 src/sys/sys/sysctl.h:1.201
--- src/sys/sys/sysctl.h:1.200	Sat Jun  2 17:36:48 2012
+++ src/sys/sys/sysctl.h	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysctl.h,v 1.200 2012/06/02 21:36:48 dsl Exp $	*/
+/*	$NetBSD: sysctl.h,v 1.201 2012/06/09 02:31:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -982,6 +982,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 { \
@@ -997,6 +998,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: src/sys/sys/uidinfo.h
diff -u src/sys/sys/uidinfo.h:1.2 src/sys/sys/uidinfo.h:1.3
--- src/sys/sys/uidinfo.h:1.2	Tue Oct 14 05:16:32 2008
+++ src/sys/sys/uidinfo.h	Fri Jun  8 22:31:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: uidinfo.h,v 1.2 2008/10/14 09:16:32 ad Exp $	*/
+/*	$NetBSD: uidinfo.h,v 1.3 2012/06/09 02:31:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993
@@ -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);

Reply via email to