Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Jul 2018 03:14:58 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r336730 - projects/bectl/sbin/bectl
Message-ID:  <201807260314.w6Q3Ewhf008665@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Thu Jul 26 03:14:58 2018
New Revision: 336730
URL: https://svnweb.freebsd.org/changeset/base/336730

Log:
  bectl(8): Support unjailing a boot environment
  
  The given parameter may either be a jid, jail name, or a BE name.  In all
  cases, the parameter will be resolved to a jid and bectl(8) will
  sanity-check that there's actually a BE mounted at the requested jail root
  before invoking jail_remove(2).

Modified:
  projects/bectl/sbin/bectl/Makefile
  projects/bectl/sbin/bectl/bectl.8
  projects/bectl/sbin/bectl/bectl.c

Modified: projects/bectl/sbin/bectl/Makefile
==============================================================================
--- projects/bectl/sbin/bectl/Makefile	Thu Jul 26 03:13:07 2018	(r336729)
+++ projects/bectl/sbin/bectl/Makefile	Thu Jul 26 03:14:58 2018	(r336730)
@@ -4,6 +4,7 @@ PROG=	bectl
 MAN=	bectl.8
 
 LIBADD+= be
+LIBADD+= jail
 LIBADD+= nvpair
 
 CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common

Modified: projects/bectl/sbin/bectl/bectl.8
==============================================================================
--- projects/bectl/sbin/bectl/bectl.8	Thu Jul 26 03:13:07 2018	(r336729)
+++ projects/bectl/sbin/bectl/bectl.8	Thu Jul 26 03:14:58 2018	(r336730)
@@ -175,8 +175,7 @@ Specifying
 .Fl f
 will force the unmount if busy.
 .Pp
-.It Ic unjail
-.Ao Ar beName Ac
+.It Ic unjail Ao Ar jailID | jailName | beName Ac
 .Pp
 Destroys the jail created from the given boot environment.
 .Pp

Modified: projects/bectl/sbin/bectl/bectl.c
==============================================================================
--- projects/bectl/sbin/bectl/bectl.c	Thu Jul 26 03:13:07 2018	(r336729)
+++ projects/bectl/sbin/bectl/bectl.c	Thu Jul 26 03:14:58 2018	(r336730)
@@ -30,6 +30,7 @@
 #include <sys/jail.h>
 #include <sys/mount.h>
 #include <errno.h>
+#include <jail.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -50,6 +51,8 @@ static int bectl_cmd_jail(int argc, char *argv[]);
 static int bectl_cmd_list(int argc, char *argv[]);
 static int bectl_cmd_mount(int argc, char *argv[]);
 static int bectl_cmd_rename(int argc, char *argv[]);
+static int bectl_search_jail_paths(const char *mnt);
+static int bectl_locate_jail(const char *ident);
 static int bectl_cmd_unjail(int argc, char *argv[]);
 static int bectl_cmd_unmount(int argc, char *argv[]);
 
@@ -74,7 +77,7 @@ usage(bool explicit)
 	    "\tbectl list [-a] [-D] [-H] [-s]\n"
 	    "\tbectl mount beName [mountpoint]\n"
 	    "\tbectl rename origBeName newBeName\n"
-	    "\tbectl { ujail | unjail } ⟨jailID | jailName⟩ bootenv\n"
+	    "\tbectl { ujail | unjail } ⟨jailID | jailName | bootenv)\n"
 	    "\tbectl { umount | unmount } [-f] beName\n");
 
 	return (explicit ? 0 : EX_USAGE);
@@ -447,7 +450,6 @@ bectl_cmd_list(int argc, char *argv[])
 		return (usage(false));
 	}
 
-
 	if (be_prop_list_alloc(&props) != 0) {
 		fprintf(stderr, "bectl list: failed to allocate prop nvlist\n");
 		return (1);
@@ -534,41 +536,100 @@ bectl_cmd_rename(int argc, char *argv[])
 	return (0);
 }
 
+static int
+bectl_search_jail_paths(const char *mnt)
+{
+	char jailpath[MAXPATHLEN + 1];
+	int jid;
 
+	jid = 0;
+	(void)mnt;
+	while ((jid = jail_getv(0, "lastjid", &jid, "path", &jailpath,
+	    NULL)) != -1) {
+		if (strcmp(jailpath, mnt) == 0)
+			return (jid);
+	}
+
+	return (-1);
+}
+
+/*
+ * Locate a jail based on an arbitrary identifier.  This may be either a name,
+ * a jid, or a BE name.  Returns the jid or -1 on failure.
+ */
 static int
-bectl_cmd_unjail(int argc, char *argv[])
+bectl_locate_jail(const char *ident)
 {
-	char *cmd, *target;
-	int opt;
-	bool force;
+	nvlist_t *belist, *props;
+	char *mnt;
+	int jid;
 
-	/* Store alias used */
-	cmd = argv[0];
+	/* Try the easy-match first */
+	jid = jail_getid(ident);
+	if (jid != -1)
+		return (jid);
 
-	force = false;
-	while ((opt = getopt(argc, argv, "f")) != -1) {
-		switch (opt) {
-		case 'f':
-			force = true;
-			break;
-		default:
-			fprintf(stderr, "bectl %s: unknown option '-%c'\n",
-			    cmd, optopt);
-			return (usage(false));
+	/* Attempt to try it as a BE name, first */
+	if (be_prop_list_alloc(&belist) != 0)
+		return (-1);
+
+	if (be_get_bootenv_props(be, belist) != 0)
+		return (-1);
+
+	if (nvlist_lookup_nvlist(belist, ident, &props) == 0) {
+		/* We'll attempt to resolve the jid by way of mountpoint */
+		if (nvlist_lookup_string(props, "mountpoint", &mnt) == 0) {
+			jid = bectl_search_jail_paths(mnt);
+			be_prop_list_free(belist);
+			return (jid);
 		}
+
+		be_prop_list_free(belist);
 	}
 
-	argc -= optind;
-	argv += optind;
+	return (-1);
+}
 
-	if (argc != 1) {
+static int
+bectl_cmd_unjail(int argc, char *argv[])
+{
+	char path[MAXPATHLEN + 1];
+	char *cmd, *name, *target;
+	int jid;
+
+	/* Store alias used */
+	cmd = argv[0];
+
+	if (argc != 2) {
 		fprintf(stderr, "bectl %s: wrong number of arguments\n", cmd);
 		return (usage(false));
 	}
 
-	target = argv[0];
+	target = argv[1];
 
-	/* unjail logic goes here */
+	/* Locate the jail */
+	if ((jid = bectl_locate_jail(target)) == -1) {
+		fprintf(stderr, "bectl %s: failed to locate BE by '%s'\n", cmd, target);
+		return (1);
+	}
+
+	bzero(&path, MAXPATHLEN + 1);
+	name = jail_getname(jid);
+	if (jail_getv(0, "name", name, "path", path, NULL) != jid) {
+		free(name);
+		fprintf(stderr, "bectl %s: failed to get path for jail requested by '%s'\n", cmd, target);
+		return (1);
+	}
+
+	free(name);
+
+	if (be_mounted_at(be, path, NULL) != 0) {
+		fprintf(stderr, "bectl %s: jail requested by '%s' not a BE\n", cmd, target);
+		return (1);
+	}
+
+	jail_remove(jid);
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807260314.w6Q3Ewhf008665>