]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
flock: improve timeout handling
authorSami Kerola <kerolasa@iki.fi>
Mon, 9 Feb 2015 23:18:09 +0000 (23:18 +0000)
committerKarel Zak <kzak@redhat.com>
Thu, 5 Mar 2015 09:31:01 +0000 (10:31 +0100)
Signal ALRM raised by the timer, and the timer only, will be considered
as a timeout criteria.

Secondly time interval is made to use monotonic clock.  Documentation of
ITIMER_REAL is unclear whether that time is affected various sources of
clock skew, or does it even tick when system is suspended.

Reviewed-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
configure.ac
include/Makemodule.am
include/monotonic.h
include/timer.h [deleted file]
lib/monotonic.c
sys-utils/Makemodule.am
sys-utils/flock.c

index 5d2b68503587488c5ef7201aed416176b9614e48..9dec9d8978d233dc24fc155d4efc79f0c9d70774 100644 (file)
@@ -371,10 +371,16 @@ AC_CHECK_FUNCS([ioperm iopl], [have_io=yes])
 AC_CHECK_FUNCS([futimens], [have_futimens=yes])
 AC_CHECK_FUNCS([inotify_init1], [have_inotify_init1=yes])
 
-dnl Old glibc requires -lrt
-AC_CHECK_FUNCS(clock_gettime, [], [
-       AC_CHECK_LIB(rt, clock_gettime, [
-               AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
+dnl lib/mononotic.c may require -lrt
+AC_CHECK_FUNCS([clock_gettime],
+       [AC_CHECK_FUNCS([timer_create], [], [
+               AC_CHECK_LIB([rt], [timer_create], [
+                       AC_DEFINE([HAVE_CLOCK_GETTIME], [1])
+                       CLOCKGETTIME_LIBS="-lrt"
+               ])
+       ])],
+       [AC_CHECK_LIB([rt], [clock_gettime], [
+               AC_DEFINE([HAVE_CLOCK_GETTIME], [1])
                CLOCKGETTIME_LIBS="-lrt"
        ])
 ])
index c4a52e4cf33988420f62a2e6cc5155b00cba1f8d..8d7c881d56948e2bf60a2160640a844899d826d0 100644 (file)
@@ -44,7 +44,6 @@ dist_noinst_HEADERS += \
        include/swapprober.h \
        include/swapheader.h \
        include/sysfs.h \
-       include/timer.h \
        include/timeutils.h \
        include/ttyutils.h \
        include/widechar.h \
index f3b03d3d00401f744014d60dcbc6da9e50a5ef99..d5ff7c8e582e6ae3439b8ab2580a500777cfd9bb 100644 (file)
@@ -8,4 +8,8 @@ extern int get_boot_time(struct timeval *boot_time);
 
 extern int gettime_monotonic(struct timeval *tv);
 
+extern int setup_timer(timer_t * t_id, struct itimerval *timeout,
+                      void (*timeout_handler)(void));
+extern void cancel_timer(timer_t * t_id);
+
 #endif /* UTIL_LINUX_BOOTTIME_H */
diff --git a/include/timer.h b/include/timer.h
deleted file mode 100644 (file)
index 79ef649..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef UTIL_LINUX_TIMER_H
-#define UTIL_LINUX_TIMER_H
-
-#include <signal.h>
-#include <sys/time.h>
-
-static inline int setup_timer(
-                       struct itimerval *timer,
-                       struct itimerval *old_timer,
-                       struct sigaction *old_sa,
-                       void (*timeout_handler)(int))
-{
-       struct sigaction sa;
-
-       memset(&sa, 0, sizeof sa);
-       sa.sa_handler = timeout_handler;
-       sa.sa_flags = SA_RESETHAND;
-       sigaction(SIGALRM, &sa, old_sa);
-
-       return setitimer(ITIMER_REAL, timer, old_timer);
-}
-
-static inline void cancel_timer(
-                       struct itimerval *old_timer,
-                       struct sigaction *old_sa)
-{
-       setitimer(ITIMER_REAL, old_timer, NULL);
-       sigaction(SIGALRM, old_sa, NULL);
-}
-
-#endif
index 3d4a4438e0637641fcb3364dc858b625bae27a59..a124debba6c414546cc649a36d8568ef319dab03 100644 (file)
@@ -3,6 +3,7 @@
  * -lrt on systems with old libc.
  */
 #include <time.h>
+#include <signal.h>
 #include <sys/sysinfo.h>
 #include <sys/time.h>
 
@@ -66,3 +67,36 @@ int gettime_monotonic(struct timeval *tv)
        return gettimeofday(tv, NULL);
 #endif
 }
+
+int setup_timer(timer_t * t_id, struct itimerval *timeout,
+               void (*timeout_handler)(void))
+{
+       struct sigaction sig_a;
+       static struct sigevent sig_e = {
+               .sigev_notify = SIGEV_SIGNAL,
+               .sigev_signo = SIGALRM
+       };
+       struct itimerspec val = {
+               .it_value.tv_sec = timeout->it_value.tv_sec,
+               .it_value.tv_nsec = timeout->it_value.tv_usec * 1000,
+               .it_interval.tv_sec = 0,
+               .it_interval.tv_nsec = 0
+       };
+
+       if (sigemptyset(&sig_a.sa_mask))
+               return 1;
+       sig_a.sa_flags = SA_SIGINFO;
+       sig_a.sa_handler = timeout_handler;
+       if (sigaction(SIGALRM, &sig_a, 0))
+               return 1;
+       if (timer_create(CLOCK_MONOTONIC, &sig_e, t_id))
+               return 1;
+       if (timer_settime(*t_id, SA_SIGINFO, &val, NULL))
+               return 1;
+       return 0;
+}
+
+void cancel_timer(timer_t *t_id)
+{
+       timer_delete(*t_id);
+}
index b6b0f91acf2a0b4e7e9b0316dd6c04c214b96f29..bd1b681e85e08afb0f283b3dca2b06f535d3bb5c 100644 (file)
@@ -2,7 +2,7 @@ if BUILD_FLOCK
 usrbin_exec_PROGRAMS += flock
 dist_man_MANS += sys-utils/flock.1
 flock_SOURCES = sys-utils/flock.c lib/monotonic.c
-flock_LDADD = $(LDADD) libcommon.la $(CLOCKGETTIME_LIBS)
+flock_LDADD = $(LDADD) libcommon.la -lrt
 endif
 
 if BUILD_IPCMK
index 707c5992bb25ed478ff62e65363a9f05009da53f..368ad1a9ff9461c284fc7b60ca65757f5ea3caca 100644 (file)
@@ -43,7 +43,6 @@
 #include "nls.h"
 #include "strutils.h"
 #include "closestream.h"
-#include "timer.h"
 #include "monotonic.h"
 
 static void __attribute__((__noreturn__)) usage(int ex)
@@ -77,9 +76,12 @@ static void __attribute__((__noreturn__)) usage(int ex)
 
 static sig_atomic_t timeout_expired = 0;
 
-static void timeout_handler(int sig __attribute__((__unused__)))
+static void timeout_handler(int sig __attribute__((__unused__)),
+                           siginfo_t *info,
+                           void *context __attribute__((__unused__)))
 {
-       timeout_expired = 1;
+       if (info->si_code == SI_TIMER)
+               timeout_expired = 1;
 }
 
 static int open_file(const char *filename, int *flags)
@@ -113,7 +115,8 @@ static int open_file(const char *filename, int *flags)
 
 int main(int argc, char *argv[])
 {
-       struct itimerval timeout, old_timer;
+       static timer_t t_id;
+       struct itimerval timeout;
        int have_timeout = 0;
        int type = LOCK_EX;
        int block = 0;
@@ -131,7 +134,6 @@ int main(int argc, char *argv[])
        int conflict_exit_code = 1;
        char **cmd_argv = NULL, *sh_c_argv[4];
        const char *filename = NULL;
-       struct sigaction old_sa;
        enum {
                OPT_VERBOSE = CHAR_MAX + 1
        };
@@ -246,7 +248,8 @@ int main(int argc, char *argv[])
                        have_timeout = 0;
                        block = LOCK_NB;
                } else
-                       setup_timer(&timeout, &old_timer, &old_sa, timeout_handler);
+                       if (setup_timer(&t_id, &timeout, &timeout_handler))
+                               err(EX_OSERR, _("cannot not setup timer"));
        }
 
        if (verbose)
@@ -298,7 +301,7 @@ int main(int argc, char *argv[])
        }
 
        if (have_timeout)
-               cancel_timer(&old_timer, &old_sa);
+               cancel_timer(&t_id);
        if (verbose) {
                struct timeval delta;