65878a
From 4323a5406bb40c76076814fd998e09c58b433e7d Mon Sep 17 00:00:00 2001
65878a
From: Miguel Angel Ajo <mangelajo@redhat.com>
65878a
Date: Mon, 7 Jul 2014 14:20:36 +0200
65878a
Subject: [PATCH] core: Added support for ERRNO NOTIFY_SOCKET  message parsing
65878a
65878a
Added StatusErrno dbus property along StatusText to allow notification of
65878a
numeric status condition while degraded service operation or any other special
65878a
situation.
65878a
65878a
(cherry picked from commit 4774e357268e4a1e9fa82adb0563a538932a4c8e)
65878a
65878a
Resolves: #1106457
65878a
---
65878a
 src/core/dbus-service.c |  3 +++
65878a
 src/core/service.c      | 33 +++++++++++++++++++++++++++++----
65878a
 src/core/service.h      |  1 +
65878a
 3 files changed, 33 insertions(+), 4 deletions(-)
65878a
65878a
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
65878a
index 696c446..edfc7ff 100644
65878a
--- a/src/core/dbus-service.c
65878a
+++ b/src/core/dbus-service.c
65878a
@@ -64,6 +64,7 @@
65878a
         "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
65878a
         "  <property name=\"BusName\" type=\"s\" access=\"read\"/>\n"   \
65878a
         "  <property name=\"StatusText\" type=\"s\" access=\"read\"/>\n" \
65878a
+        "  <property name=\"StatusErrno\" type=\"i\" access=\"read\"/>\n" \
65878a
         "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
65878a
        " </interface>\n"
65878a
 
65878a
@@ -96,6 +97,7 @@ const char bus_service_invalidating_properties[] =
65878a
         "MainPID\0"
65878a
         "ControlPID\0"
65878a
         "StatusText\0"
65878a
+        "StatusErrno\0"
65878a
         "Result\0";
65878a
 
65878a
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType);
65878a
@@ -144,6 +146,7 @@ static const BusProperty bus_service_properties[] = {
65878a
         { "ControlPID",             bus_property_append_pid,          "u", offsetof(Service, control_pid)                  },
65878a
         { "BusName",                bus_property_append_string,       "s", offsetof(Service, bus_name),               true },
65878a
         { "StatusText",             bus_property_append_string,       "s", offsetof(Service, status_text),            true },
65878a
+        { "StatusErrno",            bus_property_append_int,          "i", offsetof(Service, status_errno)                 },
65878a
         { "Result",                 bus_service_append_service_result,"s", offsetof(Service, result)                       },
65878a
         {}
65878a
 };
65878a
diff --git a/src/core/service.c b/src/core/service.c
65878a
index f6fdbbc..3f6c8ac 100644
65878a
--- a/src/core/service.c
65878a
+++ b/src/core/service.c
65878a
@@ -3443,6 +3443,7 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
65878a
 static void service_notify_message(Unit *u, pid_t pid, char **tags) {
65878a
         Service *s = SERVICE(u);
65878a
         const char *e;
65878a
+        bool notify_dbus = false;
65878a
 
65878a
         assert(u);
65878a
 
65878a
@@ -3478,6 +3479,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
65878a
                                        "%s: got %s", u->id, e);
65878a
                         service_set_main_pid(s, pid);
65878a
                         unit_watch_pid(UNIT(s), pid);
65878a
+                        notify_dbus = true;
65878a
                 }
65878a
         }
65878a
 
65878a
@@ -3516,12 +3518,34 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
65878a
 
65878a
                         free(s->status_text);
65878a
                         s->status_text = t;
65878a
-                } else {
65878a
+                } else
65878a
+                        t = NULL;
65878a
+
65878a
+                if (!streq_ptr(s->status_text, t)) {
65878a
                         free(s->status_text);
65878a
-                        s->status_text = NULL;
65878a
-                }
65878a
+                        s->status_text = t;
65878a
+                        notify_dbus = true;
65878a
+                } else
65878a
+                        free(t);
65878a
+        }
65878a
+
65878a
+        /* Interpret ERRNO= */
65878a
+        e = strv_find_prefix(tags, "ERRNO=");
65878a
+        if (e) {
65878a
+                int status_errno;
65878a
 
65878a
+                if (safe_atoi(e + 6, &status_errno) < 0)
65878a
+                        log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e);
65878a
+                else {
65878a
+                        log_debug_unit(u->id, "%s: got %s", u->id, e);
65878a
+
65878a
+                        if (s->status_errno != status_errno) {
65878a
+                                s->status_errno = status_errno;
65878a
+                                notify_dbus = true;
65878a
+                        }
65878a
+                }
65878a
         }
65878a
+
65878a
         if (strv_find(tags, "WATCHDOG=1")) {
65878a
                 log_debug_unit(u->id,
65878a
                                "%s: got WATCHDOG=1", u->id);
65878a
@@ -3530,7 +3554,8 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
65878a
         }
65878a
 
65878a
         /* Notify clients about changed status or main pid */
65878a
-        unit_add_to_dbus_queue(u);
65878a
+        if (notify_dbus)
65878a
+                unit_add_to_dbus_queue(u);
65878a
 }
65878a
 
65878a
 #ifdef HAVE_SYSV_COMPAT
65878a
diff --git a/src/core/service.h b/src/core/service.h
65878a
index ce5b5e0..fa4ef2b 100644
65878a
--- a/src/core/service.h
65878a
+++ b/src/core/service.h
65878a
@@ -187,6 +187,7 @@ struct Service {
65878a
         char *bus_name;
65878a
 
65878a
         char *status_text;
65878a
+        int status_errno;
65878a
 
65878a
         RateLimit start_limit;
65878a
         StartLimitAction start_limit_action;