device-mapper-multipath-0.9.6-1
Update to the head of the upstream staging branch Rename redhat patches * Previous patches 0001-0012 are now patches 0041-0052 Add 0053-RH-Add-mpathcleanup.patch * add mpathcleanup program
This commit is contained in:
parent
d88fe4b956
commit
e5eddaae1a
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,3 +28,4 @@ multipath-tools-091027.tar.gz
|
||||
/multipath-tools-0.9.3.tgz
|
||||
/multipath-tools-0.9.4.tgz
|
||||
/multipath-tools-0.9.5.tgz
|
||||
/multipath-tools-0.9.6.tgz
|
||||
|
@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 16:21:43 +0200
|
||||
Subject: [PATCH] libmultipath: sysfs_set_scsi_tmo: do nothing for ACT_DRY_RUN
|
||||
|
||||
"multipath -d" might change sysfs timeouts of SCSI devices.
|
||||
Make sure it doesn't.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Jehan Singh <jehan.singh@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 4 ++--
|
||||
libmultipath/discovery.c | 3 +++
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 9513baae..029fbbd2 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1193,13 +1193,13 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
|
||||
if (cmpp)
|
||||
mpp->queue_mode = cmpp->queue_mode;
|
||||
+ if (cmd == CMD_DRY_RUN && mpp->action == ACT_UNDEF)
|
||||
+ mpp->action = ACT_DRY_RUN;
|
||||
if (setup_map(mpp, ¶ms, vecs)) {
|
||||
remove_map(mpp, vecs->pathvec, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (cmd == CMD_DRY_RUN)
|
||||
- mpp->action = ACT_DRY_RUN;
|
||||
if (mpp->action == ACT_UNDEF)
|
||||
select_action(mpp, curmp,
|
||||
force_reload == FORCE_RELOAD_YES ? 1 : 0);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index e4de48e7..84ce5fe7 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -857,6 +857,9 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
|
||||
bool warn_dev_loss = false;
|
||||
bool warn_fast_io_fail = false;
|
||||
|
||||
+ if (mpp->action == ACT_DRY_RUN || mpp->action == ACT_REJECT)
|
||||
+ return 0;
|
||||
+
|
||||
if (mpp->no_path_retry > 0) {
|
||||
uint64_t no_path_retry_tmo =
|
||||
(uint64_t)mpp->no_path_retry * conf->checkint;
|
75
0002-libmultipath-add-alias_already_taken.patch
Normal file
75
0002-libmultipath-add-alias_already_taken.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 21:36:11 +0200
|
||||
Subject: [PATCH] libmultipath: add alias_already_taken()
|
||||
|
||||
Factor out a trivial helper function.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 32 +++++++++++++++++++-------------
|
||||
1 file changed, 19 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index c0139a2e..83ded886 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
+#include <stdbool.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
@@ -109,30 +110,35 @@ scan_devname(const char *alias, const char *prefix)
|
||||
return n;
|
||||
}
|
||||
|
||||
-static int
|
||||
-id_already_taken(int id, const char *prefix, const char *map_wwid)
|
||||
+static bool alias_already_taken(const char *alias, const char *map_wwid)
|
||||
{
|
||||
- STRBUF_ON_STACK(buf);
|
||||
- const char *alias;
|
||||
-
|
||||
- if (append_strbuf_str(&buf, prefix) < 0 ||
|
||||
- format_devname(&buf, id) < 0)
|
||||
- return 0;
|
||||
|
||||
- alias = get_strbuf_str(&buf);
|
||||
if (dm_map_present(alias)) {
|
||||
char wwid[WWID_SIZE];
|
||||
|
||||
/* If both the name and the wwid match, then it's fine.*/
|
||||
if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 &&
|
||||
strncmp(map_wwid, wwid, sizeof(wwid)) == 0)
|
||||
- return 0;
|
||||
- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias);
|
||||
- return 1;
|
||||
+ return false;
|
||||
+ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias",
|
||||
+ map_wwid, alias);
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
+static bool id_already_taken(int id, const char *prefix, const char *map_wwid)
|
||||
+{
|
||||
+ STRBUF_ON_STACK(buf);
|
||||
+ const char *alias;
|
||||
+
|
||||
+ if (append_strbuf_str(&buf, prefix) < 0 ||
|
||||
+ format_devname(&buf, id) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ alias = get_strbuf_str(&buf);
|
||||
+ return alias_already_taken(alias, map_wwid);
|
||||
+}
|
||||
|
||||
/*
|
||||
* Returns: 0 if matching entry in WWIDs file found
|
207
0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch
Normal file
207
0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch
Normal file
@ -0,0 +1,207 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 22:00:58 +0200
|
||||
Subject: [PATCH] libmultipath: unify use_existing_alias() and
|
||||
get_user_friendly_alias()
|
||||
|
||||
These functions are only called from select_alias(). The logic
|
||||
is more obvious when unified in a single function.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 82 ++++++++++++------------------------------
|
||||
libmultipath/alias.h | 9 ++---
|
||||
libmultipath/propsel.c | 19 +++++-----
|
||||
3 files changed, 34 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 83ded886..68f5d848 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -329,13 +329,13 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix)
|
||||
return alias;
|
||||
}
|
||||
|
||||
-char *
|
||||
-use_existing_alias (const char *wwid, const char *file, const char *alias_old,
|
||||
- const char *prefix, int bindings_read_only)
|
||||
+char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old,
|
||||
+ const char *prefix, bool bindings_read_only)
|
||||
{
|
||||
char *alias = NULL;
|
||||
int id = 0;
|
||||
int fd, can_write;
|
||||
+ bool new_binding = false;
|
||||
char buff[WWID_SIZE];
|
||||
FILE *f;
|
||||
|
||||
@@ -349,6 +349,10 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old,
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
+ if (!strlen(alias_old))
|
||||
+ goto new_alias;
|
||||
+
|
||||
/* lookup the binding. if it exists, the wwid will be in buff
|
||||
* either way, id contains the id for the alias
|
||||
*/
|
||||
@@ -358,14 +362,14 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old,
|
||||
/* if buff is our wwid, it's already
|
||||
* allocated correctly
|
||||
*/
|
||||
- if (strcmp(buff, wwid) == 0)
|
||||
+ if (strcmp(buff, wwid) == 0) {
|
||||
alias = strdup(alias_old);
|
||||
- else {
|
||||
- alias = NULL;
|
||||
+ goto out;
|
||||
+ } else {
|
||||
condlog(0, "alias %s already bound to wwid %s, cannot reuse",
|
||||
alias_old, buff);
|
||||
+ goto new_alias;
|
||||
}
|
||||
- goto out;
|
||||
}
|
||||
|
||||
id = lookup_binding(f, wwid, &alias, NULL, 0);
|
||||
@@ -377,8 +381,15 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old,
|
||||
|
||||
/* allocate the existing alias in the bindings file */
|
||||
id = scan_devname(alias_old, prefix);
|
||||
- if (id <= 0)
|
||||
- goto out;
|
||||
+
|
||||
+new_alias:
|
||||
+ if (id <= 0) {
|
||||
+ id = lookup_binding(f, wwid, &alias, prefix, 1);
|
||||
+ if (id <= 0)
|
||||
+ goto out;
|
||||
+ else
|
||||
+ new_binding = true;
|
||||
+ }
|
||||
|
||||
if (fflush(f) != 0) {
|
||||
condlog(0, "cannot fflush bindings file stream : %s",
|
||||
@@ -388,8 +399,9 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old,
|
||||
|
||||
if (can_write && !bindings_read_only) {
|
||||
alias = allocate_binding(fd, wwid, id, prefix);
|
||||
- condlog(0, "Allocated existing binding [%s] for WWID [%s]",
|
||||
- alias, wwid);
|
||||
+ if (alias && !new_binding)
|
||||
+ condlog(2, "Allocated existing binding [%s] for WWID [%s]",
|
||||
+ alias, wwid);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -399,54 +411,6 @@ out:
|
||||
return alias;
|
||||
}
|
||||
|
||||
-char *
|
||||
-get_user_friendly_alias(const char *wwid, const char *file, const char *prefix,
|
||||
- int bindings_read_only)
|
||||
-{
|
||||
- char *alias;
|
||||
- int fd, id;
|
||||
- FILE *f;
|
||||
- int can_write;
|
||||
-
|
||||
- if (!wwid || *wwid == '\0') {
|
||||
- condlog(3, "Cannot find binding for empty WWID");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- fd = open_file(file, &can_write, bindings_file_header);
|
||||
- if (fd < 0)
|
||||
- return NULL;
|
||||
-
|
||||
- f = fdopen(fd, "r");
|
||||
- if (!f) {
|
||||
- condlog(0, "cannot fdopen on bindings file descriptor : %s",
|
||||
- strerror(errno));
|
||||
- close(fd);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- id = lookup_binding(f, wwid, &alias, prefix, 1);
|
||||
- if (id < 0) {
|
||||
- fclose(f);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- pthread_cleanup_push(free, alias);
|
||||
-
|
||||
- if (fflush(f) != 0) {
|
||||
- condlog(0, "cannot fflush bindings file stream : %s",
|
||||
- strerror(errno));
|
||||
- free(alias);
|
||||
- alias = NULL;
|
||||
- } else if (can_write && !bindings_read_only && !alias)
|
||||
- alias = allocate_binding(fd, wwid, id, prefix);
|
||||
-
|
||||
- fclose(f);
|
||||
-
|
||||
- pthread_cleanup_pop(0);
|
||||
- return alias;
|
||||
-}
|
||||
-
|
||||
int
|
||||
get_user_friendly_wwid(const char *alias, char *buff, const char *file)
|
||||
{
|
||||
diff --git a/libmultipath/alias.h b/libmultipath/alias.h
|
||||
index dbc950c4..fa332233 100644
|
||||
--- a/libmultipath/alias.h
|
||||
+++ b/libmultipath/alias.h
|
||||
@@ -2,13 +2,10 @@
|
||||
#define _ALIAS_H
|
||||
|
||||
int valid_alias(const char *alias);
|
||||
-char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
- const char *prefix,
|
||||
- int bindings_readonly);
|
||||
int get_user_friendly_wwid(const char *alias, char *buff, const char *file);
|
||||
-char *use_existing_alias (const char *wwid, const char *file,
|
||||
- const char *alias_old,
|
||||
- const char *prefix, int bindings_read_only);
|
||||
+char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
+ const char *alias_old,
|
||||
+ const char *prefix, bool bindings_read_only);
|
||||
|
||||
struct config;
|
||||
int check_alias_settings(const struct config *);
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index d6bce129..354e883f 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -401,19 +401,16 @@ int select_alias(struct config *conf, struct multipath * mp)
|
||||
|
||||
select_alias_prefix(conf, mp);
|
||||
|
||||
- if (strlen(mp->alias_old) > 0) {
|
||||
- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
|
||||
- mp->alias_old, mp->alias_prefix,
|
||||
- conf->bindings_read_only);
|
||||
- memset (mp->alias_old, 0, WWID_SIZE);
|
||||
- origin = "(setting: using existing alias)";
|
||||
- }
|
||||
+ mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file,
|
||||
+ mp->alias_old, mp->alias_prefix,
|
||||
+ conf->bindings_read_only);
|
||||
|
||||
- if (mp->alias == NULL) {
|
||||
- mp->alias = get_user_friendly_alias(mp->wwid,
|
||||
- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
|
||||
+ if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE))
|
||||
+ origin = "(setting: using existing alias)";
|
||||
+ else if (mp->alias)
|
||||
origin = "(setting: user_friendly_name)";
|
||||
- }
|
||||
+ memset (mp->alias_old, 0, WWID_SIZE);
|
||||
+
|
||||
out:
|
||||
if (mp->alias == NULL) {
|
||||
mp->alias = strdup(mp->wwid);
|
101
0004-libmultipath-never-allocate-an-alias-that-s-already-.patch
Normal file
101
0004-libmultipath-never-allocate-an-alias-that-s-already-.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 22:23:29 +0200
|
||||
Subject: [PATCH] libmultipath: never allocate an alias that's already taken
|
||||
|
||||
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@suse.com>
|
||||
Cc: David Bond <dbond@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 31 +++++++++++++++++++++++--------
|
||||
tests/alias.c | 2 +-
|
||||
2 files changed, 24 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 68f5d848..3e3dfe98 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,12 +359,11 @@ 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);
|
||||
@@ -372,19 +371,35 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al
|
||||
}
|
||||
}
|
||||
|
||||
- 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 3ca6c28b..11f209e0 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)
|
||||
{
|
@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 22:30:16 +0200
|
||||
Subject: [PATCH] libmultipath: lookup_binding: add comment about the algorithm
|
||||
|
||||
When I read this code, I always get confused. Adding comments to
|
||||
explain the algorithm.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 3e3dfe98..9e9ac563 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -172,6 +172,41 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias,
|
||||
alias = strtok_r(buf, " \t", &saveptr);
|
||||
if (!alias) /* blank line */
|
||||
continue;
|
||||
+
|
||||
+ /*
|
||||
+ * Find an unused index - explanation of the algorithm
|
||||
+ *
|
||||
+ * ID: 1 = mpatha, 2 = mpathb, ...
|
||||
+ *
|
||||
+ * We assume the bindings are unsorted. The only constraint
|
||||
+ * is that no ID occurs more than once. IDs that occur in the
|
||||
+ * bindings are called "used".
|
||||
+ *
|
||||
+ * We call the list 1,2,3,..., exactly in this order, the list
|
||||
+ * of "expected" IDs. The variable "id" always holds the next
|
||||
+ * "expected" ID, IOW the last "expected" ID encountered plus 1.
|
||||
+ * Thus all IDs below "id" are known to be used. However, at the
|
||||
+ * end of the loop, the value of "id" isn't necessarily unused.
|
||||
+ *
|
||||
+ * "smallest_bigger_id" is the smallest used ID that was
|
||||
+ * encountered while it was larger than the next "expected" ID
|
||||
+ * at that iteration. Let X be some used ID. If all IDs below X
|
||||
+ * are used and encountered in the right sequence before X, "id"
|
||||
+ * will be > X when the loop ends. Otherwise, X was encountered
|
||||
+ * "out of order", the condition (X > id) holds when X is
|
||||
+ * encountered, and "smallest_bigger_id" will be set to X; i.e.
|
||||
+ * it will be less or equal than X when the loop ends.
|
||||
+ *
|
||||
+ * At the end of the loop, (id < smallest_bigger_id) means that
|
||||
+ * the value of "id" had been encountered neither in order nor
|
||||
+ * out of order, and is thus unused. (id >= smallest_bigger_id)
|
||||
+ * means that "id"'s value is in use. In this case, we play safe
|
||||
+ * and use "biggest_id + 1" as the next value to try.
|
||||
+ *
|
||||
+ * biggest_id is always > smallest_bigger_id, except in the
|
||||
+ * "perfectly ordered" case.
|
||||
+ */
|
||||
+
|
||||
curr_id = scan_devname(alias, prefix);
|
||||
if (curr_id == id) {
|
||||
if (id < INT_MAX)
|
@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Aug 2023 22:56:41 +0200
|
||||
Subject: [PATCH] multipath-tools test: simplify debugging for condlog mismatch
|
||||
|
||||
If there's a mismatch between expected and actual log message,
|
||||
print both messages.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/test-log.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/test-log.c b/tests/test-log.c
|
||||
index c1745872..63516999 100644
|
||||
--- a/tests/test-log.c
|
||||
+++ b/tests/test-log.c
|
||||
@@ -16,12 +16,14 @@ void __wrap_dlog (int prio, const char * fmt, ...)
|
||||
va_list ap;
|
||||
char *expected;
|
||||
|
||||
- check_expected(prio);
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buff, MAX_MSG_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "%s(%d): %s", __func__, prio, buff);
|
||||
expected = mock_ptr_type(char *);
|
||||
+ if (memcmp(expected, buff, strlen(expected)))
|
||||
+ fprintf(stderr, "%s(expected): %s", __func__, expected);
|
||||
+ check_expected(prio);
|
||||
assert_memory_equal(buff, expected, strlen(expected));
|
||||
}
|
||||
|
493
0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch
Normal file
493
0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch
Normal file
@ -0,0 +1,493 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Aug 2023 22:57:29 +0200
|
||||
Subject: [PATCH] multipath-tools tests: add tests for
|
||||
get_user_friendly_alias()
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 441 insertions(+)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 11f209e0..7e443b06 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -81,6 +81,35 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#define TEST_FDNO 1234
|
||||
+#define TEST_FPTR ((FILE *) 0xaffe)
|
||||
+
|
||||
+int __wrap_open_file(const char *file, int *can_write, const char *header)
|
||||
+{
|
||||
+ int cw = mock_type(int);
|
||||
+
|
||||
+ *can_write = cw;
|
||||
+ return TEST_FDNO;
|
||||
+}
|
||||
+
|
||||
+FILE *__wrap_fdopen(int fd, const char *mode)
|
||||
+{
|
||||
+ assert_int_equal(fd, TEST_FDNO);
|
||||
+ return TEST_FPTR;
|
||||
+}
|
||||
+
|
||||
+int __wrap_fflush(FILE *f)
|
||||
+{
|
||||
+ assert_ptr_equal(f, TEST_FPTR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int __wrap_fclose(FILE *f)
|
||||
+{
|
||||
+ assert_ptr_equal(f, TEST_FPTR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* strbuf wrapper for the old format_devname() */
|
||||
static int __format_devname(char *name, int id, size_t len, const char *prefix)
|
||||
{
|
||||
@@ -399,6 +428,22 @@ static void mock_self_alias(const char *alias, const char *wwid)
|
||||
}
|
||||
|
||||
#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n"
|
||||
+#define NOMATCH_STR(alias_str) ("No matching alias [" alias_str "] in bindings file.\n")
|
||||
+#define FOUND_STR(alias_str, wwid_str) \
|
||||
+ "Found matching wwid [" wwid_str "] in bindings file." \
|
||||
+ " Setting alias to " alias_str "\n"
|
||||
+#define FOUND_ALIAS_STR(alias_str, wwid_str) \
|
||||
+ "Found matching alias [" alias_str "] in bindings file." \
|
||||
+ " Setting wwid to " wwid_str "\n"
|
||||
+#define NOMATCH_WWID_STR(wwid_str) ("No matching wwid [" wwid_str "] in bindings file.\n")
|
||||
+#define NEW_STR(alias_str, wwid_str) ("Created new binding [" alias_str "] for WWID [" wwid_str "]\n")
|
||||
+#define EXISTING_STR(alias_str, wwid_str) ("Use existing binding [" alias_str "] for WWID [" wwid_str "]\n")
|
||||
+#define ALLOC_STR(alias_str, wwid_str) ("Allocated existing binding [" alias_str "] for WWID [" wwid_str "]\n")
|
||||
+#define BINDING_STR(alias_str, wwid_str) (alias_str " " wwid_str "\n")
|
||||
+#define BOUND_STR(alias_str, wwid_str) ("alias "alias_str " already bound to wwid " wwid_str ", cannot reuse")
|
||||
+#define ERR_STR(alias_str, wwid_str) ("ERROR: old alias [" alias_str "] for wwid [" wwid_str "] is used by other map\n")
|
||||
+#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n")
|
||||
+#define NOMORE_STR "no more available user_friendly_names\n"
|
||||
|
||||
static void mock_failed_alias(const char *alias, char *msg)
|
||||
{
|
||||
@@ -421,6 +466,24 @@ static void mock_used_alias(const char *alias, char *msg)
|
||||
expect_condlog(3, msg);
|
||||
}
|
||||
|
||||
+static void mock_bindings_file(const char *content, int match_line)
|
||||
+{
|
||||
+ static char cnt[1024];
|
||||
+ char *token;
|
||||
+ int i;
|
||||
+
|
||||
+ assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1);
|
||||
+
|
||||
+ for (token = strtok(cnt, "\n"), i = 0;
|
||||
+ token && *token;
|
||||
+ token = strtok(NULL, "\n"), i++) {
|
||||
+ will_return(__wrap_fgets, token);
|
||||
+ if (match_line == i)
|
||||
+ return;
|
||||
+ }
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+}
|
||||
+
|
||||
static void lb_empty(void **state)
|
||||
{
|
||||
int rc;
|
||||
@@ -1147,6 +1210,382 @@ static int test_allocate_binding(void)
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
|
||||
+#define mock_allocate_binding(alias, wwid) \
|
||||
+ do { \
|
||||
+ static const char ln[] = BINDING_STR(alias, wwid); \
|
||||
+ \
|
||||
+ will_return(__wrap_lseek, 0); \
|
||||
+ expect_value(__wrap_write, count, strlen(ln)); \
|
||||
+ expect_string(__wrap_write, buf, ln); \
|
||||
+ will_return(__wrap_write, strlen(ln)); \
|
||||
+ expect_condlog(3, NEW_STR(alias, wwid)); \
|
||||
+ } while (0)
|
||||
+
|
||||
+static void gufa_empty_new_rw(void **state) {
|
||||
+ char *alias;
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHa", "WWID0");
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_empty_new_ro_1(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, false);
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ assert_ptr_equal(alias, NULL);
|
||||
+}
|
||||
+
|
||||
+static void gufa_empty_new_ro_2(void **state) {
|
||||
+ char *alias;
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ assert_ptr_equal(alias, NULL);
|
||||
+}
|
||||
+
|
||||
+static void gufa_match_a_unused(void **state) {
|
||||
+ char *alias;
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_match_a_self(void **state) {
|
||||
+ char *alias;
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
+ mock_self_alias("MPATHa", "WWID0");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_match_a_used(void **state) {
|
||||
+ char *alias;
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ assert_ptr_equal(alias, NULL);
|
||||
+}
|
||||
+
|
||||
+static void gufa_nomatch_a_c(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHc WWID2",
|
||||
+ -1);
|
||||
+ mock_unused_alias("MPATHb");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHb", "WWID1");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHb");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_nomatch_c_a(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHc WWID2\n"
|
||||
+ "MPATHa WWID0",
|
||||
+ -1);
|
||||
+ mock_unused_alias("MPATHb");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHb", "WWID1");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHb");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_nomatch_c_b(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHc WWID2\n"
|
||||
+ "MPATHb WWID1\n",
|
||||
+ -1);
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHa", "WWID0");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_nomatch_c_b_used(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHc WWID2\n"
|
||||
+ "MPATHb WWID1",
|
||||
+ -1);
|
||||
+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4"));
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID4"));
|
||||
+ mock_unused_alias("MPATHd");
|
||||
+
|
||||
+ mock_allocate_binding("MPATHd", "WWID4");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHd");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_nomatch_b_f_a(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATHf WWID6\n"
|
||||
+ "MPATHa WWID0\n",
|
||||
+ -1);
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID7"));
|
||||
+ mock_unused_alias("MPATHg");
|
||||
+
|
||||
+ mock_allocate_binding("MPATHg", "WWID7");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHg");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_empty(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ /* rlookup_binding for ALIAS */
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHz"));
|
||||
+
|
||||
+ /* lookup_binding */
|
||||
+ will_return(__wrap_fgets, NULL);
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHz", "WWID0");
|
||||
+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHz");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_match(void **state) {
|
||||
+ char *alias;
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATHz WWID0",
|
||||
+ 1);
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHz");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_match_other(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = "MPATHz WWID9";
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
|
||||
+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+
|
||||
+ mock_allocate_binding("MPATHa", "WWID0");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_match_other_used(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = "MPATHz WWID9";
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
|
||||
+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+ mock_unused_alias("MPATHb");
|
||||
+
|
||||
+ mock_allocate_binding("MPATHb", "WWID0");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHb");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_match_other_wwidmatch(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = ("MPATHz WWID9\n"
|
||||
+ "MPATHc WWID2");
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
|
||||
+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, 1);
|
||||
+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
|
||||
+ mock_unused_alias("MPATHc");
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHc");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_match_other_wwidmatch_used(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = ("MPATHz WWID9\n"
|
||||
+ "MPATHc WWID2");
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
|
||||
+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, 1);
|
||||
+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
|
||||
+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_ptr_equal(alias, NULL);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_nomatch_wwidmatch(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = "MPATHa WWID0";
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHz"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
+ mock_unused_alias("MPATHa");
|
||||
+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHa");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_nomatch_wwidmatch_used(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = "MPATHa WWID0";
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHz"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, 0);
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_ptr_equal(alias, NULL);
|
||||
+}
|
||||
+
|
||||
+static void gufa_old_nomatch_nowwidmatch(void **state) {
|
||||
+ char *alias;
|
||||
+ static const char bindings[] = "MPATHb WWID1";
|
||||
+
|
||||
+ will_return(__wrap_open_file, true);
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHz"));
|
||||
+
|
||||
+ mock_bindings_file(bindings, -1);
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
+
|
||||
+ mock_allocate_binding("MPATHz", "WWID0");
|
||||
+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0"));
|
||||
+
|
||||
+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ assert_string_equal(alias, "MPATHz");
|
||||
+ free(alias);
|
||||
+}
|
||||
+
|
||||
+static int test_get_user_friendly_alias()
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test(gufa_empty_new_rw),
|
||||
+ cmocka_unit_test(gufa_empty_new_ro_1),
|
||||
+ cmocka_unit_test(gufa_empty_new_ro_2),
|
||||
+ cmocka_unit_test(gufa_match_a_unused),
|
||||
+ cmocka_unit_test(gufa_match_a_self),
|
||||
+ cmocka_unit_test(gufa_match_a_used),
|
||||
+ cmocka_unit_test(gufa_nomatch_a_c),
|
||||
+ cmocka_unit_test(gufa_nomatch_c_a),
|
||||
+ cmocka_unit_test(gufa_nomatch_c_b),
|
||||
+ cmocka_unit_test(gufa_nomatch_c_b_used),
|
||||
+ cmocka_unit_test(gufa_nomatch_b_f_a),
|
||||
+ cmocka_unit_test(gufa_old_empty),
|
||||
+ cmocka_unit_test(gufa_old_match),
|
||||
+ cmocka_unit_test(gufa_old_match_other),
|
||||
+ cmocka_unit_test(gufa_old_match_other_used),
|
||||
+ cmocka_unit_test(gufa_old_match_other_wwidmatch),
|
||||
+ cmocka_unit_test(gufa_old_match_other_wwidmatch_used),
|
||||
+ cmocka_unit_test(gufa_old_nomatch_wwidmatch),
|
||||
+ cmocka_unit_test(gufa_old_nomatch_wwidmatch_used),
|
||||
+ cmocka_unit_test(gufa_old_nomatch_nowwidmatch),
|
||||
+ };
|
||||
+
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1157,6 +1596,8 @@ int main(void)
|
||||
ret += test_lookup_binding();
|
||||
ret += test_rlookup_binding();
|
||||
ret += test_allocate_binding();
|
||||
+ ret += test_allocate_binding();
|
||||
+ ret += test_get_user_friendly_alias();
|
||||
|
||||
return ret;
|
||||
}
|
365
0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch
Normal file
365
0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch
Normal file
@ -0,0 +1,365 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 10:40:32 +0200
|
||||
Subject: [PATCH] multipath-tools test: consistent use of macros in alias test
|
||||
|
||||
Use the macros introduced with the tests for get_user_friendly_alias()
|
||||
also in the previously existing tests.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 80 ++++++++++++++++++++++++---------------------------
|
||||
1 file changed, 38 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 7e443b06..427b2814 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -490,7 +490,7 @@ static void lb_empty(void **state)
|
||||
char *alias;
|
||||
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0);
|
||||
assert_int_equal(rc, 1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -503,7 +503,7 @@ static void lb_empty_unused(void **state)
|
||||
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_unused_alias("MPATHa");
|
||||
- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -518,7 +518,7 @@ static void lb_empty_failed(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
mock_unused_alias("MPATHb");
|
||||
- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -533,7 +533,7 @@ static void lb_empty_1_used(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
mock_unused_alias("MPATHb");
|
||||
- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -548,7 +548,7 @@ static void lb_empty_1_used_self(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
mock_self_alias("MPATHb", "WWID0");
|
||||
- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -561,8 +561,7 @@ static void lb_match_a(void **state)
|
||||
char *alias;
|
||||
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- expect_condlog(3, "Found matching wwid [WWID0] in bindings file."
|
||||
- " Setting alias to MPATHa\n");
|
||||
+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
@@ -577,7 +576,7 @@ static void lb_nomatch_a(void **state)
|
||||
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -590,7 +589,7 @@ static void lb_nomatch_a_bad_check(void **state)
|
||||
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(0, "no more available user_friendly_names\n");
|
||||
+ expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1);
|
||||
assert_int_equal(rc, -1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -604,7 +603,7 @@ static void lb_nomatch_a_unused(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_unused_alias("MPATHb");
|
||||
- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -622,7 +621,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state)
|
||||
mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1"));
|
||||
mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1"));
|
||||
mock_self_alias("MPATHf", "WWID1");
|
||||
- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 6);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -635,8 +634,7 @@ static void do_lb_match_c(void **state, int check_if_taken)
|
||||
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
- expect_condlog(3, "Found matching wwid [WWID1] in bindings file."
|
||||
- " Setting alias to MPATHc\n");
|
||||
+ expect_condlog(3, FOUND_STR("MPATHc", "WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
@@ -662,7 +660,7 @@ static void lb_nomatch_a_c(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -677,7 +675,7 @@ static void lb_nomatch_a_d_unused(void **state)
|
||||
will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_unused_alias("MPATHb");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -693,7 +691,7 @@ static void lb_nomatch_a_d_1_used(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
mock_unused_alias("MPATHc");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 3);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -710,7 +708,7 @@ static void lb_nomatch_a_d_2_used(void **state)
|
||||
mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
mock_unused_alias("MPATHe");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 5);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -728,7 +726,7 @@ static void lb_nomatch_a_d_3_used(void **state)
|
||||
mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2"));
|
||||
mock_unused_alias("MPATHf");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 6);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -742,7 +740,7 @@ static void lb_nomatch_c_a(void **state)
|
||||
will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -758,7 +756,7 @@ static void lb_nomatch_d_a_unused(void **state)
|
||||
will_return(__wrap_fgets, "MPATHd WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_unused_alias("MPATHb");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 2);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -775,7 +773,7 @@ static void lb_nomatch_d_a_1_used(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
mock_unused_alias("MPATHe");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 5);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -790,7 +788,7 @@ static void lb_nomatch_a_b(void **state)
|
||||
will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 3);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -806,7 +804,7 @@ static void lb_nomatch_a_b_bad(void **state)
|
||||
will_return(__wrap_fgets, "MPATHb\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 3);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -823,7 +821,7 @@ static void lb_nomatch_a_b_bad_self(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
|
||||
mock_self_alias("MPATHc", "WWID2");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 3);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -838,7 +836,7 @@ static void lb_nomatch_b_a(void **state)
|
||||
will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 27);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -857,7 +855,7 @@ static void lb_nomatch_b_a_3_used(void **state)
|
||||
mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2"));
|
||||
mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2"));
|
||||
mock_unused_alias("MPATHad");
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, 30);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -873,7 +871,7 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken)
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(0, "no more available user_friendly_names\n");
|
||||
+ expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken);
|
||||
assert_int_equal(rc, -1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -898,7 +896,7 @@ static void lb_nomatch_int_max_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
- expect_condlog(0, "no more available user_friendly_names\n");
|
||||
+ expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -913,7 +911,7 @@ static void lb_nomatch_int_max_m1(void **state)
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, INT_MAX);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -929,7 +927,7 @@ static void lb_nomatch_int_max_m1_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2"));
|
||||
- expect_condlog(0, "no more available user_friendly_names\n");
|
||||
+ expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -945,7 +943,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
|
||||
- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, INT_MAX);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -961,7 +959,7 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
|
||||
will_return(__wrap_fgets, NULL);
|
||||
mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2"));
|
||||
- expect_condlog(0, "no more available user_friendly_names\n");
|
||||
+ expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -1017,7 +1015,7 @@ static void rl_empty(void **state)
|
||||
|
||||
buf[0] = '\0';
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, -1);
|
||||
assert_string_equal(buf, "");
|
||||
@@ -1030,8 +1028,7 @@ static void rl_match_a(void **state)
|
||||
|
||||
buf[0] = '\0';
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- expect_condlog(3, "Found matching alias [MPATHa] in bindings file. "
|
||||
- "Setting wwid to WWID0\n");
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, 0);
|
||||
assert_string_equal(buf, "WWID0");
|
||||
@@ -1045,7 +1042,7 @@ static void rl_nomatch_a(void **state)
|
||||
buf[0] = '\0';
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHb"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHb");
|
||||
assert_int_equal(rc, -1);
|
||||
assert_string_equal(buf, "");
|
||||
@@ -1060,7 +1057,7 @@ static void rl_malformed_a(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa \n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
expect_condlog(3, "Ignoring malformed line 1 in bindings file\n");
|
||||
- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, -1);
|
||||
assert_string_equal(buf, "");
|
||||
@@ -1080,7 +1077,7 @@ static void rl_overlong_a(void **state)
|
||||
will_return(__wrap_fgets, line);
|
||||
will_return(__wrap_fgets, NULL);
|
||||
expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n");
|
||||
- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n");
|
||||
+ expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, -1);
|
||||
assert_string_equal(buf, "");
|
||||
@@ -1095,8 +1092,7 @@ static void rl_match_b(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
will_return(__wrap_fgets, "MPATHb WWID2\n");
|
||||
- expect_condlog(3, "Found matching alias [MPATHb] in bindings file. "
|
||||
- "Setting wwid to WWID2\n");
|
||||
+ expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHb");
|
||||
assert_int_equal(rc, 0);
|
||||
assert_string_equal(buf, "WWID2");
|
||||
@@ -1125,7 +1121,7 @@ static void al_a(void **state)
|
||||
expect_value(__wrap_write, count, strlen(ln));
|
||||
expect_string(__wrap_write, buf, ln);
|
||||
will_return(__wrap_write, strlen(ln));
|
||||
- expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n");
|
||||
+ expect_condlog(3, NEW_STR("MPATHa", "WWIDa"));
|
||||
|
||||
alias = allocate_binding(0, "WWIDa", 1, "MPATH");
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
@@ -1142,7 +1138,7 @@ static void al_zz(void **state)
|
||||
expect_value(__wrap_write, count, strlen(ln));
|
||||
expect_string(__wrap_write, buf, ln);
|
||||
will_return(__wrap_write, strlen(ln));
|
||||
- expect_condlog(3, "Created new binding [MPATHzz] for WWID [WWIDzz]\n");
|
||||
+ expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz"));
|
||||
|
||||
alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH");
|
||||
assert_ptr_not_equal(alias, NULL);
|
246
0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch
Normal file
246
0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch
Normal file
@ -0,0 +1,246 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 10:49:32 +0200
|
||||
Subject: [PATCH] multipath-tools tests: convert mock_{failed,used}_alias to
|
||||
macros
|
||||
|
||||
This way we can further improve readability of the individual test
|
||||
cases.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 92 +++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 46 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 427b2814..a32b43e8 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -445,26 +445,26 @@ static void mock_self_alias(const char *alias, const char *wwid)
|
||||
#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n")
|
||||
#define NOMORE_STR "no more available user_friendly_names\n"
|
||||
|
||||
-static void mock_failed_alias(const char *alias, char *msg)
|
||||
-{
|
||||
- expect_string(__wrap_dm_map_present, str, alias);
|
||||
- will_return(__wrap_dm_map_present, 1);
|
||||
- expect_string(__wrap_dm_get_uuid, name, alias);
|
||||
- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE);
|
||||
- will_return(__wrap_dm_get_uuid, 1);
|
||||
- expect_condlog(3, msg);
|
||||
-}
|
||||
+#define mock_failed_alias(alias, wwid) \
|
||||
+ do { \
|
||||
+ expect_string(__wrap_dm_map_present, str, alias); \
|
||||
+ will_return(__wrap_dm_map_present, 1); \
|
||||
+ expect_string(__wrap_dm_get_uuid, name, alias); \
|
||||
+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \
|
||||
+ will_return(__wrap_dm_get_uuid, 1); \
|
||||
+ expect_condlog(3, USED_STR(alias, wwid)); \
|
||||
+ } while (0)
|
||||
|
||||
-static void mock_used_alias(const char *alias, char *msg)
|
||||
-{
|
||||
- expect_string(__wrap_dm_map_present, str, alias);
|
||||
- will_return(__wrap_dm_map_present, 1);
|
||||
- expect_string(__wrap_dm_get_uuid, name, alias);
|
||||
- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE);
|
||||
- will_return(__wrap_dm_get_uuid, 0);
|
||||
- will_return(__wrap_dm_get_uuid, "WWID_USED");
|
||||
- expect_condlog(3, msg);
|
||||
-}
|
||||
+#define mock_used_alias(alias, wwid) \
|
||||
+ do { \
|
||||
+ expect_string(__wrap_dm_map_present, str, alias); \
|
||||
+ will_return(__wrap_dm_map_present, 1); \
|
||||
+ expect_string(__wrap_dm_get_uuid, name, alias); \
|
||||
+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \
|
||||
+ will_return(__wrap_dm_get_uuid, 0); \
|
||||
+ will_return(__wrap_dm_get_uuid, "WWID_USED"); \
|
||||
+ expect_condlog(3, USED_STR(alias, wwid)); \
|
||||
+ } while(0)
|
||||
|
||||
static void mock_bindings_file(const char *content, int match_line)
|
||||
{
|
||||
@@ -516,7 +516,7 @@ static void lb_empty_failed(void **state)
|
||||
char *alias;
|
||||
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_failed_alias("MPATHa", "WWID0");
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
@@ -531,7 +531,7 @@ static void lb_empty_1_used(void **state)
|
||||
char *alias;
|
||||
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", "WWID0");
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
@@ -546,7 +546,7 @@ static void lb_empty_1_used_self(void **state)
|
||||
char *alias;
|
||||
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", "WWID0");
|
||||
mock_self_alias("MPATHb", "WWID0");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
@@ -616,10 +616,10 @@ static void lb_nomatch_a_3_used_failed_self(void **state)
|
||||
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1"));
|
||||
- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1"));
|
||||
- mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1"));
|
||||
- mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1"));
|
||||
+ mock_used_alias("MPATHb", "WWID1");
|
||||
+ mock_used_alias("MPATHc", "WWID1");
|
||||
+ mock_used_alias("MPATHd", "WWID1");
|
||||
+ mock_failed_alias("MPATHe", "WWID1");
|
||||
mock_self_alias("MPATHf", "WWID1");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
|
||||
@@ -689,7 +689,7 @@ static void lb_nomatch_a_d_1_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
+ mock_used_alias("MPATHb", "WWID2");
|
||||
mock_unused_alias("MPATHc");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -705,8 +705,8 @@ static void lb_nomatch_a_d_2_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
+ mock_used_alias("MPATHb", "WWID2");
|
||||
+ mock_used_alias("MPATHc", "WWID2");
|
||||
mock_unused_alias("MPATHe");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -722,9 +722,9 @@ static void lb_nomatch_a_d_3_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
- mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2"));
|
||||
+ mock_used_alias("MPATHb", "WWID2");
|
||||
+ mock_used_alias("MPATHc", "WWID2");
|
||||
+ mock_used_alias("MPATHe", "WWID2");
|
||||
mock_unused_alias("MPATHf");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -771,7 +771,7 @@ static void lb_nomatch_d_a_1_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, "MPATHd WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2"));
|
||||
+ mock_used_alias("MPATHb", "WWID2");
|
||||
mock_unused_alias("MPATHe");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -851,9 +851,9 @@ static void lb_nomatch_b_a_3_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2"));
|
||||
- mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2"));
|
||||
- mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2"));
|
||||
+ mock_used_alias("MPATHaa", "WWID2");
|
||||
+ mock_used_alias("MPATHab", "WWID2");
|
||||
+ mock_used_alias("MPATHac", "WWID2");
|
||||
mock_unused_alias("MPATHad");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -895,7 +895,7 @@ static void lb_nomatch_int_max_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
+ mock_used_alias("MPATHa", "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -926,7 +926,7 @@ static void lb_nomatch_int_max_m1_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2"));
|
||||
+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -941,7 +941,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
+ mock_used_alias("MPATHa", "WWID2");
|
||||
mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -957,8 +957,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
|
||||
will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
will_return(__wrap_fgets, NULL);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2"));
|
||||
- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2"));
|
||||
+ mock_used_alias("MPATHa", "WWID2");
|
||||
+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -1291,7 +1291,7 @@ static void gufa_match_a_used(void **state) {
|
||||
|
||||
will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", "WWID0");
|
||||
|
||||
alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -1355,7 +1355,7 @@ static void gufa_nomatch_c_b_used(void **state) {
|
||||
mock_bindings_file("MPATHc WWID2\n"
|
||||
"MPATHb WWID1",
|
||||
-1);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4"));
|
||||
+ mock_used_alias("MPATHa", "WWID4");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID4"));
|
||||
mock_unused_alias("MPATHd");
|
||||
|
||||
@@ -1450,7 +1450,7 @@ static void gufa_old_match_other_used(void **state) {
|
||||
expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
|
||||
|
||||
mock_bindings_file(bindings, -1);
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", "WWID0");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
mock_unused_alias("MPATHb");
|
||||
|
||||
@@ -1493,7 +1493,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) {
|
||||
|
||||
mock_bindings_file(bindings, 1);
|
||||
expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
|
||||
- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2"));
|
||||
+ mock_used_alias("MPATHc", "WWID2");
|
||||
|
||||
alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
@@ -1528,7 +1528,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) {
|
||||
|
||||
mock_bindings_file(bindings, 0);
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0"));
|
||||
+ mock_used_alias("MPATHa", "WWID0");
|
||||
|
||||
alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
assert_ptr_equal(alias, NULL);
|
500
0010-multipath-tools-test-use-mock_bindings_file-consiste.patch
Normal file
500
0010-multipath-tools-test-use-mock_bindings_file-consiste.patch
Normal file
@ -0,0 +1,500 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 11:13:44 +0200
|
||||
Subject: [PATCH] multipath-tools test: use mock_bindings_file() consistently
|
||||
|
||||
Further improve test readablity.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 178 +++++++++++++++++++++-----------------------------
|
||||
1 file changed, 76 insertions(+), 102 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index a32b43e8..f334f928 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -489,7 +489,7 @@ static void lb_empty(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0);
|
||||
assert_int_equal(rc, 1);
|
||||
@@ -501,7 +501,7 @@ static void lb_empty_unused(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
@@ -515,7 +515,7 @@ static void lb_empty_failed(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_failed_alias("MPATHa", "WWID0");
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
@@ -530,7 +530,7 @@ static void lb_empty_1_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_used_alias("MPATHa", "WWID0");
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
@@ -545,7 +545,7 @@ static void lb_empty_1_used_self(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_used_alias("MPATHa", "WWID0");
|
||||
mock_self_alias("MPATHb", "WWID0");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
@@ -560,7 +560,7 @@ static void lb_match_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
+ mock_bindings_file("MPATHa WWID0\n", 0);
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 0);
|
||||
@@ -574,8 +574,7 @@ static void lb_nomatch_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
@@ -587,8 +586,7 @@ static void lb_nomatch_a_bad_check(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n", -1);
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1);
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -600,8 +598,7 @@ static void lb_nomatch_a_unused(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n", -1);
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
|
||||
@@ -614,8 +611,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n", -1);
|
||||
mock_used_alias("MPATHb", "WWID1");
|
||||
mock_used_alias("MPATHc", "WWID1");
|
||||
mock_used_alias("MPATHd", "WWID1");
|
||||
@@ -632,8 +628,8 @@ static void do_lb_match_c(void **state, int check_if_taken)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHc WWID1", 1);
|
||||
expect_condlog(3, FOUND_STR("MPATHc", "WWID1"));
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken);
|
||||
assert_int_equal(rc, 0);
|
||||
@@ -657,9 +653,8 @@ static void lb_nomatch_a_c(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHc WWID1", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
@@ -671,9 +666,8 @@ static void lb_nomatch_a_d_unused(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHd WWID1", -1);
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -686,9 +680,8 @@ static void lb_nomatch_a_d_1_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHd WWID1", -1);
|
||||
mock_used_alias("MPATHb", "WWID2");
|
||||
mock_unused_alias("MPATHc");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
@@ -702,9 +695,8 @@ static void lb_nomatch_a_d_2_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHd WWID1", -1);
|
||||
mock_used_alias("MPATHb", "WWID2");
|
||||
mock_used_alias("MPATHc", "WWID2");
|
||||
mock_unused_alias("MPATHe");
|
||||
@@ -719,9 +711,8 @@ static void lb_nomatch_a_d_3_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHd WWID1", -1);
|
||||
mock_used_alias("MPATHb", "WWID2");
|
||||
mock_used_alias("MPATHc", "WWID2");
|
||||
mock_used_alias("MPATHe", "WWID2");
|
||||
@@ -737,9 +728,8 @@ static void lb_nomatch_c_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHc WWID1\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 2);
|
||||
@@ -751,10 +741,9 @@ static void lb_nomatch_d_a_unused(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHc WWID1\n"
|
||||
+ "MPATHa WWID0\n"
|
||||
+ "MPATHd WWID0\n", -1);
|
||||
mock_unused_alias("MPATHb");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -767,10 +756,9 @@ static void lb_nomatch_d_a_1_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHc WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHd WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHc WWID1\n"
|
||||
+ "MPATHa WWID0\n"
|
||||
+ "MPATHd WWID0\n", -1);
|
||||
mock_used_alias("MPATHb", "WWID2");
|
||||
mock_unused_alias("MPATHe");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
@@ -784,10 +772,9 @@ static void lb_nomatch_a_b(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHb WWID1\n", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 3);
|
||||
@@ -799,10 +786,9 @@ static void lb_nomatch_a_b_bad(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHb\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHb\n", -1);
|
||||
expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
@@ -815,10 +801,9 @@ static void lb_nomatch_a_b_bad_self(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHb\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHb\n", -1);
|
||||
expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
|
||||
mock_self_alias("MPATHc", "WWID2");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
@@ -832,10 +817,9 @@ static void lb_nomatch_b_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, 27);
|
||||
@@ -847,10 +831,9 @@ static void lb_nomatch_b_a_3_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
mock_used_alias("MPATHaa", "WWID2");
|
||||
mock_used_alias("MPATHab", "WWID2");
|
||||
mock_used_alias("MPATHac", "WWID2");
|
||||
@@ -867,10 +850,9 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken);
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -892,9 +874,8 @@ static void lb_nomatch_int_max_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1);
|
||||
mock_used_alias("MPATHa", "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -907,10 +888,9 @@ static void lb_nomatch_int_max_m1(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
|
||||
assert_int_equal(rc, INT_MAX);
|
||||
@@ -922,10 +902,9 @@ static void lb_nomatch_int_max_m1_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"
|
||||
+ "MPATHa WWID0\n", -1);
|
||||
mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
@@ -938,9 +917,8 @@ static void lb_nomatch_int_max_m1_1_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1);
|
||||
mock_used_alias("MPATHa", "WWID2");
|
||||
mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
@@ -954,9 +932,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- will_return(__wrap_fgets, "MPATHb WWID1\n");
|
||||
- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHb WWID1\n"
|
||||
+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1);
|
||||
mock_used_alias("MPATHa", "WWID2");
|
||||
mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
|
||||
expect_condlog(0, NOMORE_STR);
|
||||
@@ -1014,7 +991,7 @@ static void rl_empty(void **state)
|
||||
char buf[WWID_SIZE];
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -1027,7 +1004,7 @@ static void rl_match_a(void **state)
|
||||
char buf[WWID_SIZE];
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
+ mock_bindings_file("MPATHa WWID0\n", 0);
|
||||
expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
assert_int_equal(rc, 0);
|
||||
@@ -1040,8 +1017,7 @@ static void rl_nomatch_a(void **state)
|
||||
char buf[WWID_SIZE];
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa WWID0\n", -1);
|
||||
expect_condlog(3, NOMATCH_STR("MPATHb"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHb");
|
||||
assert_int_equal(rc, -1);
|
||||
@@ -1054,8 +1030,7 @@ static void rl_malformed_a(void **state)
|
||||
char buf[WWID_SIZE];
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, "MPATHa \n");
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("MPATHa \n", -1);
|
||||
expect_condlog(3, "Ignoring malformed line 1 in bindings file\n");
|
||||
expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
@@ -1074,8 +1049,7 @@ static void rl_overlong_a(void **state)
|
||||
snprintf(line + sizeof(line) - 2, 2, "\n");
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, line);
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file(line, -1);
|
||||
expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n");
|
||||
expect_condlog(3, NOMATCH_STR("MPATHa"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHa");
|
||||
@@ -1089,9 +1063,9 @@ static void rl_match_b(void **state)
|
||||
char buf[WWID_SIZE];
|
||||
|
||||
buf[0] = '\0';
|
||||
- will_return(__wrap_fgets, "MPATHa WWID0\n");
|
||||
- will_return(__wrap_fgets, "MPATHz WWID26\n");
|
||||
- will_return(__wrap_fgets, "MPATHb WWID2\n");
|
||||
+ mock_bindings_file("MPATHa WWID0\n"
|
||||
+ "MPATHz WWID26\n"
|
||||
+ "MPATHb WWID2\n", 2);
|
||||
expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2"));
|
||||
rc = rlookup_binding(NULL, buf, "MPATHb");
|
||||
assert_int_equal(rc, 0);
|
||||
@@ -1222,7 +1196,7 @@ static void gufa_empty_new_rw(void **state) {
|
||||
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
|
||||
@@ -1235,7 +1209,7 @@ static void gufa_empty_new_rw(void **state) {
|
||||
static void gufa_empty_new_ro_1(void **state) {
|
||||
char *alias;
|
||||
will_return(__wrap_open_file, false);
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
|
||||
@@ -1248,7 +1222,7 @@ static void gufa_empty_new_ro_2(void **state) {
|
||||
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
|
||||
@@ -1261,7 +1235,7 @@ static void gufa_match_a_unused(void **state) {
|
||||
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ mock_bindings_file("MPATHa WWID0", 0);
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
mock_unused_alias("MPATHa");
|
||||
|
||||
@@ -1275,7 +1249,7 @@ static void gufa_match_a_self(void **state) {
|
||||
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ mock_bindings_file("MPATHa WWID0", 0);
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
mock_self_alias("MPATHa", "WWID0");
|
||||
|
||||
@@ -1289,7 +1263,7 @@ static void gufa_match_a_used(void **state) {
|
||||
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0"));
|
||||
+ mock_bindings_file("MPATHa WWID0", 0);
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
mock_used_alias("MPATHa", "WWID0");
|
||||
|
||||
@@ -1389,11 +1363,11 @@ static void gufa_old_empty(void **state) {
|
||||
will_return(__wrap_open_file, true);
|
||||
|
||||
/* rlookup_binding for ALIAS */
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
expect_condlog(3, NOMATCH_STR("MPATHz"));
|
||||
|
||||
/* lookup_binding */
|
||||
- will_return(__wrap_fgets, NULL);
|
||||
+ mock_bindings_file("", -1);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
|
||||
mock_allocate_binding("MPATHz", "WWID0");
|
109
0011-libmultipath-add-global-variable-for-current-binding.patch
Normal file
109
0011-libmultipath-add-global-variable-for-current-binding.patch
Normal file
@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 15:32:17 +0200
|
||||
Subject: [PATCH] libmultipath: add global variable for current bindings
|
||||
|
||||
Add a variable global_bindings that holds the currently active vector of
|
||||
bindings. This variable is freed at program exit.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 11 +++++++++--
|
||||
libmultipath/alias.h | 1 +
|
||||
libmultipath/libmultipath.version | 1 +
|
||||
multipath/main.c | 2 ++
|
||||
multipathd/main.c | 1 +
|
||||
5 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 9e9ac563..dd363fd8 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -511,6 +511,7 @@ static void _free_binding(struct binding *bdg)
|
||||
* an abstract type.
|
||||
*/
|
||||
typedef struct _vector Bindings;
|
||||
+static Bindings global_bindings = { .allocated = 0 };
|
||||
|
||||
static void free_bindings(Bindings *bindings)
|
||||
{
|
||||
@@ -522,6 +523,11 @@ static void free_bindings(Bindings *bindings)
|
||||
vector_reset(bindings);
|
||||
}
|
||||
|
||||
+void cleanup_bindings(void)
|
||||
+{
|
||||
+ free_bindings(&global_bindings);
|
||||
+}
|
||||
+
|
||||
enum {
|
||||
BINDING_EXISTS,
|
||||
BINDING_CONFLICT,
|
||||
@@ -751,7 +757,6 @@ int check_alias_settings(const struct config *conf)
|
||||
pthread_cleanup_pop(1);
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- pthread_cleanup_push_cast(free_bindings, &bindings);
|
||||
fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER);
|
||||
if (fd != -1) {
|
||||
FILE *file = fdopen(fd, "r");
|
||||
@@ -771,6 +776,8 @@ int check_alias_settings(const struct config *conf)
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
- pthread_cleanup_pop(1);
|
||||
+
|
||||
+ cleanup_bindings();
|
||||
+ global_bindings = bindings;
|
||||
return rc;
|
||||
}
|
||||
diff --git a/libmultipath/alias.h b/libmultipath/alias.h
|
||||
index fa332233..37b49d9c 100644
|
||||
--- a/libmultipath/alias.h
|
||||
+++ b/libmultipath/alias.h
|
||||
@@ -9,5 +9,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
|
||||
struct config;
|
||||
int check_alias_settings(const struct config *);
|
||||
+void cleanup_bindings(void);
|
||||
|
||||
#endif /* _ALIAS_H */
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index a7b8c337..ddd302f5 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -64,6 +64,7 @@ global:
|
||||
checker_name;
|
||||
checker_state_name;
|
||||
check_foreign;
|
||||
+ cleanup_bindings;
|
||||
cleanup_lock;
|
||||
coalesce_paths;
|
||||
count_active_paths;
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index b78f3162..45e9745f 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -843,6 +843,8 @@ main (int argc, char *argv[])
|
||||
conf->force_sync = 1;
|
||||
if (atexit(cleanup_vecs))
|
||||
condlog(1, "failed to register cleanup handler for vecs: %m");
|
||||
+ if (atexit(cleanup_bindings))
|
||||
+ condlog(1, "failed to register cleanup handler for bindings: %m");
|
||||
while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 'v':
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 2e02a548..214ed4ae 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -3325,6 +3325,7 @@ static void cleanup_child(void)
|
||||
{
|
||||
cleanup_threads();
|
||||
cleanup_vecs();
|
||||
+ cleanup_bindings();
|
||||
if (poll_dmevents)
|
||||
cleanup_dmevent_waiter();
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 15:37:15 +0200
|
||||
Subject: [PATCH] libmultipath: rename fix_bindings_file() to
|
||||
update_bindings_file()
|
||||
|
||||
We will use this function in a more generic way, give it a more
|
||||
generic name.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index dd363fd8..0aac2393 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -595,8 +595,8 @@ static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int fix_bindings_file(const struct config *conf,
|
||||
- const Bindings *bindings)
|
||||
+static int update_bindings_file(const struct config *conf,
|
||||
+ const Bindings *bindings)
|
||||
{
|
||||
int rc;
|
||||
int fd = -1;
|
||||
@@ -766,7 +766,7 @@ int check_alias_settings(const struct config *conf)
|
||||
rc = _check_bindings_file(conf, file, &bindings);
|
||||
pthread_cleanup_pop(1);
|
||||
if (rc == -1 && can_write && !conf->bindings_read_only)
|
||||
- rc = fix_bindings_file(conf, &bindings);
|
||||
+ rc = update_bindings_file(conf, &bindings);
|
||||
else if (rc == -1)
|
||||
condlog(0, "ERROR: bad settings in read-only bindings file %s",
|
||||
conf->bindings_file);
|
285
0013-libmultipath-alias.c-move-bindings-related-code-up.patch
Normal file
285
0013-libmultipath-alias.c-move-bindings-related-code-up.patch
Normal file
@ -0,0 +1,285 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 16:54:54 +0200
|
||||
Subject: [PATCH] libmultipath: alias.c: move bindings related code up
|
||||
|
||||
No code changes, just moving code.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 239 ++++++++++++++++++++++---------------------
|
||||
1 file changed, 120 insertions(+), 119 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 0aac2393..7af403da 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
+#include <assert.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
@@ -51,6 +52,125 @@
|
||||
|
||||
static const char bindings_file_header[] = BINDINGS_FILE_HEADER;
|
||||
|
||||
+struct binding {
|
||||
+ char *alias;
|
||||
+ char *wwid;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Perhaps one day we'll implement this more efficiently, thus use
|
||||
+ * an abstract type.
|
||||
+ */
|
||||
+typedef struct _vector Bindings;
|
||||
+static Bindings global_bindings = { .allocated = 0 };
|
||||
+
|
||||
+enum {
|
||||
+ BINDING_EXISTS,
|
||||
+ BINDING_CONFLICT,
|
||||
+ BINDING_ADDED,
|
||||
+ BINDING_DELETED,
|
||||
+ BINDING_NOTFOUND,
|
||||
+ BINDING_ERROR,
|
||||
+};
|
||||
+
|
||||
+static void _free_binding(struct binding *bdg)
|
||||
+{
|
||||
+ free(bdg->wwid);
|
||||
+ free(bdg->alias);
|
||||
+ free(bdg);
|
||||
+}
|
||||
+
|
||||
+static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
+{
|
||||
+ struct binding *bdg;
|
||||
+ int i, cmp = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Keep the bindings array sorted by alias.
|
||||
+ * Optimization: Search backwards, assuming that the bindings file is
|
||||
+ * sorted already.
|
||||
+ */
|
||||
+ vector_foreach_slot_backwards(bindings, bdg, i) {
|
||||
+ if ((cmp = strcmp(bdg->alias, alias)) <= 0)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for exact match */
|
||||
+ if (i >= 0 && cmp == 0)
|
||||
+ return strcmp(bdg->wwid, wwid) ?
|
||||
+ BINDING_CONFLICT : BINDING_EXISTS;
|
||||
+
|
||||
+ i++;
|
||||
+ bdg = calloc(1, sizeof(*bdg));
|
||||
+ if (bdg) {
|
||||
+ bdg->wwid = strdup(wwid);
|
||||
+ bdg->alias = strdup(alias);
|
||||
+ if (bdg->wwid && bdg->alias &&
|
||||
+ vector_insert_slot(bindings, i, bdg))
|
||||
+ return BINDING_ADDED;
|
||||
+ else
|
||||
+ _free_binding(bdg);
|
||||
+ }
|
||||
+
|
||||
+ return BINDING_ERROR;
|
||||
+}
|
||||
+
|
||||
+static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
+{
|
||||
+ struct binding *bnd;
|
||||
+ STRBUF_ON_STACK(line);
|
||||
+ int i;
|
||||
+
|
||||
+ if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
+ != sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
+ return -1;
|
||||
+
|
||||
+ vector_foreach_slot(bindings, bnd, i) {
|
||||
+ int len;
|
||||
+
|
||||
+ if ((len = print_strbuf(&line, "%s %s\n",
|
||||
+ bnd->alias, bnd->wwid)) < 0)
|
||||
+ return -1;
|
||||
+ if (write(fd, get_strbuf_str(&line), len) != len)
|
||||
+ return -1;
|
||||
+ truncate_strbuf(&line, 0);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int update_bindings_file(const struct config *conf,
|
||||
+ const Bindings *bindings)
|
||||
+{
|
||||
+ int rc;
|
||||
+ int fd = -1;
|
||||
+ char tempname[PATH_MAX];
|
||||
+ mode_t old_umask;
|
||||
+
|
||||
+ if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file))
|
||||
+ return -1;
|
||||
+ /* coverity: SECURE_TEMP */
|
||||
+ old_umask = umask(0077);
|
||||
+ if ((fd = mkstemp(tempname)) == -1) {
|
||||
+ condlog(1, "%s: mkstemp: %m", __func__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ umask(old_umask);
|
||||
+ pthread_cleanup_push(cleanup_fd_ptr, &fd);
|
||||
+ rc = write_bindings_file(bindings, fd);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ if (rc == -1) {
|
||||
+ condlog(1, "failed to write new bindings file %s",
|
||||
+ tempname);
|
||||
+ unlink(tempname);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ if ((rc = rename(tempname, conf->bindings_file)) == -1)
|
||||
+ condlog(0, "%s: rename: %m", __func__);
|
||||
+ else
|
||||
+ condlog(1, "updated bindings file %s", conf->bindings_file);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
int
|
||||
valid_alias(const char *alias)
|
||||
{
|
||||
@@ -494,25 +614,6 @@ get_user_friendly_wwid(const char *alias, char *buff, const char *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-struct binding {
|
||||
- char *alias;
|
||||
- char *wwid;
|
||||
-};
|
||||
-
|
||||
-static void _free_binding(struct binding *bdg)
|
||||
-{
|
||||
- free(bdg->wwid);
|
||||
- free(bdg->alias);
|
||||
- free(bdg);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Perhaps one day we'll implement this more efficiently, thus use
|
||||
- * an abstract type.
|
||||
- */
|
||||
-typedef struct _vector Bindings;
|
||||
-static Bindings global_bindings = { .allocated = 0 };
|
||||
-
|
||||
static void free_bindings(Bindings *bindings)
|
||||
{
|
||||
struct binding *bdg;
|
||||
@@ -528,106 +629,6 @@ void cleanup_bindings(void)
|
||||
free_bindings(&global_bindings);
|
||||
}
|
||||
|
||||
-enum {
|
||||
- BINDING_EXISTS,
|
||||
- BINDING_CONFLICT,
|
||||
- BINDING_ADDED,
|
||||
- BINDING_DELETED,
|
||||
- BINDING_NOTFOUND,
|
||||
- BINDING_ERROR,
|
||||
-};
|
||||
-
|
||||
-static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
-{
|
||||
- struct binding *bdg;
|
||||
- int i, cmp = 0;
|
||||
-
|
||||
- /*
|
||||
- * Keep the bindings array sorted by alias.
|
||||
- * Optimization: Search backwards, assuming that the bindings file is
|
||||
- * sorted already.
|
||||
- */
|
||||
- vector_foreach_slot_backwards(bindings, bdg, i) {
|
||||
- if ((cmp = strcmp(bdg->alias, alias)) <= 0)
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* Check for exact match */
|
||||
- if (i >= 0 && cmp == 0)
|
||||
- return strcmp(bdg->wwid, wwid) ?
|
||||
- BINDING_CONFLICT : BINDING_EXISTS;
|
||||
-
|
||||
- i++;
|
||||
- bdg = calloc(1, sizeof(*bdg));
|
||||
- if (bdg) {
|
||||
- bdg->wwid = strdup(wwid);
|
||||
- bdg->alias = strdup(alias);
|
||||
- if (bdg->wwid && bdg->alias &&
|
||||
- vector_insert_slot(bindings, i, bdg))
|
||||
- return BINDING_ADDED;
|
||||
- else
|
||||
- _free_binding(bdg);
|
||||
- }
|
||||
-
|
||||
- return BINDING_ERROR;
|
||||
-}
|
||||
-
|
||||
-static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
-{
|
||||
- struct binding *bnd;
|
||||
- STRBUF_ON_STACK(line);
|
||||
- int i;
|
||||
-
|
||||
- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
- != sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
- return -1;
|
||||
-
|
||||
- vector_foreach_slot(bindings, bnd, i) {
|
||||
- int len;
|
||||
-
|
||||
- if ((len = print_strbuf(&line, "%s %s\n",
|
||||
- bnd->alias, bnd->wwid)) < 0)
|
||||
- return -1;
|
||||
- if (write(fd, get_strbuf_str(&line), len) != len)
|
||||
- return -1;
|
||||
- truncate_strbuf(&line, 0);
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int update_bindings_file(const struct config *conf,
|
||||
- const Bindings *bindings)
|
||||
-{
|
||||
- int rc;
|
||||
- int fd = -1;
|
||||
- char tempname[PATH_MAX];
|
||||
- mode_t old_umask;
|
||||
-
|
||||
- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file))
|
||||
- return -1;
|
||||
- /* coverity: SECURE_TEMP */
|
||||
- old_umask = umask(0077);
|
||||
- if ((fd = mkstemp(tempname)) == -1) {
|
||||
- condlog(1, "%s: mkstemp: %m", __func__);
|
||||
- return -1;
|
||||
- }
|
||||
- umask(old_umask);
|
||||
- pthread_cleanup_push(cleanup_fd_ptr, &fd);
|
||||
- rc = write_bindings_file(bindings, fd);
|
||||
- pthread_cleanup_pop(1);
|
||||
- if (rc == -1) {
|
||||
- condlog(1, "failed to write new bindings file %s",
|
||||
- tempname);
|
||||
- unlink(tempname);
|
||||
- return rc;
|
||||
- }
|
||||
- if ((rc = rename(tempname, conf->bindings_file)) == -1)
|
||||
- condlog(0, "%s: rename: %m", __func__);
|
||||
- else
|
||||
- condlog(1, "updated bindings file %s", conf->bindings_file);
|
||||
- return rc;
|
||||
-}
|
||||
-
|
||||
static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
Bindings *bindings)
|
||||
{
|
@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 15:53:49 +0200
|
||||
Subject: [PATCH] libmultipath: update_bindings_file: take filename argument
|
||||
|
||||
This function just uses the file name, no other configuration
|
||||
parameters. Also, pass the Bindings argument first to use the
|
||||
same convention as the other functions in this file.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 7af403da..9bd3875e 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -138,15 +138,15 @@ static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int update_bindings_file(const struct config *conf,
|
||||
- const Bindings *bindings)
|
||||
+static int update_bindings_file(const Bindings *bindings,
|
||||
+ const char *bindings_file)
|
||||
{
|
||||
int rc;
|
||||
int fd = -1;
|
||||
char tempname[PATH_MAX];
|
||||
mode_t old_umask;
|
||||
|
||||
- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file))
|
||||
+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file))
|
||||
return -1;
|
||||
/* coverity: SECURE_TEMP */
|
||||
old_umask = umask(0077);
|
||||
@@ -164,10 +164,10 @@ static int update_bindings_file(const struct config *conf,
|
||||
unlink(tempname);
|
||||
return rc;
|
||||
}
|
||||
- if ((rc = rename(tempname, conf->bindings_file)) == -1)
|
||||
+ if ((rc = rename(tempname, bindings_file)) == -1)
|
||||
condlog(0, "%s: rename: %m", __func__);
|
||||
else
|
||||
- condlog(1, "updated bindings file %s", conf->bindings_file);
|
||||
+ condlog(1, "updated bindings file %s", bindings_file);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ int check_alias_settings(const struct config *conf)
|
||||
rc = _check_bindings_file(conf, file, &bindings);
|
||||
pthread_cleanup_pop(1);
|
||||
if (rc == -1 && can_write && !conf->bindings_read_only)
|
||||
- rc = update_bindings_file(conf, &bindings);
|
||||
+ rc = update_bindings_file(&bindings, conf->bindings_file);
|
||||
else if (rc == -1)
|
||||
condlog(0, "ERROR: bad settings in read-only bindings file %s",
|
||||
conf->bindings_file);
|
@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 15:54:45 +0200
|
||||
Subject: [PATCH] libmultipath: update_bindings_file: use a single write()
|
||||
|
||||
Save code and syscalls by assembling the content in memory first.
|
||||
write() may return less bytes written than expected. Deal with it.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 26 +++++++++++++++++---------
|
||||
1 file changed, 17 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 9bd3875e..92f90f05 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -118,22 +118,30 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
{
|
||||
struct binding *bnd;
|
||||
- STRBUF_ON_STACK(line);
|
||||
+ STRBUF_ON_STACK(content);
|
||||
int i;
|
||||
+ size_t len;
|
||||
|
||||
- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
- != sizeof(BINDINGS_FILE_HEADER) - 1)
|
||||
+ if (__append_strbuf_str(&content, BINDINGS_FILE_HEADER,
|
||||
+ sizeof(BINDINGS_FILE_HEADER) - 1) == -1)
|
||||
return -1;
|
||||
|
||||
vector_foreach_slot(bindings, bnd, i) {
|
||||
- int len;
|
||||
-
|
||||
- if ((len = print_strbuf(&line, "%s %s\n",
|
||||
- bnd->alias, bnd->wwid)) < 0)
|
||||
+ if (print_strbuf(&content, "%s %s\n",
|
||||
+ bnd->alias, bnd->wwid) < 0)
|
||||
return -1;
|
||||
- if (write(fd, get_strbuf_str(&line), len) != len)
|
||||
+ }
|
||||
+ len = get_strbuf_len(&content);
|
||||
+ while (len > 0) {
|
||||
+ ssize_t n = write(fd, get_strbuf_str(&content), len);
|
||||
+
|
||||
+ if (n < 0)
|
||||
+ return n;
|
||||
+ else if (n == 0) {
|
||||
+ condlog(2, "%s: short write", __func__);
|
||||
return -1;
|
||||
- truncate_strbuf(&line, 0);
|
||||
+ }
|
||||
+ len -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 22:33:39 +0200
|
||||
Subject: [PATCH] libmultipath: update_bindings_file: don't log temp file name
|
||||
|
||||
The name of the temp file is unlikely to be helpful for users,
|
||||
and hard to predict in the unit test. Omit it.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 92f90f05..afa5879e 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -167,8 +167,7 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
rc = write_bindings_file(bindings, fd);
|
||||
pthread_cleanup_pop(1);
|
||||
if (rc == -1) {
|
||||
- condlog(1, "failed to write new bindings file %s",
|
||||
- tempname);
|
||||
+ condlog(1, "failed to write new bindings file");
|
||||
unlink(tempname);
|
||||
return rc;
|
||||
}
|
94
0017-libmultipath-alias.c-factor-out-read_binding.patch
Normal file
94
0017-libmultipath-alias.c-factor-out-read_binding.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Aug 2023 21:17:25 +0200
|
||||
Subject: [PATCH] libmultipath: alias.c: factor out read_binding()
|
||||
|
||||
This way we can test the parsing of input lines from the bindings
|
||||
file more easily.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 58 ++++++++++++++++++++++++++++++--------------
|
||||
1 file changed, 40 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index afa5879e..ecf4a2ac 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -636,6 +636,43 @@ void cleanup_bindings(void)
|
||||
free_bindings(&global_bindings);
|
||||
}
|
||||
|
||||
+enum {
|
||||
+ READ_BINDING_OK,
|
||||
+ READ_BINDING_SKIP,
|
||||
+};
|
||||
+
|
||||
+static int read_binding(char *line, unsigned int linenr, char **alias,
|
||||
+ char **wwid) {
|
||||
+ char *c, *saveptr;
|
||||
+
|
||||
+ c = strpbrk(line, "#\n\r");
|
||||
+ if (c)
|
||||
+ *c = '\0';
|
||||
+
|
||||
+ *alias = strtok_r(line, " \t", &saveptr);
|
||||
+ if (!*alias) /* blank line */
|
||||
+ return READ_BINDING_SKIP;
|
||||
+
|
||||
+ *wwid = strtok_r(NULL, " \t", &saveptr);
|
||||
+ if (!*wwid) {
|
||||
+ condlog(1, "invalid line %u in bindings file, missing WWID",
|
||||
+ linenr);
|
||||
+ return READ_BINDING_SKIP;
|
||||
+ }
|
||||
+ if (strlen(*wwid) > WWID_SIZE - 1) {
|
||||
+ condlog(3,
|
||||
+ "Ignoring too large wwid at %u in bindings file",
|
||||
+ linenr);
|
||||
+ return READ_BINDING_SKIP;
|
||||
+ }
|
||||
+ c = strtok_r(NULL, " \t", &saveptr);
|
||||
+ if (c)
|
||||
+ /* This is non-fatal */
|
||||
+ condlog(1, "invalid line %d in bindings file, extra args \"%s\"",
|
||||
+ linenr, c);
|
||||
+ return READ_BINDING_OK;
|
||||
+}
|
||||
+
|
||||
static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
Bindings *bindings)
|
||||
{
|
||||
@@ -647,27 +684,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
|
||||
pthread_cleanup_push(cleanup_free_ptr, &line);
|
||||
while ((n = getline(&line, &line_len, file)) >= 0) {
|
||||
- char *c, *alias, *wwid, *saveptr;
|
||||
+ char *alias, *wwid;
|
||||
const char *mpe_wwid;
|
||||
|
||||
- linenr++;
|
||||
- c = strpbrk(line, "#\n\r");
|
||||
- if (c)
|
||||
- *c = '\0';
|
||||
- alias = strtok_r(line, " \t", &saveptr);
|
||||
- if (!alias) /* blank line */
|
||||
- continue;
|
||||
- wwid = strtok_r(NULL, " \t", &saveptr);
|
||||
- if (!wwid) {
|
||||
- condlog(1, "invalid line %d in bindings file, missing WWID",
|
||||
- linenr);
|
||||
+ if (read_binding(line, ++linenr, &alias, &wwid)
|
||||
+ == READ_BINDING_SKIP)
|
||||
continue;
|
||||
- }
|
||||
- c = strtok_r(NULL, " \t", &saveptr);
|
||||
- if (c)
|
||||
- /* This is non-fatal */
|
||||
- condlog(1, "invalid line %d in bindings file, extra args \"%s\"",
|
||||
- linenr, c);
|
||||
|
||||
mpe_wwid = get_mpe_wwid(conf->mptable, alias);
|
||||
if (mpe_wwid && strcmp(mpe_wwid, wwid)) {
|
545
0018-libmultipath-keep-bindings-in-memory.patch
Normal file
545
0018-libmultipath-keep-bindings-in-memory.patch
Normal file
@ -0,0 +1,545 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Aug 2023 21:14:51 +0200
|
||||
Subject: [PATCH] libmultipath: keep bindings in memory
|
||||
|
||||
Rather than opening the bindings file every time we must retrieve
|
||||
a binding, keep the contents in memory and write the file only
|
||||
if additions have been made. This simplifies the code, and should speed up
|
||||
alias lookups significantly. As a side effect, the aliases will be stored
|
||||
sorted by alias, which changes the way aliases are allocated if there are
|
||||
unused "holes" in the sequence of aliases. For example, if the bindings file
|
||||
contains mpathb, mpathy, and mpatha, in this order, the next new alias used to
|
||||
be mpathz and is now mpathc.
|
||||
|
||||
Another side effect is that multipathd will not automatically pick up changes
|
||||
to the bindings file at runtime without a reconfigure operation. It is
|
||||
questionable whether these on-the-fly changes were a good idea in the first
|
||||
place, as inconsistent configurations may easily come to pass. It desired,
|
||||
it would be feasible to implement automatic update of the bindings using the
|
||||
existing inotify approach.
|
||||
|
||||
The new implementation of get_user_friendly_alias() is slightly different
|
||||
than before. The logic is summarized in a comment in the code. Unit tests
|
||||
will be provided that illustrate the changes.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 351 ++++++++++++++++-----------------------
|
||||
libmultipath/alias.h | 2 +-
|
||||
libmultipath/configure.c | 3 +-
|
||||
3 files changed, 144 insertions(+), 212 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index ecf4a2ac..d6563749 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -50,8 +50,6 @@
|
||||
"# alias wwid\n" \
|
||||
"#\n"
|
||||
|
||||
-static const char bindings_file_header[] = BINDINGS_FILE_HEADER;
|
||||
-
|
||||
struct binding {
|
||||
char *alias;
|
||||
char *wwid;
|
||||
@@ -80,6 +78,45 @@ static void _free_binding(struct binding *bdg)
|
||||
free(bdg);
|
||||
}
|
||||
|
||||
+static const struct binding *get_binding_for_alias(const Bindings *bindings,
|
||||
+ const char *alias)
|
||||
+{
|
||||
+ const struct binding *bdg;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!alias)
|
||||
+ return NULL;
|
||||
+ vector_foreach_slot(bindings, bdg, i) {
|
||||
+ if (!strncmp(bdg->alias, alias, WWID_SIZE)) {
|
||||
+ condlog(3, "Found matching alias [%s] in bindings file."
|
||||
+ " Setting wwid to %s", alias, bdg->wwid);
|
||||
+ return bdg;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ condlog(3, "No matching alias [%s] in bindings file.", alias);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static const struct binding *get_binding_for_wwid(const Bindings *bindings,
|
||||
+ const char *wwid)
|
||||
+{
|
||||
+ const struct binding *bdg;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!wwid)
|
||||
+ return NULL;
|
||||
+ vector_foreach_slot(bindings, bdg, i) {
|
||||
+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) {
|
||||
+ condlog(3, "Found matching wwid [%s] in bindings file."
|
||||
+ " Setting alias to %s", wwid, bdg->alias);
|
||||
+ return bdg;
|
||||
+ }
|
||||
+ }
|
||||
+ condlog(3, "No matching wwid [%s] in bindings file.", wwid);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
{
|
||||
struct binding *bdg;
|
||||
@@ -115,6 +152,24 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
return BINDING_ERROR;
|
||||
}
|
||||
|
||||
+static int delete_binding(Bindings *bindings, const char *wwid)
|
||||
+{
|
||||
+ struct binding *bdg;
|
||||
+ int i;
|
||||
+
|
||||
+ vector_foreach_slot(bindings, bdg, i) {
|
||||
+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) {
|
||||
+ _free_binding(bdg);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (i >= VECTOR_SIZE(bindings))
|
||||
+ return BINDING_NOTFOUND;
|
||||
+
|
||||
+ vector_del_slot(bindings, i);
|
||||
+ return BINDING_DELETED;
|
||||
+}
|
||||
+
|
||||
static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
{
|
||||
struct binding *bnd;
|
||||
@@ -267,38 +322,15 @@ static bool id_already_taken(int id, const char *prefix, const char *map_wwid)
|
||||
return alias_already_taken(alias, map_wwid);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Returns: 0 if matching entry in WWIDs file found
|
||||
- * -1 if an error occurs
|
||||
- * >0 a free ID that could be used for the WWID at hand
|
||||
- * *map_alias is set to a freshly allocated string with the matching alias if
|
||||
- * the function returns 0, or to NULL otherwise.
|
||||
- */
|
||||
-static int
|
||||
-lookup_binding(FILE *f, const char *map_wwid, char **map_alias,
|
||||
- const char *prefix, int check_if_taken)
|
||||
+int get_free_id(const Bindings *bindings, const char *prefix, const char *map_wwid)
|
||||
{
|
||||
- char buf[LINE_MAX];
|
||||
- unsigned int line_nr = 0;
|
||||
- int id = 1;
|
||||
+ const struct binding *bdg;
|
||||
+ int i, id = 1;
|
||||
int biggest_id = 1;
|
||||
int smallest_bigger_id = INT_MAX;
|
||||
|
||||
- *map_alias = NULL;
|
||||
-
|
||||
- rewind(f);
|
||||
- while (fgets(buf, LINE_MAX, f)) {
|
||||
- const char *alias, *wwid;
|
||||
- char *c, *saveptr;
|
||||
- int curr_id;
|
||||
-
|
||||
- line_nr++;
|
||||
- c = strpbrk(buf, "#\n\r");
|
||||
- if (c)
|
||||
- *c = '\0';
|
||||
- alias = strtok_r(buf, " \t", &saveptr);
|
||||
- if (!alias) /* blank line */
|
||||
- continue;
|
||||
+ vector_foreach_slot(bindings, bdg, i) {
|
||||
+ int curr_id = scan_devname(bdg->alias, prefix);
|
||||
|
||||
/*
|
||||
* Find an unused index - explanation of the algorithm
|
||||
@@ -333,8 +365,6 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias,
|
||||
* biggest_id is always > smallest_bigger_id, except in the
|
||||
* "perfectly ordered" case.
|
||||
*/
|
||||
-
|
||||
- curr_id = scan_devname(alias, prefix);
|
||||
if (curr_id == id) {
|
||||
if (id < INT_MAX)
|
||||
id++;
|
||||
@@ -345,36 +375,15 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias,
|
||||
}
|
||||
if (curr_id > biggest_id)
|
||||
biggest_id = curr_id;
|
||||
+
|
||||
if (curr_id > id && curr_id < smallest_bigger_id)
|
||||
smallest_bigger_id = curr_id;
|
||||
- wwid = strtok_r(NULL, " \t", &saveptr);
|
||||
- if (!wwid){
|
||||
- condlog(3,
|
||||
- "Ignoring malformed line %u in bindings file",
|
||||
- line_nr);
|
||||
- continue;
|
||||
- }
|
||||
- if (strcmp(wwid, map_wwid) == 0){
|
||||
- condlog(3, "Found matching wwid [%s] in bindings file."
|
||||
- " Setting alias to %s", wwid, alias);
|
||||
- *map_alias = strdup(alias);
|
||||
- if (*map_alias == NULL) {
|
||||
- condlog(0, "Cannot copy alias from bindings "
|
||||
- "file: out of memory");
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- if (!prefix && check_if_taken)
|
||||
- id = -1;
|
||||
- if (id >= smallest_bigger_id) {
|
||||
- if (biggest_id < INT_MAX)
|
||||
- id = biggest_id + 1;
|
||||
- else
|
||||
- id = -1;
|
||||
}
|
||||
- if (id > 0 && check_if_taken) {
|
||||
+
|
||||
+ if (id >= smallest_bigger_id)
|
||||
+ id = biggest_id < INT_MAX ? biggest_id + 1 : -1;
|
||||
+
|
||||
+ if (id > 0) {
|
||||
while(id_already_taken(id, prefix, map_wwid)) {
|
||||
if (id == INT_MAX) {
|
||||
id = -1;
|
||||
@@ -391,64 +400,17 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias,
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (id < 0) {
|
||||
+
|
||||
+ if (id < 0)
|
||||
condlog(0, "no more available user_friendly_names");
|
||||
- return -1;
|
||||
- } else
|
||||
- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid);
|
||||
return id;
|
||||
}
|
||||
|
||||
-static int
|
||||
-rlookup_binding(FILE *f, char *buff, const char *map_alias)
|
||||
-{
|
||||
- char line[LINE_MAX];
|
||||
- unsigned int line_nr = 0;
|
||||
-
|
||||
- buff[0] = '\0';
|
||||
-
|
||||
- while (fgets(line, LINE_MAX, f)) {
|
||||
- char *c, *saveptr;
|
||||
- const char *alias, *wwid;
|
||||
-
|
||||
- line_nr++;
|
||||
- c = strpbrk(line, "#\n\r");
|
||||
- if (c)
|
||||
- *c = '\0';
|
||||
- alias = strtok_r(line, " \t", &saveptr);
|
||||
- if (!alias) /* blank line */
|
||||
- continue;
|
||||
- wwid = strtok_r(NULL, " \t", &saveptr);
|
||||
- if (!wwid){
|
||||
- condlog(3,
|
||||
- "Ignoring malformed line %u in bindings file",
|
||||
- line_nr);
|
||||
- continue;
|
||||
- }
|
||||
- if (strlen(wwid) > WWID_SIZE - 1) {
|
||||
- condlog(3,
|
||||
- "Ignoring too large wwid at %u in bindings file", line_nr);
|
||||
- continue;
|
||||
- }
|
||||
- if (strcmp(alias, map_alias) == 0){
|
||||
- condlog(3, "Found matching alias [%s] in bindings file."
|
||||
- " Setting wwid to %s", alias, wwid);
|
||||
- strlcpy(buff, wwid, WWID_SIZE);
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- condlog(3, "No matching alias [%s] in bindings file.", map_alias);
|
||||
-
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
static char *
|
||||
-allocate_binding(int fd, const char *wwid, int id, const char *prefix)
|
||||
+allocate_binding(const char *filename, const char *wwid, int id, const char *prefix)
|
||||
{
|
||||
STRBUF_ON_STACK(buf);
|
||||
- off_t offset;
|
||||
- ssize_t len;
|
||||
- char *alias, *c;
|
||||
+ char *alias;
|
||||
|
||||
if (id <= 0) {
|
||||
condlog(0, "%s: cannot allocate new binding for id %d",
|
||||
@@ -460,164 +422,135 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix)
|
||||
format_devname(&buf, id) == -1)
|
||||
return NULL;
|
||||
|
||||
- if (print_strbuf(&buf, " %s\n", wwid) < 0)
|
||||
- return NULL;
|
||||
+ alias = steal_strbuf_str(&buf);
|
||||
|
||||
- offset = lseek(fd, 0, SEEK_END);
|
||||
- if (offset < 0){
|
||||
- condlog(0, "Cannot seek to end of bindings file : %s",
|
||||
- strerror(errno));
|
||||
+ if (add_binding(&global_bindings, alias, wwid) != BINDING_ADDED) {
|
||||
+ condlog(0, "%s: cannot allocate new binding %s for %s",
|
||||
+ __func__, alias, wwid);
|
||||
+ free(alias);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- len = get_strbuf_len(&buf);
|
||||
- alias = steal_strbuf_str(&buf);
|
||||
-
|
||||
- if (write(fd, alias, len) != len) {
|
||||
- condlog(0, "Cannot write binding to bindings file : %s",
|
||||
- strerror(errno));
|
||||
- /* clear partial write */
|
||||
- if (ftruncate(fd, offset))
|
||||
- condlog(0, "Cannot truncate the header : %s",
|
||||
- strerror(errno));
|
||||
+ if (update_bindings_file(&global_bindings, filename) == -1) {
|
||||
+ condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid);
|
||||
+ delete_binding(&global_bindings, wwid);
|
||||
free(alias);
|
||||
return NULL;
|
||||
}
|
||||
- c = strchr(alias, ' ');
|
||||
- if (c)
|
||||
- *c = '\0';
|
||||
|
||||
condlog(3, "Created new binding [%s] for WWID [%s]", alias, wwid);
|
||||
return alias;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * get_user_friendly_alias() action table
|
||||
+ *
|
||||
+ * The table shows the various cases, the actions taken, and the CI
|
||||
+ * functions from tests/alias.c that represent them.
|
||||
+ *
|
||||
+ * - O: old alias given
|
||||
+ * - A: old alias in table (y: yes, correct WWID; X: yes, wrong WWID)
|
||||
+ * - W: wwid in table
|
||||
+ *
|
||||
+ * | No | O | A | W | action | function gufa_X |
|
||||
+ * |----+---+---+---+--------------------------------------------+------------------------------|
|
||||
+ * | 1 | n | - | n | get new alias | nomatch_Y |
|
||||
+ * | 2 | n | - | y | use alias from bindings | match_a_Y |
|
||||
+ * | 3 | y | n | n | add binding for old alias | old_nomatch_nowwidmatch |
|
||||
+ * | 4 | y | n | y | use alias from bindings (avoid duplicates) | old_nomatch_wwidmatch |
|
||||
+ * | 5 | y | y | n | [ impossible ] | - |
|
||||
+ * | 6 | y | y | y | use old alias == alias from bindings | old_match |
|
||||
+ * | 7 | y | X | n | get new alias | old_match_other |
|
||||
+ * | 8 | y | X | y | use alias from bindings | old_match_other_wwidmatch |
|
||||
+ *
|
||||
+ * Notes:
|
||||
+ * - "use alias from bindings" means that the alias from the bindings file will
|
||||
+ * be tried; if it is in use, the alias selection will fail. No other
|
||||
+ * bindings will be attempted.
|
||||
+ * - "get new alias" fails if all aliases are used up, or if writing the
|
||||
+ * bindings file fails.
|
||||
+ * - if "alias_old" is set, it can't be bound to a different map. alias_old is
|
||||
+ * initialized in find_existing_alias() by scanning the mpvec. We trust
|
||||
+ * that the mpvec corrcectly represents kernel state.
|
||||
+ */
|
||||
+
|
||||
char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old,
|
||||
const char *prefix, bool bindings_read_only)
|
||||
{
|
||||
char *alias = NULL;
|
||||
int id = 0;
|
||||
- int fd, can_write;
|
||||
bool new_binding = false;
|
||||
- char buff[WWID_SIZE];
|
||||
- FILE *f;
|
||||
-
|
||||
- fd = open_file(file, &can_write, bindings_file_header);
|
||||
- if (fd < 0)
|
||||
- return NULL;
|
||||
-
|
||||
- f = fdopen(fd, "r");
|
||||
- if (!f) {
|
||||
- condlog(0, "cannot fdopen on bindings file descriptor");
|
||||
- close(fd);
|
||||
- return NULL;
|
||||
- }
|
||||
+ const struct binding *bdg;
|
||||
|
||||
- if (!strlen(alias_old))
|
||||
+ if (!*alias_old)
|
||||
goto new_alias;
|
||||
|
||||
- /* lookup the binding. if it exists, the wwid will be in buff
|
||||
- * either way, id contains the id for the alias
|
||||
- */
|
||||
- rlookup_binding(f, buff, alias_old);
|
||||
-
|
||||
- if (strlen(buff) > 0) {
|
||||
- /* If buff is our wwid, it's already allocated correctly. */
|
||||
- if (strcmp(buff, wwid) == 0) {
|
||||
+ /* See if there's a binding matching both alias_old and wwid */
|
||||
+ bdg = get_binding_for_alias(&global_bindings, alias_old);
|
||||
+ if (bdg) {
|
||||
+ if (!strcmp(bdg->wwid, wwid)) {
|
||||
alias = strdup(alias_old);
|
||||
goto out;
|
||||
-
|
||||
} else {
|
||||
condlog(0, "alias %s already bound to wwid %s, cannot reuse",
|
||||
- alias_old, buff);
|
||||
+ alias_old, bdg->wwid);
|
||||
goto new_alias;
|
||||
}
|
||||
}
|
||||
|
||||
- /*
|
||||
- * 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) {
|
||||
- if (alias_already_taken(alias, wwid)) {
|
||||
- free(alias);
|
||||
- alias = NULL;
|
||||
- } else
|
||||
+ /* allocate the existing alias in the bindings file */
|
||||
+ id = scan_devname(alias_old, prefix);
|
||||
+
|
||||
+new_alias:
|
||||
+ /* Check for existing binding of WWID */
|
||||
+ bdg = get_binding_for_wwid(&global_bindings, wwid);
|
||||
+ if (bdg) {
|
||||
+ if (!alias_already_taken(bdg->alias, wwid)) {
|
||||
condlog(3, "Use existing binding [%s] for WWID [%s]",
|
||||
- alias, wwid);
|
||||
+ bdg->alias, wwid);
|
||||
+ alias = strdup(bdg->alias);
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* 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;
|
||||
- }
|
||||
+ id = get_free_id(&global_bindings, prefix, wwid);
|
||||
if (id <= 0)
|
||||
goto out;
|
||||
else
|
||||
new_binding = true;
|
||||
}
|
||||
|
||||
- if (fflush(f) != 0) {
|
||||
- condlog(0, "cannot fflush bindings file stream : %s",
|
||||
- strerror(errno));
|
||||
- goto out;
|
||||
- }
|
||||
+ if (!bindings_read_only && id > 0)
|
||||
+ alias = allocate_binding(file, wwid, id, prefix);
|
||||
|
||||
- if (can_write && !bindings_read_only) {
|
||||
- alias = allocate_binding(fd, wwid, id, prefix);
|
||||
- if (alias && !new_binding)
|
||||
- condlog(2, "Allocated existing binding [%s] for WWID [%s]",
|
||||
- alias, wwid);
|
||||
- }
|
||||
+ if (alias && !new_binding)
|
||||
+ condlog(2, "Allocated existing binding [%s] for WWID [%s]",
|
||||
+ alias, wwid);
|
||||
|
||||
out:
|
||||
- pthread_cleanup_push(free, alias);
|
||||
- fclose(f);
|
||||
- pthread_cleanup_pop(0);
|
||||
return alias;
|
||||
}
|
||||
|
||||
-int
|
||||
-get_user_friendly_wwid(const char *alias, char *buff, const char *file)
|
||||
+int get_user_friendly_wwid(const char *alias, char *buff)
|
||||
{
|
||||
- int fd, unused;
|
||||
- FILE *f;
|
||||
+ const struct binding *bdg;
|
||||
|
||||
if (!alias || *alias == '\0') {
|
||||
condlog(3, "Cannot find binding for empty alias");
|
||||
return -1;
|
||||
}
|
||||
|
||||
- fd = open_file(file, &unused, bindings_file_header);
|
||||
- if (fd < 0)
|
||||
- return -1;
|
||||
-
|
||||
- f = fdopen(fd, "r");
|
||||
- if (!f) {
|
||||
- condlog(0, "cannot fdopen on bindings file descriptor : %s",
|
||||
- strerror(errno));
|
||||
- close(fd);
|
||||
+ bdg = get_binding_for_alias(&global_bindings, alias);
|
||||
+ if (!bdg) {
|
||||
+ *buff = '\0';
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- rlookup_binding(f, buff, alias);
|
||||
- if (!strlen(buff)) {
|
||||
- fclose(f);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- fclose(f);
|
||||
+ strlcpy(buff, bdg->wwid, WWID_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/libmultipath/alias.h b/libmultipath/alias.h
|
||||
index 37b49d9c..5ef6720b 100644
|
||||
--- a/libmultipath/alias.h
|
||||
+++ b/libmultipath/alias.h
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _ALIAS_H
|
||||
|
||||
int valid_alias(const char *alias);
|
||||
-int get_user_friendly_wwid(const char *alias, char *buff, const char *file);
|
||||
+int get_user_friendly_wwid(const char *alias, char *buff);
|
||||
char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
const char *alias_old,
|
||||
const char *prefix, bool bindings_read_only);
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 029fbbd2..d8094903 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1378,8 +1378,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev,
|
||||
refwwid = tmpwwid;
|
||||
|
||||
/* or may be a binding */
|
||||
- else if (get_user_friendly_wwid(dev, tmpwwid,
|
||||
- conf->bindings_file) == 0)
|
||||
+ else if (get_user_friendly_wwid(dev, tmpwwid) == 0)
|
||||
refwwid = tmpwwid;
|
||||
|
||||
/* or may be an alias */
|
1698
0019-multipath-tools-tests-fix-alias-tests.patch
Normal file
1698
0019-multipath-tools-tests-fix-alias-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 25 Aug 2023 20:35:19 +0200
|
||||
Subject: [PATCH] libmultipath: dm_get_uuid(): return emtpy UUID for
|
||||
non-existing maps
|
||||
|
||||
libdevmapper will most probably not return a UUID for non-existing
|
||||
maps anyway. But it's cheap to double-check here.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 248c3734..9be82f4e 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -706,12 +706,16 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
const char *uuidtmp;
|
||||
+ struct dm_info info;
|
||||
int r = 1;
|
||||
|
||||
dmt = libmp_dm_task_create(DM_DEVICE_INFO);
|
||||
if (!dmt)
|
||||
return 1;
|
||||
|
||||
+ if (uuid_len > 0)
|
||||
+ uuid[0] = '\0';
|
||||
+
|
||||
if (!dm_task_set_name (dmt, name))
|
||||
goto uuidout;
|
||||
|
||||
@@ -720,11 +724,13 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len)
|
||||
goto uuidout;
|
||||
}
|
||||
|
||||
+ if (!dm_task_get_info(dmt, &info) ||
|
||||
+ !info.exists)
|
||||
+ goto uuidout;
|
||||
+
|
||||
uuidtmp = dm_task_get_uuid(dmt);
|
||||
if (uuidtmp)
|
||||
strlcpy(uuid, uuidtmp, uuid_len);
|
||||
- else
|
||||
- uuid[0] = '\0';
|
||||
|
||||
r = 0;
|
||||
uuidout:
|
158
0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch
Normal file
158
0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 28 Aug 2023 12:26:37 +0200
|
||||
Subject: [PATCH] libmultipath: adapt to new semantics of dm_get_uuid()
|
||||
|
||||
dm_get_uuid() will return 1 for non-existing maps. Thus we don't need
|
||||
to call dm_map_present() any more in alias_already_taken(). This changes
|
||||
our semantics: previously we'd avoid using an alias for which dm_get_uuid()
|
||||
had failed. Now we treat failure in dm_get_uuid() as indication that the
|
||||
map doesn't exist. This is not dangerous because dm_task_get_uuid() cannot
|
||||
fail, and thus the modified dm_get_uuid() will fail if and only if
|
||||
dm_map_present() would return false.
|
||||
|
||||
This makes the "failed alias" test mostly obsolete, as "failed" is now
|
||||
treated as "unused".
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 25 +++++++++++++------------
|
||||
tests/alias.c | 32 +++++++-------------------------
|
||||
2 files changed, 20 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index d6563749..58436ec0 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -295,18 +295,19 @@ scan_devname(const char *alias, const char *prefix)
|
||||
static bool alias_already_taken(const char *alias, const char *map_wwid)
|
||||
{
|
||||
|
||||
- if (dm_map_present(alias)) {
|
||||
- char wwid[WWID_SIZE];
|
||||
-
|
||||
- /* If both the name and the wwid match, then it's fine.*/
|
||||
- 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, reselecting alias",
|
||||
- map_wwid, alias);
|
||||
- return true;
|
||||
- }
|
||||
- return false;
|
||||
+ char wwid[WWID_SIZE];
|
||||
+
|
||||
+ /* If the map doesn't exist, it's fine */
|
||||
+ if (dm_get_uuid(alias, wwid, sizeof(wwid)) != 0)
|
||||
+ return false;
|
||||
+
|
||||
+ /* If both the name and the wwid match, it's fine.*/
|
||||
+ if (strncmp(map_wwid, wwid, sizeof(wwid)) == 0)
|
||||
+ return false;
|
||||
+
|
||||
+ condlog(3, "%s: alias '%s' already taken, reselecting alias",
|
||||
+ map_wwid, alias);
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static bool id_already_taken(int id, const char *prefix, const char *map_wwid)
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 50a21ecf..d1cc487b 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -73,12 +73,6 @@ int __wrap_mkstemp(char *template)
|
||||
return 10;
|
||||
}
|
||||
|
||||
-int __wrap_dm_map_present(const char * str)
|
||||
-{
|
||||
- check_expected(str);
|
||||
- return mock_type(int);
|
||||
-}
|
||||
-
|
||||
int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len)
|
||||
{
|
||||
int ret;
|
||||
@@ -398,14 +392,13 @@ static int test_scan_devname(void)
|
||||
|
||||
static void mock_unused_alias(const char *alias)
|
||||
{
|
||||
- expect_string(__wrap_dm_map_present, str, alias);
|
||||
- will_return(__wrap_dm_map_present, 0);
|
||||
+ expect_string(__wrap_dm_get_uuid, name, alias);
|
||||
+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE);
|
||||
+ will_return(__wrap_dm_get_uuid, 1);
|
||||
}
|
||||
|
||||
static void mock_self_alias(const char *alias, const char *wwid)
|
||||
{
|
||||
- expect_string(__wrap_dm_map_present, str, alias);
|
||||
- will_return(__wrap_dm_map_present, 1);
|
||||
expect_string(__wrap_dm_get_uuid, name, alias);
|
||||
expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE);
|
||||
will_return(__wrap_dm_get_uuid, 0);
|
||||
@@ -432,18 +425,13 @@ static void mock_self_alias(const char *alias, const char *wwid)
|
||||
|
||||
#define mock_failed_alias(alias, wwid) \
|
||||
do { \
|
||||
- expect_string(__wrap_dm_map_present, str, alias); \
|
||||
- will_return(__wrap_dm_map_present, 1); \
|
||||
expect_string(__wrap_dm_get_uuid, name, alias); \
|
||||
expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \
|
||||
will_return(__wrap_dm_get_uuid, 1); \
|
||||
- expect_condlog(3, USED_STR(alias, wwid)); \
|
||||
} while (0)
|
||||
|
||||
#define mock_used_alias(alias, wwid) \
|
||||
do { \
|
||||
- expect_string(__wrap_dm_map_present, str, alias); \
|
||||
- will_return(__wrap_dm_map_present, 1); \
|
||||
expect_string(__wrap_dm_get_uuid, name, alias); \
|
||||
expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \
|
||||
will_return(__wrap_dm_get_uuid, 0); \
|
||||
@@ -566,9 +554,8 @@ static void lb_empty_failed(void **state)
|
||||
mock_bindings_file("");
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
mock_failed_alias("MPATHa", "WWID0");
|
||||
- mock_unused_alias("MPATHb");
|
||||
rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, 2);
|
||||
+ assert_int_equal(rc, 1);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
free(alias);
|
||||
}
|
||||
@@ -666,9 +653,8 @@ static void lb_nomatch_a_3_used_failed_self(void **state)
|
||||
mock_used_alias("MPATHc", "WWID1");
|
||||
mock_used_alias("MPATHd", "WWID1");
|
||||
mock_failed_alias("MPATHe", "WWID1");
|
||||
- mock_self_alias("MPATHf", "WWID1");
|
||||
rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, 6);
|
||||
+ assert_int_equal(rc, 5);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -940,7 +926,7 @@ static void lb_nomatch_b_a_aa(void **state)
|
||||
|
||||
static void lb_nomatch_b_a_aa_zz(void **state)
|
||||
{
|
||||
- int rc, i;
|
||||
+ int rc;
|
||||
char *alias;
|
||||
STRBUF_ON_STACK(buf);
|
||||
|
||||
@@ -949,11 +935,7 @@ static void lb_nomatch_b_a_aa_zz(void **state)
|
||||
* lookup_binding finds MPATHaaa as next free entry, because MPATHaa is
|
||||
* found before MPATHb, and MPATHzz was in the bindings, too.
|
||||
*/
|
||||
- for (i = 0; i <= 26; i++) {
|
||||
- print_strbuf(&buf, "MPATH");
|
||||
- format_devname(&buf, i + 1);
|
||||
- print_strbuf(&buf, " WWID%d\n", i);
|
||||
- }
|
||||
+ fill_bindings(&buf, 0, 26);
|
||||
print_strbuf(&buf, "MPATHzz WWID676\n");
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID703"));
|
98
0022-libmultipath-sort-aliases-by-length-and-strcmp.patch
Normal file
98
0022-libmultipath-sort-aliases-by-length-and-strcmp.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 15:19:54 +0200
|
||||
Subject: [PATCH] libmultipath: sort aliases by length and strcmp
|
||||
|
||||
The current sort order of aliases is alphabetical, which is does not match
|
||||
the actual order of aliases, where "mpathaa" > "mpathz". Change the ordering as
|
||||
follows: first sort by string length, then alphabetically. This will make
|
||||
sure that for aliases with the same prefix, alias order is correct ("mpathaaa"
|
||||
will be sorted after "mpathzz", etc). Even for mixed prefixes, the alias
|
||||
order will be correct for every individual prefix, even though aliases with
|
||||
different prefixes may alternate in the file.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 45 +++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 34 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 58436ec0..af6565b1 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -117,6 +117,35 @@ static const struct binding *get_binding_for_wwid(const Bindings *bindings,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Sort order for aliases.
|
||||
+ *
|
||||
+ * The "numeric" ordering of aliases for a given prefix P is
|
||||
+ * Pa, ..., Pz, Paa, ..., Paz, Pba, ... , Pzz, Paaa, ..., Pzzz, Paaaa, ...
|
||||
+ * We use the fact that for equal prefix, longer strings are always
|
||||
+ * higher than shorter ones. Strings of equal length are sorted alphabetically.
|
||||
+ * This is achieved by sorting be length first, then using strcmp().
|
||||
+ * If multiple prefixes are in use, the aliases with a given prefix will
|
||||
+ * not necessarily be in a contiguous range of the vector, but they will
|
||||
+ * be ordered such that for a given prefix, numercally higher aliases will
|
||||
+ * always be sorted after lower ones.
|
||||
+ */
|
||||
+static int alias_compar(const void *p1, const void *p2)
|
||||
+{
|
||||
+ const char *alias1 = *((char * const *)p1);
|
||||
+ const char *alias2 = *((char * const *)p2);
|
||||
+
|
||||
+ if (alias1 && alias2) {
|
||||
+ ssize_t ldif = strlen(alias1) - strlen(alias2);
|
||||
+
|
||||
+ if (ldif)
|
||||
+ return ldif;
|
||||
+ return strcmp(alias1, alias2);
|
||||
+ } else
|
||||
+ /* Move NULL alias to the end */
|
||||
+ return alias1 ? -1 : alias2 ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
{
|
||||
struct binding *bdg;
|
||||
@@ -128,7 +157,7 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid)
|
||||
* sorted already.
|
||||
*/
|
||||
vector_foreach_slot_backwards(bindings, bdg, i) {
|
||||
- if ((cmp = strcmp(bdg->alias, alias)) <= 0)
|
||||
+ if ((cmp = alias_compar(&bdg->alias, &alias)) <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -657,16 +686,10 @@ static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int alias_compar(const void *p1, const void *p2)
|
||||
+static int mp_alias_compar(const void *p1, const void *p2)
|
||||
{
|
||||
- const char *alias1 = (*(struct mpentry * const *)p1)->alias;
|
||||
- const char *alias2 = (*(struct mpentry * const *)p2)->alias;
|
||||
-
|
||||
- if (alias1 && alias2)
|
||||
- return strcmp(alias1, alias2);
|
||||
- else
|
||||
- /* Move NULL alias to the end */
|
||||
- return alias1 ? -1 : alias2 ? 1 : 0;
|
||||
+ return alias_compar(&((*(struct mpentry * const *)p1)->alias),
|
||||
+ &((*(struct mpentry * const *)p2)->alias));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -700,7 +723,7 @@ int check_alias_settings(const struct config *conf)
|
||||
pthread_cleanup_push_cast(free_bindings, &bindings);
|
||||
pthread_cleanup_push(cleanup_vector_free, mptable);
|
||||
|
||||
- vector_sort(mptable, alias_compar);
|
||||
+ vector_sort(mptable, mp_alias_compar);
|
||||
vector_foreach_slot(mptable, mpe, i) {
|
||||
if (!mpe->alias)
|
||||
/*
|
@ -0,0 +1,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 15:46:02 +0200
|
||||
Subject: [PATCH] multipath-tools tests: fix alias test after sort order change
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 30 ++++++++++++------------------
|
||||
1 file changed, 12 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index d1cc487b..8ed95d7a 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -932,16 +932,15 @@ static void lb_nomatch_b_a_aa_zz(void **state)
|
||||
|
||||
/*
|
||||
* add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...)
|
||||
- * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is
|
||||
- * found before MPATHb, and MPATHzz was in the bindings, too.
|
||||
+ * lookup_binding finds MPATHab as next free entry.
|
||||
*/
|
||||
fill_bindings(&buf, 0, 26);
|
||||
print_strbuf(&buf, "MPATHzz WWID676\n");
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID703"));
|
||||
- mock_unused_alias("MPATHaaa");
|
||||
+ mock_unused_alias("MPATHab");
|
||||
rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, 703);
|
||||
+ assert_int_equal(rc, 28);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -998,13 +997,8 @@ static void lb_nomatch_b_a_3_used(void **state)
|
||||
|
||||
#ifdef MPATH_ID_INT_MAX
|
||||
/*
|
||||
- * The bindings will be sorted by alias, alphabetically, which is not
|
||||
- * the same as the "numeric" sort order for user-friendly aliases.
|
||||
- * get_free_id() selects the highest used ID + 1 if an unsorted entry
|
||||
- * is encountered in the bindings table and it's id is equal to the
|
||||
- * next "expected" id. This happens if all IDs from "a" to "aa" are
|
||||
- * in the table. If the INT_MAX entry is in the table, too, it will
|
||||
- * overflow.
|
||||
+ * The bindings will be sorted by alias. Therefore we have no chance to
|
||||
+ * simulate a "full" table.
|
||||
*/
|
||||
static void lb_nomatch_int_max(void **state)
|
||||
{
|
||||
@@ -1016,9 +1010,9 @@ static void lb_nomatch_int_max(void **state)
|
||||
print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX);
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE"));
|
||||
- expect_condlog(0, NOMORE_STR);
|
||||
+ mock_unused_alias("MPATHab");
|
||||
rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, -1);
|
||||
+ assert_int_equal(rc, 28);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1049,9 +1043,9 @@ static void lb_nomatch_int_max_m1(void **state)
|
||||
print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
|
||||
- mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
|
||||
+ mock_unused_alias("MPATHab");
|
||||
rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, INT_MAX);
|
||||
+ assert_int_equal(rc, 28);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1065,10 +1059,10 @@ static void lb_nomatch_int_max_m1_used(void **state)
|
||||
print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
|
||||
- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX");
|
||||
- expect_condlog(0, NOMORE_STR);
|
||||
+ mock_used_alias("MPATHab", "WWIDMAX");
|
||||
+ mock_unused_alias("MPATHac");
|
||||
rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, -1);
|
||||
+ assert_int_equal(rc, 29);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
122
0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch
Normal file
122
0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 19:50:51 +0200
|
||||
Subject: [PATCH] libmultipath: simplify get_free_id() assuming total ordering
|
||||
|
||||
If we can assume that the bindings array is totally ordered for every
|
||||
prefix, which the previous patch guarantees, the search for a free ID can be
|
||||
simplified.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 85 ++++++++++----------------------------------
|
||||
1 file changed, 18 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index af6565b1..66e34e31 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -356,83 +356,34 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww
|
||||
{
|
||||
const struct binding *bdg;
|
||||
int i, id = 1;
|
||||
- int biggest_id = 1;
|
||||
- int smallest_bigger_id = INT_MAX;
|
||||
|
||||
vector_foreach_slot(bindings, bdg, i) {
|
||||
int curr_id = scan_devname(bdg->alias, prefix);
|
||||
|
||||
- /*
|
||||
- * Find an unused index - explanation of the algorithm
|
||||
- *
|
||||
- * ID: 1 = mpatha, 2 = mpathb, ...
|
||||
- *
|
||||
- * We assume the bindings are unsorted. The only constraint
|
||||
- * is that no ID occurs more than once. IDs that occur in the
|
||||
- * bindings are called "used".
|
||||
- *
|
||||
- * We call the list 1,2,3,..., exactly in this order, the list
|
||||
- * of "expected" IDs. The variable "id" always holds the next
|
||||
- * "expected" ID, IOW the last "expected" ID encountered plus 1.
|
||||
- * Thus all IDs below "id" are known to be used. However, at the
|
||||
- * end of the loop, the value of "id" isn't necessarily unused.
|
||||
- *
|
||||
- * "smallest_bigger_id" is the smallest used ID that was
|
||||
- * encountered while it was larger than the next "expected" ID
|
||||
- * at that iteration. Let X be some used ID. If all IDs below X
|
||||
- * are used and encountered in the right sequence before X, "id"
|
||||
- * will be > X when the loop ends. Otherwise, X was encountered
|
||||
- * "out of order", the condition (X > id) holds when X is
|
||||
- * encountered, and "smallest_bigger_id" will be set to X; i.e.
|
||||
- * it will be less or equal than X when the loop ends.
|
||||
- *
|
||||
- * At the end of the loop, (id < smallest_bigger_id) means that
|
||||
- * the value of "id" had been encountered neither in order nor
|
||||
- * out of order, and is thus unused. (id >= smallest_bigger_id)
|
||||
- * means that "id"'s value is in use. In this case, we play safe
|
||||
- * and use "biggest_id + 1" as the next value to try.
|
||||
- *
|
||||
- * biggest_id is always > smallest_bigger_id, except in the
|
||||
- * "perfectly ordered" case.
|
||||
- */
|
||||
- if (curr_id == id) {
|
||||
- if (id < INT_MAX)
|
||||
- id++;
|
||||
- else {
|
||||
- id = -1;
|
||||
- break;
|
||||
- }
|
||||
+ if (curr_id == -1)
|
||||
+ continue;
|
||||
+ if (id > curr_id) {
|
||||
+ condlog(0, "%s: ERROR: bindings are not sorted", __func__);
|
||||
+ return -1;
|
||||
}
|
||||
- if (curr_id > biggest_id)
|
||||
- biggest_id = curr_id;
|
||||
-
|
||||
- if (curr_id > id && curr_id < smallest_bigger_id)
|
||||
- smallest_bigger_id = curr_id;
|
||||
+ while (id < curr_id && id_already_taken(id, prefix, map_wwid))
|
||||
+ id++;
|
||||
+ if (id < curr_id)
|
||||
+ return id;
|
||||
+ id++;
|
||||
+ if (id <= 0)
|
||||
+ break;
|
||||
}
|
||||
|
||||
- if (id >= smallest_bigger_id)
|
||||
- id = biggest_id < INT_MAX ? biggest_id + 1 : -1;
|
||||
-
|
||||
- if (id > 0) {
|
||||
- while(id_already_taken(id, prefix, map_wwid)) {
|
||||
- if (id == INT_MAX) {
|
||||
- id = -1;
|
||||
- break;
|
||||
- }
|
||||
- id++;
|
||||
- if (id == smallest_bigger_id) {
|
||||
- if (biggest_id == INT_MAX) {
|
||||
- id = -1;
|
||||
- break;
|
||||
- }
|
||||
- if (biggest_id >= smallest_bigger_id)
|
||||
- id = biggest_id + 1;
|
||||
- }
|
||||
- }
|
||||
+ for (; id > 0; id++) {
|
||||
+ if (!id_already_taken(id, prefix, map_wwid))
|
||||
+ break;
|
||||
}
|
||||
|
||||
- if (id < 0)
|
||||
+ if (id <= 0) {
|
||||
+ id = -1;
|
||||
condlog(0, "no more available user_friendly_names");
|
||||
+ }
|
||||
return id;
|
||||
}
|
||||
|
203
0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch
Normal file
203
0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 19:58:03 +0200
|
||||
Subject: [PATCH] multipath-tools tests: adapt alias tests for total ordering
|
||||
|
||||
The "unsorted" test fail now, and are removed. The algorithm is now
|
||||
better at finding "gaps".
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 88 ++++++++-------------------------------------------
|
||||
1 file changed, 14 insertions(+), 74 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 8ed95d7a..dff5f93b 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -439,27 +439,7 @@ static void mock_self_alias(const char *alias, const char *wwid)
|
||||
expect_condlog(3, USED_STR(alias, wwid)); \
|
||||
} while(0)
|
||||
|
||||
-static int add_binding_unsorted(Bindings *bindings,
|
||||
- const char *alias, const char *wwid)
|
||||
-{
|
||||
- struct binding *bdg = calloc(1, sizeof(*bdg));
|
||||
-
|
||||
- if (!bdg)
|
||||
- return -1;
|
||||
- bdg->wwid = strdup(wwid);
|
||||
- bdg->alias = strdup(alias);
|
||||
- if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) {
|
||||
- free(bdg->alias);
|
||||
- free(bdg->wwid);
|
||||
- free(bdg);
|
||||
- return BINDING_ERROR;
|
||||
- }
|
||||
- vector_set_slot(bindings, bdg);
|
||||
- return BINDING_ADDED;
|
||||
-}
|
||||
-
|
||||
-static void __mock_bindings_file(const char *content,
|
||||
- int (*add)(Bindings *, const char *, const char *))
|
||||
+static void __mock_bindings_file(const char *content)
|
||||
{
|
||||
char *cnt __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
char *token, *savep = NULL;
|
||||
@@ -478,17 +458,13 @@ static void __mock_bindings_file(const char *content,
|
||||
== READ_BINDING_SKIP)
|
||||
continue;
|
||||
|
||||
- rc = add(&global_bindings, alias, wwid);
|
||||
+ rc = add_binding(&global_bindings, alias, wwid);
|
||||
assert_int_equal(rc, BINDING_ADDED);
|
||||
}
|
||||
}
|
||||
|
||||
static void mock_bindings_file(const char *content) {
|
||||
- return __mock_bindings_file(content, add_binding);
|
||||
-}
|
||||
-
|
||||
-static void mock_bindings_file_unsorted(const char *content) {
|
||||
- return __mock_bindings_file(content, add_binding_unsorted);
|
||||
+ return __mock_bindings_file(content);
|
||||
}
|
||||
|
||||
static int teardown_bindings(void **state)
|
||||
@@ -861,10 +837,6 @@ static void lb_nomatch_b_z_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- /*
|
||||
- * add_bindings() sorts alphabetically. Therefore get_free_id()
|
||||
- * finds MPATHc as a free entry.
|
||||
- */
|
||||
mock_bindings_file("MPATHb WWID1\n"
|
||||
"MPATHz WWID26\n"
|
||||
"MPATHa WWID0\n");
|
||||
@@ -880,10 +852,6 @@ static void lb_nomatch_b_aa_a(void **state)
|
||||
int rc;
|
||||
char *alias;
|
||||
|
||||
- /*
|
||||
- * add_bindings() sorts alphabetically. ("a", "aa", b").
|
||||
- * The get_free_id() algorithm finds the "hole" after "b".
|
||||
- */
|
||||
mock_bindings_file("MPATHb WWID1\n"
|
||||
"MPATHz WWID26\n"
|
||||
"MPATHa WWID0\n");
|
||||
@@ -911,10 +879,6 @@ static void lb_nomatch_b_a_aa(void **state)
|
||||
char *alias;
|
||||
STRBUF_ON_STACK(buf);
|
||||
|
||||
- /*
|
||||
- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...)
|
||||
- * lookup_binding finds MPATHac as next free entry.
|
||||
- */
|
||||
fill_bindings(&buf, 0, 26);
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID28"));
|
||||
@@ -930,10 +894,6 @@ static void lb_nomatch_b_a_aa_zz(void **state)
|
||||
char *alias;
|
||||
STRBUF_ON_STACK(buf);
|
||||
|
||||
- /*
|
||||
- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...)
|
||||
- * lookup_binding finds MPATHab as next free entry.
|
||||
- */
|
||||
fill_bindings(&buf, 0, 26);
|
||||
print_strbuf(&buf, "MPATHzz WWID676\n");
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
@@ -944,25 +904,6 @@ static void lb_nomatch_b_a_aa_zz(void **state)
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
-static void lb_nomatch_b_z_a_unsorted(void **state)
|
||||
-{
|
||||
- int rc;
|
||||
- char *alias;
|
||||
-
|
||||
- /*
|
||||
- * With unsorted bindings (shouldn't happen normally), get_free_id()
|
||||
- * plays safe and returns MPATHaa as first free entry.
|
||||
- */
|
||||
- mock_bindings_file_unsorted("MPATHb WWID1\n"
|
||||
- "MPATHz WWID26\n"
|
||||
- "MPATHa WWID0\n");
|
||||
- expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
|
||||
- mock_unused_alias("MPATHaa");
|
||||
- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, 27);
|
||||
- assert_ptr_equal(alias, NULL);
|
||||
-}
|
||||
-
|
||||
static void lb_nomatch_b_a(void **state)
|
||||
{
|
||||
int rc;
|
||||
@@ -1027,9 +968,9 @@ static void lb_nomatch_int_max_used(void **state)
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE"));
|
||||
mock_used_alias("MPATHa", "WWIDNOMORE");
|
||||
- expect_condlog(0, NOMORE_STR);
|
||||
+ mock_unused_alias("MPATHab");
|
||||
rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, -1);
|
||||
+ assert_int_equal(rc, 28);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1077,9 +1018,9 @@ static void lb_nomatch_int_max_m1_1_used(void **state)
|
||||
mock_bindings_file(get_strbuf_str(&buf));
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
|
||||
mock_used_alias("MPATHa", "WWIDMAX");
|
||||
- mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
|
||||
+ mock_unused_alias("MPATHab");
|
||||
rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, INT_MAX);
|
||||
+ assert_int_equal(rc, 28);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1095,10 +1036,10 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
|
||||
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
|
||||
mock_used_alias("MPATHa", "WWIDMAX");
|
||||
- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX");
|
||||
- expect_condlog(0, NOMORE_STR);
|
||||
+ mock_used_alias("MPATHab", "WWIDMAX");
|
||||
+ mock_unused_alias("MPATHac");
|
||||
rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
|
||||
- assert_int_equal(rc, -1);
|
||||
+ assert_int_equal(rc, 29);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
#endif
|
||||
@@ -1133,7 +1074,6 @@ static int test_lookup_binding(void)
|
||||
cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings),
|
||||
cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings),
|
||||
cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings),
|
||||
- cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings),
|
||||
cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings),
|
||||
cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings),
|
||||
#ifdef MPATH_ID_INT_MAX
|
||||
@@ -1593,14 +1533,14 @@ static void gufa_nomatch_b_f_a(void **state) {
|
||||
"MPATHf WWID6\n"
|
||||
"MPATHa WWID0\n");
|
||||
|
||||
- mock_bindings_file_unsorted(bindings);
|
||||
+ mock_bindings_file(bindings);
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID7"));
|
||||
- mock_unused_alias("MPATHg");
|
||||
+ mock_unused_alias("MPATHc");
|
||||
|
||||
- mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1);
|
||||
+ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1);
|
||||
|
||||
alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
|
||||
- assert_string_equal(alias, "MPATHg");
|
||||
+ assert_string_equal(alias, "MPATHc");
|
||||
free(alias);
|
||||
}
|
||||
|
275
0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch
Normal file
275
0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch
Normal file
@ -0,0 +1,275 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 21:39:44 +0200
|
||||
Subject: [PATCH] multipath-tools tests: add test for ordering of bindings
|
||||
|
||||
As the assignment of free aliases now relies on the bindings being
|
||||
properly sorted, add some unit tests to make sure the sorting algorithm
|
||||
works.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/alias.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 209 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index dff5f93b..7f3ff38a 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "globals.c"
|
||||
#include "../libmultipath/alias.c"
|
||||
|
||||
+/* For verbose printing of all aliases in the ordering tests */
|
||||
+#define ALIAS_DEBUG 0
|
||||
+
|
||||
#if INT_MAX == 0x7fffffff
|
||||
/* user_friendly_name for map #INT_MAX */
|
||||
#define MPATH_ID_INT_MAX "fxshrxw"
|
||||
@@ -439,11 +442,12 @@ static void mock_self_alias(const char *alias, const char *wwid)
|
||||
expect_condlog(3, USED_STR(alias, wwid)); \
|
||||
} while(0)
|
||||
|
||||
-static void __mock_bindings_file(const char *content)
|
||||
+static void __mock_bindings_file(const char *content, bool conflict_ok)
|
||||
{
|
||||
char *cnt __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
char *token, *savep = NULL;
|
||||
int i;
|
||||
+ uintmax_t values[] = { BINDING_ADDED, BINDING_CONFLICT };
|
||||
|
||||
cnt = strdup(content);
|
||||
assert_ptr_not_equal(cnt, NULL);
|
||||
@@ -459,12 +463,12 @@ static void __mock_bindings_file(const char *content)
|
||||
continue;
|
||||
|
||||
rc = add_binding(&global_bindings, alias, wwid);
|
||||
- assert_int_equal(rc, BINDING_ADDED);
|
||||
+ assert_in_set(rc, values, conflict_ok ? 2 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mock_bindings_file(const char *content) {
|
||||
- return __mock_bindings_file(content);
|
||||
+ return __mock_bindings_file(content, false);
|
||||
}
|
||||
|
||||
static int teardown_bindings(void **state)
|
||||
@@ -1744,6 +1748,207 @@ static int test_get_user_friendly_alias()
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
|
||||
+/* Numbers 1-1000, randomly shuffled */
|
||||
+static const int random_numbers[1000] = {
|
||||
+ 694, 977, 224, 178, 841, 818, 914, 549, 831, 942, 263, 834, 919, 800,
|
||||
+ 111, 517, 719, 297, 988, 98, 332, 516, 754, 772, 495, 488, 331, 529,
|
||||
+ 142, 747, 848, 618, 375, 624, 74, 753, 782, 944, 623, 468, 862, 997,
|
||||
+ 417, 258, 298, 774, 673, 904, 883, 766, 867, 400, 11, 950, 14, 784,
|
||||
+ 655, 155, 396, 9, 743, 93, 651, 245, 968, 306, 785, 581, 880, 486,
|
||||
+ 168, 631, 203, 4, 663, 294, 702, 762, 619, 684, 48, 181, 21, 443, 643,
|
||||
+ 863, 1000, 327, 26, 126, 382, 765, 586, 76, 49, 925, 319, 865, 797,
|
||||
+ 876, 693, 334, 433, 243, 419, 901, 854, 326, 985, 347, 874, 527, 282,
|
||||
+ 290, 380, 167, 95, 3, 257, 936, 60, 426, 227, 345, 577, 492, 467, 580,
|
||||
+ 967, 422, 823, 718, 610, 64, 700, 412, 163, 288, 506, 828, 432, 51,
|
||||
+ 356, 348, 539, 478, 17, 945, 602, 123, 450, 660, 429, 113, 310, 358,
|
||||
+ 512, 758, 508, 19, 542, 304, 286, 446, 918, 723, 333, 603, 731, 978,
|
||||
+ 230, 697, 109, 872, 175, 853, 947, 965, 121, 222, 101, 811, 117, 601,
|
||||
+ 191, 752, 384, 415, 938, 278, 915, 715, 240, 552, 912, 838, 150, 840,
|
||||
+ 627, 29, 636, 464, 861, 481, 992, 249, 934, 82, 368, 724, 807, 593,
|
||||
+ 157, 147, 199, 637, 41, 62, 902, 505, 621, 342, 174, 260, 729, 961,
|
||||
+ 219, 311, 629, 789, 81, 739, 860, 712, 223, 165, 741, 981, 485, 363,
|
||||
+ 346, 709, 125, 369, 279, 634, 399, 162, 193, 769, 149, 314, 868, 612,
|
||||
+ 524, 675, 341, 343, 476, 606, 388, 613, 850, 264, 903, 451, 908, 779,
|
||||
+ 453, 148, 497, 46, 132, 43, 885, 955, 269, 395, 72, 128, 767, 989,
|
||||
+ 929, 423, 742, 55, 13, 79, 924, 182, 295, 563, 668, 169, 974, 154,
|
||||
+ 970, 54, 674, 52, 437, 570, 550, 531, 554, 793, 678, 218, 367, 105,
|
||||
+ 197, 315, 958, 892, 86, 47, 284, 37, 561, 522, 198, 689, 817, 573,
|
||||
+ 877, 201, 803, 501, 881, 546, 530, 523, 780, 579, 953, 135, 23, 620,
|
||||
+ 84, 698, 303, 656, 357, 323, 494, 58, 131, 913, 995, 120, 70, 1, 195,
|
||||
+ 365, 210, 25, 898, 173, 307, 239, 77, 418, 952, 963, 92, 455, 425, 12,
|
||||
+ 536, 161, 328, 933, 401, 251, 735, 725, 362, 322, 557, 681, 302, 53,
|
||||
+ 786, 801, 391, 946, 748, 133, 717, 851, 7, 372, 993, 387, 906, 373,
|
||||
+ 667, 33, 670, 389, 209, 611, 896, 652, 69, 999, 344, 845, 633, 36,
|
||||
+ 487, 192, 180, 45, 640, 427, 707, 805, 188, 152, 905, 217, 30, 252,
|
||||
+ 386, 665, 299, 541, 410, 787, 5, 857, 751, 392, 44, 595, 146, 745,
|
||||
+ 641, 957, 866, 773, 806, 815, 659, 102, 704, 430, 106, 296, 129, 847,
|
||||
+ 130, 990, 669, 236, 225, 680, 159, 213, 438, 189, 447, 600, 232, 594,
|
||||
+ 32, 56, 390, 647, 855, 428, 330, 714, 738, 706, 666, 461, 469, 482,
|
||||
+ 558, 814, 559, 177, 575, 538, 309, 383, 261, 156, 420, 761, 630, 893,
|
||||
+ 10, 116, 940, 844, 71, 377, 662, 312, 520, 244, 143, 759, 119, 186,
|
||||
+ 592, 909, 864, 376, 768, 254, 265, 394, 511, 760, 574, 6, 436, 514,
|
||||
+ 59, 226, 644, 956, 578, 825, 548, 145, 736, 597, 378, 821, 987, 897,
|
||||
+ 354, 144, 722, 895, 589, 503, 826, 498, 543, 617, 763, 231, 808, 528,
|
||||
+ 89, 479, 607, 737, 170, 404, 371, 65, 103, 340, 283, 141, 313, 858,
|
||||
+ 289, 124, 971, 687, 954, 732, 39, 926, 176, 100, 267, 519, 890, 535,
|
||||
+ 276, 448, 27, 457, 899, 385, 184, 275, 770, 544, 614, 449, 160, 658,
|
||||
+ 259, 973, 108, 604, 24, 207, 562, 757, 744, 324, 444, 962, 591, 480,
|
||||
+ 398, 409, 998, 253, 325, 445, 979, 8, 35, 118, 73, 683, 208, 85, 190,
|
||||
+ 791, 408, 871, 657, 179, 18, 556, 496, 475, 20, 894, 484, 775, 889,
|
||||
+ 463, 241, 730, 57, 907, 551, 859, 943, 185, 416, 870, 590, 435, 471,
|
||||
+ 932, 268, 381, 626, 502, 565, 273, 534, 672, 778, 292, 473, 566, 104,
|
||||
+ 172, 285, 832, 411, 329, 628, 397, 472, 271, 910, 711, 690, 969, 585,
|
||||
+ 809, 941, 923, 555, 228, 685, 242, 94, 96, 211, 140, 61, 922, 795,
|
||||
+ 869, 34, 255, 38, 984, 676, 15, 560, 632, 434, 921, 355, 582, 351,
|
||||
+ 212, 200, 819, 960, 649, 852, 75, 771, 361, 996, 238, 316, 720, 671,
|
||||
+ 462, 112, 569, 171, 664, 625, 588, 405, 553, 270, 533, 353, 842, 114,
|
||||
+ 972, 83, 937, 63, 194, 237, 537, 980, 802, 916, 959, 688, 839, 350,
|
||||
+ 917, 650, 545, 615, 151, 352, 686, 726, 266, 509, 439, 491, 935, 608,
|
||||
+ 518, 653, 339, 609, 277, 635, 836, 88, 407, 440, 642, 927, 229, 727,
|
||||
+ 360, 477, 846, 413, 454, 616, 28, 598, 567, 540, 790, 424, 247, 317,
|
||||
+ 746, 911, 798, 321, 547, 248, 734, 829, 220, 138, 756, 500, 691, 196,
|
||||
+ 740, 930, 843, 733, 221, 827, 50, 813, 949, 525, 349, 474, 134, 875,
|
||||
+ 695, 513, 414, 515, 638, 99, 366, 490, 975, 246, 465, 206, 281, 583,
|
||||
+ 256, 587, 749, 2, 951, 679, 215, 364, 458, 402, 646, 991, 335, 982,
|
||||
+ 835, 300, 900, 703, 994, 983, 234, 888, 532, 804, 584, 305, 792, 442,
|
||||
+ 291, 964, 158, 370, 452, 250, 521, 166, 948, 812, 794, 272, 699, 205,
|
||||
+ 183, 507, 301, 920, 781, 233, 824, 137, 489, 833, 887, 966, 856, 78,
|
||||
+ 830, 153, 359, 696, 526, 216, 66, 701, 403, 891, 849, 571, 308, 483,
|
||||
+ 164, 293, 928, 677, 320, 837, 441, 639, 564, 510, 648, 274, 336, 661,
|
||||
+ 878, 777, 816, 976, 493, 810, 67, 87, 91, 187, 882, 986, 80, 22, 499,
|
||||
+ 90, 705, 139, 136, 122, 708, 716, 886, 572, 127, 40, 721, 764, 16,
|
||||
+ 379, 692, 645, 456, 710, 460, 783, 97, 776, 713, 884, 115, 466, 596,
|
||||
+ 374, 406, 110, 568, 68, 214, 622, 470, 107, 504, 682, 31, 421, 576,
|
||||
+ 654, 605, 788, 799, 280, 338, 931, 873, 204, 287, 459, 755, 939, 599,
|
||||
+ 431, 796, 235, 42, 750, 262, 318, 393, 202, 822, 879, 820, 728, 337,
|
||||
+};
|
||||
+
|
||||
+static void fill_bindings_random(struct strbuf *buf, int start, int end,
|
||||
+ const char *prefix)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = start; i < end; i++) {
|
||||
+ print_strbuf(buf, "%s", prefix);
|
||||
+ format_devname(buf, random_numbers[i]);
|
||||
+ print_strbuf(buf, " WWID%d\n", random_numbers[i]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+struct random_aliases {
|
||||
+ int start;
|
||||
+ int end;
|
||||
+ const char *prefix;
|
||||
+};
|
||||
+
|
||||
+static void order_test(int n, const struct random_aliases ra[], bool conflict_ok)
|
||||
+{
|
||||
+ STRBUF_ON_STACK(buf);
|
||||
+ int i, j, prev, curr, tmp;
|
||||
+ struct binding *bdg;
|
||||
+ Bindings *bindings = &global_bindings;
|
||||
+
|
||||
+ for (j = 0; j < n; j++)
|
||||
+ fill_bindings_random(&buf, ra[j].start, ra[j].end, ra[j].prefix);
|
||||
+ __mock_bindings_file(get_strbuf_str(&buf), conflict_ok);
|
||||
+
|
||||
+ for (j = 0; j < n; j++) {
|
||||
+ bdg = VECTOR_SLOT(bindings, 0);
|
||||
+ if (ALIAS_DEBUG && j == 0)
|
||||
+ printf("%d: %s\n", 0, bdg->alias);
|
||||
+ prev = scan_devname(bdg->alias, ra[j].prefix);
|
||||
+ i = 1;
|
||||
+ vector_foreach_slot_after(bindings, bdg, i) {
|
||||
+ if (ALIAS_DEBUG && j == 0)
|
||||
+ printf("%d: %s\n", i, bdg->alias);
|
||||
+ tmp = scan_devname(bdg->alias, ra[j].prefix);
|
||||
+ if (tmp == -1)
|
||||
+ continue;
|
||||
+ curr = tmp;
|
||||
+ if (prev > 0) {
|
||||
+ if (curr <= prev)
|
||||
+ printf("ERROR: %d (%s) %d >= %d\n",
|
||||
+ i, bdg->alias, prev, curr);
|
||||
+ assert_true(curr > prev);
|
||||
+ }
|
||||
+ prev = curr;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void order_01(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 0, 1000, "MPATH" },
|
||||
+ };
|
||||
+
|
||||
+ order_test(ARRAY_SIZE(ra), ra, false);
|
||||
+}
|
||||
+
|
||||
+static void order_02(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 0, 500, "MPATH" },
|
||||
+ { 200, 700, "mpath" },
|
||||
+ };
|
||||
+ order_test(ARRAY_SIZE(ra), ra, false);
|
||||
+}
|
||||
+
|
||||
+static void order_03(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 500, 1000, "MPTH" },
|
||||
+ { 0, 500, "MPATH" },
|
||||
+ };
|
||||
+ order_test(ARRAY_SIZE(ra), ra, false);
|
||||
+}
|
||||
+
|
||||
+static void order_04(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 0, 500, "mpa" },
|
||||
+ { 250, 750, "mp" },
|
||||
+ };
|
||||
+ order_test(ARRAY_SIZE(ra), ra, true);
|
||||
+}
|
||||
+
|
||||
+static void order_05(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 0, 100, "A" },
|
||||
+ { 0, 100, "B" },
|
||||
+ { 0, 100, "C" },
|
||||
+ { 0, 100, "D" },
|
||||
+ };
|
||||
+ order_test(ARRAY_SIZE(ra), ra, false);
|
||||
+}
|
||||
+
|
||||
+static void order_06(void **state)
|
||||
+{
|
||||
+ const struct random_aliases ra[] = {
|
||||
+ { 0, 100, "" },
|
||||
+ { 0, 100, "a" },
|
||||
+ { 0, 100, "aa" },
|
||||
+ { 0, 100, "ab" },
|
||||
+ { 0, 100, "aaa" },
|
||||
+ };
|
||||
+ order_test(ARRAY_SIZE(ra), ra, true);
|
||||
+}
|
||||
+
|
||||
+static int test_bindings_order()
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test_teardown(order_01, teardown_bindings),
|
||||
+ cmocka_unit_test_teardown(order_02, teardown_bindings),
|
||||
+ cmocka_unit_test_teardown(order_03, teardown_bindings),
|
||||
+ cmocka_unit_test_teardown(order_04, teardown_bindings),
|
||||
+ cmocka_unit_test_teardown(order_05, teardown_bindings),
|
||||
+ cmocka_unit_test_teardown(order_06, teardown_bindings),
|
||||
+ };
|
||||
+
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1755,6 +1960,7 @@ int main(void)
|
||||
ret += test_rlookup_binding();
|
||||
ret += test_allocate_binding();
|
||||
ret += test_get_user_friendly_alias();
|
||||
+ ret += test_bindings_order();
|
||||
|
||||
return ret;
|
||||
}
|
597
0027-multipathd-watch-bindings-file-with-inotify-timestam.patch
Normal file
597
0027-multipathd-watch-bindings-file-with-inotify-timestam.patch
Normal file
@ -0,0 +1,597 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 7 Sep 2023 22:22:43 +0200
|
||||
Subject: [PATCH] multipathd: watch bindings file with inotify + timestamp
|
||||
|
||||
Since "libmultipath: keep bindings in memory", we don't re-read the
|
||||
bindings file after every modification. Add a notification mechanism
|
||||
that makes multipathd aware of changes to the bindings file. Because
|
||||
multipathd itself will change the bindings file, it must compare
|
||||
timestamps in order to avoid reading the file repeatedly.
|
||||
|
||||
Because select_alias() can be called from multiple thread contexts (uxlsnr,
|
||||
uevent handler), we need to add locking for the bindings file. The
|
||||
timestamp must also be protected by a lock, because it can't be read
|
||||
or written atomically.
|
||||
|
||||
Note: The notification mechanism expects the bindings file to be
|
||||
atomically replaced by rename(2). Changes must be made in a temporary file and
|
||||
applied using rename(2), as in update_bindings_file(). The inotify
|
||||
mechanism deliberately does not listen to close-after-write events
|
||||
that would be generated by editing the bindings file directly. This
|
||||
|
||||
Note also: new bindings will only be read from add_map_with_path(),
|
||||
i.e. either during reconfigure(), or when a new map is created during
|
||||
runtime. Existing maps will not be renamed if the binding file changes,
|
||||
unless the user runs "multipathd reconfigure". This is not a change
|
||||
wrt the previous code, but it should be mentioned anyway.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 256 +++++++++++++++++++++++++-----
|
||||
libmultipath/alias.h | 3 +-
|
||||
libmultipath/libmultipath.version | 5 +
|
||||
multipathd/uxlsnr.c | 36 ++++-
|
||||
tests/alias.c | 3 +
|
||||
5 files changed, 256 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 66e34e31..964b8a7b 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
+#include <sys/inotify.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "config.h"
|
||||
#include "devmapper.h"
|
||||
#include "strbuf.h"
|
||||
+#include "time-util.h"
|
||||
|
||||
/*
|
||||
* significant parts of this file were taken from iscsi-bindings.c of the
|
||||
@@ -50,6 +52,12 @@
|
||||
"# alias wwid\n" \
|
||||
"#\n"
|
||||
|
||||
+/* uatomic access only */
|
||||
+static int bindings_file_changed = 1;
|
||||
+
|
||||
+static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static struct timespec bindings_last_updated;
|
||||
+
|
||||
struct binding {
|
||||
char *alias;
|
||||
char *wwid;
|
||||
@@ -60,6 +68,9 @@ struct binding {
|
||||
* an abstract type.
|
||||
*/
|
||||
typedef struct _vector Bindings;
|
||||
+
|
||||
+/* Protect global_bindings */
|
||||
+static pthread_mutex_t bindings_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static Bindings global_bindings = { .allocated = 0 };
|
||||
|
||||
enum {
|
||||
@@ -78,6 +89,27 @@ static void _free_binding(struct binding *bdg)
|
||||
free(bdg);
|
||||
}
|
||||
|
||||
+static void free_bindings(Bindings *bindings)
|
||||
+{
|
||||
+ struct binding *bdg;
|
||||
+ int i;
|
||||
+
|
||||
+ vector_foreach_slot(bindings, bdg, i)
|
||||
+ _free_binding(bdg);
|
||||
+ vector_reset(bindings);
|
||||
+}
|
||||
+
|
||||
+static void set_global_bindings(Bindings *bindings)
|
||||
+{
|
||||
+ Bindings old_bindings;
|
||||
+
|
||||
+ pthread_mutex_lock(&bindings_mutex);
|
||||
+ old_bindings = global_bindings;
|
||||
+ global_bindings = *bindings;
|
||||
+ pthread_mutex_unlock(&bindings_mutex);
|
||||
+ free_bindings(&old_bindings);
|
||||
+}
|
||||
+
|
||||
static const struct binding *get_binding_for_alias(const Bindings *bindings,
|
||||
const char *alias)
|
||||
{
|
||||
@@ -199,7 +231,8 @@ static int delete_binding(Bindings *bindings, const char *wwid)
|
||||
return BINDING_DELETED;
|
||||
}
|
||||
|
||||
-static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
+static int write_bindings_file(const Bindings *bindings, int fd,
|
||||
+ struct timespec *ts)
|
||||
{
|
||||
struct binding *bnd;
|
||||
STRBUF_ON_STACK(content);
|
||||
@@ -227,9 +260,56 @@ static int write_bindings_file(const Bindings *bindings, int fd)
|
||||
}
|
||||
len -= n;
|
||||
}
|
||||
+ fsync(fd);
|
||||
+ if (ts) {
|
||||
+ struct stat st;
|
||||
+
|
||||
+ if (fstat(fd, &st) == 0)
|
||||
+ *ts = st.st_mtim;
|
||||
+ else
|
||||
+ clock_gettime(CLOCK_REALTIME_COARSE, ts);
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void handle_bindings_file_inotify(const struct inotify_event *event)
|
||||
+{
|
||||
+ struct config *conf;
|
||||
+ const char *base;
|
||||
+ bool changed = false;
|
||||
+ struct stat st;
|
||||
+ struct timespec ts = { 0, 0 };
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!(event->mask & IN_MOVED_TO))
|
||||
+ return;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ base = strrchr(conf->bindings_file, '/');
|
||||
+ changed = base && base > conf->bindings_file &&
|
||||
+ !strcmp(base + 1, event->name);
|
||||
+ ret = stat(conf->bindings_file, &st);
|
||||
+ put_multipath_config(conf);
|
||||
+
|
||||
+ if (!changed)
|
||||
+ return;
|
||||
+
|
||||
+ pthread_mutex_lock(×tamp_mutex);
|
||||
+ if (ret == 0) {
|
||||
+ ts = st.st_mtim;
|
||||
+ changed = timespeccmp(&ts, &bindings_last_updated) > 0;
|
||||
+ }
|
||||
+ pthread_mutex_unlock(×tamp_mutex);
|
||||
+
|
||||
+ if (changed) {
|
||||
+ uatomic_xchg(&bindings_file_changed, 1);
|
||||
+ condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld",
|
||||
+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000);
|
||||
+ } else
|
||||
+ condlog(3, "%s: bindings file is up-to-date, timestamp: %ld.%06ld",
|
||||
+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000);
|
||||
+}
|
||||
+
|
||||
static int update_bindings_file(const Bindings *bindings,
|
||||
const char *bindings_file)
|
||||
{
|
||||
@@ -237,6 +317,7 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
int fd = -1;
|
||||
char tempname[PATH_MAX];
|
||||
mode_t old_umask;
|
||||
+ struct timespec ts;
|
||||
|
||||
if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file))
|
||||
return -1;
|
||||
@@ -248,7 +329,7 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
}
|
||||
umask(old_umask);
|
||||
pthread_cleanup_push(cleanup_fd_ptr, &fd);
|
||||
- rc = write_bindings_file(bindings, fd);
|
||||
+ rc = write_bindings_file(bindings, fd, &ts);
|
||||
pthread_cleanup_pop(1);
|
||||
if (rc == -1) {
|
||||
condlog(1, "failed to write new bindings file");
|
||||
@@ -257,8 +338,12 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
}
|
||||
if ((rc = rename(tempname, bindings_file)) == -1)
|
||||
condlog(0, "%s: rename: %m", __func__);
|
||||
- else
|
||||
+ else {
|
||||
+ pthread_mutex_lock(×tamp_mutex);
|
||||
+ bindings_last_updated = ts;
|
||||
+ pthread_mutex_unlock(×tamp_mutex);
|
||||
condlog(1, "updated bindings file %s", bindings_file);
|
||||
+ }
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -387,6 +472,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww
|
||||
return id;
|
||||
}
|
||||
|
||||
+/* Called with binding_mutex held */
|
||||
static char *
|
||||
allocate_binding(const char *filename, const char *wwid, int id, const char *prefix)
|
||||
{
|
||||
@@ -423,6 +509,30 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre
|
||||
return alias;
|
||||
}
|
||||
|
||||
+enum {
|
||||
+ BINDINGS_FILE_UP2DATE,
|
||||
+ BINDINGS_FILE_READ,
|
||||
+ BINDINGS_FILE_ERROR,
|
||||
+ BINDINGS_FILE_BAD,
|
||||
+};
|
||||
+
|
||||
+static int _read_bindings_file(const struct config *conf, Bindings *bindings,
|
||||
+ bool force);
|
||||
+
|
||||
+static void read_bindings_file(void)
|
||||
+{
|
||||
+ struct config *conf;
|
||||
+ Bindings bindings = {.allocated = 0, };
|
||||
+ int rc;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ pthread_cleanup_push(put_multipath_config, conf);
|
||||
+ rc = _read_bindings_file(conf, &bindings, false);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ if (rc == BINDINGS_FILE_READ)
|
||||
+ set_global_bindings(&bindings);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* get_user_friendly_alias() action table
|
||||
*
|
||||
@@ -463,6 +573,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al
|
||||
bool new_binding = false;
|
||||
const struct binding *bdg;
|
||||
|
||||
+ read_bindings_file();
|
||||
+
|
||||
+ pthread_mutex_lock(&bindings_mutex);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex);
|
||||
+
|
||||
if (!*alias_old)
|
||||
goto new_alias;
|
||||
|
||||
@@ -514,40 +629,40 @@ new_alias:
|
||||
alias, wwid);
|
||||
|
||||
out:
|
||||
+ /* unlock bindings_mutex */
|
||||
+ pthread_cleanup_pop(1);
|
||||
return alias;
|
||||
}
|
||||
|
||||
int get_user_friendly_wwid(const char *alias, char *buff)
|
||||
{
|
||||
const struct binding *bdg;
|
||||
+ int rc = -1;
|
||||
|
||||
if (!alias || *alias == '\0') {
|
||||
condlog(3, "Cannot find binding for empty alias");
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ read_bindings_file();
|
||||
+
|
||||
+ pthread_mutex_lock(&bindings_mutex);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex);
|
||||
bdg = get_binding_for_alias(&global_bindings, alias);
|
||||
- if (!bdg) {
|
||||
+ if (bdg) {
|
||||
+ strlcpy(buff, bdg->wwid, WWID_SIZE);
|
||||
+ rc = 0;
|
||||
+ } else
|
||||
*buff = '\0';
|
||||
- return -1;
|
||||
- }
|
||||
- strlcpy(buff, bdg->wwid, WWID_SIZE);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void free_bindings(Bindings *bindings)
|
||||
-{
|
||||
- struct binding *bdg;
|
||||
- int i;
|
||||
-
|
||||
- vector_foreach_slot(bindings, bdg, i)
|
||||
- _free_binding(bdg);
|
||||
- vector_reset(bindings);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
void cleanup_bindings(void)
|
||||
{
|
||||
+ pthread_mutex_lock(&bindings_mutex);
|
||||
free_bindings(&global_bindings);
|
||||
+ pthread_mutex_unlock(&bindings_mutex);
|
||||
}
|
||||
|
||||
enum {
|
||||
@@ -595,7 +710,20 @@ static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
char *line = NULL;
|
||||
size_t line_len = 0;
|
||||
ssize_t n;
|
||||
-
|
||||
+ char header[sizeof(BINDINGS_FILE_HEADER)];
|
||||
+
|
||||
+ header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0';
|
||||
+ if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) {
|
||||
+ condlog(2, "%s: failed to read header from %s", __func__,
|
||||
+ conf->bindings_file);
|
||||
+ fseek(file, 0, SEEK_SET);
|
||||
+ rc = -1;
|
||||
+ } else if (strcmp(header, BINDINGS_FILE_HEADER)) {
|
||||
+ condlog(2, "%s: invalid header in %s", __func__,
|
||||
+ conf->bindings_file);
|
||||
+ fseek(file, 0, SEEK_SET);
|
||||
+ rc = -1;
|
||||
+ }
|
||||
pthread_cleanup_push(cleanup_free_ptr, &line);
|
||||
while ((n = getline(&line, &line_len, file)) >= 0) {
|
||||
char *alias, *wwid;
|
||||
@@ -643,6 +771,68 @@ static int mp_alias_compar(const void *p1, const void *p2)
|
||||
&((*(struct mpentry * const *)p2)->alias));
|
||||
}
|
||||
|
||||
+static int _read_bindings_file(const struct config *conf, Bindings *bindings,
|
||||
+ bool force)
|
||||
+{
|
||||
+ int can_write;
|
||||
+ int rc = 0, ret, fd;
|
||||
+ FILE *file;
|
||||
+ struct stat st;
|
||||
+ int has_changed = uatomic_xchg(&bindings_file_changed, 0);
|
||||
+
|
||||
+ if (!force) {
|
||||
+ if (!has_changed) {
|
||||
+ condlog(4, "%s: bindings are unchanged", __func__);
|
||||
+ return BINDINGS_FILE_UP2DATE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER);
|
||||
+ if (fd == -1)
|
||||
+ return BINDINGS_FILE_ERROR;
|
||||
+
|
||||
+ file = fdopen(fd, "r");
|
||||
+ if (file != NULL) {
|
||||
+ condlog(3, "%s: reading %s", __func__, conf->bindings_file);
|
||||
+
|
||||
+ pthread_cleanup_push(cleanup_fclose, file);
|
||||
+ ret = _check_bindings_file(conf, file, bindings);
|
||||
+ if (ret == 0) {
|
||||
+ struct timespec ts;
|
||||
+
|
||||
+ rc = BINDINGS_FILE_READ;
|
||||
+ ret = fstat(fd, &st);
|
||||
+ if (ret == 0)
|
||||
+ ts = st.st_mtim;
|
||||
+ else {
|
||||
+ condlog(1, "%s: fstat failed (%m), using current time", __func__);
|
||||
+ clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
||||
+ }
|
||||
+ pthread_mutex_lock(×tamp_mutex);
|
||||
+ bindings_last_updated = ts;
|
||||
+ pthread_mutex_unlock(×tamp_mutex);
|
||||
+ } else if (ret == -1 && can_write && !conf->bindings_read_only) {
|
||||
+ ret = update_bindings_file(bindings, conf->bindings_file);
|
||||
+ if (ret == 0)
|
||||
+ rc = BINDINGS_FILE_READ;
|
||||
+ else
|
||||
+ rc = BINDINGS_FILE_BAD;
|
||||
+ } else {
|
||||
+ condlog(0, "ERROR: bad settings in read-only bindings file %s",
|
||||
+ conf->bindings_file);
|
||||
+ rc = BINDINGS_FILE_BAD;
|
||||
+ }
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ } else {
|
||||
+ condlog(1, "failed to fdopen %s: %m",
|
||||
+ conf->bindings_file);
|
||||
+ close(fd);
|
||||
+ rc = BINDINGS_FILE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* check_alias_settings(): test for inconsistent alias configuration
|
||||
*
|
||||
@@ -661,8 +851,7 @@ static int mp_alias_compar(const void *p1, const void *p2)
|
||||
*/
|
||||
int check_alias_settings(const struct config *conf)
|
||||
{
|
||||
- int can_write;
|
||||
- int rc = 0, i, fd;
|
||||
+ int i, rc;
|
||||
Bindings bindings = {.allocated = 0, };
|
||||
vector mptable = NULL;
|
||||
struct mpentry *mpe;
|
||||
@@ -695,27 +884,12 @@ int check_alias_settings(const struct config *conf)
|
||||
pthread_cleanup_pop(1);
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER);
|
||||
- if (fd != -1) {
|
||||
- FILE *file = fdopen(fd, "r");
|
||||
-
|
||||
- if (file != NULL) {
|
||||
- pthread_cleanup_push(cleanup_fclose, file);
|
||||
- rc = _check_bindings_file(conf, file, &bindings);
|
||||
- pthread_cleanup_pop(1);
|
||||
- if (rc == -1 && can_write && !conf->bindings_read_only)
|
||||
- rc = update_bindings_file(&bindings, conf->bindings_file);
|
||||
- else if (rc == -1)
|
||||
- condlog(0, "ERROR: bad settings in read-only bindings file %s",
|
||||
- conf->bindings_file);
|
||||
- } else {
|
||||
- condlog(1, "failed to fdopen %s: %m",
|
||||
- conf->bindings_file);
|
||||
- close(fd);
|
||||
- }
|
||||
+ rc = _read_bindings_file(conf, &bindings, true);
|
||||
+
|
||||
+ if (rc == BINDINGS_FILE_READ) {
|
||||
+ set_global_bindings(&bindings);
|
||||
+ rc = 0;
|
||||
}
|
||||
|
||||
- cleanup_bindings();
|
||||
- global_bindings = bindings;
|
||||
return rc;
|
||||
}
|
||||
diff --git a/libmultipath/alias.h b/libmultipath/alias.h
|
||||
index 5ef6720b..ca8911f4 100644
|
||||
--- a/libmultipath/alias.h
|
||||
+++ b/libmultipath/alias.h
|
||||
@@ -10,5 +10,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
struct config;
|
||||
int check_alias_settings(const struct config *);
|
||||
void cleanup_bindings(void);
|
||||
-
|
||||
+struct inotify_event;
|
||||
+void handle_bindings_file_inotify(const struct inotify_event *event);
|
||||
#endif /* _ALIAS_H */
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index ddd302f5..57e50c12 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -238,3 +238,8 @@ global:
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+
|
||||
+LIBMULTIPATH_20.1.0 {
|
||||
+global:
|
||||
+ handle_bindings_file_inotify;
|
||||
+};
|
||||
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
|
||||
index 02e89fb4..d1f8f234 100644
|
||||
--- a/multipathd/uxlsnr.c
|
||||
+++ b/multipathd/uxlsnr.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "cli.h"
|
||||
#include "uxlsnr.h"
|
||||
#include "strbuf.h"
|
||||
+#include "alias.h"
|
||||
|
||||
/* state of client connection */
|
||||
enum {
|
||||
@@ -190,6 +191,7 @@ void wakeup_cleanup(void *arg)
|
||||
struct watch_descriptors {
|
||||
int conf_wd;
|
||||
int dir_wd;
|
||||
+ int mp_wd; /* /etc/multipath; for bindings file */
|
||||
};
|
||||
|
||||
/* failing to set the watch descriptor is o.k. we just miss a warning
|
||||
@@ -200,6 +202,8 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
struct config *conf;
|
||||
int dir_reset = 0;
|
||||
int conf_reset = 0;
|
||||
+ int mp_reset = 0;
|
||||
+ char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
|
||||
if (notify_fd == -1)
|
||||
return;
|
||||
@@ -214,7 +218,10 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
conf_reset = 1;
|
||||
if (wds->dir_wd == -1)
|
||||
dir_reset = 1;
|
||||
+ if (wds->mp_wd == -1)
|
||||
+ mp_reset = 1;
|
||||
}
|
||||
+ bindings_file = strdup(conf->bindings_file);
|
||||
put_multipath_config(conf);
|
||||
|
||||
if (dir_reset) {
|
||||
@@ -235,7 +242,18 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
if (wds->conf_wd == -1)
|
||||
condlog(3, "didn't set up notifications on /etc/multipath.conf: %m");
|
||||
}
|
||||
- return;
|
||||
+ if (mp_reset && bindings_file) {
|
||||
+ char *slash = strrchr(bindings_file, '/');
|
||||
+
|
||||
+ if (slash && slash > bindings_file) {
|
||||
+ *slash = '\0';
|
||||
+ wds->mp_wd = inotify_add_watch(notify_fd, bindings_file,
|
||||
+ IN_MOVED_TO|IN_ONLYDIR);
|
||||
+ if (wds->mp_wd == -1)
|
||||
+ condlog(3, "didn't set up notifications on %s: %m",
|
||||
+ bindings_file);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void handle_inotify(int fd, struct watch_descriptors *wds)
|
||||
@@ -256,12 +274,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds)
|
||||
inotify_rm_watch(fd, wds->conf_wd);
|
||||
if (wds->dir_wd != -1)
|
||||
inotify_rm_watch(fd, wds->dir_wd);
|
||||
- wds->conf_wd = wds->dir_wd = -1;
|
||||
+ if (wds->mp_wd != -1)
|
||||
+ inotify_rm_watch(fd, wds->mp_wd);
|
||||
+ wds->conf_wd = wds->dir_wd = wds->mp_wd = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
- got_notify = 1;
|
||||
for (ptr = buff; ptr < buff + len;
|
||||
ptr += sizeof(struct inotify_event) + event->len) {
|
||||
event = (const struct inotify_event *) ptr;
|
||||
@@ -273,7 +292,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds)
|
||||
wds->conf_wd = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE, IN_CLOSE_WRITE);
|
||||
else if (wds->dir_wd == event->wd)
|
||||
wds->dir_wd = -1;
|
||||
+ else if (wds->mp_wd == event->wd)
|
||||
+ wds->mp_wd = -1;
|
||||
}
|
||||
+ if (wds->mp_wd != -1 && wds->mp_wd == event->wd)
|
||||
+ handle_bindings_file_inotify(event);
|
||||
+ else
|
||||
+ got_notify = 1;
|
||||
}
|
||||
}
|
||||
if (got_notify)
|
||||
@@ -599,7 +624,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
|
||||
int max_pfds = MIN_POLLS + POLLFDS_BASE;
|
||||
/* conf->sequence_nr will be 1 when uxsock_listen is first called */
|
||||
unsigned int sequence_nr = 0;
|
||||
- struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 };
|
||||
+ struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, };
|
||||
struct vectors *vecs = trigger_data;
|
||||
|
||||
condlog(3, "uxsock: startup listener");
|
||||
@@ -666,7 +691,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
|
||||
|
||||
reset_watch(notify_fd, &wds, &sequence_nr);
|
||||
polls[POLLFD_NOTIFY].fd = notify_fd;
|
||||
- if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1))
|
||||
+ if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1
|
||||
+ && wds.mp_wd == -1))
|
||||
polls[POLLFD_NOTIFY].events = 0;
|
||||
else
|
||||
polls[POLLFD_NOTIFY].events = POLLIN;
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 7f3ff38a..9ae27567 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -1954,6 +1954,9 @@ int main(void)
|
||||
int ret = 0;
|
||||
init_test_verbosity(3);
|
||||
|
||||
+ /* avoid open_file() call in _read_bindings_file */
|
||||
+ bindings_file_changed = 0;
|
||||
+
|
||||
ret += test_format_devname();
|
||||
ret += test_scan_devname();
|
||||
ret += test_lookup_binding();
|
102
0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch
Normal file
102
0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 19:54:07 +0200
|
||||
Subject: [PATCH] multipath-tools tests: mock pthread_mutex_{lock,unlock}
|
||||
|
||||
If some test fails with a lock held, cmocka doesn't deal well with
|
||||
pthread_cleanup_pop(). Such tests can cause deadlock with the locking
|
||||
primitives in the alias code, because locks don't get properly unlocked. Just
|
||||
mock the lock/unlock functions and generate an error if they weren't paired at
|
||||
the end of the test.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/Makefile | 1 +
|
||||
tests/alias.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 47 insertions(+)
|
||||
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index c777d07a..7dac8a8f 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -52,6 +52,7 @@ blacklist-test_LIBDEPS := -ludev
|
||||
vpd-test_OBJDEPS := $(multipathdir)/discovery.o
|
||||
vpd-test_LIBDEPS := -ludev -lpthread -ldl
|
||||
alias-test_TESTDEPS := test-log.o
|
||||
+alias-test_OBJDEPS := $(mpathutildir)/util.o
|
||||
alias-test_LIBDEPS := -lpthread -ldl
|
||||
valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o
|
||||
valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 9ae27567..94df36d8 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -89,6 +89,47 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int lock_errors;
|
||||
+static int bindings_locked;
|
||||
+static int timestamp_locked;
|
||||
+int __wrap_pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
+{
|
||||
+ if (mutex == &bindings_mutex) {
|
||||
+ if (bindings_locked) {
|
||||
+ fprintf(stderr, "%s: bindings_mutex LOCKED\n", __func__);
|
||||
+ lock_errors++;
|
||||
+ }
|
||||
+ bindings_locked = 1;
|
||||
+ } else if (mutex == ×tamp_mutex) {
|
||||
+ if (timestamp_locked) {
|
||||
+ fprintf(stderr, "%s: timestamp_mutex LOCKED\n", __func__);
|
||||
+ lock_errors++;
|
||||
+ }
|
||||
+ timestamp_locked = 1;
|
||||
+ } else
|
||||
+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
+{
|
||||
+ if (mutex == &bindings_mutex) {
|
||||
+ if (!bindings_locked) {
|
||||
+ fprintf(stderr, "%s: bindings_mutex UNLOCKED\n", __func__);
|
||||
+ lock_errors++;
|
||||
+ }
|
||||
+ bindings_locked = 0;
|
||||
+ } else if (mutex == ×tamp_mutex) {
|
||||
+ if (!timestamp_locked) {
|
||||
+ fprintf(stderr, "%s: timestamp_mutex UNLOCKED\n", __func__);
|
||||
+ lock_errors++;
|
||||
+ }
|
||||
+ timestamp_locked = 0;
|
||||
+ } else
|
||||
+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
#define TEST_FDNO 1234
|
||||
#define TEST_FPTR ((FILE *) 0xaffe)
|
||||
|
||||
@@ -1718,6 +1759,10 @@ static void gufa_old_nomatch_nowwidmatch(void **state) {
|
||||
free(alias);
|
||||
}
|
||||
|
||||
+static void gufa_check_locking(void **state) {
|
||||
+ assert_int_equal(lock_errors, 0);
|
||||
+}
|
||||
+
|
||||
static int test_get_user_friendly_alias()
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
@@ -1743,6 +1788,7 @@ static int test_get_user_friendly_alias()
|
||||
cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings),
|
||||
cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings),
|
||||
cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings),
|
||||
+ cmocka_unit_test(gufa_check_locking),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 22:13:51 +0200
|
||||
Subject: [PATCH] multipath-tools Makefile: sanitize paths for configuration
|
||||
files
|
||||
|
||||
Make the path to multipath.conf configurable, and use the same prefix
|
||||
by default for multipath.conf and multipath/conf.d. For "usr-merged"
|
||||
distributions with immutable /usr, we'll want to have the configuration
|
||||
under a different prefix. This can be achieved by using e.g.
|
||||
|
||||
make prefix=/usr etc_prefix=""
|
||||
|
||||
Note that with prefix=/usr, before this patch the code would use
|
||||
/usr/etc/multipath/conf.d, but /etc/multipath.conf. If this (rather
|
||||
inconsistent) behavior is desired, use the following command line:
|
||||
|
||||
make prefix=/usr configfile=/etc/multipath.conf
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 9 ++++++---
|
||||
libmultipath/defaults.h | 1 -
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 502cd0f1..39972d93 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -37,6 +37,8 @@ prefix :=
|
||||
exec_prefix := $(prefix)
|
||||
# Prefix for non-essential libraries (libdmmp)
|
||||
usr_prefix := $(prefix)
|
||||
+# Prefix for configfuration files (multipath.conf)
|
||||
+etc_prefix := $(prefix)
|
||||
# Where to install systemd-related files. systemd is usually installed under /usr
|
||||
# Note: some systemd installations use separate "prefix" and "rootprefix".
|
||||
# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix)
|
||||
@@ -54,7 +56,8 @@ usrlibdir := $(usr_prefix)/$(LIB)
|
||||
includedir := $(usr_prefix)/include
|
||||
pkgconfdir := $(usrlibdir)/pkgconfig
|
||||
plugindir := $(prefix)/$(LIB)/multipath
|
||||
-configdir := $(prefix)/etc/multipath/conf.d
|
||||
+configdir := $(etc_prefix)/etc/multipath/conf.d
|
||||
+configfile := $(etc_prefix)/etc/multipath.conf
|
||||
runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run)
|
||||
devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include)
|
||||
libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include)
|
||||
@@ -84,8 +87,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici
|
||||
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS)
|
||||
CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \
|
||||
-DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \
|
||||
- -DRUNTIME_DIR=\"$(runtimedir)\" \
|
||||
- -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP
|
||||
+ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \
|
||||
+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP
|
||||
CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe
|
||||
BIN_CFLAGS := -fPIE -DPIE
|
||||
LIB_CFLAGS := -fPIC
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index b3f11d4c..bc2d6388 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -66,7 +66,6 @@
|
||||
#define MAX_DEV_LOSS_TMO UINT_MAX
|
||||
#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid"
|
||||
#define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
|
||||
-#define DEFAULT_CONFIGFILE "/etc/multipath.conf"
|
||||
#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
|
||||
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
|
||||
#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys"
|
@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 22:26:22 +0200
|
||||
Subject: [PATCH] multipath-tools: add compile time configuration for
|
||||
"/etc/multipath"
|
||||
|
||||
Instead of hard-conding "/etc/multipath" as the path for the state
|
||||
files "bindings", "prkeys", and "wwids", make this path configurable
|
||||
via the "statedir" compile-time option. The default is currently still
|
||||
/etc, it might change to /var/lib or similar in the future.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 4 +++-
|
||||
libmultipath/defaults.h | 6 +++---
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 39972d93..96206b2f 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -58,6 +58,7 @@ pkgconfdir := $(usrlibdir)/pkgconfig
|
||||
plugindir := $(prefix)/$(LIB)/multipath
|
||||
configdir := $(etc_prefix)/etc/multipath/conf.d
|
||||
configfile := $(etc_prefix)/etc/multipath.conf
|
||||
+statedir := $(etc_prefix)/etc/multipath
|
||||
runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run)
|
||||
devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include)
|
||||
libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include)
|
||||
@@ -88,7 +89,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici
|
||||
CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \
|
||||
-DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \
|
||||
-DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \
|
||||
- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP
|
||||
+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \
|
||||
+ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP
|
||||
CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe
|
||||
BIN_CFLAGS := -fPIE -DPIE
|
||||
LIB_CFLAGS := -fPIC
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index bc2d6388..d01f9712 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -66,9 +66,9 @@
|
||||
#define MAX_DEV_LOSS_TMO UINT_MAX
|
||||
#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid"
|
||||
#define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
|
||||
-#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
|
||||
-#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
|
||||
-#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys"
|
||||
+#define DEFAULT_BINDINGS_FILE STATE_DIR "/bindings"
|
||||
+#define DEFAULT_WWIDS_FILE STATE_DIR "/wwids"
|
||||
+#define DEFAULT_PRKEYS_FILE STATE_DIR "/prkeys"
|
||||
#define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/"
|
||||
|
||||
|
366
0031-multipath-tools-man-pages-generate-with-correct-path.patch
Normal file
366
0031-multipath-tools-man-pages-generate-with-correct-path.patch
Normal file
@ -0,0 +1,366 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 8 Sep 2023 22:48:16 +0200
|
||||
Subject: [PATCH] multipath-tools man pages: generate with correct paths
|
||||
|
||||
Generate the man pages using the compile-time settings for paths
|
||||
to multipath.conf etc.
|
||||
|
||||
Add a paragraph about the CONFIGDIR (/etc/multipath/conf.d)
|
||||
and the drop-in configuration files in the multipath.conf man page.
|
||||
|
||||
Also, make sure all generated man pages and other files are correctly
|
||||
removed by "make clean".
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
.gitignore | 4 +++
|
||||
Makefile.inc | 3 +++
|
||||
mpathpersist/Makefile | 5 ++--
|
||||
.../{mpathpersist.8 => mpathpersist.8.in} | 2 +-
|
||||
multipath/Makefile | 13 +++++----
|
||||
multipath/{multipath.8 => multipath.8.in} | 10 +++----
|
||||
.../{multipath.conf.5 => multipath.conf.5.in} | 27 ++++++++++++-------
|
||||
multipathd/Makefile | 9 ++++---
|
||||
multipathd/{multipathd.8 => multipathd.8.in} | 8 +++---
|
||||
9 files changed, 49 insertions(+), 32 deletions(-)
|
||||
rename mpathpersist/{mpathpersist.8 => mpathpersist.8.in} (99%)
|
||||
rename multipath/{multipath.8 => multipath.8.in} (97%)
|
||||
rename multipath/{multipath.conf.5 => multipath.conf.5.in} (98%)
|
||||
rename multipathd/{multipathd.8 => multipathd.8.in} (97%)
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 535353e5..2986578f 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -13,11 +13,15 @@ cscope.files
|
||||
cscope.out
|
||||
kpartx/kpartx
|
||||
multipath/multipath
|
||||
+multipath/multipath.8
|
||||
+multipath/multipath.conf.5
|
||||
multipath/multipath.rules
|
||||
multipath/tmpfiles.conf
|
||||
multipathd/multipathd
|
||||
+multipathd/multipathd.8
|
||||
multipathd/multipathc
|
||||
mpathpersist/mpathpersist
|
||||
+mpathpersist/mpathpersist.8
|
||||
abi.tar.gz
|
||||
abi
|
||||
abi-test
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 96206b2f..79e521e1 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -133,3 +133,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version)
|
||||
@grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@
|
||||
@printf 'local:\n\t*;\n};\n' >>$@
|
||||
|
||||
+%: %.in
|
||||
+ @echo creating $@
|
||||
+ $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g' $< >$@
|
||||
diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile
|
||||
index f57c105c..f3749467 100644
|
||||
--- a/mpathpersist/Makefile
|
||||
+++ b/mpathpersist/Makefile
|
||||
@@ -8,10 +8,11 @@ LIBDEPS += -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath \
|
||||
-L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ludev
|
||||
|
||||
EXEC = mpathpersist
|
||||
+MANPAGES := mpathpersist.8
|
||||
|
||||
OBJS = main.o
|
||||
|
||||
-all: $(EXEC)
|
||||
+all: $(EXEC) $(MANPAGES)
|
||||
|
||||
$(EXEC): $(OBJS)
|
||||
$(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS)
|
||||
@@ -23,7 +24,7 @@ install:
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8
|
||||
|
||||
clean: dep_clean
|
||||
- $(Q)$(RM) core *.o $(EXEC)
|
||||
+ $(Q)$(RM) core *.o $(EXEC) $(MANPAGES)
|
||||
|
||||
include $(wildcard $(OBJS:.o=.d))
|
||||
|
||||
diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8.in
|
||||
similarity index 99%
|
||||
rename from mpathpersist/mpathpersist.8
|
||||
rename to mpathpersist/mpathpersist.8.in
|
||||
index 8d26b37c..fecef0d6 100644
|
||||
--- a/mpathpersist/mpathpersist.8
|
||||
+++ b/mpathpersist/mpathpersist.8.in
|
||||
@@ -31,7 +31,7 @@ mpathpersist \- Manages SCSI persistent reservations on dm multipath devices.
|
||||
.
|
||||
This utility is used to manage SCSI persistent reservations on Device Mapper
|
||||
Multipath devices. To be able to use this functionality, the \fIreservation_key\fR
|
||||
-attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the
|
||||
+attribute must be defined in the \fI@CONFIGFILE@\fR file. Otherwise the
|
||||
\fBmultipathd\fR daemon will not check for persistent reservation for newly
|
||||
discovered paths or reinstated paths.
|
||||
.
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 73db991a..68cb5ce7 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -3,7 +3,9 @@
|
||||
#
|
||||
include ../Makefile.inc
|
||||
|
||||
-EXEC := multipath
|
||||
+EXEC := multipath
|
||||
+MANPAGES := multipath.8 multipath.conf.5
|
||||
+GENERATED := $(MANPAGES) multipath.rules tmpfiles.conf
|
||||
|
||||
CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir)
|
||||
CFLAGS += $(BIN_CFLAGS)
|
||||
@@ -13,7 +15,7 @@ LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \
|
||||
|
||||
OBJS := main.o
|
||||
|
||||
-all: $(EXEC) multipath.rules tmpfiles.conf
|
||||
+all: $(EXEC) $(GENERATED)
|
||||
|
||||
$(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
@echo building $@ because of $?
|
||||
@@ -47,15 +49,12 @@ uninstall:
|
||||
$(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5
|
||||
+ $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf
|
||||
|
||||
clean: dep_clean
|
||||
- $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf
|
||||
+ $(Q)$(RM) core *.o $(EXEC) $(GENERATED)
|
||||
|
||||
include $(wildcard $(OBJS:.o=.d))
|
||||
|
||||
dep_clean:
|
||||
$(Q)$(RM) $(OBJS:.o=.d)
|
||||
-
|
||||
-%: %.in
|
||||
- @echo creating $@
|
||||
- $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8.in
|
||||
similarity index 97%
|
||||
rename from multipath/multipath.8
|
||||
rename to multipath/multipath.8.in
|
||||
index 5fed6df7..348eb220 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8.in
|
||||
@@ -185,7 +185,7 @@ Display the currently used multipathd configuration.
|
||||
.B \-T
|
||||
Display the currently used multipathd configuration, limiting the output to
|
||||
those devices actually present in the system. This can be used a template for
|
||||
-creating \fImultipath.conf\fR.
|
||||
+creating \fI@CONFIGFILE@\fR.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.SH OPTIONS
|
||||
@@ -233,11 +233,11 @@ option from \fBmultipath.conf(5)\fR.
|
||||
.B \-i
|
||||
Ignore WWIDs file when processing devices. If
|
||||
\fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in
|
||||
-\fImultipath.conf\fR, multipath only considers devices that are
|
||||
+\fI@CONFIGFILE@\fR, multipath only considers devices that are
|
||||
listed in the WWIDs file. This option overrides that behavior. For other values
|
||||
of \fIfind_multipaths\fR, this option has no effect. See the description of
|
||||
\fIfind_multipaths\fR in
|
||||
-.BR multipath.conf (5).
|
||||
+.BR @CONFIGFILE@ (5).
|
||||
This option should only be used in rare circumstances.
|
||||
.
|
||||
.TP
|
||||
@@ -246,8 +246,8 @@ Treat the bindings file as read only.
|
||||
.
|
||||
.TP
|
||||
.BI \-b " file"
|
||||
-Set \fIuser_friendly_names\fR bindings file location. The default is
|
||||
-\fI/etc/multipath/bindings\fR.
|
||||
+(\fBdeprecated, do not use\fR) Set \fIuser_friendly_names\fR bindings file location. The default is
|
||||
+\fI@STATE_DIR@/bindings\fR.
|
||||
.
|
||||
.TP
|
||||
.B \-q
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5.in
|
||||
similarity index 98%
|
||||
rename from multipath/multipath.conf.5
|
||||
rename to multipath/multipath.conf.5.in
|
||||
index 93af17db..20df2232 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5.in
|
||||
@@ -13,14 +13,14 @@
|
||||
.SH NAME
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.
|
||||
-multipath.conf \- multipath daemon configuration file.
|
||||
+@CONFIGFILE@, @CONFIGDIR@/*.conf \- multipath daemon configuration file.
|
||||
.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.SH DESCRIPTION
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.
|
||||
-.B "/etc/multipath.conf"
|
||||
+.B "@CONFIGFILE@"
|
||||
is the configuration file for the multipath daemon. It is used to
|
||||
overwrite the built-in configuration table of \fBmultipathd\fP.
|
||||
Any line whose first non-white-space character is a '#' is considered
|
||||
@@ -29,6 +29,15 @@ a comment line. Empty lines are ignored.
|
||||
Currently used multipathd configuration can be displayed with the \fBmultipath -t\fR
|
||||
or \fBmultipathd show config\fR command.
|
||||
.
|
||||
+.PP
|
||||
+Additional configuration can be made in drop-in files under
|
||||
+.B @CONFIGDIR@.
|
||||
+Files ending in \fI.conf\fR in this directory are read
|
||||
+in alphabetical order, after reading \fI@CONFIGFILE@\fR.
|
||||
+They use the same syntax as \fI@CONFIGFILE@\fR itself,
|
||||
+and support all sections and keywords. If a keyword occurs in the same section
|
||||
+in multiple files, the last occurence will take precedence over all others.
|
||||
+.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.SH SYNTAX
|
||||
@@ -85,7 +94,7 @@ not mandatory.
|
||||
.
|
||||
.LP
|
||||
.B Note on regular expressions:
|
||||
-The \fImultipath.conf\fR syntax allows many attribute values to be specified as POSIX
|
||||
+The \fI@CONFIGFILE@\fR syntax allows many attribute values to be specified as POSIX
|
||||
Extended Regular Expressions (see \fBregex\fR(7)). These regular expressions
|
||||
are \fBcase sensitive\fR and \fBnot anchored\fR, thus the expression "bar" matches "barbie",
|
||||
"rhabarber", and "wunderbar", but not "Barbie". To avoid unwanted substring
|
||||
@@ -711,7 +720,7 @@ The default is: \fBno\fR
|
||||
.B user_friendly_names
|
||||
If set to
|
||||
.I yes
|
||||
-, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent
|
||||
+, using the bindings file \fI@STATE_DIR@/bindings\fR to assign a persistent
|
||||
and unique alias to the multipath, in the form of mpath<n>. If set to
|
||||
.I no
|
||||
use the WWID as the alias. In either case this be will
|
||||
@@ -790,7 +799,7 @@ The full pathname of the binding file to be used when the user_friendly_names
|
||||
option is set.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB/etc/multipath/bindings\fR
|
||||
+The default is: \fB@STATE_DIR@/bindings\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
@@ -801,7 +810,7 @@ The full pathname of the WWIDs file, which is used by multipath to keep track
|
||||
of the WWIDs for LUNs it has created multipath devices on in the past.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB/etc/multipath/wwids\fR
|
||||
+The default is: \fB@STATE_DIR@/wwids\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
@@ -813,7 +822,7 @@ track of the persistent reservation key used for a specific WWID, when
|
||||
\fIreservation_key\fR is set to \fBfile\fR.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB/etc/multipath/prkeys\fR
|
||||
+The default is: \fB@STATE_DIR@/prkeys\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
@@ -872,7 +881,7 @@ The default is: \fBno\fR
|
||||
.I yes
|
||||
and the SCSI layer has already attached a hardware_handler to the device,
|
||||
multipath will not force the device to use the hardware_handler specified by
|
||||
-multipath.conf. If the SCSI layer has not attached a hardware handler,
|
||||
+@CONFIGFILE@. If the SCSI layer has not attached a hardware handler,
|
||||
multipath will continue to use its configured hardware handler.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1559,7 +1568,7 @@ given device, the attributes of all matching entries are applied to it.
|
||||
If an attribute is specified in several matching device subsections,
|
||||
later entries take precedence. Thus, entries in files under \fIconfig_dir\fR (in
|
||||
reverse alphabetical order) have the highest precedence, followed by entries
|
||||
-in \fImultipath.conf\fR; the built-in hardware table has the lowest
|
||||
+in \fI@CONFIGFILE@\fR; the built-in hardware table has the lowest
|
||||
precedence. Inside a configuration file, later entries have higher precedence
|
||||
than earlier ones.
|
||||
.LP
|
||||
diff --git a/multipathd/Makefile b/multipathd/Makefile
|
||||
index 0d0146c5..cdba3db1 100644
|
||||
--- a/multipathd/Makefile
|
||||
+++ b/multipathd/Makefile
|
||||
@@ -1,7 +1,8 @@
|
||||
include ../Makefile.inc
|
||||
|
||||
-EXEC := multipathd
|
||||
-CLI := multipathc
|
||||
+EXEC := multipathd
|
||||
+CLI := multipathc
|
||||
+MANPAGES := multipathd.8
|
||||
|
||||
CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \
|
||||
$(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \
|
||||
@@ -42,7 +43,7 @@ ifeq ($(FPIN_SUPPORT),1)
|
||||
OBJS += fpin_handlers.o
|
||||
endif
|
||||
|
||||
-all : $(EXEC) $(CLI)
|
||||
+all : $(EXEC) $(CLI) $(MANPAGES)
|
||||
|
||||
$(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
@echo building $@ because of $?
|
||||
@@ -79,7 +80,7 @@ uninstall:
|
||||
$(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket
|
||||
|
||||
clean: dep_clean
|
||||
- $(Q)$(RM) core *.o $(EXEC) $(CLI)
|
||||
+ $(Q)$(RM) core *.o $(EXEC) $(CLI) $(MANPAGES)
|
||||
|
||||
include $(wildcard $(OBJS:.o=.d) $(CLI_OBJS:.o=.d))
|
||||
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8.in
|
||||
similarity index 97%
|
||||
rename from multipathd/multipathd.8
|
||||
rename to multipathd/multipathd.8.in
|
||||
index cc72b775..e98c27fd 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8.in
|
||||
@@ -155,7 +155,7 @@ Show the format wildcards used in interactive commands taking $format.
|
||||
.TP
|
||||
.B list|show config
|
||||
Show the currently used configuration, derived from default values and values
|
||||
-specified within the configuration file \fI/etc/multipath.conf\fR.
|
||||
+specified within the configuration file \fI@CONFIGFILE@\fR.
|
||||
.
|
||||
.TP
|
||||
.B list|show config local
|
||||
@@ -165,7 +165,7 @@ the devices section to those devices that are actually present in the system.
|
||||
.TP
|
||||
.B list|show blacklist
|
||||
Show the currently used blacklist rules, derived from default values and values
|
||||
-specified within the configuration file \fI/etc/multipath.conf\fR.
|
||||
+specified within the configuration file \fI@CONFIGFILE@\fR.
|
||||
.
|
||||
.TP
|
||||
.B list|show devices
|
||||
@@ -290,13 +290,13 @@ Get the current persistent reservation key associated with $map.
|
||||
.B map|multipath $map setprkey key $key
|
||||
Set the persistent reservation key associated with $map to $key in the
|
||||
\fIprkeys_file\fR. This key will only be used by multipathd if
|
||||
-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR.
|
||||
+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR.
|
||||
.
|
||||
.TP
|
||||
.B map|multipath $map unsetprkey
|
||||
Remove the persistent reservation key associated with $map from the
|
||||
\fIprkeys_file\fR. This will only unset the key used by multipathd if
|
||||
-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR.
|
||||
+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR.
|
||||
.
|
||||
.TP
|
||||
.B path $path setmarginal
|
25
0032-libdmmp-Makefile-fix-bug-in-install-section.patch
Normal file
25
0032-libdmmp-Makefile-fix-bug-in-install-section.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 09:30:13 +0200
|
||||
Subject: [PATCH] libdmmp/Makefile: fix bug in install section
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libdmmp/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdmmp/Makefile b/libdmmp/Makefile
|
||||
index 078eca8f..172ba045 100644
|
||||
--- a/libdmmp/Makefile
|
||||
+++ b/libdmmp/Makefile
|
||||
@@ -44,7 +44,7 @@ install:
|
||||
$(DESTDIR)$(pkgconfdir)/$(PKGFILE)
|
||||
$(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \
|
||||
$(DESTDIR)$(pkgconfdir)/$(PKGFILE)
|
||||
- $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3
|
||||
+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3
|
||||
|
||||
uninstall:
|
@ -0,0 +1,75 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 10:22:13 +0200
|
||||
Subject: [PATCH] multipath-tools: README.md: improve documentation for
|
||||
compile-time options
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
README.md | 38 ++++++++++++++++++++++++++------------
|
||||
1 file changed, 26 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/README.md b/README.md
|
||||
index a7f994ae..679e55bf 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -89,9 +89,17 @@ The following variables can be passed to the `make` command line:
|
||||
* `plugindir="/some/path"`: directory where libmultipath plugins (path
|
||||
checkers, prioritizers, and foreign multipath support) will be looked up.
|
||||
This used to be the run-time option `multipath_dir` in earlier versions.
|
||||
- * `configdir="/some/path"` : directory to search for configuration files.
|
||||
+ The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on
|
||||
+ systems that have `/lib64`, and `lib` otherwise.
|
||||
+ * `configfile="/some/path`": The path to the main configuration file.
|
||||
+ The defalt is `$(etc_prefix)/etc/multipath.conf`.
|
||||
+ * `configdir="/some/path"` : directory to search for additional configuration files.
|
||||
This used to be the run-time option `config_dir` in earlier versions.
|
||||
- The default is `/etc/multipath/conf.d`.
|
||||
+ The default is `$(etc_prefix)/etc/multipath/conf.d`.
|
||||
+ * `statedir="/some/path"`: The path of the directory where multipath-tools
|
||||
+ stores run-time settings that need persist between reboots, such as known
|
||||
+ WWIDs, user-friendly names, and persistent reservation keys.
|
||||
+ The default is `$(etc_prefix)/etc/multipath`.
|
||||
* `READLINE=libedit` or `READLINE=libreadline`: enable command line history
|
||||
and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*.
|
||||
The respective development package will be required for building.
|
||||
@@ -119,21 +127,27 @@ The following variables can be passed to the `make` command line:
|
||||
### Installation Paths
|
||||
|
||||
* `prefix`: The directory prefix for (almost) all files to be installed.
|
||||
- Distributions may want to set this to `/usr`.
|
||||
- **Note**: for multipath-tools, unlike many other packages, `prefix`
|
||||
- defaults to the empty string, which resolves to the root directory (`/`).
|
||||
+ "Usr-merged" distributions[^systemd] may want to set this to `/usr`. The
|
||||
+ default is empty (`""`).
|
||||
* `usr_prefix`: where to install those parts of the code that aren't necessary
|
||||
- for booting. You may want to set this to `/usr` if `prefix` is empty.
|
||||
- * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`.
|
||||
- Some systemd installations use separate `prefix` and `rootprefix`. On such
|
||||
- a distribution, set `prefix`, and override `unitdir` to use systemd's
|
||||
- `rootprefix`.
|
||||
+ for booting. Non-usr-merged distributions[^systemd] may want to set this to
|
||||
+ `/usr`. The default is `$(prefix)`.
|
||||
+ * `systemd_prefix`: Prefix for systemd-related files[^systemd]. The default is `/usr`.
|
||||
+ * `etc_prefix`: The prefix for configuration files. "Usr-merged"
|
||||
+ distributions with immutable `/usr`[^systemd] may want to set this to
|
||||
+ `/etc`. The default is `$(prefix)`.
|
||||
* `LIB`: the subdirectory under `prefix` where shared libraries will be
|
||||
installed. By default, the makefile uses `/lib64` if this directory is
|
||||
found on the build system, and `/lib` otherwise.
|
||||
|
||||
-See also `configdir` and `plugindir` above. See `Makefile.inc` for more
|
||||
-fine-grained control.
|
||||
+The options `configdir`, `plugindir`, `configfile`, and `statedir` above can
|
||||
+be used for setting indvidual paths where the `prefix` variables don't provide
|
||||
+sufficient control. See `Makefile.inc` for even more fine-grained control.
|
||||
+
|
||||
+[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`.
|
||||
+ On such a distribution, set `prefix`, and override `unitdir` to use systemd's
|
||||
+ `rootprefix`. Recent systemd releases generally require everything to be
|
||||
+ installed under `/usr` (so-called "usr-merged" distribution). On "usr-
|
||||
|
||||
### Compiler Options
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 11:36:25 +0200
|
||||
Subject: [PATCH] libmultipath: print built-in values for deprecated options
|
||||
|
||||
In the error messages we print when a deprecated option is encountered,
|
||||
print the compile-time value of the option.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index f81c84aa..dace343d 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -314,14 +314,16 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \
|
||||
static int deprecated_handler(struct config *conf, vector strvec, const char *file,
|
||||
int line_nr);
|
||||
|
||||
-#define declare_deprecated_handler(option) \
|
||||
+#define declare_deprecated_handler(option, default) \
|
||||
static int \
|
||||
deprecated_ ## option ## _handler (struct config *conf, vector strvec, \
|
||||
const char *file, int line_nr) \
|
||||
{ \
|
||||
static bool warned; \
|
||||
if (!warned) { \
|
||||
- condlog(1, "%s line %d: ignoring deprecated option \"" #option "\"", file, line_nr); \
|
||||
+ condlog(1, "%s line %d: ignoring deprecated option \"" \
|
||||
+ #option "\", using built-in value: \"%s\"", \
|
||||
+ file, line_nr, default); \
|
||||
warned = true; \
|
||||
} \
|
||||
return deprecated_handler(conf, strvec, file, line_nr); \
|
||||
@@ -2057,11 +2059,11 @@ snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data)
|
||||
}
|
||||
|
||||
// Deprecated keywords
|
||||
-declare_deprecated_handler(config_dir)
|
||||
-declare_deprecated_handler(disable_changed_wwids)
|
||||
-declare_deprecated_handler(getuid_callout)
|
||||
-declare_deprecated_handler(multipath_dir)
|
||||
-declare_deprecated_handler(pg_timeout)
|
||||
+declare_deprecated_handler(config_dir, CONFIG_DIR)
|
||||
+declare_deprecated_handler(disable_changed_wwids, "yes")
|
||||
+declare_deprecated_handler(getuid_callout, "(not set)")
|
||||
+declare_deprecated_handler(multipath_dir, MULTIPATH_DIR)
|
||||
+declare_deprecated_handler(pg_timeout, "(not set)")
|
||||
|
||||
/*
|
||||
* If you add or remove a keyword also update multipath/multipath.conf.5
|
25
0035-multipath-add-a-missing-newline.patch
Normal file
25
0035-multipath-add-a-missing-newline.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 11:37:37 +0200
|
||||
Subject: [PATCH] multipath: add a missing newline
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 45e9745f..b91289e8 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -1025,7 +1025,7 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (check_alias_settings(conf)) {
|
||||
- fprintf(stderr, "fatal configuration error, aborting");
|
||||
+ fprintf(stderr, "fatal configuration error, aborting\n");
|
||||
exit(RTVL_FAIL);
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 16:03:34 +0200
|
||||
Subject: [PATCH] multipath-tools: allow prefixes with and w/o trailing slash
|
||||
|
||||
Add some logic to Makefile.inc that leads to the same result
|
||||
for "prefix=" and "prefix=/", or "prefix=/usr" and "prefix=/usr/".
|
||||
The logic does not work for multiple trailing slashes. It applies
|
||||
to all XYZ_prefix variables in Makefile.inc.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 35 ++++++++++++++++++++++-------------
|
||||
1 file changed, 22 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 79e521e1..6e384e68 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -43,22 +43,31 @@ etc_prefix := $(prefix)
|
||||
# Note: some systemd installations use separate "prefix" and "rootprefix".
|
||||
# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix)
|
||||
systemd_prefix := /usr
|
||||
-unitdir := $(systemd_prefix)/lib/systemd/system
|
||||
-tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d
|
||||
-modulesloaddir := $(systemd_prefix)/lib/modules-load.d
|
||||
-libudevdir := $(systemd_prefix)/lib/udev
|
||||
+
|
||||
+# Make sure all prefix variables end in "/"
|
||||
+append-slash = $(1)$(if $(filter %/,$(1)),,/)
|
||||
+override prefix := $(call append-slash,$(prefix))
|
||||
+override exec_prefix := $(call append-slash,$(exec_prefix))
|
||||
+override usr_prefix := $(call append-slash,$(usr_prefix))
|
||||
+override etc_prefix := $(call append-slash,$(etc_prefix))
|
||||
+override systemd_prefix := $(call append-slash,$(systemd_prefix))
|
||||
+
|
||||
+unitdir := $(systemd_prefix)lib/systemd/system
|
||||
+tmpfilesdir := $(systemd_prefix)lib/tmpfiles.d
|
||||
+modulesloaddir := $(systemd_prefix)lib/modules-load.d
|
||||
+libudevdir := $(systemd_prefix)lib/udev
|
||||
udevrulesdir := $(libudevdir)/rules.d
|
||||
-bindir := $(exec_prefix)/sbin
|
||||
-mandir := $(usr_prefix)/share/man
|
||||
+bindir := $(exec_prefix)sbin
|
||||
+mandir := $(usr_prefix)share/man
|
||||
LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib)
|
||||
-syslibdir := $(prefix)/$(LIB)
|
||||
-usrlibdir := $(usr_prefix)/$(LIB)
|
||||
-includedir := $(usr_prefix)/include
|
||||
+syslibdir := $(prefix)$(LIB)
|
||||
+usrlibdir := $(usr_prefix)$(LIB)
|
||||
+includedir := $(usr_prefix)include
|
||||
pkgconfdir := $(usrlibdir)/pkgconfig
|
||||
-plugindir := $(prefix)/$(LIB)/multipath
|
||||
-configdir := $(etc_prefix)/etc/multipath/conf.d
|
||||
-configfile := $(etc_prefix)/etc/multipath.conf
|
||||
-statedir := $(etc_prefix)/etc/multipath
|
||||
+plugindir := $(prefix)$(LIB)/multipath
|
||||
+configdir := $(etc_prefix)etc/multipath/conf.d
|
||||
+configfile := $(etc_prefix)etc/multipath.conf
|
||||
+statedir := $(etc_prefix)etc/multipath
|
||||
runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run)
|
||||
devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include)
|
||||
libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include)
|
897
0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch
Normal file
897
0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch
Normal file
@ -0,0 +1,897 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 Sep 2023 17:58:13 +0200
|
||||
Subject: [PATCH] libmultipath: deprecate bindings_file, wwids_file,
|
||||
prkeys_file
|
||||
|
||||
The options bindings_file, wwids_file, and prkeys_file have been
|
||||
deprecated since cb4d6db ("libmultipath: deprecate file and directory config
|
||||
options") (multipath-tools 0.8.8). Deprecate and ignore them now.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/alias.c | 43 +++++++++----------
|
||||
libmultipath/alias.h | 3 +-
|
||||
libmultipath/config.c | 18 --------
|
||||
libmultipath/config.h | 3 --
|
||||
libmultipath/dict.c | 39 +++---------------
|
||||
libmultipath/libmultipath.version | 8 +---
|
||||
libmultipath/prkey.c | 7 ++--
|
||||
libmultipath/prkey.h | 7 ++--
|
||||
libmultipath/propsel.c | 5 +--
|
||||
libmultipath/wwids.c | 18 ++------
|
||||
multipath/main.c | 2 +-
|
||||
multipath/multipath.conf.5.in | 23 +++++------
|
||||
multipathd/uxlsnr.c | 17 +++-----
|
||||
tests/alias.c | 68 +++++++++++++++----------------
|
||||
14 files changed, 90 insertions(+), 171 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index 964b8a7b..e5d3f151 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -55,6 +55,8 @@
|
||||
/* uatomic access only */
|
||||
static int bindings_file_changed = 1;
|
||||
|
||||
+static const char bindings_file_path[] = DEFAULT_BINDINGS_FILE;
|
||||
+
|
||||
static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct timespec bindings_last_updated;
|
||||
|
||||
@@ -274,7 +276,6 @@ static int write_bindings_file(const Bindings *bindings, int fd,
|
||||
|
||||
void handle_bindings_file_inotify(const struct inotify_event *event)
|
||||
{
|
||||
- struct config *conf;
|
||||
const char *base;
|
||||
bool changed = false;
|
||||
struct stat st;
|
||||
@@ -284,12 +285,9 @@ void handle_bindings_file_inotify(const struct inotify_event *event)
|
||||
if (!(event->mask & IN_MOVED_TO))
|
||||
return;
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- base = strrchr(conf->bindings_file, '/');
|
||||
- changed = base && base > conf->bindings_file &&
|
||||
- !strcmp(base + 1, event->name);
|
||||
- ret = stat(conf->bindings_file, &st);
|
||||
- put_multipath_config(conf);
|
||||
+ base = strrchr(bindings_file_path, '/');
|
||||
+ changed = base && !strcmp(base + 1, event->name);
|
||||
+ ret = stat(bindings_file_path, &st);
|
||||
|
||||
if (!changed)
|
||||
return;
|
||||
@@ -310,8 +308,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event)
|
||||
__func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
-static int update_bindings_file(const Bindings *bindings,
|
||||
- const char *bindings_file)
|
||||
+static int update_bindings_file(const Bindings *bindings)
|
||||
{
|
||||
int rc;
|
||||
int fd = -1;
|
||||
@@ -319,7 +316,7 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
mode_t old_umask;
|
||||
struct timespec ts;
|
||||
|
||||
- if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file))
|
||||
+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file_path))
|
||||
return -1;
|
||||
/* coverity: SECURE_TEMP */
|
||||
old_umask = umask(0077);
|
||||
@@ -336,13 +333,13 @@ static int update_bindings_file(const Bindings *bindings,
|
||||
unlink(tempname);
|
||||
return rc;
|
||||
}
|
||||
- if ((rc = rename(tempname, bindings_file)) == -1)
|
||||
+ if ((rc = rename(tempname, bindings_file_path)) == -1)
|
||||
condlog(0, "%s: rename: %m", __func__);
|
||||
else {
|
||||
pthread_mutex_lock(×tamp_mutex);
|
||||
bindings_last_updated = ts;
|
||||
pthread_mutex_unlock(×tamp_mutex);
|
||||
- condlog(1, "updated bindings file %s", bindings_file);
|
||||
+ condlog(1, "updated bindings file %s", bindings_file_path);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -474,7 +471,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww
|
||||
|
||||
/* Called with binding_mutex held */
|
||||
static char *
|
||||
-allocate_binding(const char *filename, const char *wwid, int id, const char *prefix)
|
||||
+allocate_binding(const char *wwid, int id, const char *prefix)
|
||||
{
|
||||
STRBUF_ON_STACK(buf);
|
||||
char *alias;
|
||||
@@ -498,7 +495,7 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (update_bindings_file(&global_bindings, filename) == -1) {
|
||||
+ if (update_bindings_file(&global_bindings) == -1) {
|
||||
condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid);
|
||||
delete_binding(&global_bindings, wwid);
|
||||
free(alias);
|
||||
@@ -565,7 +562,7 @@ static void read_bindings_file(void)
|
||||
* that the mpvec corrcectly represents kernel state.
|
||||
*/
|
||||
|
||||
-char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old,
|
||||
+char *get_user_friendly_alias(const char *wwid, const char *alias_old,
|
||||
const char *prefix, bool bindings_read_only)
|
||||
{
|
||||
char *alias = NULL;
|
||||
@@ -622,7 +619,7 @@ new_alias:
|
||||
}
|
||||
|
||||
if (!bindings_read_only && id > 0)
|
||||
- alias = allocate_binding(file, wwid, id, prefix);
|
||||
+ alias = allocate_binding(wwid, id, prefix);
|
||||
|
||||
if (alias && !new_binding)
|
||||
condlog(2, "Allocated existing binding [%s] for WWID [%s]",
|
||||
@@ -715,12 +712,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file,
|
||||
header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0';
|
||||
if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) {
|
||||
condlog(2, "%s: failed to read header from %s", __func__,
|
||||
- conf->bindings_file);
|
||||
+ bindings_file_path);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
rc = -1;
|
||||
} else if (strcmp(header, BINDINGS_FILE_HEADER)) {
|
||||
condlog(2, "%s: invalid header in %s", __func__,
|
||||
- conf->bindings_file);
|
||||
+ bindings_file_path);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
rc = -1;
|
||||
}
|
||||
@@ -787,13 +784,13 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings,
|
||||
}
|
||||
}
|
||||
|
||||
- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER);
|
||||
+ fd = open_file(bindings_file_path, &can_write, BINDINGS_FILE_HEADER);
|
||||
if (fd == -1)
|
||||
return BINDINGS_FILE_ERROR;
|
||||
|
||||
file = fdopen(fd, "r");
|
||||
if (file != NULL) {
|
||||
- condlog(3, "%s: reading %s", __func__, conf->bindings_file);
|
||||
+ condlog(3, "%s: reading %s", __func__, bindings_file_path);
|
||||
|
||||
pthread_cleanup_push(cleanup_fclose, file);
|
||||
ret = _check_bindings_file(conf, file, bindings);
|
||||
@@ -812,20 +809,20 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings,
|
||||
bindings_last_updated = ts;
|
||||
pthread_mutex_unlock(×tamp_mutex);
|
||||
} else if (ret == -1 && can_write && !conf->bindings_read_only) {
|
||||
- ret = update_bindings_file(bindings, conf->bindings_file);
|
||||
+ ret = update_bindings_file(bindings);
|
||||
if (ret == 0)
|
||||
rc = BINDINGS_FILE_READ;
|
||||
else
|
||||
rc = BINDINGS_FILE_BAD;
|
||||
} else {
|
||||
condlog(0, "ERROR: bad settings in read-only bindings file %s",
|
||||
- conf->bindings_file);
|
||||
+ bindings_file_path);
|
||||
rc = BINDINGS_FILE_BAD;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
} else {
|
||||
condlog(1, "failed to fdopen %s: %m",
|
||||
- conf->bindings_file);
|
||||
+ bindings_file_path);
|
||||
close(fd);
|
||||
rc = BINDINGS_FILE_ERROR;
|
||||
}
|
||||
diff --git a/libmultipath/alias.h b/libmultipath/alias.h
|
||||
index ca8911f4..629e8d56 100644
|
||||
--- a/libmultipath/alias.h
|
||||
+++ b/libmultipath/alias.h
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
int valid_alias(const char *alias);
|
||||
int get_user_friendly_wwid(const char *alias, char *buff);
|
||||
-char *get_user_friendly_alias(const char *wwid, const char *file,
|
||||
- const char *alias_old,
|
||||
+char *get_user_friendly_alias(const char *wwid, const char *alias_old,
|
||||
const char *prefix, bool bindings_read_only);
|
||||
|
||||
struct config;
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 7b207590..b7dbc6f5 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -752,15 +752,6 @@ static void _uninit_config(struct config *conf)
|
||||
if (conf->hwhandler)
|
||||
free(conf->hwhandler);
|
||||
|
||||
- if (conf->bindings_file)
|
||||
- free(conf->bindings_file);
|
||||
-
|
||||
- if (conf->wwids_file)
|
||||
- free(conf->wwids_file);
|
||||
-
|
||||
- if (conf->prkeys_file)
|
||||
- free(conf->prkeys_file);
|
||||
-
|
||||
if (conf->prio_name)
|
||||
free(conf->prio_name);
|
||||
|
||||
@@ -922,9 +913,6 @@ int _init_config (const char *file, struct config *conf)
|
||||
* internal defaults
|
||||
*/
|
||||
get_sys_max_fds(&conf->max_fds);
|
||||
- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
|
||||
- conf->wwids_file = set_default(DEFAULT_WWIDS_FILE);
|
||||
- conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE);
|
||||
conf->attribute_flags = 0;
|
||||
conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
|
||||
conf->checkint = CHECKINT_UNDEF;
|
||||
@@ -1078,12 +1066,6 @@ int _init_config (const char *file, struct config *conf)
|
||||
merge_blacklist(conf->elist_wwid);
|
||||
merge_blacklist_device(conf->elist_device);
|
||||
|
||||
- if (conf->bindings_file == NULL)
|
||||
- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
|
||||
-
|
||||
- if (!conf->bindings_file || !conf->wwids_file || !conf->prkeys_file)
|
||||
- goto out;
|
||||
-
|
||||
libmp_verbosity = conf->verbosity;
|
||||
return 0;
|
||||
out:
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 0a2c297b..8c22ce75 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -207,9 +207,6 @@ struct config {
|
||||
char * uid_attribute;
|
||||
char * features;
|
||||
char * hwhandler;
|
||||
- char * bindings_file;
|
||||
- char * wwids_file;
|
||||
- char * prkeys_file;
|
||||
char * prio_name;
|
||||
char * prio_args;
|
||||
char * checker_name;
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index dace343d..044067af 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -168,27 +168,6 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int
|
||||
-set_path(vector strvec, void *ptr, const char *file, int line_nr)
|
||||
-{
|
||||
- char **str_ptr = (char **)ptr;
|
||||
- char *old_str = *str_ptr;
|
||||
-
|
||||
- *str_ptr = set_value(strvec);
|
||||
- if (!*str_ptr) {
|
||||
- free(old_str);
|
||||
- return 1;
|
||||
- }
|
||||
- if ((*str_ptr)[0] != '/'){
|
||||
- condlog(1, "%s line %d, %s is not an absolute path. Ignoring",
|
||||
- file, line_nr, *str_ptr);
|
||||
- free(*str_ptr);
|
||||
- *str_ptr = old_str;
|
||||
- } else
|
||||
- free(old_str);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr)
|
||||
{
|
||||
@@ -831,15 +810,6 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef)
|
||||
declare_mp_handler(user_friendly_names, set_yes_no_undef)
|
||||
declare_mp_snprint(user_friendly_names, print_yes_no_undef)
|
||||
|
||||
-declare_def_warn_handler(bindings_file, set_path)
|
||||
-declare_def_snprint(bindings_file, print_str)
|
||||
-
|
||||
-declare_def_warn_handler(wwids_file, set_path)
|
||||
-declare_def_snprint(wwids_file, print_str)
|
||||
-
|
||||
-declare_def_warn_handler(prkeys_file, set_path)
|
||||
-declare_def_snprint(prkeys_file, print_str)
|
||||
-
|
||||
declare_def_handler(retain_hwhandler, set_yes_no_undef)
|
||||
declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef,
|
||||
DEFAULT_RETAIN_HWHANDLER)
|
||||
@@ -2064,6 +2034,9 @@ declare_deprecated_handler(disable_changed_wwids, "yes")
|
||||
declare_deprecated_handler(getuid_callout, "(not set)")
|
||||
declare_deprecated_handler(multipath_dir, MULTIPATH_DIR)
|
||||
declare_deprecated_handler(pg_timeout, "(not set)")
|
||||
+declare_deprecated_handler(bindings_file, DEFAULT_BINDINGS_FILE)
|
||||
+declare_deprecated_handler(wwids_file, DEFAULT_WWIDS_FILE)
|
||||
+declare_deprecated_handler(prkeys_file, DEFAULT_PRKEYS_FILE)
|
||||
|
||||
/*
|
||||
* If you add or remove a keyword also update multipath/multipath.conf.5
|
||||
@@ -2106,9 +2079,9 @@ init_keywords(vector keywords)
|
||||
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
|
||||
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
|
||||
install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline);
|
||||
- install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file);
|
||||
- install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file);
|
||||
- install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
|
||||
+ install_keyword("bindings_file", &deprecated_bindings_file_handler, &snprint_deprecated);
|
||||
+ install_keyword("wwids_file", &deprecated_wwids_file_handler, &snprint_deprecated);
|
||||
+ install_keyword("prkeys_file", &deprecated_prkeys_file_handler, &snprint_deprecated);
|
||||
install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
|
||||
install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
|
||||
install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt);
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 57e50c12..8368ef7a 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 {
|
||||
put_multipath_config;
|
||||
};
|
||||
|
||||
-LIBMULTIPATH_20.0.0 {
|
||||
+LIBMULTIPATH_21.0.0 {
|
||||
global:
|
||||
/* symbols referenced by multipath and multipathd */
|
||||
add_foreign;
|
||||
@@ -121,6 +121,7 @@ global:
|
||||
get_used_hwes;
|
||||
get_vpd_sgio;
|
||||
group_by_prio;
|
||||
+ handle_bindings_file_inotify;
|
||||
has_dm_info;
|
||||
init_checkers;
|
||||
init_config;
|
||||
@@ -238,8 +239,3 @@ global:
|
||||
local:
|
||||
*;
|
||||
};
|
||||
-
|
||||
-LIBMULTIPATH_20.1.0 {
|
||||
-global:
|
||||
- handle_bindings_file_inotify;
|
||||
-};
|
||||
diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c
|
||||
index a215499d..c66d293b 100644
|
||||
--- a/libmultipath/prkey.c
|
||||
+++ b/libmultipath/prkey.c
|
||||
@@ -157,8 +157,7 @@ static int do_prkey(int fd, char *wwid, char *keystr, int cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey,
|
||||
- uint8_t *sa_flags)
|
||||
+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags)
|
||||
{
|
||||
int fd;
|
||||
int unused;
|
||||
@@ -168,7 +167,7 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey,
|
||||
if (!strlen(mpp->wwid))
|
||||
goto out;
|
||||
|
||||
- fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER);
|
||||
+ fd = open_file(DEFAULT_PRKEYS_FILE, &unused, PRKEYS_FILE_HEADER);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ);
|
||||
@@ -201,7 +200,7 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey,
|
||||
sa_flags &= MPATH_F_APTPL_MASK;
|
||||
}
|
||||
|
||||
- fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER);
|
||||
+ fd = open_file(DEFAULT_PRKEYS_FILE, &can_write, PRKEYS_FILE_HEADER);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
if (!can_write) {
|
||||
diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h
|
||||
index a16de106..43afd5e4 100644
|
||||
--- a/libmultipath/prkey.h
|
||||
+++ b/libmultipath/prkey.h
|
||||
@@ -16,9 +16,8 @@
|
||||
int print_reservation_key(struct strbuf *buff,
|
||||
struct be64 key, uint8_t flags, int source);
|
||||
int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags);
|
||||
-int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey,
|
||||
- uint8_t sa_flags);
|
||||
-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey,
|
||||
- uint8_t *sa_flags);
|
||||
+int set_prkey(struct config *conf, struct multipath *mpp,
|
||||
+ uint64_t prkey, uint8_t sa_flags);
|
||||
+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags);
|
||||
|
||||
#endif /* _PRKEY_H */
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 354e883f..44241e2a 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -401,8 +401,7 @@ int select_alias(struct config *conf, struct multipath * mp)
|
||||
|
||||
select_alias_prefix(conf, mp);
|
||||
|
||||
- mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file,
|
||||
- mp->alias_old, mp->alias_prefix,
|
||||
+ mp->alias = get_user_friendly_alias(mp->wwid, mp->alias_old, mp->alias_prefix,
|
||||
conf->bindings_read_only);
|
||||
|
||||
if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE))
|
||||
@@ -992,7 +991,7 @@ int select_reservation_key(struct config *conf, struct multipath *mp)
|
||||
out:
|
||||
if (mp->prkey_source == PRKEY_SOURCE_FILE) {
|
||||
from_file = " (from prkeys file)";
|
||||
- if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0)
|
||||
+ if (get_prkey(mp, &prkey, &mp->sa_flags) != 0)
|
||||
put_be64(mp->reservation_key, 0);
|
||||
else
|
||||
put_be64(mp->reservation_key, prkey);
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 89bb60ca..591cd09b 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -94,12 +94,8 @@ replace_wwids(vector mp)
|
||||
struct multipath * mpp;
|
||||
size_t len;
|
||||
int ret = -1;
|
||||
- struct config *conf;
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- pthread_cleanup_push(put_multipath_config, conf);
|
||||
- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
|
||||
- pthread_cleanup_pop(1);
|
||||
+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
|
||||
@@ -200,7 +196,6 @@ remove_wwid(char *wwid) {
|
||||
int len, can_write;
|
||||
char *str;
|
||||
int ret = -1;
|
||||
- struct config *conf;
|
||||
|
||||
len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */
|
||||
str = malloc(len);
|
||||
@@ -216,10 +211,7 @@ remove_wwid(char *wwid) {
|
||||
goto out;
|
||||
}
|
||||
condlog(3, "removing line '%s' from wwids file", str);
|
||||
- conf = get_multipath_config();
|
||||
- pthread_cleanup_push(put_multipath_config, conf);
|
||||
- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
|
||||
- pthread_cleanup_pop(1);
|
||||
+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER);
|
||||
|
||||
if (fd < 0) {
|
||||
ret = -1;
|
||||
@@ -244,12 +236,8 @@ check_wwids_file(char *wwid, int write_wwid)
|
||||
{
|
||||
int fd, can_write, found, ret;
|
||||
FILE *f;
|
||||
- struct config *conf;
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- pthread_cleanup_push(put_multipath_config, conf);
|
||||
- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
|
||||
- pthread_cleanup_pop(1);
|
||||
+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index b91289e8..9e1c5052 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -856,7 +856,7 @@ main (int argc, char *argv[])
|
||||
libmp_verbosity = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
- conf->bindings_file = strdup(optarg);
|
||||
+ condlog(1, "option -b ignored");
|
||||
break;
|
||||
case 'B':
|
||||
conf->bindings_read_only = 1;
|
||||
diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in
|
||||
index 20df2232..d320a88f 100644
|
||||
--- a/multipath/multipath.conf.5.in
|
||||
+++ b/multipath/multipath.conf.5.in
|
||||
@@ -794,35 +794,28 @@ The default is: \fB<unset>\fR
|
||||
.
|
||||
.TP
|
||||
.B bindings_file
|
||||
-(Deprecated) This option is deprecated, and will be removed in a future release.
|
||||
-The full pathname of the binding file to be used when the user_friendly_names
|
||||
-option is set.
|
||||
+(Deprecated) This option is not supported any more, and will be ignored.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB@STATE_DIR@/bindings\fR
|
||||
+The compiled-in value is: \fB@STATE_DIR@/bindings\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
.TP
|
||||
.B wwids_file
|
||||
-(Deprecated) This option is deprecated, and will be removed in a future release.
|
||||
-The full pathname of the WWIDs file, which is used by multipath to keep track
|
||||
-of the WWIDs for LUNs it has created multipath devices on in the past.
|
||||
+(Deprecated) This option is not supported any more, and will be ignored.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB@STATE_DIR@/wwids\fR
|
||||
+The compiled-in value is: \fB@STATE_DIR@/wwids\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
.TP
|
||||
.B prkeys_file
|
||||
-(Deprecated) This option is deprecated, and will be removed in a future release.
|
||||
-The full pathname of the prkeys file, which is used by multipathd to keep
|
||||
-track of the persistent reservation key used for a specific WWID, when
|
||||
-\fIreservation_key\fR is set to \fBfile\fR.
|
||||
+(Deprecated) This option is not supported any more, and will be ignored.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB@STATE_DIR@/prkeys\fR
|
||||
+The compiled-in value is: \fB@STATE_DIR@/prkeys\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
@@ -989,6 +982,10 @@ The default is: \fB<unset>\fR
|
||||
.TP
|
||||
.B config_dir
|
||||
(Deprecated) This option is not supported any more, and the value is ignored.
|
||||
+.RS
|
||||
+.TP
|
||||
+The compiled-in value is: \fB@CONFIGDIR@\fR
|
||||
+.RE
|
||||
.
|
||||
.
|
||||
.TP
|
||||
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
|
||||
index d1f8f234..4d6f258c 100644
|
||||
--- a/multipathd/uxlsnr.c
|
||||
+++ b/multipathd/uxlsnr.c
|
||||
@@ -203,7 +203,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
int dir_reset = 0;
|
||||
int conf_reset = 0;
|
||||
int mp_reset = 0;
|
||||
- char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
|
||||
if (notify_fd == -1)
|
||||
return;
|
||||
@@ -221,7 +220,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
if (wds->mp_wd == -1)
|
||||
mp_reset = 1;
|
||||
}
|
||||
- bindings_file = strdup(conf->bindings_file);
|
||||
put_multipath_config(conf);
|
||||
|
||||
if (dir_reset) {
|
||||
@@ -242,17 +240,12 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds,
|
||||
if (wds->conf_wd == -1)
|
||||
condlog(3, "didn't set up notifications on /etc/multipath.conf: %m");
|
||||
}
|
||||
- if (mp_reset && bindings_file) {
|
||||
- char *slash = strrchr(bindings_file, '/');
|
||||
-
|
||||
- if (slash && slash > bindings_file) {
|
||||
- *slash = '\0';
|
||||
- wds->mp_wd = inotify_add_watch(notify_fd, bindings_file,
|
||||
- IN_MOVED_TO|IN_ONLYDIR);
|
||||
- if (wds->mp_wd == -1)
|
||||
+ if (mp_reset) {
|
||||
+ wds->mp_wd = inotify_add_watch(notify_fd, STATE_DIR,
|
||||
+ IN_MOVED_TO|IN_ONLYDIR);
|
||||
+ if (wds->mp_wd == -1)
|
||||
condlog(3, "didn't set up notifications on %s: %m",
|
||||
- bindings_file);
|
||||
- }
|
||||
+ STATE_DIR);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/tests/alias.c b/tests/alias.c
|
||||
index 94df36d8..f893d174 100644
|
||||
--- a/tests/alias.c
|
||||
+++ b/tests/alias.c
|
||||
@@ -1264,10 +1264,10 @@ static void al_a(void **state)
|
||||
will_return(__wrap_write, ln);
|
||||
will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
|
||||
will_return(__wrap_rename, 0);
|
||||
- expect_condlog(1, "updated bindings file foo");
|
||||
+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE);
|
||||
expect_condlog(3, NEW_STR("MPATHa", "WWIDa"));
|
||||
|
||||
- alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 1, "MPATH");
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
check_bindings_size(1);
|
||||
@@ -1283,10 +1283,10 @@ static void al_zz(void **state)
|
||||
will_return(__wrap_write, ln);
|
||||
will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
|
||||
will_return(__wrap_rename, 0);
|
||||
- expect_condlog(1, "updated bindings file foo");
|
||||
+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE);
|
||||
expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz"));
|
||||
|
||||
- alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH");
|
||||
+ alias = allocate_binding("WWIDzz", 26*26 + 26, "MPATH");
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
assert_string_equal(alias, "MPATHzz");
|
||||
check_bindings_size(1);
|
||||
@@ -1298,7 +1298,7 @@ static void al_0(void **state)
|
||||
char *alias;
|
||||
|
||||
expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n");
|
||||
- alias = allocate_binding(0, "WWIDa", 0, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 0, "MPATH");
|
||||
assert_ptr_equal(alias, NULL);
|
||||
check_bindings_size(0);
|
||||
}
|
||||
@@ -1308,7 +1308,7 @@ static void al_m2(void **state)
|
||||
char *alias;
|
||||
|
||||
expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n");
|
||||
- alias = allocate_binding(0, "WWIDa", -2, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", -2, "MPATH");
|
||||
assert_ptr_equal(alias, NULL);
|
||||
check_bindings_size(0);
|
||||
}
|
||||
@@ -1325,10 +1325,10 @@ static void al_write_partial(void **state)
|
||||
will_return(__wrap_write, ln + sizeof(ln) - 2);
|
||||
will_return(__wrap_write, 1);
|
||||
will_return(__wrap_rename, 0);
|
||||
- expect_condlog(1, "updated bindings file foo");
|
||||
+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE);
|
||||
expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n");
|
||||
|
||||
- alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 1, "MPATH");
|
||||
assert_ptr_not_equal(alias, NULL);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
check_bindings_size(1);
|
||||
@@ -1350,7 +1350,7 @@ static void al_write_short(void **state)
|
||||
expect_condlog(1, "failed to write new bindings file");
|
||||
expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
|
||||
|
||||
- alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 1, "MPATH");
|
||||
assert_ptr_equal(alias, NULL);
|
||||
check_bindings_size(0);
|
||||
}
|
||||
@@ -1366,7 +1366,7 @@ static void al_write_err(void **state)
|
||||
expect_condlog(1, "failed to write new bindings file");
|
||||
expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
|
||||
|
||||
- alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 1, "MPATH");
|
||||
assert_ptr_equal(alias, NULL);
|
||||
check_bindings_size(0);
|
||||
}
|
||||
@@ -1383,7 +1383,7 @@ static void al_rename_err(void **state)
|
||||
|
||||
expect_condlog(0, "update_bindings_file: rename: Read-only file system");
|
||||
expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
|
||||
- alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
|
||||
+ alias = allocate_binding("WWIDa", 1, "MPATH");
|
||||
assert_ptr_equal(alias, NULL);
|
||||
check_bindings_size(0);
|
||||
}
|
||||
@@ -1415,7 +1415,7 @@ static int test_allocate_binding(void)
|
||||
strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \
|
||||
will_return(__wrap_rename, err); \
|
||||
if (err == 0) { \
|
||||
- expect_condlog(1, "updated bindings file x\n"); \
|
||||
+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); \
|
||||
expect_condlog(3, NEW_STR(alias, wwid)); \
|
||||
} else { \
|
||||
expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \
|
||||
@@ -1441,7 +1441,7 @@ static void gufa_empty_new_rw(void **state) {
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
|
||||
mock_allocate_binding("MPATHa", "WWID0");
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1454,7 +1454,7 @@ static void gufa_empty_new_ro_1(void **state) {
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system");
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1465,7 +1465,7 @@ static void gufa_empty_new_ro_2(void **state) {
|
||||
expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
|
||||
mock_unused_alias("MPATHa");
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1477,7 +1477,7 @@ static void gufa_match_a_unused(void **state) {
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1490,7 +1490,7 @@ static void gufa_match_a_self(void **state) {
|
||||
mock_self_alias("MPATHa", "WWID0");
|
||||
expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1503,7 +1503,7 @@ static void gufa_match_a_used(void **state) {
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
mock_used_alias("MPATHa", "WWID0");
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1518,7 +1518,7 @@ static void gufa_nomatch_a_c(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHb");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1534,7 +1534,7 @@ static void gufa_nomatch_c_a(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHb");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1550,7 +1550,7 @@ static void gufa_nomatch_c_b(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1567,7 +1567,7 @@ static void gufa_nomatch_c_b_used(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID4", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHd");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1584,7 +1584,7 @@ static void gufa_nomatch_b_f_a(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHc");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1599,7 +1599,7 @@ static void gufa_nomatch_b_aa_a(void **state) {
|
||||
mock_unused_alias("MPATHab");
|
||||
mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID28", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHab");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1616,7 +1616,7 @@ static void gufa_nomatch_b_f_a_sorted(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHc");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1632,7 +1632,7 @@ static void gufa_old_empty(void **state) {
|
||||
mock_allocate_binding("MPATHz", "WWID0");
|
||||
expect_condlog(2, ALLOC_STR("MPATHz", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHz");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1644,7 +1644,7 @@ static void gufa_old_match(void **state) {
|
||||
"MPATHz WWID0");
|
||||
expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHz");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1661,7 +1661,7 @@ static void gufa_old_match_other(void **state) {
|
||||
|
||||
mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1);
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1678,7 +1678,7 @@ static void gufa_old_match_other_used(void **state) {
|
||||
mock_unused_alias("MPATHb");
|
||||
|
||||
mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1);
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHb");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1695,7 +1695,7 @@ static void gufa_old_match_other_wwidmatch(void **state) {
|
||||
mock_unused_alias("MPATHc");
|
||||
expect_condlog(3, EXISTING_STR("MPATHc", "WWID2"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHc");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1711,7 +1711,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) {
|
||||
expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
|
||||
mock_used_alias("MPATHc", "WWID2");
|
||||
|
||||
- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1725,7 +1725,7 @@ static void gufa_old_nomatch_wwidmatch(void **state) {
|
||||
mock_unused_alias("MPATHa");
|
||||
expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHa");
|
||||
free(alias);
|
||||
}
|
||||
@@ -1739,7 +1739,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) {
|
||||
expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
|
||||
mock_used_alias("MPATHa", "WWID0");
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_ptr_equal(alias, NULL);
|
||||
}
|
||||
|
||||
@@ -1754,7 +1754,7 @@ static void gufa_old_nomatch_nowwidmatch(void **state) {
|
||||
mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1);
|
||||
expect_condlog(2, ALLOC_STR("MPATHz", "WWID0"));
|
||||
|
||||
- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
|
||||
+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false);
|
||||
assert_string_equal(alias, "MPATHz");
|
||||
free(alias);
|
||||
}
|
158
0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch
Normal file
158
0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 Sep 2023 11:54:47 +0200
|
||||
Subject: [PATCH] libmultipath: avoid -Warray-bounds error in uatomic
|
||||
operations
|
||||
|
||||
The use of uatomic_xchg() in alias.c causes a -Warray-bounds error
|
||||
on distributions using gcc 12, such as Fedora 37. This is a similar
|
||||
error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc
|
||||
12 and musl libc"). This happens only with liburcu 0.13 and earlier,
|
||||
and only with certain gcc versions. See liburcu commit 835b9ab
|
||||
("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11").
|
||||
|
||||
Enhance the fix for 2534c4f by a adding a workaround for uatomic_xchg(),
|
||||
and introduce the macro URCU_VERSION (originally only used for multipathd)
|
||||
globally.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
create-config.mk | 5 +++++
|
||||
libmultipath/alias.c | 5 +++--
|
||||
libmultipath/lock.h | 21 +++++++++++++--------
|
||||
multipathd/Makefile | 2 --
|
||||
5 files changed, 22 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 6e384e68..04bfa56e 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS)
|
||||
-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \
|
||||
+CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \
|
||||
-DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \
|
||||
-DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \
|
||||
-DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \
|
||||
diff --git a/create-config.mk b/create-config.mk
|
||||
index d1255971..4d318b96 100644
|
||||
--- a/create-config.mk
|
||||
+++ b/create-config.mk
|
||||
@@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \
|
||||
$(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \
|
||||
|| echo -Wno-type-limits )
|
||||
|
||||
+URCU_VERSION = $(shell \
|
||||
+ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \
|
||||
+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }')
|
||||
+
|
||||
DEFINES :=
|
||||
|
||||
ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0)
|
||||
@@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h
|
||||
@echo creating $@
|
||||
@echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@
|
||||
@echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@
|
||||
+ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@
|
||||
@echo "SYSTEMD := $(SYSTEMD)" >>$@
|
||||
@echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@
|
||||
@echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@
|
||||
diff --git a/libmultipath/alias.c b/libmultipath/alias.c
|
||||
index e5d3f151..74431f3f 100644
|
||||
--- a/libmultipath/alias.c
|
||||
+++ b/libmultipath/alias.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "devmapper.h"
|
||||
#include "strbuf.h"
|
||||
#include "time-util.h"
|
||||
+#include "lock.h"
|
||||
|
||||
/*
|
||||
* significant parts of this file were taken from iscsi-bindings.c of the
|
||||
@@ -300,7 +301,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event)
|
||||
pthread_mutex_unlock(×tamp_mutex);
|
||||
|
||||
if (changed) {
|
||||
- uatomic_xchg(&bindings_file_changed, 1);
|
||||
+ uatomic_xchg_int(&bindings_file_changed, 1);
|
||||
condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld",
|
||||
__func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000);
|
||||
} else
|
||||
@@ -775,7 +776,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings,
|
||||
int rc = 0, ret, fd;
|
||||
FILE *file;
|
||||
struct stat st;
|
||||
- int has_changed = uatomic_xchg(&bindings_file_changed, 0);
|
||||
+ int has_changed = uatomic_xchg_int(&bindings_file_changed, 0);
|
||||
|
||||
if (!force) {
|
||||
if (!has_changed) {
|
||||
diff --git a/libmultipath/lock.h b/libmultipath/lock.h
|
||||
index 9814be76..ac80d1d8 100644
|
||||
--- a/libmultipath/lock.h
|
||||
+++ b/libmultipath/lock.h
|
||||
@@ -13,15 +13,20 @@ struct mutex_lock {
|
||||
int waiters; /* uatomic access only */
|
||||
};
|
||||
|
||||
-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12
|
||||
+static inline void init_lock(struct mutex_lock *a)
|
||||
+{
|
||||
+ pthread_mutex_init(&a->mutex, NULL);
|
||||
+ uatomic_set(&a->waiters, 0);
|
||||
+}
|
||||
+
|
||||
+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
|
||||
-static inline void init_lock(struct mutex_lock *a)
|
||||
+static inline int uatomic_xchg_int(int *ptr, int val)
|
||||
{
|
||||
- pthread_mutex_init(&a->mutex, NULL);
|
||||
- uatomic_set(&a->waiters, 0);
|
||||
+ return uatomic_xchg(ptr, val);
|
||||
}
|
||||
|
||||
static inline void lock(struct mutex_lock *a)
|
||||
@@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a)
|
||||
uatomic_dec(&a->waiters);
|
||||
}
|
||||
|
||||
+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00
|
||||
+#pragma GCC diagnostic pop
|
||||
+#endif
|
||||
+
|
||||
static inline int trylock(struct mutex_lock *a)
|
||||
{
|
||||
return pthread_mutex_trylock(&a->mutex);
|
||||
@@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a)
|
||||
return (uatomic_read(&a->waiters) > 0);
|
||||
}
|
||||
|
||||
-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12
|
||||
-#pragma GCC diagnostic pop
|
||||
-#endif
|
||||
-
|
||||
#define lock_cleanup_pop(a) pthread_cleanup_pop(1)
|
||||
|
||||
void cleanup_lock (void * data);
|
||||
diff --git a/multipathd/Makefile b/multipathd/Makefile
|
||||
index cdba3db1..0ba6ecb7 100644
|
||||
--- a/multipathd/Makefile
|
||||
+++ b/multipathd/Makefile
|
||||
@@ -5,8 +5,6 @@ CLI := multipathc
|
||||
MANPAGES := multipathd.8
|
||||
|
||||
CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \
|
||||
- $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \
|
||||
- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \
|
||||
-DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS)
|
||||
|
||||
#
|
52
0039-multipath-tools-fix-spelling.patch
Normal file
52
0039-multipath-tools-fix-spelling.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Date: Fri, 15 Sep 2023 22:22:06 +0200
|
||||
Subject: [PATCH] multipath-tools: fix spelling
|
||||
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
README.md | 4 ++--
|
||||
multipath/multipath.conf.5.in | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/README.md b/README.md
|
||||
index 679e55bf..524c9fb1 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -92,7 +92,7 @@ The following variables can be passed to the `make` command line:
|
||||
The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on
|
||||
systems that have `/lib64`, and `lib` otherwise.
|
||||
* `configfile="/some/path`": The path to the main configuration file.
|
||||
- The defalt is `$(etc_prefix)/etc/multipath.conf`.
|
||||
+ The default is `$(etc_prefix)/etc/multipath.conf`.
|
||||
* `configdir="/some/path"` : directory to search for additional configuration files.
|
||||
This used to be the run-time option `config_dir` in earlier versions.
|
||||
The default is `$(etc_prefix)/etc/multipath/conf.d`.
|
||||
@@ -141,7 +141,7 @@ The following variables can be passed to the `make` command line:
|
||||
found on the build system, and `/lib` otherwise.
|
||||
|
||||
The options `configdir`, `plugindir`, `configfile`, and `statedir` above can
|
||||
-be used for setting indvidual paths where the `prefix` variables don't provide
|
||||
+be used for setting individual paths where the `prefix` variables don't provide
|
||||
sufficient control. See `Makefile.inc` for even more fine-grained control.
|
||||
|
||||
[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`.
|
||||
diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in
|
||||
index d320a88f..226d0019 100644
|
||||
--- a/multipath/multipath.conf.5.in
|
||||
+++ b/multipath/multipath.conf.5.in
|
||||
@@ -36,7 +36,7 @@ Files ending in \fI.conf\fR in this directory are read
|
||||
in alphabetical order, after reading \fI@CONFIGFILE@\fR.
|
||||
They use the same syntax as \fI@CONFIGFILE@\fR itself,
|
||||
and support all sections and keywords. If a keyword occurs in the same section
|
||||
-in multiple files, the last occurence will take precedence over all others.
|
||||
+in multiple files, the last occurrence will take precedence over all others.
|
||||
.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
300
0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch
Normal file
300
0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch
Normal file
@ -0,0 +1,300 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muneendra <muneendra.kumar@broadcom.com>
|
||||
Date: Wed, 20 Sep 2023 20:41:15 -0700
|
||||
Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for
|
||||
FC-NVMe
|
||||
|
||||
This patch adds the support to handle FPIN-Li for FC-NVMe.
|
||||
On receiving the FPIN-Li events this patch moves the devices paths
|
||||
which are affected due to link integrity to marginal path groups.
|
||||
The paths which are set to marginal path group will be unset
|
||||
on receiving the RSCN events
|
||||
|
||||
(mwilck: minor compile fix for 32-bit architectures)
|
||||
|
||||
Signed-off-by: Muneendra <muneendra.kumar@broadcom.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++----------
|
||||
1 file changed, 151 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c
|
||||
index aa0f63c9..be087ca0 100644
|
||||
--- a/multipathd/fpin_handlers.c
|
||||
+++ b/multipathd/fpin_handlers.c
|
||||
@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p)
|
||||
|
||||
|
||||
/*set/unset the path state to marginal*/
|
||||
-static int fpin_set_pathstate(struct path *pp, bool set)
|
||||
+static void fpin_set_pathstate(struct path *pp, bool set)
|
||||
{
|
||||
const char *action = set ? "set" : "unset";
|
||||
|
||||
- if (!pp || !pp->mpp || !pp->mpp->alias)
|
||||
- return -1;
|
||||
-
|
||||
- condlog(3, "\n%s: %s marginal path %s (fpin)",
|
||||
- action, pp->mpp->alias, pp->dev_t);
|
||||
+ condlog(3, "%s: %s marginal path %s (fpin)",
|
||||
+ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t);
|
||||
pp->marginal = set;
|
||||
- pp->mpp->fpin_must_reload = true;
|
||||
- return 0;
|
||||
+ if (pp->mpp)
|
||||
+ pp->mpp->fpin_must_reload = true;
|
||||
}
|
||||
|
||||
/* This will unset marginal state of a device*/
|
||||
@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs)
|
||||
pp = find_path_by_dev(vecs->pathvec, devname);
|
||||
if (!pp)
|
||||
pp = find_path_by_devt(vecs->pathvec, devname);
|
||||
-
|
||||
- fpin_set_pathstate(pp, false);
|
||||
+ if (pp)
|
||||
+ fpin_set_pathstate(pp, false);
|
||||
}
|
||||
|
||||
/*This will set the marginal state of a device*/
|
||||
-static int fpin_path_setmarginal(struct path *pp)
|
||||
+static void fpin_path_setmarginal(struct path *pp)
|
||||
{
|
||||
- return fpin_set_pathstate(pp, true);
|
||||
+ fpin_set_pathstate(pp, true);
|
||||
}
|
||||
|
||||
/* Unsets all the devices in the list from marginal state */
|
||||
@@ -183,8 +180,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev)
|
||||
udev_device_get_syspath(rport_dev));
|
||||
}
|
||||
|
||||
-/*Add the marginal devices info into the list*/
|
||||
-static void
|
||||
+/*Add the marginal devices info into the list and return 0 on success*/
|
||||
+static int
|
||||
fpin_add_marginal_dev_info(uint32_t host_num, char *devname)
|
||||
{
|
||||
struct marginal_dev_list *newdev = NULL;
|
||||
@@ -199,65 +196,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname)
|
||||
list_add_tail(&(newdev->node),
|
||||
&fpin_li_marginal_dev_list_head);
|
||||
pthread_mutex_unlock(&fpin_li_marginal_dev_mutex);
|
||||
- }
|
||||
+ } else
|
||||
+ return -ENOMEM;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function goes through the vecs->pathvec, and for
|
||||
- * each path, check that the host number,
|
||||
- * the target WWPN associated with the path matches
|
||||
- * with the els wwpn and sets the path and port state to
|
||||
+ * This function compares Transport Address Controller Port pn,
|
||||
+ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn
|
||||
+ * and return 1 (match) or 0 (no match) or a negative error code
|
||||
+ */
|
||||
+static int extract_nvme_addresses_chk_path_pwwn(const char *address,
|
||||
+ uint64_t els_wwpn, uint64_t els_attached_wwpn)
|
||||
+
|
||||
+{
|
||||
+ uint64_t traddr;
|
||||
+ uint64_t host_traddr;
|
||||
+
|
||||
+ /*
|
||||
+ * Find the position of "traddr=" and "host_traddr="
|
||||
+ * and the address will be in the below format
|
||||
+ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400,
|
||||
+ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400"
|
||||
+ */
|
||||
+ const char *traddr_start = strstr(address, "traddr=");
|
||||
+ const char *host_traddr_start = strstr(address, "host_traddr=");
|
||||
+
|
||||
+ if (!traddr_start || !host_traddr_start)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Extract traddr pn */
|
||||
+ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Extract host_traddr pn*/
|
||||
+ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64,
|
||||
+ &host_traddr) != 1)
|
||||
+ return -EINVAL;
|
||||
+ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%"
|
||||
+ PRIx64" els_host_traddr 0x%" PRIx64,
|
||||
+ traddr, host_traddr,
|
||||
+ els_wwpn, els_attached_wwpn);
|
||||
+ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn))
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function check that the Transport Address Controller Port pn,
|
||||
+ * Host Transport Address Controller Port pn associated with the path matches
|
||||
+ * with the els wwpn ,attached_wwpn and sets the path state to
|
||||
* Marginal
|
||||
*/
|
||||
-static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs,
|
||||
+static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp,
|
||||
+ uint64_t els_wwpn, uint64_t attached_wwpn)
|
||||
+{
|
||||
+ struct udev_device *ctl = NULL;
|
||||
+ const char *address = NULL;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL);
|
||||
+ if (ctl == NULL) {
|
||||
+ condlog(2, "%s: No parent device for ", pp->dev);
|
||||
+ return;
|
||||
+ }
|
||||
+ address = udev_device_get_sysattr_value(ctl, "address");
|
||||
+ if (!address) {
|
||||
+ condlog(2, "%s: unable to get the address ", pp->dev);
|
||||
+ return;
|
||||
+ }
|
||||
+ condlog(4, "\n address %s: dev :%s\n", address, pp->dev);
|
||||
+ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn);
|
||||
+ if (ret <= 0)
|
||||
+ return;
|
||||
+ ret = fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||
+ if (ret < 0)
|
||||
+ return;
|
||||
+ fpin_path_setmarginal(pp);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function check the host number, the target WWPN
|
||||
+ * associated with the path matches with the els wwpn and
|
||||
+ * sets the path and port state to Marginal
|
||||
+ */
|
||||
+static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp,
|
||||
uint64_t els_wwpn)
|
||||
{
|
||||
- struct path *pp;
|
||||
- struct multipath *mpp;
|
||||
- int i, k;
|
||||
char rport_id[42];
|
||||
const char *value = NULL;
|
||||
struct udev_device *rport_dev = NULL;
|
||||
uint64_t wwpn;
|
||||
int ret = 0;
|
||||
+ sprintf(rport_id, "rport-%d:%d-%d",
|
||||
+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
|
||||
+ rport_dev = udev_device_new_from_subsystem_sysname(udev,
|
||||
+ "fc_remote_ports", rport_id);
|
||||
+ if (!rport_dev) {
|
||||
+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev,
|
||||
+ rport_id);
|
||||
+ return;
|
||||
+ }
|
||||
+ pthread_cleanup_push(_udev_device_unref, rport_dev);
|
||||
+ value = udev_device_get_sysattr_value(rport_dev, "port_name");
|
||||
+ if (!value)
|
||||
+ goto unref;
|
||||
+
|
||||
+ wwpn = strtol(value, NULL, 16);
|
||||
+ /*
|
||||
+ * If the port wwpn matches sets the path and port state
|
||||
+ * to marginal
|
||||
+ */
|
||||
+ if (wwpn == els_wwpn) {
|
||||
+ ret = fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||
+ if (ret < 0)
|
||||
+ goto unref;
|
||||
+ fpin_path_setmarginal(pp);
|
||||
+ fpin_set_rport_marginal(rport_dev);
|
||||
+ }
|
||||
+unref:
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ return;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function goes through the vecs->pathvec, and for
|
||||
+ * each path, it checks and sets the path state to marginal
|
||||
+ * if the path's associated port wwpn ,hostnum matches with
|
||||
+ * els wwnpn ,attached_wwpn
|
||||
+ */
|
||||
+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs,
|
||||
+ uint64_t els_wwpn, uint64_t attached_wwpn)
|
||||
+{
|
||||
+ struct path *pp;
|
||||
+ struct multipath *mpp;
|
||||
+ int i, k;
|
||||
+ int ret = 0;
|
||||
|
||||
pthread_cleanup_push(cleanup_lock, &vecs->lock);
|
||||
lock(&vecs->lock);
|
||||
pthread_testcancel();
|
||||
|
||||
vector_foreach_slot(vecs->pathvec, pp, k) {
|
||||
- /* Checks the host number and also for the SCSI FCP */
|
||||
- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no)
|
||||
+ if (!pp->mpp)
|
||||
continue;
|
||||
- sprintf(rport_id, "rport-%d:%d-%d",
|
||||
- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
|
||||
- rport_dev = udev_device_new_from_subsystem_sysname(udev,
|
||||
- "fc_remote_ports", rport_id);
|
||||
- if (!rport_dev) {
|
||||
- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev,
|
||||
- rport_id);
|
||||
- continue;
|
||||
- }
|
||||
- pthread_cleanup_push(_udev_device_unref, rport_dev);
|
||||
- value = udev_device_get_sysattr_value(rport_dev, "port_name");
|
||||
- if (!value)
|
||||
- goto unref;
|
||||
-
|
||||
- if (value)
|
||||
- wwpn = strtol(value, NULL, 16);
|
||||
- /*
|
||||
- * If the port wwpn matches sets the path and port state
|
||||
- * to marginal
|
||||
- */
|
||||
- if (wwpn == els_wwpn) {
|
||||
- ret = fpin_path_setmarginal(pp);
|
||||
- if (ret < 0)
|
||||
- goto unref;
|
||||
- fpin_set_rport_marginal(rport_dev);
|
||||
- fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||
+ /*checks if the bus type is nvme and the protocol is FC-NVMe*/
|
||||
+ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) {
|
||||
+ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn);
|
||||
+ } else if ((pp->bus == SYSFS_BUS_SCSI) &&
|
||||
+ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) &&
|
||||
+ (host_num == pp->sg_id.host_no)) {
|
||||
+ /* Checks the host number and also for the SCSI FCP */
|
||||
+ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn);
|
||||
}
|
||||
-unref:
|
||||
- pthread_cleanup_pop(1);
|
||||
}
|
||||
/* walk backwards because reload_and_sync_map() can remove mpp */
|
||||
vector_foreach_slot_backwards(vecs->mpvec, mpp, i) {
|
||||
@@ -286,14 +378,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv,
|
||||
struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;
|
||||
int count = 0;
|
||||
int ret = 0;
|
||||
+ uint64_t attached_wwpn;
|
||||
|
||||
/* Update the wwn to list */
|
||||
wwn_count = be32_to_cpu(li_desc->pname_count);
|
||||
- condlog(4, "Got wwn count as %d\n", wwn_count);
|
||||
+ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn);
|
||||
+ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64
|
||||
+ " attached_wwpn 0x%" PRIx64 "\n",
|
||||
+ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn);
|
||||
|
||||
for (iter = 0; iter < wwn_count; iter++) {
|
||||
wwpn = be64_to_cpu(li_desc->pname_list[iter]);
|
||||
- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn);
|
||||
+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn);
|
||||
if (ret < 0)
|
||||
condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn);
|
||||
|
@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 2e25d2ea..540e1dfc 100644
|
||||
index 04bfa56e..62d3d5cc 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -34,9 +34,9 @@ endif
|
||||
@ -27,9 +27,9 @@ index 2e25d2ea..540e1dfc 100644
|
||||
# Prefix for non-essential libraries (libdmmp)
|
||||
-usr_prefix := $(prefix)
|
||||
+usr_prefix := $(prefix)/usr
|
||||
# Prefix for configfuration files (multipath.conf)
|
||||
etc_prefix := $(prefix)
|
||||
# Where to install systemd-related files. systemd is usually installed under /usr
|
||||
# Note: some systemd installations use separate "prefix" and "rootprefix".
|
||||
# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix)
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index 1969dee0..d2b28233 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
@ -43,10 +43,10 @@ index 1969dee0..d2b28233 100644
|
||||
|
||||
LABEL="kpartx_end"
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 73db991a..b3c2cc81 100644
|
||||
index 68cb5ce7..f70e64ec 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -24,7 +24,7 @@ install:
|
||||
@@ -26,7 +26,7 @@ install:
|
||||
$(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
@ -55,7 +55,7 @@ index 73db991a..b3c2cc81 100644
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir)
|
||||
@@ -44,7 +44,7 @@ uninstall:
|
||||
@@ -46,7 +46,7 @@ uninstall:
|
||||
$(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
$(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf
|
||||
$(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf
|
||||
@ -63,4 +63,4 @@ index 73db991a..b3c2cc81 100644
|
||||
+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5
|
||||
|
||||
$(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf
|
@ -13,26 +13,25 @@ it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 6 ++----
|
||||
multipath/multipath.conf.5 | 11 ++++++-----
|
||||
tests/blacklist.c | 7 ++-----
|
||||
3 files changed, 10 insertions(+), 14 deletions(-)
|
||||
libmultipath/blacklist.c | 5 ++---
|
||||
multipath/multipath.conf.5.in | 11 ++++++-----
|
||||
tests/blacklist.c | 7 ++-----
|
||||
3 files changed, 10 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index 8d15d2ea..eff690fd 100644
|
||||
index 75100b20..0b212078 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf)
|
||||
if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
|
||||
@@ -230,8 +230,6 @@ setup_default_blist (struct config * conf)
|
||||
ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
}
|
||||
- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -409,7 +406,8 @@ filter_property(const struct config *conf, struct udev_device *udev,
|
||||
@@ -438,7 +436,8 @@ filter_property(const struct config *conf, struct udev_device *udev,
|
||||
*uid_attribute != '\0';
|
||||
bool uid_attr_seen = false;
|
||||
|
||||
@ -42,11 +41,11 @@ index 8d15d2ea..eff690fd 100644
|
||||
udev_list_entry_foreach(list_entry,
|
||||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index b4dccd1b..284282c6 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1367,9 +1367,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in
|
||||
index 226d0019..bae4168f 100644
|
||||
--- a/multipath/multipath.conf.5.in
|
||||
+++ b/multipath/multipath.conf.5.in
|
||||
@@ -1402,9 +1402,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
Regular expression for an udev property. All
|
||||
devices that have matching udev properties will be excluded/included.
|
||||
The handling of the \fIproperty\fR keyword is special,
|
||||
@ -62,7 +61,7 @@ index b4dccd1b..284282c6 100644
|
||||
.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1380,10 +1385,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
@@ -1415,10 +1420,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR)
|
||||
set. Previously, it was applied to every device, possibly causing devices to be
|
||||
blacklisted because of temporary I/O error conditions.
|
||||
@ -74,10 +73,10 @@ index b4dccd1b..284282c6 100644
|
||||
.TP
|
||||
.B protocol
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 882aa3a1..6a22b660 100644
|
||||
index ba8dfd07..693db3fa 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -375,9 +375,8 @@ static void test_property_missing(void **state)
|
||||
@@ -384,9 +384,8 @@ static void test_property_missing(void **state)
|
||||
{
|
||||
static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } };
|
||||
conf.blist_property = blist_property_wwn;
|
||||
@ -88,7 +87,7 @@ index 882aa3a1..6a22b660 100644
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"),
|
||||
MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, ""),
|
||||
@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state)
|
||||
@@ -478,9 +477,7 @@ static void test_filter_path_missing1(void **state)
|
||||
conf.blist_device = blist_device_foo_bar;
|
||||
conf.blist_protocol = blist_protocol_fcp;
|
||||
conf.blist_wwid = blist_wwid_xyzzy;
|
@ -14,17 +14,18 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 13 +++++++++++++
|
||||
libmultipath/config.h | 1 +
|
||||
multipath/main.c | 6 ++++++
|
||||
multipath/multipath.rules.in | 1 +
|
||||
multipathd/multipathd.8 | 2 ++
|
||||
multipathd/multipathd.8.in | 2 ++
|
||||
multipathd/multipathd.service | 1 +
|
||||
multipathd/multipathd.socket | 1 +
|
||||
6 files changed, 19 insertions(+)
|
||||
7 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 5c5c0726..183b319d 100644
|
||||
index b7dbc6f5..3a374b3d 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -966,6 +966,19 @@ int _init_config (const char *file, struct config *conf)
|
||||
@@ -958,6 +958,19 @@ int _init_config (const char *file, struct config *conf)
|
||||
}
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
validate_pctable(conf->overrides, 0, file);
|
||||
@ -45,7 +46,7 @@ index 5c5c0726..183b319d 100644
|
||||
|
||||
conf->processed_main_config = 1;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 87947469..0dc89c16 100644
|
||||
index 8c22ce75..92f3a0df 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -10,6 +10,7 @@
|
||||
@ -56,6 +57,35 @@ index 87947469..0dc89c16 100644
|
||||
|
||||
enum devtypes {
|
||||
DEV_NONE,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 9e1c5052..46944589 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -829,11 +829,14 @@ main (int argc, char *argv[])
|
||||
struct config *conf;
|
||||
int retries = -1;
|
||||
bool enable_foreign = false;
|
||||
+ bool have_config;
|
||||
+ struct stat buf;
|
||||
|
||||
libmultipath_init();
|
||||
if (atexit(dm_lib_exit) || atexit(libmultipath_exit))
|
||||
condlog(1, "failed to register cleanup handler for libmultipath: %m");
|
||||
logsink = LOGSINK_STDERR_WITH_TIME;
|
||||
+ have_config = (stat(DEFAULT_CONFIGFILE, &buf) == 0);
|
||||
if (init_config(DEFAULT_CONFIGFILE))
|
||||
exit(RTVL_FAIL);
|
||||
if (atexit(uninit_config))
|
||||
@@ -1081,6 +1084,9 @@ main (int argc, char *argv[])
|
||||
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||
condlog(3, "restart multipath configuration process");
|
||||
|
||||
+ if (!have_config && r == RTVL_OK &&
|
||||
+ (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG))
|
||||
+ r = RTVL_FAIL;
|
||||
out:
|
||||
put_multipath_config(conf);
|
||||
if (dev)
|
||||
diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in
|
||||
index 6f123760..70b69a06 100644
|
||||
--- a/multipath/multipath.rules.in
|
||||
@ -68,11 +98,11 @@ index 6f123760..70b69a06 100644
|
||||
|
||||
ENV{DEVTYPE}!="partition", GOTO="test_dev"
|
||||
IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH"
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||
index bdf102eb..a16a0bd5 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8
|
||||
@@ -48,6 +48,8 @@ map regains its maximum performance and redundancy.
|
||||
diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in
|
||||
index e98c27fd..fd2061e5 100644
|
||||
--- a/multipathd/multipathd.8.in
|
||||
+++ b/multipathd/multipathd.8.in
|
||||
@@ -49,6 +49,8 @@ map regains its maximum performance and redundancy.
|
||||
With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that
|
||||
sends commands to a running instance of the multipathd daemon (see
|
||||
\fBCOMMANDS\fR below).
|
@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 17 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 540e1dfc..748911e2 100644
|
||||
index 62d3d5cc..72fd8d57 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -78,11 +78,23 @@ ORIG_LDFLAGS := $(LDFLAGS)
|
||||
@@ -91,11 +91,23 @@ ORIG_LDFLAGS := $(LDFLAGS)
|
||||
SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD))
|
||||
SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon))
|
||||
|
||||
@ -38,13 +38,13 @@ index 540e1dfc..748911e2 100644
|
||||
+WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS)
|
||||
-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \
|
||||
-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \
|
||||
+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes
|
||||
+CPPFLAGS := $(CPPFLAGS) \
|
||||
+CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \
|
||||
-DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \
|
||||
-DRUNTIME_DIR=\"$(runtimedir)\" \
|
||||
-DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP
|
||||
@@ -90,7 +102,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe
|
||||
-DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \
|
||||
-DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \
|
||||
@@ -104,7 +116,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe
|
||||
BIN_CFLAGS := -fPIE -DPIE
|
||||
LIB_CFLAGS := -fPIC
|
||||
SHARED_FLAGS := -shared
|
@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 183b319d..01f36a4f 100644
|
||||
index 3a374b3d..4544f484 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -968,6 +968,8 @@ int _init_config (const char *file, struct config *conf)
|
||||
@@ -960,6 +960,8 @@ int _init_config (const char *file, struct config *conf)
|
||||
validate_pctable(conf->overrides, 0, file);
|
||||
} else {
|
||||
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
@ -34,10 +34,10 @@ index 183b319d..01f36a4f 100644
|
||||
conf->blist_devnode = vector_alloc();
|
||||
if (!conf->blist_devnode) {
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index b3c2cc81..413294ef 100644
|
||||
index f70e64ec..9942d1a9 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -22,6 +22,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
@@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
install:
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
@ -45,7 +45,7 @@ index b3c2cc81..413294ef 100644
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules
|
||||
@@ -31,6 +32,7 @@ install:
|
||||
@@ -33,6 +34,7 @@ install:
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8
|
||||
@ -53,7 +53,7 @@ index b3c2cc81..413294ef 100644
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5
|
||||
ifneq ($(SCSI_DH_MODULES_PRELOAD),)
|
||||
@@ -41,11 +43,13 @@ endif
|
||||
@@ -43,11 +45,13 @@ endif
|
||||
|
||||
uninstall:
|
||||
$(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
@ -65,8 +65,8 @@ index b3c2cc81..413294ef 100644
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8
|
||||
+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8
|
||||
$(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5
|
||||
$(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf
|
||||
|
||||
clean: dep_clean
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
new file mode 100644
|
||||
index 00000000..319664b1
|
@ -15,12 +15,12 @@ multipathd.service
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 54 +++++++++++++++++++++++++++++++++--
|
||||
multipath/multipath.8 | 7 ++++-
|
||||
multipath/multipath.8.in | 7 ++++-
|
||||
multipathd/multipathd.service | 1 +
|
||||
3 files changed, 59 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 90f940f1..3549740a 100644
|
||||
index 46944589..47f89a0a 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -120,7 +120,7 @@ usage (char * progname)
|
||||
@ -41,7 +41,7 @@ index 90f940f1..3549740a 100644
|
||||
" -c check if a device should be a path in a multipath device\n"
|
||||
" -C check if a multipath device has usable paths\n"
|
||||
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||
@@ -447,6 +449,50 @@ static void cleanup_vecs(void)
|
||||
@@ -448,6 +450,50 @@ static void cleanup_vecs(void)
|
||||
free_pathvec(vecs.pathvec, FREE_PATHS);
|
||||
}
|
||||
|
||||
@ -92,16 +92,16 @@ index 90f940f1..3549740a 100644
|
||||
static int
|
||||
configure (struct config *conf, enum mpath_cmds cmd,
|
||||
enum devtypes dev_type, char *devpath)
|
||||
@@ -842,7 +888,7 @@ main (int argc, char *argv[])
|
||||
conf->force_sync = 1;
|
||||
if (atexit(cleanup_vecs))
|
||||
@@ -848,7 +894,7 @@ main (int argc, char *argv[])
|
||||
condlog(1, "failed to register cleanup handler for vecs: %m");
|
||||
if (atexit(cleanup_bindings))
|
||||
condlog(1, "failed to register cleanup handler for bindings: %m");
|
||||
- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 'v':
|
||||
if (!isdigit(optarg[0])) {
|
||||
@@ -913,6 +959,10 @@ main (int argc, char *argv[])
|
||||
@@ -919,6 +965,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
@ -112,11 +112,11 @@ index 90f940f1..3549740a 100644
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 88149d53..072a03ee 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
||||
diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in
|
||||
index 348eb220..82a7e68e 100644
|
||||
--- a/multipath/multipath.8.in
|
||||
+++ b/multipath/multipath.8.in
|
||||
@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig.
|
||||
.B multipath
|
||||
.RB [\| \-v\ \c
|
||||
.IR level \|]
|
||||
@ -125,7 +125,7 @@ index 88149d53..072a03ee 100644
|
||||
.
|
||||
.LP
|
||||
.B multipath
|
||||
@@ -145,6 +145,11 @@ device mapper, path checkers ...).
|
||||
@@ -146,6 +146,11 @@ device mapper, path checkers ...).
|
||||
Add the WWID for the specified device to the WWIDs file.
|
||||
.
|
||||
.TP
|
@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index a5e9ea0c..514fd880 100644
|
||||
index d01f9712..ee2e13a9 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -23,7 +23,7 @@
|
@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c
|
||||
index b5c7873d..e139360c 100644
|
||||
index e9827dca..80a32aa3 100644
|
||||
--- a/libmultipath/prioritizers/ana.c
|
||||
+++ b/libmultipath/prioritizers/ana.c
|
||||
@@ -24,6 +24,7 @@
|
||||
@ -68,7 +68,7 @@ index b5c7873d..e139360c 100644
|
||||
static int get_ana_info(struct path * pp)
|
||||
{
|
||||
int rc;
|
||||
@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args,
|
||||
@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args)
|
||||
|
||||
if (pp->fd < 0)
|
||||
rc = -ANA_ERR_NO_INFORMATION;
|
@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
2 files changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 6865cd92..72825829 100644
|
||||
index 84ce5fe7..104fdd5a 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 748911e2..c07bcb0c 100644
|
||||
index 72fd8d57..a49e9f5a 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -16,7 +16,7 @@ READLINE :=
|
@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index c07bcb0c..e59313c6 100644
|
||||
index a49e9f5a..51b55196 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -12,7 +12,7 @@
|
186
0053-RH-Add-mpathcleanup.patch
Normal file
186
0053-RH-Add-mpathcleanup.patch
Normal file
@ -0,0 +1,186 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 7 Jul 2023 15:25:59 -0500
|
||||
Subject: [PATCH] RH: Add mpathcleanup
|
||||
|
||||
mpathcleanup is a program that will remove a multipath device as well as
|
||||
all of the scsi path devices that make it up.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/Makefile | 2 +
|
||||
multipath/mpathcleanup | 145 +++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 147 insertions(+)
|
||||
create mode 100755 multipath/mpathcleanup
|
||||
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 9942d1a9..d281b501 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -25,6 +25,7 @@ install:
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
$(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
|
||||
+ $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/
|
||||
$(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
$(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules
|
||||
@@ -46,6 +47,7 @@ endif
|
||||
uninstall:
|
||||
$(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
$(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf
|
||||
+ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup
|
||||
$(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
$(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf
|
||||
$(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf
|
||||
diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup
|
||||
new file mode 100755
|
||||
index 00000000..6fd921e4
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathcleanup
|
||||
@@ -0,0 +1,145 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2023 Red Hat, Inc. All rights reserved.
|
||||
+#
|
||||
+# This file is part of the device-mapper-multipath package.
|
||||
+#
|
||||
+# This copyrighted material is made available to anyone wishing to use,
|
||||
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||
+# of the GNU General Public License v.2.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software Foundation,
|
||||
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+
|
||||
+unset PROGRAM FLUSH DEVICE DEVNAME MAJOR MINOR PATHDEVS PATHDEV HAVE_MULTIPATHD QUEUEING
|
||||
+
|
||||
+function usage
|
||||
+{
|
||||
+ echo "usage: $PROGRAM [-h] [--flush] <device>"
|
||||
+ echo ""
|
||||
+ echo "remove a multipath device and its scsi path devices"
|
||||
+ echo ""
|
||||
+ echo "options:"
|
||||
+ echo " -h, --help show this help message and exit"
|
||||
+ echo " --flush disable queuing on the multipath device and"
|
||||
+ echo " flush the path devices before removing"
|
||||
+}
|
||||
+
|
||||
+function parse_args
|
||||
+{
|
||||
+ while [ -n "$1" ]; do
|
||||
+ case $1 in
|
||||
+ --flush)
|
||||
+ FLUSH=1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --help | -h)
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+ *)
|
||||
+ if [ -n "$DEVICE" ]; then
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ DEVICE=$1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function validate_device
|
||||
+{
|
||||
+ if [ -z "$DEVICE" ]; then
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [[ "$DEVICE" =~ ^[[:digit:]]+:[[:digit:]]+$ ]]; then
|
||||
+ MAJOR=${DEVICE%%:*}
|
||||
+ MINOR=${DEVICE##*:}
|
||||
+ DEVNAME=`dmsetup ls --target multipath | grep "($MAJOR, $MINOR)$" | awk '{print $1}'`
|
||||
+ else
|
||||
+ DEVNAME=`dmsetup ls --target multipath | awk '{print $1}' | grep "^$DEVICE$"`
|
||||
+ fi
|
||||
+ if [ -z "$DEVNAME" ]; then
|
||||
+ DEVNAME=`multipath -v 1 -l $DEVICE 2>/dev/null`
|
||||
+ if [ -z "$DEVNAME" ]; then
|
||||
+ echo "$DEVICE is not a multipath device"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ # verify that this is not a native nvme multipath device
|
||||
+ dmsetup ls --target multipath | awk '{print $1}' | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 1; then
|
||||
+ echo "$DEVICE is not a device-mapper multipath device"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ -z "$MINOR" ]; then
|
||||
+ MINOR=`dmsetup info -c --noheadings -o minor $DEVNAME`
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function get_paths
|
||||
+{
|
||||
+ PATHDEVS=`ls /sys/block/dm-$MINOR/slaves`
|
||||
+ for PATHDEV in $PATHDEVS; do
|
||||
+ if [[ ! "$PATHDEV" =~ ^sd[a-z]+$ ]]; then
|
||||
+ echo "$PATHDEV is not a scsi device. $PROGRAM only works with scsi devices"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function remove_devs
|
||||
+{
|
||||
+ pidof multipathd > /dev/null
|
||||
+ HAVE_MULTIPATHD=$?
|
||||
+ multipath -v2 -l "$DEVNAME" | grep features | grep -q queue_if_no_path
|
||||
+ QUEUEING=$?
|
||||
+ if [ -n "$FLUSH" ] && [ "$QUEUEING" -eq 0 ]; then
|
||||
+ if test $HAVE_MULTIPATHD -eq 0; then
|
||||
+ multipathd disablequeueing map "$DEVNAME" > /dev/null
|
||||
+ else
|
||||
+ dmsetup message "$DEVNAME" 0 fail_if_no_path
|
||||
+ fi
|
||||
+ sleep 1
|
||||
+ fi
|
||||
+ if test $HAVE_MULTIPATHD -eq 0; then
|
||||
+ multipath -f "$DEVNAME"
|
||||
+ else
|
||||
+ multipathd -Df "$DEVNAME"
|
||||
+ fi
|
||||
+ if test $? -eq 1; then
|
||||
+ echo "$DEVICE cannot be removed"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ for PATHDEV in $PATHDEVS; do
|
||||
+ if [ -n "$FLUSH" ]; then
|
||||
+ blockdev --flushbufs /dev/"$PATHDEV"
|
||||
+ fi
|
||||
+ echo 1 > /sys/block/"$PATHDEV"/device/delete
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function verify_removal
|
||||
+{
|
||||
+ multipath -v 1 -d $DEVNAME | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 0; then
|
||||
+ echo "$DEVICE removed but path devices still exist"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ multipath -v 1 -l $DEVNAME | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 0; then
|
||||
+ echo "$DEVICE removal succeeded, but device still exists"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+PROGRAM="$0"
|
||||
+parse_args "$@"
|
||||
+validate_device
|
||||
+get_paths
|
||||
+remove_devs
|
||||
+verify_removal
|
@ -1,27 +1,68 @@
|
||||
Name: device-mapper-multipath
|
||||
Version: 0.9.5
|
||||
Release: 2%{?dist}
|
||||
Version: 0.9.6
|
||||
Release: 1%{?dist}
|
||||
Summary: Tools to manage multipath devices using device-mapper
|
||||
License: GPLv2
|
||||
URL: http://christophe.varoqui.free.fr/
|
||||
|
||||
# The source for this package was pulled from upstream's git repo. Use the
|
||||
# following command to generate the tarball
|
||||
# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.5.tar.gz -o multipath-tools-0.9.5.tgz
|
||||
Source0: multipath-tools-0.9.5.tgz
|
||||
# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.6.tar.gz -o multipath-tools-0.9.6.tgz
|
||||
Source0: multipath-tools-0.9.6.tgz
|
||||
Source1: multipath.conf
|
||||
Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch0003: 0003-RH-don-t-start-without-a-config-file.patch
|
||||
Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch
|
||||
Patch0005: 0005-RH-use-rpm-optflags-if-present.patch
|
||||
Patch0006: 0006-RH-add-mpathconf.patch
|
||||
Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch
|
||||
Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch
|
||||
Patch0012: 0012-RH-compile-with-libreadline-support.patch
|
||||
Patch0001: 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch
|
||||
Patch0002: 0002-libmultipath-add-alias_already_taken.patch
|
||||
Patch0003: 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch
|
||||
Patch0004: 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch
|
||||
Patch0005: 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch
|
||||
Patch0006: 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch
|
||||
Patch0007: 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch
|
||||
Patch0008: 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch
|
||||
Patch0009: 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch
|
||||
Patch0010: 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch
|
||||
Patch0011: 0011-libmultipath-add-global-variable-for-current-binding.patch
|
||||
Patch0012: 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch
|
||||
Patch0013: 0013-libmultipath-alias.c-move-bindings-related-code-up.patch
|
||||
Patch0014: 0014-libmultipath-update_bindings_file-take-filename-argu.patch
|
||||
Patch0015: 0015-libmultipath-update_bindings_file-use-a-single-write.patch
|
||||
Patch0016: 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch
|
||||
Patch0017: 0017-libmultipath-alias.c-factor-out-read_binding.patch
|
||||
Patch0018: 0018-libmultipath-keep-bindings-in-memory.patch
|
||||
Patch0019: 0019-multipath-tools-tests-fix-alias-tests.patch
|
||||
Patch0020: 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch
|
||||
Patch0021: 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch
|
||||
Patch0022: 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch
|
||||
Patch0023: 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch
|
||||
Patch0024: 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch
|
||||
Patch0025: 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch
|
||||
Patch0026: 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch
|
||||
Patch0027: 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch
|
||||
Patch0028: 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch
|
||||
Patch0029: 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch
|
||||
Patch0030: 0030-multipath-tools-add-compile-time-configuration-for-e.patch
|
||||
Patch0031: 0031-multipath-tools-man-pages-generate-with-correct-path.patch
|
||||
Patch0032: 0032-libdmmp-Makefile-fix-bug-in-install-section.patch
|
||||
Patch0033: 0033-multipath-tools-README.md-improve-documentation-for-.patch
|
||||
Patch0034: 0034-libmultipath-print-built-in-values-for-deprecated-op.patch
|
||||
Patch0035: 0035-multipath-add-a-missing-newline.patch
|
||||
Patch0036: 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch
|
||||
Patch0037: 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch
|
||||
Patch0038: 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch
|
||||
Patch0039: 0039-multipath-tools-fix-spelling.patch
|
||||
Patch0040: 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch
|
||||
Patch0041: 0041-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch0042: 0042-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch0043: 0043-RH-don-t-start-without-a-config-file.patch
|
||||
Patch0044: 0044-RH-Fix-nvme-function-missing-argument.patch
|
||||
Patch0045: 0045-RH-use-rpm-optflags-if-present.patch
|
||||
Patch0046: 0046-RH-add-mpathconf.patch
|
||||
Patch0047: 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch0048: 0048-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch0049: 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
Patch0050: 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch
|
||||
Patch0051: 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch
|
||||
Patch0052: 0052-RH-compile-with-libreadline-support.patch
|
||||
Patch0053: 0053-RH-Add-mpathcleanup.patch
|
||||
|
||||
# runtime
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
@ -108,7 +149,7 @@ This package contains the files needed to develop applications that use
|
||||
device-mapper-multipath's libdmmp C API library
|
||||
|
||||
%prep
|
||||
%autosetup -n multipath-tools-0.9.5 -p1
|
||||
%autosetup -n multipath-tools-0.9.6 -p1
|
||||
cp %{SOURCE1} .
|
||||
|
||||
%build
|
||||
@ -158,6 +199,7 @@ fi
|
||||
%{_sbindir}/multipathd
|
||||
%{_sbindir}/multipathc
|
||||
%{_sbindir}/mpathconf
|
||||
%{_sbindir}/mpathcleanup
|
||||
%{_sbindir}/mpathpersist
|
||||
%{_unitdir}/multipathd.service
|
||||
%{_unitdir}/multipathd.socket
|
||||
@ -230,6 +272,13 @@ fi
|
||||
%{_pkgconfdir}/libdmmp.pc
|
||||
|
||||
%changelog
|
||||
* Fri Sep 22 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.9.6-1
|
||||
- Update to the head of the upstream staging branch
|
||||
- Rename redhat patches
|
||||
* Previous patches 0001-0012 are now patches 0041-0052
|
||||
- Add 0053-RH-Add-mpathcleanup.patch
|
||||
* add mpathcleanup program
|
||||
|
||||
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.5-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
|
||||
|
||||
|
2
sources
2
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (multipath-tools-0.9.5.tgz) = 39c2e5d45542c6076eb3b17b9994629b4c1f74347aa43e0119001fa2d07d3a606fd5e617962906a11b313afb37a115bd8eec2ef24447e980e61b5900625f9146
|
||||
SHA512 (multipath-tools-0.9.6.tgz) = 17d2b46ead9df6826b3266035bc077a2f4d4bea01e2cd59e32d3917cda40c320f11bc8572da7ba66251e312b46d9be317737069193d481d202d49f9aa5fd71b9
|
||||
SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942
|
||||
|
Loading…
Reference in New Issue
Block a user