PERFORCE change 163184 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Sun May 31 18:01:15 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163184
Change 163184 by trasz at trasz_victim on 2009/05/31 18:01:07
Put limits set via rlimit(2) into hrl.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#2 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#2 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#3 edit
.. //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#3 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#2 (text+ko) ====
@@ -32,22 +32,85 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/priv.h>
+#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/types.h>
+#include <sys/eventhandler.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits");
/*
- * XXX: Locking.
+ * XXX: Need a better way to store stuff; rbtree?
*/
-static struct hrl_limit **limits = NULL;
+static struct hrl_limit *limits = NULL;
static int nlimits = 0;
+static struct mtx hrllock;
+
+static void hrl_init(void);
+SYSINIT(hrl, SI_SUB_RUN_SCHEDULER, SI_ORDER_SECOND, hrl_init, NULL);
+
+int
+hrl_alloc(int object, uint64_t amount)
+{
+
+ KASSERT(amount > 0, ("invalid amount"));
+
+ return (0);
+}
+
+void
+hrl_free(int object, uint64_t amount)
+{
+
+ KASSERT(amount > 0, ("invalid amount"));
+}
+
+void
+hrl_adjust(int subject, id_t subject_id, int per, int object, int action, int64_t amount)
+{
+ mtx_lock(&hrllock);
+
+ nlimits++;
+ /*
+ * XXX: Make it possible to remove and overwrite limits, not just add them.
+ */
+ limits = realloc(limits, sizeof(struct hrl_limit) * nlimits, M_HRL, M_WAITOK);
+
+ limits[nlimits - 1].hl_subject = subject;
+ limits[nlimits - 1].hl_subject_id = subject_id;
+ limits[nlimits - 1].hl_per = per;
+ limits[nlimits - 1].hl_object = object;
+ limits[nlimits - 1].hl_action = action;
+ limits[nlimits - 1].hl_amount = amount;
+
+ mtx_unlock(&hrllock);
+}
+
+/*
+ * System calls.
+ */
static int
-hrl_check(struct hrl_limit **limits, int nlimits)
+hrl_check(struct hrl_limit *limits, int nlimits)
{
+ int i;
+
+ for (i = 0; i < nlimits; i++) {
+ if (limits[i].hl_subject <= 0 || limits[i].hl_subject > HRL_SUBJECT_MAX)
+ return (EINVAL);
+ if (limits[i].hl_per <= 0 || limits[i].hl_per > HRL_SUBJECT_MAX)
+ return (EINVAL);
+ if (limits[i].hl_object <= 0 || limits[i].hl_object > HRL_OBJECT_MAX)
+ return (EINVAL);
+ if (limits[i].hl_action <= 0 || limits[i].hl_action > HRL_ACTION_MAX)
+ return (EINVAL);
+ if (limits[i].hl_amount <= 0)
+ return (EINVAL);
+ }
return (0);
}
@@ -57,7 +120,7 @@
{
int error;
size_t buflen;
- struct hrl_limit **newlimits;
+ struct hrl_limit *newlimits;
error = priv_check(td, PRIV_HRL_GET);
if (error)
@@ -74,9 +137,11 @@
* Removing all the limits?
*/
if (uap->nentries == 0) {
+ mtx_lock(&hrllock);
free(limits, M_HRL);
limits = NULL;
nlimits = 0;
+ mtx_unlock(&hrllock);
return (0);
}
@@ -92,12 +157,16 @@
if (error)
goto out;
+ mtx_lock(&hrllock);
+
if (limits != NULL)
free(limits, M_HRL);
limits = newlimits;
nlimits = uap->nentries;
+ mtx_unlock(&hrllock);
+
return (0);
out:
@@ -119,17 +188,48 @@
* XXX: Check for being in jail?
*/
- if (suword(uap->required, nlimits) != 0)
- return (EINVAL);
+ mtx_lock(&hrllock);
+
+ if (suword(uap->required, nlimits) != 0) {
+ error = EINVAL;
+ goto out;
+ }
+
+ if (uap->nentries == 0 && uap->bufp == NULL) {
+ error = 0;
+ goto out;
+ }
- if (uap->nentries == 0 && uap->bufp == NULL)
- return (0);
+ if (uap->nentries < nlimits) {
+ error = EFBIG;
+ goto out;
+ }
- if (uap->nentries < nlimits)
- return (EFBIG);
+ if (nlimits == 0) {
+ error = 0;
+ goto out;
+ }
buflen = sizeof(struct hrl_limit) * nlimits;
error = copyout(limits, uap->bufp, buflen);
+out:
+ mtx_unlock(&hrllock);
+
return (error);
}
+
+static void
+hrl_proc_exit(void *arg __unused, struct proc *p)
+{
+ /*
+ * XXX: Remove per-process limits here.
+ */
+}
+
+static void
+hrl_init(void)
+{
+ mtx_init(&hrllock, "hrl lock", NULL, MTX_DEF);
+ EVENTHANDLER_REGISTER(process_exit, hrl_proc_exit, NULL, EVENTHANDLER_PRI_ANY);
+}
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#2 (text+ko) ====
@@ -43,6 +43,7 @@
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/file.h>
+#include <sys/hrl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -642,6 +643,82 @@
callout_reset(&p->p_limco, hz, lim_cb, p);
}
+static void
+hrl_handle_setrlimit(u_int which, struct rlimit *lim, struct thread *td)
+{
+ int object, subject, soft_action, hard_action;
+ id_t id;
+
+ /*
+ * XXX: Locking.
+ */
+ subject = HRL_SUBJECT_PROCESS;
+ id = td->td_proc->p_pid;
+ soft_action = HRL_ACTION_LOG;
+ hard_action = HRL_ACTION_DENY;
+
+ switch (which) {
+ case RLIMIT_CPU:
+ object = HRL_OBJECT_CPUTIME;
+ soft_action = HRL_ACTION_SIGXCPU;
+ break;
+ case RLIMIT_FSIZE:
+ object = HRL_OBJECT_FILESIZE;
+ break;
+ case RLIMIT_DATA:
+ object = HRL_OBJECT_DATASIZE;
+ break;
+ case RLIMIT_STACK:
+ object = HRL_OBJECT_STACKSIZE;
+ soft_action = HRL_ACTION_SIGSEGV;
+ break;
+ case RLIMIT_CORE:
+ object = HRL_OBJECT_COREDUMPSIZE;
+ break;
+ case RLIMIT_RSS:
+ object = HRL_OBJECT_MEMORYUSE;
+ break;
+ case RLIMIT_MEMLOCK:
+ object = HRL_OBJECT_MEMORYLOCKED;
+ break;
+ case RLIMIT_NPROC:
+ object = HRL_OBJECT_MAXPROCESSES;
+ subject = HRL_SUBJECT_USER;
+ id = td->td_ucred->cr_uid;
+ break;
+ case RLIMIT_NOFILE:
+ object = HRL_OBJECT_OPENFILES;
+ soft_action = HRL_ACTION_SIGXFSZ;
+ break;
+ case RLIMIT_SBSIZE:
+ object = HRL_OBJECT_SBSIZE;
+ subject = HRL_SUBJECT_USER;
+ id = td->td_ucred->cr_uid;
+ break;
+ case RLIMIT_VMEM:
+ object = HRL_OBJECT_VMEMORYUSE;
+ break;
+ case RLIMIT_NPTS:
+ object = HRL_OBJECT_PTY;
+ subject = HRL_SUBJECT_USER;
+ id = td->td_ucred->cr_uid;
+ break;
+ default:
+ panic("hrl_handle_setrlimit: unknown limit");
+ }
+
+ if (lim->rlim_cur != RLIM_INFINITY)
+ hrl_adjust(subject, id, subject, object, soft_action,
+ lim->rlim_cur);
+ else
+ hrl_adjust(subject, id, subject, object, soft_action, 0);
+ if (lim->rlim_max != RLIM_INFINITY)
+ hrl_adjust(subject, id, subject, object, hard_action,
+ lim->rlim_max);
+ else
+ hrl_adjust(subject, id, subject, object, hard_action, 0);
+}
+
int
kern_setrlimit(td, which, limp)
struct thread *td;
@@ -763,6 +840,8 @@
}
}
+ hrl_handle_setrlimit(which, alimp, td);
+
return (0);
}
==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#3 (text+ko) ====
@@ -45,7 +45,6 @@
int64_t hl_amount;
};
-#define HRL_SUBJECT_UNDEFINED 0x0000
#define HRL_SUBJECT_PROCESS 0x0001
#define HRL_SUBJECT_USER 0x0002
#define HRL_SUBJECT_GROUP 0x0003
@@ -57,7 +56,6 @@
* 'hl_per' takes the same flags as 'hl_subject'.
*/
-#define HRL_OBJECT_UNDEFINED 0x0000
#define HRL_OBJECT_CPUTIME 0x0001
#define HRL_OBJECT_FILESIZE 0x0002
#define HRL_OBJECT_DATASIZE 0x0003
@@ -72,27 +70,31 @@
#define HRL_OBJECT_PTY 0x000c
#define HRL_OBJECT_MAX HRL_OBJECT_PTY
-#define HRL_ACTION_UNDEFINED 0x0000
#define HRL_ACTION_DENY 0x0001
#define HRL_ACTION_DELAY 0x0002
#define HRL_ACTION_LOG 0x0003
#define HRL_ACTION_SIGHUP 0x0004
#define HRL_ACTION_SIGINT 0x0005
#define HRL_ACTION_SIGKILL 0x0006
-#define HRL_ACTION_SIGXCPU 0x0007
-#define HRL_ACTION_SIGXFSZ 0x0008
+#define HRL_ACTION_SIGSEGV 0x0007
+#define HRL_ACTION_SIGXCPU 0x0008
+#define HRL_ACTION_SIGXFSZ 0x0009
#define HRL_ACTION_MAX HRL_ACTION_SIGXFSZ
#define HRL_MAX_LIMITS 128
-int hrl_alloc(int tag, int amount);
-void hrl_free(int tag, int amount);
+#ifdef _KERNEL
+
+int hrl_alloc(int object, uint64_t amount);
+void hrl_free(int object, uint64_t amount);
+
+void hrl_adjust(int subject, id_t subject_id, int per, int object, int action, int64_t amount);
-#ifndef _KERNEL
+#else /* !_KERNEL */
__BEGIN_DECLS
-int hrl_get(struct hrl_limit **bufp, int nentries, int *count);
-int hrl_set(struct hrl_limit **bufp, int nentries);
+int hrl_get(struct hrl_limit *bufp, int nentries, int *count);
+int hrl_set(struct hrl_limit *bufp, int nentries);
__END_DECLS
#endif /* !_KERNEL */
==== //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#3 (text+ko) ====
@@ -30,21 +30,33 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
#include <sys/hrl.h>
static void
print_subject(int subject, id_t id)
{
+ struct passwd *pwd;
+ struct group *grp;
switch (subject) {
case HRL_SUBJECT_PROCESS:
printf("process:%u", (unsigned int)id);
break;
case HRL_SUBJECT_USER:
- printf("user:%u", (unsigned int)id);
+ pwd = getpwuid(id);
+ if (pwd != NULL)
+ printf("user:%s", pwd->pw_name);
+ else
+ printf("user:%u", (unsigned int)id);
break;
case HRL_SUBJECT_GROUP:
- printf("group:%u", (unsigned int)id);
+ grp = getgrgid(id);
+ if (grp != NULL)
+ printf("group:%s", grp->gr_name);
+ else
+ printf("group:%u", (unsigned int)id);
break;
case HRL_SUBJECT_LOGINCLASS:
printf("class:%u", (unsigned int)id);
@@ -127,6 +139,9 @@
case HRL_ACTION_SIGKILL:
printf("sigkill");
break;
+ case HRL_ACTION_SIGSEGV:
+ printf("sigsegv");
+ break;
case HRL_ACTION_SIGXCPU:
printf("sigxcpu");
break;
@@ -168,7 +183,7 @@
main(int argc __unused, char **argv __unused)
{
int error, nentries, i;
- struct hrl_limit **limits;
+ struct hrl_limit *limits;
error = hrl_get(NULL, 0, &nentries);
if (error)
@@ -190,16 +205,16 @@
printf("Defined resource limits:\n");
for (i = 0; i < nentries; i++) {
- print_subject(limits[i]->hl_subject, limits[i]->hl_subject_id);
+ print_subject(limits[i].hl_subject, limits[i].hl_subject_id);
printf(":");
- print_object(limits[i]->hl_object);
+ print_object(limits[i].hl_object);
printf(":");
- print_action(limits[i]->hl_action);
+ print_action(limits[i].hl_action);
printf(":");
- printf("%jd", limits[i]->hl_amount);
- if (limits[i]->hl_subject != limits[i]->hl_per) {
+ printf("%jd", limits[i].hl_amount);
+ if (limits[i].hl_subject != limits[i].hl_per) {
printf("/");
- print_per(limits[i]->hl_per);
+ print_per(limits[i].hl_per);
}
printf("\n");
}
More information about the p4-projects
mailing list