You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1159 lines
30 KiB
1159 lines
30 KiB
--- |
|
libmultipath/checkers.c | 23 - |
|
libmultipath/checkers.h | 5 |
|
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 | 652 ----------------------------------- |
|
libmultipath/checkers/rdac.c | 5 |
|
libmultipath/checkers/readsector0.c | 5 |
|
libmultipath/checkers/tur.c | 5 |
|
libmultipath/discovery.c | 112 ------ |
|
libmultipath/hwtable.c | 14 |
|
libmultipath/structs.h | 1 |
|
multipath.conf.annotated | 4 |
|
multipath/multipath.conf.5 | 3 |
|
multipathd/main.c | 13 |
|
17 files changed, 18 insertions(+), 851 deletions(-) |
|
|
|
Index: multipath-tools-130222/libmultipath/checkers/rbd.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/rbd.c |
|
+++ /dev/null |
|
@@ -1,652 +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 "rados/librados.h" |
|
- |
|
-#include "structs.h" |
|
-#include "checkers.h" |
|
- |
|
-#include "../libmultipath/debug.h" |
|
-#include "../libmultipath/uevent.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; |
|
- int 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(&ct->active, NULL); |
|
- 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_info; |
|
- |
|
- 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; |
|
-} |
|
- |
|
-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; |
|
- 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; |
|
-} |
|
- |
|
-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 alwayws 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) |
|
-{ |
|
- 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, 0, &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) |
|
- |
|
-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); |
|
-} |
|
- |
|
-void *rbd_thread(void *ctx) |
|
-{ |
|
- struct rbd_checker_context *ct = ctx; |
|
- int state; |
|
- |
|
- condlog(3, "rbd%d: thread starting up", ct->rbd_bus_id); |
|
- |
|
- ct->message[0] = '\0'; |
|
- /* This thread can be canceled, so setup clean up */ |
|
- rbd_thread_cleanup_push(ct) |
|
- |
|
- /* 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_mutex_unlock(&ct->lock); |
|
- pthread_cond_signal(&ct->active); |
|
- |
|
- 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) |
|
-{ |
|
- struct timeval now; |
|
- |
|
- gettimeofday(&now, NULL); |
|
- tsp->tv_sec = now.tv_sec; |
|
- tsp->tv_nsec = now.tv_usec * 1000; |
|
- tsp->tv_nsec += 1000000; /* 1 millisecond */ |
|
-} |
|
- |
|
-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); |
|
-} |
|
Index: multipath-tools-130222/multipathd/main.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/multipathd/main.c |
|
+++ multipath-tools-130222/multipathd/main.c |
|
@@ -1291,16 +1291,6 @@ int update_path_groups(struct multipath |
|
return 0; |
|
} |
|
|
|
-void repair_path(struct path * pp) |
|
-{ |
|
- if (pp->state != PATH_DOWN) |
|
- return; |
|
- |
|
- checker_repair(&pp->checker); |
|
- if (strlen(checker_message(&pp->checker))) |
|
- LOG_MSG(1, checker_message(&pp->checker)); |
|
-} |
|
- |
|
void |
|
check_path (struct vectors * vecs, struct path * pp) |
|
{ |
|
@@ -1421,7 +1411,6 @@ check_path (struct vectors * vecs, struc |
|
pp->mpp->failback_tick = 0; |
|
|
|
pp->mpp->stat_path_failures++; |
|
- repair_path(pp); |
|
return; |
|
} |
|
|
|
@@ -1501,7 +1490,7 @@ check_path (struct vectors * vecs, struc |
|
} |
|
|
|
pp->state = newstate; |
|
- repair_path(pp); |
|
+ |
|
|
|
if (pp->mpp->wait_for_udev) |
|
return; |
|
Index: multipath-tools-130222/libmultipath/checkers.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers.c |
|
+++ multipath-tools-130222/libmultipath/checkers.c |
|
@@ -139,13 +139,6 @@ struct checker * add_checker (char * nam |
|
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 = 0; |
|
c->sync = 1; |
|
@@ -214,21 +207,6 @@ void checker_put (struct checker * dst) |
|
free_checker(src); |
|
} |
|
|
|
-void checker_repair (struct checker * c) |
|
-{ |
|
- if (!c || !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; |
|
@@ -297,7 +275,6 @@ void checker_get (struct checker * dst, |
|
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; |
|
Index: multipath-tools-130222/libmultipath/hwtable.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/hwtable.c |
|
+++ multipath-tools-130222/libmultipath/hwtable.c |
|
@@ -1171,20 +1171,6 @@ static struct hwentry default_hw[] = { |
|
.checker_name = TUR, |
|
.dev_loss = 30, |
|
}, |
|
- { |
|
- /* |
|
- * Red Hat |
|
- * |
|
- * Maintainer: Mike Christie |
|
- * Mail: mchristi@redhat.com |
|
- */ |
|
- .vendor = "Ceph", |
|
- .product = "RBD", |
|
- .pgpolicy = FAILOVER, |
|
- .no_path_retry = NO_PATH_RETRY_FAIL, |
|
- .checker_name = RBD, |
|
- .deferred_remove = DEFERRED_REMOVE_ON, |
|
- }, |
|
/* |
|
* Generic NVMe devices |
|
*/ |
|
Index: multipath-tools-130222/libmultipath/checkers/Makefile |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/Makefile |
|
+++ multipath-tools-130222/libmultipath/checkers/Makefile |
|
@@ -14,17 +14,10 @@ LIBS= \ |
|
libcheckhp_sw.so \ |
|
libcheckrdac.so |
|
|
|
-ifeq ($(shell test -r /usr/include/rados/librados.h && echo 1),1) |
|
-LIBS += libcheckrbd.so |
|
-endif |
|
- |
|
CFLAGS += -fPIC -I.. |
|
|
|
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 |
|
|
|
Index: multipath-tools-130222/multipath.conf.annotated |
|
=================================================================== |
|
--- multipath-tools-130222.orig/multipath.conf.annotated |
|
+++ multipath-tools-130222/multipath.conf.annotated |
|
@@ -97,7 +97,7 @@ |
|
# # scope : multipath & multipathd |
|
# # desc : the default method used to determine the paths' state |
|
# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac| |
|
-# cciss_tur|hp_tur|rbd |
|
+# cciss_tur|hp_tur |
|
# # default : directio |
|
# # |
|
# path_checker directio |
|
@@ -493,7 +493,7 @@ |
|
# # scope : multipathd & multipathd |
|
# # desc : path checking algorithm to use to check path state |
|
# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac| |
|
-# # cciss_tur|hp_tur|rbd |
|
+# # cciss_tur|hp_tur |
|
# # |
|
# path_checker directio |
|
# |
|
Index: multipath-tools-130222/multipath/multipath.conf.5 |
|
=================================================================== |
|
--- multipath-tools-130222.orig/multipath/multipath.conf.5 |
|
+++ multipath-tools-130222/multipath/multipath.conf.5 |
|
@@ -287,9 +287,6 @@ Read the first sector with direct I/O. |
|
.B none |
|
Do not check the device, fallback to use the values retrieved from sysfs |
|
.TP |
|
-.B rbd |
|
-Check if the path is in the Ceph blacklist. |
|
-.TP |
|
Default value is \fIdirectio\fR. |
|
.RE |
|
.TP |
|
Index: multipath-tools-130222/libmultipath/checkers.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers.h |
|
+++ multipath-tools-130222/libmultipath/checkers.h |
|
@@ -76,7 +76,6 @@ enum path_check_state { |
|
#define READSECTOR0 "readsector0" |
|
#define CCISS_TUR "cciss_tur" |
|
#define NONE "none" |
|
-#define RBD "rbd" |
|
|
|
#define DEFAULT_CHECKER DIRECTIO |
|
|
|
@@ -107,9 +106,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 */ |
|
}; |
|
@@ -129,7 +125,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 *); |
|
Index: multipath-tools-130222/libmultipath/checkers/cciss_tur.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/cciss_tur.c |
|
+++ multipath-tools-130222/libmultipath/checkers/cciss_tur.c |
|
@@ -63,11 +63,6 @@ void libcheck_free (struct checker * c) |
|
return; |
|
} |
|
|
|
-void libcheck_repair (struct checker * c) |
|
-{ |
|
- return; |
|
-} |
|
- |
|
extern int |
|
libcheck_check (struct checker * c) |
|
{ |
|
Index: multipath-tools-130222/libmultipath/checkers/directio.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/directio.c |
|
+++ multipath-tools-130222/libmultipath/checkers/directio.c |
|
@@ -116,11 +116,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) |
|
{ |
|
Index: multipath-tools-130222/libmultipath/checkers/emc_clariion.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/emc_clariion.c |
|
+++ multipath-tools-130222/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, }; |
|
Index: multipath-tools-130222/libmultipath/checkers/hp_sw.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/hp_sw.c |
|
+++ multipath-tools-130222/libmultipath/checkers/hp_sw.c |
|
@@ -44,11 +44,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) |
|
Index: multipath-tools-130222/libmultipath/checkers/rdac.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/rdac.c |
|
+++ multipath-tools-130222/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) |
|
Index: multipath-tools-130222/libmultipath/checkers/readsector0.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/readsector0.c |
|
+++ multipath-tools-130222/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]; |
|
Index: multipath-tools-130222/libmultipath/checkers/tur.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/checkers/tur.c |
|
+++ multipath-tools-130222/libmultipath/checkers/tur.c |
|
@@ -187,11 +187,6 @@ void libcheck_free (struct checker * c) |
|
return; |
|
} |
|
|
|
-void libcheck_repair (struct checker * c) |
|
-{ |
|
- return; |
|
-} |
|
- |
|
#define TUR_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args); |
|
|
|
int |
|
Index: multipath-tools-130222/libmultipath/discovery.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/discovery.c |
|
+++ multipath-tools-130222/libmultipath/discovery.c |
|
@@ -922,21 +922,6 @@ nvme_sysfs_pathinfo (struct path * pp) |
|
} |
|
|
|
static int |
|
-rbd_sysfs_pathinfo (struct path * pp) |
|
-{ |
|
- 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(conf->hwtable, pp->vendor_id, pp->product_id, NULL); |
|
- return 0; |
|
-} |
|
- |
|
-static int |
|
ccw_sysfs_pathinfo (struct path * pp) |
|
{ |
|
struct udev_device *parent; |
|
@@ -1151,8 +1136,6 @@ sysfs_pathinfo(struct path * pp) |
|
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; |
|
|
|
@@ -1167,9 +1150,6 @@ sysfs_pathinfo(struct path * pp) |
|
} else if (pp->bus == SYSFS_BUS_CCISS) { |
|
if (cciss_sysfs_pathinfo(pp)) |
|
return 1; |
|
- } else if (pp->bus == SYSFS_BUS_RBD) { |
|
- if (rbd_sysfs_pathinfo(pp)) |
|
- return 1; |
|
} else if (pp->bus == SYSFS_BUS_NVME) { |
|
if (nvme_sysfs_pathinfo(pp)) |
|
return 1; |
|
@@ -1275,55 +1255,6 @@ get_prio (struct path * pp) |
|
return 0; |
|
} |
|
|
|
-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(conf->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) { |
|
- ret = 0; |
|
- } else { |
|
- condlog(0, "%s: wwid overflow", pp->dev); |
|
- ret = -EOVERFLOW; |
|
- } |
|
- |
|
-free_dev: |
|
- udev_device_unref(rbd_bus_dev); |
|
- return ret; |
|
-} |
|
- |
|
/* |
|
* Mangle string of length *len starting at start |
|
* by removing character sequence "00" (hex for a 0 byte), |
|
@@ -1405,7 +1336,6 @@ get_uid (struct path * pp, struct udev_d |
|
{ |
|
char *c; |
|
const char *value; |
|
- int ret; |
|
|
|
if (!pp->uid_attribute) |
|
select_getuid(pp); |
|
@@ -1416,34 +1346,22 @@ get_uid (struct path * pp, struct udev_d |
|
} |
|
|
|
memset(pp->wwid, 0, WWID_SIZE); |
|
- if (pp->bus == SYSFS_BUS_RBD) { |
|
- ret = get_rbd_uid(pp); |
|
- if (ret) { |
|
- condlog(1, "%s: failed to get sysfs uid: %s", |
|
- pp->dev, strerror(-ret)); |
|
- pp->missing_udev_info = INFO_MISSING; |
|
- pp->tick = conf->retrigger_delay; |
|
- } |
|
+ value = udev_device_get_property_value(udev, pp->uid_attribute); |
|
+ if ((!value || strlen(value) == 0) && conf->cmd == CMD_VALID_PATH) |
|
+ value = getenv(pp->uid_attribute); |
|
+ if (value && strlen(value)) { |
|
+ size_t len = strlcpy(pp->wwid, value, WWID_SIZE); |
|
+ if (len > WWID_SIZE && |
|
+ !fix_broken_nvme_wwid(pp, value, WWID_SIZE)) |
|
+ condlog(0, "%s: wwid overflow", pp->dev); |
|
+ condlog(4, "%s: got wwid of '%s'", pp->dev, pp->wwid); |
|
+ pp->missing_udev_info = INFO_OK; |
|
+ pp->tick = 0; |
|
} else { |
|
- value = udev_device_get_property_value(udev, |
|
- pp->uid_attribute); |
|
- if ((!value || strlen(value) == 0) && |
|
- conf->cmd == CMD_VALID_PATH) |
|
- value = getenv(pp->uid_attribute); |
|
- if (value && strlen(value)) { |
|
- size_t len = strlcpy(pp->wwid, value, WWID_SIZE); |
|
- if (len > WWID_SIZE && |
|
- !fix_broken_nvme_wwid(pp, value, WWID_SIZE)) |
|
- condlog(0, "%s: wwid overflow", pp->dev); |
|
- condlog(4, "%s: got wwid of '%s'", pp->dev, pp->wwid); |
|
- pp->missing_udev_info = INFO_OK; |
|
- pp->tick = 0; |
|
- } else { |
|
- condlog(3, "%s: no %s attribute", pp->dev, |
|
- pp->uid_attribute); |
|
- pp->missing_udev_info = INFO_MISSING; |
|
- pp->tick = conf->retrigger_delay; |
|
- } |
|
+ condlog(3, "%s: no %s attribute", pp->dev, |
|
+ pp->uid_attribute); |
|
+ pp->missing_udev_info = INFO_MISSING; |
|
+ pp->tick = conf->retrigger_delay; |
|
} |
|
|
|
/* Strip any trailing blanks */ |
|
Index: multipath-tools-130222/libmultipath/structs.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/structs.h |
|
+++ multipath-tools-130222/libmultipath/structs.h |
|
@@ -60,7 +60,6 @@ enum sysfs_buses { |
|
SYSFS_BUS_IDE, |
|
SYSFS_BUS_CCW, |
|
SYSFS_BUS_CCISS, |
|
- SYSFS_BUS_RBD, |
|
SYSFS_BUS_NVME, |
|
}; |
|
|
|
|