beadm should support an alternate root
Various packaging and installation tools like
bootadm accept a
-R flag that allows them to be constrained to a specific alternate root; i.e., a child file system that represents not the running system but an image of another system under upgrade or construction. This is primarily useful during development, release engineering, and in the context of installation software.
beadm supports systems with boot environments located in multiple pools. The tool will iterate over pools in the system and report on or operate on any boot environment it finds. There is, thus, effectively one global namespace. This single namespace presents a challenge for image construction; viz., there is no way to tell
beadm what to operate on other than by boot environment name, and thus no way to distinguish between two environments with the same name in different pools. It is thus difficult or impossible to create a boot environment in a new image named "openindiana", say, if that environment also exists on the running system.
At the ZFS level,
zpool accepts a
-R flag and creates an
altroot property, allowing a foreign pool to be imported under an alternate root. If file systems are mounted from the pool, they are prefixed with that alternate root in all automatic mountpoints for the duration of alternate root import. Multiple pools may be imported together under a particular alternate root if required.
We should enhance
beadm to use the
altroot property to distinguish between pools that are a regular part of the running system (i.e., those without an
altroot property) and those imported for image creation or installation purposes (i.e., those with an
altroot property). By adding a new
-R option to
beadm, and using it to filter on the contents of
altroot, we can effectively create one boot environment namespace per alternate root directory.
Updated by Joshua M. Clulow about 1 year ago
Sample from my updated manual page for
beadm create [-a | -t] [-d description] [-e non-activeBeName | beName@snapshot] [-o property=value] ... [-p zpool] [-v] [-R altroot] beName beadm create [-v] [-R altroot] beName@snapshot beadm destroy [-fFsv] [-R altroot] beName | beName@snapshot beadm list [-a | -ds] [-H] [-k|-K date | name | space] [-v] [-R altroot] [beName] beadm mount [-s ro|rw] [-v] [-R altroot] beName mountpoint beadm unmount [-fv] [-R altroot] beName | mountpoint beadm rename [-v] [-R altroot] beName newBeName beadm activate [-v] [-t | -T] [-R altroot] beName beadm rollback [-v] [-R altroot] beName snapshot beadm rollback [-v] [-R altroot] beName@snapshot
The following options are common to all beadm subcommands: -v Verbose mode. Displays verbose error messages from beadm. -R altroot By default, beadm operates on any pool imported without the use of the -R option to zpool import, or the altroot pool property. Pools imported in an alternate root are ignored. If the -R option is provided to beadm, then only pools in the specified alternate root are considered and pools from the running system are ignored. This facility is useful when creating a ZFS pool for use in another system; e.g., during image creation or in an installation environment where the target BE name may conflict with a BE on the running system.
Updated by Joshua M. Clulow about 1 year ago
My implementation strategy here has been to define a new
be_context_t object, and to then pass it around most of the interior calls within
libbe; this context object contains an altroot filter described in the next paragraph. I have left existing "Public" symbols alone, adding two new symbols with the
_altroot suffix that add a new parameter for an alternate root filter. Most of the public routines have made the relatively sound decision to accept their arguments in an extensible nvlist, to which I have added a new
The altroot filter is used in any place where we attempt to enumerate ZFS pools, to allow us to determine which set of pools the consumer is attempting to manipulate. By default,
libbe, and thus
beadm, will now correctly only act on pools that are not imported under an alternate root unless the
-R flag is provided. If that flag is provided, we will only act on pools under the alternate root in question. In this way,
beadm will not surprise the operator by acting on a boot environment that "leaks" in to the global namespace just by temporarily importing a foreign pool.
As an aside: while
libbe is not documented and contains no public library version, it has a well-commented set of "public" functions that may be depended upon by installers and image creation software, and we may do well to consider stabilising it in the near future. I would like to be able to depend on it in https://github.com/illumos/image-builder rather than invoking