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);
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;
}
#include <pthread.h>
-#include <signal.h>
#include "lock.h"
#include <stdio.h>
-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));
#endif
void cleanup_lock (void * data);
-void block_signal(int signum, sigset_t *old);
#endif /* _LOCK_H */
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);
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)
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);
waiter = (struct event_thread *)et;
pthread_cleanup_push(free_waiter, et);
- block_signal(SIGUSR1, NULL);
- block_signal(SIGHUP, NULL);
while (1) {
r = waiteventloop(waiter);
cli_shutdown (void * v, char ** reply, int * len, void * data)
{
condlog(3, "shutdown (operator)");
-
- return exit_daemon(0);
+ exit_daemon();
+ return 0;
}
int
#include <limits.h>
#include <linux/oom.h>
#include <libudev.h>
+#include <semaphore.h>
#include <mpath_persist.h>
/*
#include <prio.h>
#include <pgpolicies.h>
#include <uevent.h>
+#include <log.h>
#include "main.h"
#include "pidfile.h"
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
*/
static void *
ueventloop (void * ap)
{
- block_signal(SIGUSR1, NULL);
- block_signal(SIGHUP, NULL);
-
if (uevent_listen())
condlog(0, "error starting uevent listener");
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");
static void *
uxlsnrloop (void * ap)
{
- block_signal(SIGUSR1, NULL);
- block_signal(SIGHUP, NULL);
-
if (cli_init())
return NULL;
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 *
struct path *pp;
int count = 0;
unsigned int i;
- sigset_t old;
mlockall(MCL_CURRENT | MCL_FUTURE);
vecs = (struct vectors *)ap;
}
while (1) {
- block_signal(SIGHUP, &old);
pthread_cleanup_push(cleanup_lock, &vecs->lock);
lock(vecs->lock);
pthread_testcancel();
}
lock_cleanup_pop(vecs->lock);
- pthread_sigmask(SIG_SETMASK, &old, NULL);
sleep(1);
}
return NULL;
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);
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);
if (!vecs)
exit(1);
- signal_init();
setscheduler();
set_oom_adj();
}
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)
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 *);
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 */
/*
* A simple domain socket listener
*/
+#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/poll.h>
-
+#include <signal.h>
#include <checkers.h>
-
#include <memory.h>
#include <debug.h>
#include <vector.h>
#include <structs.h>
+#include <structs_vec.h>
#include <uxsock.h>
#include <defaults.h>
+#include "main.h"
#include "cli.h"
#include "uxlsnr.h"
-#define SLEEP_TIME 5000
+struct timespec sleep_time = {5, 0};
struct client {
int fd;
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
int rlen;
char *inbuf;
char *reply;
+ sigset_t mask;
ux_sock = ux_socket_listen(DEFAULT_SOCKET);
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;
}
/* 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");
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