Improvements in error messages:

Some errors printed the jail name for unnamed (command line) jails.

Attempting to create an already-existing jail from the command line
returned with no error (even for non-root) due to bad logic in
start_state.

Ignore kvm_proc errors, which are typically caused by permission
problems.  Instead, stop ignoring permission errors when removing
a jail (but continue to silently ignore other errors, i.e. the
jail no longer existing).  This makes non-root attempts at removing
a jail give a clearer error message.
This commit is contained in:
Jamie Gritton 2012-02-08 23:51:46 +00:00
parent 7ca65ae0fe
commit 1ca35de448
4 changed files with 44 additions and 18 deletions

View File

@ -274,7 +274,11 @@ run_command(struct cfjail *j)
case IP__OP:
if (down) {
(void)jail_remove(j->jid);
if (jail_remove(j->jid) < 0 && errno == EPERM) {
jail_warnx(j, "jail_remove: %s",
strerror(errno));
return -1;
}
if (verbose > 0 || (verbose == 0 && (j->flags & JF_STOP
? note_remove : j->name != NULL)))
jail_note(j, "removed\n");
@ -711,14 +715,14 @@ term_procs(struct cfjail *j)
return 0;
if (kd == NULL) {
kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "jail");
kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
if (kd == NULL)
exit(1);
return 0;
}
ki = kvm_getprocs(kd, KERN_PROC_PROC, 0, &pcnt);
if (ki == NULL)
exit(1);
return 0;
noted = 0;
for (i = 0; i < pcnt; i++)
if (ki[i].ki_jid == j->jid &&

View File

@ -62,6 +62,8 @@ static void clear_persist(struct cfjail *j);
static int update_jail(struct cfjail *j);
static int rdtun_params(struct cfjail *j, int dofail);
static void running_jid(struct cfjail *j, int dflag);
static void jail_quoted_warnx(const struct cfjail *j, const char *name_msg,
const char *noname_msg);
static int jailparam_set_note(const struct cfjail *j, struct jailparam *jp,
unsigned njp, int flags);
static void print_jail(FILE *fp, struct cfjail *j, int oldcl);
@ -317,10 +319,10 @@ main(int argc, char **argv)
error = 0;
if (op == JF_STOP) {
for (i = 0; i < argc; i++)
if (start_state(argv[i], op, Rflag) < 0)
if (start_state(argv[i], docf, op, Rflag) < 0)
error = 1;
} else {
if (start_state(docf ? argv[0] : NULL, op, 0) < 0)
if (start_state(argv[0], docf, op, 0) < 0)
exit(1);
}
@ -376,7 +378,8 @@ main(int argc, char **argv)
break;
case JF_SET_RESTART:
if (j->jid < 0) {
warnx("\"%s\" not found", j->name);
jail_quoted_warnx(j, "not found",
"no jail specified");
failed(j);
continue;
}
@ -396,7 +399,8 @@ main(int argc, char **argv)
if (j->comparam == NULL) {
if (j->jid > 0 &&
!(j->flags & (JF_DEPEND | JF_WILD))) {
warnx("\"%s\" already exists", j->name);
jail_quoted_warnx(j, "already exists",
NULL);
failed(j);
continue;
}
@ -420,7 +424,8 @@ main(int argc, char **argv)
case JF_SET:
if (j->jid < 0 && !(j->flags & JF_DEPEND)) {
warnx("\"%s\" not found", j->name);
jail_quoted_warnx(j, "not found",
"no jail specified");
failed(j);
continue;
}
@ -444,8 +449,8 @@ main(int argc, char **argv)
if (j->jid < 0) {
if (!(j->flags & (JF_DEPEND | JF_WILD))
&& verbose >= 0)
warnx("\"%s\" not found",
j->name);
jail_quoted_warnx(j,
"not found", NULL);
goto jail_remove_done;
}
j->comparam = stopcommands;
@ -834,6 +839,19 @@ running_jid(struct cfjail *j, int dflag)
j->jid = jail_get(jiov, 2, dflag ? JAIL_DYING : 0);
}
static void
jail_quoted_warnx(const struct cfjail *j, const char *name_msg,
const char *noname_msg)
{
const char *pval;
if ((pval = j->name) || (pval = string_param(j->intparams[KP_JID])) ||
(pval = string_param(j->intparams[KP_NAME])))
warnx("\"%s\" %s", pval, name_msg);
else
warnx("%s", noname_msg);
}
/*
* Set jail parameters and possible print them out.
*/

View File

@ -215,7 +215,8 @@ extern int dep_check(struct cfjail *j);
extern void dep_done(struct cfjail *j, unsigned flags);
extern void dep_reset(struct cfjail *j);
extern struct cfjail *next_jail(void);
extern int start_state(const char *target, unsigned state, int running);
extern int start_state(const char *target, int docf, unsigned state,
int running);
extern void requeue(struct cfjail *j, struct cfjails *queue);
extern void yyerror(const char *);

View File

@ -128,7 +128,7 @@ dep_setup(int docf)
/* Look for dependency loops. */
if (deps && (deps > 1 || ldeps)) {
(void)start_state(NULL, 0, 0);
(void)start_state(NULL, 0, 0, 0);
while ((j = TAILQ_FIRST(&ready))) {
requeue(j, &cfjails);
dep_done(j, DF_NOFAIL);
@ -300,20 +300,23 @@ next_jail(void)
* Set jails to the proper start state.
*/
int
start_state(const char *target, unsigned state, int running)
start_state(const char *target, int docf, unsigned state, int running)
{
struct iovec jiov[6];
struct cfjail *j, *tj;
int jid;
char namebuf[MAXHOSTNAMELEN];
if (!target || (!running && !strcmp(target, "*"))) {
if (!target || (!docf && state != JF_STOP) ||
(!running && !strcmp(target, "*"))) {
/*
* If there's no target specified, set the state on all jails,
* and start with those that have no dependencies.
* For a global wildcard (including no target specified),
* set the state on all jails and start with those that
* have no dependencies.
*/
TAILQ_FOREACH_SAFE(j, &cfjails, tq, tj) {
j->flags = (j->flags & JF_FAILED) | state | JF_WILD;
j->flags = (j->flags & JF_FAILED) | state |
(docf ? JF_WILD : 0);
dep_reset(j);
requeue(j, j->ndeps ? &depend : &ready);
}