]> git.proxmox.com Git - mirror_zfs.git/commitdiff
OpenZFS 6051 - lzc_receive: allow the caller to read the begin record
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 16 Jun 2016 17:01:33 +0000 (10:01 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 28 Jun 2016 20:47:02 +0000 (13:47 -0700)
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
OpenZFS-issue: https://www.illumos.org/issues/6051
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/620f322

include/libzfs_core.h
lib/libzfs_core/libzfs_core.c

index 5d3a6fda7dcb9f96801d7f23647f410eb51f45bf..d2d79175f6a4dd010fcc635c83c609a0ba7e9859 100644 (file)
@@ -60,10 +60,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 *);
 
index 220792300b8cac1c22d4be62bb98e18aea352f98..ada46969d5ff66d94f659aefb06bf0671133e69a 100644 (file)
@@ -548,8 +548,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
@@ -594,9 +595,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;
@@ -637,7 +643,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));
 }
 
 /*
@@ -650,7 +656,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));
 }
 
 /*