xref: /freebsd/lib/libbe/libbe.3 (revision 7cc42f6d)
1.\"
2.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3.\"
4.\" Copyright (c) 2017 Kyle Kneitinger
5.\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in the
14.\"    documentation and/or other materials provided with the distribution.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $FreeBSD$
29.\"
30.Dd July 22, 2020
31.Dt LIBBE 3
32.Os
33.Sh NAME
34.Nm libbe
35.Nd library for creating, destroying and modifying ZFS boot environments
36.Sh LIBRARY
37.Lb libbe
38.Sh SYNOPSIS
39.In be.h
40.Ft "libbe_handle_t *hdl" Ns
41.Fn libbe_init "const char *be_root"
42.Pp
43.Ft void
44.Fn libbe_close "libbe_handle_t *hdl"
45.Pp
46.Ft const char * Ns
47.Fn be_active_name "libbe_handle_t *hdl"
48.Pp
49.Ft const char * Ns
50.Fn be_active_path "libbe_handle_t *hdl"
51.Pp
52.Ft const char * Ns
53.Fn be_nextboot_name "libbe_handle_t *hdl"
54.Pp
55.Ft const char * Ns
56.Fn be_nextboot_path "libbe_handle_t *hdl"
57.Pp
58.Ft const char * Ns
59.Fn be_root_path "libbe_handle_t *hdl"
60.Pp
61.Ft bool Ns
62.Fn be_is_auto_snapshot_name "libbe_handle_t *hdl" "const char *snap"
63.Pp
64.Ft int
65.Fn be_create "libbe_handle_t *hdl" "const char *be_name"
66.Pp
67.Ft int
68.Fn be_create_depth "libbe_handle_t *hdl" "const char *be_name" "const char *snap" "int depth"
69.Pp
70.Ft int
71.Fn be_create_from_existing "libbe_handle_t *hdl" "const char *be_name" "const char *be_origin"
72.Pp
73.Ft int
74.Fn be_create_from_existing_snap "libbe_handle_t *hdl" "const char *be_name" "const char *snap"
75.Pp
76.Ft int
77.Fn be_rename "libbe_handle_t *hdl" "const char *be_old" "const char *be_new"
78.Pp
79.Ft int
80.Fn be_activate "libbe_handle_t *hdl" "const char *be_name" "bool temporary"
81.Pp
82.Ft int
83.Fn be_deactivate "libbe_handle_t *hdl" "const char *be_name" "bool temporary"
84.Pp
85.Ft int
86.Fn be_destroy "libbe_handle_t *hdl" "const char *be_name" "int options"
87.Pp
88.Ft void
89.Fn be_nicenum "uint64_t num" "char *buf" "size_t bufsz"
90.Pp
91.\" TODO: Write up of mount options
92.\" typedef enum {
93.\"	BE_MNT_FORCE		= 1 << 0,
94.\"	BE_MNT_DEEP		= 1 << 1,
95.\" } be_mount_opt_t
96.Ft int
97.Fn be_mount "libbe_handle_t *hdl" "char *be_name" "char *mntpoint" "int flags" "char *result"
98.Pp
99.Ft int
100.Fn be_mounted_at "libbe_handle_t *hdl" "const char *path" "nvlist_t *details"
101.Pp
102.Ft int
103.Fn be_unmount "libbe_handle_t *hdl" "char *be_name" "int flags"
104.Pp
105.Ft int
106.Fn libbe_errno "libbe_handle_t *hdl"
107.Pp
108.Ft const char * Ns
109.Fn libbe_error_description "libbe_handle_t *hdl"
110.Pp
111.Ft void
112.Fn libbe_print_on_error "libbe_handle_t *hdl" "bool doprint"
113.Pp
114.Ft int
115.Fn be_root_concat "libbe_handle_t *hdl" "const char *be_name" "char *result"
116.Pp
117.Ft int
118.Fn be_validate_name "libbe_handle_t *hdl" "const char *be_name"
119.Pp
120.Ft int
121.Fn be_validate_snap "libbe_handle_t *hdl" "const char *snap"
122.Pp
123.Ft int
124.Fn be_exists "libbe_handle_t *hdl" "char *be_name"
125.Pp
126.Ft int
127.Fn be_export "libbe_handle_t *hdl" "const char *be_name" "int fd"
128.Pp
129.Ft int
130.Fn be_import "libbe_handle_t *hdl" "const char *be_name" "int fd"
131.Pp
132.Ft int
133.Fn be_prop_list_alloc "nvlist_t **prop_list"
134.Pp
135.Ft int
136.Fn be_get_bootenv_props "libbe_handle_t *hdl" "nvlist_t *be_list"
137.Pp
138.Ft int
139.Fn be_get_dataset_props "libbe_handle_t *hdl" "const char *ds_name" "nvlist_t *props"
140.Pp
141.Ft int
142.Fn be_get_dataset_snapshots "libbe_handle_t *hdl" "const char *ds_name" "nvlist_t *snap_list"
143.Pp
144.Ft void
145.Fn be_prop_list_free "nvlist_t *prop_list"
146.Sh DESCRIPTION
147.Nm
148interfaces with libzfs to provide a set of functions for various operations
149regarding ZFS boot environments including "deep" boot environments in which
150a boot environments has child datasets.
151.Pp
152A context structure is passed to each function, allowing for a small amount
153of state to be retained, such as errors from previous operations.
154.Nm
155may be configured to print the corresponding error message to
156.Dv stderr
157when an error is encountered with
158.Fn libbe_print_on_error .
159.Pp
160All functions returning an
161.Vt int
162return 0 on success, or a
163.Nm
164errno otherwise as described in
165.Sx DIAGNOSTICS .
166.Pp
167The
168.Fn libbe_init
169function takes an optional BE root and initializes
170.Nm ,
171returning a
172.Vt "libbe_handle_t *"
173on success, or
174.Dv NULL
175on error.
176If a BE root is supplied,
177.Nm
178will only operate out of that pool and BE root.
179An error may occur if:
180.Bl -column
181.It /boot and / are not on the same filesystem and device,
182.It libzfs fails to initialize,
183.It The system has not been properly booted with a ZFS boot
184environment,
185.It Nm
186fails to open the zpool the active boot environment resides on, or
187.It Nm
188fails to locate the boot environment that is currently mounted.
189.El
190.Pp
191The
192.Fn libbe_close
193function frees all resources previously acquired in
194.Fn libbe_init ,
195invalidating the handle in the process.
196.Pp
197The
198.Fn be_active_name
199function returns the name of the currently booted boot environment.
200This boot environment may not belong to the same BE root as the root libbe
201is operating on!
202.Pp
203The
204.Fn be_active_path
205function returns the full path of the currently booted boot environment.
206This boot environment may not belong to the same BE root as the root libbe
207is operating on!
208.Pp
209The
210.Fn be_nextboot_name
211function returns the name of the boot environment that will be active on reboot.
212.Pp
213The
214.Fn be_nextboot_path
215function returns the full path of the boot environment that will be
216active on reboot.
217.Pp
218The
219.Fn be_root_path
220function returns the boot environment root path.
221.Pp
222The
223.Fn be_is_auto_snapshot_name
224function is used to determine if the given snapshot name matches the format that
225the
226.Fn be_snapshot
227function will use by default if it is not given a snapshot name to use.
228It returns
229.Dv true
230if the name matches the format, and
231.Dv false
232if it does not.
233.Pp
234The
235.Fn be_create
236function creates a boot environment with the given name.
237The new boot environment will be created from a recursive snapshot of the
238currently booted boot environment.
239.Pp
240The
241.Fn be_create_depth
242function creates a boot environment with the given name from an existing
243snapshot.
244The depth parameter specifies the depth of recursion that will be cloned from
245the existing snapshot.
246A depth of '0' is no recursion and '-1' is unlimited (i.e., a recursive boot
247environment).
248.Pp
249The
250.Fn be_create_from_existing
251function creates a boot environment with the given name from the name of an
252existing boot environment.
253A recursive snapshot will be made of the origin boot environment, and the new
254boot environment will be created from that.
255.Pp
256The
257.Fn be_create_from_existing_snap
258function creates a recursive boot environment with the given name from an
259existing snapshot.
260.Pp
261The
262.Fn be_rename
263function renames a boot environment without unmounting it, as if renamed with
264the
265.Fl u
266argument were passed to
267.Nm zfs
268.Cm rename
269.Pp
270The
271.Fn be_activate
272function makes a boot environment active on the next boot.
273If the
274.Fa temporary
275flag is set, then it will be active for the next boot only, as done by
276.Xr zfsbootcfg 8 .
277.Pp
278The
279.Fn be_deactivate
280function deactivates a boot environment.
281If the
282.Fa temporary
283flag is set, then it will cause removal of boot once configuration, set by
284.Fn be_activate
285function or by
286.Xr zfsbootcfg 8 .
287If the
288.Fa temporary
289flag is not set,
290.Fn be_deactivate
291function will set zfs
292.Dv canmount
293property to
294.Dv noauto .
295.Pp
296The
297.Fn be_destroy
298function will recursively destroy the given boot environment.
299It will not destroy a mounted boot environment unless the
300.Dv BE_DESTROY_FORCE
301option is set in
302.Fa options .
303If the
304.Dv BE_DESTROY_ORIGIN
305option is set in
306.Fa options ,
307the
308.Fn be_destroy
309function will destroy the origin snapshot to this boot environment as well.
310.Pp
311The
312.Fn be_nicenum
313function will format
314.Fa name
315in a traditional ZFS humanized format, similar to
316.Xr humanize_number 3 .
317This function effectively proxies
318.Fn zfs_nicenum
319from libzfs.
320.Pp
321The
322.Fn be_mount
323function will mount the given boot environment.
324If
325.Fa mountpoint
326is
327.Dv NULL ,
328a mount point will be generated in
329.Pa /tmp
330using
331.Xr mkdtemp 3 .
332If
333.Fa result
334is not
335.Dv NULL ,
336it should be large enough to accommodate
337.Dv BE_MAXPATHLEN
338including the null terminator.
339the final mount point will be copied into it.
340Setting the
341.Dv BE_MNT_FORCE
342flag will pass
343.Dv MNT_FORCE
344to the underlying
345.Xr mount 2
346call.
347.Pp
348The
349.Fn be_mounted_at
350function will check if there is a boot environment mounted at the given
351.Fa path .
352If
353.Fa details
354is not
355.Dv NULL ,
356it will be populated with a list of the mounted dataset's properties.
357This list of properties matches the properties collected by
358.Fn be_get_bootenv_props .
359.Pp
360The
361.Fn be_unmount
362function will unmount the given boot environment.
363Setting the
364.Dv BE_MNT_FORCE
365flag will pass
366.Dv MNT_FORCE
367to the underlying
368.Xr mount 2
369call.
370.Pp
371The
372.Fn libbe_errno
373function returns the
374.Nm
375errno.
376.Pp
377The
378.Fn libbe_error_description
379function returns a string description of the currently set
380.Nm
381errno.
382.Pp
383The
384.Fn libbe_print_on_error
385function will change whether or not
386.Nm
387prints the description of any encountered error to
388.Dv stderr ,
389based on
390.Fa doprint .
391.Pp
392The
393.Fn be_root_concat
394function will concatenate the boot environment root and the given boot
395environment name into
396.Fa result .
397.Pp
398The
399.Fn be_validate_name
400function will validate the given boot environment name for both length
401restrictions as well as valid character restrictions.
402This function does not set the internal library error state.
403.Pp
404The
405.Fn be_validate_snap
406function will validate the given snapshot name.
407The snapshot must have a valid name, exist, and have a mountpoint of
408.Pa / .
409This function does not set the internal library error state.
410.Pp
411The
412.Fn be_exists
413function will check whether the given boot environment exists and has a
414mountpoint of
415.Pa / .
416This function does not set the internal library error state, but will return
417the appropriate error.
418.Pp
419The
420.Fn be_export
421function will export the given boot environment to the file specified by
422.Fa fd .
423A snapshot will be created of the boot environment prior to export.
424.Pp
425The
426.Fn be_import
427function will import the boot environment in the file specified by
428.Fa fd ,
429and give it the name
430.Fa be_name .
431.Pp
432The
433.Fn be_prop_list_alloc
434function allocates a property list suitable for passing to
435.Fn be_get_bootenv_props ,
436.Fn be_get_dataset_props ,
437or
438.Fn be_get_dataset_snapshots .
439It should be freed later by
440.Fa be_prop_list_free .
441.Pp
442The
443.Fn be_get_bootenv_props
444function will populate
445.Fa be_list
446with
447.Vt nvpair_t
448of boot environment names paired with an
449.Vt nvlist_t
450of their properties.
451The following properties are currently collected as appropriate:
452.Bl -column "Returned name"
453.It Sy Returned name Ta Sy Description
454.It dataset Ta -
455.It name Ta Boot environment name
456.It mounted Ta Current mount point
457.It mountpoint Ta Do mountpoint Dc property
458.It origin Ta Do origin Dc property
459.It creation Ta Do creation Dc property
460.It active Ta Currently booted environment
461.It used Ta Literal Do used Dc property
462.It usedds Ta Literal Do usedds Dc property
463.It usedsnap Ta Literal Do usedrefreserv Dc property
464.It referenced Ta Literal Do referenced Dc property
465.It nextboot Ta Active on next boot
466.El
467.Pp
468Only the
469.Dq dataset ,
470.Dq name ,
471.Dq active ,
472and
473.Dq nextboot
474returned values will always be present.
475All other properties may be omitted if not available.
476.Pp
477The
478.Fn be_get_dataset_props
479function will get properties of the specified dataset.
480.Fa props
481is populated directly with a list of the properties as returned by
482.Fn be_get_bootenv_props .
483.Pp
484The
485.Fn be_get_dataset_snapshots
486function will retrieve all snapshots of the given dataset.
487.Fa snap_list
488will be populated with a list of
489.Vt nvpair_t
490exactly as specified by
491.Fn be_get_bootenv_props .
492.Pp
493The
494.Fn be_prop_list_free
495function will free the property list.
496.Sh DIAGNOSTICS
497Upon error, one of the following values will be returned:
498.Bl -dash -offset indent -compact
499.It
500BE_ERR_SUCCESS
501.It
502BE_ERR_INVALIDNAME
503.It
504BE_ERR_EXISTS
505.It
506BE_ERR_NOENT
507.It
508BE_ERR_PERMS
509.It
510BE_ERR_DESTROYACT
511.It
512BE_ERR_DESTROYMNT
513.It
514BE_ERR_BADPATH
515.It
516BE_ERR_PATHBUSY
517.It
518BE_ERR_PATHLEN
519.It
520BE_ERR_BADMOUNT
521.It
522BE_ERR_NOORIGIN
523.It
524BE_ERR_MOUNTED
525.It
526BE_ERR_NOMOUNT
527.It
528BE_ERR_ZFSOPEN
529.It
530BE_ERR_ZFSCLONE
531.It
532BE_ERR_IO
533.It
534BE_ERR_NOPOOL
535.It
536BE_ERR_NOMEM
537.It
538BE_ERR_UNKNOWN
539.It
540BE_ERR_INVORIGIN
541.El
542.Sh SEE ALSO
543.Xr bectl 8
544.Sh HISTORY
545.Nm
546and its corresponding command,
547.Xr bectl 8 ,
548were written as a 2017 Google Summer of Code project with Allan Jude serving
549as a mentor.
550Later work was done by
551.An Kyle Evans Aq Mt kevans@FreeBSD.org .
552