[sheepdog] [PATCH v2] lib/logger: nonblocking waitpid to avoid sheep process cannot exit

Ruoyu liangry at ucweb.com
Wed Jun 11 04:53:35 CEST 2014


Sometimes sheep process cannot exit as we expected. I think the
point might be the sequential problem by using waitpid, the
system call waiting for process to change state.

Current log_close function calling waitpid as a void method. It
will block the main process. Suppose this situation:

Father: --> active=false --------------------------------> waitpid
Child: -------------> active=true --> while(active) do sth. -->

The log process will loop forever so that the main process cannot
exit.

Therefore, it is better to retrieve the return value and pass the
nonblocking flag WNOHANG to it. Moreover, reset share memory flag
before each time calling waitpid.

Signed-off-by: Ruoyu <liangry at ucweb.com>
---
 lib/logger.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/lib/logger.c b/lib/logger.c
index 6829f45..3815ee4 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -711,13 +711,27 @@ int log_init(const char *program_name, enum log_dst_type type, int level,
 
 void log_close(void)
 {
-	if (la) {
-		la->active = false;
-		waitpid(logger_pid, NULL, 0);
+	pid_t pid;
+
+	if (!la)
+		return;
 
-		syslog(LOG_WARNING, "logger pid %d stopped\n", logger_pid);
-		closelog();
-		free_logarea();
+	while (true) {
+		la->active = false;
+		pid = waitpid(logger_pid, NULL, WNOHANG);
+		if (pid == 0) {
+			usleep(100000);
+			continue;
+		} else if (pid > 0) {
+			syslog(LOG_WARNING, "logger pid %d stopped\n",
+					logger_pid);
+			closelog();
+			free_logarea();
+			break;
+		} else {
+			syslog(LOG_ERR, "waitpid() failure\n");
+			exit(1);
+		}
 	}
 }
 
-- 
1.8.3.2





More information about the sheepdog mailing list