Add support for dm-verity try_verify_in_tasklet option.

Available since kernel 6.0.
This commit is contained in:
Milan Broz
2022-07-26 22:02:36 +02:00
parent 09ac5321f4
commit b183bb25e2
9 changed files with 41 additions and 7 deletions

View File

@@ -1183,6 +1183,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25) #define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25)
/** dm-integrity: reset automatic recalculation */ /** dm-integrity: reset automatic recalculation */
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26) #define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
/** dm-verity: try to use tasklets */
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
/** /**
* Active device runtime attributes * Active device runtime attributes

View File

@@ -205,6 +205,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch)) if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED; _dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
_dm_verity_checked = true; _dm_verity_checked = true;
} }
@@ -734,6 +737,8 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
num_options++; num_options++;
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
num_options++; num_options++;
if (flags & CRYPT_ACTIVATE_TASKLETS)
num_options++;
max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256; max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
fec_features = crypt_safe_alloc(max_fec_size); fec_features = crypt_safe_alloc(max_fec_size);
@@ -764,13 +769,14 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
} else } else
*verity_verify_args = '\0'; *verity_verify_args = '\0';
if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */ if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options, r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "", (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "", (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "", (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "", (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : ""); (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "",
(flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : "");
if (r < 0 || (size_t)r >= sizeof(features)) if (r < 0 || (size_t)r >= sizeof(features))
goto out; goto out;
} else } else
@@ -1705,6 +1711,12 @@ int dm_create_device(struct crypt_device *cd, const char *name,
r = -EINVAL; r = -EINVAL;
} }
if (dmd->flags & CRYPT_ACTIVATE_TASKLETS &&
!(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) {
log_err(cd, _("Requested dm-verity tasklets option is not supported."));
r = -EINVAL;
}
if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION && if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) { !(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) {
log_err(cd, _("Requested dm-verity data corruption handling options are not supported.")); log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
@@ -2289,6 +2301,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
else if (!strcasecmp(arg, "check_at_most_once")) else if (!strcasecmp(arg, "check_at_most_once"))
*act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE; *act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
else if (!strcasecmp(arg, "try_verify_in_tasklet"))
*act_flags |= CRYPT_ACTIVATE_TASKLETS;
else if (!strcasecmp(arg, "use_fec_from_device")) { else if (!strcasecmp(arg, "use_fec_from_device")) {
str = strsep(&params, " "); str = strsep(&params, " ");
str2 = crypt_lookup_dev(str); str2 = crypt_lookup_dev(str);

View File

@@ -75,6 +75,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */ #define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */ #define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */ #define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
#define DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type; typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY }; enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY };

View File

@@ -58,7 +58,7 @@ The <root_hash> is a hexadecimal string.
*<options>* can be [--hash-offset, --no-superblock, --ignore-corruption *<options>* can be [--hash-offset, --no-superblock, --ignore-corruption
or --restart-on-corruption, --panic-on-corruption, --ignore-zero-blocks, or --restart-on-corruption, --panic-on-corruption, --ignore-zero-blocks,
--check-at-most-once, --root-hash-signature, --root-hash-file]. --check-at-most-once, --root-hash-signature, --root-hash-file, --use-tasklets].
If option --root-hash-file is used, the root hash is read from <path> If option --root-hash-file is used, the root hash is read from <path>
instead of from the command line parameter. Expects hex-encoded text, instead of from the command line parameter. Expects hex-encoded text,
@@ -213,6 +213,10 @@ Path to root hash signature file used to verify the root hash (in
kernel). This feature requires Linux kernel version 5.4 or more kernel). This feature requires Linux kernel version 5.4 or more
recent. recent.
*--use-tasklets*::
Try to use kernel tasklets in dm-verity driver for performance reasons.
This option is available since Linux kernel version 6.0.
*--deferred*:: *--deferred*::
Defers device removal in *close* command until the last user closes Defers device removal in *close* command until the last user closes
it. it.

View File

@@ -158,6 +158,7 @@
#define OPT_USE_FSYNC "use-fsync" #define OPT_USE_FSYNC "use-fsync"
#define OPT_USE_RANDOM "use-random" #define OPT_USE_RANDOM "use-random"
#define OPT_USE_URANDOM "use-urandom" #define OPT_USE_URANDOM "use-urandom"
#define OPT_USE_TASKLETS "use-tasklets"
#define OPT_UUID "uuid" #define OPT_UUID "uuid"
#define OPT_VERACRYPT "veracrypt" #define OPT_VERACRYPT "veracrypt"
#define OPT_VERACRYPT_PIM "veracrypt-pim" #define OPT_VERACRYPT_PIM "veracrypt-pim"

View File

@@ -184,6 +184,8 @@ static int _activate(const char *dm_device,
activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
if (ARG_SET(OPT_CHECK_AT_MOST_ONCE_ID)) if (ARG_SET(OPT_CHECK_AT_MOST_ONCE_ID))
activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE; activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
if (ARG_SET(OPT_USE_TASKLETS_ID))
activate_flags |= CRYPT_ACTIVATE_TASKLETS;
if (!ARG_SET(OPT_NO_SUPERBLOCK_ID)) { if (!ARG_SET(OPT_NO_SUPERBLOCK_ID)) {
params.flags = flags; params.flags = flags;
@@ -436,13 +438,15 @@ static int action_status(void)
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION| CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
CRYPT_ACTIVATE_PANIC_ON_CORRUPTION| CRYPT_ACTIVATE_PANIC_ON_CORRUPTION|
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS| CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)) CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE|
log_std(" flags: %s%s%s%s%s\n", CRYPT_ACTIVATE_TASKLETS))
log_std(" flags: %s%s%s%s%s%s\n",
(cad.flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? "ignore_corruption " : "", (cad.flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? "ignore_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? "restart_on_corruption " : "", (cad.flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? "restart_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? "panic_on_corruption " : "", (cad.flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? "panic_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "", (cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "",
(cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : ""); (cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : "",
(cad.flags & CRYPT_ACTIVATE_TASKLETS) ? "try_verify_in_tasklet" : "");
} }
out: out:
crypt_free(cd); crypt_free(cd);

View File

@@ -63,6 +63,8 @@ ARG(OPT_ROOT_HASH_SIGNATURE, '\0', POPT_ARG_STRING, N_("Path to root hash signat
ARG(OPT_SALT, 's', POPT_ARG_STRING, N_("Salt"), N_("hex string"), CRYPT_ARG_STRING, {}, {}) ARG(OPT_SALT, 's', POPT_ARG_STRING, N_("Salt"), N_("hex string"), CRYPT_ARG_STRING, {}, {})
ARG(OPT_USE_TASKLETS, '\0', POPT_ARG_NONE, N_("Use kernel tasklets for performance"), NULL, CRYPT_ARG_BOOL, {}, OPT_USE_TASKLETS_ACTIONS)
ARG(OPT_UUID, '\0', POPT_ARG_STRING, N_("UUID for device to use"), NULL, CRYPT_ARG_STRING, {}, {}) ARG(OPT_UUID, '\0', POPT_ARG_STRING, N_("UUID for device to use"), NULL, CRYPT_ARG_STRING, {}, {})
ARG(OPT_VERBOSE, 'v', POPT_ARG_NONE, N_("Shows more detailed error messages"), NULL, CRYPT_ARG_BOOL, {}, {}) ARG(OPT_VERBOSE, 'v', POPT_ARG_NONE, N_("Shows more detailed error messages"), NULL, CRYPT_ARG_BOOL, {}, {})

View File

@@ -39,6 +39,7 @@
#define OPT_PANIC_ON_CORRUPTION_ACTIONS { OPEN_ACTION } #define OPT_PANIC_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_ROOT_HASH_FILE_ACTIONS { FORMAT_ACTION, OPEN_ACTION, VERIFY_ACTION } #define OPT_ROOT_HASH_FILE_ACTIONS { FORMAT_ACTION, OPEN_ACTION, VERIFY_ACTION }
#define OPT_ROOT_HASH_SIGNATURE_ACTIONS { OPEN_ACTION } #define OPT_ROOT_HASH_SIGNATURE_ACTIONS { OPEN_ACTION }
#define OPT_USE_TASKLETS_ACTIONS { OPEN_ACTION }
enum { enum {
OPT_UNUSED_ID = 0, OPT_UNUSED_ID = 0,

View File

@@ -476,6 +476,11 @@ if check_version 1 3; then
if check_version 1 7; then if check_version 1 7; then
check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption" check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption"
fi fi
if check_version 1 9; then
echo "Verity data performance options test."
check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet"
fi
fi fi
echo "Veritysetup [hash-offset bigger than 2G works] " echo "Veritysetup [hash-offset bigger than 2G works] "