|
Ian Kent |
1cd346 |
autofs-5.1.1 - use monotonic clock for alarm thread condition wait
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
From: Yu Ning <ning.yu@ubuntu.com>
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
The time returned by gettimeofday() is affected by discontinuous jumps
|
|
Ian Kent |
1cd346 |
in the system time, so it causes an issue that autofs may not auto
|
|
Ian Kent |
1cd346 |
unmount a mount point if system time is manually changed by the system
|
|
Ian Kent |
1cd346 |
administrator.
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
To fix the issue we need to convert to using a monotonic clock source
|
|
Ian Kent |
1cd346 |
instead of the clock source used by gettimeofday().
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
Convert the alarm_handler() to use a monotonic clock source.
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
|
|
Ian Kent |
1cd346 |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
1cd346 |
---
|
|
Ian Kent |
1cd346 |
CHANGELOG | 1 +
|
|
Ian Kent |
1cd346 |
lib/alarm.c | 28 ++++++++++++++++++++++------
|
|
Ian Kent |
1cd346 |
2 files changed, 23 insertions(+), 6 deletions(-)
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
1cd346 |
index 566a6c6..c443f49 100644
|
|
Ian Kent |
1cd346 |
--- a/CHANGELOG
|
|
Ian Kent |
1cd346 |
+++ b/CHANGELOG
|
|
Ian Kent |
1cd346 |
@@ -24,6 +24,7 @@
|
|
Ian Kent |
1cd346 |
- fix error handling of is_mounted().
|
|
Ian Kent |
1cd346 |
- Add a mode option for master map entries.
|
|
Ian Kent |
1cd346 |
- define monotonic clock helper functions.
|
|
Ian Kent |
1cd346 |
+- use monotonic clock for alarm thread condition wait.
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
21/04/2015 autofs-5.1.1
|
|
Ian Kent |
1cd346 |
=======================
|
|
Ian Kent |
1cd346 |
diff --git a/lib/alarm.c b/lib/alarm.c
|
|
Ian Kent |
1cd346 |
index 0f04ef8..e6a880b 100755
|
|
Ian Kent |
1cd346 |
--- a/lib/alarm.c
|
|
Ian Kent |
1cd346 |
+++ b/lib/alarm.c
|
|
Ian Kent |
1cd346 |
@@ -23,7 +23,7 @@ struct alarm {
|
|
Ian Kent |
1cd346 |
};
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
Ian Kent |
1cd346 |
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
|
Ian Kent |
1cd346 |
+static pthread_cond_t cond;
|
|
Ian Kent |
1cd346 |
static LIST_HEAD(alarms);
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
#define alarm_lock() \
|
|
Ian Kent |
1cd346 |
@@ -46,7 +46,7 @@ int alarm_add(struct autofs_point *ap, time_t seconds)
|
|
Ian Kent |
1cd346 |
struct list_head *head;
|
|
Ian Kent |
1cd346 |
struct list_head *p;
|
|
Ian Kent |
1cd346 |
struct alarm *new;
|
|
Ian Kent |
1cd346 |
- time_t now = time(NULL);
|
|
Ian Kent |
1cd346 |
+ time_t now = monotonic_time(NULL);
|
|
Ian Kent |
1cd346 |
time_t next_alarm = 0;
|
|
Ian Kent |
1cd346 |
unsigned int empty = 1;
|
|
Ian Kent |
1cd346 |
int status;
|
|
Ian Kent |
1cd346 |
@@ -175,17 +175,18 @@ static void *alarm_handler(void *arg)
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
first = list_entry(head->next, struct alarm, list);
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
- now = time(NULL);
|
|
Ian Kent |
1cd346 |
+ now = monotonic_time(NULL);
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
if (first->time > now) {
|
|
Ian Kent |
1cd346 |
- struct timeval usecs;
|
|
Ian Kent |
1cd346 |
+ struct timespec nsecs;
|
|
Ian Kent |
1cd346 |
+
|
|
Ian Kent |
1cd346 |
/*
|
|
Ian Kent |
1cd346 |
* Wait for alarm to trigger or a new alarm
|
|
Ian Kent |
1cd346 |
* to be added.
|
|
Ian Kent |
1cd346 |
*/
|
|
Ian Kent |
1cd346 |
- gettimeofday(&usecs, NULL);
|
|
Ian Kent |
1cd346 |
+ clock_gettime(CLOCK_MONOTONIC, &nsecs);
|
|
Ian Kent |
1cd346 |
expire.tv_sec = first->time;
|
|
Ian Kent |
1cd346 |
- expire.tv_nsec = usecs.tv_usec * 1000;
|
|
Ian Kent |
1cd346 |
+ expire.tv_nsec = nsecs.tv_nsec;
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
status = pthread_cond_timedwait(&cond, &mutex, &expire);
|
|
Ian Kent |
1cd346 |
if (status && status != ETIMEDOUT)
|
|
Ian Kent |
1cd346 |
@@ -212,6 +213,7 @@ int alarm_start_handler(void)
|
|
Ian Kent |
1cd346 |
pthread_t thid;
|
|
Ian Kent |
1cd346 |
pthread_attr_t attrs;
|
|
Ian Kent |
1cd346 |
pthread_attr_t *pattrs = &attrs;
|
|
Ian Kent |
1cd346 |
+ pthread_condattr_t condattrs;
|
|
Ian Kent |
1cd346 |
int status;
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
status = pthread_attr_init(pattrs);
|
|
Ian Kent |
1cd346 |
@@ -224,8 +226,22 @@ int alarm_start_handler(void)
|
|
Ian Kent |
1cd346 |
#endif
|
|
Ian Kent |
1cd346 |
}
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
+ status = pthread_condattr_init(&condattrs);
|
|
Ian Kent |
1cd346 |
+ if (status)
|
|
Ian Kent |
1cd346 |
+ fatal(status);
|
|
Ian Kent |
1cd346 |
+
|
|
Ian Kent |
1cd346 |
+ status = pthread_condattr_setclock(&condattrs, CLOCK_MONOTONIC);
|
|
Ian Kent |
1cd346 |
+ if (status)
|
|
Ian Kent |
1cd346 |
+ fatal(status);
|
|
Ian Kent |
1cd346 |
+
|
|
Ian Kent |
1cd346 |
+ status = pthread_cond_init(&cond, &condattrs);
|
|
Ian Kent |
1cd346 |
+ if (status)
|
|
Ian Kent |
1cd346 |
+ fatal(status);
|
|
Ian Kent |
1cd346 |
+
|
|
Ian Kent |
1cd346 |
status = pthread_create(&thid, pattrs, alarm_handler, NULL);
|
|
Ian Kent |
1cd346 |
|
|
Ian Kent |
1cd346 |
+ pthread_condattr_destroy(&condattrs);
|
|
Ian Kent |
1cd346 |
+
|
|
Ian Kent |
1cd346 |
if (pattrs)
|
|
Ian Kent |
1cd346 |
pthread_attr_destroy(pattrs);
|
|
Ian Kent |
1cd346 |
|