PERFORCE change 165909 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Fri Jul 10 17:49:46 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165909
Change 165909 by trasz at 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);
More information about the p4-projects
mailing list