Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
device-mapper.18094
bug-1172597_1-libdaemon-use-pselect-to-avoid-co...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bug-1172597_1-libdaemon-use-pselect-to-avoid-condition-checking-ra.patch of Package device-mapper.18094
From 6d4f36c2c7f782af31eca7eca63310791a4f8e93 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabelac@redhat.com> Date: Wed, 10 Apr 2019 12:50:53 +0200 Subject: [PATCH] libdaemon: use pselect to avoid condition checking race To avoid tiny race on checking arrival of signal and entering select (that can latter remain stuck as signal was already delivered) switch to use pselect(). If it would needed, we can eventually add extra code for older systems without pselect(), but there are probably no such ancient systems in use. --- daemons/lvmetad/lvmetad-core.c | 2 +- daemons/lvmpolld/lvmpolld-core.c | 2 +- libdaemon/server/daemon-server.c | 38 ++++++++++++++++++++++++++++---------- libdaemon/server/daemon-server.h | 2 +- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c index 72473d7..9ae359b 100644 --- a/daemons/lvmetad/lvmetad-core.c +++ b/daemons/lvmetad/lvmetad-core.c @@ -2953,7 +2953,7 @@ static void usage(const char *prog, FILE *file) int main(int argc, char *argv[]) { signed char opt; - struct timeval timeout; + struct timespec timeout; daemon_idle di = { .ptimeout = &timeout }; lvmetad_state ls = { .log_config = "" }; daemon_state s = { diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c index fd73272..f1056c3 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 3b19883..c61683a 100644 --- a/libdaemon/server/daemon-server.c +++ b/libdaemon/server/daemon-server.c @@ -87,7 +87,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; } @@ -96,7 +96,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; } } @@ -561,6 +561,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 @@ -628,8 +630,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. */ @@ -643,22 +644,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 2b9ceac..e77ac20 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; -- 1.8.3.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor