dm backend with support for multi-segment devices.

Support for multi-segment devices is requirement for online
reencryption to work. Introducing modififed dm backend that
splits data structures describing active device and individual
dm target (or segment).
This commit is contained in:
Ondrej Kozina
2015-10-02 17:21:10 +02:00
parent 1e22160e74
commit 39a014f601
12 changed files with 1219 additions and 772 deletions

View File

@@ -58,25 +58,15 @@ static int LUKS_endec_template(char *src, size_t srcLength,
char name[PATH_MAX], path[PATH_MAX];
char cipher_spec[MAX_CIPHER_LEN * 3];
struct crypt_dm_active_device dmd = {
.target = DM_CRYPT,
.uuid = NULL,
.flags = CRYPT_ACTIVATE_PRIVATE,
.data_device = crypt_metadata_device(ctx),
.u.crypt = {
.cipher = cipher_spec,
.vk = vk,
.offset = sector,
.iv_offset = 0,
.sector_size = SECTOR_SIZE,
}
.flags = CRYPT_ACTIVATE_PRIVATE,
};
int r, devfd = -1;
size_t bsize, keyslot_alignment, alignment;
log_dbg(ctx, "Using dmcrypt to access keyslot area.");
bsize = device_block_size(ctx, dmd.data_device);
alignment = device_alignment(dmd.data_device);
bsize = device_block_size(ctx, crypt_metadata_device(ctx));
alignment = device_alignment(crypt_metadata_device(ctx));
if (!bsize || !alignment)
return -EINVAL;
@@ -96,26 +86,33 @@ static int LUKS_endec_template(char *src, size_t srcLength,
if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, cipher_mode) < 0)
return -ENOMEM;
r = device_block_adjust(ctx, dmd.data_device, DEV_OK,
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
sector, &dmd.size, &dmd.flags);
if (r < 0) {
log_err(ctx, _("Device %s doesn't exist or access denied."),
device_path(dmd.data_device));
device_path(crypt_metadata_device(ctx)));
return -EIO;
}
if (mode != O_RDONLY && dmd.flags & CRYPT_ACTIVATE_READONLY) {
log_err(ctx, _("Cannot write to device %s, permission denied."),
device_path(dmd.data_device));
device_path(crypt_metadata_device(ctx)));
return -EACCES;
}
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size,
crypt_metadata_device(ctx), vk, cipher_spec, 0, sector,
NULL, 0, SECTOR_SIZE);
if (r)
goto out;
r = dm_create_device(ctx, name, "TEMP", &dmd);
if (r < 0) {
if (r != -EACCES && r != -ENOTSUP)
_error_hint(ctx, device_path(dmd.data_device),
_error_hint(ctx, device_path(crypt_metadata_device(ctx)),
cipher, cipher_mode, vk->keylength * 8);
return -EIO;
r = -EIO;
goto out;
}
devfd = open(path, mode | O_DIRECT | O_SYNC);
@@ -132,6 +129,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
} else
r = 0;
out:
dm_targets_free(ctx, &dmd);
if (devfd != -1)
close(devfd);
dm_remove_device(ctx, name, CRYPT_DEACTIVATE_FORCE);