From owner-svn-src-head@freebsd.org Thu Feb 22 04:01:56 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 04F71F254AF; Thu, 22 Feb 2018 04:01:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id AEBD968734; Thu, 22 Feb 2018 04:01:55 +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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A94E922388; Thu, 22 Feb 2018 04:01:55 +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 w1M41tfn018643; Thu, 22 Feb 2018 04:01:55 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1M41tp8018641; Thu, 22 Feb 2018 04:01:55 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201802220401.w1M41tp8018641@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Thu, 22 Feb 2018 04:01:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329808 - head/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Group: head X-SVN-Commit-Author: mav X-SVN-Commit-Paths: head/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Commit-Revision: 329808 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Feb 2018 04:01:56 -0000 Author: mav Date: Thu Feb 22 04:01:55 2018 New Revision: 329808 URL: https://svnweb.freebsd.org/changeset/base/329808 Log: MFV r329807: 8940 Sending an intra-pool resumable send stream may result in EXDEV illumos/illumos-gate@544132fce3fa6583f01318f9559adc46614343a7 "zfs send -t " for an incremental send should be able to resume successfully when sending to the same pool: a subtle issue in zfs_iter_children() doesn't currently allow this. Because resuming from a token requires "guid" -> "dataset" mapping (guid_to_name()), we have to walk the whole hierarchy to find the right snapshots to send. When resuming an incremental send both source and destination live in the same pool and have the same guid: this is where zfs_iter_children() gets confused and picks up the wrong snapshot, so we end up trying to send an incremental "destination@snap1 -> source@snap2" stream instead of "source@snap1 -> source@snap2": this fails with an "Invalid cross-device link" (EXDEV) error. Reviewed by: Paul Dagnelie Reviewed by: Matthew Ahrens Approved by: Hans Rosenfeld Author: loli10K Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Directory Properties: head/cddl/contrib/opensolaris/ (props changed) head/cddl/contrib/opensolaris/lib/libzfs/ (props changed) Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Thu Feb 22 04:01:05 2018 (r329807) +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Thu Feb 22 04:01:55 2018 (r329808) @@ -424,16 +424,20 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *sp /* * Iterate over all children, snapshots and filesystems + * Process snapshots before filesystems because they are nearer the input + * handle: this is extremely important when used with zfs_iter_f functions + * looking for data, following the logic that we would like to find it as soon + * and as close as possible. */ int zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data) { int ret; - if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0) + if ((ret = zfs_iter_snapshots(zhp, B_FALSE, func, data)) != 0) return (ret); - return (zfs_iter_snapshots(zhp, B_FALSE, func, data)); + return (zfs_iter_filesystems(zhp, func, data)); } Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Thu Feb 22 04:01:05 2018 (r329807) +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Thu Feb 22 04:01:55 2018 (r329808) @@ -1585,6 +1585,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla int error = 0; char name[ZFS_MAX_DATASET_NAME_LEN]; enum lzc_send_flags lzc_flags = 0; + FILE *fout = (flags->verbose && flags->dryrun) ? stdout : stderr; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot resume send")); @@ -1599,9 +1600,9 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla return (zfs_error(hdl, EZFS_FAULT, errbuf)); } if (flags->verbose) { - (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + (void) fprintf(fout, dgettext(TEXT_DOMAIN, "resume token contents:\n")); - nvlist_print(stderr, resume_nvl); + nvlist_print(fout, resume_nvl); } if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 || @@ -1658,7 +1659,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla lzc_flags, &size); if (error == 0) size = MAX(0, (int64_t)(size - bytes)); - send_print_verbose(stderr, zhp->zfs_name, fromname, + send_print_verbose(fout, zhp->zfs_name, fromname, size, flags->parsable); }