From 3faaa8b2275c847310dad152249072ac5e576ef1 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 22 Nov 2012 14:19:43 +0100 Subject: [PATCH] TCRYPT: support proper device removal --- lib/setup.c | 14 +++++++++++-- lib/tcrypt/tcrypt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ lib/tcrypt/tcrypt.h | 3 +++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/setup.c b/lib/setup.c index 9f8626f4..46db9a1c 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -750,6 +750,8 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) goto out; } } + } else if (isTCRYPT(cd->type)) { + //FIXME } out: crypt_free_volume_key(dmd.u.crypt.vk); @@ -855,6 +857,8 @@ int crypt_init_by_name_and_header(struct crypt_device **cd, (*cd)->type = strdup(CRYPT_LUKS1); else if (!strncmp(CRYPT_VERITY, dmd.uuid, sizeof(CRYPT_VERITY)-1)) (*cd)->type = strdup(CRYPT_VERITY); + else if (!strncmp(CRYPT_TCRYPT, dmd.uuid, sizeof(CRYPT_TCRYPT)-1)) + (*cd)->type = strdup(CRYPT_TCRYPT); else log_dbg("Unknown UUID set, some parameters are not set."); } else @@ -1301,7 +1305,10 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) r = 0; } else { dmd.size = new_size; - r = dm_create_device(cd, name, cd->type, &dmd, 1); + if (isTCRYPT(cd->type)) + r = -ENOTSUP; + else + r = dm_create_device(cd, name, cd->type, &dmd, 1); } out: if (dmd.target == DM_CRYPT) { @@ -2075,7 +2082,10 @@ int crypt_deactivate(struct crypt_device *cd, const char *name) switch (crypt_status(cd, name)) { case CRYPT_ACTIVE: case CRYPT_BUSY: - r = dm_remove_device(cd, name, 0, 0); + if (isTCRYPT(cd->type)) + r = TCRYPT_deactivate(cd, name); + else + r = dm_remove_device(cd, name, 0, 0); break; case CRYPT_INACTIVE: log_err(cd, _("Device %s is not active.\n"), name); diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index c88a7c35..a8c9a54a 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -573,3 +573,52 @@ int TCRYPT_activate(struct crypt_device *cd, crypt_free_volume_key(dmd.u.crypt.vk); return r; } + +static int remove_one(struct crypt_device *cd, const char *name, + const char *base_uuid, int index) +{ + struct crypt_dm_active_device dmd = {}; + char dm_name[PATH_MAX]; + int r; + + if (snprintf(dm_name, sizeof(dm_name), "%s_%d", name, index) < 0) + return -ENOMEM; + + r = dm_status_device(cd, dm_name); + if (r < 0) + return r; + + r = dm_query_device(cd, dm_name, DM_ACTIVE_UUID, &dmd); + if (!r && !strncmp(dmd.uuid, base_uuid, strlen(base_uuid))) + r = dm_remove_device(cd, dm_name, 0, 0); + + free(CONST_CAST(void*)dmd.uuid); + return r; +} + +int TCRYPT_deactivate(struct crypt_device *cd, const char *name) +{ + struct crypt_dm_active_device dmd = {}; + int r; + + r = dm_query_device(cd, name, DM_ACTIVE_UUID, &dmd); + if (r < 0) + return r; + if (!dmd.uuid) + return -EINVAL; + + r = dm_remove_device(cd, name, 0, 0); + if (r < 0) + goto out; + + r = remove_one(cd, name, dmd.uuid, 1); + if (r < 0) + goto out; + + r = remove_one(cd, name, dmd.uuid, 2); + if (r < 0) + goto out; +out: + free(CONST_CAST(void*)dmd.uuid); + return (r == -ENODEV) ? 0 : r; +} diff --git a/lib/tcrypt/tcrypt.h b/lib/tcrypt/tcrypt.h index e05e4683..e709314f 100644 --- a/lib/tcrypt/tcrypt.h +++ b/lib/tcrypt/tcrypt.h @@ -74,4 +74,7 @@ int TCRYPT_activate(struct crypt_device *cd, struct crypt_params_tcrypt *params, uint32_t flags); +int TCRYPT_deactivate(struct crypt_device *cd, + const char *name); + #endif