--- clvmd.c.orig 2012-03-01 21:14:43.000000000 +0000 +++ clvmd.c 2012-12-12 22:57:27.917901181 +0000 @@ -838,30 +838,33 @@ sigaddset(&ss, SIGTERM); pthread_sigmask(SIG_UNBLOCK, &ss, NULL); /* Main loop */ + time_t deadline = time(NULL) + cmd_timeout; while (!quit) { fd_set in; int select_status; struct local_client *thisfd; - struct timeval tv = { cmd_timeout, 0 }; - int quorate = clops->is_quorate(); - - /* Wait on the cluster FD and all local sockets/pipes */ - local_client_head.fd = clops->get_main_cluster_fd(); - FD_ZERO(&in); - for (thisfd = &local_client_head; thisfd != NULL; - thisfd = thisfd->next) { - - if (thisfd->removeme) - continue; - - /* if the cluster is not quorate then don't listen for new requests */ - if ((thisfd->type != LOCAL_RENDEZVOUS && - thisfd->type != LOCAL_SOCK) || quorate) - FD_SET(thisfd->fd, &in); + struct timeval tv = { deadline - time(NULL), 0 }; + if (tv.tv_sec > 0) { + /* Wait on the cluster FD and all local sockets/pipes */ + int quorate = clops->is_quorate(); + local_client_head.fd = clops->get_main_cluster_fd(); + FD_ZERO(&in); + for (thisfd = &local_client_head; thisfd != NULL; + thisfd = thisfd->next) { + + if (thisfd->removeme) + continue; + + /* if the cluster is not quorate then don't listen for new requests */ + if ((thisfd->type != LOCAL_RENDEZVOUS && + thisfd->type != LOCAL_SOCK) || quorate) + FD_SET(thisfd->fd, &in); + } + + select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv); + } else { + select_status = 0; } - - select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv); - if (reread_config) { int saved_errno = errno; @@ -936,28 +939,34 @@ } } - /* Select timed out. Check for clients that have been waiting too long for a response */ - if (select_status == 0) { + /* Check for clients that have been waiting too long for a response and set a new wake-up deadline */ + if (select_status >= 0) { time_t the_time = time(NULL); + deadline = the_time + cmd_timeout; for (thisfd = &local_client_head; thisfd != NULL; thisfd = thisfd->next) { if (thisfd->type == LOCAL_SOCK && thisfd->bits.localsock.sent_out - && thisfd->bits.localsock.sent_time + - cmd_timeout < the_time && thisfd->bits.localsock. expected_replies != thisfd->bits.localsock.num_replies) { - /* Send timed out message + replies we already have */ - DEBUGLOG - ("Request timed-out (send: %ld, now: %ld)\n", - thisfd->bits.localsock.sent_time, - the_time); - - thisfd->bits.localsock.all_success = 0; - - request_timed_out(thisfd); + time_t this_deadline = thisfd->bits.localsock.sent_time + + cmd_timeout; + if (this_deadline < the_time) { + /* Send timed out message + replies we already have */ + DEBUGLOG + ("Request timed-out (send: %ld, now: %ld)\n", + thisfd->bits.localsock.sent_time, + the_time); + + thisfd->bits.localsock.all_success = 0; + + request_timed_out(thisfd); + } else { + if (this_deadline < deadline) + deadline = this_deadline; + } } } }