From owner-svn-src-vendor@freebsd.org Tue Jan 26 13:20:33 2016 Return-Path: Delivered-To: svn-src-vendor@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 96606A464B2; Tue, 26 Jan 2016 13:20:33 +0000 (UTC) (envelope-from mav@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 56CF36D6; Tue, 26 Jan 2016 13:20:33 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0QDKWh5024663; Tue, 26 Jan 2016 13:20:32 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0QDKWqR024662; Tue, 26 Jan 2016 13:20:32 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201601261320.u0QDKWqR024662@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 26 Jan 2016 13:20:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r294816 - vendor-sys/illumos/dist/uts/common/fs/zfs vendor/illumos/dist/lib/libzfs/common X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Jan 2016 13:20:33 -0000 Author: mav Date: Tue Jan 26 13:20:31 2016 New Revision: 294816 URL: https://svnweb.freebsd.org/changeset/base/294816 Log: 4986 receiving replication stream fails if any snapshot exceeds refquota Reviewed by: John Kennedy Reviewed by: Matthew Ahrens Approved by: Gordon Ross Author: Dan McDonald illumos/illumos-gate@5878fad70d76d8711f6608c1f80b0447601261c6 Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c Changes in other areas also in this revision: Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c Tue Jan 26 13:14:39 2016 (r294815) +++ vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c Tue Jan 26 13:20:31 2016 (r294816) @@ -24,6 +24,7 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. */ #include @@ -58,7 +59,7 @@ extern void zfs_setprop_error(libzfs_han static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *, recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int, - uint64_t *); + uint64_t *, const char *); static int guid_to_name(libzfs_handle_t *, const char *, uint64_t, boolean_t, char *); @@ -2561,6 +2562,7 @@ zfs_receive_package(libzfs_handle_t *hdl nvlist_t *stream_nv = NULL; avl_tree_t *stream_avl = NULL; char *fromsnap = NULL; + char *sendsnap = NULL; char *cp; char tofs[ZFS_MAXNAMELEN]; char sendfs[ZFS_MAXNAMELEN]; @@ -2709,8 +2711,16 @@ zfs_receive_package(libzfs_handle_t *hdl */ (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname, ZFS_MAXNAMELEN); - if ((cp = strchr(sendfs, '@')) != NULL) + if ((cp = strchr(sendfs, '@')) != NULL) { *cp = '\0'; + /* + * Find the "sendsnap", the final snapshot in a replication + * stream. zfs_receive_one() handles certain errors + * differently, depending on if the contained stream is the + * last one or not. + */ + sendsnap = (cp + 1); + } /* Finally, receive each contained stream */ do { @@ -2723,7 +2733,7 @@ zfs_receive_package(libzfs_handle_t *hdl */ error = zfs_receive_impl(hdl, destname, NULL, flags, fd, sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd, - action_handlep); + action_handlep, sendsnap); if (error == ENODATA) { error = 0; break; @@ -2889,7 +2899,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr, dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, - uint64_t *action_handlep) + uint64_t *action_handlep, const char *finalsnap) { zfs_cmd_t zc = { 0 }; time_t begin_time; @@ -2906,6 +2916,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in nvlist_t *snapprops_nvlist = NULL; zprop_errflags_t prop_errflags; boolean_t recursive; + char *snapname = NULL; begin_time = time(NULL); @@ -2916,7 +2927,6 @@ zfs_receive_one(libzfs_handle_t *hdl, in ENOENT); if (stream_avl != NULL) { - char *snapname; nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid, &snapname); nvlist_t *props; @@ -3263,7 +3273,21 @@ zfs_receive_one(libzfs_handle_t *hdl, in ZPROP_N_MORE_ERRORS) == 0) { trunc_prop_errs(intval); break; - } else { + } else if (snapname == NULL || finalsnap == NULL || + strcmp(finalsnap, snapname) == 0 || + strcmp(nvpair_name(prop_err), + zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) { + /* + * Skip the special case of, for example, + * "refquota", errors on intermediate + * snapshots leading up to a final one. + * That's why we have all of the checks above. + * + * See zfs_ioctl.c's extract_delay_props() for + * a list of props which can fail on + * intermediate snapshots, but shouldn't + * affect the overall receive. + */ (void) snprintf(tbuf, sizeof (tbuf), dgettext(TEXT_DOMAIN, "cannot receive %s property on %s"), @@ -3448,7 +3472,7 @@ static int zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, const char *originsnap, recvflags_t *flags, int infd, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, - uint64_t *action_handlep) + uint64_t *action_handlep, const char *finalsnap) { int err; dmu_replay_record_t drr, drr_noswap; @@ -3544,10 +3568,11 @@ zfs_receive_impl(libzfs_handle_t *hdl, c if ((cp = strchr(nonpackage_sendfs, '@')) != NULL) *cp = '\0'; sendfs = nonpackage_sendfs; + VERIFY(finalsnap == NULL); } return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags, &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs, - cleanup_fd, action_handlep)); + cleanup_fd, action_handlep, finalsnap)); } else { assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_COMPOUNDSTREAM); @@ -3582,7 +3607,7 @@ zfs_receive(libzfs_handle_t *hdl, const VERIFY(cleanup_fd >= 0); err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL, - stream_avl, &top_zfs, cleanup_fd, &action_handle); + stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL); VERIFY(0 == close(cleanup_fd));