From owner-p4-projects@FreeBSD.ORG Fri Jul 10 17:49:45 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 768A110656A9; Fri, 10 Jul 2009 17:49:45 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3657C106566C for ; Fri, 10 Jul 2009 17:49:45 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 195958FC0C for ; Fri, 10 Jul 2009 17:49:45 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n6AHnisQ060155 for ; Fri, 10 Jul 2009 17:49:44 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n6AHniXI060153 for perforce@freebsd.org; Fri, 10 Jul 2009 17:49:44 GMT (envelope-from trasz@freebsd.org) Date: Fri, 10 Jul 2009 17:49:44 GMT Message-Id: <200907101749.n6AHniXI060153@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 165909 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Jul 2009 17:49:46 -0000 http://perforce.freebsd.org/chv.cgi?CH=165909 Change 165909 by trasz@trasz_victim on 2009/07/10 17:48:54 Make it possible to query for all the limits for a particular process. It's another step towards actual limit enforcement. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#28 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#21 edit .. //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#14 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#28 (text+ko) ==== @@ -986,6 +986,107 @@ } static int +hrl_get_rules_pid(struct thread *td, char *inputstr, struct sbuf **outputsbuf) +{ + int error = 0, copied = 0; + id_t pid; + struct proc *p; + struct ucred *cred; + struct hrl_rule *buf; + struct hrl_limit *limit; + struct prison *pr; + + error = str2id(inputstr, &pid); + if (error) + return (error); + + buf = malloc(HRL_MAX_RULES * sizeof(struct hrl_rule), M_HRL, M_WAITOK); + + if ((p = pfind(pid)) == NULL) { + if ((p = zpfind(pid)) == NULL) { + free(buf, M_HRL); + return (ESRCH); + } + } + + cred = p->p_ucred; + pr = cred->cr_prison; + + /* + * Copy the limits to the temporary buffer. We cannot + * copy it directly to the userland because of the mutex. + */ + mtx_lock(&hrl_lock); + LIST_FOREACH(limit, &p->p_limits, hl_next) { + if (copied >= HRL_MAX_RULES) { + /* + * XXX: Hey, what to do now? + */ + error = EDOOFUS; + break; + } + + *(buf + copied) = *(limit->hl_rule); + copied++; + } + LIST_FOREACH(limit, &cred->cr_uidinfo->ui_limits, hl_next) { + if (copied >= HRL_MAX_RULES) { + /* + * XXX: Hey, what to do now? + */ + error = EDOOFUS; + break; + } + + *(buf + copied) = *(limit->hl_rule); + copied++; + } + if (cred->cr_uidinfo != cred->cr_ruidinfo) { + LIST_FOREACH(limit, &cred->cr_ruidinfo->ui_limits, hl_next) { + if (copied >= HRL_MAX_RULES) { + /* + * XXX: Hey, what to do now? + */ + error = EDOOFUS; + break; + } + + *(buf + copied) = *(limit->hl_rule); + copied++; + } + } + + /* + * XXX: Groups. + */ + + for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) { + LIST_FOREACH(limit, &pr->pr_limits, hl_next) { + if (copied >= HRL_MAX_RULES) { + /* + * XXX: Hey, what to do now? + */ + error = EDOOFUS; + break; + } + + *(buf + copied) = *(limit->hl_rule); + copied++; + } + } + mtx_unlock(&hrl_lock); + PROC_UNLOCK(p); + if (error) + goto out; + + *outputsbuf = hrl_rules_to_sbuf(buf, copied); +out: + free(buf, M_HRL); + + return (error); +} + +static int hrl_add_rule(struct thread *td, char *inputstr) { int error; @@ -1179,6 +1280,9 @@ case HRL_OP_GET_RULES: error = hrl_get_rules(td, inputstr, &outputsbuf); break; + case HRL_OP_GET_RULES_PID: + error = hrl_get_rules_pid(td, inputstr, &outputsbuf); + break; case HRL_OP_ADD_RULE: error = hrl_add_rule(td, inputstr); break; ==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#21 (text+ko) ==== @@ -38,6 +38,7 @@ */ #define HRL_OP_GET_RULES 1 +#define HRL_OP_GET_RULES_PID 8 #define HRL_OP_ADD_RULE 6 #define HRL_OP_REMOVE_RULE 7 #define HRL_OP_GET_USAGE_PID 2 ==== //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#14 (text+ko) ==== @@ -143,6 +143,10 @@ char *outbuf = NULL, *tmp; size_t outbuflen = BUFLEN_DEFAULT / 4; + /* + * XXX: We should resolve user/group names here. + */ + do { outbuflen *= 4; outbuf = realloc(outbuf, outbuflen); @@ -173,6 +177,46 @@ free(outbuf); } +static void +print_rules_pid(id_t pid) +{ + int error; + char *outbuf = NULL, *inbuf = NULL, *tmp; + size_t outbuflen = BUFLEN_DEFAULT / 4; + + asprintf(&inbuf, "%d", (int)pid); + if (inbuf == NULL) + err(1, "asprintf"); + + /* + * XXX: We should resolve user/group names here. + */ + + do { + outbuflen *= 4; + outbuf = realloc(outbuf, outbuflen); + if (outbuf == NULL) + err(1, "realloc"); + + error = hrl(HRL_OP_GET_RULES, inbuf, strlen(inbuf) + 1, outbuf, outbuflen); + if (error && errno != EFBIG) + err(1, "hrl"); + } while (error && errno == EFBIG); + + for (tmp = outbuf; *tmp != '\0'; tmp++) + if (*tmp == ',') + *tmp = '\n'; + + printf("Defined resource limits for process %d:\n%s\n", (int)pid, outbuf); + + /* + * XXX: Resolve numeric ID-s back to names. + */ + + free(inbuf); + free(outbuf); +} + /* * Query the kernel about a resource usage and print it out. */ @@ -203,6 +247,7 @@ *tmp = '\n'; printf("Resource utilisation:\n%s\n", outbuf); + free(inbuf); free(outbuf); } @@ -254,20 +299,20 @@ usage(void) { - fprintf(stderr, "usage: hrl [-a rule | -r rule | -u user | -g group | -p pid | -j jailid] [rule]\n"); + fprintf(stderr, "usage: hrl [-a rule | -r rule | -u user | -g group | -p pid | -j jailid -P pid] [rule]\n"); exit(1); } int main(int argc __unused, char **argv __unused) { - int ch, op, aflag = 0, gflag = 0, jflag = 0, pflag = 0, rflag = 0, uflag = 0; + int ch, op, aflag = 0, gflag = 0, jflag = 0, pflag = 0, rflag = 0, uflag = 0, Pflag = 0; id_t id = 0; char *rule = NULL; op = HRL_OP_GET_RULES; - while ((ch = getopt(argc, argv, "a:g:j:p:r:u:")) != -1) { + while ((ch = getopt(argc, argv, "a:g:j:p:r:u:P:")) != -1) { switch (ch) { case 'a': aflag = 1; @@ -299,6 +344,13 @@ op = HRL_OP_GET_USAGE_UID; id = parse_user(optarg); break; + + case 'P': + Pflag = 1; + op = HRL_OP_GET_RULES_PID; + id = parse_pid(optarg); + break; + case '?': default: usage(); @@ -314,7 +366,7 @@ if (argc == 1) rule = strdup(argv[0]); - if (aflag + gflag + jflag + pflag + rflag + uflag > 1) + if (aflag + gflag + jflag + pflag + rflag + uflag + Pflag > 1) errx(1, "only one flag may be specified " "at the same time"); @@ -337,6 +389,10 @@ add_or_remove_rule(op, rule); free(rule); break; + + case HRL_OP_GET_RULES_PID: + print_rules_pid(id); + break; } return (0);