From 37dccf5dea97b3c1fc1ea563894d18b7dfea3cb1 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 21 Jun 2013 11:16:29 -0500 Subject: [PATCH] device-mapper-multipath-0.4.9-52 Add 0038-RHBZ-799860-netapp-config.patch Add 0039-RH-detect-prio-fix.patch * Don't autodetect ALUA prioritizer unless it actually can get a priority Add 0040-RH-bindings-fix.patch * Do a better job of trying to get the first free user_friendly_name Add 0041-RH-check-for-erofs.patch * Don't create/reload a device read-only unless doing it read/write fails with EROFS Remove 0017-RH-fix-sigusr1.patch * fix signal handling upstream way instead Add 0042-UP-fix-signal-handling.patch * uxlsnr now handles all the signals sent to multipathd. This makes its signal handling posix compliant, and harder to mess up. Add 0043-RH-signal-waiter.patch * ioctl isn't a pthread cancellation point. Send a signal to the waiter thread to break out of waiting in ioctl for a dm event. --- 0017-RH-fix-sigusr1.patch | 82 ----- 0038-RHBZ-799860-netapp-config.patch | 16 + 0039-RH-detect-prio-fix.patch | 28 ++ 0040-RH-bindings-fix.patch | 101 ++++++ 0041-RH-check-for-erofs.patch | 121 +++++++ 0042-UP-fix-signal-handling.patch | 493 +++++++++++++++++++++++++++ 0043-RH-signal-waiter.patch | 71 ++++ device-mapper-multipath.spec | 36 +- 8 files changed, 863 insertions(+), 85 deletions(-) delete mode 100644 0017-RH-fix-sigusr1.patch create mode 100644 0038-RHBZ-799860-netapp-config.patch create mode 100644 0039-RH-detect-prio-fix.patch create mode 100644 0040-RH-bindings-fix.patch create mode 100644 0041-RH-check-for-erofs.patch create mode 100644 0042-UP-fix-signal-handling.patch create mode 100644 0043-RH-signal-waiter.patch diff --git a/0017-RH-fix-sigusr1.patch b/0017-RH-fix-sigusr1.patch deleted file mode 100644 index 8db973c..0000000 --- a/0017-RH-fix-sigusr1.patch +++ /dev/null @@ -1,82 +0,0 @@ ---- - libmultipath/log_pthread.c | 3 +++ - multipathd/main.c | 12 +++++------- - 2 files changed, 8 insertions(+), 7 deletions(-) - -Index: multipath-tools-130222/multipathd/main.c -=================================================================== ---- multipath-tools-130222.orig/multipathd/main.c -+++ multipath-tools-130222/multipathd/main.c -@@ -1473,7 +1473,9 @@ sighup (int sig) - if (running_state != DAEMON_RUNNING) - return; - -+ lock(gvecs->lock); - reconfigure(gvecs); -+ unlock(gvecs->lock); - - #ifdef _DEBUG_ - dbg_free_final(NULL); -@@ -1487,16 +1489,9 @@ sigend (int sig) - } - - static void --sigusr1 (int sig) --{ -- condlog(3, "SIGUSR1 received"); --} -- --static void - signal_init(void) - { - signal_set(SIGHUP, sighup); -- signal_set(SIGUSR1, sigusr1); - signal_set(SIGINT, sigend); - signal_set(SIGTERM, sigend); - signal(SIGPIPE, SIG_IGN); -@@ -1652,6 +1647,7 @@ child (void * param) - */ - running_state = DAEMON_CONFIGURE; - -+ block_signal(SIGHUP, &set); - lock(vecs->lock); - if (configure(vecs, 1)) { - unlock(vecs->lock); -@@ -1659,6 +1655,7 @@ child (void * param) - exit(1); - } - unlock(vecs->lock); -+ pthread_sigmask(SIG_SETMASK, &set, NULL); - - /* - * start threads -@@ -1691,6 +1688,7 @@ child (void * param) - */ - running_state = DAEMON_SHUTDOWN; - pthread_sigmask(SIG_UNBLOCK, &set, NULL); -+ block_signal(SIGUSR1, NULL); - block_signal(SIGHUP, NULL); - lock(vecs->lock); - if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF) -Index: multipath-tools-130222/libmultipath/log_pthread.c -=================================================================== ---- multipath-tools-130222.orig/libmultipath/log_pthread.c -+++ multipath-tools-130222/libmultipath/log_pthread.c -@@ -55,14 +55,17 @@ void log_safe (int prio, const char * fm - - void log_thread_flush (void) - { -+ sigset_t old; - int empty; - - do { -+ block_signal(SIGUSR1, &old); - pthread_mutex_lock(&logq_lock); - empty = log_dequeue(la->buff); - pthread_mutex_unlock(&logq_lock); - if (!empty) - log_syslog(la->buff); -+ pthread_sigmask(SIG_SETMASK, &old, NULL); - } while (empty == 0); - } - diff --git a/0038-RHBZ-799860-netapp-config.patch b/0038-RHBZ-799860-netapp-config.patch new file mode 100644 index 0000000..3b91f9b --- /dev/null +++ b/0038-RHBZ-799860-netapp-config.patch @@ -0,0 +1,16 @@ +--- + libmultipath/hwtable.c | 1 + + 1 file changed, 1 insertion(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -794,6 +794,7 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ONTAP, + .prio_args = NULL, + .retain_hwhandler = RETAIN_HWHANDLER_ON, ++ .user_friendly_names = USER_FRIENDLY_NAMES_OFF, + .detect_prio = DETECT_PRIO_ON, + }, + /* diff --git a/0039-RH-detect-prio-fix.patch b/0039-RH-detect-prio-fix.patch new file mode 100644 index 0000000..941a570 --- /dev/null +++ b/0039-RH-detect-prio-fix.patch @@ -0,0 +1,28 @@ +--- + libmultipath/propsel.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -384,10 +384,17 @@ select_getuid (struct path * pp) + void + detect_prio(struct path * pp) + { ++ int ret; + struct prio *p = &pp->prio; + +- if (get_target_port_group_support(pp->fd) > 0) +- prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); ++ if (get_target_port_group_support(pp->fd) <= 0) ++ return; ++ ret = get_target_port_group(pp->fd); ++ if (ret < 0) ++ return; ++ if (get_asymmetric_access_state(pp->fd, ret) < 0) ++ return; ++ prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); + } + + extern int diff --git a/0040-RH-bindings-fix.patch b/0040-RH-bindings-fix.patch new file mode 100644 index 0000000..c56f352 --- /dev/null +++ b/0040-RH-bindings-fix.patch @@ -0,0 +1,101 @@ +--- + libmultipath/alias.c | 39 ++++++++++++++++++++++++++++++--------- + 1 file changed, 30 insertions(+), 9 deletions(-) + +Index: multipath-tools-130222/libmultipath/alias.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/alias.c ++++ multipath-tools-130222/libmultipath/alias.c +@@ -46,11 +46,11 @@ format_devname(char *name, int id, int l + memset(name,0, len); + strcpy(name, prefix); + for (pos = len - 1; pos >= prefix_len; pos--) { ++ id--; + name[pos] = 'a' + id % 26; + if (id < 26) + break; + id /= 26; +- id--; + } + memmove(name + prefix_len, name + pos, len - pos); + name[prefix_len + len - pos] = '\0'; +@@ -66,13 +66,22 @@ scan_devname(char *alias, char *prefix) + if (!prefix || strncmp(alias, prefix, strlen(prefix))) + return -1; + ++ if (strlen(alias) == strlen(prefix)) ++ return -1; ++ ++ if (strlen(alias) > strlen(prefix) + 7) ++ /* id of 'aaaaaaaa' overflows int */ ++ return -1; ++ + c = alias + strlen(prefix); + while (*c != '\0' && *c != ' ' && *c != '\t') { ++ if (*c < 'a' || *c > 'z') ++ return -1; + i = *c - 'a'; + n = ( n * 26 ) + i; ++ if (n < 0) ++ return -1; + c++; +- if (*c < 'a' || *c > 'z') +- break; + n++; + } + +@@ -84,7 +93,9 @@ lookup_binding(FILE *f, char *map_wwid, + { + char buf[LINE_MAX]; + unsigned int line_nr = 0; +- int id = 0; ++ int id = 1; ++ int biggest_id = 1; ++ int smallest_bigger_id = INT_MAX; + + *map_alias = NULL; + +@@ -100,8 +111,12 @@ lookup_binding(FILE *f, char *map_wwid, + if (!alias) /* blank line */ + continue; + curr_id = scan_devname(alias, prefix); +- if (curr_id >= id) +- id = curr_id + 1; ++ if (curr_id == id) ++ id++; ++ if (curr_id > biggest_id) ++ biggest_id = curr_id; ++ if (curr_id > id && curr_id < smallest_bigger_id) ++ smallest_bigger_id = curr_id; + wwid = strtok(NULL, " \t"); + if (!wwid){ + condlog(3, +@@ -116,11 +131,17 @@ lookup_binding(FILE *f, char *map_wwid, + if (*map_alias == NULL) + condlog(0, "Cannot copy alias from bindings " + "file : %s", strerror(errno)); +- return id; ++ return 0; + } + } + condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); +- return id; ++ if (id < 0) { ++ condlog(0, "no more available user_friendly_names"); ++ return 0; ++ } ++ if (id < smallest_bigger_id) ++ return id; ++ return biggest_id + 1; + } + + static int +@@ -254,7 +275,7 @@ get_user_friendly_alias(char *wwid, char + return NULL; + } + +- if (!alias && can_write && !bindings_read_only) ++ if (!alias && can_write && !bindings_read_only && id) + alias = allocate_binding(fd, wwid, id, prefix); + + fclose(f); diff --git a/0041-RH-check-for-erofs.patch b/0041-RH-check-for-erofs.patch new file mode 100644 index 0000000..d29d78d --- /dev/null +++ b/0041-RH-check-for-erofs.patch @@ -0,0 +1,121 @@ +--- + libmultipath/configure.c | 7 ------ + libmultipath/devmapper.c | 53 ++++++++++++++++++++++------------------------- + libmultipath/devmapper.h | 2 - + 3 files changed, 25 insertions(+), 37 deletions(-) + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -384,24 +384,17 @@ domap (struct multipath * mpp, char * pa + + r = dm_addmap_create(mpp, params); + +- if (!r) +- r = dm_addmap_create_ro(mpp, params); +- + lock_multipath(mpp, 0); + break; + + case ACT_RELOAD: + r = dm_addmap_reload(mpp, params); +- if (!r) +- r = dm_addmap_reload_ro(mpp, params); + if (r) + r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias); + break; + + case ACT_RESIZE: + r = dm_addmap_reload(mpp, params); +- if (!r) +- r = dm_addmap_reload_ro(mpp, params); + if (r) + r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1); + break; +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -298,42 +298,39 @@ dm_addmap (int task, const char *target, + return r; + } + +-static int +-_dm_addmap_create (struct multipath *mpp, char * params, int ro) { +- int r; +- r = dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro); +- /* +- * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD. +- * Failing the second part leaves an empty map. Clean it up. +- */ +- if (!r && dm_map_present(mpp->alias)) { +- condlog(3, "%s: failed to load map (a path might be in use)", +- mpp->alias); +- dm_flush_map_nosync(mpp->alias); ++extern int ++dm_addmap_create (struct multipath *mpp, char * params) { ++ int ro; ++ ++ for (ro = 0; ro <= 1; ro++) { ++ int err; ++ ++ if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro)) ++ return 1; ++ /* ++ * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD. ++ * Failing the second part leaves an empty map. Clean it up. ++ */ ++ err = errno; ++ if (dm_map_present(mpp->alias)) { ++ condlog(3, "%s: failed to load map (a path might be in use)", mpp->alias); ++ dm_flush_map_nosync(mpp->alias); ++ } ++ if (err != EROFS) ++ break; + } +- return r; ++ return 0; + } + + #define ADDMAP_RW 0 + #define ADDMAP_RO 1 + + extern int +-dm_addmap_create (struct multipath *mpp, char *params) { +- return _dm_addmap_create(mpp, params, ADDMAP_RW); +-} +- +-extern int +-dm_addmap_create_ro (struct multipath *mpp, char *params) { +- return _dm_addmap_create(mpp, params, ADDMAP_RO); +-} +- +-extern int + dm_addmap_reload (struct multipath *mpp, char *params) { +- return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW); +-} +- +-extern int +-dm_addmap_reload_ro (struct multipath *mpp, char *params) { ++ if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW)) ++ return 1; ++ if (errno != EROFS) ++ return 0; + return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO); + } + +Index: multipath-tools-130222/libmultipath/devmapper.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.h ++++ multipath-tools-130222/libmultipath/devmapper.h +@@ -12,9 +12,7 @@ int dm_drv_version (unsigned int * versi + int dm_simplecmd_flush (int, const char *, int); + int dm_simplecmd_noflush (int, const char *); + int dm_addmap_create (struct multipath *mpp, char *params); +-int dm_addmap_create_ro (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params); +-int dm_addmap_reload_ro (struct multipath *mpp, char *params); + int dm_map_present (const char *); + int dm_get_map(char *, unsigned long long *, char *); + int dm_get_status(char *, char *); diff --git a/0042-UP-fix-signal-handling.patch b/0042-UP-fix-signal-handling.patch new file mode 100644 index 0000000..4b4b40b --- /dev/null +++ b/0042-UP-fix-signal-handling.patch @@ -0,0 +1,493 @@ +--- + libmultipath/file.c | 4 +- + libmultipath/lock.c | 9 ---- + libmultipath/lock.h | 1 + libmultipath/log_pthread.c | 22 ----------- + libmultipath/waiter.c | 2 - + multipathd/cli_handlers.c | 4 +- + multipathd/main.c | 90 ++++++++++++++++++++------------------------- + multipathd/main.h | 3 + + multipathd/uxlsnr.c | 21 +++++++--- + multipathd/uxlsnr.h | 3 + + 10 files changed, 65 insertions(+), 94 deletions(-) + +Index: multipath-tools-130222/libmultipath/file.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/file.c ++++ multipath-tools-130222/libmultipath/file.c +@@ -98,7 +98,7 @@ lock_file(int fd, char *file_name) + sigaddset(&set, SIGALRM); + + sigaction(SIGALRM, &act, &oldact); +- sigprocmask(SIG_UNBLOCK, &set, &oldset); ++ pthread_sigmask(SIG_UNBLOCK, &set, &oldset); + + alarm(FILE_TIMEOUT); + err = fcntl(fd, F_SETLKW, &lock); +@@ -112,7 +112,7 @@ lock_file(int fd, char *file_name) + condlog(0, "%s is locked. Giving up.", file_name); + } + +- sigprocmask(SIG_SETMASK, &oldset, NULL); ++ pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigaction(SIGALRM, &oldact, NULL); + return err; + } +Index: multipath-tools-130222/libmultipath/lock.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/lock.c ++++ multipath-tools-130222/libmultipath/lock.c +@@ -1,16 +1,7 @@ + #include +-#include + #include "lock.h" + #include + +-void block_signal (int signum, sigset_t *old) +-{ +- sigset_t set; +- sigemptyset(&set); +- sigaddset(&set, signum); +- pthread_sigmask(SIG_BLOCK, &set, old); +-} +- + void cleanup_lock (void * data) + { + unlock ((*(struct mutex_lock *)data)); +Index: multipath-tools-130222/libmultipath/lock.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/lock.h ++++ multipath-tools-130222/libmultipath/lock.h +@@ -29,6 +29,5 @@ struct mutex_lock { + #endif + + void cleanup_lock (void * data); +-void block_signal(int signum, sigset_t *old); + + #endif /* _LOCK_H */ +Index: multipath-tools-130222/libmultipath/log_pthread.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/log_pthread.c ++++ multipath-tools-130222/libmultipath/log_pthread.c +@@ -22,26 +22,13 @@ pthread_cond_t logev_cond; + + int logq_running; + +-static void +-sigusr1 (int sig) +-{ +- pthread_mutex_lock(&logq_lock); +- log_reset("multipathd"); +- pthread_mutex_unlock(&logq_lock); +-} +- + void log_safe (int prio, const char * fmt, va_list ap) + { +- sigset_t old; +- + if (log_thr == (pthread_t)0) { + syslog(prio, fmt, ap); + return; + } + +- block_signal(SIGUSR1, &old); +- block_signal(SIGHUP, NULL); +- + pthread_mutex_lock(&logq_lock); + log_enqueue(prio, fmt, ap); + pthread_mutex_unlock(&logq_lock); +@@ -49,8 +36,6 @@ void log_safe (int prio, const char * fm + pthread_mutex_lock(&logev_lock); + pthread_cond_signal(&logev_cond); + pthread_mutex_unlock(&logev_lock); +- +- pthread_sigmask(SIG_SETMASK, &old, NULL); + } + + void log_thread_flush (void) +@@ -81,15 +66,8 @@ static void flush_logqueue (void) + + static void * log_thread (void * et) + { +- struct sigaction sig; + int running; + +- sig.sa_handler = sigusr1; +- sigemptyset(&sig.sa_mask); +- sig.sa_flags = 0; +- if (sigaction(SIGUSR1, &sig, NULL) < 0) +- logdbg(stderr, "Cannot set signal handler"); +- + pthread_mutex_lock(&logev_lock); + logq_running = 1; + pthread_mutex_unlock(&logev_lock); +Index: multipath-tools-130222/libmultipath/waiter.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/waiter.c ++++ multipath-tools-130222/libmultipath/waiter.c +@@ -157,8 +157,6 @@ void *waitevent (void *et) + waiter = (struct event_thread *)et; + pthread_cleanup_push(free_waiter, et); + +- block_signal(SIGUSR1, NULL); +- block_signal(SIGHUP, NULL); + while (1) { + r = waiteventloop(waiter); + +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -939,8 +939,8 @@ int + cli_shutdown (void * v, char ** reply, int * len, void * data) + { + condlog(3, "shutdown (operator)"); +- +- return exit_daemon(0); ++ exit_daemon(); ++ return 0; + } + + int +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -52,6 +53,7 @@ + #include + #include + #include ++#include + + #include "main.h" + #include "pidfile.h" +@@ -81,13 +83,11 @@ struct mpath_event_param + + unsigned int mpath_mx_alloc_len; + +-pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER; +-pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER; +- + int logsink; + enum daemon_status running_state; + pid_t daemon_pid; + ++static sem_t exit_sem; + /* + * global copy of vecs for use in sig handlers + */ +@@ -838,9 +838,6 @@ out: + static void * + ueventloop (void * ap) + { +- block_signal(SIGUSR1, NULL); +- block_signal(SIGHUP, NULL); +- + if (uevent_listen()) + condlog(0, "error starting uevent listener"); + +@@ -850,9 +847,6 @@ ueventloop (void * ap) + static void * + uevqloop (void * ap) + { +- block_signal(SIGUSR1, NULL); +- block_signal(SIGHUP, NULL); +- + if (uevent_dispatch(&uev_trigger, ap)) + condlog(0, "error starting uevent dispatcher"); + +@@ -861,9 +855,6 @@ uevqloop (void * ap) + static void * + uxlsnrloop (void * ap) + { +- block_signal(SIGUSR1, NULL); +- block_signal(SIGHUP, NULL); +- + if (cli_init()) + return NULL; + +@@ -913,18 +904,10 @@ uxlsnrloop (void * ap) + return NULL; + } + +-int +-exit_daemon (int status) ++void ++exit_daemon (void) + { +- if (status != 0) +- fprintf(stderr, "bad exit status. see daemon.log\n"); +- +- if (running_state != DAEMON_SHUTDOWN) { +- pthread_mutex_lock(&exit_mutex); +- pthread_cond_signal(&exit_cond); +- pthread_mutex_unlock(&exit_mutex); +- } +- return status; ++ sem_post(&exit_sem); + } + + const char * +@@ -1287,7 +1270,6 @@ checkerloop (void *ap) + struct path *pp; + int count = 0; + unsigned int i; +- sigset_t old; + + mlockall(MCL_CURRENT | MCL_FUTURE); + vecs = (struct vectors *)ap; +@@ -1301,7 +1283,6 @@ checkerloop (void *ap) + } + + while (1) { +- block_signal(SIGHUP, &old); + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(vecs->lock); + pthread_testcancel(); +@@ -1325,7 +1306,6 @@ checkerloop (void *ap) + } + + lock_cleanup_pop(vecs->lock); +- pthread_sigmask(SIG_SETMASK, &old, NULL); + sleep(1); + } + return NULL; +@@ -1485,36 +1465,56 @@ signal_set(int signo, void (*func) (int) + return (osig.sa_handler); + } + ++void ++handle_signals(void) ++{ ++ if (reconfig_sig && running_state == DAEMON_RUNNING) { ++ condlog(2, "reconfigure (signal)"); ++ pthread_cleanup_push(cleanup_lock, ++ &gvecs->lock); ++ lock(gvecs->lock); ++ pthread_testcancel(); ++ reconfigure(gvecs); ++ lock_cleanup_pop(gvecs->lock); ++ } ++ if (log_reset_sig) { ++ condlog(2, "reset log (signal)"); ++ pthread_mutex_lock(&logq_lock); ++ log_reset("multipathd"); ++ pthread_mutex_unlock(&logq_lock); ++ } ++ reconfig_sig = 0; ++ log_reset_sig = 0; ++} ++ + static void + sighup (int sig) + { +- condlog(2, "reconfigure (SIGHUP)"); +- +- if (running_state != DAEMON_RUNNING) +- return; +- +- reconfigure(gvecs); +- +-#ifdef _DEBUG_ +- dbg_free_final(NULL); +-#endif ++ reconfig_sig = 1; + } + + static void + sigend (int sig) + { +- exit_daemon(0); ++ exit_daemon(); + } + + static void + sigusr1 (int sig) + { +- condlog(3, "SIGUSR1 received"); ++ log_reset_sig = 1; + } + + static void + signal_init(void) + { ++ sigset_t set; ++ ++ sigemptyset(&set); ++ sigaddset(&set, SIGHUP); ++ sigaddset(&set, SIGUSR1); ++ pthread_sigmask(SIG_BLOCK, &set, NULL); ++ + signal_set(SIGHUP, sighup); + signal_set(SIGUSR1, sigusr1); + signal_set(SIGINT, sigend); +@@ -1587,10 +1587,11 @@ child (void * param) + struct vectors * vecs; + struct multipath * mpp; + int i; +- sigset_t set; + int rc, pid_rc; + + mlockall(MCL_CURRENT | MCL_FUTURE); ++ sem_init(&exit_sem, 0, 0); ++ signal_init(); + + setup_thread_attr(&misc_attr, 64 * 1024, 1); + setup_thread_attr(&waiter_attr, 32 * 1024, 1); +@@ -1650,7 +1651,6 @@ child (void * param) + if (!vecs) + exit(1); + +- signal_init(); + setscheduler(); + set_oom_adj(); + +@@ -1693,25 +1693,17 @@ child (void * param) + } + pthread_attr_destroy(&misc_attr); + +- pthread_mutex_lock(&exit_mutex); + /* Startup complete, create logfile */ + pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid); + /* Ignore errors, we can live without */ + + running_state = DAEMON_RUNNING; +- pthread_cond_wait(&exit_cond, &exit_mutex); +- /* Need to block these to avoid deadlocking */ +- sigemptyset(&set); +- sigaddset(&set, SIGTERM); +- sigaddset(&set, SIGINT); +- pthread_sigmask(SIG_BLOCK, &set, NULL); + + /* + * exit path + */ ++ while(sem_wait(&exit_sem) != 0); /* Do nothing */ + running_state = DAEMON_SHUTDOWN; +- pthread_sigmask(SIG_UNBLOCK, &set, NULL); +- block_signal(SIGHUP, NULL); + lock(vecs->lock); + if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF) + vector_foreach_slot(vecs->mpvec, mpp, i) +Index: multipath-tools-130222/multipathd/main.h +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.h ++++ multipath-tools-130222/multipathd/main.h +@@ -16,7 +16,7 @@ struct prin_resp; + + extern pid_t daemon_pid; + +-int exit_daemon(int); ++void exit_daemon(void); + const char * daemon_status(void); + int reconfigure (struct vectors *); + int ev_add_path (struct path *, struct vectors *); +@@ -35,5 +35,6 @@ int mpath_pr_event_handle(struct path *p + void * mpath_pr_event_handler_fn (void * ); + int update_map_pr(struct multipath *mpp); + void * mpath_pr_event_handler_fn (void * pathp ); ++void handle_signals(void); + + #endif /* MAIN_H */ +Index: multipath-tools-130222/multipathd/uxlsnr.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/uxlsnr.c ++++ multipath-tools-130222/multipathd/uxlsnr.c +@@ -8,6 +8,7 @@ + /* + * A simple domain socket listener + */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -19,20 +20,21 @@ + #include + #include + #include +- ++#include + #include +- + #include + #include + #include + #include ++#include + #include + #include + ++#include "main.h" + #include "cli.h" + #include "uxlsnr.h" + +-#define SLEEP_TIME 5000 ++struct timespec sleep_time = {5, 0}; + + struct client { + int fd; +@@ -42,6 +44,8 @@ struct client { + static struct client *clients; + static unsigned num_clients; + struct pollfd *polls; ++volatile sig_atomic_t reconfig_sig = 0; ++volatile sig_atomic_t log_reset_sig = 0; + + /* + * handle a new client joining +@@ -104,6 +108,7 @@ void * uxsock_listen(int (*uxsock_trigge + int rlen; + char *inbuf; + char *reply; ++ sigset_t mask; + + ux_sock = ux_socket_listen(DEFAULT_SOCKET); + +@@ -115,7 +120,9 @@ void * uxsock_listen(int (*uxsock_trigge + pthread_cleanup_push(uxsock_cleanup, NULL); + + polls = (struct pollfd *)MALLOC(0); +- ++ pthread_sigmask(SIG_SETMASK, NULL, &mask); ++ sigdelset(&mask, SIGHUP); ++ sigdelset(&mask, SIGUSR1); + while (1) { + struct client *c; + int i, poll_count; +@@ -132,11 +139,13 @@ void * uxsock_listen(int (*uxsock_trigge + } + + /* most of our life is spent in this call */ +- poll_count = poll(polls, i, SLEEP_TIME); ++ poll_count = ppoll(polls, i, &sleep_time, &mask); + + if (poll_count == -1) { +- if (errno == EINTR) ++ if (errno == EINTR) { ++ handle_signals(); + continue; ++ } + + /* something went badly wrong! */ + condlog(0, "poll"); +Index: multipath-tools-130222/multipathd/uxlsnr.h +=================================================================== +--- multipath-tools-130222.orig/multipathd/uxlsnr.h ++++ multipath-tools-130222/multipathd/uxlsnr.h +@@ -4,5 +4,8 @@ + void * uxsock_listen(int (*uxsock_trigger) + (char *, char **, int *, void *), + void * trigger_data); ++ ++extern volatile sig_atomic_t reconfig_sig; ++extern volatile sig_atomic_t log_reset_sig; + #endif + diff --git a/0043-RH-signal-waiter.patch b/0043-RH-signal-waiter.patch new file mode 100644 index 0000000..a1a63ea --- /dev/null +++ b/0043-RH-signal-waiter.patch @@ -0,0 +1,71 @@ +--- + libmultipath/waiter.c | 9 +++++++++ + multipathd/main.c | 8 ++++++++ + 2 files changed, 17 insertions(+) + +Index: multipath-tools-130222/libmultipath/waiter.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/waiter.c ++++ multipath-tools-130222/libmultipath/waiter.c +@@ -57,6 +57,7 @@ void stop_waiter_thread (struct multipat + thread = mpp->waiter; + mpp->waiter = (pthread_t)0; + pthread_cancel(thread); ++ pthread_kill(thread, SIGUSR2); + } + + /* +@@ -65,6 +66,7 @@ void stop_waiter_thread (struct multipat + */ + int waiteventloop (struct event_thread *waiter) + { ++ sigset_t set, oldset; + int event_nr; + int r; + +@@ -97,8 +99,15 @@ int waiteventloop (struct event_thread * + dm_task_no_open_count(waiter->dmt); + + /* wait */ ++ sigemptyset(&set); ++ sigaddset(&set, SIGUSR2); ++ pthread_sigmask(SIG_UNBLOCK, &set, &oldset); ++ ++ pthread_testcancel(); + r = dm_task_run(waiter->dmt); ++ pthread_testcancel(); + ++ pthread_sigmask(SIG_SETMASK, &oldset, NULL); + dm_task_destroy(waiter->dmt); + waiter->dmt = NULL; + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -1506,6 +1506,12 @@ sigusr1 (int sig) + } + + static void ++sigusr2 (int sig) ++{ ++ condlog(3, "SIGUSR2 received"); ++} ++ ++static void + signal_init(void) + { + sigset_t set; +@@ -1513,10 +1519,12 @@ signal_init(void) + sigemptyset(&set); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGUSR1); ++ sigaddset(&set, SIGUSR2); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + signal_set(SIGHUP, sighup); + signal_set(SIGUSR1, sigusr1); ++ signal_set(SIGUSR2, sigusr2); + signal_set(SIGINT, sigend); + signal_set(SIGTERM, sigend); + signal(SIGPIPE, SIG_IGN); diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index d7f8b6b..ed976e0 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 51%{?dist} +Release: 52%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -24,7 +24,7 @@ Patch0013: 0013-RHBZ-883981-cleanup-rpmdiff-issues.patch Patch0014: 0014-RH-handle-other-sector-sizes.patch Patch0015: 0015-RH-fix-output-buffer.patch Patch0016: 0016-RH-dont-print-ghost-messages.patch -Patch0017: 0017-RH-fix-sigusr1.patch +#Patch0017: 0017-RH-fix-sigusr1.patch Patch0018: 0018-RH-fix-factorize.patch Patch0019: 0019-RH-fix-sockets.patch Patch0020: 0020-RHBZ-907360-static-pthread-init.patch @@ -45,6 +45,12 @@ Patch0034: 0034-RHBZ-851416-mpathconf-display.patch Patch0035: 0035-RHBZ-891921-list-mpp.patch Patch0036: 0036-RHBZ-949239-load-multipath-module.patch Patch0037: 0037-RHBZ-768873-fix-rename.patch +Patch0038: 0038-RHBZ-799860-netapp-config.patch +Patch0039: 0039-RH-detect-prio-fix.patch +Patch0040: 0040-RH-bindings-fix.patch +Patch0041: 0041-RH-check-for-erofs.patch +Patch0042: 0042-UP-fix-signal-handling.patch +Patch0043: 0043-RH-signal-waiter.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -113,7 +119,7 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0014 -p1 %patch0015 -p1 %patch0016 -p1 -%patch0017 -p1 +#%patch0017 -p1 %patch0018 -p1 %patch0019 -p1 %patch0020 -p1 @@ -134,6 +140,12 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0035 -p1 %patch0036 -p1 %patch0037 -p1 +%patch0038 -p1 +%patch0039 -p1 +%patch0040 -p1 +%patch0041 -p1 +%patch0042 -p1 +%patch0043 -p1 cp %{SOURCE1} . %build @@ -227,6 +239,24 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||: %{_mandir}/man8/kpartx.8.gz %changelog +* Fri Jun 21 2013 Benjamin Marzinski 0.4.9-52 +- Add 0038-RHBZ-799860-netapp-config.patch +- Add 0039-RH-detect-prio-fix.patch + * Don't autodetect ALUA prioritizer unless it actually can get a priority +- Add 0040-RH-bindings-fix.patch + * Do a better job of trying to get the first free user_friendly_name +- Add 0041-RH-check-for-erofs.patch + * Don't create/reload a device read-only unless doing it read/write fails + with EROFS +- Remove 0017-RH-fix-sigusr1.patch + * fix signal handling upstream way instead +- Add 0042-UP-fix-signal-handling.patch + * uxlsnr now handles all the signals sent to multipathd. This makes its + signal handling posix compliant, and harder to mess up. +- Add 0043-RH-signal-waiter.patch + * ioctl isn't a pthread cancellation point. Send a signal to the waiter + thread to break out of waiting in ioctl for a dm event. + * Fri May 17 2013 Benjamin Marzinski 0.4.9-51 - Add 0032-RHBZ-956464-mpathconf-defaults.patch * fix defaults listed in usage