@@ -258,6 +258,7 @@ typedef struct send_data {
258258 boolean_t seento ;
259259 boolean_t holds ; /* were holds requested with send -h */
260260 boolean_t props ;
261+ boolean_t no_preserve_encryption ;
261262
262263 /*
263264 * The header nvlist is of the following format:
@@ -587,20 +588,32 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
587588 fnvlist_add_boolean (nvfs , "is_encroot" );
588589
589590 /*
590- * Encrypted datasets can only be sent with properties if
591- * the raw flag is specified because the receive side doesn't
592- * currently have a mechanism for recursively asking the user
593- * for new encryption parameters.
591+ * Encrypted datasets can only be sent with properties if the
592+ * raw flag or the no-preserve-encryption flag are specified
593+ * because the receive side doesn't currently have a mechanism
594+ * for recursively asking the user for new encryption
595+ * parameters.
596+ * We allow sending the dataset unencrypted only if the user
597+ * explicitly sets the no-preserve-encryption flag.
594598 */
595- if (!sd -> raw ) {
599+ if (!sd -> raw && ! sd -> no_preserve_encryption ) {
596600 (void ) fprintf (stderr , dgettext (TEXT_DOMAIN ,
597601 "cannot send %s@%s: encrypted dataset %s may not "
598- "be sent with properties without the raw flag\n" ),
602+ "be sent with properties without the raw flag or "
603+ "no-preserve-encryption flag\n" ),
599604 sd -> fsname , sd -> tosnap , zhp -> zfs_name );
600605 rv = -1 ;
601606 goto out ;
602607 }
603608
609+ /* If no-preserve-encryption flag is set, warn the user again */
610+ if (sd -> no_preserve_encryption ) {
611+ (void ) fprintf (stderr , dgettext (TEXT_DOMAIN ,
612+ "WARNING: no-preserve-encryption flag set, sending "
613+ "dataset %s without encryption\n" ),
614+ zhp -> zfs_name );
615+ }
616+
604617 }
605618
606619 /*
@@ -683,8 +696,8 @@ static int
683696gather_nvlist (libzfs_handle_t * hdl , const char * fsname , const char * fromsnap ,
684697 const char * tosnap , boolean_t recursive , boolean_t raw , boolean_t doall ,
685698 boolean_t replicate , boolean_t skipmissing , boolean_t verbose ,
686- boolean_t backup , boolean_t holds , boolean_t props , nvlist_t * * nvlp ,
687- avl_tree_t * * avlp )
699+ boolean_t backup , boolean_t holds , boolean_t props ,
700+ boolean_t no_preserve_encryption , nvlist_t * * nvlp , avl_tree_t * * avlp )
688701{
689702 zfs_handle_t * zhp ;
690703 send_data_t sd = { 0 };
@@ -707,6 +720,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
707720 sd .backup = backup ;
708721 sd .holds = holds ;
709722 sd .props = props ;
723+ sd .no_preserve_encryption = no_preserve_encryption ;
710724
711725 if ((error = send_iterate_fs (zhp , & sd )) != 0 ) {
712726 fnvlist_free (sd .fss );
@@ -2199,7 +2213,7 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
21992213 boolean_t gather_props , boolean_t recursive , boolean_t verbose ,
22002214 boolean_t dryrun , boolean_t raw , boolean_t replicate , boolean_t skipmissing ,
22012215 boolean_t backup , boolean_t holds , boolean_t props , boolean_t doall ,
2202- nvlist_t * * fssp , avl_tree_t * * fsavlp )
2216+ boolean_t no_preserve_encryption , nvlist_t * * fssp , avl_tree_t * * fsavlp )
22032217{
22042218 int err = 0 ;
22052219 char * packbuf = NULL ;
@@ -2245,7 +2259,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
22452259
22462260 if (gather_nvlist (zhp -> zfs_hdl , tofs ,
22472261 from , tosnap , recursive , raw , doall , replicate , skipmissing ,
2248- verbose , backup , holds , props , & fss , fsavlp ) != 0 ) {
2262+ verbose , backup , holds , props , no_preserve_encryption ,
2263+ & fss , fsavlp ) != 0 ) {
22492264 return (zfs_error (zhp -> zfs_hdl , EZFS_BADBACKUP ,
22502265 errbuf ));
22512266 }
@@ -2392,7 +2407,7 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
23922407 flags -> replicate , flags -> verbosity > 0 , flags -> dryrun ,
23932408 flags -> raw , flags -> replicate , flags -> skipmissing ,
23942409 flags -> backup , flags -> holds , flags -> props , flags -> doall ,
2395- & fss , & fsavl );
2410+ flags -> no_preserve_encryption , & fss , & fsavl );
23962411 zfs_close (tosnap );
23972412 if (err != 0 )
23982413 goto err_out ;
@@ -2735,7 +2750,8 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
27352750 err = send_prelim_records (zhp , NULL , fd , B_TRUE , B_FALSE ,
27362751 flags -> verbosity > 0 , flags -> dryrun , flags -> raw ,
27372752 flags -> replicate , B_FALSE , flags -> backup , flags -> holds ,
2738- flags -> props , flags -> doall , NULL , NULL );
2753+ flags -> props , flags -> doall , flags -> no_preserve_encryption ,
2754+ NULL , NULL );
27392755 if (err != 0 )
27402756 return (err );
27412757 }
@@ -3392,7 +3408,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
33923408 /* Using top_zfs, gather the nvlists for all local filesystems. */
33933409 if ((err = gather_nvlist (hdl , top_zfs , NULL , NULL ,
33943410 recursive , B_TRUE , B_FALSE , recursive , B_FALSE , B_FALSE , B_FALSE ,
3395- B_FALSE , B_TRUE , & local_nv , & local_avl )) != 0 )
3411+ B_FALSE , B_TRUE , B_FALSE , & local_nv , & local_avl )) != 0 )
33963412 return (err );
33973413
33983414 /*
@@ -3547,7 +3563,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
35473563
35483564 if ((error = gather_nvlist (hdl , tofs , fromsnap , NULL ,
35493565 recursive , B_TRUE , B_FALSE , recursive , B_FALSE , B_FALSE , B_FALSE ,
3550- B_FALSE , B_TRUE , & local_nv , & local_avl )) != 0 )
3566+ B_FALSE , B_TRUE , B_FALSE , & local_nv , & local_avl )) != 0 )
35513567 return (error );
35523568
35533569 /*
@@ -5138,7 +5154,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
51385154 * cp = '\0' ;
51395155 if (gather_nvlist (hdl , destsnap , NULL , NULL , B_FALSE , B_TRUE ,
51405156 B_FALSE , B_FALSE , B_FALSE , B_FALSE , B_FALSE , B_FALSE ,
5141- B_TRUE , & local_nv , & local_avl ) == 0 ) {
5157+ B_TRUE , B_FALSE , & local_nv , & local_avl ) == 0 ) {
51425158 * cp = '@' ;
51435159 fs = fsavl_find (local_avl , drrb -> drr_toguid , NULL );
51445160 fsavl_destroy (local_avl );
0 commit comments