svn commit: r308222 - vendor/illumos/dist/lib/libzfs_core/common

Andriy Gapon avg at FreeBSD.org
Wed Nov 2 17:32:33 UTC 2016


Author: avg
Date: Wed Nov  2 17:32:31 2016
New Revision: 308222
URL: https://svnweb.freebsd.org/changeset/base/308222

Log:
  6051 lzc_receive: allow the caller to read the begin record
  
  illumos/illumos-gate at 620f322510b2d6433f7f6af60fa52380c07756ad
  https://github.com/illumos/illumos-gate/commit/620f322510b2d6433f7f6af60fa52380c07756ad
  
  https://www.illumos.org/issues/6051
    Currently lzc_receive() requires that its snapname argument is a snapshot name
    (contains '').
    @zfs receive allows to specify just a dataset name and would try to deduce the
    snapshot name from the stream.
    I propose to allow lzc_receive() to do the same.
    That seems to be quite easy to implement, it requires only a small amount of
    logic, it does not require any additional system calls or any additional data
    from the stream.
    The benefit is that the new behavior would allow to keep the snapshot names the
    same between the sender and receiver at zero cost, without a need to pass the
    names out of band.
  
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Reviewed by: Paul Dagnelie <pcd at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author: Andriy Gapon <avg at icyb.net.ua>

Modified:
  vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c
  vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h

Modified: vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c
==============================================================================
--- vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c	Wed Nov  2 17:12:15 2016	(r308221)
+++ vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c	Wed Nov  2 17:32:31 2016	(r308222)
@@ -549,8 +549,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
@@ -595,9 +596,14 @@ lzc_receive_impl(const char *snapname, n
 		(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;
@@ -638,7 +644,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));
 }
 
 /*
@@ -651,7 +657,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));
 }
 
 /*

Modified: vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h
==============================================================================
--- vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h	Wed Nov  2 17:12:15 2016	(r308221)
+++ vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h	Wed Nov  2 17:32:31 2016	(r308222)
@@ -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 *);
 


More information about the svn-src-all mailing list