From owner-svn-src-all@freebsd.org Thu Jan 3 18:30:38 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DA4401432A16; Thu, 3 Jan 2019 18:30:37 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 770DF88ADF; Thu, 3 Jan 2019 18:30:37 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 68F2A2508D; Thu, 3 Jan 2019 18:30:37 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x03IUbtq007886; Thu, 3 Jan 2019 18:30:37 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x03IUa1L007882; Thu, 3 Jan 2019 18:30:36 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201901031830.x03IUa1L007882@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Thu, 3 Jan 2019 18:30:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r342738 - in stable/12: lib/libbe sbin/bectl sbin/bectl/tests X-SVN-Group: stable-12 X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in stable/12: lib/libbe sbin/bectl sbin/bectl/tests X-SVN-Commit-Revision: 342738 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 770DF88ADF X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.997,0]; NEURAL_HAM_SHORT(-0.97)[-0.968,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-0.998,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Jan 2019 18:30:38 -0000 Author: kevans Date: Thu Jan 3 18:30:36 2019 New Revision: 342738 URL: https://svnweb.freebsd.org/changeset/base/342738 Log: MFC r340722-r340723, r342466: bectl(8)/libbe(3) fixes r340722 (0mp): libbe(3): Put each error value in separate line. As requested by a TODO in the source code. r340723 (0mp): Cross-reference libbe(3) and bectl(8). Those two manual pages are already referencing each other in the HISTORY sections, which people might skip. Mention those manual pages explicitly in the SEE ALSO sections. Also, remove a reference to be(1) from libbe(3). r342466: bectl: use jail id as the default jail name for a boot environment By default, bectl is setting the jail 'name' parameter to the boot environment name, which causes an error when the boot environment name is not a valid jail name. With the attached fix, when no name is supplied, the default jail name will be the jail id - this is is the same behavior as the jail command. Additionally, this commit addresses two other bugs that prevented unjailing in scenarios where the jail name does not match the boot environment name: 1. In 'bectl_locate_jail', 'mountpoint' is used to resolve the boot environment path, but really 'mounted' should be used. 'mountpoint' is the path where the zfs dataset will be mounted. 'mounted' is the path where the dataset is actually mounted. 2. in 'bectl_search_jail_paths', 'jail_getv' would fail after the first call. Which is fine, if the boot environment you're unjailing is the next one up. According to 'man jail_getv', it's expecting name and value strings. 'jail_getv' is being passed an integer for the lastjid, so amend that to use a string instead. Test cases have been amended to reflect the bugs found. PR: 233637 Modified: stable/12/lib/libbe/libbe.3 stable/12/sbin/bectl/bectl.8 stable/12/sbin/bectl/bectl_jail.c stable/12/sbin/bectl/tests/bectl_test.sh Directory Properties: stable/12/ (props changed) Modified: stable/12/lib/libbe/libbe.3 ============================================================================== --- stable/12/lib/libbe/libbe.3 Thu Jan 3 16:47:05 2019 (r342737) +++ stable/12/lib/libbe/libbe.3 Thu Jan 3 18:30:36 2019 (r342738) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 17, 2018 +.Dd November 21, 2018 .Dt LIBBE 3 .Os .Sh NAME @@ -440,32 +440,51 @@ The .Fn be_prop_list_free function will free the property list. .Sh DIAGNOSTICS -Upon error, one of the following values will be returned. -.\" TODO: make each entry on its own line. -.Bd -ragged -offset indent -BE_ERR_SUCCESS, -BE_ERR_INVALIDNAME, -BE_ERR_EXISTS, -BE_ERR_NOENT, -BE_ERR_PERMS, -BE_ERR_DESTROYACT, -BE_ERR_DESTROYMNT, -BE_ERR_BADPATH, -BE_ERR_PATHBUSY, -BE_ERR_PATHLEN, -BE_ERR_BADMOUNT, -BE_ERR_NOORIGIN, -BE_ERR_MOUNTED, -BE_ERR_NOMOUNT, -BE_ERR_ZFSOPEN, -BE_ERR_ZFSCLONE, -BE_ERR_IO, -BE_ERR_NOPOOL, -BE_ERR_NOMEM, +Upon error, one of the following values will be returned: +.Bl -dash -offset indent -compact +.It +BE_ERR_SUCCESS +.It +BE_ERR_INVALIDNAME +.It +BE_ERR_EXISTS +.It +BE_ERR_NOENT +.It +BE_ERR_PERMS +.It +BE_ERR_DESTROYACT +.It +BE_ERR_DESTROYMNT +.It +BE_ERR_BADPATH +.It +BE_ERR_PATHBUSY +.It +BE_ERR_PATHLEN +.It +BE_ERR_BADMOUNT +.It +BE_ERR_NOORIGIN +.It +BE_ERR_MOUNTED +.It +BE_ERR_NOMOUNT +.It +BE_ERR_ZFSOPEN +.It +BE_ERR_ZFSCLONE +.It +BE_ERR_IO +.It +BE_ERR_NOPOOL +.It +BE_ERR_NOMEM +.It BE_ERR_UNKNOWN -.Ed +.El .Sh SEE ALSO -.Xr be 1 +.Xr bectl 8 .Sh HISTORY .Nm and its corresponding command, Modified: stable/12/sbin/bectl/bectl.8 ============================================================================== --- stable/12/sbin/bectl/bectl.8 Thu Jan 3 16:47:05 2019 (r342737) +++ stable/12/sbin/bectl/bectl.8 Thu Jan 3 18:30:36 2019 (r342738) @@ -18,7 +18,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 24, 2018 +.Dd December 25, 2018 .Dt BECTL 8 .Os .Sh NAME @@ -52,7 +52,6 @@ .Cm jail .Brq Fl b | Fl U .Oo Bro Fl o Ar key Ns = Ns Ar value | Fl u Ar key Brc Oc Ns ... -.Brq Ar jailID | jailName .Ar bootenv .Op Ar utility Op Ar argument ... .Nm @@ -153,7 +152,6 @@ from .Cm jail .Brq Fl b | Fl U .Oo Bro Fl o Ar key Ns = Ns Ar value | Fl u Ar key Brc Oc Ns ... -.Brq Ar jailID | jailName .Ao Ar bootenv Ac .Op Ar utility Op Ar argument ... .Xc @@ -193,10 +191,7 @@ The .Va host.hostname , and .Va path -may not actually be unset. -Attempts to unset any of these will revert them to the default values specified -below, if they have been overwritten by -.Fl o . +must be set, the default values are specified below. .Pp All .Ar key Ns = Ns Ar value @@ -207,7 +202,7 @@ The following default parameters are provided: .It Va allow.mount Ta Cm true .It Va allow.mount.devfs Ta Cm true .It Va enforce_statfs Ta Cm 1 -.It Va name Ta Va bootenv +.It Va name Ta jail id .It Va host.hostname Ta Va bootenv .It Va path Ta Set to a path in /tmp generated by .Xr libbe 3 . @@ -263,6 +258,7 @@ will force the unmount if busy. To fill in with jail upgrade example when behavior is firm. .El .Sh SEE ALSO +.Xr libbe 3 , .Xr jail 8 , .Xr zfs 8 , .Xr zpool 8 Modified: stable/12/sbin/bectl/bectl_jail.c ============================================================================== --- stable/12/sbin/bectl/bectl_jail.c Thu Jan 3 16:47:05 2019 (r342737) +++ stable/12/sbin/bectl/bectl_jail.c Thu Jan 3 18:30:36 2019 (r342738) @@ -181,10 +181,10 @@ bectl_cmd_jail(int argc, char *argv[]) { char *bootenv, *mountpoint; int jid, opt, ret; - bool default_hostname, default_name, interactive, unjail; + bool default_hostname, interactive, unjail; pid_t pid; - default_hostname = default_name = interactive = unjail = true; + default_hostname = interactive = unjail = true; jpcnt = INIT_PARAMCOUNT; jp = malloc(jpcnt * sizeof(*jp)); if (jp == NULL) @@ -206,8 +206,6 @@ bectl_cmd_jail(int argc, char *argv[]) * optarg has been modified to null terminate * at the assignment operator. */ - if (strcmp(optarg, "name") == 0) - default_name = false; if (strcmp(optarg, "host.hostname") == 0) default_hostname = false; } @@ -217,8 +215,6 @@ bectl_cmd_jail(int argc, char *argv[]) break; case 'u': if ((ret = jailparam_delarg(optarg)) == 0) { - if (strcmp(optarg, "name") == 0) - default_name = true; if (strcmp(optarg, "host.hostname") == 0) default_hostname = true; } else if (ret != ENOENT) { @@ -259,8 +255,6 @@ bectl_cmd_jail(int argc, char *argv[]) return (1); } - if (default_name) - jailparam_add("name", bootenv); if (default_hostname) jailparam_add("host.hostname", bootenv); @@ -316,15 +310,23 @@ bectl_cmd_jail(int argc, char *argv[]) static int bectl_search_jail_paths(const char *mnt) { - char jailpath[MAXPATHLEN]; int jid; + char lastjid[16]; + char jailpath[MAXPATHLEN]; + /* jail_getv expects name/value strings */ + snprintf(lastjid, sizeof(lastjid), "%d", 0); + jid = 0; - (void)mnt; - while ((jid = jail_getv(0, "lastjid", &jid, "path", &jailpath, + while ((jid = jail_getv(0, "lastjid", lastjid, "path", &jailpath, NULL)) != -1) { + + /* the jail we've been looking for */ if (strcmp(jailpath, mnt) == 0) return (jid); + + /* update lastjid and keep on looking */ + snprintf(lastjid, sizeof(lastjid), "%d", jid); } return (-1); @@ -354,8 +356,11 @@ bectl_locate_jail(const char *ident) 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) { + + /* path where a boot environment is mounted */ + if (nvlist_lookup_string(props, "mounted", &mnt) == 0) { + + /* looking for a jail that matches our bootenv path */ jid = bectl_search_jail_paths(mnt); be_prop_list_free(belist); return (jid); Modified: stable/12/sbin/bectl/tests/bectl_test.sh ============================================================================== --- stable/12/sbin/bectl/tests/bectl_test.sh Thu Jan 3 16:47:05 2019 (r342737) +++ stable/12/sbin/bectl/tests/bectl_test.sh Thu Jan 3 18:30:36 2019 (r342738) @@ -254,6 +254,14 @@ bectl_jail_body() atf_check cp /rescue/rescue ${root}/rescue/rescue atf_check bectl -r ${zpool}/ROOT umount default + # Prepare a second boot environment + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default target + + # When a jail name is not explicit, it should match the jail id. + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o jid=233637 default + atf_check -o inline:"233637\n" -s exit:0 -x "jls -j 233637 name" + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default + # Basic command-mode tests, with and without jail cleanup atf_check -o inline:"rescue\n" bectl -r ${zpool}/ROOT \ jail default /rescue/rescue ls -1 @@ -271,6 +279,11 @@ bectl_jail_body() atf_check bectl -r ${zpool}/ROOT jail -b default atf_check bectl -r ${zpool}/ROOT unjail default atf_check -s not-exit:0 -x "jls | grep -F \"${root}\"" + # 'unjail' by BE name. Force bectl to lookup jail id by the BE name. + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b default + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o name=bectl_test target + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail target + atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default # cannot unjail an unjailed BE (by either command name) atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT ujail default atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT unjail default @@ -281,8 +294,24 @@ bectl_jail_body() atf_check -s not-exit:0 -x "mount | grep -F '${root}'" atf_check bectl -r ${zpool}/ROOT ujail default } + +# If a test has failed, it's possible that the boot environment hasn't +# been 'unjail'ed. We want to remove the jail before 'bectl_cleanup' +# attempts to destroy the zpool. bectl_jail_cleanup() { + for bootenv in "default" "target"; do + # mountpoint of the boot environment + mountpoint="$(bectl -r bectl_test/ROOT list -H | grep ${bootenv} | awk '{print $3}')" + + # see if any jail paths match the boot environment mountpoint + jailid="$(jls | grep ${mountpoint} | awk '{print $1}')" + + if [ -z "$jailid" ]; then + continue; + fi + jail -r ${jailid} + done; bectl_cleanup bectl_test }