Date: Sun, 2 Aug 2009 13:40:26 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 166928 for review Message-ID: <200908021340.n72DeQ0i005205@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166928 Change 166928 by trasz@trasz_anger on 2009/08/02 13:40:05 Some changes in preparation for per-class limits. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#38 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#38 (text+ko) ==== @@ -718,14 +718,18 @@ again: mtx_lock(&hrl_lock); LIST_FOREACH_SAFE(limit, limits_head, hl_next, limittmp) { - if (hrl_rule_matches(limit->hl_rule, filter)) { - LIST_REMOVE(limit, hl_next); - mtx_unlock(&hrl_lock); - hrl_rule_release(limit->hl_rule); - uma_zfree(hrl_limit_zone, limit); - removed++; - goto again; - } + if (!hrl_rule_matches(limit->hl_rule, filter)) + continue; + + LIST_REMOVE(limit, hl_next); + mtx_unlock(&hrl_lock); + hrl_rule_release(limit->hl_rule); + if (limit->hl_rule->hr_subject == HRL_SUBJECT_LOGINCLASS && + limit->hl_rule->hr_subject_id != HRL_SUBJECT_ID_UNDEFINED) + loginclass_release((struct loginclass *)(long)limit->hl_rule->hr_subject_id); + uma_zfree(hrl_limit_zone, limit); + removed++; + goto again; } mtx_unlock(&hrl_lock); return (removed); @@ -804,6 +808,99 @@ return (1); } +static struct hrl_rule * +hrl_rule_from_string(char *rulestr) +{ + int error; + char *subjectstr, *subject_idstr, *resourcestr, *actionstr, + *amountstr, *perstr; + struct loginclass *lc; + struct hrl_rule *rule; + + rule = hrl_rule_alloc(); + + subjectstr = strsep(&rulestr, ":"); + subject_idstr = strsep(&rulestr, ":"); + resourcestr = strsep(&rulestr, ":"); + actionstr = strsep(&rulestr, "=/"); + amountstr = strsep(&rulestr, "/"); + perstr = rulestr; + + if (subjectstr == NULL || subjectstr[0] == '\0') + rule->hr_subject = HRL_SUBJECT_UNDEFINED; + else { + error = str2value(subjectstr, &rule->hr_subject, subjectnames); + if (error) + goto out; + } + + /* + * Login classes don't have any ID. Instead, we just put a pointer + * to the 'struct loginclass' into the hr_subject_id field. + */ + if (rule->hr_subject == HRL_SUBJECT_LOGINCLASS) { + if (subject_idstr == NULL || subject_idstr[0] == '\0') + goto out; + + lc = loginclass_find(subject_idstr); + rule->hr_subject_id = (long)lc; + } else { + if (subject_idstr == NULL || subject_idstr[0] == '\0') + rule->hr_subject_id = HRL_SUBJECT_ID_UNDEFINED; + else { + error = str2id(subject_idstr, &rule->hr_subject_id); + if (error) + goto out; + } + } + + if (resourcestr == NULL || resourcestr[0] == '\0') + rule->hr_resource = HRL_RESOURCE_UNDEFINED; + else { + error = str2value(resourcestr, &rule->hr_resource, + resourcenames); + if (error) + goto out; + } + + if (actionstr == NULL || actionstr[0] == '\0') + rule->hr_action = HRL_ACTION_UNDEFINED; + else { + error = str2value(actionstr, &rule->hr_action, actionnames); + if (error) + goto out; + } + + if (amountstr == NULL || amountstr[0] == '\0') + rule->hr_amount = -1; + else { + error = str2int64(amountstr, &rule->hr_amount); + if (error) + goto out; + } + + if (perstr == NULL || perstr[0] == '\0') + rule->hr_per = rule->hr_subject; + else { + error = str2value(perstr, &rule->hr_per, subjectnames); + if (error) + goto out; + } + + if (rule->hr_subject_id != HRL_SUBJECT_ID_UNDEFINED && + rule->hr_subject == HRL_SUBJECT_UNDEFINED) + goto out; + +out: + if (error) { + hrl_rule_release(rule); + return (NULL); + } + + return (rule); +} + + /* * Link a rule with subjects to which it applies. */ @@ -963,93 +1060,34 @@ return (ESRCH); } -static int -hrl_rule_parse(struct hrl_rule *rule, char *rulestr) -{ - int error; - char *subjectstr, *subject_idstr, *resourcestr, *actionstr, - *amountstr, *perstr; - - subjectstr = strsep(&rulestr, ":"); - subject_idstr = strsep(&rulestr, ":"); - resourcestr = strsep(&rulestr, ":"); - actionstr = strsep(&rulestr, "=/"); - amountstr = strsep(&rulestr, "/"); - perstr = rulestr; - - if (subjectstr == NULL || subjectstr[0] == '\0') - rule->hr_subject = HRL_SUBJECT_UNDEFINED; - else { - error = str2value(subjectstr, &rule->hr_subject, subjectnames); - if (error) - return (EINVAL); - } - - if (subject_idstr == NULL || subject_idstr[0] == '\0') - rule->hr_subject_id = HRL_SUBJECT_ID_UNDEFINED; - else { - error = str2id(subject_idstr, &rule->hr_subject_id); - if (error) - return (EINVAL); - } - - if (resourcestr == NULL || resourcestr[0] == '\0') - rule->hr_resource = HRL_RESOURCE_UNDEFINED; - else { - error = str2value(resourcestr, &rule->hr_resource, - resourcenames); - if (error) - return (EINVAL); - } - - if (actionstr == NULL || actionstr[0] == '\0') - rule->hr_action = HRL_ACTION_UNDEFINED; - else { - error = str2value(actionstr, &rule->hr_action, actionnames); - if (error) - return (EINVAL); - } - - if (amountstr == NULL || amountstr[0] == '\0') - rule->hr_amount = -1; - else { - error = str2int64(amountstr, &rule->hr_amount); - if (error) - return (EINVAL); - } - - if (perstr == NULL || perstr[0] == '\0') - rule->hr_per = rule->hr_subject; - else { - error = str2value(perstr, &rule->hr_per, subjectnames); - if (error) - return (EINVAL); - } - - if (rule->hr_subject_id != HRL_SUBJECT_ID_UNDEFINED && - rule->hr_subject == HRL_SUBJECT_UNDEFINED) - return (EINVAL); - - return (0); -} - static struct sbuf * -hrl_rules_to_sbuf(struct hrl_rule *usage, int nrules) +hrl_rules_to_sbuf(struct hrl_rule *rules, int nrules) { int i; struct sbuf *sb; sb = sbuf_new_auto(); for (i = 0; i < nrules; i++) { - sbuf_printf(sb, "%s:%d:%s:%s=%jd", - hrl_subject_name(usage[i].hr_subject), - (int)usage[i].hr_subject_id, - hrl_resource_name(usage[i].hr_resource), - hrl_action_name(usage[i].hr_action), - usage[i].hr_amount); - if (usage[i].hr_per != usage[i].hr_subject) + if (rules[i].hr_subject == HRL_SUBJECT_LOGINCLASS) { + KASSERT(rules[i].hr_subject_id != HRL_SUBJECT_ID_UNDEFINED, + ("rules[i].hr_subject_id != HRL_SUBJECT_ID_UNDEFINED")); + sbuf_printf(sb, "%s:%s:%s:%s=%jd", + hrl_subject_name(rules[i].hr_subject), + ((struct loginclass *)(long)rules[i].hr_subject_id)->lc_name, + hrl_resource_name(rules[i].hr_resource), + hrl_action_name(rules[i].hr_action), + rules[i].hr_amount); + } else { + sbuf_printf(sb, "%s:%d:%s:%s=%jd", + hrl_subject_name(rules[i].hr_subject), + (int)rules[i].hr_subject_id, + hrl_resource_name(rules[i].hr_resource), + hrl_action_name(rules[i].hr_action), + rules[i].hr_amount); + } + if (rules[i].hr_per != rules[i].hr_subject) sbuf_printf(sb, "/%s,", - hrl_subject_name(usage[i].hr_per)); + hrl_subject_name(rules[i].hr_per)); else sbuf_printf(sb, ","); } @@ -1191,35 +1229,35 @@ { int error; char *inputstr; - struct hrl_rule filter; + struct hrl_rule *filter; struct sbuf *outputsbuf = NULL; error = hrl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); if (error) return (error); - error = hrl_rule_parse(&filter, inputstr); + filter = hrl_rule_from_string(inputstr); free(inputstr, M_HRL); - if (error) - return (error); + if (filter == NULL) + return (EINVAL); - switch (filter.hr_subject) { + switch (filter->hr_subject) { case HRL_SUBJECT_PROCESS: - error = hrl_get_usage_pid(td, filter.hr_subject_id, &outputsbuf); + error = hrl_get_usage_pid(td, filter->hr_subject_id, &outputsbuf); break; case HRL_SUBJECT_USER: - error = hrl_get_usage_uid(td, filter.hr_subject_id, &outputsbuf); + error = hrl_get_usage_uid(td, filter->hr_subject_id, &outputsbuf); break; case HRL_SUBJECT_GROUP: - error = hrl_get_usage_gid(td, filter.hr_subject_id, &outputsbuf); + error = hrl_get_usage_gid(td, filter->hr_subject_id, &outputsbuf); break; case HRL_SUBJECT_JAIL: - error = hrl_get_usage_jid(td, filter.hr_subject_id, &outputsbuf); + error = hrl_get_usage_jid(td, filter->hr_subject_id, &outputsbuf); break; default: - return (EINVAL); + error = EINVAL; } - + hrl_rule_release(filter); if (error) return (error); @@ -1234,7 +1272,7 @@ int error, copied, maxcopied = HRL_MAX_RULES; char *inputstr; struct sbuf *outputsbuf; - struct hrl_rule filter, *buf; + struct hrl_rule *filter, *buf; struct hrl_limit *limit; struct proc *p; @@ -1242,10 +1280,10 @@ if (error) return (error); - error = hrl_rule_parse(&filter, inputstr); + filter = hrl_rule_from_string(inputstr); free(inputstr, M_HRL); - if (error) - return (error); + if (filter == NULL) + return (EINVAL); buf = malloc(HRL_MAX_RULES * sizeof(struct hrl_rule), M_HRL, M_WAITOK); @@ -1263,7 +1301,7 @@ free(buf, M_HRL); goto again; } - if (!hrl_rule_matches(limit->hl_rule, &filter)) + if (!hrl_rule_matches(limit->hl_rule, filter)) continue; *(buf + copied) = *limit->hl_rule; copied++; @@ -1282,6 +1320,7 @@ error = hrl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen); out: + hrl_rule_release(filter); free(buf, M_HRL); return (error); } @@ -1292,7 +1331,7 @@ int error, copied, maxcopied = HRL_MAX_RULES; char *inputstr; struct sbuf *outputsbuf; - struct hrl_rule filter, *buf; + struct hrl_rule *filter, *buf; struct hrl_limit *limit; struct proc *p; @@ -1300,25 +1339,31 @@ if (error) return (error); - error = hrl_rule_parse(&filter, inputstr); + filter = hrl_rule_from_string(inputstr); free(inputstr, M_HRL); - if (error) - return (error); + if (filter == NULL) + return (EINVAL); - if (filter.hr_subject == HRL_SUBJECT_UNDEFINED) - return (EINVAL); + if (filter->hr_subject == HRL_SUBJECT_UNDEFINED) { + error = EINVAL; + goto out; + } - if (filter.hr_subject_id == HRL_SUBJECT_ID_UNDEFINED) - return (EINVAL); + if (filter->hr_subject_id == HRL_SUBJECT_ID_UNDEFINED) { + error = EINVAL; + goto out; + } - if (filter.hr_subject != HRL_SUBJECT_PROCESS) - return (EOPNOTSUPP); + if (filter->hr_subject != HRL_SUBJECT_PROCESS) { + error = EOPNOTSUPP; + goto out; + } again: buf = malloc(maxcopied * sizeof(*buf), M_HRL, M_WAITOK); copied = 0; - p = pfind(filter.hr_subject_id); + p = pfind(filter->hr_subject_id); if (p == NULL) { error = ESRCH; goto out; @@ -1332,7 +1377,7 @@ free(buf, M_HRL); goto again; } - if (!hrl_rule_matches(limit->hl_rule, &filter)) + if (!hrl_rule_matches(limit->hl_rule, filter)) continue; *(buf + copied) = *limit->hl_rule; copied++; @@ -1346,6 +1391,7 @@ error = hrl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen); out: + hrl_rule_release(filter); free(buf, M_HRL); return (error); } @@ -1365,12 +1411,12 @@ if (error) return (error); - rule = hrl_rule_alloc(); - - error = hrl_rule_parse(rule, inputstr); + rule = hrl_rule_from_string(inputstr); free(inputstr, M_HRL); - if (error) + if (rule == NULL) { + error = EINVAL; goto out; + } if (!hrl_rule_fully_specified(rule)) { error = EINVAL; @@ -1388,7 +1434,7 @@ hrl_remove_rule(struct thread *td, struct hrl_remove_rule_args *uap) { int error; - struct hrl_rule filter; + struct hrl_rule *filter; char *inputstr; error = priv_check(td, PRIV_HRL_SET); @@ -1399,12 +1445,13 @@ if (error) return (error); - error = hrl_rule_parse(&filter, inputstr); + filter = hrl_rule_from_string(inputstr); free(inputstr, M_HRL); - if (error) - return (error); + if (filter == NULL) + return (EINVAL); - error = hrl_rule_remove(&filter); + error = hrl_rule_remove(filter); + hrl_rule_release(filter); return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908021340.n72DeQ0i005205>
