From 7ff32709862801d6954fd004ab1db61ca9b786c4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 31 Dec 2015 13:19:12 +0100 Subject: syslogd: enforce timeouts on the semaphore Now syslogd waits at most one second to try to get the semaphore and will simply not log the message to the circular buffer if it fails. Logread will wait for up to 3 seconds. This ensures it remains possible to log into the system in case one process died with the semaphore held or something similar. --- sysklogd/logread.c | 15 +++++++++++---- sysklogd/syslogd.c | 9 +++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 4a867a3..6002086 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c @@ -24,6 +24,7 @@ */ +#include #include #include #include @@ -67,13 +68,19 @@ static inline void sem_up(int semid) } /* - * sem_down - down()'s a semaphore + * sem_down - down()'s a semaphore. Returns >=0 on success, <0 on failure. */ static inline int sem_down(int semid) { - if ( semop(semid, SMrdn, 2) == -1 ) - error_exit("semop[SMrdn]"); - return 0; + struct timespec timeout; + + timeout.tv_sec = 3; timeout.tv_nsec = 0; + if (semtimedop(semid, SMrdn, 2, &timeout) != -1) + return 0; + if (errno == EAGAIN) + return -1; + error_exit("semop[SMrdn]"); + return -1; } extern int logread_main(int argc, char **argv) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 5b13e5d..4bd9b69 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -170,10 +170,15 @@ static inline void sem_up(int semid) */ static inline int sem_down(int semid) { + struct timespec timeout; + do { - if (semop(semid, SMwdn, 3) != -1) + timeout.tv_sec = 1; timeout.tv_nsec = 0; + if (semtimedop(semid, SMwdn, 3, &timeout) != -1) return 0; - } while (errno == EAGAIN || errno == EINTR); + if (errno == EAGAIN) + return -1; + } while (errno == EINTR); bb_perror_msg_and_die("semop[SMwdn]"); return -1; } -- 1.7.12.1