socsvn commit: r324213 - in soc2017/kneitinger/libbe-head: lib/libbe sbin/be
kneitinger at FreeBSD.org
kneitinger at FreeBSD.org
Mon Jul 3 11:16:50 UTC 2017
Author: kneitinger
Date: Mon Jul 3 11:16:47 2017
New Revision: 324213
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=324213
Log:
libbe(3): Refactor error reporting system & start work on bootenv destroy function
Modified:
soc2017/kneitinger/libbe-head/lib/libbe/be.c
soc2017/kneitinger/libbe-head/lib/libbe/be.h
soc2017/kneitinger/libbe-head/lib/libbe/be_error.c
soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h
soc2017/kneitinger/libbe-head/lib/libbe/be_info.c
soc2017/kneitinger/libbe-head/sbin/be/be.c
Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.c Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.c Mon Jul 3 11:16:47 2017 (r324213)
@@ -43,24 +43,23 @@
libbe_init(void)
{
libbe_handle_t *lbh;
- char buf[MAX_PATHLEN];
+ char buf[MAXPATHLEN];
if ((lbh = calloc(1, sizeof(libbe_handle_t))) == NULL) {
return (NULL);
}
-
if ((lbh->lzh = libzfs_init()) == NULL) {
free(lbh);
return (NULL);
}
- libzfs_print_on_error(lbh->lzh, 1);
+ lbh->print_on_err = true;
/* Obtain path to active boot environment */
- if ((kenv(KENV_GET, "zfs_be_active", buf, MAX_PATHLEN)) == -1) {
+ if ((kenv(KENV_GET, "zfs_be_active", buf, MAXPATHLEN)) == -1) {
libzfs_fini(lbh->lzh);
free(lbh);
return (NULL);
@@ -80,7 +79,7 @@
/* Obtain path to boot environment root */
- if ((kenv(KENV_GET, "zfs_be_root", buf, MAX_PATHLEN)) == -1) {
+ if ((kenv(KENV_GET, "zfs_be_root", buf, MAXPATHLEN)) == -1) {
zfs_close(lbh->be_active);
libzfs_fini(lbh->lzh);
free(lbh);
@@ -97,7 +96,6 @@
return (NULL);
}
-
/* TODO: verify that /boot is mounted on the active be */
prop_list_builder(lbh);
@@ -116,6 +114,50 @@
zfs_close(lbh->be_active);
zfs_close(lbh->be_root);
libzfs_fini(lbh->lzh);
- /* TODO: clean up property list */
+ prop_list_free(lbh);
free(lbh);
}
+
+
+/*
+ * Destroy the boot environment specified by the name parameter
+ * Options are or'd together with the possible values:
+ * BE_DESTROY_FORCE : forces operation on mounted datasets
+ *
+ */
+int
+be_destroy(libbe_handle_t *lbh, char *name, int options)
+{
+ zfs_handle_t *fs;
+ char path[MAXPATHLEN];
+ char *p = path;
+ int mounted;
+ int force = options & BE_DESTROY_FORCE;
+
+ int err = BE_ERR_SUCCESS;
+
+ snprintf(path, MAXPATHLEN, "%s/%s", zfs_get_name(lbh->be_root), name);
+
+ if(!zfs_dataset_exists(lbh->lzh, path, ZFS_TYPE_DATASET)) {
+ err = set_error(lbh, BE_ERR_NOENT);
+ return (err);
+ }
+
+ fs = zfs_open(lbh->lzh, p, ZFS_TYPE_DATASET);
+
+ if(strcmp(path, zfs_get_name(lbh->be_active)) != 0) {
+ err = set_error(lbh, BE_ERR_DESTROYACT);
+ return (err);
+ }
+
+
+ //check mounted
+ if((mounted = zfs_is_mounted(fs, &p)) && !(force)) {
+ err = set_error(lbh, BE_ERR_DESTROYMNT);
+ return (err);
+ }
+
+ // check dependants
+
+ return (0);
+}
Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.h
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.h Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.h Mon Jul 3 11:16:47 2017 (r324213)
@@ -30,11 +30,22 @@
#define _LIBBE_H
#include <libzfs.h>
-
-#define MAX_PATHLEN 512
+#include <stdbool.h>
typedef struct libbe_handle libbe_handle_t;
+typedef enum be_error {
+ BE_ERR_SUCCESS = 0, /* No error */
+ BE_ERR_INVALIDNAME, /* invalid boot env name */
+ BE_ERR_EXISTS, /* boot env name already taken */
+ BE_ERR_NOENT, /* boot env doesn't exist */
+ BE_ERR_PERMS, /* insufficient permissions */
+ BE_ERR_DESTROYACT, /* cannot destroy active boot env */
+ BE_ERR_DESTROYMNT, /* cannot destroy active boot env */
+ BE_ERR_UNKNOWN, /* unknown error */
+} be_error_t;
+
+
/* Library handling functions: be.c */
libbe_handle_t *libbe_init(void);
void libbe_close(libbe_handle_t *);
@@ -53,6 +64,9 @@
int be_rename(libbe_handle_t *, char *, char *);
/* Bootenv removal functions */
+
+#define BE_DESTROY_FORCE 1
+
int be_destroy(libbe_handle_t *, char *, int);
/* Bootenv mounting functions */
@@ -65,5 +79,6 @@
/* Error related functions: be_error.c */
int libbe_errno(libbe_handle_t *);
const char *libbe_error_description(libbe_handle_t *);
+void libbe_print_on_error(libbe_handle_t *, bool);
#endif /* _LIBBE_H */
Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_error.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_error.c Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_error.c Mon Jul 3 11:16:47 2017 (r324213)
@@ -44,14 +44,23 @@
{
switch (lbh->error) {
case BE_ERR_INVALIDNAME:
- return ("invalid boot env name");
+ return ("invalid boot environment name");
case BE_ERR_EXISTS:
- return ("boot env name already taken");
+ return ("boot environment name already taken");
+
+ case BE_ERR_NOENT:
+ return ("specified boot environment does not exist");
case BE_ERR_PERMS:
return ("insufficient permissions");
+ case BE_ERR_DESTROYACT:
+ return ("cannot destroy active boot environment");
+
+ case BE_ERR_DESTROYMNT:
+ return ("cannot destroy mounted boot env unless forced");
+
case BE_ERR_UNKNOWN:
return ("unknown error");
@@ -60,3 +69,24 @@
return ("no error");
}
}
+
+void
+libbe_print_on_error(libbe_handle_t *lbh, bool val)
+{
+ lbh->print_on_err = val;
+ libzfs_print_on_error(lbh->lzh, val);
+}
+
+int
+set_error(libbe_handle_t *lbh, be_error_t err)
+{
+ // TODO: should the old error be overwritten or no?
+
+ lbh->error = err;
+
+ if(lbh->print_on_err) {
+ fprintf(stderr, "%s\n", libbe_error_description(lbh));
+ }
+
+ return (err);
+}
Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h Mon Jul 3 11:16:47 2017 (r324213)
@@ -30,14 +30,8 @@
#define _LIBBE_IMPL_H
#include <libzfs.h>
+#include "be.h"
-typedef enum be_error {
- BE_ERR_SUCCESS = 0, /* No error */
- BE_ERR_INVALIDNAME, /* invalid boot env name */
- BE_ERR_EXISTS, /* boot env name already taken */
- BE_ERR_PERMS, /* insufficient permissions */
- BE_ERR_UNKNOWN, /* unknown error */
-} be_error_t;
struct libbe_handle {
libzfs_handle_t *lzh;
@@ -45,9 +39,12 @@
zfs_handle_t *be_active;
be_error_t error;
nvlist_t *list;
+ bool print_on_err;
};
int prop_list_builder(libbe_handle_t *);
void prop_list_free(libbe_handle_t *);
+int set_error(libbe_handle_t *, be_error_t);
+
#endif /* _LIBBE_IMPL_H */
Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_info.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_info.c Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_info.c Mon Jul 3 11:16:47 2017 (r324213)
@@ -70,6 +70,8 @@
nvlist_t *
be_get_bootenv_props(libbe_handle_t *lbh)
{
+ // TODO: Should there be a dirty flag that re-calcs the list if an op
+ // has changed it?
return (lbh->list);
}
@@ -82,8 +84,13 @@
static int
prop_list_builder_cb(zfs_handle_t *zfs_hdl, void *data)
{
+ /*
+ * TODO:
+ * some system for defining constants for the nvlist keys
+ * error checking
+ */
+
boolean_t mounted, active, nextboot;
- /* TODO: what type for size? Number bytes as int or long? */
char buf[512];
@@ -159,6 +166,8 @@
/*
* Updates the properties of each bootenv in the libbe handle
* TODO: rename to be_proplist_update
+ * TODO: ensure that this is always consistent (run after adds, deletes,
+ * renames,etc
*/
int
prop_list_builder(libbe_handle_t *lbh)
@@ -179,9 +188,28 @@
return (0);
}
-
+/*
+ * Frees property list and its children
+ */
void
prop_list_free(libbe_handle_t *lbh)
{
- /* TODO */
+ nvlist_t *be_list;
+ nvlist_t *prop_list;
+
+ if((be_list = lbh->list) == 0) {
+ return;
+ }
+
+ nvpair_t *be_pair = nvlist_next_nvpair(be_list, NULL);
+
+ if(nvpair_value_nvlist(be_pair, &prop_list) == 0) {
+ nvlist_free(prop_list);
+ }
+
+ while((be_pair = nvlist_next_nvpair(be_list, be_pair)) != NULL) {
+ if(nvpair_value_nvlist(be_pair, &prop_list) == 0) {
+ nvlist_free(prop_list);
+ }
+ }
}
Modified: soc2017/kneitinger/libbe-head/sbin/be/be.c
==============================================================================
--- soc2017/kneitinger/libbe-head/sbin/be/be.c Mon Jul 3 10:24:49 2017 (r324212)
+++ soc2017/kneitinger/libbe-head/sbin/be/be.c Mon Jul 3 11:16:47 2017 (r324213)
@@ -476,6 +476,8 @@
be = libbe_init();
+ libbe_print_on_error(be, true);
+
int rc = command_map[command_index].fn(argc-1, argv+1);
libbe_close(be);
More information about the svn-soc-all
mailing list