diff options
-rw-r--r-- | WHATS_NEW | 1 | ||||
-rw-r--r-- | daemons/lvmpolld/lvmpolld-core.c | 2 | ||||
-rw-r--r-- | libdaemon/server/daemon-server.c | 38 | ||||
-rw-r--r-- | libdaemon/server/daemon-server.h | 2 |
4 files changed, 31 insertions, 12 deletions
@@ -1,5 +1,6 @@ Version 2.03.02 - =================================== + Fix signal delivery checking race in libdaemon (lvmetad). Add missing Before=shutdown.target to LVM2 services to fix shutdown ordering. Skip autoactivation for a PV when PV size does not match device size. Remove first-pvscan-initialization which should no longer be needed. diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c index 3aac65f23..af98843c9 100644 --- a/daemons/lvmpolld/lvmpolld-core.c +++ b/daemons/lvmpolld/lvmpolld-core.c @@ -915,7 +915,7 @@ int main(int argc, char *argv[]) int option_index = 0; int client = 0, server = 0; unsigned action = ACTION_MAX; - struct timeval timeout; + struct timespec timeout; daemon_idle di = { .ptimeout = &timeout }; struct lvmpolld_state ls = { .log_config = "" }; daemon_state s = { diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c index a2216ac2e..e4ff8a103 100644 --- a/libdaemon/server/daemon-server.c +++ b/libdaemon/server/daemon-server.c @@ -85,7 +85,7 @@ static int _is_idle(daemon_state s) return s.idle && s.idle->is_idle && !s.threads->next; } -static struct timeval *_get_timeout(daemon_state s) +static struct timespec *_get_timeout(daemon_state s) { return s.idle ? s.idle->ptimeout : NULL; } @@ -94,7 +94,7 @@ static void _reset_timeout(daemon_state s) { if (s.idle) { s.idle->ptimeout->tv_sec = 1; - s.idle->ptimeout->tv_usec = 0; + s.idle->ptimeout->tv_nsec = 0; } } @@ -559,6 +559,8 @@ void daemon_start(daemon_state s) thread_state _threads = { .next = NULL }; unsigned timeout_count = 0; fd_set in; + sigset_t new_set, old_set; + int ret; /* * Switch to C locale to avoid reading large locale-archive file used by @@ -626,8 +628,7 @@ void daemon_start(daemon_state s) if (!s.foreground) kill(getppid(), SIGTERM); - /* - * Use daemon_main for daemon-specific init and polling, or + /* * Use daemon_main for daemon-specific init and polling, or * use daemon_init for daemon-specific init and generic lib polling. */ @@ -641,22 +642,39 @@ void daemon_start(daemon_state s) if (!s.daemon_init(&s)) failed = 1; + if (s.socket_fd >= FD_SETSIZE) + failed = 1; /* FD out of available selectable set */ + + sigfillset(&new_set); + sigprocmask(SIG_SETMASK, NULL, &old_set); + while (!failed) { _reset_timeout(s); FD_ZERO(&in); FD_SET(s.socket_fd, &in); - if (select(FD_SETSIZE, &in, NULL, NULL, _get_timeout(s)) < 0 && errno != EINTR) - perror("select error"); + + sigprocmask(SIG_SETMASK, &new_set, NULL); + if (_shutdown_requested && !s.threads->next) { + sigprocmask(SIG_SETMASK, &old_set, NULL); + INFO(&s, "shutdown requested", s.name); + break; + } + ret = pselect(s.socket_fd + 1, &in, NULL, NULL, _get_timeout(s), &old_set); + sigprocmask(SIG_SETMASK, &old_set, NULL); + + if (ret < 0) { + if (errno != EINTR && errno != EAGAIN && + (EWOULDBLOCK == EAGAIN || errno != EWOULDBLOCK)) + perror("select error"); + continue; + } + if (FD_ISSET(s.socket_fd, &in)) { timeout_count = 0; _handle_connect(s); } - _reap(s, 0); - if (_shutdown_requested && !s.threads->next) - break; - /* s.idle == NULL equals no shutdown on timeout */ if (_is_idle(s)) { DEBUGLOG(&s, "timeout occured"); diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h index f8c0ca681..18fd3ad9f 100644 --- a/libdaemon/server/daemon-server.h +++ b/libdaemon/server/daemon-server.h @@ -47,7 +47,7 @@ struct timeval; typedef struct { volatile unsigned is_idle; unsigned max_timeouts; - struct timeval *ptimeout; + struct timespec *ptimeout; } daemon_idle; struct daemon_state; |