* Link a rule with all the subjects it applies to. */
| 1273 | * Link a rule with all the subjects it applies to. |
| 1274 | */ |
| 1275 | int |
| 1276 | rctl_rule_add(struct rctl_rule *rule) |
| 1277 | { |
| 1278 | struct proc *p; |
| 1279 | struct ucred *cred; |
| 1280 | struct uidinfo *uip; |
| 1281 | struct prison *pr; |
| 1282 | struct prison_racct *prr; |
| 1283 | struct loginclass *lc; |
| 1284 | struct rctl_rule *rule2; |
| 1285 | int match; |
| 1286 | |
| 1287 | ASSERT_RACCT_ENABLED(); |
| 1288 | KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); |
| 1289 | |
| 1290 | /* |
| 1291 | * Some rules just don't make sense, like "deny" rule for an undeniable |
| 1292 | * resource. The exception are the RSS and %CPU resources - they are |
| 1293 | * not deniable in the racct sense, but the limit is enforced in |
| 1294 | * a different way. |
| 1295 | */ |
| 1296 | if (rule->rr_action == RCTL_ACTION_DENY && |
| 1297 | !RACCT_IS_DENIABLE(rule->rr_resource) && |
| 1298 | rule->rr_resource != RACCT_RSS && |
| 1299 | rule->rr_resource != RACCT_PCTCPU) { |
| 1300 | return (EOPNOTSUPP); |
| 1301 | } |
| 1302 | |
| 1303 | if (rule->rr_action == RCTL_ACTION_THROTTLE && |
| 1304 | !RACCT_IS_DECAYING(rule->rr_resource)) { |
| 1305 | return (EOPNOTSUPP); |
| 1306 | } |
| 1307 | |
| 1308 | if (rule->rr_action == RCTL_ACTION_THROTTLE && |
| 1309 | rule->rr_resource == RACCT_PCTCPU) { |
| 1310 | return (EOPNOTSUPP); |
| 1311 | } |
| 1312 | |
| 1313 | if (rule->rr_per == RCTL_SUBJECT_TYPE_PROCESS && |
| 1314 | RACCT_IS_SLOPPY(rule->rr_resource)) { |
| 1315 | return (EOPNOTSUPP); |
| 1316 | } |
| 1317 | |
| 1318 | /* |
| 1319 | * Make sure there are no duplicated rules. Also, for the "deny" |
| 1320 | * rules, remove ones differing only by "amount". |
| 1321 | */ |
| 1322 | if (rule->rr_action == RCTL_ACTION_DENY) { |
| 1323 | rule2 = rctl_rule_duplicate(rule, M_WAITOK); |
| 1324 | rule2->rr_amount = RCTL_AMOUNT_UNDEFINED; |
| 1325 | rctl_rule_remove(rule2); |
| 1326 | rctl_rule_release(rule2); |
| 1327 | } else |
| 1328 | rctl_rule_remove(rule); |
| 1329 | |
| 1330 | switch (rule->rr_subject_type) { |
| 1331 | case RCTL_SUBJECT_TYPE_PROCESS: |
| 1332 | p = rule->rr_subject.rs_proc; |
no test coverage detected