From 3062a9ba91333953829a8db994f82cc18b5b2955 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 15 Jul 2020 15:35:19 +0100 Subject: [PATCH] libcrypsetup: add CRYPT_DEACTIVATE_DEFERRED_CANCEL for crypt_deactivate_by_name Allows to cancel a previously set deferred deactivation flag for a specific device. [mbroz: slight changes] --- lib/libcryptsetup.h | 2 ++ lib/libdevmapper.c | 5 +++++ lib/setup.c | 12 +++++++++++- lib/utils_dm.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 6dd9da41..5886ee07 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -1351,6 +1351,8 @@ int crypt_activate_by_keyring(struct crypt_device *cd, #define CRYPT_DEACTIVATE_DEFERRED (1 << 0) /** force deactivation - if the device is busy, it is replaced by error device */ #define CRYPT_DEACTIVATE_FORCE (1 << 1) +/** if set, remove lazy deactivation */ +#define CRYPT_DEACTIVATE_DEFERRED_CANCEL (1 << 2) /** * Deactivate crypt device. This function tries to remove active device-mapper diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 8f8c94b5..8560d1e5 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -2942,6 +2942,11 @@ out: return r; } +int dm_cancel_deferred_removal(const char *name) +{ + return _dm_message(name, "@cancel_deferred_remove") ? 0 : -ENOTSUP; +} + const char *dm_get_dir(void) { return dm_dir(); diff --git a/lib/setup.c b/lib/setup.c index 2631fd73..389ae724 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -4474,6 +4474,9 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t if (!name) return -EINVAL; + if ((flags & CRYPT_DEACTIVATE_DEFERRED) && (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL)) + return -EINVAL; + log_dbg(cd, "Deactivating volume %s.", name); if (!cd) { @@ -4484,12 +4487,19 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t } /* skip holders detection and early abort when some flags raised */ - if (flags & (CRYPT_DEACTIVATE_FORCE | CRYPT_DEACTIVATE_DEFERRED)) + if (flags & (CRYPT_DEACTIVATE_FORCE | CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) get_flags &= ~DM_ACTIVE_HOLDERS; switch (crypt_status(cd, name)) { case CRYPT_ACTIVE: case CRYPT_BUSY: + if (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL) { + r = dm_cancel_deferred_removal(name); + if (r < 0) + log_err(cd, _("Could not cancel deferred remove from device %s."), name); + break; + } + r = dm_query_device(cd, name, get_flags, &dmd); if (r >= 0) { if (dmd.holders) { diff --git a/lib/utils_dm.h b/lib/utils_dm.h index 0cd543b0..ef48c0e0 100644 --- a/lib/utils_dm.h +++ b/lib/utils_dm.h @@ -220,6 +220,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name, const struct volume_key *vk); int dm_error_device(struct crypt_device *cd, const char *name); int dm_clear_device(struct crypt_device *cd, const char *name); +int dm_cancel_deferred_removal(const char *name); const char *dm_get_dir(void);