[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