From 9c2d918474c17be0ea143390a821f517f04f790f Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sat, 8 Aug 2020 20:54:07 +0100 Subject: [PATCH] libdevmapper: always return EEXIST if a task fails because the device already exists Allows concurrent opens to return a usable error instead of EINVAL --- lib/libdevmapper.c | 12 +++++++++++- lib/setup.c | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index a82163b0..0906bd72 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -1305,6 +1305,12 @@ err: return r; } +static bool dm_device_exists(struct crypt_device *cd, const char *name) +{ + int r = dm_status_device(cd, name); + return (r >= 0 || r == -EEXIST); +} + static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type, const char *uuid, struct crypt_dm_active_device *dmd) { @@ -1354,8 +1360,11 @@ static int _dm_create_device(struct crypt_device *cd, const char *name, const ch if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags)) goto out; - if (!dm_task_run(dmt)) + if (!dm_task_run(dmt)) { + if (dm_device_exists(cd, name)) + r = -EEXIST; goto out; + } if (dm_task_get_info(dmt, &dmi)) r = 0; @@ -1720,6 +1729,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi, goto out; } + r = -EEXIST; dm_get_next_target(dmt, NULL, &start, &length, &target_type, ¶ms); diff --git a/lib/setup.c b/lib/setup.c index 52b472a1..d8e665c0 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -4161,21 +4161,26 @@ static int _activate_loopaes(struct crypt_device *cd, static int _activate_check_status(struct crypt_device *cd, const char *name, unsigned reload) { - crypt_status_info ci; + int r; if (!name) return 0; - ci = crypt_status(cd, name); - if (ci == CRYPT_INVALID) { - log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name); - return -EINVAL; - } else if (ci >= CRYPT_ACTIVE && !reload) { + r = dm_status_device(cd, name); + + if (r >= 0 && reload) + return 0; + + if (r >= 0 || r == -EEXIST) { log_err(cd, _("Device %s already exists."), name); return -EEXIST; } - return 0; + if (r == -ENODEV) + return 0; + + log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name); + return r; } // activation/deactivation of device mapping