libbe.3 14 KB

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