[systemd-devel] [PATCH] [RFC] systemctl-clock: Use monotonic instead of realtime clock
Shakeel, Muhammad
muhammad_shakeel at mentor.com
Tue Jun 25 06:58:02 PDT 2013
From: Muhammad Shakeel <mshakeel at pkl-mshakeel-ubuntu.(none)>
Currently if system clock is updated then 'ago' part of any service
running time doesn't show correct information. This is reported here:
https://bugs.freedesktop.org/show_bug.cgi?id=65616
---
src/login/loginctl.c | 10 ++++++++--
src/shared/time-util.c | 2 +-
src/systemctl/systemctl.c | 27 ++++++++++++++++++++++++---
3 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 3637a40..9010b9d 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -329,6 +329,7 @@ typedef struct SessionStatusInfo {
uid_t uid;
const char *name;
usec_t timestamp;
+ usec_t timestamp_monotonic;
const char *default_control_group;
int vtnr;
const char *seat;
@@ -349,6 +350,7 @@ typedef struct UserStatusInfo {
uid_t uid;
const char *name;
usec_t timestamp;
+ usec_t timestamp_monotonic;
const char *default_control_group;
const char *state;
char **sessions;
@@ -386,7 +388,7 @@ static void print_session_status_info(SessionStatusInfo *i) {
else
printf("%u\n", (unsigned) i->uid);
- s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
+ s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp_monotonic);
s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
if (s1)
@@ -486,7 +488,7 @@ static void print_user_status_info(UserStatusInfo *i) {
else
printf("%u\n", (unsigned) i->uid);
- s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
+ s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp_monotonic);
s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
if (s1)
@@ -711,6 +713,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
if (streq(name, "Timestamp"))
i->timestamp = (usec_t) u;
+ else if (streq(name, "TimestampMonotonic"))
+ i->timestamp_monotonic = (usec_t) u;
break;
}
@@ -785,6 +789,8 @@ static int status_property_user(const char *name, DBusMessageIter *iter, UserSta
if (streq(name, "Timestamp"))
i->timestamp = (usec_t) u;
+ else if (streq(name, "TimestampMonotonic"))
+ i->timestamp_monotonic = (usec_t) u;
break;
}
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
index 9ee711a..08c8a2f 100644
--- a/src/shared/time-util.c
+++ b/src/shared/time-util.c
@@ -171,7 +171,7 @@ char *format_timestamp(char *buf, size_t l, usec_t t) {
char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
usec_t n, d;
- n = now(CLOCK_REALTIME);
+ n = now(CLOCK_MONOTONIC);
if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
return NULL;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 71bf17d..8c43623 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2651,6 +2651,9 @@ typedef struct UnitStatusInfo {
usec_t active_enter_timestamp;
usec_t active_exit_timestamp;
usec_t inactive_enter_timestamp;
+ usec_t active_enter_timestamp_monotonic;
+ usec_t active_exit_timestamp_monotonic;
+ usec_t inactive_enter_timestamp_monotonic;
bool need_daemon_reload;
@@ -2667,6 +2670,7 @@ typedef struct UnitStatusInfo {
int exit_code, exit_status;
usec_t condition_timestamp;
+ usec_t condition_timestamp_monotonic;
bool condition_result;
/* Socket */
@@ -2692,7 +2696,7 @@ typedef struct UnitStatusInfo {
static void print_status_info(UnitStatusInfo *i) {
ExecStatusInfo *p;
const char *on, *off, *ss;
- usec_t timestamp;
+ usec_t timestamp, timestamp_monotonic;
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
const char *path;
@@ -2796,7 +2800,14 @@ static void print_status_info(UnitStatusInfo *i) {
streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
i->active_exit_timestamp;
- s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
+ timestamp_monotonic = (streq_ptr(i->active_state, "active") ||
+ streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp_monotonic :
+ (streq_ptr(i->active_state, "inactive") ||
+ streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp_monotonic :
+ streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp_monotonic :
+ i->active_exit_timestamp_monotonic;
+
+ s1 = format_timestamp_relative(since1, sizeof(since1), timestamp_monotonic);
s2 = format_timestamp(since2, sizeof(since2), timestamp);
if (s1)
@@ -2807,7 +2818,7 @@ static void print_status_info(UnitStatusInfo *i) {
printf("\n");
if (!i->condition_result && i->condition_timestamp > 0) {
- s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
+ s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp_monotonic);
s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
if (s1)
@@ -3149,6 +3160,16 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
i->active_exit_timestamp = (usec_t) u;
else if (streq(name, "ConditionTimestamp"))
i->condition_timestamp = (usec_t) u;
+ else if (streq(name, "ActiveEnterTimestampMonotonic"))
+ i->active_enter_timestamp_monotonic = (usec_t) u;
+ else if (streq(name, "InactiveEnterTimestampMonotonic"))
+ i->inactive_enter_timestamp_monotonic = (usec_t) u;
+ else if (streq(name, "InactiveExitTimestampMonotonic"))
+ i->inactive_exit_timestamp_monotonic = (usec_t) u;
+ else if (streq(name, "ActiveExitTimestampMonotonic"))
+ i->active_exit_timestamp_monotonic = (usec_t) u;
+ else if (streq(name, "ConditionTimestampMonotonic"))
+ i->condition_timestamp_monotonic = (usec_t) u;
break;
}
--
1.7.9.5
More information about the systemd-devel
mailing list