svn commit: r223189 - projects/jailconf/usr.sbin/jail

Jamie Gritton jamie at FreeBSD.org
Fri Jun 17 16:18:44 UTC 2011


Author: jamie
Date: Fri Jun 17 16:18:44 2011
New Revision: 223189
URL: http://svn.freebsd.org/changeset/base/223189

Log:
  Split run_command up into an outer function (next_command) that chooses
   a single command string to run, and an inner function (run_command) that
   runs that single string.
  Move the list of start/stop commands to run from a switch statement into
   an array, with a new placeholder parameter IP__OP for actually creating
   or removing the jail.
  When jail creation fails, revert all non-exec commands in reverse order.

Modified:
  projects/jailconf/usr.sbin/jail/command.c
  projects/jailconf/usr.sbin/jail/config.c
  projects/jailconf/usr.sbin/jail/jail.c
  projects/jailconf/usr.sbin/jail/jailp.h

Modified: projects/jailconf/usr.sbin/jail/command.c
==============================================================================
--- projects/jailconf/usr.sbin/jail/command.c	Fri Jun 17 16:06:13 2011	(r223188)
+++ projects/jailconf/usr.sbin/jail/command.c	Fri Jun 17 16:18:44 2011	(r223189)
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
 
 #include "jailp.h"
 
-#define COMSTRING_DUMMY		((struct cfstring *)1)
 #define DEFAULT_STOP_TIMEOUT	10
 #define PHASH_SIZE		256
 
@@ -66,12 +65,13 @@ int paralimit = -1;
 
 extern char **environ;
 
-static int get_user_info(struct cfjail *j, const char *username,
-    const struct passwd **pwdp, login_cap_t **lcapp);
+static int run_command(struct cfjail *j);
 static void add_proc(struct cfjail *j, pid_t pid);
 static void clear_procs(struct cfjail *j);
 static struct cfjail *find_proc(pid_t pid);
 static int term_procs(struct cfjail *j);
+static int get_user_info(struct cfjail *j, const char *username,
+    const struct passwd **pwdp, login_cap_t **lcapp);
 static int check_path(struct cfjail *j, const char *pname, const char *path,
     int isfile, const char *umount_type);
 
@@ -81,58 +81,188 @@ static struct phhead phash[PHASH_SIZE];
 static int kq;
 
 /*
- * Run a command associated with a jail, possibly inside the jail.
+ * Run the next command associated with a jail.
+ */
+int
+next_command(struct cfjail *j)
+{
+	const struct cfstring *comstring;
+	enum intparam comparam;
+	int rval, create_failed;
+
+	static struct cfstring dummystring = { .len = 1 };
+
+	rval = 0;
+	create_failed = (j->flags & (JF_STOP | JF_FAILED)) == JF_FAILED;
+	for (; (comparam = *j->comparam) && comparam != IP__OP;
+	     j->comparam += create_failed ? -1 : 1) {
+		if (j->comstring == NULL) {
+			switch (comparam) {
+			case IP_MOUNT_DEVFS:
+				if (!bool_param(j->intparams[IP_MOUNT_DEVFS]))
+					continue;
+				/* FALLTHROUGH */
+			case IP_STOP_TIMEOUT:
+				j->comstring = &dummystring;
+				break;
+			default:
+				if (j->intparams[comparam] == NULL)
+					continue;
+				j->comstring = create_failed
+				    ? TAILQ_LAST(&j->intparams[comparam]->val,
+					cfstrings)
+				    : TAILQ_FIRST(&j->intparams[comparam]->val);
+			}
+		}
+		for (; j->comstring != NULL;
+		     j->comstring = create_failed
+			? TAILQ_PREV(j->comstring, cfstrings, tq)
+			: TAILQ_NEXT(j->comstring, tq)) {
+			if (rval != 0)
+				return rval;
+			if (j->comstring->len == 0 || (create_failed &&
+			    (comparam == IP_EXEC_PRESTART || comparam ==
+			    IP_EXEC_START || comparam == IP_COMMAND ||
+			    comparam == IP_EXEC_POSTSTART)))
+				continue;
+			if (paralimit == 0) {
+				requeue(j, &runnable);
+				return 1;
+			}
+			rval = run_command(j);
+			create_failed =
+			    (j->flags & (JF_STOP | JF_FAILED)) == JF_FAILED;
+		}
+	}
+	return rval;
+}
+
+/*
+ * Check command exit status
+ */
+int
+finish_command(struct cfjail *j)
+{
+	int error;
+
+	if (!(j->flags & JF_SLEEPQ))
+		return 0;
+	j->flags &= ~JF_SLEEPQ;
+	if (*j->comparam != IP_STOP_TIMEOUT) {
+		paralimit++;
+		if (!TAILQ_EMPTY(&runnable))
+			requeue(TAILQ_FIRST(&runnable), &ready);
+	}
+	error = 0;
+	if (j->flags & JF_TIMEOUT) {
+		j->flags &= ~JF_TIMEOUT;
+		if (*j->comparam != IP_STOP_TIMEOUT) {
+			jail_warnx(j, "%s: timed out", j->comline);
+			failed(j);
+			error = -1;
+		} else if (verbose > 0)
+			jail_note(j, "timed out\n");
+	} else if (j->pstatus != 0) {
+		if (WIFSIGNALED(j->pstatus))
+			jail_warnx(j, "%s: exited on signal %d",
+			    j->comline, WTERMSIG(j->pstatus));
+		else
+			jail_warnx(j, "%s: failed", j->comline);
+		j->pstatus = 0;
+		failed(j);
+		error = -1;
+	}
+	free(j->comline);
+	j->comline = NULL;
+	return error;
+}
+
+/*
+ * Check for finished processed or timeouts.
+ */
+struct cfjail *
+next_proc(int nonblock)
+{
+	struct kevent ke;
+	struct timespec ts;
+	struct timespec *tsp;
+	struct cfjail *j;
+
+	if (!TAILQ_EMPTY(&sleeping)) {
+	again:
+		tsp = NULL;
+		if ((j = TAILQ_FIRST(&sleeping)) && j->timeout.tv_sec) {
+			clock_gettime(CLOCK_REALTIME, &ts);
+			ts.tv_sec = j->timeout.tv_sec - ts.tv_sec;
+			ts.tv_nsec = j->timeout.tv_nsec - ts.tv_nsec;
+			if (ts.tv_nsec < 0) {
+				ts.tv_sec--;
+				ts.tv_nsec += 1000000000;
+			}
+			if (ts.tv_sec < 0 ||
+			    (ts.tv_sec == 0 && ts.tv_nsec == 0)) {
+				j->flags |= JF_TIMEOUT;
+				clear_procs(j);
+				return j;
+			}
+			tsp = &ts;
+		}
+		if (nonblock) {
+			ts.tv_sec = 0;
+			ts.tv_nsec = 0;
+			tsp = &ts;
+		}
+		switch (kevent(kq, NULL, 0, &ke, 1, tsp)) {
+		case -1:
+			if (errno != EINTR)
+				err(1, "kevent");
+			goto again;
+		case 0:
+			if (!nonblock) {
+				j = TAILQ_FIRST(&sleeping);
+				j->flags |= JF_TIMEOUT;
+				clear_procs(j);
+				return j;
+			}
+			break;
+		case 1:
+			(void)waitpid(ke.ident, NULL, WNOHANG);
+			if ((j = find_proc(ke.ident))) {
+				j->pstatus = ke.data;
+				return j;
+			}
+			goto again;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * Run a single command for a jail, possible inside the jail.
  */
 int
-run_command(struct cfjail *j, enum intparam comparam)
+run_command(struct cfjail *j)
 {
 	const struct passwd *pwd;
-	struct cfstring *comstring, *s;
+	const struct cfstring *comstring, *s;
 	login_cap_t *lcap;
 	char **argv;
 	char *cs, *addr, *comcs, *devpath;
 	const char *jidstr, *conslog, *path, *ruleset, *term, *username;
+	enum intparam comparam;
 	size_t comlen;
 	pid_t pid;
 	int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout;
 
 	static char *cleanenv;
 
-	if (comparam) {
-		switch (comparam) {
-		case IP_MOUNT_DEVFS:
-			if (!bool_param(j->intparams[IP_MOUNT_DEVFS]))
-				return 0;
-			/* FALLTHROUGH */
-		case IP_STOP_TIMEOUT:
-			j->comstring = COMSTRING_DUMMY;
-			break;
-		default:
-			if (j->intparams[comparam] == NULL)
-				return 0;
-			j->comstring =
-			    TAILQ_FIRST(&j->intparams[comparam]->val);
-		}
-		j->comparam = comparam;
-	} else
-		comparam = j->comparam;
- next_comstring:
-	comstring = j->comstring;
-	if (comstring == NULL)
-		return 0;
-	if (paralimit == 0) {
-		requeue(j, &runnable);
-		return 1;
-	}
-	j->comstring =
-	    comstring == COMSTRING_DUMMY ? NULL : TAILQ_NEXT(comstring, tq);
-	if (comstring != COMSTRING_DUMMY && comstring->len == 0)
-		goto next_comstring;
 	/*
 	 * Collect exec arguments.  Internal commands for network and
 	 * mounting build their own argument lists.
 	 */
-	bg = j->flags & JF_FAILED;
+	comparam = *j->comparam;
+	comstring = j->comstring;
+	bg = 0;
 	down = j->flags & (JF_STOP | JF_FAILED);
 	switch (comparam) {
 	case IP_STOP_TIMEOUT:
@@ -169,7 +299,6 @@ run_command(struct cfjail *j, enum intpa
 		}
 		*(const char **)&argv[argc] = down ? "-alias" : "alias";
 		argv[argc + 1] = NULL;
-		j->flags |= JF_IFUP;
 		break;
 
 #ifdef INET6
@@ -195,7 +324,6 @@ run_command(struct cfjail *j, enum intpa
 			argc = 4;
 		*(const char **)&argv[argc] = down ? "-alias" : "alias";
 		argv[argc + 1] = NULL;
-		j->flags |= JF_IFUP;
 		break;	
 #endif
 
@@ -208,7 +336,6 @@ run_command(struct cfjail *j, enum intpa
 		*(const char **)&argv[3] =
 			jidstr ? jidstr : string_param(j->intparams[KP_NAME]);
 		argv[4] = NULL;
-		j->flags |= JF_IFUP;
 		break;
 
 	case IP_MOUNT:
@@ -221,7 +348,7 @@ run_command(struct cfjail *j, enum intpa
 		     cs = strtok(NULL, " \t\f\v\r\n"))
 			argv[argc++] = cs;
 		if (argc == 0)
-			goto next_comstring;
+			return 0;
 		if (argc < 3) {
 			jail_warnx(j, "%s: %s: missing information",
 			    j->intparams[comparam]->name, comstring->s);
@@ -252,7 +379,6 @@ run_command(struct cfjail *j, enum intpa
 			*(const char **)&argv[0] = _PATH_MOUNT;
 		}
 		*(const char **)&argv[1] = "-t";
-		j->flags |= JF_MOUNTED;
 		break;
 
 	case IP_MOUNT_DEVFS:
@@ -287,7 +413,6 @@ run_command(struct cfjail *j, enum intpa
 			    ruleset ? " " : "", ruleset ? ruleset : "");
 			argv[3] = NULL;
 		}
-		j->flags |= JF_MOUNTED;
 		break;
 
 	case IP_COMMAND:
@@ -333,9 +458,9 @@ run_command(struct cfjail *j, enum intpa
 			argv[argc] = NULL;
 		}
 	}
-
 	if (argv[0] == NULL)
-		goto next_comstring;
+		return 0;
+
 	if (int_param(j->intparams[IP_EXEC_TIMEOUT], &timeout) &&
 	    timeout != 0) {
 		clock_gettime(CLOCK_REALTIME, &j->timeout);
@@ -399,6 +524,7 @@ run_command(struct cfjail *j, enum intpa
 	if (bg)
 		setsid();
 
+	/* Set up the environment and run the command */
 	pwd = NULL;
 	lcap = NULL;
 	if ((clean || username) && injail && sjuser &&
@@ -462,106 +588,6 @@ run_command(struct cfjail *j, enum intpa
 }
 
 /*
- * Check command exit status
- */
-int
-finish_command(struct cfjail *j)
-{
-	int error;
-
-	if (!(j->flags & JF_SLEEPQ))
-		return 0;
-	j->flags &= ~JF_SLEEPQ;
-	if (j->comparam != IP_STOP_TIMEOUT) {
-		paralimit++;
-		if (!TAILQ_EMPTY(&runnable))
-			requeue(TAILQ_FIRST(&runnable), &ready);
-	}
-	error = 0;
-	if (j->flags & JF_TIMEOUT) {
-		j->flags &= ~JF_TIMEOUT;
-		if (j->comparam != IP_STOP_TIMEOUT) {
-			jail_warnx(j, "%s: timed out", j->comline);
-			failed(j);
-			error = -1;
-		} else if (verbose > 0)
-			jail_note(j, "timed out\n");
-	} else if (j->pstatus != 0) {
-		if (WIFSIGNALED(j->pstatus))
-			jail_warnx(j, "%s: exited on signal %d",
-			    j->comline, WTERMSIG(j->pstatus));
-		else
-			jail_warnx(j, "%s: failed", j->comline);
-		j->pstatus = 0;
-		failed(j);
-		error = -1;
-	}
-	free(j->comline);
-	j->comline = NULL;
-	return error;
-}
-
-/*
- * Check for finished processed or timeouts.
- */
-struct cfjail *
-next_proc(int nonblock)
-{
-	struct kevent ke;
-	struct timespec ts;
-	struct timespec *tsp;
-	struct cfjail *j;
-
-	if (!TAILQ_EMPTY(&sleeping)) {
-	again:
-		tsp = NULL;
-		if ((j = TAILQ_FIRST(&sleeping)) && j->timeout.tv_sec) {
-			clock_gettime(CLOCK_REALTIME, &ts);
-			ts.tv_sec = j->timeout.tv_sec - ts.tv_sec;
-			ts.tv_nsec = j->timeout.tv_nsec - ts.tv_nsec;
-			if (ts.tv_nsec < 0) {
-				ts.tv_sec--;
-				ts.tv_nsec += 1000000000;
-			}
-			if (ts.tv_sec < 0 ||
-			    (ts.tv_sec == 0 && ts.tv_nsec == 0)) {
-				j->flags |= JF_TIMEOUT;
-				clear_procs(j);
-				return j;
-			}
-			tsp = &ts;
-		}
-		if (nonblock) {
-			ts.tv_sec = 0;
-			ts.tv_nsec = 0;
-			tsp = &ts;
-		}
-		switch (kevent(kq, NULL, 0, &ke, 1, tsp)) {
-		case -1:
-			if (errno != EINTR)
-				err(1, "kevent");
-			goto again;
-		case 0:
-			if (!nonblock) {
-				j = TAILQ_FIRST(&sleeping);
-				j->flags |= JF_TIMEOUT;
-				clear_procs(j);
-				return j;
-			}
-			break;
-		case 1:
-			(void)waitpid(ke.ident, NULL, WNOHANG);
-			if ((j = find_proc(ke.ident))) {
-				j->pstatus = ke.data;
-				return j;
-			}
-			goto again;
-		}
-	}
-	return NULL;
-}
-
-/*
  * Add a process to the hash, tied to a jail.
  */
 static void

Modified: projects/jailconf/usr.sbin/jail/config.c
==============================================================================
--- projects/jailconf/usr.sbin/jail/config.c	Fri Jun 17 16:06:13 2011	(r223188)
+++ projects/jailconf/usr.sbin/jail/config.c	Fri Jun 17 16:18:44 2011	(r223189)
@@ -87,6 +87,7 @@ static const struct ipspec intparams[] =
     [IP__IP6_IFADDR] =		{"ip6.addr",		PF_INTERNAL | PF_CONV},
 #endif
     [IP__MOUNT_FROM_FSTAB] =	{"mount.fstab",		PF_INTERNAL | PF_CONV},
+    [IP__OP] =			{NULL,			PF_CONV},
     [KP_ALLOW_CHFLAGS] =	{"allow.chflags",	0},
     [KP_ALLOW_MOUNT] =		{"allow.mount",		0},
     [KP_ALLOW_RAW_SOCKETS] =	{"allow.raw_sockets",	0},

Modified: projects/jailconf/usr.sbin/jail/jail.c
==============================================================================
--- projects/jailconf/usr.sbin/jail/jail.c	Fri Jun 17 16:06:13 2011	(r223188)
+++ projects/jailconf/usr.sbin/jail/jail.c	Fri Jun 17 16:18:44 2011	(r223189)
@@ -78,6 +78,41 @@ static struct permspec perm_sysctl[] = {
 	{ "security.jail.socket_unixiproute_only", KP_ALLOW_SOCKET_AF, 1 },
 };
 
+static const enum intparam startcommands[] = {
+    0,
+    IP__IP4_IFADDR,
+#ifdef INET6
+    IP__IP6_IFADDR,
+#endif
+    IP_MOUNT,
+    IP__MOUNT_FROM_FSTAB,
+    IP_MOUNT_DEVFS,
+    IP_EXEC_PRESTART, 
+    IP__OP,
+    IP_VNET_INTERFACE,
+    IP_EXEC_START,
+    IP_COMMAND,
+    IP_EXEC_POSTSTART,
+    0
+};
+
+static const enum intparam stopcommands[] = {
+    0,
+    IP_EXEC_PRESTOP,
+    IP_EXEC_STOP,
+    IP_STOP_TIMEOUT,
+    IP__OP,
+    IP_EXEC_POSTSTOP,
+    IP_MOUNT_DEVFS,
+    IP__MOUNT_FROM_FSTAB,
+    IP_MOUNT,
+#ifdef INET6
+    IP__IP6_IFADDR,
+#endif
+    IP__IP4_IFADDR,
+    0
+};
+
 int
 main(int argc, char **argv)
 {
@@ -290,25 +325,11 @@ main(int argc, char **argv)
 	while ((j = next_jail()))
 	{
 		if (j->flags & JF_FAILED) {
-			clear_persist(j);
-			if (j->flags & JF_MOUNTED) {
-				(void)run_command(j, IP_MOUNT_DEVFS);
-				if (run_command(j, IP__MOUNT_FROM_FSTAB))
-					while (run_command(j, 0)) ;
-				if (run_command(j, IP_MOUNT))
-					while (run_command(j, 0)) ;
-			}
-			if (j->flags & JF_IFUP) {
-				if (run_command(j, IP__IP4_IFADDR))
-					while (run_command(j, 0)) ;
-#ifdef INET6
-				if (run_command(j, IP__IP6_IFADDR))
-					while (run_command(j, 0)) ;
-#endif
-			}
 			error = 1;
-			dep_done(j, 0);
-			continue;
+			if (j->comparam == NULL) {
+				dep_done(j, 0);
+				continue;
+			}
 		}
 		if (!(j->flags & JF_PARAMS))
 		{
@@ -326,7 +347,7 @@ main(int argc, char **argv)
 			    (j->flags & (JF_SET | JF_DEPEND)) == JF_SET
 			    ? dflag || bool_param(j->intparams[IP_ALLOW_DYING])
 			    : 0);
-		if (finish_command(j) || run_command(j, 0))
+		if (finish_command(j))
 			continue;
 
 		switch (j->flags & JF_OP_MASK) {
@@ -356,17 +377,7 @@ main(int argc, char **argv)
 
 		switch (j->flags & JF_OP_MASK) {
 		case JF_START:
-			/*
-			 * 1: check existence and dependencies
-			 * 2: configure IP addresses
-			 * 3: run any exec.prestart commands
-			 * 4: create the jail
-			 * 5: configure vnet interfaces
-			 * 6: run any exec.start or "command" commands
-			 * 7: run any exec.poststart commands
-			 */
-			switch (j->comparam) {
-			default:
+			if (j->comparam == NULL) {
 				if (j->jid > 0 &&
 				    !(j->flags & (JF_DEPEND | JF_WILD))) {
 					warnx("\"%s\" already exists", j->name);
@@ -377,70 +388,38 @@ main(int argc, char **argv)
 					continue;
 				if (j->jid > 0)
 					goto jail_create_done;
-				if (run_command(j, IP__IP4_IFADDR))
-					continue;
-				/* FALLTHROUGH */
-			case IP__IP4_IFADDR:
-#ifdef INET6
-				if (run_command(j, IP__IP6_IFADDR))
-					continue;
-				/* FALLTHROUGH */
-			case IP__IP6_IFADDR:
-#endif
-				if (run_command(j, IP_MOUNT))
-					continue;
-				/* FALLTHROUGH */
-			case IP_MOUNT:
-				if (run_command(j,
-				    IP__MOUNT_FROM_FSTAB))
-					continue;
-				/* FALLTHROUGH */
-			case IP__MOUNT_FROM_FSTAB:
-				if (run_command(j, IP_MOUNT_DEVFS))
-					continue;
-				/* FALLTHROUGH */
-			case IP_MOUNT_DEVFS:
-				if (run_command(j, IP_EXEC_PRESTART))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_PRESTART:
-				if (create_jail(j) < 0)
-					continue;
-				if (iflag)
-					printf("%d\n", j->jid);
-				if (jfp != NULL)
-					print_jail(jfp, j, oldcl);
-				if (verbose >= 0 && (j->name || verbose > 0))
-					jail_note(j, "created\n");
-				dep_done(j, DF_LIGHT);
-				if (bool_param(j->intparams[KP_VNET]) &&
-				    run_command(j, IP_VNET_INTERFACE))
-					continue;
-				/* FALLTHROUGH */
-			case IP_VNET_INTERFACE:
-				if (run_command(j, IP_EXEC_START))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_START:
-				if (run_command(j, IP_COMMAND))
-					continue;
-				/* FALLTHROUGH */
-			case IP_COMMAND:
-				if (run_command(j, IP_EXEC_POSTSTART))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_POSTSTART:
-			jail_create_done:
-				clear_persist(j);
-				dep_done(j, 0);
+				j->comparam == startcommands + 1;
+			} else if (*j->comparam == IP__OP) {
+				if (j->flags & JF_FAILED) {
+					if (jail_remove(j->jid) == 0 &&
+					    verbose >= 0 &&
+					    (j->name || verbose > 0))
+						jail_note(j, "removed\n");
+					j->jid = -1;
+					j->flags &= ~JF_PERSIST;
+					j->comparam--;
+				} else if (create_jail(j) < 0) {
+					j->comparam--;
+				} else {
+					if (verbose >= 0 &&
+					    (j->name || verbose > 0))
+						jail_note(j, "created\n");
+					dep_done(j, DF_LIGHT);
+					j->comparam++;
+				}
 			}
+			if (next_command(j))
+				continue;
+		jail_create_done:
+			clear_persist(j);
+			if (iflag)
+				printf("%d\n", j->jid);
+			if (jfp != NULL)
+				print_jail(jfp, j, oldcl);
+			dep_done(j, 0);
 			break;
 
 		case JF_SET:
-			/*
-			 * 1: check existence and dependencies
-			 * 2: update the jail
-			 */
 			if (j->jid < 0 && !(j->flags & JF_DEPEND)) {
 				warnx("\"%s\" not found", j->name);
 				failed(j);
@@ -460,17 +439,7 @@ main(int argc, char **argv)
 
 		case JF_STOP:
 		case JF_RESTART:
-			/*
-			 * 1: check dependencies and existence (note order)
-			 * 2: run any exec.prestop commands
-			 * 3: run any exec.stop commands
-			 * 4: send SIGTERM to all jail processes
-			 * 5: remove the jail
-			 * 6: run any exec.poststop commands
-			 * 7: take down IP addresses
-			 */
-			switch (j->comparam) {
-			default:
+			if (j->comparam == NULL) {
 				if (dep_check(j))
 					continue;
 				if (j->jid < 0) {
@@ -480,60 +449,28 @@ main(int argc, char **argv)
 						    j->name);
 					goto jail_remove_done;
 				}
-				if (run_command(j, IP_EXEC_PRESTOP))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_PRESTOP:
-				if (run_command(j, IP_EXEC_STOP))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_STOP:
-				if (run_command(j, IP_STOP_TIMEOUT))
-					continue;
-				/* FALLTHROUGH */
-			case IP_STOP_TIMEOUT:
-				(void)jail_remove(j->jid);
-				j->jid = -1;
-				if (verbose >= 0 &&
+				j->comparam == stopcommands + 1;
+			} else if ((j->flags & JF_FAILED) && j->jid > 0) {
+				goto jail_remove_done;
+			} else if (*j->comparam == IP__OP) {
+				if (jail_remove(j->jid) == 0 &&
+				    verbose >= 0 &&
 				    (docf || argc > 1 ||
 				     wild_jail_name(argv[0]) || verbose > 0))
 					jail_note(j, "removed\n");
+				j->jid = -1;
 				dep_done(j, DF_LIGHT);
-				if (run_command(j, IP_EXEC_POSTSTOP))
-					continue;
-				/* FALLTHROUGH */
-			case IP_EXEC_POSTSTOP:
-				if (run_command(j, IP_MOUNT_DEVFS))
-					continue;
-				/* FALLTHROUGH */
-			case IP_MOUNT_DEVFS:
-				if (run_command(j, IP__MOUNT_FROM_FSTAB))
-					continue;
-				/* FALLTHROUGH */
-			case IP__MOUNT_FROM_FSTAB:
-				if (run_command(j, IP_MOUNT))
-					continue;
-				/* FALLTHROUGH */
-			case IP_MOUNT:
-				if (run_command(j, IP__IP4_IFADDR))
-					continue;
-				/* FALLTHROUGH */
-			case IP__IP4_IFADDR:
-#ifdef INET6
-				if (run_command(j, IP__IP6_IFADDR))
-					continue;
-				/* FALLTHROUGH */
-			case IP__IP6_IFADDR:
-#endif
-			jail_remove_done:
-				dep_done(j, 0);
-				if (j->flags & JF_START) {
-					j->comparam = 0;
-					j->flags &= ~JF_STOP;
-					dep_reset(j);
-					requeue(j,
-					    j->ndeps ? &depend : &ready);
-				}
+				j->comparam++;
+			}
+			if (next_command(j))
+				continue;
+		jail_remove_done:
+			dep_done(j, 0);
+			if ((j->flags & (JF_START | JF_FAILED)) == JF_START) {
+				j->comparam = NULL;
+				j->flags &= ~JF_STOP;
+				dep_reset(j);
+				requeue(j, j->ndeps ? &depend : &ready);
 			}
 			break;
 		}

Modified: projects/jailconf/usr.sbin/jail/jailp.h
==============================================================================
--- projects/jailconf/usr.sbin/jail/jailp.h	Fri Jun 17 16:06:13 2011	(r223188)
+++ projects/jailconf/usr.sbin/jail/jailp.h	Fri Jun 17 16:18:44 2011	(r223189)
@@ -59,11 +59,9 @@
 #define JF_FAILED	0x0020	/* Operation failed */
 #define JF_PARAMS	0x0040	/* Parameters checked and imported */
 #define JF_RDTUN	0x0080	/* Create-only parameter check has been done */
-#define JF_IFUP		0x0100	/* IP addresses have been configured */
-#define JF_MOUNTED	0x0200	/* Filesystems have been mounted */
-#define JF_PERSIST	0x0400	/* Jail is temporarily persistent */
-#define JF_TIMEOUT	0x0800	/* A command (or process kill) timed out */
-#define JF_SLEEPQ	0x2000	/* Waiting on a command and/or timeout */
+#define JF_PERSIST	0x0100	/* Jail is temporarily persistent */
+#define JF_TIMEOUT	0x0200	/* A command (or process kill) timed out */
+#define JF_SLEEPQ	0x0400	/* Waiting on a command and/or timeout */
 
 #define JF_OP_MASK		(JF_START | JF_SET | JF_STOP)
 #define JF_RESTART		(JF_START | JF_STOP)
@@ -102,6 +100,7 @@ enum intparam {
 	IP__IP6_IFADDR,		/* Copy of ip6.addr with interface/prefixlen */
 #endif
 	IP__MOUNT_FROM_FSTAB,	/* Line from mount.fstab file */
+	IP__OP,			/* Placeholder for requested operation */
 	KP_ALLOW_CHFLAGS,
 	KP_ALLOW_MOUNT,
 	KP_ALLOW_RAW_SOCKETS,
@@ -164,7 +163,7 @@ struct cfjail {
 	struct cfstring		*comstring;
 	struct jailparam	*jp;
 	struct timespec		timeout;
-	enum intparam		comparam;
+	const enum intparam	*comparam;
 	unsigned		flags;
 	int			jid;
 	int			seq;
@@ -187,7 +186,7 @@ extern void failed(struct cfjail *j);
 extern void jail_note(const struct cfjail *j, const char *fmt, ...);
 extern void jail_warnx(const struct cfjail *j, const char *fmt, ...);
 
-extern int run_command(struct cfjail *j, enum intparam comparam);
+extern int next_command(struct cfjail *j);
 extern int finish_command(struct cfjail *j);
 extern struct cfjail *next_proc(int nonblock);
 


More information about the svn-src-projects mailing list