PERFORCE change 166016 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Mon Jul 13 17:21:06 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166016
Change 166016 by trasz at trasz_victim on 2009/07/13 17:20:20
Add support for actions.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#30 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#30 (text+ko) ====
@@ -157,6 +157,7 @@
static void hrl_rule_add_limits(struct hrl_rule *rule);
static void hrl_compute_available(struct proc *p, int64_t (*availablep)[],
struct hrl_rule *(*rulesp)[]);
+static struct sbuf *hrl_rules_to_sbuf(struct hrl_rule *usage, int nrules);
MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits");
@@ -289,18 +290,93 @@
mtx_unlock(&hrl_lock);
}
+static void
+hrl_deferred_psignal(struct proc *p, int signum)
+{
+
+ PROC_LOCK(p);
+ psignal(p, signum);
+ PROC_UNLOCK(p);
+}
+
/*
+ * Check whether the proc 'p' can allocate 'amount' of 'resource' in addition
+ * to what it has allocated now. Returns fake error code if the allocation
+ * should fail.
+ */
+static int
+hrl_enforce_proc(struct proc *p, int resource, uint64_t amount)
+{
+ int64_t available[HRL_RESOURCE_MAX];
+ struct hrl_rule *rules[HRL_RESOURCE_MAX];
+ struct sbuf *sb;
+
+ /*
+ * XXX: Check maxfilesperproc.
+ */
+ /*
+ * XXX: Do this just before we start running on a CPU, not all the time.
+ */
+ hrl_compute_available(p, &available, &rules);
+
+ if (available[resource] >= amount)
+ return (0);
+
+ switch (rules[resource]->hr_action) {
+ case HRL_ACTION_DENY:
+ /*
+ * Return fake error code; the caller should change it
+ * into proper one for the situation - EFSIZ, ENOMEM etc.
+ */
+ return (EDOOFUS);
+ case HRL_ACTION_DELAY:
+ /*
+ * XXX: Think whether we actually can and want to do this.
+ */
+ printf("hrl_enforce_proc: XXX, \"delay\" unimplemented.\n");
+ return (0);
+ case HRL_ACTION_LOG:
+ sb = hrl_rules_to_sbuf(rules[resource], 1);
+ sbuf_finish(sb);
+ printf("resource limit \"%s\" exceeded by process %d (%s), "
+ "uid %d\n", sbuf_data(sb), p->p_pid, p->p_comm,
+ p->p_ucred->cr_uid);
+ sbuf_delete(sb);
+ return (0);
+ case HRL_ACTION_SIGHUP:
+ hrl_deferred_psignal(p, SIGHUP);
+ return (0);
+ case HRL_ACTION_SIGINT:
+ hrl_deferred_psignal(p, SIGINT);
+ return (0);
+ case HRL_ACTION_SIGKILL:
+ hrl_deferred_psignal(p, SIGKILL);
+ return (0);
+ case HRL_ACTION_SIGSEGV:
+ hrl_deferred_psignal(p, SIGSEGV);
+ return (0);
+ case HRL_ACTION_SIGXCPU:
+ hrl_deferred_psignal(p, SIGXCPU);
+ return (0);
+ case HRL_ACTION_SIGXFSZ:
+ hrl_deferred_psignal(p, SIGXFSZ);
+ return (0);
+ default:
+ panic("hrl_enforce_proc: unknown action %d",
+ rules[resource]->hr_action);
+ }
+}
+
+/*
* Increase allocation of 'resource' by 'amount' for process 'p'.
* Return 0 if it's below limits, or errno, if it's not.
*/
int
hrl_alloc_proc(struct proc *p, int resource, uint64_t amount)
{
- int i, j;
+ int i, j, error;
struct ucred *cred;
struct prison *pr;
- int64_t available[HRL_RESOURCE_MAX];
- struct hrl_rule *rules[HRL_RESOURCE_MAX];
KASSERT(amount > 0, ("hrl_alloc_proc: invalid amount for %s: %lld",
hrl_resource_name(resource), amount));
@@ -310,20 +386,10 @@
#endif
mtx_lock(&hrl_lock);
- /*
- * XXX: Check maxfilesperproc.
- */
- /*
- * XXX: Do this just before we start running on a CPU, not all the time.
- */
- hrl_compute_available(p, &available, &rules);
- /*
- * Return fake error code; the caller should change it into proper
- * one for the situation - EFSIZ, ENOMEM, EMFILE etc.
- */
- if (available[resource] < 0 && rules[resource]->hr_action == HRL_ACTION_DENY) {
+ error = hrl_enforce_proc(p, resource, amount);
+ if (error) {
mtx_unlock(&hrl_lock);
- return (EDOOFUS);
+ return (error);
}
p->p_usage.hu_resources[resource] += amount;
cred = p->p_ucred;
@@ -368,12 +434,10 @@
int
hrl_allocated_proc(struct proc *p, int resource, uint64_t amount)
{
- int i, j;
+ int i, j, error;
int64_t diff;
struct ucred *cred;
struct prison *pr;
- int64_t available[HRL_RESOURCE_MAX];
- struct hrl_rule *rules[HRL_RESOURCE_MAX];
KASSERT(amount >= 0, ("hrl_allocated_proc: invalid amount for %s: %lld",
hrl_resource_name(resource), amount));
@@ -385,17 +449,10 @@
mtx_lock(&hrl_lock);
diff = amount - p->p_usage.hu_resources[resource];
if (diff > 0) {
- /*
- * XXX: Do this just before we start running on a CPU, not all the time.
- */
- hrl_compute_available(p, &available, &rules);
- /*
- * Return fake error code; the caller should change it into proper
- * one for the situation - EFSIZ, ENOMEM, EMFILE etc.
- */
- if (available[resource] < 0 && rules[resource]->hr_action == HRL_ACTION_DENY) {
+ error = hrl_enforce_proc(p, resource, diff);
+ if (error) {
mtx_unlock(&hrl_lock);
- return (EDOOFUS);
+ return (error);
}
}
p->p_usage.hu_resources[resource] = amount;
@@ -1111,6 +1168,8 @@
* copy it directly to the userland because of the mutex.
*/
for (i = 0; i < HRL_RESOURCE_MAX; i++) {
+ if (rules[i] == NULL)
+ continue;
*(buf + copied) = *(rules[i]);
copied++;
}
More information about the p4-projects
mailing list