Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/jail/state.c
Show All 38 Lines | |||||
struct cfjails ready = TAILQ_HEAD_INITIALIZER(ready); | struct cfjails ready = TAILQ_HEAD_INITIALIZER(ready); | ||||
struct cfjails depend = TAILQ_HEAD_INITIALIZER(depend); | struct cfjails depend = TAILQ_HEAD_INITIALIZER(depend); | ||||
static void dep_add(struct cfjail *from, struct cfjail *to, unsigned flags); | static void dep_add(struct cfjail *from, struct cfjail *to, unsigned flags); | ||||
static int cmp_jailptr(const void *a, const void *b); | static int cmp_jailptr(const void *a, const void *b); | ||||
static int cmp_jailptr_name(const void *a, const void *b); | static int cmp_jailptr_name(const void *a, const void *b); | ||||
static struct cfjail *find_jail(const char *name); | static struct cfjail *find_jail(const char *name); | ||||
static int running_jid(const char *name, int flags); | static struct cfjail *running_jail(const char *name, int flags); | ||||
static struct cfjail **jails_byname; | static struct cfjail **jails_byname; | ||||
kevans: Explicit initialization to NULL shouldn't be required, since this is a global | |||||
static size_t njails; | static size_t njails; | ||||
/* | /* | ||||
* Set up jail dependency lists. | * Set up jail dependency lists. | ||||
*/ | */ | ||||
void | void | ||||
dep_setup(int docf) | dep_setup(int docf) | ||||
{ | { | ||||
Show All 9 Lines | dep_setup(int docf) | ||||
if (!docf) { | if (!docf) { | ||||
/* | /* | ||||
* With no config file, let "depend" for a single jail | * With no config file, let "depend" for a single jail | ||||
* look at currently running jails. | * look at currently running jails. | ||||
*/ | */ | ||||
if ((j = TAILQ_FIRST(&cfjails)) && | if ((j = TAILQ_FIRST(&cfjails)) && | ||||
(p = j->intparams[IP_DEPEND])) { | (p = j->intparams[IP_DEPEND])) { | ||||
TAILQ_FOREACH(s, &p->val, tq) { | TAILQ_FOREACH(s, &p->val, tq) { | ||||
if (running_jid(s->s, 0) < 0) { | if (running_jail(s->s, 0) == NULL) { | ||||
Not Done Inline ActionsI don't think this part can work. dep_setup is called exactly once- if !docf, then we never setup jails_byname just below and this condition is trivially true. I would consider, perhaps, reworking running_jail ever-so-slightly to take a struct cfjail **jail and populate *jail if jail != NULL -- and always returning the jid if it's running. kevans: I don't think this part can work. dep_setup is called exactly once- if `!docf`, then we never… | |||||
Done Inline Actions
mizhka: 1) running_jail returns running cfjail* even if there is no config file. So this part is… | |||||
Done Inline ActionsI suspect this leads to a segfault before we get to fake the cfjail *, though, with an uninitialized jails_byname kevans: I suspect this leads to a segfault before we get to fake the cfjail *, though, with an… | |||||
warnx("depends on nonexistent jail " | warnx("depends on nonexistent jail " | ||||
"\"%s\"", s->s); | "\"%s\"", s->s); | ||||
j->flags |= JF_FAILED; | j->flags |= JF_FAILED; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | if (running) { | ||||
requeue(j, &ready); | requeue(j, &ready); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
j = find_jail(target); | j = find_jail(target); | ||||
if (j == NULL && state == JF_STOP) { | if (j == NULL && state == JF_STOP) { | ||||
/* Allow -[rR] to specify a currently running jail. */ | /* Allow -[rR] to specify a currently running jail. */ | ||||
if ((jid = running_jid(target, JAIL_DYING)) > 0) { | j = running_jail(target, JAIL_DYING); | ||||
j = add_jail(); | |||||
j->name = estrdup(target); | |||||
j->jid = jid; | |||||
} | } | ||||
} | |||||
if (j == NULL) { | if (j == NULL) { | ||||
warnx("\"%s\" not found", target); | warnx("\"%s\" not found", target); | ||||
return -1; | return -1; | ||||
} | } | ||||
j->flags = (j->flags & JF_FAILED) | state; | j->flags = (j->flags & JF_FAILED) | state; | ||||
dep_reset(j); | dep_reset(j); | ||||
requeue(j, &ready); | requeue(j, &ready); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Find a jail object by name. | * Find a jail object by name. | ||||
*/ | */ | ||||
static struct cfjail * | static struct cfjail * | ||||
find_jail(const char *name) | find_jail(const char *name) | ||||
{ | { | ||||
struct cfjail **jp; | struct cfjail **jp; | ||||
if (jails_byname == NULL) | |||||
return NULL; | |||||
jp = bsearch(name, jails_byname, njails, sizeof(struct cfjail *), | jp = bsearch(name, jails_byname, njails, sizeof(struct cfjail *), | ||||
cmp_jailptr_name); | cmp_jailptr_name); | ||||
return jp ? *jp : NULL; | return jp ? *jp : NULL; | ||||
} | } | ||||
/* | /* | ||||
* Return the named jail's jid if it is running, and -1 if it isn't. | * Return jail if it is running, and NULL if it isn't. | ||||
*/ | */ | ||||
static int | static struct cfjail * | ||||
running_jid(const char *name, int flags) | running_jail(const char *name, int flags) | ||||
{ | { | ||||
struct iovec jiov[2]; | struct iovec jiov[4]; | ||||
struct cfjail *jail; | |||||
char *ep; | char *ep; | ||||
int jid; | char jailname[MAXHOSTNAMELEN]; | ||||
int jid, ret, len; | |||||
if ((jid = strtol(name, &ep, 10)) && !*ep) { | if ((jid = strtol(name, &ep, 10)) && !*ep) { | ||||
memset(jailname,0,sizeof(jailname)); | |||||
len = sizeof(jailname); | |||||
} else { | |||||
strncpy(jailname, name,sizeof(jailname)); | |||||
len = strlen(name) + 1; | |||||
jid = 0; | |||||
} | |||||
jiov[0].iov_base = __DECONST(char *, "jid"); | jiov[0].iov_base = __DECONST(char *, "jid"); | ||||
jiov[0].iov_len = sizeof("jid"); | jiov[0].iov_len = sizeof("jid"); | ||||
jiov[1].iov_base = &jid; | jiov[1].iov_base = &jid; | ||||
jiov[1].iov_len = sizeof(jid); | jiov[1].iov_len = sizeof(jid); | ||||
} else { | jiov[2].iov_base = __DECONST(char *, "name"); | ||||
jiov[0].iov_base = __DECONST(char *, "name"); | jiov[2].iov_len = sizeof("name"); | ||||
jiov[0].iov_len = sizeof("name"); | jiov[3].iov_base = &jailname; | ||||
jiov[1].iov_len = strlen(name) + 1; | jiov[3].iov_len = len; | ||||
jiov[1].iov_base = alloca(jiov[1].iov_len); | |||||
strcpy(jiov[1].iov_base, name); | if ((ret = jail_get(jiov, 4, flags)) < 0) | ||||
return (NULL); | |||||
if ((jail = find_jail(jailname)) == NULL) { | |||||
jail = add_jail(); | |||||
jail->name = estrdup(jailname); | |||||
jail->jid = ret; | |||||
} | } | ||||
return jail_get(jiov, 2, flags); | |||||
return (jail); | |||||
} | } |
Explicit initialization to NULL shouldn't be required, since this is a global