PERFORCE change 166739 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Wed Jul 29 17:14:35 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166739

Change 166739 by trasz at trasz_victim on 2009/07/29 17:14:03

	Rework syscall interface.  I'm quite happy with how it looks
	now, even though the implementation is still a little crappy.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/lib/libc/sys/Symbol.map#9 edit
.. //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_proto.h#6 edit
.. //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_syscall.h#6 edit
.. //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_syscalls.c#6 edit
.. //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_sysent.c#7 edit
.. //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/syscalls.master#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#7 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/init_sysent.c#9 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#32 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/syscalls.c#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/syscalls.master#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/systrace_args.c#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#24 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/syscall.h#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/syscall.mk#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/sysproto.h#8 edit
.. //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#15 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/lib/libc/sys/Symbol.map#9 (text) ====

@@ -359,7 +359,11 @@
 	shmctl;
 	symlinkat;
 	unlinkat;
-	hrl;
+	hrl_get_usage;
+	hrl_get_rules;
+	hrl_get_limits;
+	hrl_add_rule;
+	hrl_remove_rule;
 };
 
 FBSDprivate_1.0 {

==== //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_proto.h#6 (text+ko) ====

@@ -453,13 +453,6 @@
 	char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
 	char buf_l_[PADL_(struct shmid_ds32 *)]; struct shmid_ds32 * buf; char buf_r_[PADR_(struct shmid_ds32 *)];
 };
-struct hrl_args {
-	char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
-	char inbufp_l_[PADL_(const void)]; const void inbufp; char inbufp_r_[PADR_(const void)];
-	char inbuflen_l_[PADL_(size_t *)]; size_t * inbuflen; char inbuflen_r_[PADR_(size_t *)];
-	char outbufp_l_[PADL_(void *)]; void * outbufp; char outbufp_r_[PADR_(void *)];
-	char outbuflen_l_[PADL_(size_t)]; size_t outbuflen; char outbuflen_r_[PADR_(size_t)];
-};
 int	freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *);
 int	freebsd32_recvmsg(struct thread *, struct freebsd32_recvmsg_args *);
 int	freebsd32_sendmsg(struct thread *, struct freebsd32_sendmsg_args *);
@@ -543,7 +536,6 @@
 int	freebsd32_semctl(struct thread *, struct freebsd32_semctl_args *);
 int	freebsd32_msgctl(struct thread *, struct freebsd32_msgctl_args *);
 int	freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *);
-int	hrl(struct thread *, struct hrl_args *);
 
 #ifdef COMPAT_43
 
@@ -822,7 +814,6 @@
 #define	FREEBSD32_SYS_AUE_freebsd32_semctl	AUE_SEMCTL
 #define	FREEBSD32_SYS_AUE_freebsd32_msgctl	AUE_MSGCTL
 #define	FREEBSD32_SYS_AUE_freebsd32_shmctl	AUE_SHMCTL
-#define	FREEBSD32_SYS_AUE_hrl	AUE_NULL
 
 #undef PAD_
 #undef PADL_

==== //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_syscall.h#6 (text+ko) ====

@@ -382,7 +382,11 @@
 #define	FREEBSD32_SYS_freebsd32_msgctl	511
 #define	FREEBSD32_SYS_freebsd32_shmctl	512
 #define	FREEBSD32_SYS_lpathconf	513
-#define	FREEBSD32_SYS_hrl	514
-#define	FREEBSD32_SYS_getloginclass	515
-#define	FREEBSD32_SYS_setloginclass	516
-#define	FREEBSD32_SYS_MAXSYSCALL	517
+#define	FREEBSD32_SYS_getloginclass	514
+#define	FREEBSD32_SYS_setloginclass	515
+#define	FREEBSD32_SYS_hrl_get_usage	516
+#define	FREEBSD32_SYS_hrl_get_rules	517
+#define	FREEBSD32_SYS_hrl_get_limits	518
+#define	FREEBSD32_SYS_hrl_add_rule	519
+#define	FREEBSD32_SYS_hrl_remove_rule	520
+#define	FREEBSD32_SYS_MAXSYSCALL	521

==== //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_syscalls.c#6 (text+ko) ====

@@ -521,7 +521,11 @@
 	"freebsd32_msgctl",			/* 511 = freebsd32_msgctl */
 	"freebsd32_shmctl",			/* 512 = freebsd32_shmctl */
 	"lpathconf",			/* 513 = lpathconf */
-	"hrl",			/* 514 = hrl */
-	"getloginclass",			/* 515 = getloginclass */
-	"setloginclass",			/* 516 = setloginclass */
+	"getloginclass",			/* 514 = getloginclass */
+	"setloginclass",			/* 515 = setloginclass */
+	"hrl_get_usage",			/* 516 = hrl_get_usage */
+	"hrl_get_rules",			/* 517 = hrl_get_rules */
+	"hrl_get_limits",			/* 518 = hrl_get_limits */
+	"hrl_add_rule",			/* 519 = hrl_add_rule */
+	"hrl_remove_rule",			/* 520 = hrl_remove_rule */
 };

==== //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/freebsd32_sysent.c#7 (text+ko) ====

@@ -558,7 +558,11 @@
 	{ AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 },	/* 511 = freebsd32_msgctl */
 	{ AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 },	/* 512 = freebsd32_shmctl */
 	{ AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 },	/* 513 = lpathconf */
-	{ AS(hrl_args), (sy_call_t *)hrl, AUE_NULL, NULL, 0, 0, 0 },	/* 514 = hrl */
-	{ AS(getloginclass_args), (sy_call_t *)getloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 515 = getloginclass */
-	{ AS(setloginclass_args), (sy_call_t *)setloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 516 = setloginclass */
+	{ AS(getloginclass_args), (sy_call_t *)getloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 514 = getloginclass */
+	{ AS(setloginclass_args), (sy_call_t *)setloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 515 = setloginclass */
+	{ AS(hrl_get_usage_args), (sy_call_t *)hrl_get_usage, AUE_NULL, NULL, 0, 0, 0 },	/* 516 = hrl_get_usage */
+	{ AS(hrl_get_rules_args), (sy_call_t *)hrl_get_rules, AUE_NULL, NULL, 0, 0, 0 },	/* 517 = hrl_get_rules */
+	{ AS(hrl_get_limits_args), (sy_call_t *)hrl_get_limits, AUE_NULL, NULL, 0, 0, 0 },	/* 518 = hrl_get_limits */
+	{ AS(hrl_add_rule_args), (sy_call_t *)hrl_add_rule, AUE_NULL, NULL, 0, 0, 0 },	/* 519 = hrl_add_rule */
+	{ AS(hrl_remove_rule_args), (sy_call_t *)hrl_remove_rule, AUE_NULL, NULL, 0, 0, 0 },	/* 520 = hrl_remove_rule */
 };

==== //depot/projects/soc2009/trasz_limits/sys/compat/freebsd32/syscalls.master#8 (text+ko) ====

@@ -901,7 +901,11 @@
 512	AUE_SHMCTL	STD	{ int freebsd32_shmctl(int shmid, int cmd, \
 				    struct shmid_ds32 *buf); }
 513	AUE_LPATHCONF	NOPROTO	{ int lpathconf(char *path, int name); }
-514	AUE_NULL	STD	{ int hrl(int op, const void inbufp, size_t *inbuflen, void *outbufp, size_t outbuflen); }
-515	AUE_NULL	NOPROTO	{ int getloginclass(char *namebuf, size_t \
+514	AUE_NULL	NOPROTO	{ int getloginclass(char *namebuf, size_t \
 				    namelen); }
-516	AUE_NULL	NOPROTO	{ int setloginclass(const char *namebuf); }
+515	AUE_NULL	NOPROTO	{ int setloginclass(const char *namebuf); }
+516	AUE_NULL	NOPROTO	{ int hrl_get_usage(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+517	AUE_NULL	NOPROTO	{ int hrl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+518	AUE_NULL	NOPROTO	{ int hrl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+519	AUE_NULL	NOPROTO	{ int hrl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+520	AUE_NULL	NOPROTO	{ int hrl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }

==== //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#7 (text+ko) ====

@@ -463,6 +463,9 @@
 #endif
 	td->td_ucred = crhold(p->p_ucred);
 
+	/* Set default login class. */
+	p->p_loginclass = loginclass_find("default");
+
 	/* Create sigacts. */
 	p->p_sigacts = sigacts_alloc();
 

==== //depot/projects/soc2009/trasz_limits/sys/kern/init_sysent.c#9 (text+ko) ====

@@ -548,7 +548,11 @@
 	{ AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 511 = msgctl */
 	{ AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 512 = shmctl */
 	{ AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 },	/* 513 = lpathconf */
-	{ AS(hrl_args), (sy_call_t *)hrl, AUE_NULL, NULL, 0, 0, 0 },	/* 514 = hrl */
-	{ AS(getloginclass_args), (sy_call_t *)getloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 515 = getloginclass */
-	{ AS(setloginclass_args), (sy_call_t *)setloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 516 = setloginclass */
+	{ AS(getloginclass_args), (sy_call_t *)getloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 514 = getloginclass */
+	{ AS(setloginclass_args), (sy_call_t *)setloginclass, AUE_NULL, NULL, 0, 0, 0 },	/* 515 = setloginclass */
+	{ AS(hrl_get_usage_args), (sy_call_t *)hrl_get_usage, AUE_NULL, NULL, 0, 0, 0 },	/* 516 = hrl_get_usage */
+	{ AS(hrl_get_rules_args), (sy_call_t *)hrl_get_rules, AUE_NULL, NULL, 0, 0, 0 },	/* 517 = hrl_get_rules */
+	{ AS(hrl_get_limits_args), (sy_call_t *)hrl_get_limits, AUE_NULL, NULL, 0, 0, 0 },	/* 518 = hrl_get_limits */
+	{ AS(hrl_add_rule_args), (sy_call_t *)hrl_add_rule, AUE_NULL, NULL, 0, 0, 0 },	/* 519 = hrl_add_rule */
+	{ AS(hrl_remove_rule_args), (sy_call_t *)hrl_remove_rule, AUE_NULL, NULL, 0, 0, 0 },	/* 520 = hrl_remove_rule */
 };

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#32 (text+ko) ====

@@ -1020,58 +1020,6 @@
 	return (sb);
 }
 
-static int
-hrl_get_rules(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
-{
-	int error = 0, copied = 0;
-	struct hrl_rule *buf, filter;
-	struct hrl_node *node;
-
-	if (inputstr != NULL) {
-		error = hrl_rule_parse(&filter, inputstr);
-		if (error)
-			return (error);
-	}
-
-	buf = malloc(HRL_MAX_RULES * sizeof(struct hrl_rule), M_HRL, M_WAITOK);
-
-	/*
-	 * Copy the limits to the temporary buffer.  We cannot
-	 * copy it directly to the userland because of the mutex.
-	 */
-	mtx_lock(&hrl_lock);
-	RB_FOREACH(node, hrl_tree, &hrls) {
-		/*
-		 * XXX: Do not show everything to the client; just the
-		 *      nodes that affect him.
-		 */
-		if (copied >= HRL_MAX_RULES) {
-			/*
-			 * XXX: Hey, what to do now?
-			 */
-			error = EDOOFUS;
-			break;
-		}
-
-		if (inputstr != NULL) {
-			if (!hrl_rule_matches(&node->hn_rule, &filter))
-				continue;
-		}
-
-		*(buf + copied) = node->hn_rule;
-		copied++;
-	}
-	mtx_unlock(&hrl_lock);
-	if (error)
-		goto out;
-
-	*outputsbuf = hrl_rules_to_sbuf(buf, copied);
-out:
-	free(buf, M_HRL);
-	
-	return (error);
-}
-
 /*
  * XXX: We should sort the rules somewhat, so that 'log' rules are enforced
  *      before 'deny', if both are for the same subject, resource and amount.
@@ -1139,77 +1087,6 @@
 	    rulesp);
 }
 
-static int
-hrl_get_rules_pid(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
-{
-	int error = 0, copied = 0, i;
-	id_t pid;
-	struct proc *p;
-	struct hrl_rule *buf;
-	int64_t available[HRL_RESOURCE_MAX];
-	struct hrl_rule *rules[HRL_RESOURCE_MAX];
-
-	error = str2id(inputstr, &pid);
-	if (error)
-		return (error);
-
-	buf = malloc(HRL_RESOURCE_MAX * sizeof(struct hrl_rule), M_HRL, M_WAITOK);
-
-	if ((p = pfind(pid)) == NULL) {
-		if ((p = zpfind(pid)) == NULL) {
-			free(buf, M_HRL);
-			return (ESRCH);
-		}
-	}
-
-	mtx_lock(&hrl_lock);
-	hrl_compute_available(p, &available, &rules);
-
-	/*
-	 * Copy the limits to the temporary buffer.  We cannot
-	 * copy it directly to the userland because of the mutex.
-	 */
-	for (i = 0; i < HRL_RESOURCE_MAX; i++) {
-		if (rules[i] == NULL)
-			continue;
-		*(buf + copied) = *(rules[i]);
-		copied++;
-	}
-	mtx_unlock(&hrl_lock);
-
-	PROC_UNLOCK(p);
-	if (error)
-		goto out;
-
-	*outputsbuf = hrl_rules_to_sbuf(buf, copied);
-out:
-	free(buf, M_HRL);
-	
-	return (error);
-}
-
-static int
-hrl_add_rule(struct thread *td, char *inputstr)
-{
-	int error;
-	struct hrl_rule rule;
-
-	error = priv_check(td, PRIV_HRL_SET);
-	if (error)
-		return (error);
-	error = hrl_rule_parse(&rule, inputstr);
-	if (rule.hr_subject == HRL_SUBJECT_UNDEFINED ||
-	    rule.hr_subject_id <= 0 ||
-	    rule.hr_resource == HRL_RESOURCE_UNDEFINED ||
-	    rule.hr_action == HRL_ACTION_UNDEFINED ||
-	    rule.hr_amount < 0)
-		return (EINVAL);
-	if (error)
-		return (error);
-	error = hrl_rule_add(&rule);
-	return (error);
-}
-
 /*
  * Remove a rule from the ruleset.
  */
@@ -1242,19 +1119,48 @@
 	return (0);
 }
 
+/*
+ * Routine used by HRL syscalls to read in input string.
+ */
 static int
-hrl_remove_rule(struct thread *td, char *inputstr)
+hrl_read_inbuf(char **inputstr, const char *inbufp, size_t inbuflen)
 {
 	int error;
-	struct hrl_rule rule;
+	char *str;
+
+	if (inbuflen <= 0)
+		return (EINVAL);
 
-	error = priv_check(td, PRIV_HRL_SET);
-	if (error)
+	str = malloc(inbuflen + 1, M_HRL, M_WAITOK);
+	error = copyinstr(inbufp, str, inbuflen, NULL);
+	if (error) {
+		free(str, M_HRL);
 		return (error);
-	error = hrl_rule_parse(&rule, inputstr);
-	if (error)
-		return (error);
-	error = hrl_rule_remove(&rule);
+	}
+
+	*inputstr = str;
+
+	return (0);
+}
+
+/*
+ * Routine used by HRL syscalls to write out output string.
+ */
+static int
+hrl_write_outbuf(struct sbuf *outputsbuf, char *outbufp, size_t outbuflen)
+{
+	int error;
+
+	if (outputsbuf == NULL)
+		return (0);
+
+	sbuf_finish(outputsbuf);
+	if (outbuflen < sbuf_len(outputsbuf) + 1) {
+		sbuf_delete(outputsbuf);
+		return (EFBIG); /* ERANGE? */
+	}
+	error = copyout(sbuf_data(outputsbuf), outbufp, sbuf_len(outputsbuf) + 1);
+	sbuf_delete(outputsbuf);
 	return (error);
 }
 
@@ -1274,16 +1180,11 @@
 }
 
 static int
-hrl_get_usage_pid(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
+hrl_get_usage_pid(struct thread *td, id_t pid, struct sbuf **outputsbuf)
 {
-	int error;
-	id_t pid;
 	struct proc *p;
 	struct hrl_usage usage;
 
-	error = str2id(inputstr, &pid);
-	if (error)
-		return (error);
 	if ((p = pfind(pid)) == NULL) {
 		if ((p = zpfind(pid)) == NULL)
 			return (ESRCH);
@@ -1293,61 +1194,45 @@
 
 	*outputsbuf = hrl_usage_to_sbuf(&usage);
 
-	return (error);
+	return (0);
 }
 
 static int
-hrl_get_usage_uid(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
+hrl_get_usage_uid(struct thread *td, id_t uid, struct sbuf **outputsbuf)
 {
-	int error;
-	id_t uid;
 	struct uidinfo *uip;
 
-	error = str2id(inputstr, &uid);
-	if (error)
-		return (error);
 	uip = uifind_existing(uid);
 	if (uip == NULL)
 		return (ESRCH);
 	*outputsbuf = hrl_usage_to_sbuf(&uip->ui_usage);
 	uifree(uip);
 
-	return (error);
+	return (0);
 }
 
 static int
-hrl_get_usage_gid(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
+hrl_get_usage_gid(struct thread *td, id_t gid, struct sbuf **outputsbuf)
 {
-	int error;
-	id_t gid;
 	struct gidinfo *gip;
 
 	if (!hrl_group_accounting)
 		return (EOPNOTSUPP);
 
-	error = str2id(inputstr, &gid);
-	if (error)
-		return (error);
 	gip = gifind_existing(gid);
 	if (gip == NULL)
 		return (ESRCH);
 	*outputsbuf = hrl_usage_to_sbuf(&gip->gi_usage);
 	gifree(gip);
 
-	return (error);
+	return (0);
 }
 
 static int
-hrl_get_usage_jid(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
+hrl_get_usage_jid(struct thread *td, id_t jid, struct sbuf **outputsbuf)
 {
-	int error;
-	id_t jid;
 	struct prison *pr;
 
-	error = str2id(inputstr, &jid);
-	if (error)
-		return (error);
-
 	sx_xlock(&allprison_lock);
 	pr = prison_find(jid);
 	if (pr == NULL) {
@@ -1358,69 +1243,176 @@
 	prison_free(pr);
 	sx_xunlock(&allprison_lock);
 
-	return (error);
+	return (0);
 }
 
 int
-hrl(struct thread *td, struct hrl_args *uap)
+hrl_get_usage(struct thread *td, struct hrl_get_usage_args *uap)
 {
 	int error;
-	char *inputstr = NULL;
+	char *inputstr;
+	struct hrl_rule filter;
 	struct sbuf *outputsbuf = NULL;
 
-	if (uap->inbufp != NULL && uap->inbuflen != 0) {
-		if (uap->inbuflen <= 0)
-			return (EINVAL);
+	error = hrl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen);
+	if (error)
+		return (error);
 
-		inputstr = malloc(uap->inbuflen + 1, M_HRL, M_WAITOK);
-		error = copyinstr(uap->inbufp, inputstr, uap->inbuflen, NULL);
-		if (error)
-			goto out;
-	}
+	error = hrl_rule_parse(&filter, inputstr);
+	free(inputstr, M_HRL);
+	if (error)
+		return (error);
 
-	switch (uap->op) {
-	case HRL_OP_GET_RULES:
-		error = hrl_get_rules(td, inputstr, &outputsbuf);
+	switch (filter.hr_subject) {
+	case HRL_SUBJECT_PROCESS:
+		error = hrl_get_usage_pid(td, filter.hr_subject_id, &outputsbuf);
 		break;
-	case HRL_OP_GET_RULES_PID:
-		error = hrl_get_rules_pid(td, inputstr, &outputsbuf);
+	case HRL_SUBJECT_USER:
+		error = hrl_get_usage_uid(td, filter.hr_subject_id, &outputsbuf);
 		break;
-	case HRL_OP_ADD_RULE:
-		error = hrl_add_rule(td, inputstr);
+	case HRL_SUBJECT_GROUP:
+		error = hrl_get_usage_gid(td, filter.hr_subject_id, &outputsbuf);
 		break;
-	case HRL_OP_REMOVE_RULE:
-		error = hrl_remove_rule(td, inputstr);
-		break;
-	case HRL_OP_GET_USAGE_PID:
-		error = hrl_get_usage_pid(td, inputstr, &outputsbuf);
+	case HRL_SUBJECT_JAIL:
+		error = hrl_get_usage_jid(td, filter.hr_subject_id, &outputsbuf);
 		break;
-	case HRL_OP_GET_USAGE_UID:
-		error = hrl_get_usage_uid(td, inputstr, &outputsbuf);
-		break;
-	case HRL_OP_GET_USAGE_GID:
-		error = hrl_get_usage_gid(td, inputstr, &outputsbuf);
-		break;
-	case HRL_OP_GET_USAGE_JAILID:
-		error = hrl_get_usage_jid(td, inputstr, &outputsbuf);
-		break;
 	default:
-		error = EINVAL;
+		return (EINVAL);
 	}
 
-	if (outputsbuf != NULL) {
-		sbuf_finish(outputsbuf);
-		if (uap->outbuflen < sbuf_len(outputsbuf) + 1) {
-			error = EFBIG;
-			goto out;
+	error = hrl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen);
+
+	return (error);
+}
+
+static int
+hrl_get_rules_2(struct thread *td, char *inputstr, struct sbuf **outputsbuf)
+{
+	int error = 0, copied = 0;
+	struct hrl_rule *buf, filter;
+	struct hrl_node *node;
+
+	error = hrl_rule_parse(&filter, inputstr);
+	if (error)
+		return (error);
+
+	buf = malloc(HRL_MAX_RULES * sizeof(struct hrl_rule), M_HRL, M_WAITOK);
+
+	/*
+	 * Copy the limits to the temporary buffer.  We cannot
+	 * copy it directly to the userland because of the mutex.
+	 */
+	mtx_lock(&hrl_lock);
+	RB_FOREACH(node, hrl_tree, &hrls) {
+		/*
+		 * XXX: Do not show everything to the client; just the
+		 *      nodes that affect him.
+		 */
+		if (copied >= HRL_MAX_RULES) {
+			/*
+			 * XXX: Hey, what to do now?
+			 */
+			error = EDOOFUS;
+			break;
 		}
-		error = copyout(sbuf_data(outputsbuf), uap->outbufp, sbuf_len(outputsbuf) + 1);
+
+		if (!hrl_rule_matches(&node->hn_rule, &filter))
+			continue;
+
+		*(buf + copied) = node->hn_rule;
+		copied++;
 	}
+	mtx_unlock(&hrl_lock);
+	if (error)
+		goto out;
 
+	*outputsbuf = hrl_rules_to_sbuf(buf, copied);
 out:
-	if (inputstr != NULL)
-		free(inputstr, M_HRL);
-	if (outputsbuf != NULL)
-		sbuf_delete(outputsbuf);
+	free(buf, M_HRL);
+	
+	return (error);
+}
+
+
+int
+hrl_get_rules(struct thread *td, struct hrl_get_rules_args *uap)
+{
+	int error;
+	char *inputstr;
+	struct sbuf *outputsbuf;
+
+	error = hrl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen);
+	if (error)
+		return (error);
+
+	error = hrl_get_rules_2(td, inputstr, &outputsbuf);
+	free(inputstr, M_HRL);
+	if (error)
+		return (error);
+
+	error = hrl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen);
+	return (error);
+}
+
+int
+hrl_get_limits(struct thread *td, struct hrl_get_limits_args *uap)
+{
+	return (EDOOFUS);
+}
+
+int
+hrl_add_rule(struct thread *td, struct hrl_add_rule_args *uap)
+{
+	int error;
+	struct hrl_rule rule;
+	char *inputstr;
+
+	error = priv_check(td, PRIV_HRL_SET);
+	if (error)
+		return (error);
+
+	error = hrl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen);
+	if (error)
+		return (error);
+
+	error = hrl_rule_parse(&rule, inputstr);
+	free(inputstr, M_HRL);
+	if (error)
+		return (error);
+
+	if (rule.hr_subject == HRL_SUBJECT_UNDEFINED ||
+	    rule.hr_subject_id <= 0 ||
+	    rule.hr_resource == HRL_RESOURCE_UNDEFINED ||
+	    rule.hr_action == HRL_ACTION_UNDEFINED ||
+	    rule.hr_amount < 0)
+		return (EINVAL);
+
+	error = hrl_rule_add(&rule);
+
+	return (error);
+}
+
+int
+hrl_remove_rule(struct thread *td, struct hrl_remove_rule_args *uap)
+{
+	int error;
+	struct hrl_rule rule;
+	char *inputstr;
+
+	error = priv_check(td, PRIV_HRL_SET);
+	if (error)
+		return (error);
+
+	error = hrl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen);
+	if (error)
+		return (error);
+
+	error = hrl_rule_parse(&rule, inputstr);
+	free(inputstr, M_HRL);
+	if (error)
+		return (error);
+
+	error = hrl_rule_remove(&rule);
 
 	return (error);
 }

==== //depot/projects/soc2009/trasz_limits/sys/kern/syscalls.c#8 (text+ko) ====

@@ -521,7 +521,11 @@
 	"msgctl",			/* 511 = msgctl */
 	"shmctl",			/* 512 = shmctl */
 	"lpathconf",			/* 513 = lpathconf */
-	"hrl",			/* 514 = hrl */
-	"getloginclass",			/* 515 = getloginclass */
-	"setloginclass",			/* 516 = setloginclass */
+	"getloginclass",			/* 514 = getloginclass */
+	"setloginclass",			/* 515 = setloginclass */
+	"hrl_get_usage",			/* 516 = hrl_get_usage */
+	"hrl_get_rules",			/* 517 = hrl_get_rules */
+	"hrl_get_limits",			/* 518 = hrl_get_limits */
+	"hrl_add_rule",			/* 519 = hrl_add_rule */
+	"hrl_remove_rule",			/* 520 = hrl_remove_rule */
 };

==== //depot/projects/soc2009/trasz_limits/sys/kern/syscalls.master#8 (text+ko) ====

@@ -911,9 +911,13 @@
 512	AUE_SHMCTL	NOSTD	{ int shmctl(int shmid, int cmd, \
 				    struct shmid_ds *buf); }
 513	AUE_LPATHCONF	STD	{ int lpathconf(char *path, int name); }
-514	AUE_NULL	STD	{ int hrl(int op, const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
-515	AUE_NULL	STD	{ int getloginclass(char *namebuf, size_t \
+514	AUE_NULL	STD	{ int getloginclass(char *namebuf, size_t \
 				    namelen); }
-516	AUE_NULL	STD	{ int setloginclass(const char *namebuf); }
+515	AUE_NULL	STD	{ int setloginclass(const char *namebuf); }
+516	AUE_NULL	STD	{ int hrl_get_usage(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+517	AUE_NULL	STD	{ int hrl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+518	AUE_NULL	STD	{ int hrl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+519	AUE_NULL	STD	{ int hrl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+520	AUE_NULL	STD	{ int hrl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
 ; Please copy any additions and changes to the following compatability tables:
 ; sys/compat/freebsd32/syscalls.master

==== //depot/projects/soc2009/trasz_limits/sys/kern/systrace_args.c#8 (text+ko) ====

@@ -3072,19 +3072,8 @@
 		*n_args = 2;
 		break;
 	}
-	/* hrl */
+	/* getloginclass */
 	case 514: {
-		struct hrl_args *p = params;
-		iarg[0] = p->op; /* int */
-		uarg[1] = (intptr_t) p->inbufp; /* const void * */
-		uarg[2] = p->inbuflen; /* size_t */
-		uarg[3] = (intptr_t) p->outbufp; /* void * */
-		uarg[4] = p->outbuflen; /* size_t */
-		*n_args = 5;
-		break;
-	}
-	/* getloginclass */
-	case 515: {
 		struct getloginclass_args *p = params;
 		uarg[0] = (intptr_t) p->namebuf; /* char * */
 		uarg[1] = p->namelen; /* size_t */
@@ -3092,12 +3081,62 @@
 		break;
 	}
 	/* setloginclass */
-	case 516: {
+	case 515: {
 		struct setloginclass_args *p = params;
 		uarg[0] = (intptr_t) p->namebuf; /* const char * */
 		*n_args = 1;
 		break;
 	}
+	/* hrl_get_usage */
+	case 516: {
+		struct hrl_get_usage_args *p = params;
+		uarg[0] = (intptr_t) p->inbufp; /* const void * */
+		uarg[1] = p->inbuflen; /* size_t */
+		uarg[2] = (intptr_t) p->outbufp; /* void * */
+		uarg[3] = p->outbuflen; /* size_t */
+		*n_args = 4;
+		break;
+	}
+	/* hrl_get_rules */
+	case 517: {
+		struct hrl_get_rules_args *p = params;
+		uarg[0] = (intptr_t) p->inbufp; /* const void * */
+		uarg[1] = p->inbuflen; /* size_t */
+		uarg[2] = (intptr_t) p->outbufp; /* void * */
+		uarg[3] = p->outbuflen; /* size_t */
+		*n_args = 4;
+		break;
+	}
+	/* hrl_get_limits */
+	case 518: {
+		struct hrl_get_limits_args *p = params;
+		uarg[0] = (intptr_t) p->inbufp; /* const void * */
+		uarg[1] = p->inbuflen; /* size_t */
+		uarg[2] = (intptr_t) p->outbufp; /* void * */
+		uarg[3] = p->outbuflen; /* size_t */
+		*n_args = 4;
+		break;
+	}
+	/* hrl_add_rule */
+	case 519: {
+		struct hrl_add_rule_args *p = params;
+		uarg[0] = (intptr_t) p->inbufp; /* const void * */
+		uarg[1] = p->inbuflen; /* size_t */
+		uarg[2] = (intptr_t) p->outbufp; /* void * */
+		uarg[3] = p->outbuflen; /* size_t */
+		*n_args = 4;
+		break;
+	}
+	/* hrl_remove_rule */
+	case 520: {
+		struct hrl_remove_rule_args *p = params;
+		uarg[0] = (intptr_t) p->inbufp; /* const void * */
+		uarg[1] = p->inbuflen; /* size_t */
+		uarg[2] = (intptr_t) p->outbufp; /* void * */
+		uarg[3] = p->outbuflen; /* size_t */
+		*n_args = 4;
+		break;
+	}
 	default:
 		*n_args = 0;
 		break;
@@ -8180,46 +8219,119 @@
 			break;
 		};
 		break;
-	/* hrl */
+	/* getloginclass */
 	case 514:
 		switch(ndx) {
 		case 0:
-			p = "int";
+			p = "char *";
 			break;
 		case 1:
+			p = "size_t";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* setloginclass */
+	case 515:
+		switch(ndx) {
+		case 0:
+			p = "const char *";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* hrl_get_usage */
+	case 516:
+		switch(ndx) {
+		case 0:
 			p = "const void *";
 			break;
+		case 1:
+			p = "size_t";
+			break;
 		case 2:
+			p = "void *";
+			break;
+		case 3:
 			p = "size_t";
 			break;
+		default:
+			break;
+		};
+		break;
+	/* hrl_get_rules */
+	case 517:
+		switch(ndx) {
+		case 0:
+			p = "const void *";
+			break;
+		case 1:
+			p = "size_t";
+			break;
+		case 2:
+			p = "void *";
+			break;
 		case 3:
+			p = "size_t";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* hrl_get_limits */
+	case 518:
+		switch(ndx) {
+		case 0:
+			p = "const void *";
+			break;
+		case 1:
+			p = "size_t";
+			break;
+		case 2:
 			p = "void *";
 			break;
-		case 4:
+		case 3:
 			p = "size_t";
 			break;
 		default:
 			break;
 		};
 		break;
-	/* getloginclass */
-	case 515:
+	/* hrl_add_rule */
+	case 519:
 		switch(ndx) {
 		case 0:
-			p = "char *";
+			p = "const void *";
 			break;
 		case 1:
 			p = "size_t";
 			break;
+		case 2:
+			p = "void *";
+			break;
+		case 3:
+			p = "size_t";
+			break;
 		default:
 			break;
 		};
 		break;
-	/* setloginclass */
-	case 516:
+	/* hrl_remove_rule */
+	case 520:
 		switch(ndx) {
 		case 0:
-			p = "const char *";
+			p = "const void *";
+			break;
+		case 1:
+			p = "size_t";
+			break;
+		case 2:
+			p = "void *";
+			break;
+		case 3:
+			p = "size_t";
 			break;
 		default:
 			break;

==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#24 (text+ko) ====

@@ -37,15 +37,6 @@
  * Hierarchical Resource Limits.
  */
 
-#define	HRL_OP_GET_RULES		1
-#define	HRL_OP_GET_RULES_PID		2
-#define	HRL_OP_ADD_RULE			3
-#define	HRL_OP_REMOVE_RULE		4
-#define	HRL_OP_GET_USAGE_PID		5
-#define	HRL_OP_GET_USAGE_UID		6
-#define	HRL_OP_GET_USAGE_GID		7
-#define	HRL_OP_GET_USAGE_JAILID		8
-
 /*
  * 'hrl_rule' describes a single limit configured by the system
  * administrator or a temporary limit set using setrlimit(2).
@@ -146,7 +137,11 @@
 #else /* !_KERNEL */
 
 __BEGIN_DECLS
-int	hrl(int op, const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
+int	hrl_get_usage(const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
+int	hrl_get_rules(const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
+int	hrl_get_limits(const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
+int	hrl_add_rule(const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
+int	hrl_remove_rule(const char *inbufp, size_t inbuflen, char *outbufp, size_t outbuflen);
 __END_DECLS
 
 #endif /* !_KERNEL */

==== //depot/projects/soc2009/trasz_limits/sys/sys/syscall.h#8 (text+ko) ====

@@ -428,7 +428,11 @@
 #define	SYS_msgctl	511
 #define	SYS_shmctl	512
 #define	SYS_lpathconf	513
-#define	SYS_hrl	514
-#define	SYS_getloginclass	515
-#define	SYS_setloginclass	516
-#define	SYS_MAXSYSCALL	517
+#define	SYS_getloginclass	514
+#define	SYS_setloginclass	515
+#define	SYS_hrl_get_usage	516
+#define	SYS_hrl_get_rules	517
+#define	SYS_hrl_get_limits	518
+#define	SYS_hrl_add_rule	519
+#define	SYS_hrl_remove_rule	520
+#define	SYS_MAXSYSCALL	521

==== //depot/projects/soc2009/trasz_limits/sys/sys/syscall.mk#8 (text+ko) ====

@@ -377,6 +377,10 @@
 	msgctl.o \
 	shmctl.o \
 	lpathconf.o \
-	hrl.o \
 	getloginclass.o \
-	setloginclass.o
+	setloginclass.o \
+	hrl_get_usage.o \

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list