run_command (mostly) cleanup:

Make the parallelism limit a global instead of always passing it
 to run_command and finish_command.
In the case of an empty command string, try to run any other strings
 the command may have.
Replace JF_BACKGROUND with its sort-of opposite JF_SLEEPQ.
Change j->comstring earlier to render JF_RUNQ unncessary.
Change the if-else series to a more readable switch statement.
Treat IP_STOP_TIMEOUT like a command, calling run_command which then
 calls term_procs.
When the IP_STOP_TIMEOUT "command" finishes, it shouldn't mess with
 the parallelism limit.
Make sufficient checks in finish_command and run_command so that
 the nonintuitive j->comstring null check isn't necessary to run them.
Rename the "waiting" queue to "depend", because the "sleeping" and
 "runnable" queues are also used to wait for something.
This commit is contained in:
Jamie Gritton 2010-12-10 23:57:55 +00:00
parent 5264032f22
commit aa02af5404
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/jailconf/; revision=216367
4 changed files with 225 additions and 191 deletions

View File

@ -62,6 +62,8 @@ struct phash {
pid_t pid;
};
int paralimit = -1;
extern char **environ;
static int get_user_info(struct cfjail *j, const char *username,
@ -69,6 +71,7 @@ static int get_user_info(struct cfjail *j, const char *username,
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 check_path(struct cfjail *j, const char *pname, const char *path,
int isfile, const char *umount_type);
@ -81,7 +84,7 @@ static int kq;
* Run a command associated with a jail, possibly inside the jail.
*/
int
run_command(struct cfjail *j, int *plimit, enum intparam comparam)
run_command(struct cfjail *j, enum intparam comparam)
{
const struct passwd *pwd;
struct cfstring *comstring, *s;
@ -96,37 +99,47 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
static char *cleanenv;
if (comparam) {
if (comparam == IP_MOUNT_DEVFS
? !bool_param(j->intparams[IP_MOUNT_DEVFS])
: j->intparams[comparam] == NULL)
return 0;
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 =
STAILQ_FIRST(&j->intparams[comparam]->val);
}
j->comparam = comparam;
j->comstring = comparam == IP_MOUNT_DEVFS ? COMSTRING_DUMMY
: STAILQ_FIRST(&j->intparams[comparam]->val);
} else {
} else
comparam = j->comparam;
if (!(j->flags & JF_RUNQ))
j->comstring = j->comstring == COMSTRING_DUMMY
? NULL : STAILQ_NEXT(j->comstring, tq);
}
next_comstring:
comstring = j->comstring;
if (comstring == NULL ||
(comstring != COMSTRING_DUMMY && comstring->len == 0))
if (comstring == NULL)
return 0;
if (plimit && *plimit == 0) {
j->flags |= JF_RUNQ;
if (paralimit == 0) {
requeue(j, &runnable);
return 1;
}
j->flags &= ~(JF_RUNQ | JF_BACKGROUND);
j->comstring =
comstring == COMSTRING_DUMMY ? NULL : STAILQ_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 (XXX they should be
* truly internal).
* mounting build their own argument lists.
*/
bg = j->flags & JF_FAILED;
down = j->flags & (JF_STOP | JF_FAILED);
if (comparam == IP__IP4_IFADDR) {
switch (comparam) {
case IP_STOP_TIMEOUT:
/* This isn't really a command */
return term_procs(j);
case IP__IP4_IFADDR:
argv = alloca(8 * sizeof(char *));
*(const char **)&argv[0] = _PATH_IFCONFIG;
if ((cs = strchr(comstring->s, '|'))) {
@ -157,8 +170,10 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
*(const char **)&argv[argc] = down ? "-alias" : "alias";
argv[argc + 1] = NULL;
j->flags |= JF_IFUP;
break;
#ifdef INET6
} else if (comparam == IP__IP6_IFADDR) {
case IP__IP6_IFADDR:
argv = alloca(8 * sizeof(char *));
*(const char **)&argv[0] = _PATH_IFCONFIG;
if ((cs = strchr(comstring->s, '|'))) {
@ -181,8 +196,10 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
*(const char **)&argv[argc] = down ? "-alias" : "alias";
argv[argc + 1] = NULL;
j->flags |= JF_IFUP;
break;
#endif
} else if (comparam == IP_VNET_INTERFACE) {
case IP_VNET_INTERFACE:
argv = alloca(5 * sizeof(char *));
*(const char **)&argv[0] = _PATH_IFCONFIG;
argv[1] = comstring->s;
@ -192,7 +209,10 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
jidstr ? jidstr : string_param(j->intparams[KP_NAME]);
argv[4] = NULL;
j->flags |= JF_IFUP;
} else if (comparam == IP_MOUNT || comparam == IP__MOUNT_FROM_FSTAB) {
break;
case IP_MOUNT:
case IP__MOUNT_FROM_FSTAB:
argv = alloca(8 * sizeof(char *));
comcs = alloca(comstring->len + 1);
strcpy(comcs, comstring->s);
@ -201,7 +221,7 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
cs = strtok(NULL, " \t\f\v\r\n"))
argv[argc++] = cs;
if (argc == 0)
return 0;
goto next_comstring;
if (argc < 3) {
jail_warnx(j, "%s: %s: missing information",
j->intparams[comparam]->name, comstring->s);
@ -233,7 +253,9 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
}
*(const char **)&argv[1] = "-t";
j->flags |= JF_MOUNTED;
} else if (comparam == IP_MOUNT_DEVFS) {
break;
case IP_MOUNT_DEVFS:
path = string_param(j->intparams[KP_PATH]);
if (path == NULL) {
jail_warnx(j, "mount.devfs: no path");
@ -266,7 +288,11 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
argv[3] = NULL;
}
j->flags |= JF_MOUNTED;
} else if (comparam == IP_COMMAND && j->name == NULL) {
break;
case IP_COMMAND:
if (j->name != NULL)
goto default_command;
argc = 0;
STAILQ_FOREACH(s, &j->intparams[IP_COMMAND]->val, tq)
argc++;
@ -276,36 +302,40 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
argv[argc++] = s->s;
argv[argc] = NULL;
j->comstring = NULL;
} else if ((cs = strpbrk(comstring->s, "!\"$&'()*;<>?[\\]`{|}~")) &&
!(cs[0] == '&' && cs[1] == '\0')) {
argv = alloca(4 * sizeof(char *));
*(const char **)&argv[0] = _PATH_BSHELL;
*(const char **)&argv[1] = "-c";
argv[2] = comstring->s;
argv[3] = NULL;
} else {
if (cs) {
*cs = 0;
bg = 1;
}
comcs = alloca(comstring->len + 1);
strcpy(comcs, comstring->s);
argc = 0;
for (cs = strtok(comcs, " \t\f\v\r\n"); cs;
cs = strtok(NULL, " \t\f\v\r\n"))
argc++;
argv = alloca((argc + 1) * sizeof(char *));
strcpy(comcs, comstring->s);
argc = 0;
for (cs = strtok(comcs, " \t\f\v\r\n"); cs;
cs = strtok(NULL, " \t\f\v\r\n"))
argv[argc++] = cs;
argv[argc] = NULL;
}
if (argv[0] == NULL)
return 0;
break;
j->pstatus = 0;
default:
default_command:
if ((cs = strpbrk(comstring->s, "!\"$&'()*;<>?[\\]`{|}~")) &&
!(cs[0] == '&' && cs[1] == '\0')) {
argv = alloca(4 * sizeof(char *));
*(const char **)&argv[0] = _PATH_BSHELL;
*(const char **)&argv[1] = "-c";
argv[2] = comstring->s;
argv[3] = NULL;
} else {
if (cs) {
*cs = 0;
bg = 1;
}
comcs = alloca(comstring->len + 1);
strcpy(comcs, comstring->s);
argc = 0;
for (cs = strtok(comcs, " \t\f\v\r\n"); cs;
cs = strtok(NULL, " \t\f\v\r\n"))
argc++;
argv = alloca((argc + 1) * sizeof(char *));
strcpy(comcs, comstring->s);
argc = 0;
for (cs = strtok(comcs, " \t\f\v\r\n"); cs;
cs = strtok(NULL, " \t\f\v\r\n"))
argv[argc++] = cs;
argv[argc] = NULL;
}
}
if (argv[0] == NULL)
goto next_comstring;
if (int_param(j->intparams[IP_EXEC_TIMEOUT], &timeout) &&
timeout != 0) {
clock_gettime(CLOCK_REALTIME, &j->timeout);
@ -357,10 +387,11 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
err(1, "fork");
if (pid > 0) {
if (bg) {
j->flags |= JF_BACKGROUND;
free(j->comline);
j->comline = NULL;
requeue(j, &ready);
} else {
--*plimit;
paralimit--;
add_proc(j, pid);
}
return 1;
@ -434,15 +465,18 @@ run_command(struct cfjail *j, int *plimit, enum intparam comparam)
* Check command exit status
*/
int
finish_command(struct cfjail *j, int *plimit)
finish_command(struct cfjail *j)
{
int error;
if (j->flags & (JF_RUNQ | JF_BACKGROUND))
if (!(j->flags & JF_SLEEPQ))
return 0;
++*plimit;
if (!TAILQ_EMPTY(&runnable))
requeue(TAILQ_FIRST(&runnable), &ready);
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;
@ -458,10 +492,12 @@ finish_command(struct cfjail *j, int *plimit)
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;
}
@ -525,10 +561,92 @@ next_proc(int nonblock)
return NULL;
}
/*
* Add a process to the hash, tied to a jail.
*/
static void
add_proc(struct cfjail *j, pid_t pid)
{
struct kevent ke;
struct cfjail *tj;
struct phash *ph;
if (!kq && (kq = kqueue()) < 0)
err(1, "kqueue");
EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0)
err(1, "kevent");
ph = emalloc(sizeof(struct phash));
ph->j = j;
ph->pid = pid;
LIST_INSERT_HEAD(&phash[pid % PHASH_SIZE], ph, le);
j->nprocs++;
j->flags |= JF_SLEEPQ;
if (j->timeout.tv_sec == 0)
requeue(j, &sleeping);
else {
/* File the jail in the sleep queue acording to its timeout. */
TAILQ_REMOVE(j->queue, j, tq);
TAILQ_FOREACH(tj, &sleeping, tq) {
if (!tj->timeout.tv_sec ||
j->timeout.tv_sec < tj->timeout.tv_sec ||
(j->timeout.tv_sec == tj->timeout.tv_sec &&
j->timeout.tv_nsec <= tj->timeout.tv_nsec)) {
TAILQ_INSERT_BEFORE(tj, j, tq);
break;
}
}
if (tj == NULL)
TAILQ_INSERT_TAIL(&sleeping, j, tq);
j->queue = &sleeping;
}
}
/*
* Remove any processes from the hash that correspond to a jail.
*/
static void
clear_procs(struct cfjail *j)
{
struct kevent ke;
struct phash *ph, *tph;
int i;
j->nprocs = 0;
for (i = 0; i < PHASH_SIZE; i++)
LIST_FOREACH_SAFE(ph, &phash[i], le, tph)
if (ph->j == j) {
EV_SET(&ke, ph->pid, EVFILT_PROC, EV_DELETE,
NOTE_EXIT, 0, NULL);
(void)kevent(kq, &ke, 1, NULL, 0, NULL);
LIST_REMOVE(ph, le);
free(ph);
}
}
/*
* Find the jail that corresponds to an exited process.
*/
static struct cfjail *
find_proc(pid_t pid)
{
struct cfjail *j;
struct phash *ph;
LIST_FOREACH(ph, &phash[pid % PHASH_SIZE], le)
if (ph->pid == pid) {
j = ph->j;
LIST_REMOVE(ph, le);
free(ph);
return --j->nprocs ? NULL : j;
}
return NULL;
}
/*
* Send SIGTERM to all processes in a jail and wait for them to die.
*/
int
static int
term_procs(struct cfjail *j)
{
struct kinfo_proc *ki;
@ -573,85 +691,6 @@ term_procs(struct cfjail *j)
return 0;
}
/*
* Add a process to the hash, tied to a jail.
*/
static void
add_proc(struct cfjail *j, pid_t pid)
{
struct kevent ke;
struct cfjail *tj;
struct phash *ph;
if (!kq && (kq = kqueue()) < 0)
err(1, "kqueue");
EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0)
err(1, "kevent");
ph = emalloc(sizeof(struct phash));
ph->j = j;
ph->pid = pid;
LIST_INSERT_HEAD(&phash[pid % PHASH_SIZE], ph, le);
j->nprocs++;
if (j->timeout.tv_sec) {
TAILQ_REMOVE(j->queue, j, tq);
TAILQ_FOREACH(tj, &sleeping, tq) {
if (!tj->timeout.tv_sec ||
j->timeout.tv_sec < tj->timeout.tv_sec ||
(j->timeout.tv_sec == tj->timeout.tv_sec &&
j->timeout.tv_nsec <= tj->timeout.tv_nsec)) {
TAILQ_INSERT_BEFORE(tj, j, tq);
break;
}
}
if (tj == NULL)
TAILQ_INSERT_TAIL(&sleeping, j, tq);
j->queue = &sleeping;
} else
requeue(j, &sleeping);
}
/*
* Remove any processes from the hash that correspond to a jail.
*/
static void
clear_procs(struct cfjail *j)
{
struct kevent ke;
struct phash *ph, *tph;
int i;
j->nprocs = 0;
for (i = 0; i < PHASH_SIZE; i++)
LIST_FOREACH_SAFE(ph, &phash[i], le, tph)
if (ph->j == j) {
EV_SET(&ke, ph->pid, EVFILT_PROC, EV_DELETE,
NOTE_EXIT, 0, NULL);
(void)kevent(kq, &ke, 1, NULL, 0, NULL);
LIST_REMOVE(ph, le);
free(ph);
}
}
/*
* Find the jail that corresponds to an exited process.
*/
static struct cfjail *
find_proc(pid_t pid)
{
struct cfjail *j;
struct phash *ph;
LIST_FOREACH(ph, &phash[pid % PHASH_SIZE], le)
if (ph->pid == pid) {
j = ph->j;
LIST_REMOVE(ph, le);
free(ph);
return --j->nprocs ? NULL : j;
}
return NULL;
}
/*
* Look up a user in the passwd and login.conf files.
*/

View File

@ -91,11 +91,10 @@ main(int argc, char **argv)
size_t sysvallen;
unsigned op, pi;
int ch, docf, error, i, oldcl, sysval;
int dflag, iflag, plimit, Rflag;
int dflag, iflag, Rflag;
char enforce_statfs[4];
op = 0;
plimit = -1;
dflag = iflag = Rflag = 0;
docf = 1;
cfname = CONF_FILE;
@ -135,9 +134,9 @@ main(int argc, char **argv)
docf = 0;
break;
case 'p':
plimit = strtol(optarg, NULL, 10);
if (plimit == 0)
plimit = -1;
paralimit = strtol(optarg, NULL, 10);
if (paralimit == 0)
paralimit = -1;
break;
case 'q':
verbose = -1;
@ -293,18 +292,18 @@ main(int argc, char **argv)
if (j->flags & JF_FAILED) {
clear_persist(j);
if (j->flags & JF_MOUNTED) {
(void)run_command(j, NULL, IP_MOUNT_DEVFS);
if (run_command(j, NULL, IP__MOUNT_FROM_FSTAB))
while (run_command(j, NULL, 0)) ;
if (run_command(j, NULL, IP_MOUNT))
while (run_command(j, NULL, 0)) ;
(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, NULL, IP__IP4_IFADDR))
while (run_command(j, NULL, 0)) ;
if (run_command(j, IP__IP4_IFADDR))
while (run_command(j, 0)) ;
#ifdef INET6
if (run_command(j, NULL, IP__IP6_IFADDR))
while (run_command(j, NULL, 0)) ;
if (run_command(j, IP__IP6_IFADDR))
while (run_command(j, 0)) ;
#endif
}
error = 1;
@ -327,8 +326,7 @@ main(int argc, char **argv)
(j->flags & (JF_SET | JF_DEPEND)) == JF_SET
? dflag || bool_param(j->intparams[IP_ALLOW_DYING])
: 0);
if (j->comstring != NULL &&
(finish_command(j, &plimit) || run_command(j, &plimit, 0)))
if (finish_command(j) || run_command(j, 0))
continue;
switch (j->flags & JF_OP_MASK) {
@ -379,30 +377,30 @@ main(int argc, char **argv)
continue;
if (j->jid > 0)
goto jail_create_done;
if (run_command(j, &plimit, IP__IP4_IFADDR))
if (run_command(j, IP__IP4_IFADDR))
continue;
/* FALLTHROUGH */
case IP__IP4_IFADDR:
#ifdef INET6
if (run_command(j, &plimit, IP__IP6_IFADDR))
if (run_command(j, IP__IP6_IFADDR))
continue;
/* FALLTHROUGH */
case IP__IP6_IFADDR:
#endif
if (run_command(j, &plimit, IP_MOUNT))
if (run_command(j, IP_MOUNT))
continue;
/* FALLTHROUGH */
case IP_MOUNT:
if (run_command(j, &plimit,
if (run_command(j,
IP__MOUNT_FROM_FSTAB))
continue;
/* FALLTHROUGH */
case IP__MOUNT_FROM_FSTAB:
if (run_command(j, &plimit, IP_MOUNT_DEVFS))
if (run_command(j, IP_MOUNT_DEVFS))
continue;
/* FALLTHROUGH */
case IP_MOUNT_DEVFS:
if (run_command(j, &plimit, IP_EXEC_PRESTART))
if (run_command(j, IP_EXEC_PRESTART))
continue;
/* FALLTHROUGH */
case IP_EXEC_PRESTART:
@ -416,19 +414,19 @@ main(int argc, char **argv)
jail_note(j, "created\n");
dep_done(j, DF_LIGHT);
if (bool_param(j->intparams[KP_VNET]) &&
run_command(j, &plimit, IP_VNET_INTERFACE))
run_command(j, IP_VNET_INTERFACE))
continue;
/* FALLTHROUGH */
case IP_VNET_INTERFACE:
if (run_command(j, &plimit, IP_EXEC_START))
if (run_command(j, IP_EXEC_START))
continue;
/* FALLTHROUGH */
case IP_EXEC_START:
if (run_command(j, &plimit, IP_COMMAND))
if (run_command(j, IP_COMMAND))
continue;
/* FALLTHROUGH */
case IP_COMMAND:
if (run_command(j, &plimit, IP_EXEC_POSTSTART))
if (run_command(j, IP_EXEC_POSTSTART))
continue;
/* FALLTHROUGH */
case IP_EXEC_POSTSTART:
@ -482,16 +480,15 @@ main(int argc, char **argv)
j->name);
goto jail_remove_done;
}
if (run_command(j, &plimit, IP_EXEC_PRESTOP))
if (run_command(j, IP_EXEC_PRESTOP))
continue;
/* FALLTHROUGH */
case IP_EXEC_PRESTOP:
if (run_command(j, &plimit, IP_EXEC_STOP))
if (run_command(j, IP_EXEC_STOP))
continue;
/* FALLTHROUGH */
case IP_EXEC_STOP:
j->comparam = IP_STOP_TIMEOUT;
if (term_procs(j))
if (run_command(j, IP_STOP_TIMEOUT))
continue;
/* FALLTHROUGH */
case IP_STOP_TIMEOUT:
@ -502,29 +499,28 @@ main(int argc, char **argv)
wild_jail_name(argv[0]) || verbose > 0))
jail_note(j, "removed\n");
dep_done(j, DF_LIGHT);
if (run_command(j, &plimit, IP_EXEC_POSTSTOP))
if (run_command(j, IP_EXEC_POSTSTOP))
continue;
/* FALLTHROUGH */
case IP_EXEC_POSTSTOP:
if (run_command(j, &plimit, IP_MOUNT_DEVFS))
if (run_command(j, IP_MOUNT_DEVFS))
continue;
/* FALLTHROUGH */
case IP_MOUNT_DEVFS:
if (run_command(j, &plimit,
IP__MOUNT_FROM_FSTAB))
if (run_command(j, IP__MOUNT_FROM_FSTAB))
continue;
/* FALLTHROUGH */
case IP__MOUNT_FROM_FSTAB:
if (run_command(j, &plimit, IP_MOUNT))
if (run_command(j, IP_MOUNT))
continue;
/* FALLTHROUGH */
case IP_MOUNT:
if (run_command(j, &plimit, IP__IP4_IFADDR))
if (run_command(j, IP__IP4_IFADDR))
continue;
/* FALLTHROUGH */
case IP__IP4_IFADDR:
#ifdef INET6
if (run_command(j, &plimit, IP__IP6_IFADDR))
if (run_command(j, IP__IP6_IFADDR))
continue;
/* FALLTHROUGH */
case IP__IP6_IFADDR:
@ -536,7 +532,7 @@ main(int argc, char **argv)
j->flags &= ~JF_STOP;
dep_reset(j);
requeue(j,
j->ndeps ? &waiting : &ready);
j->ndeps ? &depend : &ready);
}
}
break;

View File

@ -63,8 +63,7 @@
#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_RUNQ 0x1000 /* Jail was in the run qeueue */
#define JF_BACKGROUND 0x2000 /* Command was run in the background */
#define JF_SLEEPQ 0x2000 /* Waiting on a command and/or timeout */
#define JF_OP_MASK (JF_START | JF_SET | JF_STOP)
#define JF_RESTART (JF_START | JF_STOP)
@ -188,10 +187,9 @@ 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, int *plimit, enum intparam comparam);
extern int finish_command(struct cfjail *j, int *plimit);
extern int run_command(struct cfjail *j, enum intparam comparam);
extern int finish_command(struct cfjail *j);
extern struct cfjail *next_proc(int nonblock);
extern int term_procs(struct cfjail *j);
extern void load_config(void);
extern struct cfjail *add_jail(void);
@ -220,6 +218,7 @@ extern int yyparse(void);
extern struct cfjails cfjails;
extern struct cfjails ready;
extern struct cfjails waiting;
extern struct cfjails depend;
extern const char *cfname;
extern int paralimit;
extern int verbose;

View File

@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include "jailp.h"
struct cfjails ready = TAILQ_HEAD_INITIALIZER(ready);
struct cfjails waiting = TAILQ_HEAD_INITIALIZER(waiting);
struct cfjails depend = TAILQ_HEAD_INITIALIZER(depend);
static void dep_add(struct cfjail *from, struct cfjail *to, unsigned flags);
static int cmp_jailptr(const void *a, const void *b);
@ -133,7 +133,7 @@ dep_setup(int docf)
requeue(j, &cfjails);
dep_done(j, DF_NOFAIL);
}
while ((j = TAILQ_FIRST(&waiting)) != NULL) {
while ((j = TAILQ_FIRST(&depend)) != NULL) {
jail_warnx(j, "dependency loop");
j->flags |= JF_FAILED;
do {
@ -222,7 +222,7 @@ dep_check(struct cfjail *j)
}
if (ndeps == 0)
return 0;
requeue(j, &waiting);
requeue(j, &depend);
return 1;
}
@ -256,7 +256,7 @@ dep_done(struct cfjail *j, unsigned flags)
jail_warnx(dj, "skipped");
dj->flags |= JF_FAILED;
}
if (!--dj->ndeps && dj->queue == &waiting)
if (!--dj->ndeps && dj->queue == &depend)
requeue(dj, &ready);
}
}
@ -315,7 +315,7 @@ start_state(const char *target, unsigned state, int running)
TAILQ_FOREACH_SAFE(j, &cfjails, tq, tj) {
j->flags = (j->flags & JF_FAILED) | state | JF_WILD;
dep_reset(j);
requeue(j, j->ndeps ? &waiting : &ready);
requeue(j, j->ndeps ? &depend : &ready);
}
} else if (wild_jail_name(target)) {
/*