* Check whether the proc 'p' can allocate 'amount' of 'resource' in addition * to what it keeps allocated now. Returns non-zero if the allocation should * be denied, 0 otherwise. */
| 495 | * be denied, 0 otherwise. |
| 496 | */ |
| 497 | int |
| 498 | rctl_enforce(struct proc *p, int resource, uint64_t amount) |
| 499 | { |
| 500 | static struct timeval log_lasttime, devctl_lasttime; |
| 501 | static int log_curtime = 0, devctl_curtime = 0; |
| 502 | struct rctl_rule *rule; |
| 503 | struct rctl_rule_link *link; |
| 504 | struct sbuf sb; |
| 505 | char *buf; |
| 506 | int64_t available; |
| 507 | uint64_t sleep_ms, sleep_ratio; |
| 508 | int should_deny = 0; |
| 509 | |
| 510 | ASSERT_RACCT_ENABLED(); |
| 511 | RACCT_LOCK_ASSERT(); |
| 512 | |
| 513 | /* |
| 514 | * There may be more than one matching rule; go through all of them. |
| 515 | * Denial should be done last, after logging and sending signals. |
| 516 | */ |
| 517 | LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { |
| 518 | rule = link->rrl_rule; |
| 519 | if (rule->rr_resource != resource) |
| 520 | continue; |
| 521 | |
| 522 | available = rctl_available_resource(p, rule); |
| 523 | if (available >= (int64_t)amount) { |
| 524 | link->rrl_exceeded = 0; |
| 525 | continue; |
| 526 | } |
| 527 | |
| 528 | switch (rule->rr_action) { |
| 529 | case RCTL_ACTION_DENY: |
| 530 | should_deny = 1; |
| 531 | continue; |
| 532 | case RCTL_ACTION_LOG: |
| 533 | /* |
| 534 | * If rrl_exceeded != 0, it means we've already |
| 535 | * logged a warning for this process. |
| 536 | */ |
| 537 | if (link->rrl_exceeded != 0) |
| 538 | continue; |
| 539 | |
| 540 | /* |
| 541 | * If the process state is not fully initialized yet, |
| 542 | * we can't access most of the required fields, e.g. |
| 543 | * p->p_comm. This happens when called from fork1(). |
| 544 | * Ignore this rule for now; it will be processed just |
| 545 | * after fork, when called from racct_proc_fork_done(). |
| 546 | */ |
| 547 | if (p->p_state != PRS_NORMAL) |
| 548 | continue; |
| 549 | |
| 550 | if (!ppsratecheck(&log_lasttime, &log_curtime, |
| 551 | rctl_log_rate_limit)) |
| 552 | continue; |
| 553 | |
| 554 | buf = malloc(RCTL_LOG_BUFSIZE, M_RCTL, M_NOWAIT); |
no test coverage detected