mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Split low level code for creating dm devices.
The separate code for reloading device tables will be used in later features.
This commit is contained in:
committed by
Milan Broz
parent
6e1e11f6cd
commit
120ebea917
@@ -237,7 +237,7 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dm_create_device(cd, name, "INTEGRITY", &dmdi, 0);
|
||||
r = dm_create_device(cd, name, "INTEGRITY", &dmdi);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
return -ENOTSUP;
|
||||
@@ -309,7 +309,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
if (params && params->integrity_key_size)
|
||||
dmdi.u.integrity.vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||
|
||||
r = dm_create_device(cd, tmp_name, "INTEGRITY", &dmdi, 0);
|
||||
r = dm_create_device(cd, tmp_name, "INTEGRITY", &dmdi);
|
||||
|
||||
crypt_free_volume_key(dmdi.u.integrity.vk);
|
||||
if (r)
|
||||
|
||||
@@ -900,6 +900,8 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _dm_resume_device(const char *name, uint32_t flags);
|
||||
|
||||
static int _error_device(const char *name, size_t size)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
@@ -923,7 +925,7 @@ static int _error_device(const char *name, size_t size)
|
||||
if (!dm_task_run(dmt))
|
||||
goto error;
|
||||
|
||||
if (!_dm_simple(DM_DEVICE_RESUME, name, 1)) {
|
||||
if (_dm_resume_device(name, 0)) {
|
||||
_dm_simple(DM_DEVICE_CLEAR, name, 0);
|
||||
goto error;
|
||||
}
|
||||
@@ -1051,16 +1053,14 @@ int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char
|
||||
static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
|
||||
struct device *device, uint32_t flags,
|
||||
const char *uuid, uint64_t size,
|
||||
dm_target_type target, char *params, int reload)
|
||||
dm_target_type target, char *params)
|
||||
{
|
||||
struct dm_task *dmt = NULL;
|
||||
struct dm_info dmi;
|
||||
char dev_uuid[DM_UUID_LEN] = {0};
|
||||
const char *target_name;
|
||||
int r = -EINVAL;
|
||||
uint32_t read_ahead = 0;
|
||||
uint32_t cookie = 0;
|
||||
uint32_t dmt_flags;
|
||||
uint32_t dmt_flags, cookie = 0, read_ahead = 0;
|
||||
uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
||||
|
||||
/* Only need DM_SECURE_SUPPORTED, no target specific fail matters */
|
||||
@@ -1082,74 +1082,49 @@ static int _dm_create_device(struct crypt_device *cd, const char *name, const ch
|
||||
udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
|
||||
|
||||
/* All devices must have DM_UUID, only resize on old device is exception */
|
||||
if (reload) {
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
|
||||
goto out_no_removal;
|
||||
if (!dm_prepare_uuid(cd, name, type, uuid, dev_uuid, sizeof(dev_uuid)))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out_no_removal;
|
||||
} else {
|
||||
if (!dm_prepare_uuid(cd, name, type, uuid, dev_uuid, sizeof(dev_uuid)))
|
||||
goto out_no_removal;
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
|
||||
goto out;
|
||||
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
|
||||
goto out_no_removal;
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out_no_removal;
|
||||
|
||||
if (!dm_task_set_uuid(dmt, dev_uuid))
|
||||
goto out_no_removal;
|
||||
}
|
||||
if (!dm_task_set_uuid(dmt, dev_uuid))
|
||||
goto out;
|
||||
|
||||
if ((dmt_flags & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
|
||||
goto out_no_removal;
|
||||
goto out;
|
||||
if ((flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
|
||||
goto out_no_removal;
|
||||
goto out;
|
||||
|
||||
if (!dm_task_add_target(dmt, 0, size, target_name, params))
|
||||
goto out_no_removal;
|
||||
goto out;
|
||||
|
||||
#ifdef DM_READ_AHEAD_MINIMUM_FLAG
|
||||
if (device_read_ahead(device, &read_ahead) &&
|
||||
!dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
|
||||
goto out_no_removal;
|
||||
goto out;
|
||||
#endif
|
||||
/* do not set cookie for DM_DEVICE_RELOAD task */
|
||||
if (!reload && _dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out_no_removal;
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
goto out_no_removal;
|
||||
|
||||
if (reload) {
|
||||
dm_task_destroy(dmt);
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
|
||||
goto out;
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
|
||||
goto out;
|
||||
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dm_task_get_info(dmt, &dmi))
|
||||
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
|
||||
if (dm_task_get_info(dmt, &dmi))
|
||||
r = 0;
|
||||
|
||||
if (_dm_use_udev()) {
|
||||
(void)_dm_udev_wait(cookie);
|
||||
cookie = 0;
|
||||
}
|
||||
|
||||
if (r < 0 && !reload)
|
||||
if (r < 0)
|
||||
_dm_remove(name, 1, 0);
|
||||
|
||||
out_no_removal:
|
||||
out:
|
||||
if (cookie && _dm_use_udev())
|
||||
(void)_dm_udev_wait(cookie);
|
||||
|
||||
@@ -1164,6 +1139,96 @@ out_no_removal:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _dm_resume_device(const char *name, uint32_t flags)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
int r = -EINVAL;
|
||||
uint32_t cookie = 0;
|
||||
uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_PRIVATE)
|
||||
udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
|
||||
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
|
||||
return r;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
|
||||
if (dm_task_run(dmt))
|
||||
r = 0;
|
||||
out:
|
||||
if (cookie && _dm_use_udev())
|
||||
(void)_dm_udev_wait(cookie);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
dm_task_update_nodes();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _dm_reload_device(struct crypt_device *cd,
|
||||
const char *name, struct device *device,
|
||||
uint32_t flags, uint64_t size,
|
||||
dm_target_type target, const char *params)
|
||||
{
|
||||
const char *target_name;
|
||||
int r = -EINVAL;
|
||||
struct dm_task *dmt = NULL;
|
||||
uint32_t dmt_flags = 0, read_ahead = 0;
|
||||
|
||||
if (target == DM_CRYPT)
|
||||
target_name = DM_CRYPT_TARGET;
|
||||
else if (target == DM_VERITY)
|
||||
target_name = DM_VERITY_TARGET;
|
||||
else if (target == DM_INTEGRITY)
|
||||
target_name = DM_INTEGRITY_TARGET;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
/* All devices must have DM_UUID, only resize on old device is exception */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
if (dm_flags(cd, target, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if ((dmt_flags & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
|
||||
goto out;
|
||||
|
||||
/* FIXME: resume only ?*/
|
||||
if ((flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_add_target(dmt, 0, size, target_name, params))
|
||||
goto out;
|
||||
|
||||
#ifdef DM_READ_AHEAD_MINIMUM_FLAG
|
||||
if (device_read_ahead(device, &read_ahead) &&
|
||||
!dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
if (dm_task_run(dmt))
|
||||
r = 0;
|
||||
|
||||
out:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
/* If code just loaded target module, update versions */
|
||||
_dm_check_versions(cd, target);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1197,8 +1262,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
|
||||
int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
int reload)
|
||||
struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
char *table_params = NULL;
|
||||
uint32_t dmd_flags, dmt_flags;
|
||||
@@ -1223,16 +1287,16 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
goto out;
|
||||
|
||||
r = _dm_create_device(cd, name, type, dmd->data_device, dmd_flags,
|
||||
dmd->uuid, dmd->size, dmd->target, table_params, reload);
|
||||
dmd->uuid, dmd->size, dmd->target, table_params);
|
||||
|
||||
if (r < 0 && dm_flags(cd, dmd->target, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if (!reload && r && dmd->target == DM_CRYPT && check_retry(cd, &dmd_flags, dmt_flags)) {
|
||||
if (r && dmd->target == DM_CRYPT && check_retry(cd, &dmd_flags, dmt_flags)) {
|
||||
crypt_safe_free(table_params);
|
||||
table_params = get_dm_crypt_params(dmd, dmd_flags);
|
||||
r = _dm_create_device(cd, name, type, dmd->data_device, dmd_flags,
|
||||
dmd->uuid, dmd->size, dmd->target, table_params, reload);
|
||||
dmd->uuid, dmd->size, dmd->target, table_params);
|
||||
}
|
||||
|
||||
if (r == -EINVAL &&
|
||||
@@ -1263,6 +1327,46 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_reload_device(struct crypt_device *cd, const char *name,
|
||||
struct crypt_dm_active_device *dmd, unsigned resume)
|
||||
{
|
||||
char *table_params = NULL;
|
||||
uint32_t dmt_flags;
|
||||
int r = -EINVAL;
|
||||
|
||||
if (dm_init_context(cd, dmd->target))
|
||||
return -ENOTSUP;
|
||||
|
||||
dm_flags(cd, dmd->target, &dmt_flags);
|
||||
|
||||
if (dmd->target == DM_CRYPT)
|
||||
table_params = get_dm_crypt_params(dmd, dmd->flags);
|
||||
else if (dmd->target == DM_VERITY)
|
||||
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd, dmd->flags);
|
||||
else if (dmd->target == DM_INTEGRITY)
|
||||
table_params = get_dm_integrity_params(dmd, dmd->flags, dmt_flags);
|
||||
else
|
||||
return r;
|
||||
|
||||
r = _dm_reload_device(cd, name, dmd->data_device, dmd->flags, dmd->size,
|
||||
dmd->target, table_params);
|
||||
|
||||
if (r == -EINVAL && dmd->target == DM_CRYPT) {
|
||||
if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
}
|
||||
|
||||
if (!r && resume)
|
||||
r = _dm_resume_device(name, dmd->flags);
|
||||
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
const char *target, char **status_line)
|
||||
{
|
||||
@@ -2138,7 +2242,7 @@ int dm_suspend_and_wipe_key(struct crypt_device *cd, const char *name)
|
||||
}
|
||||
|
||||
if (!_dm_message(name, "key wipe", dmt_flags)) {
|
||||
_dm_simple(DM_DEVICE_RESUME, name, 1);
|
||||
_dm_resume_device(name, 0);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2180,7 +2284,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
hex_key(&msg[8], vk->keylength, vk->key);
|
||||
|
||||
if (!_dm_message(name, msg, dmt_flags) ||
|
||||
!_dm_simple(DM_DEVICE_RESUME, name, 1)) {
|
||||
_dm_resume_device(name, 0)) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
log_dbg(cd, "Trying to activate loop-AES device %s using cipher %s.",
|
||||
name, dmd.u.crypt.cipher);
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_LOOPAES, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_LOOPAES, &dmd);
|
||||
|
||||
if (r < 0 && !dm_flags(cd, DM_CRYPT, &dmc_flags) &&
|
||||
(dmc_flags & req_flags) != req_flags) {
|
||||
|
||||
@@ -110,7 +110,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
r = dm_create_device(ctx, name, "TEMP", &dmd, 0);
|
||||
r = dm_create_device(ctx, name, "TEMP", &dmd);
|
||||
if (r < 0) {
|
||||
if (r != -EACCES && r != -ENOTSUP)
|
||||
_error_hint(ctx, device_path(dmd.data_device),
|
||||
|
||||
@@ -1189,7 +1189,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
return -ENOMEM;
|
||||
|
||||
dmd.u.crypt.cipher = dm_cipher;
|
||||
r = dm_create_device(cd, name, CRYPT_LUKS1, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_LUKS1, &dmd);
|
||||
|
||||
free(dm_cipher);
|
||||
return r;
|
||||
|
||||
@@ -1934,7 +1934,7 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
r = device_block_adjust(cd, dmd.data_device, device_check,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (!r)
|
||||
r = dm_create_device(cd, name, CRYPT_LUKS2, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_LUKS2, &dmd);
|
||||
|
||||
if (r < 0 && dmd.u.crypt.integrity)
|
||||
dm_remove_device(cd, dm_int_name, 0);
|
||||
|
||||
@@ -517,7 +517,7 @@ int PLAIN_activate(struct crypt_device *cd,
|
||||
log_dbg(cd, "Trying to activate PLAIN device %s using cipher %s.",
|
||||
name, dmd.u.crypt.cipher);
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_PLAIN, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_PLAIN, &dmd);
|
||||
|
||||
free(dm_cipher);
|
||||
return r;
|
||||
@@ -2211,7 +2211,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
else if (isLUKS2(cd->type))
|
||||
r = LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, 0);
|
||||
if (!r)
|
||||
r = dm_create_device(cd, name, cd->type, &dmd, 1);
|
||||
r = dm_reload_device(cd, name, &dmd, 1);
|
||||
}
|
||||
out:
|
||||
if (dmd.target == DM_CRYPT) {
|
||||
|
||||
@@ -846,7 +846,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
|
||||
log_dbg(cd, "Trying to activate TCRYPT device %s using cipher %s.",
|
||||
dm_name, dmd.u.crypt.cipher);
|
||||
r = dm_create_device(cd, dm_name, CRYPT_TCRYPT, &dmd, 0);
|
||||
r = dm_create_device(cd, dm_name, CRYPT_TCRYPT, &dmd);
|
||||
|
||||
device_free(cd, device);
|
||||
device = NULL;
|
||||
|
||||
@@ -139,8 +139,9 @@ int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint
|
||||
int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
uint32_t get_flags, struct crypt_dm_active_device *dmd);
|
||||
int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
const char *type, struct crypt_dm_active_device *dmd,
|
||||
int reload);
|
||||
const char *type, struct crypt_dm_active_device *dmd);
|
||||
int dm_reload_device(struct crypt_device *cd, const char *name,
|
||||
struct crypt_dm_active_device *dmd, unsigned resume);
|
||||
int dm_suspend_device(struct crypt_device *cd, const char *name);
|
||||
int dm_suspend_and_wipe_key(struct crypt_device *cd, const char *name);
|
||||
int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
|
||||
@@ -303,7 +303,7 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_VERITY, &dmv_flags) || !(dmv_flags & DM_VERITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-verity mapping."));
|
||||
return -ENOTSUP;
|
||||
|
||||
Reference in New Issue
Block a user