Date: Mon, 3 Jul 2017 11:16:47 GMT From: kneitinger@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r324213 - in soc2017/kneitinger/libbe-head: lib/libbe sbin/be Message-ID: <201707031116.v63BGlKJ078238@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707031116.v63BGlKJ078238>