[dm-devel] [PATCH v2 04/37] libmultipath: never allocate an alias that's already taken
mwilck at suse.com
mwilck at suse.com
Mon Sep 11 16:38:13 UTC 2023
From: Martin Wilck <mwilck at suse.com>
If the bindings file is changed in a way that multipathd can't handle
(e.g. by swapping the aliases of two maps), multipathd must not try
to re-use an alias that is already used by another map. Creating
or renaming a map with such an alias will fail. We already avoid
this for some cases, but not for all. Fix it.
Signed-off-by: Martin Wilck <mwilck at suse.com>
Cc: David Bond <dbond at suse.com>
---
libmultipath/alias.c | 33 ++++++++++++++++++++++++---------
tests/alias.c | 2 +-
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
index 68f5d84..b5248f2 100644
--- a/libmultipath/alias.c
+++ b/libmultipath/alias.c
@@ -120,7 +120,7 @@ static bool alias_already_taken(const char *alias, const char *map_wwid)
if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 &&
strncmp(map_wwid, wwid, sizeof(wwid)) == 0)
return false;
- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias",
+ condlog(3, "%s: alias '%s' already taken, reselecting alias",
map_wwid, alias);
return true;
}
@@ -359,32 +359,47 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al
rlookup_binding(f, buff, alias_old);
if (strlen(buff) > 0) {
- /* if buff is our wwid, it's already
- * allocated correctly
- */
+ /* If buff is our wwid, it's already allocated correctly. */
if (strcmp(buff, wwid) == 0) {
alias = strdup(alias_old);
goto out;
+
} else {
condlog(0, "alias %s already bound to wwid %s, cannot reuse",
alias_old, buff);
- goto new_alias;
+ goto new_alias; ;
}
}
- id = lookup_binding(f, wwid, &alias, NULL, 0);
+ /*
+ * Look for an existing alias in the bindings file.
+ * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id.
+ */
+ lookup_binding(f, wwid, &alias, NULL, 0);
if (alias) {
- condlog(3, "Use existing binding [%s] for WWID [%s]",
- alias, wwid);
+ if (alias_already_taken(alias, wwid)) {
+ free(alias);
+ alias = NULL;
+ } else
+ condlog(3, "Use existing binding [%s] for WWID [%s]",
+ alias, wwid);
goto out;
}
- /* allocate the existing alias in the bindings file */
+ /* alias_old is already taken by our WWID, update bindings file. */
id = scan_devname(alias_old, prefix);
new_alias:
if (id <= 0) {
+ /*
+ * no existing alias was provided, or allocating it
+ * failed. Try a new one.
+ */
id = lookup_binding(f, wwid, &alias, prefix, 1);
+ if (id == 0 && alias_already_taken(alias, wwid)) {
+ free(alias);
+ alias = NULL;
+ }
if (id <= 0)
goto out;
else
diff --git a/tests/alias.c b/tests/alias.c
index 3ca6c28..11f209e 100644
--- a/tests/alias.c
+++ b/tests/alias.c
@@ -398,7 +398,7 @@ static void mock_self_alias(const char *alias, const char *wwid)
will_return(__wrap_dm_get_uuid, wwid);
}
-#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n"
+#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n"
static void mock_failed_alias(const char *alias, char *msg)
{
--
2.42.0
More information about the dm-devel
mailing list