All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] mpathpersist: add all_tg_pt option
@ 2018-06-01 22:22 Benjamin Marzinski
  2018-06-01 22:22 ` [PATCH 2/2] libmultipath: remove rbd code Benjamin Marzinski
  2018-06-06 20:25 ` [PATCH 1/2] mpathpersist: add all_tg_pt option Martin Wilck
  0 siblings, 2 replies; 7+ messages in thread
From: Benjamin Marzinski @ 2018-06-01 22:22 UTC (permalink / raw)
  To: device-mapper development

Some arrays, such as the EMC VNX, don't follow the scsi persistent
reservations spec in making key registrations per I_T NEXUS. Instead,
the registration is shared by all target ports connected to a given
host.  This causes mpathpersist to fail whenever it tries to register a
key, since it will receive a registration conflict on some of the paths.

To deal with this, mpathpersist needs to track the hosts that it has
done a registration on, and only register once per host. The new
"all_tg_pt" multipath.conf option is used to set which arrays need this
feature.  I currently don't know if all EMC VNX arrays handle persistent
reservations like this, or if it is configurable. A future patch will
update the VNX built-in config, if this is indeed their default (or
only) setting.

Multipathd doesn't need to worry about this. It is often the case that
when a path device comes back, it will still have the keys registered to
it. Because of this, multipathd uses register-and-ignore, which means
that it won't cause an error if the registration has already happened
down a different target port.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 libmpathpersist/mpath_persist.c | 28 ++++++++++++++++++++++------
 libmultipath/config.c           |  2 ++
 libmultipath/config.h           |  2 ++
 libmultipath/defaults.h         |  1 +
 libmultipath/dict.c             | 10 ++++++++++
 libmultipath/propsel.c          | 15 +++++++++++++++
 libmultipath/propsel.h          |  1 +
 libmultipath/structs.h          |  7 +++++++
 multipath/multipath.conf.5      | 11 +++++++++++
 9 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
index 907a17c..ca91c55 100644
--- a/libmpathpersist/mpath_persist.c
+++ b/libmpathpersist/mpath_persist.c
@@ -335,6 +335,7 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
 
 	conf = get_multipath_config();
 	select_reservation_key(conf, mpp);
+	select_all_tg_pt(conf, mpp);
 	put_multipath_config(conf);
 
 	memcpy(&prkey, paramp->sa_key, 8);
@@ -456,7 +457,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 	unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
 {
 
-	int i, j;
+	int i, j, k;
 	struct pathgroup *pgp = NULL;
 	struct path *pp = NULL;
 	int rollback = 0;
@@ -481,11 +482,13 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 	}
 
 	struct threadinfo thread[active_pathcount];
+	int hosts[active_pathcount];
 
 	memset(thread, 0, sizeof(thread));
 
 	/* init thread parameter */
 	for (i =0; i< active_pathcount; i++){
+		hosts[i] = -1;
 		thread[i].param.rq_servact = rq_servact;
 		thread[i].param.rq_scope = rq_scope;
 		thread[i].param.rq_type = rq_type;
@@ -514,6 +517,17 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 				condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev);
 				continue;
 			}
+			if (mpp->all_tg_pt == ALL_TG_PT_ON &&
+			    pp->sg_id.host_no != -1) {
+				for (k = 0; k < count; k++) {
+					if (pp->sg_id.host_no == hosts[k]) {
+						condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no);
+						break;
+					}
+				}
+				if (k < count)
+					continue;
+			}
 			strncpy(thread[count].param.dev, pp->dev,
 				FILE_NAME_SIZE - 1);
 
@@ -531,10 +545,12 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 				condlog (0, "%s: failed to create thread %d", mpp->wwid, rc);
 				thread[count].param.status = MPATH_PR_THREAD_ERROR;
 			}
+			else
+				hosts[count] = pp->sg_id.host_no;
 			count = count + 1;
 		}
 	}
-	for( i=0; i < active_pathcount ; i++){
+	for( i=0; i < count ; i++){
 		if (thread[i].param.status != MPATH_PR_THREAD_ERROR) {
 			rc = pthread_join(thread[i].id, NULL);
 			if (rc){
@@ -557,7 +573,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 	}
 	if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){
 		condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid);
-		for( i=0 ; i < active_pathcount ; i++){
+		for( i=0 ; i < count ; i++){
 			if(thread[i].param.status == MPATH_PR_SUCCESS) {
 				memcpy(&thread[i].param.paramp->key, &thread[i].param.paramp->sa_key, 8);
 				memset(&thread[i].param.paramp->sa_key, 0, 8);
@@ -571,7 +587,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
 			} else
 				thread[i].param.status = MPATH_PR_SKIP;
 		}
-		for(i=0; i < active_pathcount ; i++){
+		for(i=0; i < count ; i++){
 			if (thread[i].param.status != MPATH_PR_SKIP &&
 			    thread[i].param.status != MPATH_PR_THREAD_ERROR) {
 				rc = pthread_join(thread[i].id, NULL);
@@ -720,7 +736,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
 		}
 	}
 	pthread_attr_destroy (&attr);
-	for (i = 0; i < active_pathcount; i++){
+	for (i = 0; i < count; i++){
 		if (thread[i].param.status != MPATH_PR_THREAD_ERROR) {
 			rc = pthread_join (thread[i].id, NULL);
 			if (rc){
@@ -729,7 +745,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
 		}
 	}
 
-	for (i = 0; i < active_pathcount; i++){
+	for (i = 0; i < count; i++){
 		/*  check thread status here and return the status */
 
 		if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)
diff --git a/libmultipath/config.c b/libmultipath/config.c
index 085a3e1..5872927 100644
--- a/libmultipath/config.c
+++ b/libmultipath/config.c
@@ -352,6 +352,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src)
 	merge_num(skip_kpartx);
 	merge_num(max_sectors_kb);
 	merge_num(ghost_delay);
+	merge_num(all_tg_pt);
 
 	snprintf(id, sizeof(id), "%s/%s", dst->vendor, dst->product);
 	reconcile_features_with_options(id, &dst->features,
@@ -622,6 +623,7 @@ load_config (char * file)
 	conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS;
 	conf->remove_retries = 0;
 	conf->ghost_delay = DEFAULT_GHOST_DELAY;
+	conf->all_tg_pt = DEFAULT_ALL_TG_PT;
 
 	/*
 	 * preload default hwtable
diff --git a/libmultipath/config.h b/libmultipath/config.h
index 6e69a37..1bf708a 100644
--- a/libmultipath/config.h
+++ b/libmultipath/config.h
@@ -82,6 +82,7 @@ struct hwentry {
 	int skip_kpartx;
 	int max_sectors_kb;
 	int ghost_delay;
+	int all_tg_pt;
 	char * bl_product;
 };
 
@@ -194,6 +195,7 @@ struct config {
 	char * partition_delim;
 	char * config_dir;
 	int prkey_source;
+	int all_tg_pt;
 	struct be64 reservation_key;
 
 	vector keywords;
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
index d7b87b4..f076b4b 100644
--- a/libmultipath/defaults.h
+++ b/libmultipath/defaults.h
@@ -43,6 +43,7 @@
 #define DEFAULT_GHOST_DELAY GHOST_DELAY_OFF
 #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10
 #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1
+#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF
 
 #define DEFAULT_CHECKINT	5
 #define MAX_CHECKINT(a)		(a << 2)
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
index 3e7c5d6..2557b8a 100644
--- a/libmultipath/dict.c
+++ b/libmultipath/dict.c
@@ -1178,6 +1178,13 @@ declare_hw_snprint(ghost_delay, print_off_int_undef)
 declare_mp_handler(ghost_delay, set_off_int_undef)
 declare_mp_snprint(ghost_delay, print_off_int_undef)
 
+declare_def_handler(all_tg_pt, set_yes_no_undef)
+declare_def_snprint_defint(all_tg_pt, print_yes_no_undef, DEFAULT_ALL_TG_PT)
+declare_ovr_handler(all_tg_pt, set_yes_no_undef)
+declare_ovr_snprint(all_tg_pt, print_yes_no_undef)
+declare_hw_handler(all_tg_pt, set_yes_no_undef)
+declare_hw_snprint(all_tg_pt, print_yes_no_undef)
+
 
 static int
 def_uxsock_timeout_handler(struct config *conf, vector strvec)
@@ -1509,6 +1516,7 @@ init_keywords(vector keywords)
 	install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
 	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);
 	install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler);
 	install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
 	install_keyword("detect_checker", &def_detect_checker_handler, &snprint_def_detect_checker);
@@ -1618,6 +1626,7 @@ init_keywords(vector keywords)
 	install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx);
 	install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb);
 	install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay);
+	install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt);
 	install_sublevel_end();
 
 	install_keyword_root("overrides", &overrides_handler);
@@ -1654,6 +1663,7 @@ init_keywords(vector keywords)
 	install_keyword("skip_kpartx", &ovr_skip_kpartx_handler, &snprint_ovr_skip_kpartx);
 	install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb);
 	install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay);
+	install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt);
 
 	install_keyword_root("multipaths", &multipaths_handler);
 	install_keyword_multi("multipath", &multipath_handler, NULL);
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 627d366..9ca1355 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -978,3 +978,18 @@ out:
 		pp->dev, pp->find_multipaths_timeout, origin);
 	return 0;
 }
+
+int select_all_tg_pt (struct config *conf, struct multipath * mp)
+{
+	const char *origin;
+
+	mp_set_ovr(all_tg_pt);
+	mp_set_hwe(all_tg_pt);
+	mp_set_conf(all_tg_pt);
+	mp_set_default(all_tg_pt, DEFAULT_ALL_TG_PT);
+out:
+	condlog(3, "%s: all_tg_pt = %s %s", mp->alias,
+		(mp->all_tg_pt == ALL_TG_PT_ON)? "yes" : "no",
+		origin);
+	return 0;
+}
diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h
index a022bee..ae99b92 100644
--- a/libmultipath/propsel.h
+++ b/libmultipath/propsel.h
@@ -34,3 +34,4 @@ int select_ghost_delay(struct config *conf, struct multipath * mp);
 void reconcile_features_with_options(const char *id, char **features,
 				     int* no_path_retry,
 				     int *retain_hwhandler);
+int select_all_tg_pt (struct config *conf, struct multipath * mp);
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index e424b15..0194b1e 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -217,6 +217,12 @@ enum prkey_sources {
 	PRKEY_SOURCE_FILE,
 };
 
+enum all_tg_pt_states {
+	ALL_TG_PT_UNDEF = YNU_UNDEF,
+	ALL_TG_PT_OFF = YNU_NO,
+	ALL_TG_PT_ON = YNU_YES,
+};
+
 struct sg_id {
 	int host_no;
 	int channel;
@@ -362,6 +368,7 @@ struct multipath {
 	int prkey_source;
 	struct be64 reservation_key;
 	unsigned char prflag;
+	int all_tg_pt;
 	struct gen_multipath generic_mp;
 };
 
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 96d1b66..0c1f174 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -743,6 +743,17 @@ The default is: \fB<unset>\fR
 .
 .
 .TP
+.B all_tg_pt
+This must be set to \fByes\fR to successfully use mpathpersist on arrays that
+automatically set and clear registration keys on all target ports from a
+host, instead of per target port per host.
+.RS
+.TP
+The default is: \fBno\fR
+.RE
+.
+.
+.TP
 .B retain_attached_hw_handler
 (Obsolete for kernels >= 4.3) If set to
 .I yes
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] libmultipath: remove rbd code
  2018-06-01 22:22 [PATCH 1/2] mpathpersist: add all_tg_pt option Benjamin Marzinski
@ 2018-06-01 22:22 ` Benjamin Marzinski
  2018-06-02  3:57   ` Mike Christie
  2018-06-06 20:25 ` [PATCH 1/2] mpathpersist: add all_tg_pt option Martin Wilck
  1 sibling, 1 reply; 7+ messages in thread
From: Benjamin Marzinski @ 2018-06-01 22:22 UTC (permalink / raw)
  To: device-mapper development; +Cc: Michael Christie, Jason Dillaman

The Ceph tean has asked to drop support for multipathed rbd, since it
was running into data corruption issues. There was never an upstream
Ceph release based on it, and because of the corruption, there should be
no users of this code. This patch simply reverts all the rbd code from
multipath.

Cc: Michael Christie <mchristi@redhat.com>
Cc: Jason Dillaman <dillaman@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 libmultipath/checkers.c              |  22 --
 libmultipath/checkers.h              |   6 -
 libmultipath/checkers/Makefile       |   7 -
 libmultipath/checkers/cciss_tur.c    |   5 -
 libmultipath/checkers/directio.c     |   5 -
 libmultipath/checkers/emc_clariion.c |   5 -
 libmultipath/checkers/hp_sw.c        |   5 -
 libmultipath/checkers/rbd.c          | 653 -----------------------------------
 libmultipath/checkers/rdac.c         |   5 -
 libmultipath/checkers/readsector0.c  |   5 -
 libmultipath/checkers/tur.c          |   5 -
 libmultipath/discovery.c             |  70 ----
 libmultipath/hwtable.c               |  12 -
 multipath/multipath.conf.5           |   3 -
 multipathd/main.c                    |  11 -
 15 files changed, 819 deletions(-)
 delete mode 100644 libmultipath/checkers/rbd.c

diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 08cdfc3..0bacc86 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -141,13 +141,6 @@ struct checker * add_checker (char *multipath_dir, char * name)
 	if (!c->free)
 		goto out;
 
-	c->repair = (void (*)(struct checker *)) dlsym(c->handle,
-						       "libcheck_repair");
-	errstr = dlerror();
-	if (errstr != NULL)
-		condlog(0, "A dynamic linking error occurred: (%s)", errstr);
-	if (!c->repair)
-		goto out;
 done:
 	c->fd = -1;
 	c->sync = 1;
@@ -222,20 +215,6 @@ void checker_put (struct checker * dst)
 	free_checker(src);
 }
 
-void checker_repair (struct checker * c)
-{
-	if (!checker_selected(c))
-		return;
-
-	c->message[0] = '\0';
-	if (c->disable) {
-		MSG(c, "checker disabled");
-		return;
-	}
-	if (c->repair)
-		c->repair(c);
-}
-
 int checker_check (struct checker * c, int path_state)
 {
 	int r;
@@ -310,7 +289,6 @@ void checker_get (char *multipath_dir, struct checker * dst, char * name)
 	dst->sync = src->sync;
 	strncpy(dst->name, src->name, CHECKER_NAME_LEN);
 	strncpy(dst->message, src->message, CHECKER_MSG_LEN);
-	dst->repair = src->repair;
 	dst->check = src->check;
 	dst->init = src->init;
 	dst->free = src->free;
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index 52154ca..7b18a1a 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -86,7 +86,6 @@ enum path_check_state {
 #define READSECTOR0  "readsector0"
 #define CCISS_TUR    "cciss_tur"
 #define NONE         "none"
-#define RBD          "rbd"
 
 #define ASYNC_TIMEOUT_SEC	30
 
@@ -113,9 +112,6 @@ struct checker {
 						multipath-wide. Use MALLOC if
 						you want to stuff data in. */
 	int (*check)(struct checker *);
-	void (*repair)(struct checker *);    /* called if check returns
-						PATH_DOWN to bring path into
-						usable state */
 	int (*init)(struct checker *);       /* to allocate the context */
 	void (*free)(struct checker *);      /* to free the context */
 };
@@ -136,7 +132,6 @@ void checker_set_async (struct checker *);
 void checker_set_fd (struct checker *, int);
 void checker_enable (struct checker *);
 void checker_disable (struct checker *);
-void checker_repair (struct checker *);
 int checker_check (struct checker *, int);
 int checker_selected (struct checker *);
 char * checker_name (struct checker *);
@@ -148,6 +143,5 @@ void checker_get (char *, struct checker *, char *);
 int libcheck_check(struct checker *);
 int libcheck_init(struct checker *);
 void libcheck_free(struct checker *);
-void libcheck_repair(struct checker *);
 
 #endif /* _CHECKERS_H */
diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile
index 87c15bd..02caea6 100644
--- a/libmultipath/checkers/Makefile
+++ b/libmultipath/checkers/Makefile
@@ -15,15 +15,8 @@ LIBS= \
 	libcheckhp_sw.so \
 	libcheckrdac.so
 
-ifneq ($(call check_file,/usr/include/rados/librados.h),0)
-LIBS += libcheckrbd.so
-endif
-
 all: $(LIBS)
 
-libcheckrbd.so: rbd.o
-	$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lrados -ludev
-
 libcheckdirectio.so: libsg.o directio.o
 	$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio
 
diff --git a/libmultipath/checkers/cciss_tur.c b/libmultipath/checkers/cciss_tur.c
index 436470c..1cab201 100644
--- a/libmultipath/checkers/cciss_tur.c
+++ b/libmultipath/checkers/cciss_tur.c
@@ -59,11 +59,6 @@ void libcheck_free (struct checker * c)
 	return;
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 int libcheck_check(struct checker * c)
 {
 	int rc;
diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
index ce60e4c..a80848d 100644
--- a/libmultipath/checkers/directio.c
+++ b/libmultipath/checkers/directio.c
@@ -118,11 +118,6 @@ void libcheck_free (struct checker * c)
 	free(ct);
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 static int
 check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
 {
diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c
index 9c1ffed..9115b1b 100644
--- a/libmultipath/checkers/emc_clariion.c
+++ b/libmultipath/checkers/emc_clariion.c
@@ -90,11 +90,6 @@ void libcheck_free (struct checker * c)
 	free(c->context);
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 int libcheck_check (struct checker * c)
 {
 	unsigned char sense_buffer[128] = { 0, };
diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c
index cee9aab..0ad34a6 100644
--- a/libmultipath/checkers/hp_sw.c
+++ b/libmultipath/checkers/hp_sw.c
@@ -45,11 +45,6 @@ void libcheck_free (struct checker * c)
 	return;
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 static int
 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
        void *resp, int mx_resp_len, int noisy, unsigned int timeout)
diff --git a/libmultipath/checkers/rbd.c b/libmultipath/checkers/rbd.c
deleted file mode 100644
index 4ff54f4..0000000
--- a/libmultipath/checkers/rbd.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat
- * Copyright (c) 2004 Christophe Varoqui
- *
- * Code based off of tur.c and ceph's krbd.cc
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread.h>
-#include <libudev.h>
-#include <ifaddrs.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <urcu.h>
-
-#include "rados/librados.h"
-
-#include "structs.h"
-#include "checkers.h"
-
-#include "../libmultipath/debug.h"
-#include "../libmultipath/util.h"
-#include "../libmultipath/time-util.h"
-#include "../libmultipath/util.h"
-
-struct rbd_checker_context;
-typedef int (thread_fn)(struct rbd_checker_context *ct, char *msg);
-
-#define RBD_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
-
-#define RBD_FEATURE_EXCLUSIVE_LOCK	(1 << 2)
-
-struct rbd_checker_context {
-	int rbd_bus_id;
-	char *client_addr;
-	char *config_info;
-	char *snap;
-	char *pool;
-	char *image;
-	char *username;
-	int remapped;
-	int blacklisted;
-	unsigned lock_on_read:1;
-
-	rados_t cluster;
-
-	int state;
-	int running;
-	time_t time;
-	thread_fn *fn;
-	pthread_t thread;
-	pthread_mutex_t lock;
-	pthread_cond_t active;
-	pthread_spinlock_t hldr_lock;
-	int holders;
-	char message[CHECKER_MSG_LEN];
-};
-
-int libcheck_init(struct checker * c)
-{
-	struct rbd_checker_context *ct;
-	struct udev_device *block_dev;
-	struct udev_device *bus_dev;
-	struct udev *udev;
-	struct stat sb;
-	const char *block_name, *addr, *config_info, *features_str;
-	const char *image, *pool, *snap, *username;
-	uint64_t features = 0;
-	char sysfs_path[PATH_SIZE];
-	int ret;
-
-	ct = malloc(sizeof(struct rbd_checker_context));
-	if (!ct)
-		return 1;
-	memset(ct, 0, sizeof(struct rbd_checker_context));
-	ct->holders = 1;
-	pthread_cond_init_mono(&ct->active);
-	pthread_mutex_init(&ct->lock, NULL);
-	pthread_spin_init(&ct->hldr_lock, PTHREAD_PROCESS_PRIVATE);
-	c->context = ct;
-
-	/*
-	 * The rbd block layer sysfs device is not linked to the rbd bus
-	 * device that we interact with, so figure that out now.
-	 */
-	if (fstat(c->fd, &sb) != 0)
-		goto free_ct;
-
-	udev = udev_new();
-	if (!udev)
-		goto free_ct;
-
-	block_dev = udev_device_new_from_devnum(udev, 'b', sb.st_rdev);
-	if (!block_dev)
-		goto free_udev;
-
-	block_name  = udev_device_get_sysname(block_dev);
-	ret = sscanf(block_name, "rbd%d", &ct->rbd_bus_id);
-
-	udev_device_unref(block_dev);
-	if (ret != 1)
-		goto free_udev;
-
-	snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d",
-		 ct->rbd_bus_id);
-	bus_dev = udev_device_new_from_syspath(udev, sysfs_path);
-	if (!bus_dev)
-		goto free_udev;
-
-	addr = udev_device_get_sysattr_value(bus_dev, "client_addr");
-	if (!addr) {
-		condlog(0, "rbd%d: Could not find client_addr in rbd sysfs. "
-			"Try updating kernel", ct->rbd_bus_id);
-		goto free_dev;
-	}
-
-	ct->client_addr = strdup(addr);
-	if (!ct->client_addr)
-		goto free_dev;
-
-	features_str = udev_device_get_sysattr_value(bus_dev, "features");
-	if (!features_str)
-		goto free_addr;
-	features = strtoll(features_str, NULL, 16);
-	if (!(features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
-		condlog(3, "rbd%d: Exclusive lock not set.", ct->rbd_bus_id);
-		goto free_addr;
-	}
-
-	config_info = udev_device_get_sysattr_value(bus_dev, "config_info");
-	if (!config_info)
-		goto free_addr;
-
-	if (!strstr(config_info, "noshare")) {
-		condlog(3, "rbd%d: Only nonshared clients supported.",
-			ct->rbd_bus_id);
-		goto free_addr;
-	}
-
-	if (strstr(config_info, "lock_on_read"))
-		ct->lock_on_read = 1;
-
-	ct->config_info = strdup(config_info);
-	if (!ct->config_info)
-		goto free_addr;
-
-	username = strstr(config_info, "name=");
-	if (username) {
-		char *end;
-		int len;
-
-		username += 5;
-		end = strchr(username, ',');
-		if (!end)
-			goto free_info;
-		len = end - username;
-
-		ct->username = malloc(len + 1);
-		if (!ct->username)
-			goto free_info;
-		strncpy(ct->username, username, len);
-		ct->username[len] = '\0';
-	}
-
-	image = udev_device_get_sysattr_value(bus_dev, "name");
-	if (!image)
-		goto free_username;
-
-	ct->image = strdup(image);
-	if (!ct->image)
-		goto free_username;
-
-	pool = udev_device_get_sysattr_value(bus_dev, "pool");
-	if (!pool)
-		goto free_image;
-
-	ct->pool = strdup(pool);
-	if (!ct->pool)
-		goto free_image;
-
-	snap = udev_device_get_sysattr_value(bus_dev, "current_snap");
-	if (!snap)
-		goto free_pool;
-
-	if (strcmp("-", snap)) {
-		ct->snap = strdup(snap);
-		if (!ct->snap)
-			goto free_pool;
-	}
-
-	if (rados_create(&ct->cluster, NULL) < 0) {
-		condlog(0, "rbd%d: Could not create rados cluster",
-			ct->rbd_bus_id);
-		goto free_snap;
-	}
-
-	if (rados_conf_read_file(ct->cluster, NULL) < 0) {
-		condlog(0, "rbd%d: Could not read rados conf", ct->rbd_bus_id);
-		goto shutdown_rados;
-	}
-
-	ret = rados_connect(ct->cluster);
-	if (ret < 0) {
-		condlog(0, "rbd%d: Could not connect to rados cluster",
-			ct->rbd_bus_id);
-		goto shutdown_rados;
-	}
-
-	udev_device_unref(bus_dev);
-	udev_unref(udev);
-
-	condlog(3, "rbd%d checker init %s %s/%s@%s %s", ct->rbd_bus_id,
-		ct->client_addr, ct->pool, ct->image, ct->snap ? ct->snap : "-",
-		ct->username ? ct->username : "none");
-	return 0;
-
-shutdown_rados:
-	rados_shutdown(ct->cluster);
-free_snap:
-	if (ct->snap)
-		free(ct->snap);
-free_pool:
-	free(ct->pool);
-free_image:
-	free(ct->image);
-free_username:
-	if (ct->username)
-		free(ct->username);
-free_info:
-	free(ct->config_info);
-free_addr:
-	free(ct->client_addr);
-free_dev:
-	udev_device_unref(bus_dev);
-free_udev:
-	udev_unref(udev);
-free_ct:
-	free(ct);
-	return 1;
-}
-
-static void cleanup_context(struct rbd_checker_context *ct)
-{
-	pthread_mutex_destroy(&ct->lock);
-	pthread_cond_destroy(&ct->active);
-	pthread_spin_destroy(&ct->hldr_lock);
-
-	rados_shutdown(ct->cluster);
-
-	if (ct->username)
-		free(ct->username);
-	if (ct->snap)
-		free(ct->snap);
-	free(ct->pool);
-	free(ct->image);
-	free(ct->config_info);
-	free(ct->client_addr);
-	free(ct);
-}
-
-void libcheck_free(struct checker * c)
-{
-	if (c->context) {
-		struct rbd_checker_context *ct = c->context;
-		int holders;
-		pthread_t thread;
-
-		pthread_spin_lock(&ct->hldr_lock);
-		ct->holders--;
-		holders = ct->holders;
-		thread = ct->thread;
-		pthread_spin_unlock(&ct->hldr_lock);
-		if (holders)
-			pthread_cancel(thread);
-		else
-			cleanup_context(ct);
-		c->context = NULL;
-	}
-}
-
-static int rbd_is_blacklisted(struct rbd_checker_context *ct, char *msg)
-{
-	char *addr_tok, *start, *save;
-	const char *cmd[2];
-	char *blklist, *stat;
-	size_t blklist_len, stat_len;
-	int ret;
-	char *end;
-
-	cmd[0] = "{\"prefix\": \"osd blacklist ls\"}";
-	cmd[1] = NULL;
-
-	ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0,
-				&blklist, &blklist_len, &stat, &stat_len);
-	if (ret < 0) {
-		RBD_MSG(msg, "checker failed: mon command failed %d", ret);
-		return ret;
-	}
-
-	if (!blklist || !blklist_len)
-		goto free_bufs;
-
-	/*
-	 * parse list of addrs with the format
-	 * ipv4:port/nonce date time\n
-	 * or
-	 * [ipv6]:port/nonce date time\n
-	 */
-	ret = 0;
-	for (start = blklist; ; start = NULL) {
-		addr_tok = strtok_r(start, "\n", &save);
-		if (!addr_tok || !strlen(addr_tok))
-			break;
-
-		end = strchr(addr_tok, ' ');
-		if (!end) {
-			RBD_MSG(msg, "checker failed: invalid blacklist %s",
-				 addr_tok);
-			break;
-		}
-		*end = '\0';
-
-		if (!strcmp(addr_tok, ct->client_addr)) {
-			ct->blacklisted = 1;
-			RBD_MSG(msg, "%s is blacklisted", ct->client_addr);
-			ret = 1;
-			break;
-		}
-	}
-
-free_bufs:
-	rados_buffer_free(blklist);
-	rados_buffer_free(stat);
-	return ret;
-}
-
-static int rbd_check(struct rbd_checker_context *ct, char *msg)
-{
-	if (ct->blacklisted || rbd_is_blacklisted(ct, msg) == 1)
-		return PATH_DOWN;
-
-	RBD_MSG(msg, "checker reports path is up");
-	/*
-	 * Path may have issues, but the ceph cluster is at least
-	 * accepting IO, so we can attempt to do IO.
-	 *
-	 * TODO: in future versions, we can run other tests to
-	 * verify OSDs and networks.
-	 */
-	return PATH_UP;
-}
-
-static int sysfs_write_rbd_bus(const char *which, const char *buf,
-			       size_t buf_len)
-{
-	char sysfs_path[PATH_SIZE];
-	int fd;
-	int r;
-
-	/* we require newer kernels so single_major should always be there */
-	snprintf(sysfs_path, sizeof(sysfs_path),
-		 "/sys/bus/rbd/%s_single_major", which);
-	fd = open(sysfs_path, O_WRONLY);
-	if (fd < 0)
-		return -errno;
-
-	r = safe_write(fd, buf, buf_len);
-	close(fd);
-	return r;
-}
-
-static int rbd_remap(struct rbd_checker_context *ct)
-{
-	char *argv[11];
-	pid_t pid;
-	int ret = 0, i = 0;
-	int status;
-
-	pid = fork();
-	switch (pid) {
-	case 0:
-		argv[i++] = "rbd";
-		argv[i++] = "map";
-		if (ct->lock_on_read)
-			argv[i++] = "-o noshare,lock_on_read";
-		else
-			argv[i++] = "-o noshare";
-		if (ct->username) {
-			argv[i++] = "--id";
-			argv[i++] = ct->username;
-		}
-		argv[i++] = "--pool";
-		argv[i++] = ct->pool;
-		if (ct->snap) {
-			argv[i++] = "--snap";
-			argv[i++] = ct->snap;
-		}
-		argv[i++] = ct->image;
-		argv[i] = NULL;
-
-		ret = execvp(argv[0], argv);
-		condlog(0, "rbd%d: Error executing rbd: %s", ct->rbd_bus_id,
-			strerror(errno));
-		exit(-1);
-	case -1:
-		condlog(0, "rbd%d: fork failed: %s", ct->rbd_bus_id,
-			strerror(errno));
-		return -1;
-	default:
-		ret = -1;
-		wait(&status);
-		if (WIFEXITED(status)) {
-			status = WEXITSTATUS(status);
-			if (status == 0)
-				ret = 0;
-			else
-				condlog(0, "rbd%d: failed with %d",
-					ct->rbd_bus_id, status);
-		}
-	}
-
-	return ret;
-}
-
-static int sysfs_write_rbd_remove(const char *buf, int buf_len)
-{
-	return sysfs_write_rbd_bus("remove", buf, buf_len);
-}
-
-static int rbd_rm_blacklist(struct rbd_checker_context *ct)
-{
-	const char *cmd[2];
-	char *stat, *cmd_str;
-	size_t stat_len;
-	int ret;
-
-	ret = asprintf(&cmd_str, "{\"prefix\": \"osd blacklist\", \"blacklistop\": \"rm\", \"addr\": \"%s\"}",
-		       ct->client_addr);
-	if (ret == -1)
-		return -ENOMEM;
-
-	cmd[0] = cmd_str;
-	cmd[1] = NULL;
-
-	ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0,
-				NULL, NULL, &stat, &stat_len);
-	if (ret < 0) {
-		condlog(1, "rbd%d: repair failed to remove blacklist for %s %d",
-			ct->rbd_bus_id, ct->client_addr, ret);
-		goto free_cmd;
-	}
-
-	condlog(1, "rbd%d: repair rm blacklist for %s",
-	       ct->rbd_bus_id, ct->client_addr);
-	free(stat);
-free_cmd:
-	free(cmd_str);
-	return ret;
-}
-
-static int rbd_repair(struct rbd_checker_context *ct, char *msg)
-{
-	char del[17];
-	int ret;
-
-	if (!ct->blacklisted)
-		return PATH_UP;
-
-	if (!ct->remapped) {
-		ret = rbd_remap(ct);
-		if (ret) {
-			RBD_MSG(msg, "repair failed to remap. Err %d", ret);
-			return PATH_DOWN;
-		}
-	}
-	ct->remapped = 1;
-
-	snprintf(del, sizeof(del), "%d force", ct->rbd_bus_id);
-	ret = sysfs_write_rbd_remove(del, strlen(del) + 1);
-	if (ret) {
-		RBD_MSG(msg, "repair failed to clean up. Err %d", ret);
-		return PATH_DOWN;
-	}
-
-	ret = rbd_rm_blacklist(ct);
-	if (ret) {
-		RBD_MSG(msg, "repair could not remove blacklist entry. Err %d",
-			ret);
-		return PATH_DOWN;
-	}
-
-	ct->remapped = 0;
-	ct->blacklisted = 0;
-
-	RBD_MSG(msg, "has been repaired");
-	return PATH_UP;
-}
-
-#define rbd_thread_cleanup_push(ct) pthread_cleanup_push(cleanup_func, ct)
-#define rbd_thread_cleanup_pop(ct) pthread_cleanup_pop(1)
-
-static void cleanup_func(void *data)
-{
-	int holders;
-	struct rbd_checker_context *ct = data;
-	pthread_spin_lock(&ct->hldr_lock);
-	ct->holders--;
-	holders = ct->holders;
-	ct->thread = 0;
-	pthread_spin_unlock(&ct->hldr_lock);
-	if (!holders)
-		cleanup_context(ct);
-	rcu_unregister_thread();
-}
-
-static void *rbd_thread(void *ctx)
-{
-	struct rbd_checker_context *ct = ctx;
-	int state;
-
-	/* This thread can be canceled, so setup clean up */
-	rbd_thread_cleanup_push(ct)
-	rcu_register_thread();
-	condlog(3, "rbd%d: thread starting up", ct->rbd_bus_id);
-
-	ct->message[0] = '\0';
-
-	/* checker start up */
-	pthread_mutex_lock(&ct->lock);
-	ct->state = PATH_PENDING;
-	pthread_mutex_unlock(&ct->lock);
-
-	state = ct->fn(ct, ct->message);
-
-	/* checker done */
-	pthread_mutex_lock(&ct->lock);
-	ct->state = state;
-	pthread_cond_signal(&ct->active);
-	pthread_mutex_unlock(&ct->lock);
-
-	condlog(3, "rbd%d: thead finished, state %s", ct->rbd_bus_id,
-		checker_state_name(state));
-	rbd_thread_cleanup_pop(ct);
-	return ((void *)0);
-}
-
-static void rbd_timeout(struct timespec *tsp)
-{
-	clock_gettime(CLOCK_MONOTONIC, tsp);
-	tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
-	normalize_timespec(tsp);
-}
-
-static int rbd_exec_fn(struct checker *c, thread_fn *fn)
-{
-	struct rbd_checker_context *ct = c->context;
-	struct timespec tsp;
-	pthread_attr_t attr;
-	int rbd_status, r;
-
-	if (c->sync)
-		return fn(ct, c->message);
-	/*
-	 * Async mode
-	 */
-	r = pthread_mutex_lock(&ct->lock);
-	if (r != 0) {
-		condlog(2, "rbd%d: mutex lock failed with %d", ct->rbd_bus_id,
-			r);
-		MSG(c, "rbd%d: thread failed to initialize", ct->rbd_bus_id);
-		return PATH_WILD;
-	}
-
-	if (ct->running) {
-		/* Check if checker is still running */
-		if (ct->thread) {
-			condlog(3, "rbd%d: thread not finished",
-				ct->rbd_bus_id);
-			rbd_status = PATH_PENDING;
-		} else {
-			/* checker done */
-			ct->running = 0;
-			rbd_status = ct->state;
-			strncpy(c->message, ct->message, CHECKER_MSG_LEN);
-			c->message[CHECKER_MSG_LEN - 1] = '\0';
-		}
-		pthread_mutex_unlock(&ct->lock);
-	} else {
-		/* Start new checker */
-		ct->state = PATH_UNCHECKED;
-		ct->fn = fn;
-		pthread_spin_lock(&ct->hldr_lock);
-		ct->holders++;
-		pthread_spin_unlock(&ct->hldr_lock);
-		setup_thread_attr(&attr, 32 * 1024, 1);
-		r = pthread_create(&ct->thread, &attr, rbd_thread, ct);
-		if (r) {
-			pthread_mutex_unlock(&ct->lock);
-			ct->thread = 0;
-			ct->holders--;
-			condlog(3, "rbd%d failed to start rbd thread, using sync mode",
-				ct->rbd_bus_id);
-			return fn(ct, c->message);
-		}
-		pthread_attr_destroy(&attr);
-		rbd_timeout(&tsp);
-		r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp);
-		rbd_status = ct->state;
-		strncpy(c->message, ct->message,CHECKER_MSG_LEN);
-		c->message[CHECKER_MSG_LEN -1] = '\0';
-		pthread_mutex_unlock(&ct->lock);
-
-		if (ct->thread &&
-		    (rbd_status == PATH_PENDING || rbd_status == PATH_UNCHECKED)) {
-			condlog(3, "rbd%d: thread still running",
-				ct->rbd_bus_id);
-			ct->running = 1;
-			rbd_status = PATH_PENDING;
-		}
-	}
-
-	return rbd_status;
-}
-
-void libcheck_repair(struct checker * c)
-{
-	struct rbd_checker_context *ct = c->context;
-
-	if (!ct || !ct->blacklisted)
-		return;
-	rbd_exec_fn(c, rbd_repair);
-}
-
-int libcheck_check(struct checker * c)
-{
-	struct rbd_checker_context *ct = c->context;
-
-	if (!ct)
-		return PATH_UNCHECKED;
-
-	if (ct->blacklisted)
-		return PATH_DOWN;
-
-	return rbd_exec_fn(c, rbd_check);
-}
diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
index a643a4a..5104e4e 100644
--- a/libmultipath/checkers/rdac.c
+++ b/libmultipath/checkers/rdac.c
@@ -139,11 +139,6 @@ void libcheck_free (struct checker * c)
 	return;
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 static int
 do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len,
        unsigned int timeout)
diff --git a/libmultipath/checkers/readsector0.c b/libmultipath/checkers/readsector0.c
index 8fccb46..1c2a868 100644
--- a/libmultipath/checkers/readsector0.c
+++ b/libmultipath/checkers/readsector0.c
@@ -23,11 +23,6 @@ void libcheck_free (struct checker * c)
 	return;
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 int libcheck_check (struct checker * c)
 {
 	unsigned char buf[4096];
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
index eb3348d..bf8486d 100644
--- a/libmultipath/checkers/tur.c
+++ b/libmultipath/checkers/tur.c
@@ -112,11 +112,6 @@ void libcheck_free (struct checker * c)
 	return;
 }
 
-void libcheck_repair (struct checker * c)
-{
-	return;
-}
-
 #define TUR_MSG(fmt, args...)					\
 	do {							\
 		char msg[CHECKER_MSG_LEN];			\
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 1ef1dfa..18ad0e2 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -1246,21 +1246,6 @@ nvme_sysfs_pathinfo (struct path * pp, vector hwtable)
 }
 
 static int
-rbd_sysfs_pathinfo (struct path * pp, vector hwtable)
-{
-	sprintf(pp->vendor_id, "Ceph");
-	sprintf(pp->product_id, "RBD");
-
-	condlog(3, "%s: vendor = %s product = %s", pp->dev, pp->vendor_id,
-		pp->product_id);
-	/*
-	 * set the hwe configlet pointer
-	 */
-	pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
-	return 0;
-}
-
-static int
 ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
 {
 	struct udev_device *parent;
@@ -1486,8 +1471,6 @@ sysfs_pathinfo(struct path * pp, vector hwtable)
 		pp->bus = SYSFS_BUS_CCW;
 	if (!strncmp(pp->dev,"sd", 2))
 		pp->bus = SYSFS_BUS_SCSI;
-	if (!strncmp(pp->dev,"rbd", 3))
-		pp->bus = SYSFS_BUS_RBD;
 	if (!strncmp(pp->dev,"nvme", 4))
 		pp->bus = SYSFS_BUS_NVME;
 
@@ -1502,9 +1485,6 @@ sysfs_pathinfo(struct path * pp, vector hwtable)
 	} else if (pp->bus == SYSFS_BUS_CCISS) {
 		if (cciss_sysfs_pathinfo(pp, hwtable))
 			return 1;
-	} else if (pp->bus == SYSFS_BUS_RBD) {
-		if (rbd_sysfs_pathinfo(pp, hwtable))
-			return 1;
 	} else if (pp->bus == SYSFS_BUS_NVME) {
 		if (nvme_sysfs_pathinfo(pp, hwtable))
 			return 1;
@@ -1753,53 +1733,6 @@ get_udev_uid(struct path * pp, char *uid_attribute, struct udev_device *udev)
 }
 
 static int
-get_rbd_uid(struct path * pp)
-{
-	struct udev_device *rbd_bus_dev;
-	int ret, rbd_bus_id;
-	const char *pool, *image, *snap;
-	char sysfs_path[PATH_SIZE];
-	uint64_t snap_id, max_snap_id = -3;
-
-	ret = sscanf(pp->dev, "rbd%d", &rbd_bus_id);
-	if (ret != 1)
-		return -EINVAL;
-
-	snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d",
-		 rbd_bus_id);
-	rbd_bus_dev = udev_device_new_from_syspath(udev, sysfs_path);
-	if (!rbd_bus_dev)
-		return -ENODEV;
-
-	ret = -EINVAL;
-	pool = udev_device_get_sysattr_value(rbd_bus_dev, "pool_id");
-	if (!pool)
-		goto free_dev;
-
-	image = udev_device_get_sysattr_value(rbd_bus_dev, "image_id");
-	if (!image)
-		goto free_dev;
-
-	snap = udev_device_get_sysattr_value(rbd_bus_dev, "snap_id");
-	if (!snap)
-		goto free_dev;
-	snap_id = strtoull(snap, NULL, 19);
-	if (snap_id >= max_snap_id)
-		ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s", pool, image);
-	else
-		ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s-%s", pool,
-			       image, snap);
-	if (ret >= WWID_SIZE) {
-		condlog(0, "%s: wwid overflow", pp->dev);
-		ret = -EOVERFLOW;
-	}
-
-free_dev:
-	udev_device_unref(rbd_bus_dev);
-	return ret;
-}
-
-static int
 get_vpd_uid(struct path * pp)
 {
 	struct udev_device *parent = pp->udev;
@@ -1876,9 +1809,6 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
 		} else
 			len = strlen(pp->wwid);
 		origin = "callout";
-	} else if (pp->bus == SYSFS_BUS_RBD) {
-		len = get_rbd_uid(pp);
-		origin = "sysfs";
 	} else {
 
 		if (udev && pp->uid_attribute) {
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
index 148f0ba..d529bae 100644
--- a/libmultipath/hwtable.c
+++ b/libmultipath/hwtable.c
@@ -1000,18 +1000,6 @@ static struct hwentry default_hw[] = {
 		.prio_name     = PRIO_ALUA,
 	},
 	/*
-	 * Red Hat
-	 *
-	 * Maintainer: Mike Christie
-	 * Mail: mchristi@redhat.com
-	 */
-	{
-		.vendor        = "Ceph",
-		.product       = "RBD",
-		.checker_name  = RBD,
-		.deferred_remove = DEFERRED_REMOVE_ON,
-	},
-	/*
 	 * Kove
 	 */
 	{
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 0c1f174..31f4585 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -482,9 +482,6 @@ Check the path state for HP/COMPAQ Smart Array(CCISS) controllers.
 .I none
 Do not check the device, fallback to use the values retrieved from sysfs
 .TP
-.I rbd
-Check if the path is in the Ceph blacklist and remap the path if it is.
-.TP
 The default is: \fBtur\fR
 .RE
 .
diff --git a/multipathd/main.c b/multipathd/main.c
index 0db88ee..d40c416 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1783,15 +1783,6 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
 	return 0;
 }
 
-void repair_path(struct path * pp)
-{
-	if (pp->state != PATH_DOWN)
-		return;
-
-	checker_repair(&pp->checker);
-	LOG_MSG(1, checker_message(&pp->checker));
-}
-
 /*
  * Returns '1' if the path has been checked, '-1' if it was blacklisted
  * and '0' otherwise
@@ -1972,7 +1963,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
 			pp->mpp->failback_tick = 0;
 
 			pp->mpp->stat_path_failures++;
-			repair_path(pp);
 			return 1;
 		}
 
@@ -2071,7 +2061,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
 	}
 
 	pp->state = newstate;
-	repair_path(pp);
 
 	if (pp->mpp->wait_for_udev)
 		return 1;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] libmultipath: remove rbd code
  2018-06-01 22:22 ` [PATCH 2/2] libmultipath: remove rbd code Benjamin Marzinski
@ 2018-06-02  3:57   ` Mike Christie
  0 siblings, 0 replies; 7+ messages in thread
From: Mike Christie @ 2018-06-02  3:57 UTC (permalink / raw)
  To: Benjamin Marzinski, device-mapper development; +Cc: Jason Dillaman

On 06/01/2018 05:22 PM, Benjamin Marzinski wrote:
> The Ceph tean has asked to drop support for multipathed rbd, since it
> was running into data corruption issues. There was never an upstream
> Ceph release based on it, and because of the corruption, there should be
> no users of this code. This patch simply reverts all the rbd code from
> multipath.
> 
> Cc: Michael Christie <mchristi@redhat.com>
> Cc: Jason Dillaman <dillaman@redhat.com>
> Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>

Reviewed-by: Mike Christie <mchristi@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] mpathpersist: add all_tg_pt option
  2018-06-01 22:22 [PATCH 1/2] mpathpersist: add all_tg_pt option Benjamin Marzinski
  2018-06-01 22:22 ` [PATCH 2/2] libmultipath: remove rbd code Benjamin Marzinski
@ 2018-06-06 20:25 ` Martin Wilck
  2018-06-06 21:56   ` Benjamin Marzinski
  1 sibling, 1 reply; 7+ messages in thread
From: Martin Wilck @ 2018-06-06 20:25 UTC (permalink / raw)
  To: Benjamin Marzinski, device-mapper development

On Fri, 2018-06-01 at 17:22 -0500, Benjamin Marzinski wrote:
> Some arrays, such as the EMC VNX, don't follow the scsi persistent
> reservations spec in making key registrations per I_T NEXUS. Instead,
> the registration is shared by all target ports connected to a given
> host.  This causes mpathpersist to fail whenever it tries to register
> a
> key, since it will receive a registration conflict on some of the
> paths.
> 
> To deal with this, mpathpersist needs to track the hosts that it has
> done a registration on, and only register once per host. The new
> "all_tg_pt" multipath.conf option is used to set which arrays need
> this
> feature.  I currently don't know if all EMC VNX arrays handle
> persistent
> reservations like this, or if it is configurable. A future patch will
> update the VNX built-in config, if this is indeed their default (or
> only) setting.
> 
> Multipathd doesn't need to worry about this. It is often the case
> that
> when a path device comes back, it will still have the keys registered
> to
> it. Because of this, multipathd uses register-and-ignore, which means
> that it won't cause an error if the registration has already happened
> down a different target port.
> 
> Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
> ---
>  libmpathpersist/mpath_persist.c | 28 ++++++++++++++++++++++------
>  libmultipath/config.c           |  2 ++
>  libmultipath/config.h           |  2 ++
>  libmultipath/defaults.h         |  1 +
>  libmultipath/dict.c             | 10 ++++++++++
>  libmultipath/propsel.c          | 15 +++++++++++++++
>  libmultipath/propsel.h          |  1 +
>  libmultipath/structs.h          |  7 +++++++
>  multipath/multipath.conf.5      | 11 +++++++++++
>  9 files changed, 71 insertions(+), 6 deletions(-)

The patch looks good to me, but doesn't this mean that mpathpersist
would now also support persistent reservations with the ALL_TG_PT bit
set (IIUC, the VNX basically acts as if that bit was always set)? 

If yes, I think the warning in mpath_prout_reg() about this flag could
be dropped, and mpathpersist could be extended to support the -Y/
--param-alltgpt option, no?

Otherwise, I'd suggest to give this option a different name, because
it'd just too easily be confused with ALL_TG_PT from the spec.

Regards,
Martin

-- 
Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] mpathpersist: add all_tg_pt option
  2018-06-06 20:25 ` [PATCH 1/2] mpathpersist: add all_tg_pt option Martin Wilck
@ 2018-06-06 21:56   ` Benjamin Marzinski
  2018-06-07  7:24     ` Martin Wilck
  0 siblings, 1 reply; 7+ messages in thread
From: Benjamin Marzinski @ 2018-06-06 21:56 UTC (permalink / raw)
  To: Martin Wilck; +Cc: device-mapper development, Vijay Chauhan

On Wed, Jun 06, 2018 at 10:25:36PM +0200, Martin Wilck wrote:
> On Fri, 2018-06-01 at 17:22 -0500, Benjamin Marzinski wrote:
> > Some arrays, such as the EMC VNX, don't follow the scsi persistent
> > reservations spec in making key registrations per I_T NEXUS. Instead,
> > the registration is shared by all target ports connected to a given
> > host.  This causes mpathpersist to fail whenever it tries to register
> > a
> > key, since it will receive a registration conflict on some of the
> > paths.
> > 
> > To deal with this, mpathpersist needs to track the hosts that it has
> > done a registration on, and only register once per host. The new
> > "all_tg_pt" multipath.conf option is used to set which arrays need
> > this
> > feature.  I currently don't know if all EMC VNX arrays handle
> > persistent
> > reservations like this, or if it is configurable. A future patch will
> > update the VNX built-in config, if this is indeed their default (or
> > only) setting.
> > 
> > Multipathd doesn't need to worry about this. It is often the case
> > that
> > when a path device comes back, it will still have the keys registered
> > to
> > it. Because of this, multipathd uses register-and-ignore, which means
> > that it won't cause an error if the registration has already happened
> > down a different target port.
> > 
> > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
> > ---
> >  libmpathpersist/mpath_persist.c | 28 ++++++++++++++++++++++------
> >  libmultipath/config.c           |  2 ++
> >  libmultipath/config.h           |  2 ++
> >  libmultipath/defaults.h         |  1 +
> >  libmultipath/dict.c             | 10 ++++++++++
> >  libmultipath/propsel.c          | 15 +++++++++++++++
> >  libmultipath/propsel.h          |  1 +
> >  libmultipath/structs.h          |  7 +++++++
> >  multipath/multipath.conf.5      | 11 +++++++++++
> >  9 files changed, 71 insertions(+), 6 deletions(-)
> 
> The patch looks good to me, but doesn't this mean that mpathpersist
> would now also support persistent reservations with the ALL_TG_PT bit
> set (IIUC, the VNX basically acts as if that bit was always set)? 
> 
> If yes, I think the warning in mpath_prout_reg() about this flag could
> be dropped, and mpathpersist could be extended to support the -Y/
> --param-alltgpt option, no?

I'm a little fuzzy on the --param-alltgpt option. The initial
mpathpersist sumbission didn't include support for it, on the grounds
that supporting it would cause mpathpersist to do a lot of extra work.
What I did cuts down on the amout of work that mpathpersist has to do.
If I could clear that up, I'd happily add the option to mpathpersist.

-Ben

> 
> Otherwise, I'd suggest to give this option a different name, because
> it'd just too easily be confused with ALL_TG_PT from the spec.
> 
> Regards,
> Martin
> 
> -- 
> Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] mpathpersist: add all_tg_pt option
  2018-06-06 21:56   ` Benjamin Marzinski
@ 2018-06-07  7:24     ` Martin Wilck
  2018-06-07 16:20       ` Benjamin Marzinski
  0 siblings, 1 reply; 7+ messages in thread
From: Martin Wilck @ 2018-06-07  7:24 UTC (permalink / raw)
  To: Benjamin Marzinski; +Cc: device-mapper development, Vijay Chauhan

On Wed, 2018-06-06 at 16:56 -0500, Benjamin Marzinski wrote:
> On Wed, Jun 06, 2018 at 10:25:36PM +0200, Martin Wilck wrote:
> > 
> > The patch looks good to me, but doesn't this mean that mpathpersist
> > would now also support persistent reservations with the ALL_TG_PT
> > bit
> > set (IIUC, the VNX basically acts as if that bit was always set)? 
> > 
> > If yes, I think the warning in mpath_prout_reg() about this flag
> > could
> > be dropped, and mpathpersist could be extended to support the -Y/
> > --param-alltgpt option, no?
> 
> I'm a little fuzzy on the --param-alltgpt option. The initial
> mpathpersist sumbission didn't include support for it, on the grounds
> that supporting it would cause mpathpersist to do a lot of extra
> work.
> What I did cuts down on the amout of work that mpathpersist has to
> do.
> If I could clear that up, I'd happily add the option to mpathpersist.
> 

Are you saying you intend to do so? Again, from a user point of view,
without much knowledge about what's going on behind the scenes, seeing
an all_tg_pt option in multipath.conf would make me think that I could 
simply set that option and thus have multipath-tools issue PROUT
commands with the ALL_TG_PT bit set, which isn't true at this point in
time.

Best
Martin

-- 
Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] mpathpersist: add all_tg_pt option
  2018-06-07  7:24     ` Martin Wilck
@ 2018-06-07 16:20       ` Benjamin Marzinski
  0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Marzinski @ 2018-06-07 16:20 UTC (permalink / raw)
  To: Martin Wilck; +Cc: device-mapper development

On Thu, Jun 07, 2018 at 09:24:00AM +0200, Martin Wilck wrote:
> On Wed, 2018-06-06 at 16:56 -0500, Benjamin Marzinski wrote:
> > On Wed, Jun 06, 2018 at 10:25:36PM +0200, Martin Wilck wrote:
> > > 
> > > The patch looks good to me, but doesn't this mean that mpathpersist
> > > would now also support persistent reservations with the ALL_TG_PT
> > > bit
> > > set (IIUC, the VNX basically acts as if that bit was always set)? 
> > > 
> > > If yes, I think the warning in mpath_prout_reg() about this flag
> > > could
> > > be dropped, and mpathpersist could be extended to support the -Y/
> > > --param-alltgpt option, no?
> > 
> > I'm a little fuzzy on the --param-alltgpt option. The initial
> > mpathpersist sumbission didn't include support for it, on the grounds
> > that supporting it would cause mpathpersist to do a lot of extra
> > work.
> > What I did cuts down on the amout of work that mpathpersist has to
> > do.
> > If I could clear that up, I'd happily add the option to mpathpersist.
> > 
> 
> Are you saying you intend to do so? Again, from a user point of view,
> without much knowledge about what's going on behind the scenes, seeing
> an all_tg_pt option in multipath.conf would make me think that I could 
> simply set that option and thus have multipath-tools issue PROUT
> commands with the ALL_TG_PT bit set, which isn't true at this point in
> time.
> 
> Best
> Martin

I get your concern, and I do plan on either allowing the mpathpersist
option or renaming the multipath.conf option so as to not confuse
people. I was hoping to get some reassurance that what I did does
actually make the ALL_TG_TP flag for persistent reservations work.  I
don't have any arrays that seem to actually honor it. They either are
like the VNX, and always treat the reservation as being for all target
ports, or they never do, even when I use the option with sg_persist.  If
I can find an array to test on with multiple target ports that actually
does something in response to the ALL_TG_PT flag, I can check whether my
all_tg_pt code makes this work correctly.

-Ben 

> 
> -- 
> Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-06-07 16:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-01 22:22 [PATCH 1/2] mpathpersist: add all_tg_pt option Benjamin Marzinski
2018-06-01 22:22 ` [PATCH 2/2] libmultipath: remove rbd code Benjamin Marzinski
2018-06-02  3:57   ` Mike Christie
2018-06-06 20:25 ` [PATCH 1/2] mpathpersist: add all_tg_pt option Martin Wilck
2018-06-06 21:56   ` Benjamin Marzinski
2018-06-07  7:24     ` Martin Wilck
2018-06-07 16:20       ` Benjamin Marzinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.