summaryrefslogtreecommitdiff
path: root/lib/libbe
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-01-23 02:09:15 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-01-23 02:09:15 +0000
commit16ac0705815ba661a3c1a693ff3a7562e932fb47 (patch)
tree79bad612cad9ef1463eb0b45c6ad0d0ca8f87744 /lib/libbe
parent20694769bd0ae33e298a6539640da702107fec15 (diff)
downloadsrc-test-16ac0705815ba661a3c1a693ff3a7562e932fb47.tar.gz
src-test-16ac0705815ba661a3c1a693ff3a7562e932fb47.zip
libbe(3): simplify import, allow replication streams
Previously, we directly used libzfs_core's lzc_receive to import to a temporary snapshot, then cloned the snapshot and setup the properties. This failed when attempting to import replication streams with questionable error. libzfs's zfs_receive is a much better fit here, so we now use it instead with the destination dataset and let libzfs take care of the dirty details. be_import is greatly simplified as a result. Reported by: Marie Helene Kvello-Aune <freebsd@mhka.no> MFC after: 1 week
Notes
Notes: svn path=/head/; revision=343335
Diffstat (limited to 'lib/libbe')
-rw-r--r--lib/libbe/be.c49
1 files changed, 7 insertions, 42 deletions
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index 8640af11a5dfb..b07e791805b60 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -649,32 +649,14 @@ int
be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
{
char buf[BE_MAXPATHLEN];
- time_t rawtime;
nvlist_t *props;
zfs_handle_t *zfs;
- int err, len;
- char nbuf[24];
-
- /*
- * We don't need this to be incredibly random, just unique enough that
- * it won't conflict with an existing dataset name. Chopping time
- * down to 32 bits is probably good enough for this.
- */
- snprintf(nbuf, 24, "tmp%u",
- (uint32_t)(time(NULL) & 0xFFFFFFFF));
- if ((err = be_root_concat(lbh, nbuf, buf)) != 0)
- /*
- * Technically this is our problem, but we try to use short
- * enough names that we won't run into problems except in
- * worst-case BE root approaching MAXPATHLEN.
- */
- return (set_error(lbh, BE_ERR_PATHLEN));
+ recvflags_t flags = { .nomount = 1 };
+ int err;
- time(&rawtime);
- len = strlen(buf);
- strftime(buf + len, sizeof(buf) - len, "@%F-%T", localtime(&rawtime));
+ be_root_concat(lbh, bootenv, buf);
- if ((err = lzc_receive(buf, NULL, NULL, false, fd)) != 0) {
+ if ((err = zfs_receive(lbh->lzh, buf, NULL, &flags, fd, NULL)) != 0) {
switch (err) {
case EINVAL:
return (set_error(lbh, BE_ERR_NOORIGIN));
@@ -687,39 +669,22 @@ be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
}
}
- if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT)) == NULL)
+ if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_FILESYSTEM)) == NULL)
return (set_error(lbh, BE_ERR_ZFSOPEN));
nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
nvlist_add_string(props, "canmount", "noauto");
nvlist_add_string(props, "mountpoint", "/");
- be_root_concat(lbh, bootenv, buf);
-
- err = zfs_clone(zfs, buf, props);
- zfs_close(zfs);
+ err = zfs_prop_set_list(zfs, props);
nvlist_free(props);
- 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));
+ return (0);
}
#if SOON