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