From owner-p4-projects@FreeBSD.ORG Thu Jun 25 15:32:10 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 030F4106567E; Thu, 25 Jun 2009 15:32:10 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AC1041065677 for ; Thu, 25 Jun 2009 15:32:09 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8E4CA8FC15 for ; Thu, 25 Jun 2009 15:32:09 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5PFW93x010501 for ; Thu, 25 Jun 2009 15:32:09 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5PFW9ZB010497 for perforce@freebsd.org; Thu, 25 Jun 2009 15:32:09 GMT (envelope-from trasz@freebsd.org) Date: Thu, 25 Jun 2009 15:32:09 GMT Message-Id: <200906251532.n5PFW9ZB010497@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 165167 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Jun 2009 15:32:11 -0000 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