Page MenuHomeFreeBSD

rc.d/zfsbe: a new script designed for boot environment support
ClosedPublic

Authored by avg on Sep 6 2016, 1:18 PM.

Details

Summary

Currently zfsbe ensures that subordinate filesystems are mounted at the
right mount points.
The script assumes that the subordinate filesystems of a boot environment
have their canmount property set to noauto, so that they are not
automatically mounted on boot. Whereas the root filesystem is mounted
by the kernel, there was nothing to mount its subordinates.
rc.d/zfsbe fills that gap.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

avg retitled this revision from to rc.d/zfsbe: a new script designed for boot environment support.
avg updated this object.
avg edited the test plan for this revision. (Show Details)
avg added reviewers: ZFS, asomers, allanjude, will, smh, delphij.

Looks good, though it might be helpful to include an explanation of what issue this is intended to address, or new feature this is intended to implement. I remember you telling me about this once, but it's been probably at least a year. I think it makes BEs more self-contained, but if they are single filesystems, what difference does it make?

etc/rc.d/zfsbe
33 ↗(On Diff #20088)

Why shouldn't this be included in the zfs list output to avoid the extra zfs calls?

In D7797#161787, @will wrote:

Looks good, though it might be helpful to include an explanation of what issue this is intended to address, or new feature this is intended to implement. I remember you telling me about this once, but it's been probably at least a year. I think it makes BEs more self-contained, but if they are single filesystems, what difference does it make?

No difference whatsoever in that case.
I thought that the references to subordinate filesystems in the summary were descriptive enough.

etc/rc.d/zfsbe
33 ↗(On Diff #20088)

I'll do this, thanks!

In D7797#161802, @avg wrote:

No difference whatsoever in that case.

OK, I believe this is the usual case. At least for me, beadm creates single filesystems, and all other filesystems on my system are data-only:

miranda% zfs list -r -o name,mountpoint,canmount
NAME                                        MOUNTPOINT               CANMOUNT
zroot                                       /zroot                         on
zroot/ROOT                                  none                           on
zroot/ROOT/11.0-BETA1-20160715.163019       /                          noauto
zroot/ROOT/11.0-BETA4-20160806.032058       /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160825.041625  /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160901.143052  /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160904.035358  /                              on
zroot/tmp                                   /tmp                           on
zroot/usr                                   /usr                          off
zroot/usr/home                              /usr/home                      on
zroot/usr/obj                               /usr/obj                       on
zroot/usr/ports                             /usr/ports                     on
zroot/var                                   /var                          off
zroot/var/audit                             /var/audit                     on
zroot/var/crash                             /var/crash                     on
zroot/var/log                               /var/log                       on
zroot/var/mail                              /var/mail                      on
zroot/var/tmp                               /var/tmp                       on
In D7797#161812, @will wrote:
In D7797#161802, @avg wrote:

No difference whatsoever in that case.

OK, I believe this is the usual case. At least for me, beadm creates single filesystems, and all other filesystems on my system are data-only:

miranda% zfs list -r -o name,mountpoint,canmount
NAME                                        MOUNTPOINT               CANMOUNT
zroot                                       /zroot                         on
zroot/ROOT                                  none                           on
zroot/ROOT/11.0-BETA1-20160715.163019       /                          noauto
zroot/ROOT/11.0-BETA4-20160806.032058       /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160825.041625  /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160901.143052  /                          noauto
zroot/ROOT/11.0-PRERELEASE-20160904.035358  /                              on
zroot/tmp                                   /tmp                           on
zroot/usr                                   /usr                          off
zroot/usr/home                              /usr/home                      on
zroot/usr/obj                               /usr/obj                       on
zroot/usr/ports                             /usr/ports                     on
zroot/var                                   /var                          off
zroot/var/audit                             /var/audit                     on
zroot/var/crash                             /var/crash                     on
zroot/var/log                               /var/log                       on
zroot/var/mail                              /var/mail                      on
zroot/var/tmp                               /var/tmp                       on

Right, in that case, this does nothing.

What this handles is when you have a separate /usr, /var, and so on inside each BE

You set them all canmount=noauto, because you don't want the /usr from BE1 mounted when you are running BE2 etc.

Instead of having to manually use fstab to mount these, this script finds which BE is active, and mounts all of its descendants that have a mountpoint and are not canmount=off

@will yes, that would be the most common case.
I use a different, home-grown tool and I customize my boot environments for my needs.
An example:

zfs list -r -o name,mountpoint,canmount rpool/ROOT/20160614
NAME                                  MOUNTPOINT                             CANMOUNT
rpool/ROOT/20160614                   /rpool/ROOT/20160614                     noauto
rpool/ROOT/20160614/usr               /rpool/ROOT/20160614/usr                    off
rpool/ROOT/20160614/usr/compat        /rpool/ROOT/20160614/usr/compat          noauto
rpool/ROOT/20160614/usr/compat/linux  /rpool/ROOT/20160614/usr/compat/linux    noauto
rpool/ROOT/20160614/usr/lib           /rpool/ROOT/20160614/usr/lib                off
rpool/ROOT/20160614/usr/lib/debug     /rpool/ROOT/20160614/usr/lib/debug       noauto
rpool/ROOT/20160614/usr/local         /rpool/ROOT/20160614/usr/local           noauto
rpool/ROOT/20160614/usr/local/etc     /rpool/ROOT/20160614/usr/local/etc       noauto
In D7797#161821, @avg wrote:
zfs list -r -o name,mountpoint,canmount rpool/ROOT/20160614
NAME                                  MOUNTPOINT                             CANMOUNT
rpool/ROOT/20160614                   /rpool/ROOT/20160614                     noauto
rpool/ROOT/20160614/usr               /rpool/ROOT/20160614/usr                    off
rpool/ROOT/20160614/usr/compat        /rpool/ROOT/20160614/usr/compat          noauto
rpool/ROOT/20160614/usr/compat/linux  /rpool/ROOT/20160614/usr/compat/linux    noauto
rpool/ROOT/20160614/usr/lib           /rpool/ROOT/20160614/usr/lib                off
rpool/ROOT/20160614/usr/lib/debug     /rpool/ROOT/20160614/usr/lib/debug       noauto
rpool/ROOT/20160614/usr/local         /rpool/ROOT/20160614/usr/local           noauto
rpool/ROOT/20160614/usr/local/etc     /rpool/ROOT/20160614/usr/local/etc       noauto

The main reason I can think of that you would do this would be to have different properties on these subordinate filesystems, like compression? However, I would think it would be beneficial to compress a BE root. I'm curious what properties you modify on subordinates? Either way, makes sense. I'm surprised no one has included this type of capability in beadm itself though.

In D7797#161832, @will wrote:

The main reason I can think of that you would do this would be to have different properties on these subordinate filesystems, like compression? However, I would think it would be beneficial to compress a BE root. I'm curious what properties you modify on subordinates? Either way, makes sense. I'm surprised no one has included this type of capability in beadm itself though.

beadm is not run at boot though

Well, illumos beadm does have the support.
I mostly use those different filesystems to separate base and package upgrade cycles and to have different auto-snapshotting policies.
Perhaps an overkill, but I got used to this setup.

Some of the issues that this addresses, as pointed out:

  1. beadm does not have any awareness of the boot loader and its recent ability to chose a BE at boot time. Accordingly, it would have to do something like this does.
  2. Life is read-only at the boot stage, which may impact a few things.
  3. The canmount property is not inheritable, which may solve some of the issues.
  4. There are now various forks of beadm, some of which set canmount to "on" and some to "noauto".

That said, I like this approach but am concerned that it a user might have a mix of "on" and "noauto" below <pool>/ROOT/* (A path that is user-configurable with scripted bsdinstall.)

I will post a diff separately but the heart of it is:

be_preflight()
{

  1. Incoming _dev variable $1 will appear as zroot/ROOT/default
  2. Challenge: "canmount=on" could be set in other zroot/ROOT be's

local _name
local _canmount
dirname $1 | zfs list -rH -o name,canmount | \
while read _name _canmount ; do

		if [ "$_canmount" = "on" ]; then
			zfs set canmount=noauto $_name

Force unmounting it because it would have been mounted before zfsbe

			zfs umount -f $_name
		fi

done
}

I also suggest "echo 'Mounting subordinate boot environment datasets.'" and cleaning up the spaces/tabs.

The forced unmount might be a bit draconian but if the dataset is a child of the BE and was "on", it should be re-mounted. Perhaps it could check that it is a child of the selected boot environment and force umount ones that are not, and are members of other boot environments. (This has nothing to do with datasets outside of <pool>/ROOT/*

avg edited edge metadata.

include mounted property in the listing instead of separately querying it

avg marked an inline comment as done.Sep 7 2016, 12:49 PM

I am strongly opposed to doing any configuration changes from a startup script.
If any tool produces a broken system configuration, then that tool should be fixed.
zfsbe will obey the ZFS properties, not change them.

@editor_callfortesting.org wrote:

cleaning up the spaces/tabs

Could you please point out those issues inline?

In D7797#162091, @avg wrote:

I am strongly opposed to doing any configuration changes from a startup script.
If any tool produces a broken system configuration, then that tool should be fixed.
zfsbe will obey the ZFS properties, not change them.

Maybe there is another solution but here's the issue from what I have observed:

The beadm in ports sets canmount=on when you change BE
The TrueOS beadm sets canmount=noauto

If you use the one in ports (which has been around for some time) and activate a given boot environment that has child datasets such as use and var, choosing another one in the loader and having zfsbe mount the child datasets will overlay the two. No?

In D7797#162091, @avg wrote:

I am strongly opposed to doing any configuration changes from a startup script.
If any tool produces a broken system configuration, then that tool should be fixed.
zfsbe will obey the ZFS properties, not change them.

Maybe there is another solution but here's the issue from what I have observed:

The beadm in ports sets canmount=on when you change BE
The TrueOS beadm sets canmount=noauto

If you use the one in ports (which has been around for some time) and activate a given boot environment that has child datasets such as use and var, choosing another one in the loader and having zfsbe mount the child datasets will overlay the two. No?

That's correct. And I prefer that the problem is fixed in beadm from ports.

That's correct. And I prefer that the problem is fixed in beadm from ports.

That said, I strongly-suggest that beadm functionality be incorporated into the base OS with something as simple as nextboot(8) (perhaps nextbe?) which simply lets you choose then next boot environment. Informed users can set the pool's 'bootfs' property but the average user should probably be given some hand-holding.

While it is not a FreeBSD feature, TrueOS will now install to boot environment. zfsbe and nextbe would be a good start in supporting this approach and advanced users can do all the BE creation, copying and tinkering they like with whatever tool they like.

In D7797#162208, @avg wrote:

@editor_callfortesting.org D7612 might be of interest to you as well :-)

Indeed! Glad nextboot was mentioned.

Reviewing...

In D7797#162208, @avg wrote:

@editor_callfortesting.org D7612 might be of interest to you as well :-)

I still think a warning of conflicting 'canmount' datasets should be included somewhere. Might that utility want to run a check and warn the user?

This revision was automatically updated to reflect the committed changes.