aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLOLi <[email protected]>2017-08-31 18:00:35 +0200
committerBrian Behlendorf <[email protected]>2017-08-31 09:00:35 -0700
commitcf7684bc8d57ace26d086027e8059c725fd9ff92 (patch)
treebe5019f83891bdad022feb5b90cd7723a93547e1 /lib
parent1afc54f7f4f88902d0a3a3d88f6c7c6311c886ee (diff)
Retire send space estimation via ZFS_IOC_SEND
Add a small wrapper around libzfs_core`lzc_send_space() to libzfs so that every legacy ZFS_IOC_SEND consumer, along with their userland counterpart estimate_ioctl(), can leverage ZFS_IOC_SEND_SPACE to request send space estimation. The legacy functionality in zfs_ioc_send() is left untouched for compatibility purposes. Reviewed by: Thomas Caputi <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #6029
Diffstat (limited to 'lib')
-rw-r--r--lib/libzfs/libzfs_sendrecv.c55
-rw-r--r--lib/libzfs_core/libzfs_core.c2
2 files changed, 30 insertions, 27 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index 3146b4e61..fddcd9c02 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -1013,39 +1013,32 @@ typedef struct send_dump_data {
} send_dump_data_t;
static int
-estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
- boolean_t fromorigin, enum lzc_send_flags flags, uint64_t *sizep)
+zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from,
+ enum lzc_send_flags flags, uint64_t *spacep)
{
- zfs_cmd_t zc = {"\0"};
libzfs_handle_t *hdl = zhp->zfs_hdl;
+ int error;
- assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
- assert(fromsnap_obj == 0 || !fromorigin);
+ assert(snapname != NULL);
+ error = lzc_send_space(snapname, from, flags, spacep);
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- zc.zc_obj = fromorigin;
- zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
- zc.zc_fromobj = fromsnap_obj;
- zc.zc_guid = 1; /* estimate flag */
- zc.zc_flags = flags;
-
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
+ if (error != 0) {
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot estimate space for '%s'"), zhp->zfs_name);
+ "warning: cannot estimate space for '%s'"), snapname);
- switch (errno) {
+ switch (error) {
case EXDEV:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"not an earlier snapshot from the same fs"));
return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
case ENOENT:
- if (zfs_dataset_exists(hdl, zc.zc_name,
+ if (zfs_dataset_exists(hdl, snapname,
ZFS_TYPE_SNAPSHOT)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source (@%s) does not exist"),
- zc.zc_value);
+ "incremental source (%s) does not exist"),
+ snapname);
}
return (zfs_error(hdl, EZFS_NOENT, errbuf));
@@ -1060,16 +1053,15 @@ estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
case ERANGE:
case EFAULT:
case EROFS:
- zfs_error_aux(hdl, strerror(errno));
+ case EINVAL:
+ zfs_error_aux(hdl, strerror(error));
return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
default:
- return (zfs_standard_error(hdl, errno, errbuf));
+ return (zfs_standard_error(hdl, error, errbuf));
}
}
- *sizep = zc.zc_objset_type;
-
return (0);
}
@@ -1355,12 +1347,21 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
if (sdd->verbose) {
uint64_t size = 0;
- (void) estimate_ioctl(zhp, sdd->prevsnap_obj,
- fromorigin, flags, &size);
+ char fromds[ZFS_MAX_DATASET_NAME_LEN];
- send_print_verbose(fout, zhp->zfs_name,
- sdd->prevsnap[0] ? sdd->prevsnap : NULL,
- size, sdd->parsable);
+ if (sdd->prevsnap[0] != '\0') {
+ (void) strlcpy(fromds, zhp->zfs_name, sizeof (fromds));
+ *(strchr(fromds, '@') + 1) = '\0';
+ (void) strlcat(fromds, sdd->prevsnap, sizeof (fromds));
+ }
+ if (zfs_send_space(zhp, zhp->zfs_name,
+ sdd->prevsnap[0] ? fromds : NULL, flags, &size) != 0) {
+ size = 0; /* cannot estimate send space */
+ } else {
+ send_print_verbose(fout, zhp->zfs_name,
+ sdd->prevsnap[0] ? sdd->prevsnap : NULL,
+ size, sdd->parsable);
+ }
sdd->size += size;
}
diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c
index 8c3272da6..cc663f9dd 100644
--- a/lib/libzfs_core/libzfs_core.c
+++ b/lib/libzfs_core/libzfs_core.c
@@ -590,6 +590,8 @@ lzc_send_space(const char *snapname, const char *from,
fnvlist_add_boolean(args, "embedok");
if (flags & LZC_SEND_FLAG_COMPRESS)
fnvlist_add_boolean(args, "compressok");
+ if (flags & LZC_SEND_FLAG_RAW)
+ fnvlist_add_boolean(args, "rawok");
err = lzc_ioctl(ZFS_IOC_SEND_SPACE, snapname, args, &result);
nvlist_free(args);
if (err == 0)