You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.7 KiB
150 lines
4.7 KiB
From 2e4aaa1adad2d0838593b13efbf5efe79f58255c Mon Sep 17 00:00:00 2001 |
|
From: Ondrej Kozina <okozina@redhat.com> |
|
Date: Mon, 16 Oct 2017 16:41:43 +0200 |
|
Subject: [PATCH] crypt_deactivate: fail earlier when holders detected |
|
|
|
crypt_deactivate fails earlier without noisy dm retries |
|
when other device holders detected. The early detection |
|
works if: |
|
|
|
a) other device-mapper device has a hold reference on the |
|
device |
|
|
|
- or - |
|
|
|
b) mounted fs is detected on the device |
|
|
|
diff -rupN cryptsetup-1.7.4.old/config.h.in cryptsetup-1.7.4/config.h.in |
|
--- cryptsetup-1.7.4.old/config.h.in 2017-03-15 10:43:26.000000000 +0100 |
|
+++ cryptsetup-1.7.4/config.h.in 2017-10-19 09:37:17.000000000 +0200 |
|
@@ -97,6 +97,14 @@ |
|
*/ |
|
#undef HAVE_DCGETTEXT |
|
|
|
+/* Define to 1 if you have the declaration of `dm_device_has_holders', and to |
|
+ 0 if you don't. */ |
|
+#undef HAVE_DECL_DM_DEVICE_HAS_HOLDERS |
|
+ |
|
+/* Define to 1 if you have the declaration of `dm_device_has_mounted_fs', and |
|
+ to 0 if you don't. */ |
|
+#undef HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS |
|
+ |
|
/* Define to 1 if you have the declaration of `dm_task_retry_remove', and to 0 |
|
if you don't. */ |
|
#undef HAVE_DECL_DM_TASK_RETRY_REMOVE |
|
diff -rupN cryptsetup-1.7.4.old/configure cryptsetup-1.7.4/configure |
|
--- cryptsetup-1.7.4.old/configure 2017-03-15 10:43:13.000000000 +0100 |
|
+++ cryptsetup-1.7.4/configure 2017-10-19 09:37:18.590530138 +0200 |
|
@@ -16735,6 +16735,30 @@ cat >>confdefs.h <<_ACEOF |
|
#define HAVE_DECL_DM_TASK_RETRY_REMOVE $ac_have_decl |
|
_ACEOF |
|
|
|
+ac_fn_c_check_decl "$LINENO" "dm_device_has_mounted_fs" "ac_cv_have_decl_dm_device_has_mounted_fs" "#include <libdevmapper.h> |
|
+" |
|
+if test "x$ac_cv_have_decl_dm_device_has_mounted_fs" = xyes; then : |
|
+ ac_have_decl=1 |
|
+else |
|
+ ac_have_decl=0 |
|
+fi |
|
+ |
|
+cat >>confdefs.h <<_ACEOF |
|
+#define HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS $ac_have_decl |
|
+_ACEOF |
|
+ |
|
+ac_fn_c_check_decl "$LINENO" "dm_device_has_holders" "ac_cv_have_decl_dm_device_has_holders" "#include <libdevmapper.h> |
|
+" |
|
+if test "x$ac_cv_have_decl_dm_device_has_holders" = xyes; then : |
|
+ ac_have_decl=1 |
|
+else |
|
+ ac_have_decl=0 |
|
+fi |
|
+ |
|
+cat >>confdefs.h <<_ACEOF |
|
+#define HAVE_DECL_DM_DEVICE_HAS_HOLDERS $ac_have_decl |
|
+_ACEOF |
|
+ |
|
ac_fn_c_check_decl "$LINENO" "DM_UDEV_DISABLE_DISK_RULES_FLAG" "ac_cv_have_decl_DM_UDEV_DISABLE_DISK_RULES_FLAG" "#include <libdevmapper.h> |
|
" |
|
if test "x$ac_cv_have_decl_DM_UDEV_DISABLE_DISK_RULES_FLAG" = xyes; then : |
|
diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c |
|
index a0d6872..d6017b1 100644 |
|
--- a/lib/libdevmapper.c |
|
+++ b/lib/libdevmapper.c |
|
@@ -1181,6 +1181,13 @@ int dm_query_device(struct crypt_device *cd, const char *name, |
|
dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN); |
|
} |
|
|
|
+ dmd->holders = 0; |
|
+#if (HAVE_DECL_DM_DEVICE_HAS_HOLDERS && HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS) |
|
+ if (get_flags & DM_ACTIVE_HOLDERS) |
|
+ dmd->holders = (dm_device_has_mounted_fs(dmi.major, dmi.minor) || |
|
+ dm_device_has_holders(dmi.major, dmi.minor)); |
|
+#endif |
|
+ |
|
r = (dmi.open_count > 0); |
|
out: |
|
if (dmt) |
|
diff --git a/lib/setup.c b/lib/setup.c |
|
index b2e4396..93e8079 100644 |
|
--- a/lib/setup.c |
|
+++ b/lib/setup.c |
|
@@ -2249,6 +2249,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, |
|
int crypt_deactivate(struct crypt_device *cd, const char *name) |
|
{ |
|
struct crypt_device *fake_cd = NULL; |
|
+ struct crypt_dm_active_device dmd = {}; |
|
int r; |
|
|
|
if (!name) |
|
@@ -2266,6 +2267,13 @@ int crypt_deactivate(struct crypt_device *cd, const char *name) |
|
switch (crypt_status(cd, name)) { |
|
case CRYPT_ACTIVE: |
|
case CRYPT_BUSY: |
|
+ r = dm_query_device(cd, name, DM_ACTIVE_HOLDERS, &dmd); |
|
+ if (r >= 0 && dmd.holders) { |
|
+ log_err(cd, _("Device %s is still in use.\n"), name); |
|
+ r = -EBUSY; |
|
+ break; |
|
+ } |
|
+ |
|
if (isTCRYPT(cd->type)) |
|
r = TCRYPT_deactivate(cd, name); |
|
else |
|
diff --git a/lib/utils_dm.h b/lib/utils_dm.h |
|
index c87e9aa..cf22e12 100644 |
|
--- a/lib/utils_dm.h |
|
+++ b/lib/utils_dm.h |
|
@@ -48,14 +48,16 @@ uint32_t dm_flags(void); |
|
|
|
#define DM_ACTIVE_DEVICE (1 << 0) |
|
#define DM_ACTIVE_UUID (1 << 1) |
|
+#define DM_ACTIVE_HOLDERS (1 << 2) |
|
|
|
-#define DM_ACTIVE_CRYPT_CIPHER (1 << 2) |
|
-#define DM_ACTIVE_CRYPT_KEYSIZE (1 << 3) |
|
-#define DM_ACTIVE_CRYPT_KEY (1 << 4) |
|
+#define DM_ACTIVE_CRYPT_CIPHER (1 << 3) |
|
+#define DM_ACTIVE_CRYPT_KEYSIZE (1 << 4) |
|
+#define DM_ACTIVE_CRYPT_KEY (1 << 5) |
|
+ |
|
+#define DM_ACTIVE_VERITY_ROOT_HASH (1 << 6) |
|
+#define DM_ACTIVE_VERITY_HASH_DEVICE (1 << 7) |
|
+#define DM_ACTIVE_VERITY_PARAMS (1 << 8) |
|
|
|
-#define DM_ACTIVE_VERITY_ROOT_HASH (1 << 5) |
|
-#define DM_ACTIVE_VERITY_HASH_DEVICE (1 << 6) |
|
-#define DM_ACTIVE_VERITY_PARAMS (1 << 7) |
|
|
|
struct crypt_dm_active_device { |
|
enum { DM_CRYPT = 0, DM_VERITY } target; |
|
@@ -63,6 +65,7 @@ struct crypt_dm_active_device { |
|
uint32_t flags; /* activation flags */ |
|
const char *uuid; |
|
struct device *data_device; |
|
+ unsigned holders:1; |
|
union { |
|
struct { |
|
const char *cipher; |
|
-- |
|
1.8.3.1 |
|
|
|
|