jls: add a -c mode to check for a jail's existence

This is intended to be primarily used in scripts that want to check if
a jail exists before taking some action -- for instance, the jail(8)
test cleanup functions that want to remove the jail if it still exists.
Having a mode that limits its output for their usage is useful both
for cleaner scripts and also to avoid masking real problems.

Reviewed by:	jamie
Differential Revision:	https://reviews.freebsd.org/D51541
This commit is contained in:
Kyle Evans 2025-07-25 22:13:43 -05:00
parent dbaaadd437
commit 1d85903710
2 changed files with 62 additions and 6 deletions

View file

@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 13, 2025
.Dd July 25, 2025
.Dt JLS 8
.Os
.Sh NAME
@ -35,6 +35,10 @@
.Op Fl dhNnqsv
.Op Fl j Ar jail
.Op Ar parameter ...
.Nm
.Fl c
.Op Fl d
.Fl j Ar jail
.Sh DESCRIPTION
The
.Nm
@ -54,11 +58,21 @@ for a description of some core parameters.
If no
.Ar parameters
or any of the options
.Fl hns
.Fl chns
are given, the following four columns will be printed:
jail identifier (jid), IP address (ip4.addr), hostname (host.hostname),
and path (path).
.Pp
When the
.Fl c
option is used,
.Nm
will not emit any output except for usage errors.
This mode is intended solely to check for a single jail's existence, and it does
not accept any
.Ar parameter
or print-option flags.
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl -libxo
@ -68,6 +82,8 @@ in a selection of different human and machine readable formats.
See
.Xr xo_options 7
for details on command line arguments.
.It Fl c
Only check for the jail's existence.
.It Fl d
List
.Va dying

View file

@ -37,6 +37,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <jail.h>
@ -59,6 +60,7 @@
#define PRINT_SKIP 0x10
#define PRINT_VERBOSE 0x20
#define PRINT_JAIL_NAME 0x40
#define PRINT_EXISTS 0x80
static struct jailparam *params;
static int *param_parent;
@ -81,6 +83,14 @@ static void quoted_print(int pflags, char *name, char *value);
static void emit_ip_addr_list(int af_family, const char *list_name,
struct jailparam *param);
static void
usage(void)
{
xo_errx(1,
"usage: jls [-dhNnqv] [-j jail] [param ...]\n"
" jls -c [-d] -j jail");
}
int
main(int argc, char **argv)
{
@ -94,12 +104,15 @@ main(int argc, char **argv)
xo_set_version(JLS_XO_VERSION);
jname = NULL;
pflags = jflags = jid = 0;
while ((c = getopt(argc, argv, "adj:hNnqsv")) >= 0)
while ((c = getopt(argc, argv, "acdj:hNnqsv")) >= 0)
switch (c) {
case 'a':
case 'd':
jflags |= JAIL_DYING;
break;
case 'c':
pflags |= PRINT_EXISTS;
break;
case 'j':
jid = strtoul(optarg, &ep, 10);
if (!jid || *ep) {
@ -130,7 +143,7 @@ main(int argc, char **argv)
PRINT_VERBOSE;
break;
default:
xo_errx(1, "usage: jls [-dhNnqv] [-j jail] [param ...]");
usage();
}
#ifdef INET6
@ -144,7 +157,24 @@ main(int argc, char **argv)
argv += optind;
/* Add the parameters to print. */
if (argc == 0) {
if ((pflags & PRINT_EXISTS) != 0) {
if ((pflags & ~PRINT_EXISTS) != 0) {
xo_warnx("-c is incompatible with other print options");
usage();
} else if (argc != 0) {
xo_warnx("-c does not accept non-option arguments");
usage();
} else if (jid == 0 && jname == NULL) {
xo_warnx("-j jail to check must be provided for -c");
usage();
}
/*
* Force libxo to be silent, as well -- we're only wanting our
* exit status.
*/
xo_set_style(NULL, XO_STYLE_TEXT);
} else if (argc == 0) {
if (pflags & (PRINT_HEADER | PRINT_NAMEVAL))
add_param("all", NULL, (size_t)0, NULL, JP_USER);
else if (pflags & PRINT_VERBOSE) {
@ -239,9 +269,17 @@ main(int argc, char **argv)
xo_open_list("jail");
/* Fetch the jail(s) and print the parameters. */
if (jid != 0 || jname != NULL) {
if (print_jail(pflags, jflags) < 0)
if (print_jail(pflags, jflags) < 0) {
/*
* We omit errors from existential issues if we're just
* doing a -c check that the jail exists.
*/
if (pflags & PRINT_EXISTS)
exit(1);
xo_errx(1, "%s", jail_errmsg);
}
} else {
assert((pflags & PRINT_EXISTS) == 0);
for (lastjid = 0;
(lastjid = print_jail(pflags, jflags)) >= 0; )
;
@ -392,6 +430,8 @@ print_jail(int pflags, int jflags)
jid = jailparam_get(params, nparams, jflags);
if (jid < 0)
return jid;
else if (pflags & PRINT_EXISTS)
return 0;
xo_open_instance("jail");