From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 1 Jun 2018 16:30:44 -0500
Subject: [PATCH] libmultipath: remove rbd code

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

