PERFORCE change 166928 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Sun Aug 2 13:40:27 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166928
Change 166928 by trasz at 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);
}
More information about the p4-projects
mailing list