svn commit: r342807 - in stable/11: . contrib/mdocml lib lib/libbe sbin sbin/bectl share/mk sys/amd64/conf tools/build/mk usr.sbin/config
Kyle Evans
kevans at FreeBSD.org
Sun Jan 6 02:13:20 UTC 2019
Author: kevans
Date: Sun Jan 6 02:13:16 2019
New Revision: 342807
URL: https://svnweb.freebsd.org/changeset/base/342807
Log:
MFC r342362-r342363: config(8) duplicate option handling
r342362:
config(8): Allow duplicate options to be specified
config(8)'s option handling has been written to allow duplicate options; if
the value changes, then the latest value is used and an informative message
is printed to stderr like so:
/usr/src/sys/amd64/conf/TEST: option "VERBOSE_SYSINIT" redefined from 0 to 1
Currently, this is only a possibility for cpu types, MAXUSERS, and
MACHINE_ARCH. Anything else duplicated in a config file will use the first
value set and error about duplicated options on subsequent appearances,
which is arguably unfriendly since one could specify:
include GENERIC
nooptions VERBOSE_SYSINIT
options VERBOSE_SYSINIT
to redefine the value later anyways.
Reported by: mmacy
r342363:
config(8): Remove all instances of an option when opting out
Quick follow-up to r342362: options can appear multiple times now, so
clean up all of them as needed. For non-OPTIONS options, this has no effect
since they're already de-duplicated.
Added:
stable/11/lib/libbe/
- copied from r337664, head/lib/libbe/
stable/11/lib/libbe/Makefile
- copied, changed from r337995, head/lib/libbe/Makefile
stable/11/sbin/bectl/
- copied from r337664, head/sbin/bectl/
Modified:
stable/11/Makefile.inc1
stable/11/ObsoleteFiles.inc
stable/11/contrib/mdocml/lib.in
stable/11/lib/Makefile
stable/11/lib/libbe/be.c
stable/11/lib/libbe/be.h
stable/11/lib/libbe/be_access.c
stable/11/lib/libbe/be_error.c
stable/11/lib/libbe/be_info.c
stable/11/lib/libbe/libbe.3
stable/11/sbin/Makefile
stable/11/sbin/bectl/Makefile
stable/11/sbin/bectl/bectl.8
stable/11/sbin/bectl/bectl.c
stable/11/sbin/bectl/bectl_jail.c
stable/11/sbin/bectl/bectl_list.c
stable/11/share/mk/bsd.libnames.mk
stable/11/share/mk/src.libnames.mk
stable/11/sys/amd64/conf/GENERIC
stable/11/sys/amd64/conf/MINIMAL
stable/11/tools/build/mk/OptionalObsoleteFiles.inc
stable/11/usr.sbin/config/config.y
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/Makefile.inc1
==============================================================================
--- stable/11/Makefile.inc1 Sun Jan 6 02:12:55 2019 (r342806)
+++ stable/11/Makefile.inc1 Sun Jan 6 02:13:16 2019 (r342807)
@@ -2144,7 +2144,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
${_cddl_lib_libuutil} \
${_cddl_lib_libavl} \
- ${_cddl_lib_libzfs_core} \
+ ${_cddl_lib_libzfs_core} ${_cddl_lib_libzfs} \
${_cddl_lib_libctf} \
lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \
${_secure_lib_libcrypto} ${_lib_libldns} \
@@ -2213,7 +2213,15 @@ _cddl_lib_libavl= cddl/lib/libavl
_cddl_lib_libuutil= cddl/lib/libuutil
.if ${MK_ZFS} != "no"
_cddl_lib_libzfs_core= cddl/lib/libzfs_core
+_cddl_lib_libzfs= cddl/lib/libzfs
+
cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L
+
+cddl/lib/libzfs__L: cddl/lib/libzfs_core__L lib/msun__L lib/libutil__L
+cddl/lib/libzfs__L: lib/libthr__L lib/libmd__L lib/libz__L cddl/lib/libumem__L
+cddl/lib/libzfs__L: cddl/lib/libuutil__L cddl/lib/libavl__L lib/libgeom__L
+
+lib/libbe__L: cddl/lib/libzfs__L
.endif
_cddl_lib_libctf= cddl/lib/libctf
_cddl_lib= cddl/lib
Modified: stable/11/ObsoleteFiles.inc
==============================================================================
--- stable/11/ObsoleteFiles.inc Sun Jan 6 02:12:55 2019 (r342806)
+++ stable/11/ObsoleteFiles.inc Sun Jan 6 02:13:16 2019 (r342807)
@@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20181115: libbe(3) SHLIBDIR fixed to reflect correct location
+OLD_LIBS+=usr/lib/libbe.so.1
# 20180812: move of libmlx5.so.1 and libibverbs.so.1
OLD_LIBS+=usr/lib/libmlx5.so.1
OLD_LIBS+=usr/lib/libibverbs.so.1
Modified: stable/11/contrib/mdocml/lib.in
==============================================================================
--- stable/11/contrib/mdocml/lib.in Sun Jan 6 02:12:55 2019 (r342806)
+++ stable/11/contrib/mdocml/lib.in Sun Jan 6 02:13:16 2019 (r342807)
@@ -28,6 +28,7 @@ LINE("lib80211", "802.11 Wireless Network Management L
LINE("libarchive", "Streaming Archive Library (libarchive, \\-larchive)")
LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
+LINE("libbe", "Boot Environment Library (libbe, \\-lbe)")
LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
LINE("libbsm", "Basic Security Module Library (libbsm, \\-lbsm)")
LINE("libc", "Standard C\\~Library (libc, \\-lc)")
Modified: stable/11/lib/Makefile
==============================================================================
--- stable/11/lib/Makefile Sun Jan 6 02:12:55 2019 (r342806)
+++ stable/11/lib/Makefile Sun Jan 6 02:13:16 2019 (r342807)
@@ -289,6 +289,7 @@ _libproc= libproc
_librtld_db= librtld_db
.endif
SUBDIR.${MK_OFED}+= ofed
+SUBDIR.${MK_ZFS}+= libbe
.if ${MK_OPENSSL} != "no"
_libmp= libmp
Copied and modified: stable/11/lib/libbe/Makefile (from r337995, head/lib/libbe/Makefile)
==============================================================================
--- head/lib/libbe/Makefile Sat Aug 18 03:20:59 2018 (r337995, copy source)
+++ stable/11/lib/libbe/Makefile Sun Jan 6 02:13:16 2019 (r342807)
@@ -2,6 +2,7 @@
PACKAGE= lib${LIB}
LIB= be
+SHLIBDIR?= /lib
SHLIB_MAJOR= 1
SHLIB_MINOR= 0
Modified: stable/11/lib/libbe/be.c
==============================================================================
--- head/lib/libbe/be.c Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/be.c Sun Jan 6 02:13:16 2019 (r342807)
@@ -64,10 +64,13 @@ be_locate_rootfs(zfs_handle_t *chkds, void *data)
if (lbh == NULL)
return (1);
+ mntpoint = NULL;
if (zfs_is_mounted(chkds, &mntpoint) && strcmp(mntpoint, "/") == 0) {
- strncpy(lbh->rootfs, zfs_get_name(chkds), BE_MAXPATHLEN);
+ strlcpy(lbh->rootfs, zfs_get_name(chkds), sizeof(lbh->rootfs));
+ free(mntpoint);
return (1);
- }
+ } else if(mntpoint != NULL)
+ free(mntpoint);
return (0);
}
@@ -88,7 +91,6 @@ libbe_init(void)
lbh = NULL;
poolname = pos = NULL;
- pnamelen = 0;
rootds = NULL;
/* Verify that /boot and / are mounted on the same filesystem */
@@ -115,13 +117,14 @@ libbe_init(void)
goto err;
/* Obtain path to boot environment root */
- if ((kenv(KENV_GET, "zfs_be_root", lbh->root, BE_MAXPATHLEN)) == -1)
+ if ((kenv(KENV_GET, "zfs_be_root", lbh->root,
+ sizeof(lbh->root))) == -1)
goto err;
/* Remove leading 'zfs:' if present, otherwise use value as-is */
if (strcmp(lbh->root, "zfs:") == 0)
- strncpy(lbh->root, strchr(lbh->root, ':') + sizeof(char),
- BE_MAXPATHLEN);
+ strlcpy(lbh->root, strchr(lbh->root, ':') + sizeof(char),
+ sizeof(lbh->root));
if ((pos = strchr(lbh->root, '/')) == NULL)
goto err;
@@ -131,13 +134,14 @@ libbe_init(void)
if (poolname == NULL)
goto err;
- strncpy(poolname, lbh->root, pnamelen);
- poolname[pnamelen] = '\0';
+ strlcpy(poolname, lbh->root, pnamelen + 1);
if ((lbh->active_phandle = zpool_open(lbh->lzh, poolname)) == NULL)
goto err;
+ free(poolname);
+ poolname = NULL;
if (zpool_get_prop(lbh->active_phandle, ZPOOL_PROP_BOOTFS, lbh->bootfs,
- BE_MAXPATHLEN, NULL, true) != 0)
+ sizeof(lbh->bootfs), NULL, true) != 0)
goto err;
/* Obtain path to boot environment rootfs (currently booted) */
@@ -160,8 +164,6 @@ err:
libzfs_fini(lbh->lzh);
free(lbh);
}
- if (rootds != NULL)
- zfs_close(rootds);
free(poolname);
return (NULL);
}
@@ -217,7 +219,6 @@ be_destroy(libbe_handle_t *lbh, const char *name, int
p = path;
force = options & BE_DESTROY_FORCE;
- err = BE_ERR_SUCCESS;
be_root_concat(lbh, name, path);
@@ -269,22 +270,27 @@ be_snapshot(libbe_handle_t *lbh, const char *source, c
be_root_concat(lbh, source, buf);
- if (!be_exists(lbh, buf))
- return (BE_ERR_NOENT);
+ if ((err = be_exists(lbh, buf)) != 0)
+ return (set_error(lbh, err));
if (snap_name != NULL) {
- strcat(buf, "@");
- strcat(buf, snap_name);
+ if (strlcat(buf, "@", sizeof(buf)) >= sizeof(buf))
+ return (set_error(lbh, BE_ERR_INVALIDNAME));
+
+ if (strlcat(buf, snap_name, sizeof(buf)) >= sizeof(buf))
+ return (set_error(lbh, BE_ERR_INVALIDNAME));
+
if (result != NULL)
snprintf(result, BE_MAXPATHLEN, "%s@%s", source,
snap_name);
} else {
time(&rawtime);
len = strlen(buf);
- strftime(buf + len, BE_MAXPATHLEN - len,
+ strftime(buf + len, sizeof(buf) - len,
"@%F-%T", localtime(&rawtime));
- if (result != NULL)
- strcpy(result, strrchr(buf, '/') + 1);
+ if (result != NULL && strlcpy(result, strrchr(buf, '/') + 1,
+ sizeof(buf)) >= sizeof(buf))
+ return (set_error(lbh, BE_ERR_INVALIDNAME));
}
if ((err = zfs_snapshot(lbh->lzh, buf, recursive, NULL)) != 0) {
@@ -397,20 +403,16 @@ be_deep_clone(zfs_handle_t *ds, void *data)
ZFS_TYPE_FILESYSTEM) == ZPROP_INVAL)
return (-1);
- if ((err = zfs_clone(snap_hdl, be_path, props)) != 0) {
- switch (err) {
- case EZFS_SUCCESS:
- err = BE_ERR_SUCCESS;
- break;
- default:
- err = BE_ERR_ZFSCLONE;
- break;
- }
- }
+ if ((err = zfs_clone(snap_hdl, be_path, props)) != 0)
+ err = BE_ERR_ZFSCLONE;
nvlist_free(props);
zfs_close(snap_hdl);
+ /* Failed to clone */
+ if (err != BE_ERR_SUCCESS)
+ return (set_error(isdc->lbh, err));
+
sdc.lbh = isdc->lbh;
sdc.bename = NULL;
sdc.snapname = isdc->snapname;
@@ -451,14 +453,13 @@ be_create_from_existing_snap(libbe_handle_t *lbh, cons
else
bename++;
- if ((parentname = strdup(snap_path)) == NULL) {
- err = BE_ERR_UNKNOWN;
- return (set_error(lbh, err));
- }
+ if ((parentname = strdup(snap_path)) == NULL)
+ return (set_error(lbh, BE_ERR_UNKNOWN));
+
snapname = strchr(parentname, '@');
if (snapname == NULL) {
- err = BE_ERR_UNKNOWN;
- return (set_error(lbh, err));
+ free(parentname);
+ return (set_error(lbh, BE_ERR_UNKNOWN));
}
*snapname = '\0';
snapname++;
@@ -471,6 +472,7 @@ be_create_from_existing_snap(libbe_handle_t *lbh, cons
parent_hdl = zfs_open(lbh->lzh, parentname, ZFS_TYPE_DATASET);
err = be_deep_clone(parent_hdl, &sdc);
+ free(parentname);
return (set_error(lbh, err));
}
@@ -484,7 +486,7 @@ be_create_from_existing(libbe_handle_t *lbh, const cha
int err;
char buf[BE_MAXPATHLEN];
- if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)))
+ if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)) != 0)
return (set_error(lbh, err));
err = be_create_from_existing_snap(lbh, name, (char *)buf);
@@ -513,7 +515,7 @@ be_validate_snap(libbe_handle_t *lbh, const char *snap
ZFS_TYPE_SNAPSHOT))
return (BE_ERR_NOENT);
- strncpy(buf, snap_name, BE_MAXPATHLEN);
+ strlcpy(buf, snap_name, sizeof(buf));
/* Find the base filesystem of the snapshot */
if ((delim_pos = strchr(buf, '@')) == NULL)
@@ -524,12 +526,12 @@ be_validate_snap(libbe_handle_t *lbh, const char *snap
zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL)
return (BE_ERR_NOORIGIN);
- if ((err = zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, BE_MAXPATHLEN,
- NULL, NULL, 0, 1)) != 0)
- err = BE_ERR_INVORIGIN;
+ if ((err = zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf,
+ sizeof(buf), NULL, NULL, 0, 1)) != 0)
+ err = BE_ERR_BADMOUNT;
- if ((err != 0) && (strncmp(buf, "/", BE_MAXPATHLEN) != 0))
- err = BE_ERR_INVORIGIN;
+ if ((err != 0) && (strncmp(buf, "/", sizeof(buf)) != 0))
+ err = BE_ERR_BADMOUNT;
zfs_close(zfs_hdl);
@@ -561,7 +563,7 @@ be_root_concat(libbe_handle_t *lbh, const char *name,
if (name_len >= BE_MAXPATHLEN)
return (BE_ERR_PATHLEN);
- strncpy(result, name, BE_MAXPATHLEN);
+ strlcpy(result, name, BE_MAXPATHLEN);
return (BE_ERR_SUCCESS);
} else if (name_len + root_len + 1 < BE_MAXPATHLEN) {
snprintf(result, BE_MAXPATHLEN, "%s/%s", lbh->root,
@@ -575,11 +577,12 @@ be_root_concat(libbe_handle_t *lbh, const char *name,
/*
* Verifies the validity of a boot environment name (A-Za-z0-9-_.). Returns
- * BE_ERR_SUCCESS (0) if name is valid, otherwise returns BE_ERR_INVALIDNAME.
+ * BE_ERR_SUCCESS (0) if name is valid, otherwise returns BE_ERR_INVALIDNAME
+ * or BE_ERR_PATHLEN.
* Does not set internal library error state.
*/
int
-be_validate_name(libbe_handle_t *lbh __unused, const char *name)
+be_validate_name(libbe_handle_t *lbh, const char *name)
{
for (int i = 0; *name; i++) {
char c = *(name++);
@@ -588,6 +591,12 @@ be_validate_name(libbe_handle_t *lbh __unused, const c
return (BE_ERR_INVALIDNAME);
}
+ /*
+ * Impose the additional restriction that the entire dataset name must
+ * not exceed the maximum length of a dataset, i.e. MAXNAMELEN.
+ */
+ if (strlen(lbh->root) + 1 + strlen(name) > MAXNAMELEN)
+ return (BE_ERR_PATHLEN);
return (BE_ERR_SUCCESS);
}
@@ -603,18 +612,17 @@ be_rename(libbe_handle_t *lbh, const char *old, const
zfs_handle_t *zfs_hdl;
int err;
+ /*
+ * be_validate_name is documented not to set error state, so we should
+ * do so here.
+ */
+ if ((err = be_validate_name(lbh, new)) != 0)
+ return (set_error(lbh, err));
if ((err = be_root_concat(lbh, old, full_old)) != 0)
return (set_error(lbh, err));
if ((err = be_root_concat(lbh, new, full_new)) != 0)
return (set_error(lbh, err));
- if ((err = be_validate_name(lbh, new)) != 0)
- return (err);
-
- /* Check if old is active BE */
- if (strcmp(full_old, be_active_path(lbh)) == 0)
- return (set_error(lbh, BE_ERR_MOUNTED));
-
if (!zfs_dataset_exists(lbh->lzh, full_old, ZFS_TYPE_DATASET))
return (set_error(lbh, BE_ERR_NOENT));
@@ -625,20 +633,17 @@ be_rename(libbe_handle_t *lbh, const char *old, const
ZFS_TYPE_FILESYSTEM)) == NULL)
return (set_error(lbh, BE_ERR_ZFSOPEN));
- /* XXX TODO: Allow a force flag */
- if (zfs_is_mounted(zfs_hdl, NULL)) {
- zfs_close(zfs_hdl);
- return (set_error(lbh, BE_ERR_MOUNTED));
- }
-
/* recurse, nounmount, forceunmount */
- struct renameflags flags = { 0, 0, 0 };
+ struct renameflags flags = {
+ .nounmount = 1,
+ };
err = zfs_rename(zfs_hdl, NULL, full_new, flags);
zfs_close(zfs_hdl);
-
- return (set_error(lbh, err));
+ if (err != 0)
+ return (set_error(lbh, BE_ERR_UNKNOWN));
+ return (0);
}
@@ -693,8 +698,7 @@ be_import(libbe_handle_t *lbh, const char *bootenv, in
time(&rawtime);
len = strlen(buf);
- strftime(buf + len, BE_MAXPATHLEN - len,
- "@%F-%T", localtime(&rawtime));
+ strftime(buf + len, sizeof(buf) - len, "@%F-%T", localtime(&rawtime));
if ((err = lzc_receive(buf, NULL, NULL, false, fd)) != 0) {
switch (err) {
@@ -720,11 +724,28 @@ be_import(libbe_handle_t *lbh, const char *bootenv, in
err = zfs_clone(zfs, buf, props);
zfs_close(zfs);
-
nvlist_free(props);
- /* XXX TODO: Figure out how to destroy the ghost... */
- return (BE_ERR_SUCCESS);
+ if (err != 0)
+ return (set_error(lbh, BE_ERR_UNKNOWN));
+
+ /*
+ * Finally, we open up the dataset we just cloned the snapshot so that
+ * we may promote it. This is necessary in order to clean up the ghost
+ * snapshot that doesn't need to be seen after the operation is
+ * complete.
+ */
+ if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL)
+ return (set_error(lbh, BE_ERR_ZFSOPEN));
+
+ err = zfs_promote(zfs);
+ zfs_close(zfs);
+
+ if (err != 0)
+ return (set_error(lbh, BE_ERR_UNKNOWN));
+
+ /* Clean up the temporary snapshot */
+ return (be_destroy(lbh, nbuf, 0));
}
#if SOON
@@ -901,21 +922,38 @@ be_set_nextboot(libbe_handle_t *lbh, nvlist_t *config,
return (0);
}
+/*
+ * Deactivate old BE dataset; currently just sets canmount=noauto
+ */
+static int
+be_deactivate(libbe_handle_t *lbh, const char *ds)
+{
+ zfs_handle_t *zfs;
+ if ((zfs = zfs_open(lbh->lzh, ds, ZFS_TYPE_DATASET)) == NULL)
+ return (1);
+ if (zfs_prop_set(zfs, "canmount", "noauto") != 0)
+ return (1);
+ zfs_close(zfs);
+ return (0);
+}
+
int
be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
{
char be_path[BE_MAXPATHLEN];
char buf[BE_MAXPATHLEN];
+ nvlist_t *config, *dsprops, *vdevs;
+ char *origin;
uint64_t pool_guid;
- nvlist_t *config, *vdevs;
+ zfs_handle_t *zhp;
int err;
be_root_concat(lbh, bootenv, be_path);
/* Note: be_exists fails if mountpoint is not / */
- if (!be_exists(lbh, be_path))
- return (BE_ERR_NOENT);
+ if ((err = be_exists(lbh, be_path)) != 0)
+ return (set_error(lbh, err));
if (temporary) {
config = zpool_get_config(lbh->active_phandle, NULL);
@@ -929,9 +967,7 @@ be_activate(libbe_handle_t *lbh, const char *bootenv,
return (set_error(lbh, BE_ERR_UNKNOWN));
/* Expected format according to zfsbootcfg(8) man */
- strcpy(buf, "zfs:");
- strcat(buf, be_path);
- strcat(buf, ":");
+ snprintf(buf, sizeof(buf), "zfs:%s:", be_path);
/* We have no config tree */
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
@@ -940,16 +976,35 @@ be_activate(libbe_handle_t *lbh, const char *bootenv,
return (be_set_nextboot(lbh, vdevs, pool_guid, buf));
} else {
+ if (be_deactivate(lbh, lbh->bootfs) != 0)
+ return (-1);
+
/* Obtain bootenv zpool */
err = zpool_set_prop(lbh->active_phandle, "bootfs", be_path);
+ if (err)
+ return (-1);
- switch (err) {
- case 0:
- return (BE_ERR_SUCCESS);
+ zhp = zfs_open(lbh->lzh, be_path, ZFS_TYPE_FILESYSTEM);
+ if (zhp == NULL)
+ return (-1);
- default:
- /* XXX TODO correct errors */
+ if (be_prop_list_alloc(&dsprops) != 0)
return (-1);
+
+ if (be_get_dataset_props(lbh, be_path, dsprops) != 0) {
+ nvlist_free(dsprops);
+ return (-1);
}
+
+ if (nvlist_lookup_string(dsprops, "origin", &origin) == 0)
+ err = zfs_promote(zhp);
+ nvlist_free(dsprops);
+
+ zfs_close(zhp);
+
+ if (err)
+ return (-1);
}
+
+ return (BE_ERR_SUCCESS);
}
Modified: stable/11/lib/libbe/be.h
==============================================================================
--- head/lib/libbe/be.h Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/be.h Sun Jan 6 02:13:16 2019 (r342807)
@@ -49,7 +49,7 @@ typedef enum be_error {
BE_ERR_BADPATH, /* path not suitable for operation */
BE_ERR_PATHBUSY, /* requested path is busy */
BE_ERR_PATHLEN, /* provided name exceeds maximum length limit */
- BE_ERR_INVORIGIN, /* snapshot origin's mountpoint is not '/' */
+ BE_ERR_BADMOUNT, /* 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 */
@@ -118,7 +118,7 @@ void libbe_print_on_error(libbe_handle_t *, bool);
int be_root_concat(libbe_handle_t *, const char *, char *);
int be_validate_name(libbe_handle_t * __unused, const char *);
int be_validate_snap(libbe_handle_t *, const char *);
-bool be_exists(libbe_handle_t *, char *);
+int be_exists(libbe_handle_t *, char *);
int be_export(libbe_handle_t *, const char *, int fd);
int be_import(libbe_handle_t *, const char *, int fd);
Modified: stable/11/lib/libbe/be_access.c
==============================================================================
--- head/lib/libbe/be_access.c Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/be_access.c Sun Jan 6 02:13:16 2019 (r342807)
@@ -51,8 +51,10 @@ be_mountcheck_cb(zfs_handle_t *zfs_hdl, void *data)
return (0);
if (strcmp(mountpoint, info->path) == 0) {
info->name = strdup(zfs_get_name(zfs_hdl));
+ free(mountpoint);
return (1);
}
+ free(mountpoint);
return (0);
}
@@ -62,12 +64,12 @@ be_mountcheck_cb(zfs_handle_t *zfs_hdl, void *data)
int
be_mounted_at(libbe_handle_t *lbh, const char *path, nvlist_t *details)
{
- char be[BE_MAXPATHLEN + 1];
+ char be[BE_MAXPATHLEN];
zfs_handle_t *root_hdl;
struct be_mountcheck_info info;
prop_data_t propinfo;
- bzero(&be, BE_MAXPATHLEN + 1);
+ bzero(&be, BE_MAXPATHLEN);
if ((root_hdl = zfs_open(lbh->lzh, lbh->root,
ZFS_TYPE_FILESYSTEM)) == NULL)
return (BE_ERR_ZFSOPEN);
@@ -106,24 +108,23 @@ be_mount(libbe_handle_t *lbh, char *bootenv, char *mou
{
char be[BE_MAXPATHLEN];
char mnt_temp[BE_MAXPATHLEN];
- char *path;
int mntflags;
int err;
if ((err = be_root_concat(lbh, bootenv, be)) != 0)
return (set_error(lbh, err));
- if (!be_exists(lbh, bootenv))
- return (set_error(lbh, BE_ERR_NOENT));
+ if ((err = be_exists(lbh, bootenv)) != 0)
+ return (set_error(lbh, err));
- if (is_mounted(lbh->lzh, be, &path))
+ if (is_mounted(lbh->lzh, be, NULL))
return (set_error(lbh, BE_ERR_MOUNTED));
mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
/* Create mountpoint if it is not specified */
if (mountpoint == NULL) {
- strcpy(mnt_temp, "/tmp/be_mount.XXXX");
+ strlcpy(mnt_temp, "/tmp/be_mount.XXXX", sizeof(mnt_temp));
if (mkdtemp(mnt_temp) == NULL)
return (set_error(lbh, BE_ERR_IO));
}
@@ -148,7 +149,8 @@ be_mount(libbe_handle_t *lbh, char *bootenv, char *mou
}
if (result_loc != NULL)
- strcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint);
+ strlcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint,
+ BE_MAXPATHLEN);
return (BE_ERR_SUCCESS);
}
Modified: stable/11/lib/libbe/be_error.c
==============================================================================
--- head/lib/libbe/be_error.c Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/be_error.c Sun Jan 6 02:13:16 2019 (r342807)
@@ -75,8 +75,8 @@ libbe_error_description(libbe_handle_t *lbh)
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_BADMOUNT:
+ return ("mountpoint is not \"/\"");
case BE_ERR_NOORIGIN:
return ("could not open snapshot's origin");
Modified: stable/11/lib/libbe/be_info.c
==============================================================================
--- head/lib/libbe/be_info.c Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/be_info.c Sun Jan 6 02:13:16 2019 (r342807)
@@ -285,7 +285,7 @@ be_prop_list_free(nvlist_t *be_list)
/*
* Usage
*/
-bool
+int
be_exists(libbe_handle_t *lbh, char *be)
{
char buf[BE_MAXPATHLEN];
@@ -296,25 +296,23 @@ be_exists(libbe_handle_t *lbh, char *be)
be_root_concat(lbh, be, buf);
if (!zfs_dataset_exists(lbh->lzh, buf, ZFS_TYPE_DATASET))
- return (false);
+ return (BE_ERR_NOENT);
/* Also check if it's mounted at / */
- if (be_prop_list_alloc(&dsprops) != 0) {
- set_error(lbh, BE_ERR_UNKNOWN);
- return (false);
- }
+ if (be_prop_list_alloc(&dsprops) != 0)
+ return (BE_ERR_UNKNOWN);
if (be_get_dataset_props(lbh, buf, dsprops) != 0) {
nvlist_free(dsprops);
- return (false);
+ return (BE_ERR_UNKNOWN);
}
if (nvlist_lookup_string(dsprops, "mountpoint", &mntpoint) == 0) {
valid = (strcmp(mntpoint, "/") == 0);
nvlist_free(dsprops);
- return (valid);
+ return (valid ? BE_ERR_SUCCESS : BE_ERR_BADMOUNT);
}
nvlist_free(dsprops);
- return (false);
+ return (BE_ERR_BADMOUNT);
}
Modified: stable/11/lib/libbe/libbe.3
==============================================================================
--- head/lib/libbe/libbe.3 Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/lib/libbe/libbe.3 Sun Jan 6 02:13:16 2019 (r342807)
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 10, 2018
+.Dd August 31, 2018
.Dt LIBBE 3
.Os
.Sh NAME
@@ -111,7 +111,7 @@
.Ft int
.Fn be_validate_snap "libbe_handle_t *hdl" "const char *snap"
.Pp
-.Ft bool
+.Ft int
.Fn be_exists "libbe_handle_t *hdl" "char *be_name"
.Pp
.Ft int
@@ -222,7 +222,12 @@ snapshot.
.Pp
The
.Fn be_rename
-function renames a boot environment.
+function renames a boot environment without unmounting it, as if renamed with
+the
+.Fl u
+argument were passed to
+.Nm zfs
+.Cm rename
.Pp
The
.Fn be_activate
@@ -267,6 +272,9 @@ If
.Fa result
is not
.Dv NULL ,
+it should be large enough to accommodate
+.Dv BE_MAXPATHLEN
+including the null terminator.
the final mount point will be copied into it.
Setting the
.Dv BE_MNT_FORCE
@@ -328,7 +336,9 @@ environment name into
.Pp
The
.Fn be_validate_name
-function will validate the given boot environment name.
+function will validate the given boot environment name for both length
+restrictions as well as valid character restrictions.
+This function does not set the internal library error state.
.Pp
The
.Fn be_validate_snap
@@ -342,6 +352,8 @@ The
function will check whether the given boot environment exists and has a
mountpoint of
.Pa / .
+This function does not set the internal library error state, but will return
+the appropriate error.
.Pp
The
.Fn be_export
@@ -434,7 +446,7 @@ BE_ERR_DESTROYMNT,
BE_ERR_BADPATH,
BE_ERR_PATHBUSY,
BE_ERR_PATHLEN,
-BE_ERR_INVORIGIN,
+BE_ERR_BADMOUNT,
BE_ERR_NOORIGIN,
BE_ERR_MOUNTED,
BE_ERR_NOMOUNT,
@@ -455,9 +467,3 @@ were written as a 2017 Google Summer of Code project w
as a mentor.
Later work was done by
.An Kyle Evans Aq Mt kevans at FreeBSD.org .
-.Sh BUGS
-The
-.Fn be_import
-function does not destroy the temporary boot environment it creates for import,
-because the snapshot created to do the import may not be deleted since it is the
-origin of the new boot environment.
Modified: stable/11/sbin/Makefile
==============================================================================
--- stable/11/sbin/Makefile Sun Jan 6 02:12:55 2019 (r342806)
+++ stable/11/sbin/Makefile Sun Jan 6 02:13:16 2019 (r342807)
@@ -87,6 +87,7 @@ SUBDIR.${MK_PF}+= pfctl
SUBDIR.${MK_PF}+= pflogd
SUBDIR.${MK_QUOTAS}+= quotacheck
SUBDIR.${MK_ROUTED}+= routed
+SUBDIR.${MK_ZFS}+= bectl
SUBDIR.${MK_ZFS}+= zfsbootcfg
SUBDIR.${MK_TESTS}+= tests
Modified: stable/11/sbin/bectl/Makefile
==============================================================================
--- head/sbin/bectl/Makefile Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/sbin/bectl/Makefile Sun Jan 6 02:13:16 2019 (r342807)
@@ -13,7 +13,6 @@ LIBADD+= util
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
-CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
Modified: stable/11/sbin/bectl/bectl.8
==============================================================================
--- head/sbin/bectl/bectl.8 Sun Aug 12 00:00:13 2018 (r337664)
+++ stable/11/sbin/bectl/bectl.8 Sun Jan 6 02:13:16 2019 (r342807)
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 10, 2018
+.Dd August 24, 2018
.Dt BECTL 8
.Os
.Sh NAME
@@ -26,130 +26,137 @@
.Nd Utility to manage Boot Environments on ZFS
.Sh SYNOPSIS
.Nm
-activate
+.Cm activate
.Op Fl t
-.Ao Ar beName Ac
+.Ar beName
.Nm
-create
+.Cm create
.Op Fl r
-.Op Fl e Ar nonActiveBe | Fl e Ar beName at snapshot
-.Ao Ar beName Ac
+.Op Fl e Brq Ar nonActiveBe | beName at snapshot
+.Ar beName
.Nm
-create
+.Cm create
.Op Fl r
-.Ao Ar beName at snapshot Ac
+.Ar beName at snapshot
.Nm
-destroy
+.Cm destroy
.Op Fl F
-.Ao Ar beName | beName at snapshot Ac
+.Brq Ar beName | beName at snapshot
.Nm
-export
-.Ao Ar sourceBe Ac
+.Cm export
+.Ar sourceBe
.Nm
-import
-.Ao Ar targetBe Ac
+.Cm import
+.Ar targetBe
.Nm
-jail
-.Oo Fl o Ar key Ns = Ns Ar value | Fl u Ar key Oc Ns ...
-.Ao Ar jailID | jailName Ac
-.Ao Ar bootenv Ac
+.Cm jail
+.Brq Fl b | Fl U
+.Oo Bro Fl o Ar key Ns = Ns Ar value | Fl u Ar key Brc Oc Ns ...
+.Brq Ar jailID | jailName
+.Ar bootenv
+.Op Ar utility Op Ar argument ...
.Nm
-list
-.Op Fl a
-.Op Fl D
-.Op Fl H
-.Op Fl s
+.Cm list
+.Op Fl DHas
.Nm
-mount
-.Ao Ar beName Ac
+.Cm mount
+.Ar beName
.Op mountpoint
.Nm
-rename
-.Ao Ar origBeName Ac
-.Ao Ar newBeName Ac
+.Cm rename
+.Ar origBeName
+.Ar newBeName
.Nm
-{ ujail | unjail }
-.Ao Ar jailID | jailName Ac
-.Ao Ar bootenv Ac
+.Brq Cm ujail | unjail
+.Brq Ar jailID | jailName
+.Ar bootenv
.Nm
-{ umount | unmount }
+.Brq Cm umount | unmount
.Op Fl f
-.Ao Ar beName Ac
+.Ar beName
.Sh DESCRIPTION
The
.Nm
-command is used to setup and interact with ZFS boot environments, which are bootable clones of datasets.
+command is used to setup and interact with ZFS boot environments, which are
+bootable clones of datasets.
.Pp
.Em Boot Environments
-allows the system to be upgraded, while preserving the old system environment in a separate ZFS dataset.
+allows the system to be upgraded, while preserving the old system environment in
+a separate ZFS dataset.
.Sh COMMANDS
The following commands are supported by
.Nm :
.Bl -tag -width activate
-.It Ic activate
+.It Xo
+.Cm activate
.Op Fl t
-.Ar <beName>
-.Pp
+.Ar beName
+.Xc
Activate the given
.Ar beName
as the default boot filesystem.
If the
.Op Fl t
flag is given, this takes effect only for the next boot.
-.It Ic create
+.It Xo
+.Cm create
.Op Fl r
-.Op Fl e Ar nonActiveBe | Fl e Ar beName at snapshot
-.Ao Ar beName Ac
-.Pp
+.Op Fl e Brq Ar nonActiveBe | beName at snapshot
+.Ar beName
+.Xc
Creates a new boot environment named
.Ar beName .
-If the -e param is specified, the new environment will be cloned from the given
-.Ar nonActiveBe | Ar beName at snapshot .
If the
-.Op Fl r
+.Fl e
+argument is specified, the new environment will be cloned from the given
+.Brq Ar nonActiveBe | Ar beName at snapshot .
+If the
+.Fl r
flag is given, a recursive boot environment will be made.
-.It Ic create
+.It Xo
+.Cm create
.Op Fl r
-.Ao Ar beName at snapshot Ac
-.Pp
+.Ar beName at snapshot
+.Xc
Creates a snapshot of the existing boot environment named
.Ar beName .
If the
-.Op Fl r
+.Fl r
flag is given, a recursive boot environment will be made.
-.It Ic destroy
+.It Xo
+.Cm destroy
.Op Fl F
-.Ao Ar beName | beName at snapshot Ac
-.Pp
+.Brq Ar beName | beName at snapshot
+.Xc
Destroys the given
.Ar beName
boot environment or
.Ar beName at snapshot
-snapshot.
+snapshot without confirmation, unlike in
+.Nm beadm .
Specifying
.Fl F
will automatically unmount without confirmation.
-.It Ic export
-.Ao Ar sourceBe Ac
-.Pp
+.It Cm export Ar sourceBe
Export
.Ar sourceBe
to
.Dv stdout .
.Dv stdout
must be piped or redirected to a file.
-.It Ic import
-.Ao Ar targetBe Ac
-.Pp
+.It Cm import Ar targetBe
Import
.Ar targetBe
from
.Dv stdin .
-.It Ic jail
-.Oo Fl o Ar key Ns = Ns Ar value | Fl u Ar key Oc Ns ...
-.Ao Ar jailID | jailName Ac
+.It Xo
+.Cm jail
+.Brq Fl b | Fl U
+.Oo Bro Fl o Ar key Ns = Ns Ar value | Fl u Ar key Brc Oc Ns ...
+.Brq Ar jailID | jailName
.Ao Ar bootenv Ac
-.Pp
+.Op Ar utility Op Ar argument ...
+.Xc
Creates a jail of the given boot environment.
Multiple
.Fl o
@@ -161,7 +168,27 @@ will set a jail parameter, and
.Fl u
will unset a jail parameter.
.Pp
+By default, jails are created in interactive mode and
+.Pa /bin/sh
+is
+executed within the jail.
+If
+.Ar utility
+is specified, it will be executed instead of
+.Pa /bin/sh .
+The jail will be destroyed and the boot environment unmounted when the command
+finishes executing, unless the
+.Fl U
+argument is specified.
+.Pp
The
+.Fl b
+argument enables batch mode, thereby disabling interactive mode.
+The
+.Fl U
+argument will be ignored in batch mode.
+.Pp
+The
.Va name ,
.Va host.hostname ,
and
@@ -172,66 +199,59 @@ below, if they have been overwritten by
.Fl o .
.Pp
All
-.Ar key ,
-.Ar value
+.Ar key Ns = Ns Ar value
pairs are interpreted as jail parameters as described in
.Xr jail 8 .
The following default parameters are provided:
-.Bl -tag -width -indent
-.It Va allow.mount Ns = Ns Ar true
-.It Va allow.mount.devfs Ns = Ns Ar true
-.It Va enforce_statfs Ns = Ns Ar 1
-.It Va name Ns = Ns Ar bootenv
-.It Va host.hostname Ns = Ns Ar bootenv
-.It Va path
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list