Bug 217545

Summary: jail: exec.poststop not executed, mount.fstab does not umount after removing jail
Product: Base System Reporter: Martin Birgmeier <d8zNeCFG>
Component: binAssignee: freebsd-jail (Nobody) <jail>
Status: Closed Unable to Reproduce    
Severity: Affects Only Me CC: dch, jamie, stefan
Priority: ---    
Version: 11.0-RELEASE   
Hardware: amd64   
OS: Any   

Description Martin Birgmeier 2017-03-04 21:02:52 UTC
I am configuring a jail where I want to mount a few filesystems before starting it, and unmount them after removing it. The jail config file contains

    command = "/bin/sh";

In order to mount/unmount the filesystems, I tried using either

    mount.fstab = "/path/to/jailfstab";

or

    exec.prestart = "/path/to/mount_shell_script";
    exec.poststop = "/path/to/unmount_shell_script";

In either case, the filesystems are mounted before strarting the jail, but when I leave the shell using ^D the filesystems are never unmounted.

While the man page does not promise that umounts will be done when using mount.fstab, exec.poststop should definitely be executed but is not.

-- Martin
Comment 1 Jamie Gritton freebsd_committer freebsd_triage 2017-03-05 17:39:31 UTC
Filesystems mounted with mount.fstab are indeed unmounted when a jail is stopped, and the exec.poststop command(s) are indeed executed.  But what you're doing isn't jail removal.

Am existing jail is removed by running "jail -r", which will run the prestop and stop commands, actually remove the jail, then run poststop commands and then clean up mounts and IP address assignments.  But note that you never ran "jail -r".

When a jail is created, it will (among other things) run the exec.start and/or "command" commands.  Those commands are not expected to all finish - generally the command is something like "sh /etc/rc" which starts daemons which continue to run.  If all commands complete, and the jail isn't marked with the "persist" parameter, the jail will naturally die on its own.  That has nothing to do with the jail(8) command, which is likely no longer running at the time, and which thus cannot running any of the shutdown commands.

If you intend on running jails this way, I recommend unmounting the filesystems not in exec.poststop, but in exec.poststart which runs as the last step in the creation process.
Comment 2 Martin Birgmeier 2017-03-06 17:27:46 UTC
I also tried this use case:

- Executed "jail -c -f <conffile>" in one terminal
- This gives me a shell prompt in the jail
- Executed "jail -r <jailname>" in another terminal
- This kills the shell in the jail, prints "<jailname>: removed", but does not execute the poststop script (in neither of the two terminals)

Expected behavior: The poststop script should be executed.

-- Martin
Comment 3 Jamie Gritton freebsd_committer freebsd_triage 2017-03-06 17:46:56 UTC
I just did a quick test as you outlined, and it worked for me.  This seems more like a Q&A issue than a bug.
Comment 4 gronke 2018-05-06 18:48:15 UTC
It appears that exec.prestop, exec.stop and exec.poststop are not executed when the jail was started with them via jail command arguments:

    jail -c persist name="myjail" exec.stop="/bin/sh /etc/rc.shutdown"
    jail -r myjail

The exec.stop argument cannot be passed to `jail -r`, but a temporary jail.conf file makes it it execute:

    jail -c persist name="myjail"
    echo -e "myjail {\nexec.stop = \"/bin/sh /etc/rc.shutdown\";\n}" > myjail.conf
    jail -r -f myjail.conf
    rm myjail.conf
Comment 5 Jamie Gritton freebsd_committer freebsd_triage 2018-05-08 02:06:56 UTC
On the one hand, it makes perfect (technical) sense to me why a jail created  from the command line wouldn't run ant of the closing commands, either the exec.stop scripts or such things as unmounting.

But I can see why someone who isn't familiar with how it's set up wouldn't make that assumption.  It's not really a feature that could be easily added, but its absence should at least be noted by way of an error or warning when such a jail is created.

Passing an exec.stop or other parameter to jail -r is an interesting idea, which may be feasible.
Comment 6 gronke 2018-05-08 02:24:03 UTC
I would expect jail -r to respect the configuration a jail was started with when the jail -c command did not complain about ignored options when setting them. On the other hand it should still be able to override options with jail -r.

    $ jail -c persist name=myjail exec.stop="/bin/echo EXECUTED"
    $ jail -r -v myjail | grep -c EXECUTED
    1
    $ jail -c persist name=myjail exec.stop="/bin/echo EXECUTED"
    $ jail -r -v exec.stop="/usr/bin/true" | grep -c EXECUTED
    0

In result a started jail can be safely stopped without any knowledge of its internals when configured accordingly.