summaryrefslogtreecommitdiff
path: root/usr/src/test
diff options
context:
space:
mode:
authorTom Caputi <tcaputi@datto.com>2019-06-25 19:39:35 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-06-25 19:40:06 +0000
commiteb633035c80613ec93d62f90482837adaaf21a0a (patch)
tree67f2e3e15231d06a3525ce3958bbce24aa3de7e8 /usr/src/test
parent07eb1aef88b873c5c1036d9cf69820c1ef6a32fb (diff)
downloadillumos-joyent-eb633035c80613ec93d62f90482837adaaf21a0a.tar.gz
8727 Native data and metadata encryption for zfs
Portions contributed by: Jorgen Lundman <lundman@lundman.net> Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com> Portions contributed by: Paul Zuchowski <pzuchowski@datto.com> Portions contributed by: Tim Chase <tim@chase2k.com> Portions contributed by: Matthew Ahrens <mahrens@delphix.com> Portions contributed by: ab-oe <arkadiusz.bubala@open-e.com> Portions contributed by: Brian Behlendorf <behlendorf1@llnl.gov> Portions contributed by: loli10K <ezomori.nozomu@gmail.com> Portions contributed by: Igor K <igor@dilos.org> Portions contributed by: Richard Laager <rlaager@wiktel.com> Reviewed by: Jason Cohen <jwittlincohen@gmail.com> Reviewed by: Allan Jude <allanjude@freebsd.org> Reviewed by: George Melikov <mail@gmelikov.ru> Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: RageLtMan <rageltman@sempervictus> Reviewed by: Matthew Thode <prometheanfire@gentoo.org> Reviewed by: Giuseppe Di Natale <dinatale2@llnl.gov> Reviewed by: Kash Pande <kash@tripleback.net> Reviewed by: Alek Pinchuk <apinchuk@datto.com> Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: David Quigley <david.quigley@intel.com> Reviewed by: Jorgen Lundman <lundman@lundman.net> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: C Fraire <cfraire@me.com> Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: Andy Stormont <astormont@racktopsystems.com> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/test')
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run47
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run44
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run44
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile21
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh30
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh32
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh62
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh86
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh72
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh78
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh58
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh65
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh75
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh83
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh99
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh134
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_003_pos.ksh4
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile21
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh30
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh32
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg26
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh85
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh77
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib102
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh58
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh73
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh54
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh66
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh69
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh80
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh1
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh83
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh93
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh95
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh75
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh78
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh51
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh76
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh59
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh79
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh1
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh93
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile21
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh30
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh32
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh69
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh76
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh72
-rw-r--r--[-rwxr-xr-x]usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_005_pos.ksh0
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh90
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh95
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/blockfiles/missing_ivset.dat.bz2bin0 -> 167066 bytes
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2bin0 -> 94716 bytes
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh59
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh59
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh99
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata4.ksh143
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh71
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib104
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh130
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy.ksh96
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_truncated_files.ksh118
-rw-r--r--[-rwxr-xr-x]usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh0
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/rsend/send_mixed_raw.ksh118
-rw-r--r--[-rwxr-xr-x]usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh0
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_encrypted_files.ksh112
67 files changed, 4150 insertions, 37 deletions
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index 738fe89309..fb5c8e7bbe 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -113,11 +113,16 @@ post =
[/opt/zfs-tests/tests/functional/cli_root/zfs]
tests = ['zfs_001_neg', 'zfs_002_pos', 'zfs_003_neg']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_change-key]
+tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
+ 'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
+ 'zfs_change-key_pbkdf2iters']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_clone]
tests = ['zfs_clone_001_neg', 'zfs_clone_002_pos', 'zfs_clone_003_pos',
'zfs_clone_004_pos', 'zfs_clone_005_pos', 'zfs_clone_006_pos',
'zfs_clone_007_pos', 'zfs_clone_008_neg', 'zfs_clone_009_neg',
- 'zfs_clone_010_pos']
+ 'zfs_clone_010_pos', 'zfs_clone_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_copies]
tests = ['zfs_copies_001_pos', 'zfs_copies_002_pos', 'zfs_copies_003_pos',
@@ -128,7 +133,8 @@ tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos',
'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos',
'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg',
'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos',
- 'zfs_create_013_pos']
+ 'zfs_create_013_pos', 'zfs_create_encrypted',
+ 'zfs_create_crypt_combos']
[/opt/zfs-tests/tests/functional/cli_root/zfs_destroy]
tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos',
@@ -146,12 +152,17 @@ tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_inherit]
tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg', 'zfs_inherit_003_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_load-key]
+tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file',
+ 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_mount]
tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos',
'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_006_pos',
'zfs_mount_007_pos', 'zfs_mount_008_pos', 'zfs_mount_009_neg',
'zfs_mount_010_neg', 'zfs_mount_011_neg', 'zfs_mount_012_neg',
- 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints']
+ 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints',
+ 'zfs_mount_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_program]
tests = ['zfs_program_json']
@@ -159,7 +170,7 @@ tests = ['zfs_program_json']
[/opt/zfs-tests/tests/functional/cli_root/zfs_promote]
tests = ['zfs_promote_001_pos', 'zfs_promote_002_pos', 'zfs_promote_003_pos',
'zfs_promote_004_pos', 'zfs_promote_005_pos', 'zfs_promote_006_neg',
- 'zfs_promote_007_neg', 'zfs_promote_008_pos']
+ 'zfs_promote_007_neg', 'zfs_promote_008_pos', 'zfs_promote_encryptionroot']
[/opt/zfs-tests/tests/functional/cli_root/zfs_property]
tests = ['zfs_written_property_001_pos']
@@ -169,7 +180,9 @@ tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos',
'zfs_receive_005_neg', 'zfs_receive_006_pos',
'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg',
'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos',
- 'zfs_receive_013_pos', 'zfs_receive_014_pos']
+ 'zfs_receive_013_pos', 'zfs_receive_014_pos',
+ 'zfs_receive_from_encrypted', 'zfs_receive_raw',
+ 'zfs_receive_raw_incremental', 'zfs_receive_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_remap]
tests = ['zfs_remap_cliargs', 'zfs_remap_obsolete_counts']
@@ -179,7 +192,8 @@ tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos',
'zfs_rename_004_neg', 'zfs_rename_005_neg', 'zfs_rename_006_pos',
'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_009_neg',
'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg',
- 'zfs_rename_013_pos', 'zfs_rename_014_neg']
+ 'zfs_rename_013_pos', 'zfs_rename_014_neg', 'zfs_rename_encrypted_child',
+ 'zfs_rename_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_reservation]
tests = ['zfs_reservation_001_pos', 'zfs_reservation_002_pos']
@@ -191,7 +205,7 @@ tests = ['zfs_rollback_001_pos', 'zfs_rollback_002_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_send]
tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos',
'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos',
- 'zfs_send_007_pos']
+ 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw']
[/opt/zfs-tests/tests/functional/cli_root/zfs_set]
tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
@@ -202,7 +216,7 @@ tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
'ro_props_001_pos', 'share_mount_001_neg', 'snapdir_001_pos',
'user_property_001_pos', 'user_property_002_pos', 'user_property_003_neg',
'user_property_004_pos', 'version_001_neg', 'zfs_set_001_neg',
- 'zfs_set_002_neg', 'zfs_set_003_neg']
+ 'zfs_set_002_neg', 'zfs_set_003_neg', 'zfs_set_keylocation']
[/opt/zfs-tests/tests/functional/cli_root/zfs_share]
tests = ['zfs_share_001_pos', 'zfs_share_002_pos', 'zfs_share_003_pos',
@@ -216,6 +230,9 @@ tests = ['zfs_snapshot_001_neg', 'zfs_snapshot_002_neg',
'zfs_snapshot_006_pos', 'zfs_snapshot_007_neg', 'zfs_snapshot_008_neg',
'zfs_snapshot_009_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_unload-key]
+tests = ['zfs_unload-key', 'zfs_unload-key_all', 'zfs_unload-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_unmount]
tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos',
'zfs_unmount_004_pos', 'zfs_unmount_005_pos', 'zfs_unmount_006_pos',
@@ -258,6 +275,7 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_024_pos',
+ 'zpool_create_encrypted', 'zpool_create_crypt_combos',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
'zpool_create_tempname']
@@ -306,7 +324,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'import_rewind_device_replaced',
'import_cachefile_shared_device',
'import_paths_changed',
- 'import_devices_missing']
+ 'import_devices_missing',
+ 'zpool_import_encrypted', 'zpool_import_encrypted_load']
[/opt/zfs-tests/tests/functional/cli_root/zpool_labelclear]
tests = ['zpool_labelclear_active', 'zpool_labelclear_exported']
@@ -346,7 +365,8 @@ tags = ['functional', 'cli_root', 'zpool_resilver']
[/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
- 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
+ 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies',
+ 'zpool_scrub_encrypted_unloaded']
[/opt/zfs-tests/tests/functional/cli_root/zpool_set]
tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
@@ -408,7 +428,7 @@ tests = ['ctime_001_pos' ]
tests = ['zfs_allow_001_pos', 'zfs_allow_002_pos',
'zfs_allow_004_pos', 'zfs_allow_005_pos', 'zfs_allow_006_pos',
'zfs_allow_007_pos', 'zfs_allow_008_pos', 'zfs_allow_009_neg',
- 'zfs_allow_010_pos', 'zfs_allow_011_neg', 'zfs_allow_012_neg',
+ 'zfs_allow_011_neg', 'zfs_allow_012_neg',
'zfs_unallow_001_pos', 'zfs_unallow_002_pos', 'zfs_unallow_003_pos',
'zfs_unallow_004_pos', 'zfs_unallow_005_pos', 'zfs_unallow_006_pos',
'zfs_unallow_007_neg', 'zfs_unallow_008_neg']
@@ -583,7 +603,10 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
'send-c_mixed_compression', 'send-c_stream_size_estimate', 'send-cD',
'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
- 'send-c_recv_dedup']
+ 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
+ 'send_encrypted_truncated_files',
+ 'send_realloc_encrypted_files',
+ 'send_mixed_raw']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index 926f65cb20..5d3571307e 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -114,11 +114,16 @@ post =
[/opt/zfs-tests/tests/functional/cli_root/zfs]
tests = ['zfs_001_neg', 'zfs_002_pos', 'zfs_003_neg']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_change-key]
+tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
+ 'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
+ 'zfs_change-key_pbkdf2iters']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_clone]
tests = ['zfs_clone_001_neg', 'zfs_clone_002_pos', 'zfs_clone_003_pos',
'zfs_clone_004_pos', 'zfs_clone_005_pos', 'zfs_clone_006_pos',
'zfs_clone_007_pos', 'zfs_clone_008_neg', 'zfs_clone_009_neg',
- 'zfs_clone_010_pos']
+ 'zfs_clone_010_pos', 'zfs_clone_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_copies]
tests = ['zfs_copies_001_pos', 'zfs_copies_002_pos', 'zfs_copies_003_pos',
@@ -129,7 +134,7 @@ tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos',
'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos',
'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg',
'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos',
- 'zfs_create_013_pos']
+ 'zfs_create_013_pos', 'zfs_create_encrypted', 'zfs_create_crypt_combos']
[/opt/zfs-tests/tests/functional/cli_root/zfs_destroy]
tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos',
@@ -147,12 +152,17 @@ tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_inherit]
tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg', 'zfs_inherit_003_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_load-key]
+tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file',
+ 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_mount]
tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos',
'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_006_pos',
'zfs_mount_007_pos', 'zfs_mount_008_pos', 'zfs_mount_009_neg',
'zfs_mount_010_neg', 'zfs_mount_011_neg', 'zfs_mount_012_neg',
- 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints']
+ 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints'
+ 'zfs_mount_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_program]
tests = ['zfs_program_json']
@@ -160,7 +170,7 @@ tests = ['zfs_program_json']
[/opt/zfs-tests/tests/functional/cli_root/zfs_promote]
tests = ['zfs_promote_001_pos', 'zfs_promote_002_pos', 'zfs_promote_003_pos',
'zfs_promote_004_pos', 'zfs_promote_005_pos', 'zfs_promote_006_neg',
- 'zfs_promote_007_neg', 'zfs_promote_008_pos']
+ 'zfs_promote_007_neg', 'zfs_promote_008_pos', 'zfs_promote_encryptionroot']
[/opt/zfs-tests/tests/functional/cli_root/zfs_property]
tests = ['zfs_written_property_001_pos']
@@ -170,7 +180,9 @@ tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos',
'zfs_receive_005_neg', 'zfs_receive_006_pos',
'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg',
'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos',
- 'zfs_receive_013_pos', 'zfs_receive_014_pos']
+ 'zfs_receive_013_pos', 'zfs_receive_014_pos',
+ 'zfs_receive_from_encrypted', 'zfs_receive_raw',
+ 'zfs_receive_raw_incremental', 'zfs_receive_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_remap]
tests = ['zfs_remap_cliargs', 'zfs_remap_obsolete_counts']
@@ -180,7 +192,8 @@ tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos',
'zfs_rename_004_neg', 'zfs_rename_005_neg', 'zfs_rename_006_pos',
'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_009_neg',
'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg',
- 'zfs_rename_013_pos', 'zfs_rename_014_neg']
+ 'zfs_rename_013_pos', 'zfs_rename_014_neg', 'zfs_rename_encrypted_child',
+ 'zfs_rename_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_reservation]
tests = ['zfs_reservation_001_pos', 'zfs_reservation_002_pos']
@@ -192,7 +205,7 @@ tests = ['zfs_rollback_001_pos', 'zfs_rollback_002_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_send]
tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos',
'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos',
- 'zfs_send_007_pos']
+ 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw']
[/opt/zfs-tests/tests/functional/cli_root/zfs_set]
tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
@@ -203,7 +216,7 @@ tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
'ro_props_001_pos', 'share_mount_001_neg', 'snapdir_001_pos',
'user_property_001_pos', 'user_property_002_pos', 'user_property_003_neg',
'user_property_004_pos', 'version_001_neg', 'zfs_set_001_neg',
- 'zfs_set_002_neg', 'zfs_set_003_neg']
+ 'zfs_set_002_neg', 'zfs_set_003_neg', 'zfs_set_keylocation']
[/opt/zfs-tests/tests/functional/cli_root/zfs_share]
tests = ['zfs_share_001_pos', 'zfs_share_002_pos', 'zfs_share_003_pos',
@@ -217,6 +230,9 @@ tests = ['zfs_snapshot_001_neg', 'zfs_snapshot_002_neg',
'zfs_snapshot_006_pos', 'zfs_snapshot_007_neg', 'zfs_snapshot_008_neg',
'zfs_snapshot_009_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_unload-key]
+tests = ['zfs_unload-key', 'zfs_unload-key_all', 'zfs_unload-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_unmount]
tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos',
'zfs_unmount_004_pos', 'zfs_unmount_005_pos', 'zfs_unmount_006_pos',
@@ -259,6 +275,7 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_024_pos',
+ 'zpool_create_encrypted', 'zpool_create_crypt_combos',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
'zpool_create_tempname']
@@ -306,7 +323,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'import_rewind_config_changed',
'import_cachefile_shared_device',
'import_paths_changed',
- 'import_devices_missing']
+ 'import_devices_missing',
+ 'zpool_import_encrypted', 'zpool_import_encrypted_load']
[/opt/zfs-tests/tests/functional/cli_root/zpool_labelclear]
tests = ['zpool_labelclear_active', 'zpool_labelclear_exported']
@@ -347,7 +365,8 @@ tags = ['functional', 'cli_root', 'zpool_resilver']
[/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
- 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
+ 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies',
+ 'zpool_scrub_encrypted_unloaded']
[/opt/zfs-tests/tests/functional/cli_root/zpool_set]
tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
@@ -583,7 +602,10 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
'send-c_mixed_compression', 'send-c_stream_size_estimate', 'send-cD',
'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
- 'send-c_recv_dedup']
+ 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
+ 'send_encrypted_truncated_files',
+ 'send_realloc_encrypted_files',
+ 'send_mixed_raw']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index f86d6d9a7b..451852e863 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -114,11 +114,16 @@ post =
[/opt/zfs-tests/tests/functional/cli_root/zfs]
tests = ['zfs_001_neg', 'zfs_002_pos', 'zfs_003_neg']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_change-key]
+tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
+ 'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
+ 'zfs_change-key_pbkdf2iters']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_clone]
tests = ['zfs_clone_001_neg', 'zfs_clone_002_pos', 'zfs_clone_003_pos',
'zfs_clone_004_pos', 'zfs_clone_005_pos', 'zfs_clone_006_pos',
'zfs_clone_007_pos', 'zfs_clone_008_neg', 'zfs_clone_009_neg',
- 'zfs_clone_010_pos']
+ 'zfs_clone_010_pos', 'zfs_clone_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_copies]
tests = ['zfs_copies_001_pos', 'zfs_copies_002_pos', 'zfs_copies_003_pos',
@@ -129,7 +134,7 @@ tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos',
'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos',
'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg',
'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos',
- 'zfs_create_013_pos']
+ 'zfs_create_013_pos', 'zfs_create_encrypted', 'zfs_create_crypt_combos']
[/opt/zfs-tests/tests/functional/cli_root/zfs_destroy]
tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos',
@@ -147,12 +152,17 @@ tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_inherit]
tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg', 'zfs_inherit_003_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_load-key]
+tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file',
+ 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_mount]
tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos',
'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_006_pos',
'zfs_mount_007_pos', 'zfs_mount_008_pos', 'zfs_mount_009_neg',
'zfs_mount_010_neg', 'zfs_mount_011_neg', 'zfs_mount_012_neg',
- 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints']
+ 'zfs_mount_all_001_pos', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints'
+ 'zfs_mount_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_program]
tests = ['zfs_program_json']
@@ -160,7 +170,7 @@ tests = ['zfs_program_json']
[/opt/zfs-tests/tests/functional/cli_root/zfs_promote]
tests = ['zfs_promote_001_pos', 'zfs_promote_002_pos', 'zfs_promote_003_pos',
'zfs_promote_004_pos', 'zfs_promote_005_pos', 'zfs_promote_006_neg',
- 'zfs_promote_007_neg', 'zfs_promote_008_pos']
+ 'zfs_promote_007_neg', 'zfs_promote_008_pos', 'zfs_promote_encryptionroot']
[/opt/zfs-tests/tests/functional/cli_root/zfs_property]
tests = ['zfs_written_property_001_pos']
@@ -170,7 +180,9 @@ tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos',
'zfs_receive_005_neg', 'zfs_receive_006_pos',
'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg',
'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos',
- 'zfs_receive_013_pos', 'zfs_receive_014_pos']
+ 'zfs_receive_013_pos', 'zfs_receive_014_pos',
+ 'zfs_receive_from_encrypted', 'zfs_receive_raw',
+ 'zfs_receive_raw_incremental', 'zfs_receive_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_remap]
tests = ['zfs_remap_cliargs', 'zfs_remap_obsolete_counts']
@@ -180,7 +192,8 @@ tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos',
'zfs_rename_004_neg', 'zfs_rename_005_neg', 'zfs_rename_006_pos',
'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_009_neg',
'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg',
- 'zfs_rename_013_pos', 'zfs_rename_014_neg']
+ 'zfs_rename_013_pos', 'zfs_rename_014_neg', 'zfs_rename_encrypted_child',
+ 'zfs_rename_to_encrypted']
[/opt/zfs-tests/tests/functional/cli_root/zfs_reservation]
tests = ['zfs_reservation_001_pos', 'zfs_reservation_002_pos']
@@ -192,7 +205,7 @@ tests = ['zfs_rollback_001_pos', 'zfs_rollback_002_pos',
[/opt/zfs-tests/tests/functional/cli_root/zfs_send]
tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos',
'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos',
- 'zfs_send_007_pos']
+ 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw']
[/opt/zfs-tests/tests/functional/cli_root/zfs_set]
tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
@@ -203,7 +216,7 @@ tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos',
'ro_props_001_pos', 'share_mount_001_neg', 'snapdir_001_pos',
'user_property_001_pos', 'user_property_002_pos', 'user_property_003_neg',
'user_property_004_pos', 'version_001_neg', 'zfs_set_001_neg',
- 'zfs_set_002_neg', 'zfs_set_003_neg']
+ 'zfs_set_002_neg', 'zfs_set_003_neg', 'zfs_set_keylocation']
[/opt/zfs-tests/tests/functional/cli_root/zfs_share]
tests = ['zfs_share_001_pos', 'zfs_share_002_pos', 'zfs_share_003_pos',
@@ -217,6 +230,9 @@ tests = ['zfs_snapshot_001_neg', 'zfs_snapshot_002_neg',
'zfs_snapshot_006_pos', 'zfs_snapshot_007_neg', 'zfs_snapshot_008_neg',
'zfs_snapshot_009_pos']
+[/opt/zfs-tests/tests/functional/cli_root/zfs_unload-key]
+tests = ['zfs_unload-key', 'zfs_unload-key_all', 'zfs_unload-key_recursive']
+
[/opt/zfs-tests/tests/functional/cli_root/zfs_unmount]
tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos',
'zfs_unmount_004_pos', 'zfs_unmount_005_pos', 'zfs_unmount_006_pos',
@@ -259,6 +275,7 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_024_pos',
+ 'zpool_create_encrypted', 'zpool_create_crypt_combos',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
'zpool_create_tempname']
@@ -306,7 +323,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'import_rewind_config_changed',
'import_cachefile_shared_device',
'import_paths_changed',
- 'import_devices_missing']
+ 'import_devices_missing',
+ 'zpool_import_encrypted', 'zpool_import_encrypted_load']
[/opt/zfs-tests/tests/functional/cli_root/zpool_labelclear]
tests = ['zpool_labelclear_active', 'zpool_labelclear_exported']
@@ -347,7 +365,8 @@ tags = ['functional', 'cli_root', 'zpool_resilver']
[/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
- 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
+ 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies',
+ 'zpool_scrub_encrypted_unloaded']
[/opt/zfs-tests/tests/functional/cli_root/zpool_set]
tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
@@ -583,7 +602,10 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
'send-c_mixed_compression', 'send-c_stream_size_estimate', 'send-cD',
'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
- 'send-c_recv_dedup']
+ 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
+ 'send_encrypted_truncated_files',
+ 'send_realloc_encrypted_files',
+ 'send_mixed_raw']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile
new file mode 100644
index 0000000000..5be730f3fa
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zfs_change-key
+
+include $(SRC)/test/zfs-tests/Makefile.com
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh
new file mode 100644
index 0000000000..79cd6e9f90
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh
new file mode 100644
index 0000000000..6a9af3bc28
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh
new file mode 100644
index 0000000000..781caae5b5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh
@@ -0,0 +1,62 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key' should change the key material.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to change the key
+# 3. Unmount the dataset and unload its key
+# 4. Attempt to load the old key
+# 5. Verify the key is not loaded
+# 6. Attempt to load the new key
+# 7. Verify the key is loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key' should change the key material"
+
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must eval "echo $PASSPHRASE2 | zfs change-key $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE1 | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key' changes the key material"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh
new file mode 100644
index 0000000000..dda7c1df43
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key' should promote an encrypted child to an encryption root.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create an encrypted child dataset
+# 3. Attempt to change the key without any flags
+# 4. Attempt to change the key specifying keylocation
+# 5. Attempt to change the key specifying keyformat
+# 6. Verify the new encryption root can unload and load its key
+# 7. Recreate the child dataset
+# 8. Attempt to change the key specifying both the keylocation and keyformat
+# 9. Verify the new encryption root can unload and load its key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "'zfs change-key' should promote an encrypted child to an" \
+ "encryption root"
+
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_mustnot eval "echo $PASSPHRASE2 | zfs change-key" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_mustnot eval "echo $PASSPHRASE2 | zfs change-key -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must eval "echo $PASSPHRASE2 | zfs change-key -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1/child"
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs destroy $TESTPOOL/$TESTFS1/child
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs change-key -o keyformat=passphrase" \
+ "-o keylocation=prompt $TESTPOOL/$TESTFS1/child"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1/child"
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs change-key' promotes an encrypted child to an encryption root"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh
new file mode 100644
index 0000000000..1c68b8f4cc
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh
@@ -0,0 +1,72 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+# Copyright (c) 2019 DilOS
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the key format.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with a passphrase key format
+# 2. Unmount the dataset
+# 3. Verify the key format is passphrase
+# 4. Change the key format to hex
+# 5. Verify the key format is hex
+# 6. Attempt to reload the dataset's key
+# 7. Change the key format to raw
+# 8. Verify the key format is raw
+# 9. Attempt to reload the dataset's key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the key format"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "passphrase"
+
+log_must eval "echo $HEXKEY | zfs change-key -o keyformat=hex" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "hex"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $HEXKEY | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must eval "echo $RAWKEY | tr -d '\n' | zfs change-key -o keyformat=raw" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "raw"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $RAWKEY | tr -d '\n' | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_pass "'zfs change-key -o' changes the key format"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh
new file mode 100644
index 0000000000..94820c37ec
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -i' should cause a dataset to inherit its parent key
+#
+# STRATEGY:
+# 1. Create a parent encrypted dataset
+# 2. Create a child dataset as an encryption root
+# 3. Attempt to inherit the parent key
+# 4. Verify the key is inherited
+# 5. Unmount the parent and unload its key
+# 6. Verify the key is unavailable for parent and child
+# 7. Load the parent key
+# 8. Verify the key is available for parent and child
+# 9. Attempt to mount the datasets
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -i' should cause a dataset to inherit its" \
+ "parent key"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must zfs change-key -i $TESTPOOL/$TESTFS1/child
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child "$TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs change-key -i' causes a dataset to inherit its parent key"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh
new file mode 100644
index 0000000000..4ed4aadfe0
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -l' should load a dataset's key to change it.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Unload dataset and unload its key
+# 3. Attempt to change the key
+# 4. Verify the dataset key is loaded
+# 3. Attempt to change the key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -l' should load a dataset's key to change it"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs change-key -l $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs change-key -l $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -l' loads a dataset's key to change it"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh
new file mode 100644
index 0000000000..5cbe34b269
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh
@@ -0,0 +1,65 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the keylocation.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with a file key location
+# 2. Change the key location to 'prompt'
+# 3. Verify the key location
+# 4. Unmount the dataset and unload its key
+# 5. Attempt to load the dataset's key
+# 6. Attempt to change the key location to 'none'
+# 7. Attempt to change the key location to an invalid value
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the keylocation"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file:///$TESTPOOL/pkey"
+
+log_must eval "echo $PASSPHRASE1 | zfs change-key -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "prompt"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $PASSPHRASE1 | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_mustnot zfs change-key -o keylocation=none $TESTPOOL/$TESTFS1
+log_mustnot zfs change-key -o keylocation=foobar $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -o' changes the keylocation"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh
new file mode 100644
index 0000000000..b1672248be
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the pbkdf2 iterations.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with 200k PBKDF2 iterations
+# 2. Unmount the dataset
+# 3. Change the PBKDF2 iterations to 150k
+# 4. Verify the PBKDF2 iterations
+# 5. Unload the dataset's key
+# 6. Attempt to load the dataset's key
+#
+
+verify_runnable "both"
+
+function verify_pbkdf2iters
+{
+ typeset ds=$1
+ typeset iterations=$2
+ typeset iters=$(get_prop pbkdf2iters $ds)
+
+ if [[ "$iters" != "$iterations" ]]; then
+ log_fail "Expected $iterations iterations, got $iters"
+ fi
+
+ return 0
+}
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the pbkdf2 iterations"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey -o pbkdf2iters=200000 \
+ $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must verify_pbkdf2iters $TESTPOOL/$TESTFS1 "200000"
+
+log_must zfs change-key -o pbkdf2iters=150000 $TESTPOOL/$TESTFS1
+log_must verify_pbkdf2iters $TESTPOOL/$TESTFS1 "150000"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must zfs load-key $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -o' changes the pbkdf2 iterations"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh
new file mode 100644
index 0000000000..86f335bde2
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh
@@ -0,0 +1,83 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs clone' should create encrypted clones of encrypted datasets
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a snapshot of the dataset
+# 3. Attempt to clone the snapshot as an unencrypted dataset
+# 4. Attempt to clone the snapshot with a new key
+# 5. Attempt to clone the snapshot as a child of an unencrypted dataset
+# 6. Attempt to clone the snapshot as a child of an encrypted dataset
+# 7. Verify the encryption root of the datasets
+# 8. Unmount all datasets and unload their keys
+# 9. Attempt to load the encryption root's key
+# 10. Verify each dataset's key is loaded
+# 11. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs clone' should create encrypted clones of encrypted datasets"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs snapshot $TESTPOOL/$TESTFS1@now
+
+log_mustnot zfs clone -o encryption=off $TESTPOOL/$TESTFS1@now \
+ $TESTPOOL/$TESTFS2
+log_mustnot eval "echo $PASSPHRASE1 | zfs clone -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS2"
+log_must zfs clone $TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS2
+log_must zfs clone $TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS1/child
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS2 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS2
+log_must zfs unload-key -a
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+log_must key_available $TESTPOOL/$TESTFS2
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+log_must zfs mount $TESTPOOL/$TESTFS2
+
+log_pass "'zfs clone' creates encrypted clones of encrypted datasets"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh
new file mode 100644
index 0000000000..91e4cbdada
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh
@@ -0,0 +1,99 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+# Copyright (c) 2019, DilOS
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/properties.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs create' should create an encrypted dataset with a valid encryption
+# algorithm, key format, key location, and key.
+#
+# STRATEGY:
+# 1. Create a filesystem for each combination of encryption type and key format
+# 2. Verify that each filesystem has the correct properties set
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+set -A ENCRYPTION_ALGS \
+ "encryption=on" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A ENCRYPTION_PROPS \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A KEYFORMATS "keyformat=raw" \
+ "keyformat=hex" \
+ "keyformat=passphrase"
+
+set -A USER_KEYS "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ "abcdefgh"
+
+log_assert "'zfs create' should create encrypted datasets using all" \
+ "combinations of supported properties"
+
+typeset -i i=0
+while (( i < ${#ENCRYPTION_ALGS[*]} )); do
+ typeset -i j=0
+ while (( j < ${#KEYFORMATS[*]} )); do
+ log_must eval "echo ${USER_KEYS[j]} | tr -d '\n' | zfs create" \
+ "-o ${ENCRYPTION_ALGS[i]} -o ${KEYFORMATS[j]}" \
+ "$TESTPOOL/$TESTFS1"
+
+ datasetexists $TESTPOOL/$TESTFS1 || \
+ log_fail "Failed to create dataset using" \
+ "${ENCRYPTION_ALGS[i]} and ${KEYFORMATS[j]}"
+
+ propertycheck $TESTPOOL/$TESTFS1 ${ENCRYPTION_PROPS[i]} || \
+ log_fail "failed to set ${ENCRYPTION_ALGS[i]}"
+ propertycheck $TESTPOOL/$TESTFS1 ${KEYFORMATS[j]} || \
+ log_fail "failed to set ${KEYFORMATS[j]}"
+
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+ (( j = j + 1 ))
+ done
+ (( i = i + 1 ))
+done
+
+log_pass "'zfs create' creates encrypted datasets using all combinations of" \
+ "supported properties"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
new file mode 100644
index 0000000000..9d5ecab0df
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
@@ -0,0 +1,134 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/properties.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# ZFS should create datasets only if they have a valid combination of
+# encryption properties set.
+#
+# penc = parent encrypted
+# enc = encryption
+# loc = keylocation provided
+# fmt = keyformat provided
+#
+# penc enc fmt loc valid notes
+# -------------------------------------------
+# no unspec 0 0 yes inherit no encryption (not tested here)
+# no unspec 0 1 no no crypt specified
+# no unspec 1 0 no no crypt specified
+# no unspec 1 1 no no crypt specified
+# no off 0 0 yes explicit no encryption
+# no off 0 1 no keylocation given, but crypt off
+# no off 1 0 no keyformat given, but crypt off
+# no off 1 1 no keyformat given, but crypt off
+# no on 0 0 no no keyformat specified for new key
+# no on 0 1 no no keyformat specified for new key
+# no on 1 0 yes new encryption root
+# no on 1 1 yes new encryption root
+# yes unspec 0 0 yes inherit encryption
+# yes unspec 0 1 no no keyformat specified
+# yes unspec 1 0 yes new encryption root, crypt inherited
+# yes unspec 1 1 yes new encryption root, crypt inherited
+# yes off 0 0 no unencrypted child of encrypted parent
+# yes off 0 1 no unencrypted child of encrypted parent
+# yes off 1 0 no unencrypted child of encrypted parent
+# yes off 1 1 no unencrypted child of encrypted parent
+# yes on 0 0 yes inherited encryption, local crypt
+# yes on 0 1 no no keyformat specified for new key
+# yes on 1 0 yes new encryption root
+# yes on 1 1 yes new encryption root
+#
+# STRATEGY:
+# 1. Attempt to create a dataset using all combinations of encryption
+# properties
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "ZFS should create datasets only if they have a valid" \
+ "combination of encryption properties set."
+
+# Unencrypted parent
+log_must zfs create $TESTPOOL/$TESTFS1
+log_mustnot zfs create -o keyformat=passphrase $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o keylocation=prompt $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o keyformat=passphrase -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c1
+
+log_must zfs create -o encryption=off $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o encryption=off -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ -o keylocation=prompt $TESTPOOL/$TESTFS1/c2
+
+log_mustnot zfs create -o encryption=on $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=on -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c2
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1/c3"
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1/c4"
+
+# Encrypted parent
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+log_must zfs create $TESTPOOL/$TESTFS2/c1
+log_mustnot zfs create -o keylocation=prompt $TESTPOOL/$TESTFS2/c2
+log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS2/c3"
+log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
+ "-o keylocation=prompt $TESTPOOL/$TESTFS2/c4"
+
+log_mustnot zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keylocation=prompt \
+ $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ -o keylocation=prompt $TESTPOOL/$TESTFS2/c5
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "$TESTPOOL/$TESTFS2/c5"
+log_mustnot zfs create -o encryption=on -o keylocation=prompt \
+ $TESTPOOL/$TESTFS2/c6
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c6"
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c7"
+
+log_pass "ZFS creates datasets only if they have a valid combination of" \
+ "encryption properties set."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_003_pos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_003_pos.ksh
index 5ffe51ebef..d41dc9b5bc 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_003_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_003_pos.ksh
@@ -134,8 +134,8 @@ log_note "Verify that 'zfs destroy -r' fails to destroy dataset " \
for obj in $child_fs $child_fs1 $ctr $ctr1; do
log_mustnot zfs destroy -r $obj
datasetexists $obj || \
- log_fail "'zfs destroy -r' fails to keep clone " \
- "dependant outside the hirearchy."
+ log_fail "'zfs destroy -r' fails to keep dependent " \
+ "clone outside the hierarchy."
done
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile
new file mode 100644
index 0000000000..0751428a0d
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zfs_load-key
+
+include $(SRC)/test/zfs-tests/Makefile.com
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh
new file mode 100644
index 0000000000..79cd6e9f90
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh
new file mode 100644
index 0000000000..6a9af3bc28
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
new file mode 100644
index 0000000000..90d9f63f1d
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
@@ -0,0 +1,26 @@
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+export PASSPHRASE="password"
+export PASSPHRASE1="password1"
+export PASSPHRASE2="password2"
+export HEXKEY="000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"
+export HEXKEY1="201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A090807060504030201"
+export RAWKEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+export RAWKEY1="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh
new file mode 100644
index 0000000000..847a6aabd3
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh
@@ -0,0 +1,85 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key' should only load a key for an unloaded encrypted dataset.
+#
+# STRATEGY:
+# 1. Attempt to load the default dataset's key
+# 2. Unmount the dataset
+# 3. Attempt to load the default dataset's key
+# 4. Create an encrypted dataset
+# 5. Unmount the dataset and unload its key
+# 6. Attempt to load the dataset's key
+# 7. Verify the dataset's key is loaded
+# 8. Attempt to load the dataset's key again
+# 9. Create an encrypted pool
+# 10. Unmount the pool and unload its key
+# 11. Attempt to load the pool's key
+# 12. Verify the pool's key is loaded
+# 13. Attempt to load the pool's key again
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key' should only load the key for an" \
+ "unloaded encrypted dataset"
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS"
+
+log_must zfs unmount $TESTPOOL/$TESTFS
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2 }')"
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $DISK2"
+
+log_must zfs unmount $TESTPOOL1
+log_must zfs unload-key $TESTPOOL1
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL1"
+log_must key_available $TESTPOOL1
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL1"
+
+log_pass "'zfs load-key' only loads the key for an unloaded encrypted dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh
new file mode 100644
index 0000000000..5e331fd120
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh
@@ -0,0 +1,77 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -a' should load keys for all datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem, encrypted zvol, and an encrypted pool
+# 2. Unmount all datasets and unload their keys
+# 3. Attempt to load all dataset keys
+# 4. Verify each dataset has its key loaded
+# 5. Attempt to mount the pool and filesystem
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/zvol && log_must zfs destroy $TESTPOOL/zvol
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -a' should load keys for all datasets"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs create -V 64M -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/zvol
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2}')"
+log_must zpool create -O encryption=on -O keyformat=passphrase \
+ -O keylocation=file:///$TESTPOOL/pkey $TESTPOOL1 $DISK2
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs unload-key $TESTPOOL/zvol
+
+log_must zfs unmount $TESTPOOL1
+log_must zfs unload-key $TESTPOOL1
+
+log_must zfs load-key -a
+
+log_must key_available $TESTPOOL1
+log_must key_available $TESTPOOL/zvol
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs mount $TESTPOOL1
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs load-key -a' loads keys for all datasets"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
new file mode 100644
index 0000000000..627b68267e
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
@@ -0,0 +1,102 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
+
+# Return 0 is a dataset key is available, 1 otherwise
+#
+# $1 - dataset
+#
+function key_available
+{
+ typeset ds=$1
+
+ datasetexists $ds || return 1
+
+ typeset val=$(get_prop keystatus $ds)
+ if [[ "$val" == "none" ]]; then
+ log_note "Dataset $ds is not encrypted"
+ elif [[ "$val" == "available" ]]; then
+ return 0
+ fi
+
+ return 1
+}
+
+function key_unavailable
+{
+ key_available $1 && return 1
+ return 0
+}
+
+function verify_keyformat
+{
+ typeset ds=$1
+ typeset format=$2
+ typeset fmt=$(get_prop keyformat $ds)
+
+ if [[ "$fmt" != "$format" ]]; then
+ log_fail "Expected keyformat $format, got $fmt"
+ fi
+
+ return 0
+}
+
+function verify_keylocation
+{
+ typeset ds=$1
+ typeset location=$2
+ typeset keyloc=$(get_prop keylocation $ds)
+
+ if [[ "$keyloc" != "$location" ]]; then
+ log_fail "Expected keylocation $location, got $keyloc"
+ fi
+
+ return 0
+}
+
+function verify_encryption_root
+{
+ typeset ds=$1
+ typeset val=$2
+ typeset eroot=$(get_prop encryptionroot $ds)
+
+ if [[ "$eroot" != "$val" ]]; then
+ log_note "Expected encryption root '$val', got '$eroot'"
+ return 1
+ fi
+
+ return 0
+}
+
+function verify_origin
+{
+ typeset ds=$1
+ typeset val=$2
+ typeset orig=$(get_prop origin $ds)
+
+ if [[ "$orig" != "$val" ]]; then
+ log_note "Expected origin '$val', got '$orig'"
+ return 1
+ fi
+
+ return 0
+}
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh
new file mode 100644
index 0000000000..7cbda43ff2
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key' should load a dataset's key from a file.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset with a key file
+# 2. Unmount the dataset and unload the key
+# 3. Attempt to load the dataset's key
+# 4. Verify the key is loaded
+# 5. Attempt to mount the dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key' should load a key from a file"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs load-key' loads a key from a file"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh
new file mode 100644
index 0000000000..d0b1cdb20e
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -L' should override keylocation with provided value.
+#
+# STRATEGY:
+# 1. Create a key file
+# 2. Copy the key file to another location
+# 3. Create an encrypted dataset using the keyfile
+# 4. Unmount the dataset and unload its key
+# 5. Attempt to load the dataset specifying a keylocation of file
+# 6. Verify the key is loaded
+# 7. Verify the keylocation is the original key file
+# 8. Unload the dataset's key
+# 9. Attempt to load the dataset specifying a keylocation of prompt
+# 10. Verify the key is loaded
+# 11. Verify the keylocation is the original key file
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -L' should override keylocation with provided value"
+
+typeset key_location="/$TESTPOOL/pkey1"
+
+log_must eval "echo $PASSPHRASE > $key_location"
+log_must cp $key_location /$TESTPOOL/pkey2
+
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$key_location $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key -L file:///$TESTPOOL/pkey2 $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $PASSPHRASE | zfs load-key -L prompt $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location"
+
+log_pass "'zfs load-key -L' overrides keylocation with provided value"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh
new file mode 100644
index 0000000000..bfce786448
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -n' should load the key for an already loaded dataset.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to load the dataset's key
+# 3. Verify the key is loaded
+# 4. Attempt to load the dataset's key with an invalid key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -n' should load the key for a loaded dataset"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+
+log_must eval "echo $PASSPHRASE | zfs load-key -n $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE1 | zfs load-key -n $TESTPOOL/$TESTFS1"
+
+log_pass "'zfs load-key -n' loads the key for a loaded dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh
new file mode 100644
index 0000000000..7385b69cf5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh
@@ -0,0 +1,66 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -r' should recursively load keys.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a child dataset as an encryption root
+# 3. Unmount all datasets and unload their keys
+# 4. Attempt to load all dataset keys
+# 5. Verify each dataset has its key loaded
+# 6. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -r' should recursively load keys"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs create -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key -r $TESTPOOL
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs load-key -r' recursively loads keys"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh
new file mode 100644
index 0000000000..9749a9b3aa
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs mount -l' should accept a valid key as it mounts the filesystem.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Unmount and unload the dataset's key
+# 3. Verify the key is unloaded
+# 4. Attempt to mount all datasets in the pool
+# 5. Verify that no error code is produced
+# 6. Verify that the encrypted dataset is not mounted
+# 7. Attempt to load the key while mounting the dataset
+# 8. Verify the key is loaded
+# 9. Verify the dataset is mounted
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "'zfs mount -l' should properly load a valid wrapping key"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_must zfs mount -a
+unmounted $TESTPOOL/$TESTFS1 || \
+ log_fail "Filesystem $TESTPOOL/$TESTFS1 is mounted"
+
+log_must eval "echo $PASSPHRASE | zfs mount -l $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+mounted $TESTPOOL/$TESTFS1 || \
+ log_fail "Filesystem $TESTPOOL/$TESTFS1 is unmounted"
+
+log_pass "'zfs mount -l' properly loads a valid wrapping key"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh
new file mode 100644
index 0000000000..336c7b2538
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh
@@ -0,0 +1,80 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# ZFS must promote clones of an encryption root.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Clone the encryption root
+# 3. Clone the clone
+# 4. Verify the encryption root of all three datasets is the origin
+# 5. Promote the clone of the clone
+# 6. Verify the encryption root of all three datasets is still the origin
+# 7. Promote the clone of the original encryption root
+# 8. Verify the encryption root of all three datasets is the promoted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -Rf $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/clone1 && \
+ log_must zfs destroy -Rf $TESTPOOL/clone1
+ datasetexists $TESTPOOL/clone2 && \
+ log_must zfs destroy -Rf $TESTPOOL/clone2
+}
+log_onexit cleanup
+
+log_assert "ZFS must promote clones of an encryption root"
+
+passphrase="password"
+snaproot="$TESTPOOL/$TESTFS1@snap1"
+snapclone="$TESTPOOL/clone1@snap2"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snap $snaproot
+log_must zfs clone $snaproot $TESTPOOL/clone1
+log_must zfs snap $snapclone
+log_must zfs clone $snapclone $TESTPOOL/clone2
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/$TESTFS1
+
+log_must zfs promote $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/$TESTFS1
+
+log_must zfs promote $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/clone2
+
+log_pass "ZFS promotes clones of an encryption root"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
index eb00235877..486513256e 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
@@ -28,6 +28,7 @@
. $STF_SUITE/include/libtest.shlib
DISK=${DISKS%% *}
+
if is_global_zone; then
default_volume_setup $DISK
else
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh
new file mode 100644
index 0000000000..5eee9eecf4
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh
@@ -0,0 +1,83 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive an unencrypted stream from an encrypted dataset
+#
+# STRATEGY:
+# 1. Create an unencrypted dataset
+# 2. Create an encrypted dataset
+# 3. Create and checksum a file on the encrypted dataset
+# 4. Snapshot the encrypted dataset
+# 5. Attempt to receive the snapshot into an unencrypted child
+# 6. Verify encryption is not enabled
+# 7. Verify the cheksum of the file is the same as the original
+# 8. Attempt to receive the snapshot into an encrypted child
+# 9. Verify the cheksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive an unencrypted stream from an encrypted dataset"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS2@snap"
+
+log_must zfs create $TESTPOOL/$TESTFS1
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS2/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+
+log_must zfs snapshot $snap
+
+log_note "Verify ZFS can receive into an unencrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+crypt=$(get_prop encryption $TESTPOOL/$TESTFS1/c1)
+[[ "$crypt" == "off" ]] || log_fail "Received unencrypted stream as encrypted"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS1/c1/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_note "Verify ZFS can receive into an encrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS2/c1"
+
+typeset cksum2=$(md5sum /$TESTPOOL/$TESTFS2/c1/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum2" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum2 != $checksum)"
+
+log_pass "ZFS can receive an unencrypted stream from an encrypted dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh
new file mode 100644
index 0000000000..2042b37a98
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive streams from raw sends.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a file and get its checksum
+# 3. Snapshot the dataset
+# 4. Attempt to receive a raw send stream as a child of an unencrypted dataset
+# 5. Verify the key is unavailable
+# 6. Attempt to load the key and mount the dataset
+# 7. Verify the cheksum of the file is the same as the original
+# 8. Attempt to receive a raw send stream as a child of an encrypted dataset
+# 9. Verify the key is unavailable
+# 10. Attempt to load the key and mount the dataset
+# 11. Verify the cheksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive streams from raw sends"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS1/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS1/$TESTFILE0 | \
+ awk '{ print $1 }')
+
+log_must zfs snapshot $snap
+
+log_note "Verify ZFS can receive a raw send stream from an encrypted dataset"
+log_must eval "zfs send -w $snap | zfs receive $TESTPOOL/$TESTFS2"
+
+keystatus=$(get_prop keystatus $TESTPOOL/$TESTFS2)
+[[ "$keystatus" == "unavailable" ]] || \
+ log_fail "Expected keystatus unavailable, got $keystatus"
+
+log_must eval "echo $passphrase | zfs mount -l $TESTPOOL/$TESTFS2"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_must eval "zfs send -w $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+keystatus=$(get_prop keystatus $TESTPOOL/$TESTFS1/c1)
+[[ "$keystatus" == "unavailable" ]] || \
+ log_fail "Expected keystatus unavailable, got $keystatus"
+
+log_must eval "echo $passphrase | zfs mount -l $TESTPOOL/$TESTFS1/c1"
+typeset cksum2=$(md5sum /$TESTPOOL/$TESTFS1/c1/$TESTFILE0 | \
+ awk '{ print $1 }')
+[[ "$cksum2" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum2 != $checksum)"
+
+log_pass "ZFS can receive streams from raw sends"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh
new file mode 100644
index 0000000000..48878327b8
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh
@@ -0,0 +1,95 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive streams from raw incremental sends.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the dataset
+# 3. Create a file and get its checksum
+# 4. Snapshot the dataset
+# 5. Attempt to receive a raw send stream of the first snapshot
+# 6. Change the passphrase required to unlock the original filesystem
+# 7. Attempt and intentionally fail to receive the second snapshot
+# 8. Verify that the required passphrase hasn't changed on the receive side
+# 9. Attempt a real raw incremental send stream of the second snapshot
+# 10. Attempt load the key and mount the dataset
+# 11. Verify the checksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+
+ [[ -f $ibackup ]] && log_must rm -f $ibackup
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive streams from raw incremental sends"
+
+typeset ibackup="/var/tmp/ibackup.$$"
+typeset ibackup_trunc="/var/tmp/ibackup_trunc.$$"
+typeset passphrase="password"
+typeset passphrase2="password2"
+typeset snap1="$TESTPOOL/$TESTFS1@snap1"
+typeset snap2="$TESTPOOL/$TESTFS1@snap2"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snapshot $snap1
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS1/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS1/$TESTFILE0 | awk '{ print $1 }')
+
+log_must zfs snapshot $snap2
+
+log_must eval "zfs send -w $snap1 | zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "echo $passphrase2 | zfs change-key $TESTPOOL/$TESTFS1"
+log_must eval "zfs send -w -i $snap1 $snap2 > $ibackup"
+
+typeset trunc_size=$(stat -c %s $ibackup)
+trunc_size=$(expr $trunc_size - 64)
+log_must cp $ibackup $ibackup_trunc
+log_must truncate -s $trunc_size $ibackup_trunc
+log_mustnot eval "zfs receive $TESTPOOL/$TESTFS2 < $ibackup_trunc"
+log_mustnot eval "echo $passphrase2 | zfs load-key $TESTPOOL/$TESTFS2"
+log_must eval "echo $passphrase | zfs load-key $TESTPOOL/$TESTFS2"
+log_must zfs unload-key $TESTPOOL/$TESTFS2
+
+log_must eval "zfs receive $TESTPOOL/$TESTFS2 < $ibackup"
+log_must eval "echo $passphrase2 | zfs mount -l $TESTPOOL/$TESTFS2"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_pass "ZFS can receive streams from raw incremental sends"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
new file mode 100644
index 0000000000..57896c6fd3
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive to an encrypted child dataset.
+#
+# STRATEGY:
+# 1. Snapshot the default dataset
+# 2. Create an encrypted dataset
+# 3. Attempt to receive a stream to an encrypted child
+# 4. Attempt to receive a stream with properties to an encrypted child
+# 5. Attempt to receive a replication stream to an encrypted child
+# 6. Unmount and unload the encrypted dataset keys
+# 7. Attempt to receive a snapshot stream to an encrypted child
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ snapexists $snap && log_must_busy zfs destroy -f $snap
+
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive to an encrypted child dataset"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS@snap"
+typeset testfile="testfile"
+
+log_must zfs snapshot $snap
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_note "Verifying ZFS will receive to an encrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+log_note "Verifying 'send -p' will not receive to an encrypted child"
+log_mustnot eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2"
+
+log_note "Verifying 'send -R' will not receive to an encrypted child"
+log_mustnot eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3"
+
+log_note "Verifying ZFS will not receive to an encrypted child when the" \
+ "parent key is unloaded"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_mustnot eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c4"
+
+log_pass "ZFS can receive to an encrypted child dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh
new file mode 100644
index 0000000000..fa57658f18
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs rename' should not move an encrypted child dataset outside of its
+# encryption root.
+#
+# STRATEGY:
+# 1. Create two encryption roots, and a child and grandchild of the first
+# encryption root
+# 2. Attempt to rename the grandchild under an unencrypted parent
+# 3. Attempt to rename the grandchild under a different encrypted parent
+# 4. Attempt to rename the grandchild under the current parent
+# 5. Verify the encryption root of the dataset
+# 6. Attempt to rename the grandchild to a child
+# 7. Verify the encryption root of the dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/$TESTFS3 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS3
+}
+log_onexit cleanup
+
+log_assert "'zfs rename' should not move an encrypted child outside of its" \
+ "encryption root"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+log_must zfs create $TESTPOOL/$TESTFS2/child
+log_must zfs create $TESTPOOL/$TESTFS2/child/grandchild
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS3"
+
+log_mustnot zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/grandchild
+
+log_mustnot zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/$TESTFS3/grandchild
+
+log_must zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/$TESTFS2/child/grandchild2
+log_must verify_encryption_root $TESTPOOL/$TESTFS2/child/grandchild2 \
+ $TESTPOOL/$TESTFS2
+
+log_must zfs rename $TESTPOOL/$TESTFS2/child/grandchild2 \
+ $TESTPOOL/$TESTFS2/grandchild2
+log_must verify_encryption_root $TESTPOOL/$TESTFS2/grandchild2 \
+ $TESTPOOL/$TESTFS2
+
+log_pass "'zfs rename' does not move an encrypted child outside of its" \
+ "encryption root"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
new file mode 100644
index 0000000000..400592aaca
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
@@ -0,0 +1,51 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs rename' should not rename an unencrypted dataset to a child
+# of an encrypted dataset
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to rename the default dataset to a child of the encrypted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "'zfs rename' should not rename an unencrypted dataset to a" \
+ "child of an encrypted dataset"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+log_mustnot zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS
+
+log_pass "'zfs rename' does not rename an unencrypted dataset to a child" \
+ "of an encrypted dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh
new file mode 100644
index 0000000000..490e146ba6
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh
@@ -0,0 +1,76 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should perform unencrypted sends of encrypted datasets, unless the '-p'
+# or '-R' options are specified.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 6. Create a child encryption root
+# 2. Snapshot the dataset
+# 3. Attempt a send
+# 4. Attempt a send with properties
+# 5. Attempt a replication send
+# 7. Unmount the parent and unload its key
+# 8. Attempt a send of the parent dataset
+# 9. Attempt a send of the child encryption root
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should perform unencrypted sends of encrypted datasets, " \
+ "unless the '-p' or '-R' options are specified"
+
+typeset passphrase="password"
+typeset passphrase1="password1"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must eval "echo $passphrase1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1/child"
+
+log_must zfs snapshot -r $snap
+
+log_must eval "zfs send $snap > /dev/null"
+log_mustnot eval "zfs send -p $snap > /dev/null"
+log_mustnot eval "zfs send -R $snap > /dev/null"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_mustnot eval "zfs send $snap > /dev/null"
+log_must eval "zfs send $TESTPOOL/$TESTFS1/child@snap > /dev/null"
+
+log_pass "ZFS performs unencrypted sends of encrypted datasets, unless the" \
+ "'-p' or '-R' options are specified"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh
new file mode 100644
index 0000000000..112ee1143d
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should not perform unencrypted sends from encrypted datasets
+# with unloaded keys.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the dataset
+# 3. Unload the dataset key
+# 4. Verify sending the stream fails
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should not perform unencrypted sends from encrypted datasets" \
+ "with unloaded keys."
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+log_must zfs snapshot $snap
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_mustnot eval "zfs send $snap > /dev/null"
+
+log_pass "ZFS does not perform unencrypted sends from encrypted datasets" \
+ "with unloaded keys."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh
new file mode 100644
index 0000000000..85cc7407e1
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh
@@ -0,0 +1,79 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should perform raw sends of datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the default dataset and the encrypted dataset
+# 3. Attempt a raw send of both datasets
+# 4. Attempt a raw send with properties of both datasets
+# 5. Attempt a raw replication send of both datasets
+# 6. Unmount and unload the encrypted dataset key
+# 7. Attempt a raw send of the encrypted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ snapexists $snap && \
+ log_must zfs destroy $snap
+
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should perform raw sends of datasets"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS@snap"
+typeset snap1="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snapshot $snap
+log_must zfs snapshot $snap1
+
+log_must eval "zfs send -w $snap > /dev/null"
+log_must eval "zfs send -w $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform raw sends with properties"
+log_must eval "zfs send -wp $snap > /dev/null"
+log_must eval "zfs send -wp $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform raw replication sends"
+log_must eval "zfs send -wR $snap > /dev/null"
+log_must eval "zfs send -wR $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform a raw send of an encrypted datasets with" \
+ "its key unloaded"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "zfs send -w $snap1 > /dev/null"
+
+log_pass "ZFS performs raw sends of datasets"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
index 8868747d22..b2b5c077bf 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
@@ -28,4 +28,5 @@
. $STF_SUITE/include/libtest.shlib
DISK=${DISKS%% *}
+
default_container_volume_setup $DISK
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh
new file mode 100644
index 0000000000..313fa4e4d1
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# Unencrypted datasets should only allow keylocation of 'none', encryption
+# roots should only allow keylocation of 'prompt' and file URI, and encrypted
+# child datasets should not be able to change their keylocation.
+#
+# STRATEGY:
+# 1. Verify the key location of the default dataset is 'none'
+# 2. Attempt to change the key location of the default dataset
+# 3. Create an encrypted dataset using a key file
+# 4. Attempt to change the key location of the encrypted dataset to 'none',
+# an invalid location, its current location, and 'prompt'
+# 5. Attempt to reload the encrypted dataset key using the new key location
+# 6. Create a encrypted child dataset
+# 7. Verify the key location of the child dataset is 'none'
+# 8. Attempt to change the key location of the child dataset
+# 9. Verify the key location of the child dataset has not changed
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "Key location can only be 'prompt' or a file path for encryption" \
+ "roots, and 'none' for unencrypted volumes"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+
+log_must verify_keylocation $TESTPOOL/$TESTFS "none"
+log_must zfs set keylocation=none $TESTPOOL/$TESTFS
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS
+log_mustnot zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS
+log_must verify_keylocation $TESTPOOL/$TESTFS "none"
+
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_mustnot zfs set keylocation=none $TESTPOOL/$TESTFS1
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file:///$TESTPOOL/pkey"
+
+log_must zfs set keylocation=prompt $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "prompt"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must rm /$TESTPOOL/pkey
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_must zfs create $TESTPOOL/$TESTFS1/child
+log_must verify_keylocation $TESTPOOL/$TESTFS1/child "none"
+
+log_mustnot zfs set keylocation=none $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=prompt $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+
+log_must verify_keylocation $TESTPOOL/$TESTFS1/child "none"
+
+log_pass "Key location can only be 'prompt' or a file path for encryption" \
+ "roots, and 'none' for unencrypted volumes"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile
new file mode 100644
index 0000000000..8fe2bf42ca
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zfs_unload-key
+
+include $(SRC)/test/zfs-tests/Makefile.com
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh
new file mode 100644
index 0000000000..79cd6e9f90
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh
new file mode 100644
index 0000000000..6a9af3bc28
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh
new file mode 100644
index 0000000000..9e08ac69d4
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key' should only unload the key of an unmounted dataset.
+#
+# STRATEGY:
+# 1. Attempt to unload the default dataset's key
+# 2. Unmount the dataset
+# 3. Attempt to unload the default dataset's key
+# 4. Create an encrypted dataset
+# 5. Attempt to unload the dataset's key
+# 6. Verify the key is loaded
+# 7. Unmount the dataset
+# 8. Attempt to unload the dataset's key
+# 9. Verify the key is not loaded
+# 10. Attempt to unload the dataset's key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key' should unload the key for an unmounted" \
+ "encrypted dataset"
+
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS
+
+log_must zfs unmount $TESTPOOL/$TESTFS
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS1
+
+log_pass "'zfs unload-key' unloads the key for an unmounted encrypted dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh
new file mode 100644
index 0000000000..ecb98d1894
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh
@@ -0,0 +1,76 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key -a' should unload keys for all datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem, encrypted child dataset, an encrypted
+# zvol, and an encrypted pool
+# 2. Unmount all datasets
+# 3. Attempt to unload all dataset keys
+# 4. Verify each dataset has its key unloaded
+# 5. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/zvol && log_must zfs destroy $TESTPOOL/zvol
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key -a' should unload keys for all datasets"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_must zfs create -V 64M -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/zvol
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2}')"
+log_must zpool create -O encryption=on -O keyformat=passphrase \
+ -O keylocation=file:///$TESTPOOL/pkey $TESTPOOL1 $DISK2
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL1
+
+log_must zfs unload-key -a
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/zvol
+log_must key_unavailable $TESTPOOL1
+
+log_mustnot zfs mount $TESTPOOL
+log_mustnot zfs mount $TESTPOOL/zvol
+log_mustnot zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs unload-key -a' unloads keys for all datasets"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh
new file mode 100644
index 0000000000..9766b59058
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh
@@ -0,0 +1,72 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key -r' should recursively unload keys.
+#
+# STRATEGY:
+# 1. Create a parent encrypted dataset
+# 2. Create a sibling encrypted dataset
+# 3. Create a child dataset as an encryption root
+# 4. Unmount all datasets
+# 5. Attempt to unload all dataset keys under parent
+# 6. Verify parent and child have their keys unloaded
+# 7. Verify sibling has its key loaded
+# 8. Attempt to mount all datasets
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key -r' should recursively unload keys"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs create -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS2
+
+log_must zfs unload-key -r $TESTPOOL/$TESTFS1
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must key_available $TESTPOOL/$TESTFS2
+
+log_mustnot zfs mount $TESTPOOL/$TESTFS1
+log_mustnot zfs mount $TESTPOOL/$TESTFS1/child
+log_must zfs mount $TESTPOOL/$TESTFS2
+
+log_pass "'zfs unload-key -r' recursively unloads keys"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_005_pos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_005_pos.ksh
index 2afbec37dc..2afbec37dc 100755..100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_005_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_005_pos.ksh
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh
new file mode 100644
index 0000000000..d28d5953c5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh
@@ -0,0 +1,90 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+# Copyright (c) 2019, DilOS
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool create' should create encrypted pools when using a valid encryption
+# algorithm, key format, key location, and key.
+#
+# STRATEGY:
+# 1. Create a pool for each combination of encryption type and key format
+# 2. Verify that each filesystem has the correct properties set
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+log_onexit cleanup
+
+set -A ENCRYPTION_ALGS "encryption=on" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A ENCRYPTION_PROPS "encryption=aes-256-ccm" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A KEYFORMATS "keyformat=raw" \
+ "keyformat=hex" \
+ "keyformat=passphrase"
+
+set -A USER_KEYS "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ "abcdefgh"
+
+log_assert "'zpool create' should create encrypted pools when using a valid" \
+ "encryption algorithm, key format, key location, and key."
+
+typeset -i i=0
+while (( i < ${#ENCRYPTION_ALGS[*]} )); do
+ typeset -i j=0
+ while (( j < ${#KEYFORMATS[*]} )); do
+ log_must eval "printf '%s' ${USER_KEYS[j]} | zpool create" \
+ "-O ${ENCRYPTION_ALGS[i]} -O ${KEYFORMATS[j]}" \
+ "$TESTPOOL $DISKS"
+
+ propertycheck $TESTPOOL ${ENCRYPTION_PROPS[i]} || \
+ log_fail "failed to set ${ENCRYPTION_ALGS[i]}"
+ propertycheck $TESTPOOL ${KEYFORMATS[j]} || \
+ log_fail "failed to set ${KEYFORMATS[j]}"
+
+ log_must zpool destroy $TESTPOOL
+ (( j = j + 1 ))
+ done
+ (( i = i + 1 ))
+done
+
+log_pass "'zpool create' creates encrypted pools when using a valid" \
+ "encryption algorithm, key format, key location, and key."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh
new file mode 100644
index 0000000000..aa154d5c65
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh
@@ -0,0 +1,95 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017, Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool create' should create an encrypted dataset only if it has a valid
+# combination of encryption properties set.
+#
+# enc = encryption
+# loc = keylocation provided
+# fmt = keyformat provided
+#
+# U = unspecified
+# N = off
+# Y = on
+#
+# enc fmt loc valid notes
+# -------------------------------------------
+# U 0 1 no no crypt specified
+# U 1 0 no no crypt specified
+# U 1 1 no no crypt specified
+# N 0 0 yes explicit no encryption
+# N 0 1 no keylocation given, but crypt off
+# N 1 0 no keyformat given, but crypt off
+# N 1 1 no keyformat given, but crypt off
+# Y 0 0 no no keyformat specified for new key
+# Y 0 1 no no keyformat specified for new key
+# Y 1 0 yes new encryption root
+# Y 1 1 yes new encryption root
+#
+# STRATEGY:
+# 1. Attempt to create a dataset using all combinations of encryption
+# properties
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+log_onexit cleanup
+
+log_assert "'zpool create' should create an encrypted dataset only if it" \
+ "has a valid combination of encryption properties set."
+
+log_mustnot zpool create -O keylocation=prompt $TESTPOOL $DISKS
+log_mustnot zpool create -O keyformat=passphrase $TESTPOOL $DISKS
+log_mustnot zpool create -O keyformat=passphrase -O keylocation=prompt \
+ $TESTPOOL $DISKS
+
+log_must zpool create -O encryption=off $TESTPOOL $DISKS
+log_must zpool destroy $TESTPOOL
+
+log_mustnot zpool create -O encryption=off -O keylocation=prompt \
+ $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=off -O keyformat=passphrase \
+ $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=off -O keyformat=passphrase \
+ -O keylocation=prompt $TESTPOOL $DISKS
+
+log_mustnot zpool create -O encryption=on $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=on -O keylocation=prompt \
+ $TESTPOOL $DISKS
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase $TESTPOOL $DISKS"
+log_must zpool destroy $TESTPOOL
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL $DISKS"
+log_must zpool destroy $TESTPOOL
+
+log_pass "'zpool create' creates an encrypted dataset only if it has a" \
+ "valid combination of encryption properties set."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
index fc4ce85bdb..998fe0e2b3 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
@@ -79,4 +79,6 @@ typeset -a properties=(
"feature@spacemap_v2"
"feature@allocation_classes"
"feature@resilver_defer"
+ "feature@encryption"
+ "feature@bookmark_v2"
)
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/blockfiles/missing_ivset.dat.bz2 b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/blockfiles/missing_ivset.dat.bz2
new file mode 100644
index 0000000000..2b91d9003b
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/blockfiles/missing_ivset.dat.bz2
Binary files differ
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2 b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2
new file mode 100644
index 0000000000..1c625c2c44
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2
Binary files differ
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh
new file mode 100644
index 0000000000..4e9013afeb
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool import' should import a pool with an encrypted dataset without
+# mounting it.
+#
+# STRATEGY:
+# 1. Create an encrypted pool
+# 2. Export the pool
+# 3. Attempt to import the pool
+# 4. Verify the pool exists and the key is not loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL1
+ log_must rm $VDEV0
+ log_must mkfile $FILE_SIZE $VDEV0
+}
+log_onexit cleanup
+
+log_assert "'zpool import' should import a pool with an encrypted dataset" \
+ "without mounting it"
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $VDEV0"
+log_must zpool export $TESTPOOL1
+log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+log_must poolexists $TESTPOOL1
+log_must key_unavailable $TESTPOOL1
+log_must unmounted $TESTPOOL1
+
+log_pass "'zpool import' imports a pool with an encrypted dataset without" \
+ "mounting it"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh
new file mode 100644
index 0000000000..d060e8a798
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool import -l' should import a pool with an encrypted dataset and load
+# its key.
+#
+# STRATEGY:
+# 1. Create an encrypted pool
+# 2. Export the pool
+# 3. Attempt to import the pool with the key
+# 4. Verify the pool exists and the key is loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL1
+ log_must rm $VDEV0
+ log_must mkfile $FILE_SIZE $VDEV0
+}
+log_onexit cleanup
+
+log_assert "'zpool import -l' should import a pool with an encrypted dataset" \
+ "and load its key"
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $VDEV0"
+log_must zpool export $TESTPOOL1
+log_must eval "echo $PASSPHRASE | zpool import -l -d $DEVICE_DIR $TESTPOOL1"
+log_must poolexists $TESTPOOL1
+log_must key_available $TESTPOOL1
+log_must mounted $TESTPOOL1
+
+log_pass "'zpool import -l' imports a pool with an encrypted dataset and" \
+ "loads its key"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh
new file mode 100644
index 0000000000..e58af126b3
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh
@@ -0,0 +1,99 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# 'zpool import' should import a pool with Errata #3 while preventing
+# the user from performing read write operations
+#
+# STRATEGY:
+# 1. Import a pre-packaged pool with Errata #3
+# 2. Attempt to write to the effected datasets
+# 3. Attempt to read from the effected datasets
+# 4. Attempt to perform a raw send of the effected datasets
+# 5. Perform a regular send of the datasets under a new encryption root
+# 6. Verify the new datasets can be read from and written to
+# 7. Destroy the old effected datasets
+# 8. Reimport the pool and verify that the errata is no longer present
+#
+
+verify_runnable "global"
+
+POOL_NAME=cryptv0
+POOL_FILE=cryptv0.dat
+
+function uncompress_pool
+{
+
+ log_note "Creating pool from $POOL_FILE"
+ log_must bzcat \
+ $STF_SUITE/tests/functional/cli_root/zpool_import/$POOL_FILE.bz2 \
+ > /$TESTPOOL/$POOL_FILE
+ return 0
+}
+
+function cleanup
+{
+ poolexists $POOL_NAME && log_must zpool destroy $POOL_NAME
+ [[ -e /$TESTPOOL/$POOL_FILE ]] && rm /$TESTPOOL/$POOL_FILE
+ return 0
+}
+log_onexit cleanup
+
+log_assert "Verify that Errata 3 is properly handled"
+
+uncompress_pool
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_must eval "zpool status $POOL_NAME | grep -q Errata" # also detects 'Errata #4'
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testfs"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testvol"
+
+log_mustnot zfs mount $POOL_NAME/testfs
+log_must zfs mount -o ro $POOL_NAME/testfs
+
+old_mntpnt=$(get_prop mountpoint $POOL_NAME/testfs)
+log_must eval "ls $old_mntpnt | grep -q testfile"
+log_mustnot dd if=/dev/zero of=/dev/zvol/rdsk/$POOL_NAME/testvol bs=512 count=1
+log_must dd if=/dev/zvol/rdsk/$POOL_NAME/testvol of=/dev/null bs=512 count=1
+log_must eval "echo 'password' | zfs create \
+ -o encryption=on -o keyformat=passphrase -o keylocation=prompt \
+ cryptv0/encroot"
+log_mustnot eval "zfs send -w $POOL_NAME/testfs@snap1 | \
+ zfs recv $POOL_NAME/encroot/testfs"
+log_mustnot eval "zfs send -w $POOL_NAME/testvol@snap1 | \
+ zfs recv $POOL_NAME/encroot/testvol"
+
+log_must eval "zfs send $POOL_NAME/testfs@snap1 | \
+ zfs recv $POOL_NAME/encroot/testfs"
+log_must eval "zfs send $POOL_NAME/testvol@snap1 | \
+ zfs recv $POOL_NAME/encroot/testvol"
+block_device_wait
+log_must dd if=/dev/zero of=/dev/zvol/rdsk/$POOL_NAME/encroot/testvol bs=512 count=1
+new_mntpnt=$(get_prop mountpoint $POOL_NAME/encroot/testfs)
+log_must eval "ls $new_mntpnt | grep -q testfile"
+log_must zfs destroy -r $POOL_NAME/testfs
+log_must zfs destroy -r $POOL_NAME/testvol
+
+log_must zpool export $POOL_NAME
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_mustnot eval "zpool status $POOL_NAME | grep -q 'Errata #3'"
+log_pass "Errata 3 is properly handled"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata4.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata4.ksh
new file mode 100755
index 0000000000..d06a9cd754
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata4.ksh
@@ -0,0 +1,143 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2019 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# 'zpool import' should import a pool with Errata #4. Users should be
+# able to set the zfs_disable_ivset_guid_check to continue normal
+# operation and the errata should disappear when no more effected
+# datasets remain.
+#
+# STRATEGY:
+# 1. Import a pre-packaged pool with Errata #4 and verify its state
+# 2. Prepare pool to fix existing datasets
+# 3. Use raw sends to fix datasets
+# 4. Ensure fixed datasets match their initial counterparts
+# 5. Destroy the initial datasets and verify the errata is gone
+#
+
+verify_runnable "global"
+
+POOL_NAME=missing_ivset
+POOL_FILE=missing_ivset.dat
+
+function uncompress_pool
+{
+ log_note "Creating pool from $POOL_FILE"
+ log_must bzcat \
+ $STF_SUITE/tests/functional/cli_root/zpool_import/blockfiles/$POOL_FILE.bz2 \
+ > /$TESTPOOL/$POOL_FILE
+ return 0
+}
+
+function cleanup
+{
+ log_must set_tunable32 zfs_disable_ivset_guid_check 0
+ poolexists $POOL_NAME && log_must zpool destroy $POOL_NAME
+ [[ -e /$TESTPOOL/$POOL_FILE ]] && rm /$TESTPOOL/$POOL_FILE
+ return 0
+}
+log_onexit cleanup
+
+log_assert "Verify that Errata 4 is properly handled"
+
+function has_ivset_guid # dataset
+{
+ ds="$1"
+ ivset_guid=$(get_prop ivsetguid $ds)
+
+ if [ "$ivset_guid" == "-" ]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+# 1. Import a pre-packaged pool with Errata #4 and verify its state
+uncompress_pool
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_must eval "zpool status $POOL_NAME | grep -q 'Errata #4'"
+log_must eval "zpool status $POOL_NAME | grep -q ZFS-8000-ER"
+bm2_value=$(zpool get -H -o value feature@bookmark_v2 $POOL_NAME)
+if [ "$bm2_value" != "disabled" ]; then
+ log_fail "initial pool's bookmark_v2 feature is not disabled"
+fi
+
+log_mustnot has_ivset_guid $POOL_NAME/testfs@snap1
+log_mustnot has_ivset_guid $POOL_NAME/testfs@snap2
+log_mustnot has_ivset_guid $POOL_NAME/testfs@snap3
+log_mustnot has_ivset_guid $POOL_NAME/testvol@snap1
+log_mustnot has_ivset_guid $POOL_NAME/testvol@snap2
+log_mustnot has_ivset_guid $POOL_NAME/testvol@snap3
+
+# 2. Prepare pool to fix existing datasets
+log_must zpool set feature@bookmark_v2=enabled $POOL_NAME
+log_must set_tunable32 zfs_disable_ivset_guid_check 1
+log_must zfs create $POOL_NAME/fixed
+
+# 3. Use raw sends to fix datasets
+log_must eval "zfs send -w $POOL_NAME/testfs@snap1 | \
+ zfs recv $POOL_NAME/fixed/testfs"
+log_must eval "zfs send -w -i @snap1 $POOL_NAME/testfs@snap2 | \
+ zfs recv $POOL_NAME/fixed/testfs"
+log_must eval \
+ "zfs send -w -i $POOL_NAME/testfs#snap2 $POOL_NAME/testfs@snap3 | \
+ zfs recv $POOL_NAME/fixed/testfs"
+
+log_must eval "zfs send -w $POOL_NAME/testvol@snap1 | \
+ zfs recv $POOL_NAME/fixed/testvol"
+log_must eval "zfs send -w -i @snap1 $POOL_NAME/testvol@snap2 | \
+ zfs recv $POOL_NAME/fixed/testvol"
+log_must eval \
+ "zfs send -w -i $POOL_NAME/testvol#snap2 $POOL_NAME/testvol@snap3 | \
+ zfs recv $POOL_NAME/fixed/testvol"
+
+# 4. Ensure fixed datasets match their initial counterparts
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testfs"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testvol"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/fixed/testfs"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/fixed/testvol"
+log_must zfs mount $POOL_NAME/testfs
+log_must zfs mount $POOL_NAME/fixed/testfs
+block_device_wait
+
+old_mntpnt=$(get_prop mountpoint $POOL_NAME/testfs)
+new_mntpnt=$(get_prop mountpoint $POOL_NAME/fixed/testfs)
+log_must diff -r "$old_mntpnt" "$new_mntpnt"
+log_must diff /dev/zvol/$POOL_NAME/testvol /dev/zvol/$POOL_NAME/fixed/testvol
+
+log_must has_ivset_guid $POOL_NAME/fixed/testfs@snap1
+log_must has_ivset_guid $POOL_NAME/fixed/testfs@snap2
+log_must has_ivset_guid $POOL_NAME/fixed/testfs@snap3
+log_must has_ivset_guid $POOL_NAME/fixed/testvol@snap1
+log_must has_ivset_guid $POOL_NAME/fixed/testvol@snap2
+log_must has_ivset_guid $POOL_NAME/fixed/testvol@snap3
+
+# 5. Destroy the initial datasets and verify the errata is gone
+log_must zfs destroy -r $POOL_NAME/testfs
+log_must zfs destroy -r $POOL_NAME/testvol
+
+log_must zpool export $POOL_NAME
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_mustnot eval "zpool status $POOL_NAME | grep -q 'Errata #4'"
+log_mustnot eval "zpool status $POOL_NAME | grep -q ZFS-8000-ER"
+log_pass "Errata 4 is properly handled"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh
new file mode 100644
index 0000000000..483a683bd5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Scrubs must work on an encrypted dataset with an unloaded key.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Generate data on the dataset
+# 3. Unmount the encrypted dataset and unload its key
+# 4. Start a scrub
+# 5. Wait for the scrub to complete
+# 6. Verify the scrub had no errors
+# 7. Load the dataset key and mount it
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "Scrubs must work on an encrypted dataset with an unloaded key"
+
+log_must eval "echo 'password' | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+typeset mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS2)
+log_must mkfile 10m $mntpnt/file1
+
+for i in 2..10; do
+ log_must mkfile 512b $mntpnt/file$i
+done
+
+log_must zfs unmount $TESTPOOL/$TESTFS2
+log_must zfs unload-key $TESTPOOL/$TESTFS2
+
+log_must zpool scrub $TESTPOOL
+
+while ! is_pool_scrubbed $TESTPOOL; do
+ sleep 1
+done
+
+log_must check_pool_status $TESTPOOL "scan" "with 0 errors"
+
+log_must eval "echo 'password' | zfs mount -l $TESTPOOL/$TESTFS2"
+
+log_pass "Scrubs work on an encrypted dataset with an unloaded key"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
index 5d2ba60f18..6b22cb709e 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
@@ -428,6 +428,108 @@ function rm_files
}
#
+# Simulate a random set of operations which could be reasonably expected
+# to occur on an average filesystem.
+#
+# $1 Number of files to modify
+# $2 Maximum file size
+# $3 File system to modify the file on
+# $4 Enabled xattrs (optional)
+#
+function churn_files
+{
+ nfiles=$1
+ maxsize=$2
+ fs=$3
+ xattrs=${4:-1}
+
+ #
+ # Remove roughly half of the files in order to make it more
+ # likely that a dnode will be reallocated.
+ #
+ for ((i=0; i<$nfiles; i=i+1)); do
+ file_name="/$fs/file-$i"
+
+ if [[ -e $file_name ]]; then
+ if [ $((RANDOM % 2)) -eq 0 ]; then
+ rm $file_name || \
+ log_fail "Failed to remove $file_name"
+ fi
+ fi
+ done
+
+ #
+ # Remount the filesystem to simulate normal usage. This resets
+ # the last allocated object id allowing for new objects to be
+ # reallocated in the locations of previously freed objects.
+ #
+ log_must zfs unmount $fs
+ log_must zfs mount $fs
+
+ for i in {0..$nfiles}; do
+ file_name="/$fs/file-$i"
+ file_size=$((($RANDOM * $RANDOM % ($maxsize - 1)) + 1))
+
+ #
+ # When the file exists modify it in one of five ways to
+ # simulate normal usage:
+ # - (20%) Remove and set and extended attribute on the file
+ # - (20%) Overwrite the existing file
+ # - (20%) Truncate the existing file to a random length
+ # - (20%) Truncate the existing file to zero length
+ # - (20%) Remove the file
+ #
+ # Otherwise create the missing file. 20% of the created
+ # files will be small and use embedded block pointers, the
+ # remainder with have random sizes up to the maximum size.
+ # Three extended attributes are attached to all of the files.
+ #
+ if [[ -e $file_name ]]; then
+ value=$((RANDOM % 5))
+ if [ $value -eq 0 -a $xattrs -ne 0 ]; then
+ attrname="testattr$((RANDOM % 3))"
+ attr -qr $attrname $file_name || \
+ log_fail "Failed to remove $attrname"
+ attr -qs $attrname -V TestValue $file_name || \
+ log_fail "Failed to set $attrname"
+ elif [ $value -eq 1 ]; then
+ dd if=/dev/urandom of=$file_name \
+ bs=$file_size count=1 >/dev/null 2>&1 || \
+ log_fail "Failed to overwrite $file_name"
+ elif [ $value -eq 2 ]; then
+ truncate -s $file_size $file_name || \
+ log_fail "Failed to truncate $file_name"
+ elif [ $value -eq 3 ]; then
+ truncate -s 0 $file_name || \
+ log_fail "Failed to truncate $file_name"
+ else
+ rm $file_name || \
+ log_fail "Failed to remove $file_name"
+ fi
+ else
+ if [ $((RANDOM % 5)) -eq 0 ]; then
+ file_size=$((($RANDOM % 64) + 1))
+ fi
+
+ dd if=/dev/urandom of=$file_name \
+ bs=$file_size count=1 >/dev/null 2>&1 || \
+ log_fail "Failed to create $file_name"
+
+ if [ $xattrs -ne 0 ]; then
+ for j in {0..2}; do
+ attrname="testattr$j"
+ attr -qs $attrname -V TestValue \
+ $file_name || log_fail \
+ "Failed to set $attrname"
+ done
+ fi
+ fi
+ done
+
+ return 0
+}
+
+#
# Mess up file contents
#
# $1 The file path
@@ -606,7 +708,7 @@ function parse_dump
if ($1 == "OBJECT") print $1" "$4
if ($1 == "FREEOBJECTS") print $1" "$4" "$7
if ($1 == "FREE") print $1" "$7" "$10
- if ($1 == "WRITE") print $1" "$15" "$18" "$21" "$24" "$27}'
+ if ($1 == "WRITE") print $1" "$15" "$21" "$24" "$27" "$30}'
}
#
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh
new file mode 100644
index 0000000000..c85dd40965
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh
@@ -0,0 +1,130 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# DESCRIPTION:
+# Verify that a raw zfs send and receive can deal with several different
+# types of file layouts.
+#
+# STRATEGY:
+# 1. Create a new encrypted filesystem
+# 2. Add an empty file to the filesystem
+# 3. Add a small 512 byte file to the filesystem
+# 4. Add a larger 32M file to the filesystem
+# 5. Add a large sparse file to the filesystem
+# 6. Add 1000 empty files to the filesystem
+# 7. Add a file with a large xattr value
+# 8. Use xattrtest to create files with random xattrs (with and without xattrs=on)
+# 9. Take a snapshot of the filesystem
+# 10. Remove the 1000 empty files to the filesystem
+# 11. Take another snapshot of the filesystem
+# 12. Send and receive both snapshots
+# 13. Mount the filesystem and check the contents
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/recv && \
+ log_must zfs destroy -r $TESTPOOL/recv
+ [[ -f $keyfile ]] && log_must rm $keyfile
+ [[ -f $sendfile ]] && log_must rm $sendfile
+}
+log_onexit cleanup
+
+function recursive_cksum
+{
+ find $1 -type f -exec sha256sum {} \; | \
+ sort -k 2 | awk '{ print $1 }' | sha256sum
+}
+
+log_assert "Verify 'zfs send -w' works with many different file layouts"
+
+typeset keyfile=/$TESTPOOL/pkey
+typeset sendfile=/$TESTPOOL/sendfile
+typeset sendfile2=/$TESTPOOL/sendfile2
+
+# Create an encrypted dataset
+log_must eval "echo 'password' > $keyfile"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$keyfile $TESTPOOL/$TESTFS2
+
+# Create files with varied layouts on disk
+log_must touch /$TESTPOOL/$TESTFS2/empty
+log_must mkfile 512 /$TESTPOOL/$TESTFS2/small
+log_must mkfile 32M /$TESTPOOL/$TESTFS2/full
+log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/sparse \
+ bs=512 count=1 seek=1048576 >/dev/null 2>&1
+
+log_must mkdir -p /$TESTPOOL/$TESTFS2/dir
+for i in {1..1000}; do
+ log_must mkfile 512 /$TESTPOOL/$TESTFS2/dir/file-$i
+done
+
+log_must mkdir -p /$TESTPOOL/$TESTFS2/xattrondir
+log_must zfs set xattr=on $TESTPOOL/$TESTFS2
+
+# XXX - the lines below (through the end of the file) that are commented out
+# are differences from ZoL due to currently unsupported extended attribute code
+# on illumos.
+# log_must xattrtest -f 10 -x 3 -s 32768 -r -k -p /$TESTPOOL/$TESTFS2/xattrondir
+# log_must mkdir -p /$TESTPOOL/$TESTFS2/xattrsadir
+# log_must zfs set xattr=sa $TESTPOOL/$TESTFS2
+# log_must xattrtest -f 10 -x 3 -s 32768 -r -k -p /$TESTPOOL/$TESTFS2/xattrsadir
+
+# ZoL issue #7432
+# log_must zfs set compression=on xattr=sa $TESTPOOL/$TESTFS2
+# log_must touch /$TESTPOOL/$TESTFS2/attrs
+# log_must eval "python -c 'print \"a\" * 4096' | \
+# attr -s bigval /$TESTPOOL/$TESTFS2/attrs"
+# log_must zfs set compression=off xattr=on $TESTPOOL/$TESTFS2
+
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap1
+
+# Remove the empty files created in the first snapshot
+for i in {1..1000}; do
+ log_must rm /$TESTPOOL/$TESTFS2/dir/file-$i
+done
+sync
+
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap2
+expected_cksum=$(recursive_cksum /$TESTPOOL/$TESTFS2)
+
+log_must eval "zfs send -wp $TESTPOOL/$TESTFS2@snap1 > $sendfile"
+log_must eval "zfs send -wp -i @snap1 $TESTPOOL/$TESTFS2@snap2 > $sendfile2"
+
+log_must eval "zfs recv -F $TESTPOOL/recv < $sendfile"
+log_must eval "zfs recv -F $TESTPOOL/recv < $sendfile2"
+log_must zfs load-key $TESTPOOL/recv
+
+log_must zfs mount -a
+actual_cksum=$(recursive_cksum /$TESTPOOL/recv)
+[[ "$expected_cksum" != "$actual_cksum" ]] && \
+ log_fail "Recursive checksums differ ($expected_cksum != $actual_cksum)"
+
+# log_must xattrtest -f 10 -o3 -y -p /$TESTPOOL/recv/xattrondir
+# log_must xattrtest -f 10 -o3 -y -p /$TESTPOOL/recv/xattrsadir
+
+log_pass "Verified 'zfs send -w' works with many different file layouts"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy.ksh
new file mode 100644
index 0000000000..5e19a6b6c0
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy.ksh
@@ -0,0 +1,96 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2017 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# Raw recursive sends preserve filesystem structure.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem with a clone and a child
+# 2. Snapshot and send the filesystem tree
+# 3. Verify that the filesystem structure was correctly received
+# 4. Change the child to an encryption root and promote the clone
+# 5. Snapshot and send the filesystem tree again
+# 6. Verify that the new structure is received correctly
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ log_must cleanup_pool $POOL
+ log_must cleanup_pool $POOL2
+ log_must setup_test_model $POOL
+}
+
+log_assert "Raw recursive sends preserve filesystem structure."
+log_onexit cleanup
+
+# Create the filesystem heirarchy
+log_must cleanup_pool $POOL
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $POOL/$FS"
+log_must zfs snapshot $POOL/$FS@snap
+log_must zfs clone $POOL/$FS@snap $POOL/clone
+log_must zfs create $POOL/$FS/child
+
+# Back up the tree and verify the structure
+log_must zfs snapshot -r $POOL@before
+log_must eval "zfs send -wR $POOL@before > $BACKDIR/fs-before-R"
+log_must eval "zfs receive -d -F $POOL2 < $BACKDIR/fs-before-R"
+dstds=$(get_dst_ds $POOL/$FS $POOL2)
+log_must cmp_ds_subs $POOL/$FS $dstds
+
+log_must verify_encryption_root $POOL/$FS $POOL/$FS
+log_must verify_keylocation $POOL/$FS "prompt"
+log_must verify_origin $POOL/$FS "-"
+
+log_must verify_encryption_root $POOL/clone $POOL/$FS
+log_must verify_keylocation $POOL/clone "none"
+log_must verify_origin $POOL/clone "$POOL/$FS@snap"
+
+log_must verify_encryption_root $POOL/$FS/child $POOL/$FS
+log_must verify_keylocation $POOL/$FS/child "none"
+
+# Alter the heirarchy and re-send
+log_must eval "echo $PASSPHRASE1 | zfs change-key -o keyformat=passphrase" \
+ "$POOL/$FS/child"
+log_must zfs promote $POOL/clone
+log_must zfs snapshot -r $POOL@after
+log_must eval "zfs send -wR -i $POOL@before $POOL@after >" \
+ "$BACKDIR/fs-after-R"
+log_must eval "zfs receive -d -F $POOL2 < $BACKDIR/fs-after-R"
+log_must cmp_ds_subs $POOL/$FS $dstds
+
+log_must verify_encryption_root $POOL/$FS $POOL/clone
+log_must verify_keylocation $POOL/$FS "none"
+log_must verify_origin $POOL/$FS "$POOL/clone@snap"
+
+log_must verify_encryption_root $POOL/clone $POOL/clone
+log_must verify_keylocation $POOL/clone "prompt"
+log_must verify_origin $POOL/clone "-"
+
+log_must verify_encryption_root $POOL/$FS/child $POOL/$FS/child
+log_must verify_keylocation $POOL/$FS/child "prompt"
+
+log_pass "Raw recursive sends preserve filesystem structure."
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_truncated_files.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_truncated_files.ksh
new file mode 100644
index 0000000000..d701bcecb9
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_encrypted_truncated_files.ksh
@@ -0,0 +1,118 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# DESCRIPTION:
+#
+#
+# STRATEGY:
+# 1. Create a new encrypted filesystem
+# 2. Add a 4 files that are to be truncated later
+# 3. Take a snapshot of the filesystem
+# 4. Truncate one of the files from 32M to 128k
+# 5. Truncate one of the files from 512k to 384k
+# 6. Truncate one of the files from 512k to 0 to 384k via reallocation
+# 7. Truncate one of the files from 1k to 0 to 512b via reallocation
+# 8. Take another snapshot of the filesystem
+# 9. Send and receive both snapshots
+# 10. Mount the filesystem and check the contents
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/recv && \
+ log_must zfs destroy -r $TESTPOOL/recv
+ [[ -f $keyfile ]] && log_must rm $keyfile
+ [[ -f $sendfile ]] && log_must rm $sendfile
+}
+log_onexit cleanup
+
+function recursive_cksum
+{
+ find $1 -type f -exec sha256sum {} \; | \
+ sort -k 2 | awk '{ print $1 }' | sha256sum
+}
+
+log_assert "Verify 'zfs send -w' works with many different file layouts"
+
+typeset keyfile=/$TESTPOOL/pkey
+typeset sendfile=/$TESTPOOL/sendfile
+typeset sendfile2=/$TESTPOOL/sendfile2
+
+# Create an encrypted dataset
+log_must eval "echo 'password' > $keyfile"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$keyfile $TESTPOOL/$TESTFS2
+
+# Explicitly set the recordsize since the truncation sizes below depend on
+# this value being 128k. This is currently same as the default recordsize.
+log_must zfs set recordsize=128k $TESTPOOL/$TESTFS2
+
+# Create files with varied layouts on disk
+log_must mkfile 32M /$TESTPOOL/$TESTFS2/truncated
+log_must mkfile 524288 /$TESTPOOL/$TESTFS2/truncated2
+log_must mkfile 524288 /$TESTPOOL/$TESTFS2/truncated3
+log_must mkfile 1024 /$TESTPOOL/$TESTFS2/truncated4
+
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap1
+
+#
+# Truncate files created in the first snapshot. The first tests
+# truncating a large file to a single block. The second tests
+# truncating one block off the end of a file without changing
+# the required nlevels to hold it. The third tests handling
+# of a maxblkid that is dropped and then raised again. The
+# fourth tests an object that is truncated from a single block
+# to a smaller single block.
+#
+log_must truncate -s 131072 /$TESTPOOL/$TESTFS2/truncated
+log_must truncate -s 393216 /$TESTPOOL/$TESTFS2/truncated2
+log_must rm -f /$TESTPOOL/$TESTFS2/truncated3
+log_must rm -f /$TESTPOOL/$TESTFS2/truncated4
+log_must zpool sync $TESTPOOL
+log_must zfs umount $TESTPOOL/$TESTFS2
+log_must zfs mount $TESTPOOL/$TESTFS2
+log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/truncated3 \
+ bs=128k count=3 iflag=fullblock
+log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/truncated4 \
+ bs=512 count=1 iflag=fullblock
+
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap2
+expected_cksum=$(recursive_cksum /$TESTPOOL/$TESTFS2)
+
+log_must eval "zfs send -wp $TESTPOOL/$TESTFS2@snap1 > $sendfile"
+log_must eval "zfs send -wp -i @snap1 $TESTPOOL/$TESTFS2@snap2 > $sendfile2"
+
+log_must eval "zfs recv -F $TESTPOOL/recv < $sendfile"
+log_must eval "zfs recv -F $TESTPOOL/recv < $sendfile2"
+log_must zfs load-key $TESTPOOL/recv
+
+log_must zfs mount -a
+actual_cksum=$(recursive_cksum /$TESTPOOL/recv)
+[[ "$expected_cksum" != "$actual_cksum" ]] && \
+ log_fail "Recursive checksums differ ($expected_cksum != $actual_cksum)"
+
+log_pass "Verified 'zfs send -w' works with many different file layouts"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh
index 6533352a9a..6533352a9a 100755..100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_mixed_raw.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_mixed_raw.ksh
new file mode 100755
index 0000000000..eea535af11
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_mixed_raw.ksh
@@ -0,0 +1,118 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2019 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Verify that 'zfs receive' produces an error when mixing
+# raw and non-raw sends in a way that would break IV set
+# consistency.
+#
+# STRATEGY:
+# 1. Create an initial dataset with 3 snapshots.
+# 2. Perform a raw send of the first snapshot to 2 other datasets.
+# 3. Perform a non-raw send of the second snapshot to one of
+# the other datasets. Perform a raw send from this dataset to
+# the last one.
+# 4. Attempt to raw send the final snapshot of the first dataset
+# to the other 2 datasets, which should fail.
+# 5. Repeat steps 1-4, but using bookmarks for incremental sends.
+#
+#
+# A B C notes
+# ------------------------------------------------------------------------------
+# snap1 ---raw---> snap1 --raw--> snap1 # all snaps initialized via raw send
+# snap2 -non-raw-> snap2 --raw--> snap2 # A sends non-raw to B, B sends raw to C
+# snap3 ------------raw---------> snap3 # attempt send to C (should fail)
+#
+
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS3 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS3
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "Mixing raw and non-raw receives should fail"
+
+typeset passphrase="password"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snapshot $TESTPOOL/$TESTFS1@1
+log_must touch /$TESTPOOL/$TESTFS1/a
+log_must zfs snapshot $TESTPOOL/$TESTFS1@2
+log_must touch /$TESTPOOL/$TESTFS1/b
+log_must zfs snapshot $TESTPOOL/$TESTFS1@3
+
+# Testing with snapshots
+log_must eval "zfs send -w $TESTPOOL/$TESTFS1@1 |" \
+ "zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "echo $passphrase | zfs load-key $TESTPOOL/$TESTFS2"
+log_must eval "zfs send -w $TESTPOOL/$TESTFS2@1 |" \
+ "zfs receive $TESTPOOL/$TESTFS3"
+log_must eval "echo $passphrase | zfs load-key $TESTPOOL/$TESTFS3"
+
+log_must eval "zfs send -i $TESTPOOL/$TESTFS1@1 $TESTPOOL/$TESTFS1@2 |" \
+ "zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "zfs send -w -i $TESTPOOL/$TESTFS2@1 $TESTPOOL/$TESTFS2@2 |" \
+ "zfs receive $TESTPOOL/$TESTFS3"
+
+log_mustnot eval "zfs send -w -i $TESTPOOL/$TESTFS1@2 $TESTPOOL/$TESTFS1@3 |" \
+ "zfs receive $TESTPOOL/$TESTFS2"
+log_mustnot eval "zfs send -w -i $TESTPOOL/$TESTFS2@2 $TESTPOOL/$TESTFS2@3 |" \
+ "zfs receive $TESTPOOL/$TESTFS3"
+
+log_must zfs destroy -r $TESTPOOL/$TESTFS3
+log_must zfs destroy -r $TESTPOOL/$TESTFS2
+
+# Testing with bookmarks
+log_must zfs bookmark $TESTPOOL/$TESTFS1@1 $TESTPOOL/$TESTFS1#b1
+log_must zfs bookmark $TESTPOOL/$TESTFS1@2 $TESTPOOL/$TESTFS1#b2
+
+log_must eval "zfs send -w $TESTPOOL/$TESTFS1@1 |" \
+ "zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "echo $passphrase | zfs load-key $TESTPOOL/$TESTFS2"
+
+log_must zfs bookmark $TESTPOOL/$TESTFS2@1 $TESTPOOL/$TESTFS2#b1
+
+log_must eval "zfs send -w $TESTPOOL/$TESTFS2@1 |" \
+ "zfs receive $TESTPOOL/$TESTFS3"
+log_must eval "echo $passphrase | zfs load-key $TESTPOOL/$TESTFS3"
+
+log_must eval "zfs send -i $TESTPOOL/$TESTFS1#b1 $TESTPOOL/$TESTFS1@2 |" \
+ "zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "zfs send -w -i $TESTPOOL/$TESTFS2#b1 $TESTPOOL/$TESTFS2@2 |" \
+ "zfs receive $TESTPOOL/$TESTFS3"
+
+log_mustnot eval "zfs send -w -i $TESTPOOL/$TESTFS1#b2" \
+ "$TESTPOOL/$TESTFS1@3 | zfs receive $TESTPOOL/$TESTFS2"
+log_mustnot eval "zfs send -w -i $TESTPOOL/$TESTFS2#b2" \
+ "$TESTPOOL/$TESTFS2@3 | zfs receive $TESTPOOL/$TESTFS3"
+
+log_pass "Mixing raw and non-raw receives fail as expected"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh
index 12a72fa092..12a72fa092 100755..100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_encrypted_files.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_encrypted_files.ksh
new file mode 100644
index 0000000000..0649beaa35
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_encrypted_files.ksh
@@ -0,0 +1,112 @@
+#!/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2019 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify encrypted raw incremental receives handle dnode reallocation.
+
+# Strategy:
+# 1. Create a pool containing an encrypted filesystem.
+# 2. Use 'zfs send -wp' to perform a raw send of the initial filesystem.
+# 3. Repeat the followings steps N times to verify raw incremental receives.
+# a) Randomly change several key dataset properties.
+# b) Modify the contents of the filesystem such that dnode reallocation
+# is likely during the 'zfs receive', and receive_object() exercises
+# as much of its functionality as possible.
+# c) Create a new snapshot and generate an raw incremental stream.
+# d) Receive the raw incremental stream and verify the received contents.
+# e) Destroy the incremental stream and old snapshot.
+#
+
+verify_runnable "both"
+
+log_assert "Verify encrypted raw incremental receive handles reallocation"
+
+function cleanup
+{
+ rm -f $BACKDIR/fs@*
+ rm -f $keyfile
+ destroy_dataset $POOL/fs "-rR"
+ destroy_dataset $POOL/newfs "-rR"
+}
+
+log_onexit cleanup
+
+typeset keyfile=/$TESTPOOL/pkey
+
+# Create an encrypted dataset
+log_must eval "echo 'password' > $keyfile"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$keyfile $POOL/fs
+
+last_snap=1
+log_must zfs snapshot $POOL/fs@snap${last_snap}
+log_must eval "zfs send -wp $POOL/fs@snap${last_snap} \
+ >$BACKDIR/fs@snap${last_snap}"
+log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs@snap${last_snap}"
+
+# Set atime=off to prevent the recursive_cksum from modifying newfs.
+log_must zfs set atime=off $POOL/newfs
+
+for i in {1..5}; do
+ # Randomly modify several dataset properties in order to generate
+ # more interesting incremental send streams.
+ rand_set_prop $POOL/fs checksum "off" "fletcher4" "sha256"
+ rand_set_prop $POOL/fs compression "off" "lzjb" "gzip" "lz4"
+ rand_set_prop $POOL/fs recordsize "32K" "128K"
+ rand_set_prop $POOL/fs dnodesize "legacy" "auto" "4k"
+ rand_set_prop $POOL/fs xattr "on" "sa"
+
+ # Churn the filesystem in such a way that we're likely to be both
+ # allocating and reallocating objects in the incremental stream.
+ #
+ # Disable xattrs until the following spill block issue is resolved:
+ # https://github.com/openzfs/openzfs/pull/705
+ #
+ log_must churn_files 1000 524288 $POOL/fs 0
+ expected_cksum=$(recursive_cksum /$fs)
+
+ # Create a snapshot and use it to send an incremental stream.
+ this_snap=$((last_snap + 1))
+ log_must zfs snapshot $POOL/fs@snap${this_snap}
+ log_must eval "zfs send -wp -i $POOL/fs@snap${last_snap} \
+ $POOL/fs@snap${this_snap} > $BACKDIR/fs@snap${this_snap}"
+
+ # Receive the incremental stream and verify the received contents.
+ log_must eval "zfs recv -Fu $POOL/newfs < $BACKDIR/fs@snap${this_snap}"
+
+ log_must zfs load-key $POOL/newfs
+ log_must zfs mount $POOL/newfs
+ actual_cksum=$(recursive_cksum /$POOL/newfs)
+ log_must zfs umount $POOL/newfs
+ log_must zfs unload-key $POOL/newfs
+
+ if [[ "$expected_cksum" != "$actual_cksum" ]]; then
+ log_fail "Checksums differ ($expected_cksum != $actual_cksum)"
+ fi
+
+ # Destroy the incremental stream and old snapshot.
+ rm -f $BACKDIR/fs@snap${last_snap}
+ log_must zfs destroy $POOL/fs@snap${last_snap}
+ log_must zfs destroy $POOL/newfs@snap${last_snap}
+ last_snap=$this_snap
+done
+
+log_pass "Verify encrypted raw incremental receive handles reallocation"