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