aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch')
-rw-r--r--meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch1093
1 files changed, 1093 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch b/meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch
new file mode 100644
index 0000000000..8d1954725c
--- /dev/null
+++ b/meta-oe/recipes-support/multipath-tools/files/0016-libmultipath-remove-rbd-code.patch
@@ -0,0 +1,1093 @@
+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
+