9abdc502cf
Rebased on top of additional commits staged for upstream * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 Add 0048-libmultipath-add-device-to-hwtable.c.patch Add 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch Add 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch Add 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch Add 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch Add 0055-libmultipath-remove-code-duplication-in-path-countin.patch Add 0056-libmultipath-count-pending-paths-as-active-on-loads.patch Add 0057-libmultipath-deal-with-flushing-no-maps.patch Add 0058-multipath-deal-with-delegation-failures-correctly.patch Add 0070-multipath-add-libmpathvalid-library.patch * adds the libmpathvalid.so library to determine if devices are valid multipath paths. Add 0071-libmultipath-add-uid-failback-for-dasd-devices.patch Add 0072-libmultipath-add-ignore_udev_uid-option.patch
370 lines
9.8 KiB
Diff
370 lines
9.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
|
Date: Wed, 13 May 2020 17:04:24 -0500
|
|
Subject: [PATCH] multipath: add libmpathvalid library
|
|
|
|
This library allows other programs to check if a path should be claimed
|
|
by multipath. It exports an init and exit function, that need to be
|
|
called before any other functions can be called, a pointer to a struct
|
|
config, that stores the configuration which is dealt with in the
|
|
init and exit functions, and two more functions.
|
|
|
|
mpath_get_mode() get the configured find_multipaths mode.
|
|
mpath_is_path() returns whether the device is claimed by multipath, and
|
|
optionally returns the wwid. This code works slightly different than
|
|
the multipath -c/u code for SMART mode. Instead of checking all the
|
|
existing paths to see if another has the same wwid, it expects the
|
|
caller to pass in an array of the already known path wwids, and checks
|
|
if the current path matches any of those.
|
|
|
|
The library also doesn't set up the device-mapper log fuctions. It
|
|
leaves this up to the caller.
|
|
|
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|
---
|
|
Makefile | 3 +-
|
|
Makefile.inc | 1 +
|
|
libmpathvalid/Makefile | 38 +++++++
|
|
libmpathvalid/libmpathvalid.version | 10 ++
|
|
libmpathvalid/mpath_valid.c | 168 ++++++++++++++++++++++++++++
|
|
libmpathvalid/mpath_valid.h | 57 ++++++++++
|
|
6 files changed, 276 insertions(+), 1 deletion(-)
|
|
create mode 100644 libmpathvalid/Makefile
|
|
create mode 100644 libmpathvalid/libmpathvalid.version
|
|
create mode 100644 libmpathvalid/mpath_valid.c
|
|
create mode 100644 libmpathvalid/mpath_valid.h
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 8bcaba66..f157a549 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -9,6 +9,7 @@ BUILDDIRS := \
|
|
libmultipath/checkers \
|
|
libmultipath/foreign \
|
|
libmpathpersist \
|
|
+ libmpathvalid \
|
|
multipath \
|
|
multipathd \
|
|
mpathpersist \
|
|
@@ -29,7 +30,7 @@ $(BUILDDIRS):
|
|
$(MAKE) -C $@
|
|
|
|
libmultipath libdmmp: libmpathcmd
|
|
-libmpathpersist multipath multipathd: libmultipath
|
|
+libmpathpersist libmpathvalid multipath multipathd: libmultipath
|
|
mpathpersist multipathd: libmpathpersist
|
|
|
|
libmultipath/checkers.install \
|
|
diff --git a/Makefile.inc b/Makefile.inc
|
|
index e2f5d0dc..936e5833 100644
|
|
--- a/Makefile.inc
|
|
+++ b/Makefile.inc
|
|
@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath
|
|
unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system
|
|
mpathpersistdir = $(TOPDIR)/libmpathpersist
|
|
mpathcmddir = $(TOPDIR)/libmpathcmd
|
|
+mpathvaliddir = $(TOPDIR)/libmpathvalid
|
|
thirdpartydir = $(TOPDIR)/third-party
|
|
libdmmpdir = $(TOPDIR)/libdmmp
|
|
nvmedir = $(TOPDIR)/libmultipath/nvme
|
|
diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile
|
|
new file mode 100644
|
|
index 00000000..70b97eca
|
|
--- /dev/null
|
|
+++ b/libmpathvalid/Makefile
|
|
@@ -0,0 +1,38 @@
|
|
+include ../Makefile.inc
|
|
+
|
|
+SONAME = 0
|
|
+DEVLIB = libmpathvalid.so
|
|
+LIBS = $(DEVLIB).$(SONAME)
|
|
+
|
|
+CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathcmddir)
|
|
+
|
|
+LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) \
|
|
+ -lmultipath -L$(mpathcmddir) -lmpathcmd -ludev
|
|
+
|
|
+OBJS = mpath_valid.o
|
|
+
|
|
+all: $(LIBS)
|
|
+
|
|
+$(LIBS): $(OBJS)
|
|
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -Wl,--version-script=libmpathvalid.version
|
|
+ $(LN) $(LIBS) $(DEVLIB)
|
|
+
|
|
+install: $(LIBS)
|
|
+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir)
|
|
+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
|
+ $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
|
|
+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir)
|
|
+ $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir)
|
|
+
|
|
+uninstall:
|
|
+ $(RM) $(DESTDIR)$(syslibdir)/$(LIBS)
|
|
+ $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB)
|
|
+ $(RM) $(DESTDIR)$(includedir)/mpath_valid.h
|
|
+
|
|
+clean: dep_clean
|
|
+ $(RM) core *.a *.o *.so *.so.* *.gz
|
|
+
|
|
+include $(wildcard $(OBJS:.o=.d))
|
|
+
|
|
+dep_clean:
|
|
+ $(RM) $(OBJS:.o=.d)
|
|
diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version
|
|
new file mode 100644
|
|
index 00000000..4d8a8ba4
|
|
--- /dev/null
|
|
+++ b/libmpathvalid/libmpathvalid.version
|
|
@@ -0,0 +1,10 @@
|
|
+MPATH_1.0 {
|
|
+ global:
|
|
+ mpathvalid_conf;
|
|
+ mpathvalid_init;
|
|
+ mpathvalid_exit;
|
|
+ mpathvalid_is_path;
|
|
+ mpathvalid_get_mode;
|
|
+ local:
|
|
+ *;
|
|
+};
|
|
diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c
|
|
new file mode 100644
|
|
index 00000000..6153e8b7
|
|
--- /dev/null
|
|
+++ b/libmpathvalid/mpath_valid.c
|
|
@@ -0,0 +1,168 @@
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <stdint.h>
|
|
+#include <libdevmapper.h>
|
|
+#include <libudev.h>
|
|
+#include <errno.h>
|
|
+
|
|
+#include "devmapper.h"
|
|
+#include "structs.h"
|
|
+#include "util.h"
|
|
+#include "config.h"
|
|
+#include "discovery.h"
|
|
+#include "wwids.h"
|
|
+#include "sysfs.h"
|
|
+#include "mpath_cmd.h"
|
|
+#include "valid.h"
|
|
+#include "mpath_valid.h"
|
|
+
|
|
+static struct config default_config = { .verbosity = -1 };
|
|
+struct config *mpathvalid_conf = &default_config;
|
|
+
|
|
+static unsigned int get_conf_mode(struct config *conf)
|
|
+{
|
|
+ if (conf->find_multipaths == FIND_MULTIPATHS_SMART)
|
|
+ return MPATH_SMART;
|
|
+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY)
|
|
+ return MPATH_GREEDY;
|
|
+ return MPATH_STRICT;
|
|
+}
|
|
+
|
|
+static void set_conf_mode(struct config *conf, unsigned int mode)
|
|
+{
|
|
+ if (mode == MPATH_SMART)
|
|
+ conf->find_multipaths = FIND_MULTIPATHS_SMART;
|
|
+ else if (mode == MPATH_GREEDY)
|
|
+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY;
|
|
+ else
|
|
+ conf->find_multipaths = FIND_MULTIPATHS_STRICT;
|
|
+}
|
|
+
|
|
+unsigned int mpathvalid_get_mode(void)
|
|
+{
|
|
+ int mode;
|
|
+ struct config *conf;
|
|
+
|
|
+ conf = get_multipath_config();
|
|
+ if (!conf)
|
|
+ return -1;
|
|
+ mode = get_conf_mode(conf);
|
|
+ put_multipath_config(conf);
|
|
+ return mode;
|
|
+}
|
|
+
|
|
+static int convert_result(int result) {
|
|
+ switch (result) {
|
|
+ case PATH_IS_ERROR:
|
|
+ return MPATH_IS_ERROR;
|
|
+ case PATH_IS_NOT_VALID:
|
|
+ return MPATH_IS_NOT_VALID;
|
|
+ case PATH_IS_VALID:
|
|
+ return MPATH_IS_VALID;
|
|
+ case PATH_IS_VALID_NO_CHECK:
|
|
+ return MPATH_IS_VALID_NO_CHECK;
|
|
+ case PATH_IS_MAYBE_VALID:
|
|
+ return MPATH_IS_MAYBE_VALID;
|
|
+ }
|
|
+ return MPATH_IS_ERROR;
|
|
+}
|
|
+
|
|
+int
|
|
+mpathvalid_init(int verbosity)
|
|
+{
|
|
+ unsigned int version[3];
|
|
+ struct config *conf;
|
|
+
|
|
+ default_config.verbosity = verbosity;
|
|
+ skip_libmp_dm_init();
|
|
+ conf = load_config(DEFAULT_CONFIGFILE);
|
|
+ if (!conf)
|
|
+ return -1;
|
|
+ conf->verbosity = verbosity;
|
|
+ if (dm_prereq(version))
|
|
+ goto fail;
|
|
+ memcpy(conf->version, version, sizeof(version));
|
|
+
|
|
+ mpathvalid_conf = conf;
|
|
+ return 0;
|
|
+fail:
|
|
+ free_config(conf);
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+int
|
|
+mpathvalid_exit(void)
|
|
+{
|
|
+ struct config *conf = mpathvalid_conf;
|
|
+
|
|
+ default_config.verbosity = -1;
|
|
+ if (mpathvalid_conf == &default_config)
|
|
+ return 0;
|
|
+ mpathvalid_conf = &default_config;
|
|
+ free_config(conf);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * name: name of path to check
|
|
+ * mode: mode to use for determination. MPATH_DEFAULT uses configured mode
|
|
+ * info: on success, contains the path wwid
|
|
+ * paths: array of the returned mpath_info from other claimed paths
|
|
+ * nr_paths: the size of the paths array
|
|
+ */
|
|
+int
|
|
+mpathvalid_is_path(const char *name, unsigned int mode, char **wwid,
|
|
+ const char **path_wwids, unsigned int nr_paths)
|
|
+{
|
|
+ struct config *conf;
|
|
+ int r = MPATH_IS_ERROR;
|
|
+ unsigned int i;
|
|
+ struct path *pp;
|
|
+
|
|
+ if (!name || mode >= MPATH_MAX_MODE)
|
|
+ return r;
|
|
+
|
|
+ if (nr_paths > 0 && !path_wwids)
|
|
+ return r;
|
|
+
|
|
+ pp = alloc_path();
|
|
+ if (!pp)
|
|
+ return r;
|
|
+
|
|
+ if (wwid) {
|
|
+ *wwid = (char *)malloc(WWID_SIZE);
|
|
+ if (!*wwid)
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ conf = get_multipath_config();
|
|
+ if (!conf || conf == &default_config)
|
|
+ goto out_wwid;
|
|
+ if (mode != MPATH_DEFAULT)
|
|
+ set_conf_mode(conf, mode);
|
|
+ r = convert_result(is_path_valid(name, conf, pp, true));
|
|
+ put_multipath_config(conf);
|
|
+
|
|
+ if (r == MPATH_IS_MAYBE_VALID) {
|
|
+ for (i = 0; i < nr_paths; i++) {
|
|
+ if (strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) {
|
|
+ r = MPATH_IS_VALID;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+out_wwid:
|
|
+ if (wwid) {
|
|
+ if (r == MPATH_IS_VALID || r == MPATH_IS_VALID_NO_CHECK ||
|
|
+ r == MPATH_IS_MAYBE_VALID)
|
|
+ strlcpy(*wwid, pp->wwid, WWID_SIZE);
|
|
+ else {
|
|
+ free(*wwid);
|
|
+ *wwid = NULL;
|
|
+ }
|
|
+ }
|
|
+out:
|
|
+ free_path(pp);
|
|
+ return r;
|
|
+}
|
|
diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h
|
|
new file mode 100644
|
|
index 00000000..7fd8aa47
|
|
--- /dev/null
|
|
+++ b/libmpathvalid/mpath_valid.h
|
|
@@ -0,0 +1,57 @@
|
|
+/*
|
|
+ * Copyright (C) 2015 Red Hat, Inc.
|
|
+ *
|
|
+ * This file is part of the device-mapper multipath userspace tools.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public License
|
|
+ * as published by the Free Software Foundation; either version 2
|
|
+ * of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public License
|
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
+ */
|
|
+
|
|
+#ifndef LIB_MPATH_VALID_H
|
|
+#define LIB_MPATH_VALID_H
|
|
+
|
|
+#ifdef __cpluscplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+enum mpath_valid_mode {
|
|
+ MPATH_DEFAULT,
|
|
+ MPATH_STRICT,
|
|
+ MPATH_SMART,
|
|
+ MPATH_GREEDY,
|
|
+ MPATH_MAX_MODE, /* used only for bounds checking */
|
|
+};
|
|
+
|
|
+/* MPATH_IS_VALID_NO_CHECK is used to skip checks to see if the device
|
|
+ * has already been unclaimed by multipath in the past */
|
|
+enum mpath_valid_result {
|
|
+ MPATH_IS_ERROR = -1,
|
|
+ MPATH_IS_NOT_VALID,
|
|
+ MPATH_IS_VALID,
|
|
+ MPATH_IS_VALID_NO_CHECK,
|
|
+ MPATH_IS_MAYBE_VALID,
|
|
+};
|
|
+
|
|
+struct config;
|
|
+extern struct config *mpathvalid_conf;
|
|
+int mpathvalid_init(int verbosity);
|
|
+int mpathvalid_exit(void);
|
|
+unsigned int mpathvalid_get_mode(void);
|
|
+int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid,
|
|
+ const char **path_wwids, unsigned int nr_paths);
|
|
+
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+#endif /* LIB_PATH_VALID_H */
|
|
--
|
|
2.17.2
|
|
|