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
This commit is contained in:
parent
20694769bd
commit
16ac070581
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=343335
@ -649,32 +649,14 @@ int
|
|||||||
be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
|
be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
|
||||||
{
|
{
|
||||||
char buf[BE_MAXPATHLEN];
|
char buf[BE_MAXPATHLEN];
|
||||||
time_t rawtime;
|
|
||||||
nvlist_t *props;
|
nvlist_t *props;
|
||||||
zfs_handle_t *zfs;
|
zfs_handle_t *zfs;
|
||||||
int err, len;
|
recvflags_t flags = { .nomount = 1 };
|
||||||
char nbuf[24];
|
int err;
|
||||||
|
|
||||||
/*
|
be_root_concat(lbh, bootenv, buf);
|
||||||
* 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));
|
|
||||||
|
|
||||||
time(&rawtime);
|
if ((err = zfs_receive(lbh->lzh, buf, NULL, &flags, fd, NULL)) != 0) {
|
||||||
len = strlen(buf);
|
|
||||||
strftime(buf + len, sizeof(buf) - len, "@%F-%T", localtime(&rawtime));
|
|
||||||
|
|
||||||
if ((err = lzc_receive(buf, NULL, NULL, false, fd)) != 0) {
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
return (set_error(lbh, BE_ERR_NOORIGIN));
|
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));
|
return (set_error(lbh, BE_ERR_ZFSOPEN));
|
||||||
|
|
||||||
nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
|
nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
|
||||||
nvlist_add_string(props, "canmount", "noauto");
|
nvlist_add_string(props, "canmount", "noauto");
|
||||||
nvlist_add_string(props, "mountpoint", "/");
|
nvlist_add_string(props, "mountpoint", "/");
|
||||||
|
|
||||||
be_root_concat(lbh, bootenv, buf);
|
err = zfs_prop_set_list(zfs, props);
|
||||||
|
|
||||||
err = zfs_clone(zfs, buf, props);
|
|
||||||
zfs_close(zfs);
|
|
||||||
nvlist_free(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);
|
zfs_close(zfs);
|
||||||
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return (set_error(lbh, BE_ERR_UNKNOWN));
|
return (set_error(lbh, BE_ERR_UNKNOWN));
|
||||||
|
|
||||||
/* Clean up the temporary snapshot */
|
return (0);
|
||||||
return (be_destroy(lbh, nbuf, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOON
|
#if SOON
|
||||||
|
Loading…
Reference in New Issue
Block a user