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>