diff options
author | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2015-04-29 10:23:02 +0000 |
---|---|---|
committer | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2015-04-29 10:23:02 +0000 |
commit | 4b5c9cf62f33d8359a272dda846930aaa7c635f8 (patch) | |
tree | 59650c7275c65023f54e8bff435945b07bc2714a /sys/kern/kern_rctl.c | |
parent | da2f98a1cf890caeb84b303d3bd94da2b518785c (diff) | |
download | src-4b5c9cf62f33d8359a272dda846930aaa7c635f8.tar.gz src-4b5c9cf62f33d8359a272dda846930aaa7c635f8.zip |
Add kern.racct.enable tunable and RACCT_DISABLED config option.
The point of this is to be able to add RACCT (with RACCT_DISABLED)
to GENERIC, to avoid having to rebuild the kernel to use rctl(8).
Differential Revision: https://reviews.freebsd.org/D2369
Reviewed by: kib@
MFC after: 1 month
Relnotes: yes
Sponsored by: The FreeBSD Foundation
Notes
Notes:
svn path=/head/; revision=282213
Diffstat (limited to 'sys/kern/kern_rctl.c')
-rw-r--r-- | sys/kern/kern_rctl.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c index 934327a41d82..c43b83df433a 100644 --- a/sys/kern/kern_rctl.c +++ b/sys/kern/kern_rctl.c @@ -225,6 +225,7 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) int64_t available = INT64_MAX; struct ucred *cred = p->p_ucred; + ASSERT_RACCT_ENABLED(); rw_assert(&rctl_lock, RA_LOCKED); resource = rule->rr_resource; @@ -264,6 +265,8 @@ rctl_would_exceed(const struct proc *p, const struct rctl_rule *rule, { int64_t available; + ASSERT_RACCT_ENABLED(); + rw_assert(&rctl_lock, RA_LOCKED); available = rctl_available_resource(p, rule); @@ -283,6 +286,8 @@ rctl_pcpu_available(const struct proc *p) { struct rctl_rule_link *link; int64_t available, minavailable, limit; + ASSERT_RACCT_ENABLED(); + minavailable = INT64_MAX; limit = 0; @@ -334,6 +339,8 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount) static int curtime = 0; static struct timeval lasttime; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -457,6 +464,8 @@ rctl_get_limit(struct proc *p, int resource) struct rctl_rule_link *link; uint64_t amount = UINT64_MAX; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -487,6 +496,8 @@ rctl_get_available(struct proc *p, int resource) minavailable = INT64_MAX; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -521,6 +532,8 @@ static int rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) { + ASSERT_RACCT_ENABLED(); + if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) { if (rule->rr_subject_type != filter->rr_subject_type) return (0); @@ -635,6 +648,7 @@ rctl_racct_add_rule(struct racct *racct, struct rctl_rule *rule) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); rctl_rule_acquire(rule); @@ -652,6 +666,7 @@ rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); rw_assert(&rctl_lock, RA_WLOCKED); @@ -678,6 +693,7 @@ rctl_racct_remove_rules(struct racct *racct, int removed = 0; struct rctl_rule_link *link, *linktmp; + ASSERT_RACCT_ENABLED(); rw_assert(&rctl_lock, RA_WLOCKED); LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) { @@ -696,6 +712,8 @@ static void rctl_rule_acquire_subject(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: @@ -722,6 +740,8 @@ static void rctl_rule_release_subject(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: @@ -749,6 +769,8 @@ rctl_rule_alloc(int flags) { struct rctl_rule *rule; + ASSERT_RACCT_ENABLED(); + rule = uma_zalloc(rctl_rule_zone, flags); if (rule == NULL) return (NULL); @@ -771,6 +793,8 @@ rctl_rule_duplicate(const struct rctl_rule *rule, int flags) { struct rctl_rule *copy; + ASSERT_RACCT_ENABLED(); + copy = uma_zalloc(rctl_rule_zone, flags); if (copy == NULL) return (NULL); @@ -793,6 +817,7 @@ void rctl_rule_acquire(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); refcount_acquire(&rule->rr_refcount); @@ -805,6 +830,7 @@ rctl_rule_free(void *context, int pending) rule = (struct rctl_rule *)context; + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount == 0, ("rule->rr_refcount != 0")); /* @@ -819,6 +845,7 @@ void rctl_rule_release(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); if (refcount_release(&rule->rr_refcount)) { @@ -838,6 +865,8 @@ static int rctl_rule_fully_specified(const struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: return (0); @@ -882,6 +911,8 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep) struct rctl_rule *rule; id_t id; + ASSERT_RACCT_ENABLED(); + rule = rctl_rule_alloc(M_WAITOK); subjectstr = strsep(&rulestr, ":"); @@ -1008,6 +1039,7 @@ rctl_rule_add(struct rctl_rule *rule) struct rctl_rule *rule2; int match; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); /* @@ -1118,6 +1150,8 @@ rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3) struct rctl_rule *filter = (struct rctl_rule *)arg2; int found = 0; + ASSERT_RACCT_ENABLED(); + rw_wlock(&rctl_lock); found += rctl_racct_remove_rules(racct, filter); rw_wunlock(&rctl_lock); @@ -1134,6 +1168,8 @@ rctl_rule_remove(struct rctl_rule *filter) int found = 0; struct proc *p; + ASSERT_RACCT_ENABLED(); + if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && filter->rr_subject.rs_proc != NULL) { p = filter->rr_subject.rs_proc; @@ -1172,6 +1208,8 @@ rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule) { int64_t amount; + ASSERT_RACCT_ENABLED(); + sbuf_printf(sb, "%s:", rctl_subject_type_name(rule->rr_subject_type)); switch (rule->rr_subject_type) { @@ -1231,6 +1269,8 @@ rctl_read_inbuf(char **inputstr, const char *inbufp, size_t inbuflen) int error; char *str; + ASSERT_RACCT_ENABLED(); + if (inbuflen <= 0) return (EINVAL); if (inbuflen > RCTL_MAX_INBUFLEN) @@ -1256,6 +1296,8 @@ rctl_write_outbuf(struct sbuf *outputsbuf, char *outbufp, size_t outbuflen) { int error; + ASSERT_RACCT_ENABLED(); + if (outputsbuf == NULL) return (0); @@ -1277,6 +1319,8 @@ rctl_racct_to_sbuf(struct racct *racct, int sloppy) int64_t amount; struct sbuf *sb; + ASSERT_RACCT_ENABLED(); + sb = sbuf_new_auto(); for (i = 0; i <= RACCT_MAX; i++) { if (sloppy == 0 && RACCT_IS_SLOPPY(i)) @@ -1302,6 +1346,9 @@ sys_rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) struct loginclass *lc; struct prison_racct *prr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_RACCT); if (error != 0) return (error); @@ -1372,6 +1419,8 @@ rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3) struct rctl_rule_link *link; struct sbuf *sb = (struct sbuf *)arg3; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { if (!rctl_rule_matches(link->rrl_rule, filter)) @@ -1393,6 +1442,9 @@ sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) struct rctl_rule_link *link; struct proc *p; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_RULES); if (error != 0) return (error); @@ -1467,6 +1519,9 @@ sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) struct rctl_rule *filter; struct rctl_rule_link *link; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_LIMITS); if (error != 0) return (error); @@ -1538,6 +1593,9 @@ sys_rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) struct rctl_rule *rule; char *inputstr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_ADD_RULE); if (error != 0) return (error); @@ -1580,6 +1638,9 @@ sys_rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap) struct rctl_rule *filter; char *inputstr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_REMOVE_RULE); if (error != 0) return (error); @@ -1616,6 +1677,8 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) struct prison_racct *newprr; LIST_HEAD(, rctl_rule_link) newrules; + ASSERT_RACCT_ENABLED(); + newuip = newcred->cr_ruidinfo; newlc = newcred->cr_loginclass; newprr = newcred->cr_prison->pr_prison_racct; @@ -1756,6 +1819,7 @@ rctl_proc_fork(struct proc *parent, struct proc *child) LIST_INIT(&child->p_racct->r_rule_links); + ASSERT_RACCT_ENABLED(); KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent)); rw_wlock(&rctl_lock); @@ -1809,6 +1873,8 @@ rctl_racct_release(struct racct *racct) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); + rw_wlock(&rctl_lock); while (!LIST_EMPTY(&racct->r_rule_links)) { link = LIST_FIRST(&racct->r_rule_links); @@ -1823,6 +1889,9 @@ static void rctl_init(void) { + if (!racct_enable) + return; + rctl_rule_link_zone = uma_zcreate("rctl_rule_link", sizeof(struct rctl_rule_link), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); |