summaryrefslogtreecommitdiffstats
path: root/cddl/contrib/opensolaris
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2016-11-17 15:19:27 +0000
committeravg <avg@FreeBSD.org>2016-11-17 15:19:27 +0000
commit6d62938c33e63fb7ec6e36199c10bd573599eb97 (patch)
tree9d307ecd7c2c57f6f1ecfeb274c5abd3e5dfee3d /cddl/contrib/opensolaris
parent43c0e7af561eeda2e12f5b3ecf2139c20b17f676 (diff)
downloadFreeBSD-src-6d62938c33e63fb7ec6e36199c10bd573599eb97.zip
FreeBSD-src-6d62938c33e63fb7ec6e36199c10bd573599eb97.tar.gz
MFC r308247: MFV r308222: 6051 lzc_receive: allow the caller to read the
begin record
Diffstat (limited to 'cddl/contrib/opensolaris')
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c42
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h7
2 files changed, 41 insertions, 8 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
index c1ada8d..ee3158b 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -596,8 +596,9 @@ recv_read(int fd, void *buf, int ilen)
}
static int
-lzc_receive_impl(const char *snapname, nvlist_t *props, const char *origin,
- boolean_t force, boolean_t resumable, int fd)
+recv_impl(const char *snapname, nvlist_t *props, const char *origin,
+ boolean_t force, boolean_t resumable, int fd,
+ const dmu_replay_record_t *begin_record)
{
/*
* The receive ioctl is still legacy, so we need to construct our own
@@ -642,9 +643,14 @@ lzc_receive_impl(const char *snapname, nvlist_t *props, const char *origin,
(void) strlcpy(zc.zc_string, origin, sizeof (zc.zc_string));
/* zc_begin_record is non-byteswapped BEGIN record */
- error = recv_read(fd, &zc.zc_begin_record, sizeof (zc.zc_begin_record));
- if (error != 0)
- goto out;
+ if (begin_record == NULL) {
+ error = recv_read(fd, &zc.zc_begin_record,
+ sizeof (zc.zc_begin_record));
+ if (error != 0)
+ goto out;
+ } else {
+ zc.zc_begin_record = *begin_record;
+ }
/* zc_cookie is fd to read from */
zc.zc_cookie = fd;
@@ -685,7 +691,7 @@ int
lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, int fd)
{
- return (lzc_receive_impl(snapname, props, origin, force, B_FALSE, fd));
+ return (recv_impl(snapname, props, origin, force, B_FALSE, fd, NULL));
}
/*
@@ -698,7 +704,29 @@ int
lzc_receive_resumable(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, int fd)
{
- return (lzc_receive_impl(snapname, props, origin, force, B_TRUE, fd));
+ return (recv_impl(snapname, props, origin, force, B_TRUE, fd, NULL));
+}
+
+/*
+ * Like lzc_receive, but allows the caller to read the begin record and then to
+ * pass it in. That could be useful if the caller wants to derive, for example,
+ * the snapname or the origin parameters based on the information contained in
+ * the begin record.
+ * The begin record must be in its original form as read from the stream,
+ * in other words, it should not be byteswapped.
+ *
+ * The 'resumable' parameter allows to obtain the same behavior as with
+ * lzc_receive_resumable.
+ */
+int
+lzc_receive_with_header(const char *snapname, nvlist_t *props,
+ const char *origin, boolean_t force, boolean_t resumable, int fd,
+ const dmu_replay_record_t *begin_record)
+{
+ if (begin_record == NULL)
+ return (EINVAL);
+ return (recv_impl(snapname, props, origin, force, resumable, fd,
+ begin_record));
}
/*
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
index d922ab5..8ff00cc 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
@@ -68,10 +68,15 @@ enum lzc_send_flags {
int lzc_send(const char *, const char *, int, enum lzc_send_flags);
int lzc_send_resume(const char *, const char *, int,
enum lzc_send_flags, uint64_t, uint64_t);
+int lzc_send_space(const char *, const char *, uint64_t *);
+
+struct dmu_replay_record;
+
int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int);
int lzc_receive_resumable(const char *, nvlist_t *, const char *,
boolean_t, int);
-int lzc_send_space(const char *, const char *, uint64_t *);
+int lzc_receive_with_header(const char *, nvlist_t *, const char *, boolean_t,
+ boolean_t, int, const struct dmu_replay_record *);
boolean_t lzc_exists(const char *);
OpenPOWER on IntegriCloud