diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 14e8a5e27af3..a379d14cda96 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -1304,19 +1304,18 @@ ztest_dmu_objset_own(const char *name, dmu_objset_type_t type, boolean_t readonly, boolean_t decrypt, void *tag, objset_t **osp) { int err; + char *cp = NULL; + char ddname[ZFS_MAX_DATASET_NAME_LEN]; + + strcpy(ddname, name); + cp = strchr(ddname, '@'); + if (cp != NULL) + *cp = '\0'; err = dmu_objset_own(name, type, readonly, decrypt, tag, osp); - if (decrypt && err == EACCES) { - char ddname[ZFS_MAX_DATASET_NAME_LEN]; + while (decrypt && err == EACCES) { dsl_crypto_params_t *dcp; nvlist_t *crypto_args = fnvlist_alloc(); - char *cp = NULL; - - /* spa_keystore_load_wkey() expects a dsl dir name */ - strcpy(ddname, name); - cp = strchr(ddname, '@'); - if (cp != NULL) - *cp = '\0'; fnvlist_add_uint8_array(crypto_args, "wkeydata", (uint8_t *)ztest_wkeydata, WRAPPING_KEY_LEN); @@ -1326,10 +1325,23 @@ ztest_dmu_objset_own(const char *name, dmu_objset_type_t type, dsl_crypto_params_free(dcp, B_FALSE); fnvlist_free(crypto_args); - if (err != 0) - return (err); + if (err != 0) { + /* + * We couldn't load a key for this dataset so try + * the parent. This loop will eventually hit the + * encryption root since ztest only makes clones + * as children of their origin datasets. + */ + cp = strchr(ddname, '/'); + if (cp == NULL) + return (err); + + *cp = '\0'; + continue; + } err = dmu_objset_own(name, type, readonly, decrypt, tag, osp); + break; } return (err); @@ -6744,6 +6756,34 @@ ztest_dataset_close(int d) ztest_zd_fini(zd); } +/* ARGSUSED */ +static int +ztest_replay_zil_cb(const char *name, void *arg) +{ + objset_t *os; + ztest_ds_t *zdtmp; + + VERIFY0(ztest_dmu_objset_own(name, DMU_OST_ANY, B_TRUE, + B_TRUE, FTAG, &os)); + + if (dmu_objset_zil(os)->zl_parse_lr_count != 0 && + ztest_opts.zo_verbose >= 4) { + (void) printf("replaying logs for '%s' (%llu records)\n", name, + (unsigned long long)dmu_objset_zil(os)->zl_parse_lr_count); + } + + zdtmp = umem_alloc(sizeof (ztest_ds_t), UMEM_NOFAIL); + + ztest_zd_init(zdtmp, NULL, os); + zil_replay(os, zdtmp, ztest_replay_vector); + ztest_zd_fini(zdtmp); + + umem_free(zdtmp, sizeof (ztest_ds_t)); + + dmu_objset_disown(os, B_TRUE, FTAG); + return (0); +} + /* * Kick off threads to run tests on all datasets in parallel. */ @@ -6845,6 +6885,11 @@ ztest_run(ztest_shared_t *zs) if (ztest_opts.zo_verbose >= 4) (void) printf("starting main threads...\n"); + + /* Replay all logs of all datasets in the pool */ + (void) dmu_objset_find(ztest_opts.zo_pool, ztest_replay_zil_cb, + NULL, DS_FIND_CHILDREN); + /* * Kick off all the tests that run in parallel. */ diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index d2545c6fa41b..56df33705a7d 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -758,7 +758,7 @@ spa_keystore_load_wkey(const char *dsname, dsl_crypto_params_t *dcp, dsl_crypto_key_t *dck = NULL; dsl_wrapping_key_t *wkey = dcp->cp_wkey; dsl_pool_t *dp = NULL; - uint64_t keyformat, salt, iters; + uint64_t rddobj, keyformat, salt, iters; /* * We don't validate the wrapping key's keyformat, salt, or iters @@ -786,6 +786,13 @@ spa_keystore_load_wkey(const char *dsname, dsl_crypto_params_t *dcp, goto error; } + /* confirm that dd is the encryption root */ + ret = dsl_dir_get_encryption_root_ddobj(dd, &rddobj); + if (ret != 0 || rddobj != dd->dd_object) { + ret = (SET_ERROR(EINVAL)); + goto error; + } + /* initialize the wkey's ddobj */ wkey->wk_ddobj = dd->dd_object;