Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jul 2017 08:03:21 GMT
From:      kneitinger@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r324530 - in soc2017/kneitinger/libbe-head: lib/libbe sbin/be
Message-ID:  <201707120803.v6C83LkX084984@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kneitinger
Date: Wed Jul 12 08:03:21 2017
New Revision: 324530
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=324530

Log:
  libbe(3): add mount/unmount functions
  

Added:
  soc2017/kneitinger/libbe-head/lib/libbe/be_access.c
Modified:
  soc2017/kneitinger/libbe-head/lib/libbe/Makefile
  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/Makefile
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/Makefile	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/Makefile	Wed Jul 12 08:03:21 2017	(r324530)
@@ -28,7 +28,7 @@
 LIB=		be
 SHLIB_MAJOR=	1
 SHLIB_MINOR=	0
-SRCS=		be.c be_error.c be_info.c
+SRCS=		be.c be_access.c be_error.c be_info.c
 INCS=		be.h
 MAN=		libbe.3
 

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.c	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.c	Wed Jul 12 08:03:21 2017	(r324530)
@@ -26,11 +26,12 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/types.h>
+
 #include <ctype.h>
 #include <kenv.h>
 #include <libgen.h>
 #include <stdio.h>
-#include <sys/types.h>
 #include <time.h>
 
 #include "be.h"
@@ -135,20 +136,17 @@
 	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);
+		return (set_error(lbh, BE_ERR_NOENT));
 	}
 
 	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);
+		return (set_error(lbh, BE_ERR_DESTROYACT));
 	}
 
 	if ((mounted = zfs_is_mounted(fs, &p)) && !(force)) {
-		err = set_error(lbh, BE_ERR_DESTROYMNT);
-		return (err);
+		return (set_error(lbh, BE_ERR_DESTROYMNT));
 	}
 
 	// TODO: check dependants
@@ -327,6 +325,9 @@
 int
 be_root_concat(libbe_handle_t *lbh, char *name, char *result)
 {
+	// TODO: make idempotent. As in: if it already is of the form:
+	// pool/beroot/be, return that
+
 	const char *root = be_root_path(lbh);
 	int n = snprintf(result, MAXPATHLEN, "%s/%s", root, name);
 

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.h
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.h	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.h	Wed Jul 12 08:03:21 2017	(r324530)
@@ -45,6 +45,9 @@
 	BE_ERR_PATHLEN,         /* provided name exceeds maximum length limit */
 	BE_ERR_INVORIGIN,       /* snapshot origin's mountpoint is not '/' */
 	BE_ERR_NOORIGIN,        /* could not open snapshot's origin */
+	BE_ERR_MOUNTED,         /* boot environment is already mounted */
+	BE_ERR_NOMOUNT,         /* boot environment is not mounted */
+	BE_ERR_ZFSOPEN,         /* calling zfs_open() failed */
 	BE_ERR_UNKNOWN,         /* unknown error */
 } be_error_t;
 
@@ -58,6 +61,7 @@
 const char *be_active_path(libbe_handle_t *);
 const char *be_root_path(libbe_handle_t *);
 nvlist_t *be_get_bootenv_props(libbe_handle_t *);
+bool be_exists(libbe_handle_t, char *);
 
 /* Bootenv creation functions */
 int be_create(libbe_handle_t *, char *);
@@ -68,15 +72,23 @@
 
 /* Bootenv removal functions */
 
-#define BE_DESTROY_FORCE    1
+typedef enum {
+	BE_DESTROY_FORCE = 1 << 0,
+} be_destroy_opt_t;
 
 int be_destroy(libbe_handle_t *, char *, int);
 
-/* Bootenv mounting functions */
-int be_mount(libbe_handle_t *, char *, char *);
+/* Bootenv mounting functions: be_access.c */
+
+typedef enum {
+	BE_MNT_FORCE		= 1 << 0,
+		BE_MNT_DEEP	= 1 << 1,
+} be_mount_opt_t;
+
+int be_mount(libbe_handle_t *, char *, char *, int);
 int be_unmount(libbe_handle_t *, char *, int);
 
-/* Bootenv jail functions */
+/* Bootenv jail functions: be_access.c */
 int be_jail(libbe_handle_t *, char *);
 
 /* Error related functions: be_error.c */
@@ -88,5 +100,6 @@
 int be_root_concat(libbe_handle_t *, char *, char *);
 int be_validate_name(libbe_handle_t *, char *);
 int be_validate_snap(libbe_handle_t *, char *);
+bool be_exists(libbe_handle_t *, char *);
 
 #endif  /* _LIBBE_H */

Added: soc2017/kneitinger/libbe-head/lib/libbe/be_access.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_access.c	Wed Jul 12 08:03:21 2017	(r324530)
@@ -0,0 +1,127 @@
+/*
+ * be_access.c
+ *
+ * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "be.h"
+#include "be_impl.h"
+
+/*
+ * usage
+ */
+int
+be_mount(libbe_handle_t *lbh, char *bootenv, char *mountpoint, int flags)
+{
+    char be[MAXPATHLEN];
+    zfs_handle_t *zfs_hdl;
+    char *path;
+    int mntflags;
+    int err;
+
+    // TODO: handle deep bes
+
+    if (err = be_root_concat(lbh, bootenv, be)) {
+        return (set_error(lbh, err));
+    }
+
+    // TODO: make sure it exists (in a be_exists fn)!
+
+    if (is_mounted(lbh->lzh, be, &path)) {
+        return (set_error(lbh, BE_ERR_MOUNTED));
+    }
+
+
+    mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
+
+    char opt = '\0';
+    if (err = zmount(be, mountpoint, mntflags, MNTTYPE_ZFS,
+        NULL, 0, &opt, 1)) {
+        // TODO: zmount returns the nmount error, look into what kind of
+        // errors we can report from that
+        return (set_error(lbh, BE_ERR_UNKNOWN));
+    }
+
+    return (set_error(lbh, BE_ERR_SUCCESS));
+}
+
+
+/*
+ * usage
+ */
+int
+be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
+{
+    int err, mntflags;
+    char be[MAXPATHLEN];
+    struct statfs *mntbuf;
+    int mntsize;
+    char *mntpath;
+
+    if (err = be_root_concat(lbh, bootenv, be)) {
+        return (set_error(lbh, err));
+    }
+
+    if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+        // TODO correct error
+        return (set_error(lbh, BE_ERR_NOMOUNT));
+    }
+
+    mntpath = NULL;
+    for (int i = 0; i < mntsize; ++i) {
+        /* 0x000000de is the type number of zfs */
+        if (mntbuf[i].f_type != 0x000000de) {
+            continue;
+        }
+
+        if (strcmp(mntbuf[i].f_mntfromname, be) == 0) {
+            mntpath = mntbuf[i].f_mntonname;
+            break;
+        }
+    }
+
+    if (mntpath == NULL) {
+        return (set_error(lbh, BE_ERR_NOMOUNT));
+    }
+
+    mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
+
+    if (err = unmount(mntpath, mntflags)) {
+        // TODO correct error
+        return (set_error(lbh, BE_ERR_NOMOUNT));
+    }
+
+    return (set_error(lbh, BE_ERR_SUCCESS));
+}
+
+
+/*
+ * usage
+ */
+int
+be_jail(libbe_handle_t *lbh, char *bootenv)
+{
+    return (BE_ERR_SUCCESS);
+}

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_error.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_error.c	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_error.c	Wed Jul 12 08:03:21 2017	(r324530)
@@ -35,69 +35,78 @@
 int
 libbe_errno(libbe_handle_t *lbh)
 {
-	return (lbh->error);
+    return (lbh->error);
 }
 
 
 const char *
 libbe_error_description(libbe_handle_t *lbh)
 {
-	switch (lbh->error) {
-	case BE_ERR_INVALIDNAME:
-		return ("invalid boot environment name");
+    switch (lbh->error) {
+    case BE_ERR_INVALIDNAME:
+        return ("invalid boot environment name");
 
-	case BE_ERR_EXISTS:
-		return ("boot environment name already taken");
+    case BE_ERR_EXISTS:
+        return ("boot environment name already taken");
 
-	case BE_ERR_NOENT:
-		return ("specified boot environment does not exist");
+    case BE_ERR_NOENT:
+        return ("specified boot environment does not exist");
 
-	case BE_ERR_PERMS:
-		return ("insufficient permissions");
+    case BE_ERR_PERMS:
+        return ("insufficient permissions");
 
-	case BE_ERR_DESTROYACT:
-		return ("cannot destroy active boot environment");
+    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_DESTROYMNT:
+        return ("cannot destroy mounted boot env unless forced");
 
-	case BE_ERR_PATHLEN:
-		return ("provided path name exceeds maximum length limit");
+    case BE_ERR_PATHLEN:
+        return ("provided path name exceeds maximum length limit");
 
-	case BE_ERR_INVORIGIN:
-		return ("snapshot origin's mountpoint is not \"/\"");
+    case BE_ERR_INVORIGIN:
+        return ("snapshot origin's mountpoint is not \"/\"");
 
-	case BE_ERR_NOORIGIN:
-		return ("could not open snapshot's origin");
+    case BE_ERR_NOORIGIN:
+        return ("could not open snapshot's origin");
 
-	case BE_ERR_UNKNOWN:
-		return ("unknown error");
+    case BE_ERR_MOUNTED:
+        return ("boot environment is already mounted");
 
-	default:
-		assert(lbh->error == BE_ERR_SUCCESS);
-		return ("no error");
-	}
+    case BE_ERR_NOMOUNT:
+        return ("boot environment is not mounted");
+
+    case BE_ERR_ZFSOPEN:
+        return ("calling zfs_open() failed");
+
+    case BE_ERR_UNKNOWN:
+        return ("unknown error");
+
+    default:
+        assert(lbh->error == BE_ERR_SUCCESS);
+        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);
+    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?
+    // TODO: should the old error be overwritten or no?
 
-	lbh->error = err;
+    lbh->error = err;
 
-	if (lbh->print_on_err) {
-		fprintf(stderr, "%s\n", libbe_error_description(lbh));
-	}
+    if (lbh->print_on_err) {
+        fprintf(stderr, "%s\n", libbe_error_description(lbh));
+    }
 
-	return (err);
+    return (err);
 }

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_impl.h	Wed Jul 12 08:03:21 2017	(r324530)
@@ -30,16 +30,17 @@
 #define _LIBBE_IMPL_H
 
 #include <libzfs.h>
+
 #include "be.h"
 
 
 struct libbe_handle {
-	libzfs_handle_t *lzh;
-	zfs_handle_t *be_root;
-	zfs_handle_t *be_active;
-	be_error_t error;
-	nvlist_t *list;
-	bool print_on_err;
+    libzfs_handle_t *lzh;
+    zfs_handle_t *be_root;
+    zfs_handle_t *be_active;
+    be_error_t error;
+    nvlist_t *list;
+    bool print_on_err;
 };
 
 int prop_list_builder(libbe_handle_t *);

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_info.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_info.c	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_info.c	Wed Jul 12 08:03:21 2017	(r324530)
@@ -37,9 +37,9 @@
 const char *
 be_active_name(libbe_handle_t *lbh)
 {
-	const char *full_path = zfs_get_name(lbh->be_active);
+    const char *full_path = zfs_get_name(lbh->be_active);
 
-	return (strrchr(full_path, '/') + 1);
+    return (strrchr(full_path, '/') + 1);
 }
 
 
@@ -49,7 +49,7 @@
 const char *
 be_active_path(libbe_handle_t *lbh)
 {
-	return (zfs_get_name(lbh->be_active));
+    return (zfs_get_name(lbh->be_active));
 }
 
 
@@ -59,7 +59,7 @@
 const char *
 be_root_path(libbe_handle_t *lbh)
 {
-	return (zfs_get_name(lbh->be_root));
+    return (zfs_get_name(lbh->be_root));
 }
 
 
@@ -70,9 +70,9 @@
 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);
+    // TODO: Should there be a dirty flag that re-calcs the list if an op
+    // has changed it?
+    return (lbh->list);
 }
 
 
@@ -84,82 +84,83 @@
 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
-	 */
+    /*
+     * TODO:
+     *      some system for defining constants for the nvlist keys
+     *      error checking
+     */
 
-	boolean_t mounted, active, nextboot;
+    boolean_t mounted, active, nextboot;
 
-	char buf[512];
+    char buf[512];
 
-	nvlist_t *props;
+    nvlist_t *props;
 
-	libbe_handle_t *lbh = (libbe_handle_t *)data;
+    libbe_handle_t *lbh = (libbe_handle_t *)data;
 
 
-	nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
+    nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
 
-	const char *dataset = zfs_get_name(zfs_hdl);
-	nvlist_add_string(props, "dataset", dataset);
+    const char *dataset = zfs_get_name(zfs_hdl);
+    nvlist_add_string(props, "dataset", dataset);
 
-	const char *name = strrchr(dataset, '/') + 1;
-	nvlist_add_string(props, "name", name);
+    const char *name = strrchr(dataset, '/') + 1;
+    nvlist_add_string(props, "name", name);
 
 
-	mounted = zfs_prop_get_int(zfs_hdl, ZFS_PROP_MOUNTED);
-	nvlist_add_boolean_value(props, "mounted", mounted);
+    mounted = zfs_prop_get_int(zfs_hdl, ZFS_PROP_MOUNTED);
+    nvlist_add_boolean_value(props, "mounted", mounted);
 
-	if (mounted) {
-		zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, 512,
-		    NULL, NULL, 0, 1);
-		nvlist_add_string(props, "mountpoint", buf);
-	}
+    // TODO: NOT CORRECT! Must use is_mounted
+    if (mounted) {
+        zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, 512,
+            NULL, NULL, 0, 1);
+        nvlist_add_string(props, "mountpoint", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_ORIGIN, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "origin", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_ORIGIN, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "origin", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_CREATION, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "creation", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_CREATION, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "creation", buf);
+    }
 
-	nvlist_add_boolean_value(props, "active",
-	    (strcmp(be_active_path(lbh), dataset) == 0));
+    nvlist_add_boolean_value(props, "active",
+        (strcmp(be_active_path(lbh), dataset) == 0));
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_USED, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "used", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_USED, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "used", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDDS, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "usedds", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDDS, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "usedds", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDSNAP, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "usedsnap", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDSNAP, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "usedsnap", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDREFRESERV, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "usedrefreserv", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_USEDREFRESERV, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "usedrefreserv", buf);
+    }
 
-	if (zfs_prop_get(zfs_hdl, ZFS_PROP_REFERENCED, buf, 512,
-	    NULL, NULL, 0, 1)) {
-		nvlist_add_string(props, "referenced", buf);
-	}
+    if (zfs_prop_get(zfs_hdl, ZFS_PROP_REFERENCED, buf, 512,
+        NULL, NULL, 0, 1)) {
+        nvlist_add_string(props, "referenced", buf);
+    }
 
-	/* TODO figure out how to read nextboot (set in libzfs_pool.c) */
+    /* TODO figure out how to read nextboot (set in libzfs_pool.c) */
 
-	nvlist_add_nvlist(lbh->list, name, props);
+    nvlist_add_nvlist(lbh->list, name, props);
 
-	return (0);
+    return (0);
 }
 
 
@@ -172,45 +173,56 @@
 int
 prop_list_builder(libbe_handle_t *lbh)
 {
-	if (lbh->list != NULL) {
-		/* TODO: should actually call prop_list_free */
-		nvlist_free(lbh->list);
-		return (1);
-	}
+    if (lbh->list != NULL) {
+        /* TODO: should actually call prop_list_free */
+        nvlist_free(lbh->list);
+        return (1);
+    }
 
-	if (nvlist_alloc(&lbh->list, NV_UNIQUE_NAME, KM_SLEEP) != 0) {
-		/* TODO: actually handle error */
-		return (1);
-	}
+    if (nvlist_alloc(&lbh->list, NV_UNIQUE_NAME, KM_SLEEP) != 0) {
+        /* TODO: actually handle error */
+        return (1);
+    }
 
-	zfs_iter_filesystems(lbh->be_root, prop_list_builder_cb, lbh);
+    zfs_iter_filesystems(lbh->be_root, prop_list_builder_cb, lbh);
 
-	return (0);
+    return (0);
 }
 
 
 /*
- * Frees property list and its children
+ * frees property list and its children
  */
 void
 prop_list_free(libbe_handle_t *lbh)
 {
-	nvlist_t *be_list;
-	nvlist_t *prop_list;
+    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);
-		}
-	}
+    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);
+        }
+    }
+}
+
+
+/*
+ * Usage
+ */
+bool
+be_exists(libbe_handle_t lbh, char *be)
+{
+    // TODO
+    return (true);
 }

Modified: soc2017/kneitinger/libbe-head/sbin/be/be.c
==============================================================================
--- soc2017/kneitinger/libbe-head/sbin/be/be.c	Wed Jul 12 07:31:28 2017	(r324529)
+++ soc2017/kneitinger/libbe-head/sbin/be/be.c	Wed Jul 12 08:03:21 2017	(r324530)
@@ -148,11 +148,10 @@
 static int
 be_cmd_create(int argc, char *argv[])
 {
-	int opt;
+	int err, opt;
 	bool recursive;
 	char *existing;
 	char *bootenv;
-	char *snapshot;
 
 	existing = NULL;
 	recursive = false;
@@ -179,25 +178,17 @@
 		return (usage(false));
 	}
 
-	/* Determine bootenv name, and snapshot if provided */
-	char *buffer = malloc((strlen(argv[0])+1) * sizeof(char));
-	strcpy(buffer, argv[0]);
-	char *delimiter;
-	if ((delimiter = strchr(buffer, '@')) != NULL) {
-		*delimiter = '\0';
-		snapshot = delimiter + sizeof(char);
-		if (strchr(snapshot, '@') != NULL) {
-			fprintf(stderr, "be destroy: invalid snapshot name\n");
-			free(buffer);
-			return (usage(false));
-		}
-	}
-	bootenv = buffer;
+	bootenv = *argv;
 
-	/* create logic goes here */
 
-	free(buffer);
-	return (0);
+	if (existing != NULL) {
+		err = be_create_from_existing(be, bootenv, existing);
+		// TODO: look at err and print useful message
+	} else {
+		err = be_create(be, bootenv);
+	}
+
+	return (err);
 }
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707120803.v6C83LkX084984>