From owner-svn-src-all@freebsd.org Wed Nov 2 17:32:32 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DBC1DC2CBB0; Wed, 2 Nov 2016 17:32:32 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9624F1865; Wed, 2 Nov 2016 17:32:32 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uA2HWVEv016799; Wed, 2 Nov 2016 17:32:31 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uA2HWVKw016797; Wed, 2 Nov 2016 17:32:31 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201611021732.uA2HWVKw016797@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Wed, 2 Nov 2016 17:32:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r308222 - vendor/illumos/dist/lib/libzfs_core/common X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Nov 2016 17:32:33 -0000 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@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 Reviewed by: Paul Dagnelie Approved by: Robert Mustacchi Author: Andriy Gapon 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 *);