summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamie <jamie@FreeBSD.org>2016-07-17 14:15:08 +0000
committerjamie <jamie@FreeBSD.org>2016-07-17 14:15:08 +0000
commit20a9e2385387eac2880c92072cc3507c169a0f59 (patch)
treec6857cb72261c17ac0ac770deaabfebf54953cfc
parentfe7d8eb771182dfb7f101007684e4676707922c8 (diff)
downloadFreeBSD-src-20a9e2385387eac2880c92072cc3507c169a0f59.zip
FreeBSD-src-20a9e2385387eac2880c92072cc3507c169a0f59.tar.gz
MFC r302856:
Fix up the order in which jail creation processes are run, to preserve the config file's order in the non-parallel-start case. PR: 209112
-rw-r--r--usr.sbin/jail/command.c19
-rw-r--r--usr.sbin/jail/jailp.h2
-rw-r--r--usr.sbin/jail/state.c8
3 files changed, 23 insertions, 6 deletions
diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c
index a374604..037ec7f 100644
--- a/usr.sbin/jail/command.c
+++ b/usr.sbin/jail/command.c
@@ -92,9 +92,13 @@ next_command(struct cfjail *j)
int create_failed, stopping;
if (paralimit == 0) {
- requeue(j, &runnable);
+ if (j->flags & JF_FROM_RUNQ)
+ requeue_head(j, &runnable);
+ else
+ requeue(j, &runnable);
return 1;
}
+ j->flags &= ~JF_FROM_RUNQ;
create_failed = (j->flags & (JF_STOP | JF_FAILED)) == JF_FAILED;
stopping = (j->flags & JF_STOP) != 0;
comparam = *j->comparam;
@@ -160,20 +164,23 @@ next_command(struct cfjail *j)
int
finish_command(struct cfjail *j)
{
+ struct cfjail *rj;
int error;
if (!(j->flags & JF_SLEEPQ))
return 0;
j->flags &= ~JF_SLEEPQ;
- if (*j->comparam == IP_STOP_TIMEOUT)
- {
+ if (*j->comparam == IP_STOP_TIMEOUT) {
j->flags &= ~JF_TIMEOUT;
j->pstatus = 0;
return 0;
}
paralimit++;
- if (!TAILQ_EMPTY(&runnable))
- requeue(TAILQ_FIRST(&runnable), &ready);
+ if (!TAILQ_EMPTY(&runnable)) {
+ rj = TAILQ_FIRST(&runnable);
+ rj->flags |= JF_FROM_RUNQ;
+ requeue(rj, &ready);
+ }
error = 0;
if (j->flags & JF_TIMEOUT) {
j->flags &= ~JF_TIMEOUT;
@@ -259,7 +266,7 @@ next_proc(int nonblock)
}
/*
- * Run a single command for a jail, possible inside the jail.
+ * Run a single command for a jail, possibly inside the jail.
*/
static int
run_command(struct cfjail *j)
diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h
index 4498f4b..5c4efd5 100644
--- a/usr.sbin/jail/jailp.h
+++ b/usr.sbin/jail/jailp.h
@@ -64,6 +64,7 @@
#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_FROM_RUNQ 0x0800 /* Has already been on the run queue */
#define JF_OP_MASK (JF_START | JF_SET | JF_STOP)
#define JF_RESTART (JF_START | JF_STOP)
@@ -223,6 +224,7 @@ extern struct cfjail *next_jail(void);
extern int start_state(const char *target, int docf, unsigned state,
int running);
extern void requeue(struct cfjail *j, struct cfjails *queue);
+extern void requeue_head(struct cfjail *j, struct cfjails *queue);
extern void yyerror(const char *);
extern int yylex(void);
diff --git a/usr.sbin/jail/state.c b/usr.sbin/jail/state.c
index 17b2a0c..6af2037 100644
--- a/usr.sbin/jail/state.c
+++ b/usr.sbin/jail/state.c
@@ -398,6 +398,14 @@ requeue(struct cfjail *j, struct cfjails *queue)
}
}
+void
+requeue_head(struct cfjail *j, struct cfjails *queue)
+{
+ TAILQ_REMOVE(j->queue, j, tq);
+ TAILQ_INSERT_HEAD(queue, j, tq);
+ j->queue = queue;
+}
+
/*
* Add a dependency edge between two jails.
*/
OpenPOWER on IntegriCloud