Lines Matching full:rule

124  * 'rctl_rule_link' connects a rule with every racct it's related to.
125 * For example, rule 'user:X:openfiles:deny=N/process' is linked
218 static int rctl_rule_fully_specified(const struct rctl_rule *rule);
219 static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule);
331 rctl_proc_rule_to_racct(const struct proc *p, const struct rctl_rule *rule) in rctl_proc_rule_to_racct() argument
338 switch (rule->rr_per) { in rctl_proc_rule_to_racct()
348 panic("%s: unknown per %d", __func__, rule->rr_per); in rctl_proc_rule_to_racct()
354 * hitting 'rule'.
357 rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) in rctl_available_resource() argument
365 racct = rctl_proc_rule_to_racct(p, rule); in rctl_available_resource()
366 available = rule->rr_amount - racct->r_resources[rule->rr_resource]; in rctl_available_resource()
381 struct rctl_rule *rule; in rctl_throttle_decay() local
391 rule = link->rrl_rule; in rctl_throttle_decay()
393 if (rule->rr_resource != resource) in rctl_throttle_decay()
395 if (rule->rr_action != RCTL_ACTION_THROTTLE) in rctl_throttle_decay()
398 if (rule->rr_amount < minavailable) in rctl_throttle_decay()
399 minavailable = rule->rr_amount; in rctl_throttle_decay()
407 * if we changed the rule lowering the allowed amount, it could in rctl_throttle_decay()
424 struct rctl_rule *rule; in rctl_pcpu_available() local
435 rule = link->rrl_rule; in rctl_pcpu_available()
436 if (rule->rr_resource != RACCT_PCTCPU) in rctl_pcpu_available()
438 if (rule->rr_action != RCTL_ACTION_DENY) in rctl_pcpu_available()
440 available = rctl_available_resource(p, rule); in rctl_pcpu_available()
443 limit = rule->rr_amount; in rctl_pcpu_available()
498 struct rctl_rule *rule; in rctl_enforce() local
510 * There may be more than one matching rule; go through all of them. in rctl_enforce()
514 rule = link->rrl_rule; in rctl_enforce()
515 if (rule->rr_resource != resource) in rctl_enforce()
518 available = rctl_available_resource(p, rule); in rctl_enforce()
524 switch (rule->rr_action) { in rctl_enforce()
540 * Ignore this rule for now; it will be processed just in rctl_enforce()
556 rctl_rule_to_sbuf(&sb, rule); in rctl_enforce()
558 printf("rctl: rule \"%s\" matched by pid %d " in rctl_enforce()
583 sbuf_cat(&sb, "rule="); in rctl_enforce()
584 rctl_rule_to_sbuf(&sb, rule); in rctl_enforce()
589 devctl_notify("RCTL", "rule", "matched", in rctl_enforce()
599 if (rule->rr_amount == 0) { in rctl_enforce()
617 * rule->rr_amount; in rctl_enforce()
625 if (sleep_ms < rctl_throttle_min * rule->rr_amount) in rctl_enforce()
626 sleep_ms = rctl_throttle_min * rule->rr_amount; in rctl_enforce()
633 * four times as much for hitting the same rule. The in rctl_enforce()
638 sleep_ratio = -available / rule->rr_amount; in rctl_enforce()
648 sleep_ms /= rule->rr_amount; in rctl_enforce()
656 rule->rr_amount, (uintmax_t)sleep_ms, in rctl_enforce()
671 KASSERT(rule->rr_action > 0 && in rctl_enforce()
672 rule->rr_action <= RCTL_ACTION_SIGNAL_MAX, in rctl_enforce()
674 rule->rr_action)); in rctl_enforce()
680 kern_psignal(p, rule->rr_action); in rctl_enforce()
700 struct rctl_rule *rule; in rctl_get_limit() local
708 * There may be more than one matching rule; go through all of them. in rctl_get_limit()
712 rule = link->rrl_rule; in rctl_get_limit()
713 if (rule->rr_resource != resource) in rctl_get_limit()
715 if (rule->rr_action != RCTL_ACTION_DENY) in rctl_get_limit()
717 if (rule->rr_amount < amount) in rctl_get_limit()
718 amount = rule->rr_amount; in rctl_get_limit()
727 struct rctl_rule *rule; in rctl_get_available() local
737 * There may be more than one matching rule; go through all of them. in rctl_get_available()
741 rule = link->rrl_rule; in rctl_get_available()
742 if (rule->rr_resource != resource) in rctl_get_available()
744 if (rule->rr_action != RCTL_ACTION_DENY) in rctl_get_available()
746 available = rctl_available_resource(p, rule); in rctl_get_available()
764 rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) in rctl_rule_matches() argument
770 if (rule->rr_subject_type != filter->rr_subject_type) in rctl_rule_matches()
776 rule->rr_subject.rs_proc != in rctl_rule_matches()
782 rule->rr_subject.rs_uip != in rctl_rule_matches()
788 rule->rr_subject.rs_loginclass != in rctl_rule_matches()
794 rule->rr_subject.rs_prison_racct != in rctl_rule_matches()
805 if (rule->rr_resource != filter->rr_resource) in rctl_rule_matches()
810 if (rule->rr_action != filter->rr_action) in rctl_rule_matches()
815 if (rule->rr_amount != filter->rr_amount) in rctl_rule_matches()
820 if (rule->rr_per != filter->rr_per) in rctl_rule_matches()
879 * Connect the rule to the racct, increasing refcount for the rule.
882 rctl_racct_add_rule(struct racct *racct, struct rctl_rule *rule) in rctl_racct_add_rule() argument
887 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); in rctl_racct_add_rule()
889 rctl_rule_acquire(rule); in rctl_racct_add_rule()
891 link->rrl_rule = rule; in rctl_racct_add_rule()
900 rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule) in rctl_racct_add_rule_locked() argument
905 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); in rctl_racct_add_rule_locked()
911 rctl_rule_acquire(rule); in rctl_racct_add_rule_locked()
912 link->rrl_rule = rule; in rctl_racct_add_rule_locked()
948 rctl_rule_acquire_subject(struct rctl_rule *rule) in rctl_rule_acquire_subject() argument
953 switch (rule->rr_subject_type) { in rctl_rule_acquire_subject()
958 if (rule->rr_subject.rs_prison_racct != NULL) in rctl_rule_acquire_subject()
959 prison_racct_hold(rule->rr_subject.rs_prison_racct); in rctl_rule_acquire_subject()
962 if (rule->rr_subject.rs_uip != NULL) in rctl_rule_acquire_subject()
963 uihold(rule->rr_subject.rs_uip); in rctl_rule_acquire_subject()
966 if (rule->rr_subject.rs_loginclass != NULL) in rctl_rule_acquire_subject()
967 loginclass_hold(rule->rr_subject.rs_loginclass); in rctl_rule_acquire_subject()
971 rule->rr_subject_type); in rctl_rule_acquire_subject()
976 rctl_rule_release_subject(struct rctl_rule *rule) in rctl_rule_release_subject() argument
981 switch (rule->rr_subject_type) { in rctl_rule_release_subject()
986 if (rule->rr_subject.rs_prison_racct != NULL) in rctl_rule_release_subject()
987 prison_racct_free(rule->rr_subject.rs_prison_racct); in rctl_rule_release_subject()
990 if (rule->rr_subject.rs_uip != NULL) in rctl_rule_release_subject()
991 uifree(rule->rr_subject.rs_uip); in rctl_rule_release_subject()
994 if (rule->rr_subject.rs_loginclass != NULL) in rctl_rule_release_subject()
995 loginclass_free(rule->rr_subject.rs_loginclass); in rctl_rule_release_subject()
999 rule->rr_subject_type); in rctl_rule_release_subject()
1006 struct rctl_rule *rule; in rctl_rule_alloc() local
1010 rule = uma_zalloc(rctl_rule_zone, flags); in rctl_rule_alloc()
1011 if (rule == NULL) in rctl_rule_alloc()
1013 rule->rr_subject_type = RCTL_SUBJECT_TYPE_UNDEFINED; in rctl_rule_alloc()
1014 rule->rr_subject.rs_proc = NULL; in rctl_rule_alloc()
1015 rule->rr_subject.rs_uip = NULL; in rctl_rule_alloc()
1016 rule->rr_subject.rs_loginclass = NULL; in rctl_rule_alloc()
1017 rule->rr_subject.rs_prison_racct = NULL; in rctl_rule_alloc()
1018 rule->rr_per = RCTL_SUBJECT_TYPE_UNDEFINED; in rctl_rule_alloc()
1019 rule->rr_resource = RACCT_UNDEFINED; in rctl_rule_alloc()
1020 rule->rr_action = RCTL_ACTION_UNDEFINED; in rctl_rule_alloc()
1021 rule->rr_amount = RCTL_AMOUNT_UNDEFINED; in rctl_rule_alloc()
1022 refcount_init(&rule->rr_refcount, 1); in rctl_rule_alloc()
1024 return (rule); in rctl_rule_alloc()
1028 rctl_rule_duplicate(const struct rctl_rule *rule, int flags) in rctl_rule_duplicate() argument
1037 copy->rr_subject_type = rule->rr_subject_type; in rctl_rule_duplicate()
1038 copy->rr_subject.rs_proc = rule->rr_subject.rs_proc; in rctl_rule_duplicate()
1039 copy->rr_subject.rs_uip = rule->rr_subject.rs_uip; in rctl_rule_duplicate()
1040 copy->rr_subject.rs_loginclass = rule->rr_subject.rs_loginclass; in rctl_rule_duplicate()
1041 copy->rr_subject.rs_prison_racct = rule->rr_subject.rs_prison_racct; in rctl_rule_duplicate()
1042 copy->rr_per = rule->rr_per; in rctl_rule_duplicate()
1043 copy->rr_resource = rule->rr_resource; in rctl_rule_duplicate()
1044 copy->rr_action = rule->rr_action; in rctl_rule_duplicate()
1045 copy->rr_amount = rule->rr_amount; in rctl_rule_duplicate()
1053 rctl_rule_acquire(struct rctl_rule *rule) in rctl_rule_acquire() argument
1057 KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); in rctl_rule_acquire()
1059 refcount_acquire(&rule->rr_refcount); in rctl_rule_acquire()
1065 struct rctl_rule *rule; in rctl_rule_free() local
1067 rule = (struct rctl_rule *)context; in rctl_rule_free()
1070 KASSERT(rule->rr_refcount == 0, ("rule->rr_refcount != 0")); in rctl_rule_free()
1073 * We don't need locking here; rule is guaranteed to be inaccessible. in rctl_rule_free()
1076 rctl_rule_release_subject(rule); in rctl_rule_free()
1077 uma_zfree(rctl_rule_zone, rule); in rctl_rule_free()
1081 rctl_rule_release(struct rctl_rule *rule) in rctl_rule_release() argument
1085 KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); in rctl_rule_release()
1087 if (refcount_release(&rule->rr_refcount)) { in rctl_rule_release()
1095 TASK_INIT(&rule->rr_task, 0, rctl_rule_free, rule); in rctl_rule_release()
1096 taskqueue_enqueue(taskqueue_thread, &rule->rr_task); in rctl_rule_release()
1101 rctl_rule_fully_specified(const struct rctl_rule *rule) in rctl_rule_fully_specified() argument
1106 switch (rule->rr_subject_type) { in rctl_rule_fully_specified()
1110 if (rule->rr_subject.rs_proc == NULL) in rctl_rule_fully_specified()
1114 if (rule->rr_subject.rs_uip == NULL) in rctl_rule_fully_specified()
1118 if (rule->rr_subject.rs_loginclass == NULL) in rctl_rule_fully_specified()
1122 if (rule->rr_subject.rs_prison_racct == NULL) in rctl_rule_fully_specified()
1127 rule->rr_subject_type); in rctl_rule_fully_specified()
1129 if (rule->rr_resource == RACCT_UNDEFINED) in rctl_rule_fully_specified()
1131 if (rule->rr_action == RCTL_ACTION_UNDEFINED) in rctl_rule_fully_specified()
1133 if (rule->rr_amount == RCTL_AMOUNT_UNDEFINED) in rctl_rule_fully_specified()
1135 if (rule->rr_per == RCTL_SUBJECT_TYPE_UNDEFINED) in rctl_rule_fully_specified()
1144 struct rctl_rule *rule; in rctl_string_to_rule() local
1152 rule = rctl_rule_alloc(M_WAITOK); in rctl_string_to_rule()
1162 rule->rr_subject_type = RCTL_SUBJECT_TYPE_UNDEFINED; in rctl_string_to_rule()
1164 error = str2value(subjectstr, &rule->rr_subject_type, subjectnames); in rctl_string_to_rule()
1170 rule->rr_subject.rs_proc = NULL; in rctl_string_to_rule()
1171 rule->rr_subject.rs_uip = NULL; in rctl_string_to_rule()
1172 rule->rr_subject.rs_loginclass = NULL; in rctl_string_to_rule()
1173 rule->rr_subject.rs_prison_racct = NULL; in rctl_string_to_rule()
1175 switch (rule->rr_subject_type) { in rctl_string_to_rule()
1184 rule->rr_subject.rs_proc = pfind(id); in rctl_string_to_rule()
1185 if (rule->rr_subject.rs_proc == NULL) { in rctl_string_to_rule()
1189 PROC_UNLOCK(rule->rr_subject.rs_proc); in rctl_string_to_rule()
1195 rule->rr_subject.rs_uip = uifind(id); in rctl_string_to_rule()
1198 rule->rr_subject.rs_loginclass = in rctl_string_to_rule()
1200 if (rule->rr_subject.rs_loginclass == NULL) { in rctl_string_to_rule()
1206 rule->rr_subject.rs_prison_racct = in rctl_string_to_rule()
1208 if (rule->rr_subject.rs_prison_racct == NULL) { in rctl_string_to_rule()
1215 rule->rr_subject_type); in rctl_string_to_rule()
1220 rule->rr_resource = RACCT_UNDEFINED; in rctl_string_to_rule()
1222 error = str2value(resourcestr, &rule->rr_resource, in rctl_string_to_rule()
1229 rule->rr_action = RCTL_ACTION_UNDEFINED; in rctl_string_to_rule()
1231 error = str2value(actionstr, &rule->rr_action, actionnames); in rctl_string_to_rule()
1237 rule->rr_amount = RCTL_AMOUNT_UNDEFINED; in rctl_string_to_rule()
1239 error = str2int64(amountstr, &rule->rr_amount); in rctl_string_to_rule()
1242 if (RACCT_IS_IN_MILLIONS(rule->rr_resource)) { in rctl_string_to_rule()
1243 if (rule->rr_amount > INT64_MAX / 1000000) { in rctl_string_to_rule()
1247 rule->rr_amount *= 1000000; in rctl_string_to_rule()
1252 rule->rr_per = RCTL_SUBJECT_TYPE_UNDEFINED; in rctl_string_to_rule()
1254 error = str2value(perstr, &rule->rr_per, subjectnames); in rctl_string_to_rule()
1261 *rulep = rule; in rctl_string_to_rule()
1263 rctl_rule_release(rule); in rctl_string_to_rule()
1269 * Link a rule with all the subjects it applies to.
1272 rctl_rule_add(struct rctl_rule *rule) in rctl_rule_add() argument
1284 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); in rctl_rule_add()
1287 * Some rules just don't make sense, like "deny" rule for an undeniable in rctl_rule_add()
1292 if (rule->rr_action == RCTL_ACTION_DENY && in rctl_rule_add()
1293 !RACCT_IS_DENIABLE(rule->rr_resource) && in rctl_rule_add()
1294 rule->rr_resource != RACCT_RSS && in rctl_rule_add()
1295 rule->rr_resource != RACCT_PCTCPU) { in rctl_rule_add()
1299 if (rule->rr_action == RCTL_ACTION_THROTTLE && in rctl_rule_add()
1300 !RACCT_IS_DECAYING(rule->rr_resource)) { in rctl_rule_add()
1304 if (rule->rr_action == RCTL_ACTION_THROTTLE && in rctl_rule_add()
1305 rule->rr_resource == RACCT_PCTCPU) { in rctl_rule_add()
1309 if (rule->rr_per == RCTL_SUBJECT_TYPE_PROCESS && in rctl_rule_add()
1310 RACCT_IS_SLOPPY(rule->rr_resource)) { in rctl_rule_add()
1318 if (rule->rr_action == RCTL_ACTION_DENY) { in rctl_rule_add()
1319 rule2 = rctl_rule_duplicate(rule, M_WAITOK); in rctl_rule_add()
1324 rctl_rule_remove(rule); in rctl_rule_add()
1326 switch (rule->rr_subject_type) { in rctl_rule_add()
1328 p = rule->rr_subject.rs_proc; in rctl_rule_add()
1331 rctl_racct_add_rule(p->p_racct, rule); in rctl_rule_add()
1333 * In case of per-process rule, we don't have anything more in rctl_rule_add()
1339 uip = rule->rr_subject.rs_uip; in rctl_rule_add()
1341 rctl_racct_add_rule(uip->ui_racct, rule); in rctl_rule_add()
1345 lc = rule->rr_subject.rs_loginclass; in rctl_rule_add()
1347 rctl_racct_add_rule(lc->lc_racct, rule); in rctl_rule_add()
1351 prr = rule->rr_subject.rs_prison_racct; in rctl_rule_add()
1353 rctl_racct_add_rule(prr->prr_racct, rule); in rctl_rule_add()
1358 rule->rr_subject_type); in rctl_rule_add()
1362 * Now go through all the processes and add the new rule to the ones in rctl_rule_add()
1368 switch (rule->rr_subject_type) { in rctl_rule_add()
1370 if (cred->cr_uidinfo == rule->rr_subject.rs_uip || in rctl_rule_add()
1371 cred->cr_ruidinfo == rule->rr_subject.rs_uip) in rctl_rule_add()
1375 if (cred->cr_loginclass == rule->rr_subject.rs_loginclass) in rctl_rule_add()
1381 if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) { in rctl_rule_add()
1391 rule->rr_subject_type); in rctl_rule_add()
1394 rctl_racct_add_rule(p->p_racct, rule); in rctl_rule_add()
1473 * Appends a rule to the sbuf.
1476 rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule) in rctl_rule_to_sbuf() argument
1482 sbuf_printf(sb, "%s:", rctl_subject_type_name(rule->rr_subject_type)); in rctl_rule_to_sbuf()
1484 switch (rule->rr_subject_type) { in rctl_rule_to_sbuf()
1486 if (rule->rr_subject.rs_proc == NULL) in rctl_rule_to_sbuf()
1490 rule->rr_subject.rs_proc->p_pid); in rctl_rule_to_sbuf()
1493 if (rule->rr_subject.rs_uip == NULL) in rctl_rule_to_sbuf()
1497 rule->rr_subject.rs_uip->ui_uid); in rctl_rule_to_sbuf()
1500 if (rule->rr_subject.rs_loginclass == NULL) in rctl_rule_to_sbuf()
1504 rule->rr_subject.rs_loginclass->lc_name); in rctl_rule_to_sbuf()
1507 if (rule->rr_subject.rs_prison_racct == NULL) in rctl_rule_to_sbuf()
1511 rule->rr_subject.rs_prison_racct->prr_name); in rctl_rule_to_sbuf()
1515 rule->rr_subject_type); in rctl_rule_to_sbuf()
1518 amount = rule->rr_amount; in rctl_rule_to_sbuf()
1520 RACCT_IS_IN_MILLIONS(rule->rr_resource)) in rctl_rule_to_sbuf()
1524 rctl_resource_name(rule->rr_resource), in rctl_rule_to_sbuf()
1525 rctl_action_name(rule->rr_action), in rctl_rule_to_sbuf()
1528 if (rule->rr_per != rule->rr_subject_type) in rctl_rule_to_sbuf()
1529 sbuf_printf(sb, "/%s", rctl_subject_type_name(rule->rr_per)); in rctl_rule_to_sbuf()
1876 struct rctl_rule *rule; in sys_rctl_add_rule() local
1892 error = rctl_string_to_rule(inputstr, &rule); in sys_rctl_add_rule()
1899 * The 'per' part of a rule is optional. in sys_rctl_add_rule()
1901 if (rule->rr_per == RCTL_SUBJECT_TYPE_UNDEFINED && in sys_rctl_add_rule()
1902 rule->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) in sys_rctl_add_rule()
1903 rule->rr_per = rule->rr_subject_type; in sys_rctl_add_rule()
1905 if (!rctl_rule_fully_specified(rule)) { in sys_rctl_add_rule()
1910 error = rctl_rule_add(rule); in sys_rctl_add_rule()
1913 rctl_rule_release(rule); in sys_rctl_add_rule()
1952 * Update RCTL rule list after credential change.
2057 * Free the old rule list. in rctl_proc_ucred_changed()
2088 * Rule list changed while we were not holding the rctl_lock. in rctl_proc_ucred_changed()
2108 struct rctl_rule *rule; in rctl_proc_fork() local
2126 rule = rctl_rule_duplicate(link->rrl_rule, M_NOWAIT); in rctl_proc_fork()
2127 if (rule == NULL) in rctl_proc_fork()
2129 KASSERT(rule->rr_subject.rs_proc == parent, in rctl_proc_fork()
2130 ("rule->rr_subject.rs_proc != parent")); in rctl_proc_fork()
2131 rule->rr_subject.rs_proc = child; in rctl_proc_fork()
2133 rule); in rctl_proc_fork()
2134 rctl_rule_release(rule); in rctl_proc_fork()