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