Author: avg
Date: Wed Sep  4 07:33:22 2019
New Revision: 351803
URL: https://svnweb.freebsd.org/changeset/base/351803

Log:
  ZFS: Always refuse receving non-resume stream when resume state exists
  
  This fixes a hole in the situation where the resume state is left from
  receiving a new dataset and, so, the state is set on the dataset itself
  (as opposed to %recv child).
  
  Additionally, distinguish incremental and resume streams in error
  messages.
  
  This was also committed to ZoL:
  zfsonlinux/zfs@ebeb6f23bf7e8fe6732a05267ed1cab4c38d3b23
  
  MFC after:    2 weeks
  Sponsored by: CyberSecure

Modified:
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c   Wed Sep 
 4 04:44:03 2019        (r351802)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c   Wed Sep 
 4 07:33:22 2019        (r351803)
@@ -3278,11 +3278,18 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const 
                }
        } else {
                /*
-                * if the fs does not exist, look for it based on the
-                * fromsnap GUID
+                * If the fs does not exist, look for it based on the
+                * fromsnap GUID.
                 */
-               (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
-                   "cannot receive incremental stream"));
+               if (resuming) {
+                       (void) snprintf(errbuf, sizeof (errbuf),
+                           dgettext(TEXT_DOMAIN,
+                           "cannot receive resume stream"));
+               } else {
+                       (void) snprintf(errbuf, sizeof (errbuf),
+                           dgettext(TEXT_DOMAIN,
+                           "cannot receive incremental stream"));
+               }
 
                (void) strcpy(zc.zc_name, zc.zc_value);
                *strchr(zc.zc_name, '@') = '\0';

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c      Wed Sep 
 4 04:44:03 2019        (r351802)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c      Wed Sep 
 4 07:33:22 2019        (r351803)
@@ -1311,19 +1311,23 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *d
        int error;
        dsl_pool_t *dp = ds->ds_dir->dd_pool;
 
-       /* temporary clone name must not exist */
+       /* Temporary clone name must not exist. */
        error = zap_lookup(dp->dp_meta_objset,
            dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, recv_clone_name,
            8, 1, &val);
        if (error != ENOENT)
-               return (error == 0 ? EBUSY : error);
+               return (error == 0 ? SET_ERROR(EBUSY) : error);
 
-       /* new snapshot name must not exist */
+       /* Resume state must not be set. */
+       if (dsl_dataset_has_resume_receive_state(ds))
+               return (SET_ERROR(EBUSY));
+
+       /* New snapshot name must not exist. */
        error = zap_lookup(dp->dp_meta_objset,
            dsl_dataset_phys(ds)->ds_snapnames_zapobj,
            drba->drba_cookie->drc_tosnap, 8, 1, &val);
        if (error != ENOENT)
-               return (error == 0 ? EEXIST : error);
+               return (error == 0 ? SET_ERROR(EEXIST) : error);
 
        /*
         * Check snapshot limit before receiving. We'll recheck again at the
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to