Bug 233637 - bectl jail doesn't honour {jailID | jailName}
Summary: bectl jail doesn't honour {jailID | jailName}
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 12.0-RELEASE
Hardware: Any Any
: --- Affects Only Me
Assignee: Kyle Evans
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-29 14:30 UTC by Dave Cottlehuber
Modified: 2019-01-03 18:30 UTC (History)
3 users (show)

See Also:
kevans: mfc-stable12?


Attachments
bectl change default jail name from the boot environment name to the jail id (3.69 KB, patch)
2018-12-19 11:32 UTC, Robert Wing
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Cottlehuber freebsd_committer freebsd_triage 2018-11-29 14:30:28 UTC
So great to have this in base now.

TLDR this looks like a manpage addition, and/or a command line parsing bug. I'm happy to contribute text for the manpage changes, although it may need some massaging for man format.

I want to create a named jail of an existing BE that has a name that is also an invalid jail name.

According to my reading of bectl(8) this should work, passing in a name or jid as the first parameter after:

# bectl create next
# bectl jail prison next
specified boot environment does not exist
could not mount bootenv

The outcome I wanted, to create a jail with a known name/tag works just fine if I *don't* specify a parameter, however if you *need* to specify a parameter because the BE name is not a valid jail name, then we have a problem:

for example: If the BE name is e.g. 12.0-RC2 then it's not possible to use bectl at all:

# bectl list
BE              Active Mountpoint Space Created
default         NR     /          2.13G 2018-11-27 10:34
12.0-RC2-update -      -          636K  2018-11-29 13:59
# echo $RELEASE
12.0-RC2-update
# bectl jail ${RELEASE}
unable to create jail.  error: 2
# bectl jail next ${RELEASE}
specified boot environment does not exist
could not mount bootenv
# mount |grep be_; jls
zroot/ROOT/12.0-RC2-update on /tmp/be_mount.WVe0 (zfs, local, noatime, nfsv4acls)
   JID  IP Address      Hostname                      Path

Finally, it is actually still possible via:

# bectl jail -o name=next ${RELEASE}

# man bectl 

     jail {-b |	-U} [{-o key=value | -u	key}]... {jailID | jailName} <bootenv>
	       [utility	[argument ...]]
	       Creates a jail of the given boot	environment.  Multiple -o and
	       -u arguments may	be specified.  -o will set a jail parameter,
	       and -u will unset a jail	parameter.

	       By default, jails are created in	interactive mode and /bin/sh
	       is executed within the jail.  If	utility	is specified, it will
	       be executed instead of /bin/sh.	The jail will be destroyed and
	       the boot	environment unmounted when the command finishes	exe-
	       cuting, unless the -U argument is specified.

	       The -b argument enables batch mode, thereby disabling interac-
	       tive mode.  The -U argument will	be ignored in batch mode.

	       The name, host.hostname,	and 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	-o.

	       All key=value pairs are interpreted as jail parameters as
	       described in jail(8).  The following default parameters are
	       provided:

	       allow.mount	    true
	       allow.mount.devfs    true
	       enforce_statfs	    1
	       name		    bootenv
	       host.hostname	    bootenv
	       path		    Set	to a path in /tmp generated by
					libbe(3).
Comment 1 Robert Wing freebsd_committer freebsd_triage 2018-12-19 11:32:36 UTC
Created attachment 200258 [details]
bectl change default jail name from the boot environment name to the jail id

the patch is based off r342069
Comment 2 Robert Wing freebsd_committer freebsd_triage 2018-12-19 11:34:58 UTC
(In reply to Dave Cottlehuber from comment #0)

I made a revision for the patch: https://reviews.freebsd.org/D18607

# bectl jail ${RELEASE}
unable to create jail.  error: 2

By default, bectl is setting the jail 'name' parameter to the boot environment name, which causes the above error. 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.

During testing, when I started using the jail id as the default name, the jail would execute with no errors. However, bectl wasn't able to unjail a boot environment because it was failing to match the boot environment path with an existing jail path. The source of this problem was two bugs.

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 boot environment is 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. The attached patch uses a string for the lastjid instead.

Should now be possible to:

# echo $RELEASE
12.0-RC2-update
# bectl jail ${RELEASE}
...
# bectl unjail ${RELEASE}

The other examples:


I looked into the command line parsing a bit, it doesn't handle the format <jailID | jailName> <bootenv> <utility [...]>.

The documentation should be:      
jail {-b | -U} [{-o key=value | -u key}]... <bootenv> [utility [argument ...]]

Looking at this example:

# bectl create next

/* bectl is looking for the prison boot environment */
/* next is the utility that will be executed for the jail */
# bectl jail prison next
specified boot environment does not exist
could not mount bootenv

from your example:
# bectl jail next ${RELEASE}
specified boot environment does not exist
could not mount bootenv

In the above command, bectl is looking for the 'next' boot environment, which doesn't exist. IF it did though, ${RELEASE} is the utility that gets executed for the jail command.

I can help with manpage additions or tests if it looks like this patch is in the right direction.
Comment 3 Kyle Evans freebsd_committer freebsd_triage 2018-12-20 04:24:01 UTC
Take; Rob has brought this patch into the Phabricator and further progress will happen there until the patch is committed.
Comment 4 commit-hook freebsd_committer freebsd_triage 2018-12-25 15:19:43 UTC
A commit references this bug:

Author: kevans
Date: Tue Dec 25 15:18:42 UTC 2018
New revision: 342466
URL: https://svnweb.freebsd.org/changeset/base/342466

Log:
  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
  Submitted by:	Rob <rob.fx907_gmail.com>
  MFC after:	3 days
  Differential Revision:	https://reviews.freebsd.org/D18607

Changes:
  head/sbin/bectl/bectl.8
  head/sbin/bectl/bectl_jail.c
  head/sbin/bectl/tests/bectl_test.sh
Comment 5 commit-hook freebsd_committer freebsd_triage 2019-01-03 18:30:48 UTC
A commit references this bug:

Author: kevans
Date: Thu Jan  3 18:30:37 UTC 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

Changes:
_U  stable/12/
  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