LIBBE(3)

๐Ÿ“ฆ
version 15.1 ยท 2 versions
, in freebsd 15.1

๐Ÿ’– LIBBE(3) โ€” meet libbe ๐Ÿ’–

from the Library Functions Manual; manual name: libbe. okay bestie, this part is the intro + the full synopsis roster, and we are keeping every single function signature exactly. no cap. ๐ŸŽ€

โœจ NAME โœจ

libbe โ€” the library for creating, destroying and modifying ZFS boot environments. that's the whole gig, literally. ๐Ÿฆ‹

๐Ÿ“š LIBRARY ๐Ÿ“š

the library is literally libbe โ€” as in, library โ€œlibbeโ€. iconic name, zero notes. ๐Ÿ’…

๐Ÿ› ๏ธ SYNOPSIS ๐Ÿ› ๏ธ

okay so here's the full cast, signatures exactly as they appear. do not retype a single character from memory, bestie. ๐Ÿ’–

       #include <be.h>

       libbe_handle_t *hdl
       libbe_init(const char *be_root);

       void
       libbe_close(libbe_handle_t *hdl);

       const char *
       be_active_name(libbe_handle_t *hdl);

       const char *
       be_active_path(libbe_handle_t *hdl);

       const char *
       be_nextboot_name(libbe_handle_t *hdl);

       const char *
       be_nextboot_path(libbe_handle_t *hdl);

       const char *
       be_root_path(libbe_handle_t *hdl);

       int
       be_snapshot(libbe_handle_t *hdl, const char *be_name,
           const char *snap_name, bool recursive, char *result);

       bool
       be_is_auto_snapshot_name(libbe_handle_t *hdl, const char *snap);

       int
       be_create(libbe_handle_t *hdl, const char *be_name);

       int
       be_create_depth(libbe_handle_t *hdl, const char *be_name,
           const char *snap, int depth);

       int
       be_create_empty(libbe_handle_t *hdl, const char *be_name);

       int
       be_create_from_existing(libbe_handle_t *hdl, const char *be_name,
           const char *be_origin);

       int
       be_create_from_existing_snap(libbe_handle_t *hdl, const char *be_name,
           const char *snap);

       int
       be_rename(libbe_handle_t *hdl, const char *be_old, const char *be_new);

       int
       be_activate(libbe_handle_t *hdl, const char *be_name, bool temporary);

       int
       be_deactivate(libbe_handle_t *hdl, const char *be_name, bool temporary);

       int
       be_destroy(libbe_handle_t *hdl, const char *be_name, int options);

       void
       be_nicenum(uint64_t num, char *buf, size_t bufsz);

       int
       be_mount(libbe_handle_t *hdl, const char *be_name, const char *mntpoint,
           int flags, char *result);

       int
       be_mounted_at(libbe_handle_t *hdl, const char *path, nvlist_t *details);

       int
       be_unmount(libbe_handle_t *hdl, const char *be_name, int flags);

       int
       libbe_errno(libbe_handle_t *hdl);

       const char *
       libbe_error_description(libbe_handle_t *hdl);

       void
       libbe_print_on_error(libbe_handle_t *hdl, bool doprint);

       int
       be_root_concat(libbe_handle_t *hdl, const char *be_name, char *result);

       int
       be_validate_name(libbe_handle_t *hdl, const char *be_name);

       int
       be_validate_snap(libbe_handle_t *hdl, const char *snap);

       int
       be_exists(libbe_handle_t *hdl, const char *be_name);

       int
       be_export(libbe_handle_t *hdl, const char *be_name, int fd);

       int
       be_import(libbe_handle_t *hdl, const char *be_name, int fd);

       int
       be_prop_list_alloc(nvlist_t **prop_list);

       int
       be_get_bootenv_props(libbe_handle_t *hdl, nvlist_t *be_list);

       int
       be_get_dataset_props(libbe_handle_t *hdl, const char *ds_name,
           nvlist_t *props);

       int
       be_get_dataset_snapshots(libbe_handle_t *hdl, const char *ds_name,
           nvlist_t *snap_list);

       void
       be_prop_list_free(nvlist_t *prop_list);

       int
       be_log_history(libbe_handle_t *hdl, const char *message);

โœจ DESCRIPTION โœจ

okay so picture this: libbe is besties with libzfs, and together they give you a whole lil toolkit of functions for doing stuff with ZFS boot environments โ€” and yes, that includes "deep" boot environments, aka the ones where a boot environment has child datasets of its own. iconic honestly.

Every function takes a context structure, so a tiny bit of state can be carried around between calls โ€” like errors from stuff you did earlier. And if you want, libbe can be configured to print the matching error message straight to stderr the second something goes wrong, using libbe_print_on_error(). very much "tell me immediately" energy.

Every function that returns an int gives you 0 on success, or a libbe errno otherwise, exactly as described down in "DIAGNOSTICS". no surprises, no cap.


The libbe_init() function takes an optional BE root and initializes libbe, handing you back a libbe_handle_t * on success, or NULL if it's not vibing. If you do supply a BE root, libbe will only operate out of that pool and BE root โ€” it stays in its lane. An error may occur if:

  • /boot and / are not on the same filesystem and device,
  • libzfs fails to initialize,
  • the system has not been properly booted with a ZFS boot environment,
  • libbe fails to open the zpool the active boot environment resides on, or
  • libbe fails to locate the boot environment that is currently mounted.

The libbe_close() function frees all resources previously acquired in libbe_init(), invalidating the handle in the process. bye bestie ๐Ÿ’…


The be_active_name() function returns the name of the currently booted boot environment.

โš ๏ธ heads up: this boot environment may not belong to the same BE root as the root libbe is operating on!

The be_active_path() function returns the full path of the currently booted boot environment.

โš ๏ธ same warning, same drama: this boot environment may not belong to the same BE root as the root libbe is operating on!

The be_nextboot_name() function returns the name of the boot environment that will be active on reboot. ๐Ÿ”ฎ

The be_nextboot_path() function returns the full path of the boot environment that will be active on reboot.

The be_root_path() function returns the boot environment root path.


The be_snapshot() function creates a snapshot of be_name named snap_name. You can pass NULL for that, which means be_snaphot() should derive the snapshot name from the current date and time. very "let the clock decide" of it. If recursive is set, then be_snapshot() will recursively snapshot the dataset. And if result is not NULL, then it gets populated with the final "be_name@snap_name". ๐ŸŽ€

The be_is_auto_snapshot_name() function figures out whether the given snapshot name matches the format that be_snapshot() will use by default when it isn't handed a snapshot name to use. Returns true if the name matches the format, and false if it doesn't. simple as.


The be_create() function creates a boot environment with the given name. The new boot environment will be created from a recursive snapshot of the currently booted boot environment. fresh start, love that for you โœจ

The be_create_depth() function creates a boot environment with the given name from an existing snapshot. The depth parameter specifies the depth of recursion that will be cloned from the existing snapshot. A depth of '0' is no recursion and '-1' is unlimited (i.e., a recursive boot environment). pick your fighter.

The be_create_empty() function creates an empty boot environment with the given name. ๐Ÿซ™

The be_create_from_existing() function creates a boot environment with the given name, sourced from the name of an existing boot environment. A recursive snapshot will be made of the origin boot environment, and the new boot environment will be created from that.

The be_create_from_existing_snap() function creates a recursive boot environment with the given name from an existing snapshot.


The be_rename() function renames a boot environment without unmounting it, as if renamed with the -u argument were passed to zfs rename. no unmount required, we stay mounted ๐Ÿ’…

The be_activate() function makes a boot environment active on the next boot. If the temporary flag is set, then it will be active for the next boot only, as done by zfsbootcfg(8). one-time appearance, main character energy.

The be_deactivate() function deactivates a boot environment. If the temporary flag is set, then it will cause removal of boot once configuration, set by the be_activate() function or by zfsbootcfg(8). If the temporary flag is not set, the be_deactivate() function will set the zfs canmount property to noauto. so basically two totally different behaviours depending on that flag โ€” read it twice, bestie.


The be_destroy() function will recursively destroy the given boot environment. It will not destroy a mounted boot environment unless the BE_DESTROY_FORCE option is set in options. If the BE_DESTROY_ORIGIN option is set in options, the be_destroy() function will destroy the origin snapshot to this boot environment as well. ๐Ÿ’€ irreversible, proceed with the vibes checked.

The be_nicenum() function will format name in a traditional ZFS humanized format, similar to humanize_number(3). This function effectively proxies zfs_nicenum() from libzfs. cute little middleman.


The be_mount() function will mount the given boot environment. If mountpoint is NULL, a mount point will be generated in TMPDIR or, if TMPDIR is not set, /tmp, using mkdtemp(3). If result is not NULL, it should be large enough to accommodate BE_MAXPATHLEN including the null terminator โ€” and the final mount point will be copied into it. Setting the BE_MNT_FORCE flag will pass MNT_FORCE to the underlying mount(2) call.

The be_mounted_at() function will check if there is a boot environment mounted at the given path. If details is not NULL, it will be populated with a list of the mounted dataset's properties. This list of properties matches the properties collected by be_get_bootenv_props(). ๐Ÿ•ต๏ธ

The be_unmount() function will unmount the given boot environment. If the mount point looks like it was created by be_mount(), then be_unmount() will attempt to rmdir(2) the mountpoint after a successful unmount โ€” cleaning up after itself, we stan. Setting the BE_MNT_FORCE flag will pass MNT_FORCE to the underlying mount(2) call.


The libbe_errno() function returns the libbe errno.

The libbe_error_description() function returns a string description of the currently set libbe errno. plain english, thank god.

The libbe_print_on_error() function will change whether or not libbe prints the description of any encountered error to stderr, based on doprint.

The be_root_concat() function will concatenate the boot environment root and the given boot environment name into result.


The be_validate_name() function will validate the given boot environment name for both length restrictions as well as valid character restrictions.

๐Ÿซถ note: this function does not set the internal library error state.

The be_validate_snap() function will validate the given snapshot name. The snapshot must have a valid name, exist, and have a mountpoint of /.

๐Ÿซถ again: this function does not set the internal library error state.

The be_exists() function will check whether the given boot environment exists and has a mountpoint of /. This function does not set the internal library error state, but will return the appropriate error.


The be_export() function will export the given boot environment to the file specified by fd. A snapshot will be created of the boot environment prior to export. ๐Ÿ“ฆ

The be_import() function will import the boot environment in the file specified by fd, and give it the name be_name.


The be_prop_list_alloc() function allocates a property list suitable for passing to be_get_bootenv_props(), be_get_dataset_props(), or be_get_dataset_snapshots(). It should be freed later by be_prop_list_free. don't forget the free, bestie, it's giving memory leak ๐Ÿงš

The be_get_bootenv_props() function will populate be_list with nvpair_t of boot environment names paired with an nvlist_t of their properties. The following properties are currently collected as appropriate:

  • dataset โ€” -
  • name โ€” Boot environment name
  • mounted โ€” Current mount point
  • mountpoint โ€” "mountpoint" property
  • origin โ€” "origin" property
  • creation โ€” "creation" property
  • active โ€” Currently booted environment
  • used โ€” Literal "used" property
  • usedds โ€” Literal "usedds" property
  • usedsnap โ€” Literal "usedrefreserv" property
  • referenced โ€” Literal "referenced" property
  • nextboot โ€” Active on next boot

Only the "dataset", "name", "active", and "nextboot" returned values will always be present. All other properties may be omitted if not available. so like, don't count on them showing up ๐ŸŒธ

The be_get_dataset_props() function will get properties of the specified dataset. props is populated directly with a list of the properties as returned by be_get_bootenv_props().

The be_get_dataset_snapshots() function will retrieve all snapshots of the given dataset. snap_list will be populated with a list of nvpair_t exactly as specified by be_get_bootenv_props().

The be_prop_list_free() function will free the property list. ๐Ÿงน


The be_log_history() function will log the given message to the zpool history, which can be later retrieved using the zpool-history(8) command. receipts, preserved forever.


๐Ÿ”ฅ DIAGNOSTICS ๐Ÿ”ฅ

Upon error, one of the following values will be returned:

  • 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
  • BE_ERR_UNKNOWN
  • BE_ERR_INVORIGIN

๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

bectl(8), zpool-history(8)


๐Ÿ‘‘ HISTORY ๐Ÿ‘‘

bectl(8) and libbe were written by Kyle Kneitinger (kneitinger) <kyle@kneit.in> as a 2017 Google Summer of Code project, with Allan Jude (allanjude) <allanjude@freebsd.org> as mentor. GSoC 2017, we love to see it ๐ŸŽ“

๐Ÿ’œ AUTHORS ๐Ÿ’œ

Kyle Kneitinger, mentored as above.

Post-GSoC changes were written by Kyle Evans (kevans) <kevans@freebsd.org>.


and that's the whole page, bestie!! this one's the Debian build of LIBBE(3), dated February 4, 2026 โ€” go forth and snapshot responsibly ๐Ÿ’…โœจ๐Ÿซถ

๐Ÿ“ฆ where this page comes from
  • freebsd 15.1: base 15.1
  • ๐Ÿ“œ the page's license: BSD-2-Clause
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms