1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-04 09:18:36 +03:00

lvmetad: process new connections after shutdown signal

Currently, a shutdown signal will cause lvmetad to quit
responding to new connections, but not actually exit until
all connections are gone.  If a program is maintaining a
long running connection (e.g. lvmlockd, or even an lvm
command) when lvmetad gets a shutdown signal, then all
further commands will hang indefinately waiting for a
response that won't be sent.

With this patch, make lvmetad continue handling new
connections even after a shutdown signal.  It will exit
once all connections are gone.
This commit is contained in:
David Teigland 2016-06-20 13:19:02 -05:00
parent 6ae22125c6
commit b12961e7eb

View File

@ -490,8 +490,10 @@ static int handle_connect(daemon_state s)
socklen_t sl = sizeof(sockaddr); socklen_t sl = sizeof(sockaddr);
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl); client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
if (client.socket_fd < 0) if (client.socket_fd < 0) {
ERROR(&s, "Failed to accept connection.");
return 0; return 0;
}
if (fcntl(client.socket_fd, F_SETFD, FD_CLOEXEC)) if (fcntl(client.socket_fd, F_SETFD, FD_CLOEXEC))
WARN(&s, "setting CLOEXEC on client socket fd %d failed", client.socket_fd); WARN(&s, "setting CLOEXEC on client socket fd %d failed", client.socket_fd);
@ -510,8 +512,10 @@ static int handle_connect(daemon_state s)
ts->s = s; ts->s = s;
ts->client = client; ts->client = client;
if (pthread_create(&ts->client.thread_id, NULL, client_thread, ts)) if (pthread_create(&ts->client.thread_id, NULL, client_thread, ts)) {
ERROR(&s, "Failed to create client thread.");
return 0; return 0;
}
return 1; return 1;
} }
@ -622,7 +626,7 @@ void daemon_start(daemon_state s)
if (!s.daemon_init(&s)) if (!s.daemon_init(&s))
failed = 1; failed = 1;
while (!_shutdown_requested && !failed) { while (!failed) {
_reset_timeout(s); _reset_timeout(s);
FD_ZERO(&in); FD_ZERO(&in);
FD_SET(s.socket_fd, &in); FD_SET(s.socket_fd, &in);
@ -630,12 +634,14 @@ void daemon_start(daemon_state s)
perror("select error"); perror("select error");
if (FD_ISSET(s.socket_fd, &in)) { if (FD_ISSET(s.socket_fd, &in)) {
timeout_count = 0; timeout_count = 0;
if (!_shutdown_requested && !handle_connect(s)) handle_connect(s);
ERROR(&s, "Failed to handle a client connection.");
} }
reap(s, 0); reap(s, 0);
if (_shutdown_requested && !s.threads->next)
break;
/* s.idle == NULL equals no shutdown on timeout */ /* s.idle == NULL equals no shutdown on timeout */
if (_is_idle(s)) { if (_is_idle(s)) {
DEBUGLOG(&s, "timeout occured"); DEBUGLOG(&s, "timeout occured");