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