event poll may become un-triggerable after changing system clock.
The steps to reproduce the problem:
1 run event-test
1 define and start a domain with name vm1.
2 destroy vm1
3 change system time to 1 hour before when timer.expiresAt has been set in
virEventPollUpdateTimeout
(and before virEventPollDispatchTimeouts()).
4 event-test will recive no message until 1 hour later.
The reasons for the problem is :
1 The value of timer.expiresAt is set by virTimeMillisNowRaw. virTimeMillisNowRaw is
effectable by settimeofday(),
bacause it uses CLOCK_REALTIME to get time.
2 If we change the system time to a time long before now, after that timer.expiresAt has
been set. timer.expiresAt
is not affected, while virEventPollDispatchTimeouts is.
Suppose it's now May 12th, and we set it to 10th, then the expiresAt is 12th, and
the time virEventPollDispatchTimeouts
got is 10th.
if (eventLoop.timeouts[i].expiresAt <= (now+20)) { // expiresAt will not be
less than now until 2 days later.
*Solution(not good enough)*:
1 change the clock mode in virTimeMillisNowRaw from REALTIME to MONOTONIC, which would not
be affected by
settimeofday().
2 add the time got from clock_gettime(*MONOTONIC*) with the system-start-time from epoch,
making it equal to the value got from REALTIME.
3 As that the timestamp of the log message should follow system time, so we keep it to
REALTIME as before.
However, there's still problems:
1 pthread_cond_wait() gets time with REALTIME mode. When we change system time,
pthread_cond_wait() may still be affected.
So, Is there any other better solution? thanks in advance.
oscar