socsvn commit: r324318 - soc2017/kneitinger/libbe-head/lib/libbe

kneitinger at FreeBSD.org kneitinger at FreeBSD.org
Thu Jul 6 04:03:29 UTC 2017


Author: kneitinger
Date: Thu Jul  6 04:03:25 2017
New Revision: 324318
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=324318

Log:
  libbe(3): add function to create boot env from exising snapshot
  

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_info.c

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.c	Thu Jul  6 00:53:12 2017	(r324317)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.c	Thu Jul  6 04:03:25 2017	(r324318)
@@ -169,7 +169,7 @@
 	time_t rawtime;
 	zfs_handle_t *snap_hdl;
 
-	if (!(be_valid_name(lbh, name))) {
+	if (be_validate_name(lbh, name)) {
 		err = set_error(lbh, BE_ERR_INVALIDNAME);
 		return (err);
 	}
@@ -215,9 +215,114 @@
 
 
 /*
+ * Create the boot environment from pre-existing snapshot
+ */
+int
+be_create_from_existing(libbe_handle_t *lbh, char *name, char *snap)
+{
+	int err, pos;
+	char be_path[MAXPATHLEN];
+	char snap_name[MAXPATHLEN];
+	time_t rawtime;
+	zfs_handle_t *snap_hdl;
+
+
+	if (be_validate_name(lbh, name)) {
+		err = set_error(lbh, BE_ERR_INVALIDNAME);
+		return (err);
+	}
+
+
+	/* Ensure snap exists and it's parent dataset has mountpoint of '/' */
+	if (err = be_validate_snap(lbh, snap)) {
+		// set correct errs
+		return (-1);
+	}
+
+
+	if (err = be_root_concat(lbh, name, be_path)) {
+		return (err);
+	}
+
+	pos = snprintf(be_path, MAXPATHLEN, "%s/%s", be_root_path(lbh), name);
+
+	if ((pos < 0) || (pos >= MAXPATHLEN)) {
+		err = set_error(lbh, BE_ERR_PATHLEN);
+	}
+
+	if (zfs_dataset_exists(lbh->lzh, be_path, ZFS_TYPE_DATASET)) {
+		err = set_error(lbh, BE_ERR_EXISTS);
+		return (err);
+	}
+
+
+	snap_hdl = zfs_open(lbh->lzh, snap, ZFS_TYPE_SNAPSHOT);
+
+	// TODO: should any props be in the last arg (nvlist)?
+	if (err = zfs_clone(snap_hdl, be_path, NULL)) {
+		// TODO: switch on err to determine correct BE_ERR_* to return
+		return (-1);
+	}
+
+	zfs_close(snap_hdl);
+
+	return (err);
+}
+
+
+/* Verifies that a snapshot has a valid name, exists, and has a mountpoint of
+ * '/'. Returns BE_ERR_SUCCESS (0), upon success, or the relevant BE_ERR_* upon
+ * failure. Does not set the internal library error state.
+ */
+int
+be_validate_snap(libbe_handle_t *lbh, char *snap_name)
+{
+	zfs_handle_t *zfs_hdl;
+	char buf[MAXPATHLEN];
+	char *snap_delim;
+	char *mountpoint;
+	int err = 0;
+
+	if (strlen(snap_name) >= MAXPATHLEN) {
+		return (BE_ERR_PATHLEN);
+	}
+
+	if (!zfs_dataset_exists(lbh->lzh, snap_name, ZFS_TYPE_SNAPSHOT)) {
+		return (BE_ERR_NOENT);
+	}
+
+	strncpy(buf, snap_name, MAXPATHLEN);
+
+	if ((snap_delim = strchr(buf, '@')) == NULL) {
+		return (BE_ERR_INVALIDNAME);
+	}
+
+	*snap_delim = '\0';
+
+	if ((zfs_hdl = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL) {
+		return (BE_ERR_NOORIGIN);
+	}
+
+	if (err = zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
+	    NULL, NULL, 0, 1)) {
+		err = BE_ERR_INVORIGIN;
+	}
+
+	if ((err != 0) && (strncmp(buf, "/", MAXPATHLEN) != 0)) {
+		err = BE_ERR_INVORIGIN;
+	}
+
+	zfs_close(zfs_hdl);
+
+	return (BE_ERR_SUCCESS);
+}
+
+
+/*
  * Appends the name argument on the root boot environment path and copies the
  * resulting string into the result buffer. Returns 0 upon success and
- * BE_ERR_PATHLEN if the resulting path is longer than MAXPATHLEN
+ * BE_ERR_PATHLEN if the resulting path is longer than MAXPATHLEN. Does not set
+ * internal library error state.
  */
 int
 be_root_concat(libbe_handle_t *lbh, char *name, char *result)
@@ -229,28 +334,23 @@
 		return (BE_ERR_SUCCESS);
 	}
 
-	// TODO: reconsider if this, or the caller, should set_error.
-	return (set_error(lbh, BE_ERR_PATHLEN));
+	return (BE_ERR_PATHLEN);
 }
 
 
 /*
  * Verifies the validity of a boot environment name (A-Za-z0-9-_.,). Returns 0
  * if the name is valid, otherwise, returns the position of the first offending
- * character
+ * character. Does not set internal library error state.
  */
 int
-be_valid_name(libbe_handle_t *lbh, char *name)
+be_validate_name(libbe_handle_t *lbh, char *name)
 {
 	for (int i = 0; *name; i++) {
 		char c = *(name++);
 		// TODO: beadm allows commas...they seem like a bad idea though
 		if (isalnum(c) || (c == '-') || (c == '_') || (c == '.') ||
 		    (c == ',')) {
-			// if lbh is not null, the offending char could be
-			// logged into some field for helpful error reporting
-			// also, should the set_error happen here, or in the
-			// caller (probably caller)??
 			return (i);
 		}
 	}

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be.h
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be.h	Thu Jul  6 00:53:12 2017	(r324317)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be.h	Thu Jul  6 04:03:25 2017	(r324318)
@@ -43,6 +43,8 @@
 	BE_ERR_DESTROYACT,      /* cannot destroy active boot env */
 	BE_ERR_DESTROYMNT,      /* destroying a mounted be requires force */
 	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_UNKNOWN,         /* unknown error */
 } be_error_t;
 
@@ -84,6 +86,7 @@
 
 /* Utility Functions */
 int be_root_concat(libbe_handle_t *, char *, char *);
-int be_valid_name(libbe_handle_t *, char *);
+int be_validate_name(libbe_handle_t *, char *);
+int be_validate_snap(libbe_handle_t *, char *);
 
 #endif  /* _LIBBE_H */

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_error.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_error.c	Thu Jul  6 00:53:12 2017	(r324317)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_error.c	Thu Jul  6 04:03:25 2017	(r324318)
@@ -64,6 +64,12 @@
 	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_NOORIGIN:
+		return ("could not open snapshot's origin");
+
 	case BE_ERR_UNKNOWN:
 		return ("unknown error");
 

Modified: soc2017/kneitinger/libbe-head/lib/libbe/be_info.c
==============================================================================
--- soc2017/kneitinger/libbe-head/lib/libbe/be_info.c	Thu Jul  6 00:53:12 2017	(r324317)
+++ soc2017/kneitinger/libbe-head/lib/libbe/be_info.c	Thu Jul  6 04:03:25 2017	(r324318)
@@ -117,41 +117,41 @@
 		nvlist_add_string(props, "mountpoint", buf);
 	}
 
-	if ((zfs_prop_get(zfs_hdl, ZFS_PROP_ORIGIN, buf, 512,
-	    NULL, NULL, 0, 1)) == 0) {
+	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)) == 0) {
+	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));
 
-	if ((zfs_prop_get(zfs_hdl, ZFS_PROP_USED, buf, 512,
-	    NULL, NULL, 0, 1)) == 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_USEDDS, buf, 512,
-	    NULL, NULL, 0, 1)) == 0) {
+	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)) == 0) {
+	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)) == 0) {
+	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)) == 0) {
+	if (zfs_prop_get(zfs_hdl, ZFS_PROP_REFERENCED, buf, 512,
+	    NULL, NULL, 0, 1)) {
 		nvlist_add_string(props, "referenced", buf);
 	}
 


More information about the svn-soc-all mailing list