Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Jun 2009 15:32:09 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 165167 for review
Message-ID:  <200906251532.n5PFW9ZB010497@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165167

Change 165167 by trasz@trasz_victim on 2009/06/25 15:31:59

	Add support for rule addition and removal.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#15 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#11 edit

Differences ...

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

@@ -107,7 +107,6 @@
 
 MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits");
 
-#define notyet
 #if 0
 #undef KASSERT
 #define	KASSERT(exp,msg) do {                                           \
@@ -482,34 +481,7 @@
 	mtx_unlock(&hrl_lock);
 }
 
-/*
- * System calls.
- */
-
-#if 0
 static int
-hrl_check(struct hrl_rule *limits, int nlimits)
-{
-	int i;
-
-	for (i = 0; i < nlimits; i++) {
-		if (limits[i].hr_subject <= 0 || limits[i].hr_subject > HRL_SUBJECT_MAX)
-			return (EINVAL);
-		if (limits[i].hr_per <= 0 || limits[i].hr_per > HRL_SUBJECT_MAX)
-			return (EINVAL);
-		if (limits[i].hr_resource <= 0 || limits[i].hr_resource > HRL_RESOURCE_MAX)
-			return (EINVAL);
-		if (limits[i].hr_action <= 0 || limits[i].hr_action > HRL_ACTION_MAX)
-			return (EINVAL);
-		if (limits[i].hr_amount <= 0)
-			return (EINVAL);
-	}
-
-	return (0);
-}
-#endif
-
-static int
 hrl_get_rules(struct thread *td, void *bufp, size_t buflen)
 {
 	int error = 0, copied = 0;
@@ -558,6 +530,113 @@
 }
 
 static int
+hrl_rule_add(struct hrl_rule *rule)
+{
+	struct hrl_node *node, *existing;
+
+	node = uma_zalloc(hrl_zone, M_WAITOK);
+	node->hn_rule = *rule;
+
+	mtx_lock(&hrl_lock);
+	existing = RB_INSERT(hrl_tree, &hrls, node);
+	if (existing != NULL)
+		existing->hn_rule.hr_amount = rule->hr_amount;
+	mtx_unlock(&hrl_lock);
+
+	if (existing != NULL)
+		uma_zfree(hrl_zone, node);
+
+	return (0);
+}
+
+static int
+hrl_rule_remove(struct hrl_rule *rule)
+{
+	struct hrl_node searched, *node;
+
+	node = uma_zalloc(hrl_zone, M_WAITOK);
+	searched.hn_rule = *rule;
+
+	mtx_lock(&hrl_lock);
+	node = RB_FIND(hrl_tree, &hrls, &searched);
+	if (node != NULL) {
+		node = RB_REMOVE(hrl_tree, &hrls, node);
+		KASSERT(node != NULL, ("hrl_adjust: node removal failed"));
+	}
+	mtx_unlock(&hrl_lock);
+
+	uma_zfree(hrl_zone, node);
+
+	return (0);
+}
+
+static int
+hrl_rule_check(struct hrl_rule *rule)
+{
+
+	if (rule.hr_subject <= 0 || rule.hr_subject > HRL_SUBJECT_MAX)
+		return (EINVAL);
+	if (rule.hr_per <= 0 || rule.hr_per > HRL_SUBJECT_MAX)
+		return (EINVAL);
+	if (rule.hr_resource <= 0 || rule.hr_resource > HRL_RESOURCE_MAX)
+		return (EINVAL);
+	if (rule.hr_action <= 0 || rule.hr_action > HRL_ACTION_MAX)
+		return (EINVAL);
+	if (rule.hr_amount <= 0)
+		return (EINVAL);
+
+	return (0);
+}
+
+static int
+hrl_add_rule(struct thread *td, const void *bufp, size_t buflen)
+{
+	int error;
+	struct hrl_rule rule;
+
+	error = priv_check(td, PRIV_HRL_SET);
+	if (error)
+		return (error);
+
+	if (buflen != sizeof(rule))
+		return (EINVAL);
+
+	error = copyin(bufp, &rule, buflen);
+	if (error)
+		return (error);
+
+	error = hrl_rule_check(&rule);
+	if (error)
+		return (error);
+
+	error = hrl_rule_add(&rule);
+
+	return (0);
+}
+
+static int
+hrl_remove_rule(struct thread *td, const void *bufp, size_t buflen)
+{
+	int error;
+	struct hrl_rule rule;
+
+	error = priv_check(td, PRIV_HRL_SET);
+	if (error)
+		return (error);
+
+	if (buflen != sizeof(rule))
+		return (EINVAL);
+
+	error = copyin(bufp, &rule, buflen);
+	if (error)
+		return (error);
+
+	error = hrl_rule_remove(&rule);
+
+	return (0);
+}
+
+static int
 hrl_get_acc_pid(struct thread *td, id_t pid, void *bufp, size_t buflen)
 {
 	int error;
@@ -643,6 +722,10 @@
 	switch (uap->op) {
 	case HRL_OP_GET_RULES:
 		return (hrl_get_rules(td, uap->outbufp, uap->outbuflen));
+	case HRL_OP_ADD_RULE:
+		return (hrl_add_rule(td, uap->inbufp, uap->inbuflen));
+	case HRL_OP_REMOVE_RULE:
+		return (hrl_remove_rule(td, uap->inbufp, uap->inbuflen));
 	case HRL_OP_GET_ACC_PID:
 		return (hrl_get_acc_pid(td, id, uap->outbufp, uap->outbuflen));
 	case HRL_OP_GET_ACC_UID:

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

@@ -93,6 +93,8 @@
 #define	HRL_MAX_LIMITS		1024
 
 #define	HRL_OP_GET_RULES	1
+#define	HRL_OP_ADD_RULE		6
+#define	HRL_OP_REMOVE_RULE	7
 #define	HRL_OP_GET_ACC_PID	2
 #define	HRL_OP_GET_ACC_UID	3
 #define	HRL_OP_GET_ACC_GID	4



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906251532.n5PFW9ZB010497>