Blame SOURCES/0343-systemctl-rework-systemctl-status-a-bit.patch

17b0f1
From 41bb37959c96b8fddc13b37384b3453393517f4f Mon Sep 17 00:00:00 2001
17b0f1
From: Lennart Poettering <lennart@poettering.net>
17b0f1
Date: Mon, 13 Jun 2016 19:11:26 +0200
17b0f1
Subject: [PATCH] systemctl: rework "systemctl status" a bit
17b0f1
17b0f1
This reworks "systemctl status" and "systemctl show" a bit. It removes the
17b0f1
definition of the `property_info` structure, because we can simply reuse the
17b0f1
existing UnitStatusInfo type for that.
17b0f1
17b0f1
The "could not be found" message is now printed by show_one() itself (and not
17b0f1
its caller), so that it is shown regardless by who the function is called.
17b0f1
(This makes it necessary to pass the unit name to the function.)
17b0f1
17b0f1
This also adds all properties found to a set, and then checks if any of the
17b0f1
properties passed via "--property=" is mising in it, if so, a proper error is
17b0f1
generated.
17b0f1
17b0f1
Support for checking the PID file of a unit is removed, as this cannot be done
17b0f1
reasonably client side (since the systemd instance we are talking to might sit
17b0f1
on another host)
17b0f1
17b0f1
Replaces: #3411
17b0f1
Fixes: #3425
17b0f1
Also see: #3504
17b0f1
17b0f1
(cherry picked from commit 3dced37b7c2c9a5c733817569d2bbbaa397adaf7)
17b0f1
Related: #1047466
17b0f1
---
17b0f1
 src/systemctl/systemctl.c | 106 ++++++++++++++++++++++++--------------
17b0f1
 1 file changed, 68 insertions(+), 38 deletions(-)
17b0f1
17b0f1
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
17b0f1
index fdda174ae7..93b7a193b2 100644
17b0f1
--- a/src/systemctl/systemctl.c
17b0f1
+++ b/src/systemctl/systemctl.c
17b0f1
@@ -4211,12 +4211,19 @@ static int show_one(
17b0f1
                 const char *verb,
17b0f1
                 sd_bus *bus,
17b0f1
                 const char *path,
17b0f1
+                const char *unit,
17b0f1
                 bool show_properties,
17b0f1
                 bool *new_line,
17b0f1
                 bool *ellipsized) {
17b0f1
 
17b0f1
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
17b0f1
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
17b0f1
+        _cleanup_set_free_ Set *found_properties = NULL;
17b0f1
+        static const struct bus_properties_map property_map[] = {
17b0f1
+                { "LoadState",   "s", NULL, offsetof(UnitStatusInfo, load_state)   },
17b0f1
+                { "ActiveState", "s", NULL, offsetof(UnitStatusInfo, active_state) },
17b0f1
+                {}
17b0f1
+        };
17b0f1
         UnitStatusInfo info = {
17b0f1
                 .memory_current = (uint64_t) -1,
17b0f1
                 .memory_limit = (uint64_t) -1,
17b0f1
@@ -4243,6 +4250,25 @@ static int show_one(
17b0f1
                 return r;
17b0f1
         }
17b0f1
 
17b0f1
+        if (unit) {
17b0f1
+                r = bus_message_map_all_properties(bus, reply, property_map, &info;;
17b0f1
+                if (r < 0)
17b0f1
+                        return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
17b0f1
+
17b0f1
+                if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
17b0f1
+                        log_error("Unit %s could not be found.", unit);
17b0f1
+
17b0f1
+                        if (streq(verb, "status"))
17b0f1
+                                return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
17b0f1
+
17b0f1
+                        return -ENOENT;
17b0f1
+                }
17b0f1
+
17b0f1
+                r = sd_bus_message_rewind(reply, true);
17b0f1
+                if (r < 0)
17b0f1
+                        return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
17b0f1
+        }
17b0f1
+
17b0f1
         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
17b0f1
         if (r < 0)
17b0f1
                 return bus_log_parse_error(r);
17b0f1
@@ -4267,9 +4293,17 @@ static int show_one(
17b0f1
                 if (r < 0)
17b0f1
                         return bus_log_parse_error(r);
17b0f1
 
17b0f1
-                if (show_properties)
17b0f1
+                if (show_properties) {
17b0f1
+                        r = set_ensure_allocated(&found_properties, &string_hash_ops);
17b0f1
+                        if (r < 0)
17b0f1
+                                return log_oom();
17b0f1
+
17b0f1
+                        r = set_put(found_properties, name);
17b0f1
+                        if (r < 0 && r != EEXIST)
17b0f1
+                                return log_oom();
17b0f1
+
17b0f1
                         r = print_property(name, reply, contents);
17b0f1
-                else
17b0f1
+                } else
17b0f1
                         r = status_property(name, reply, &info, contents);
17b0f1
                 if (r < 0)
17b0f1
                         return r;
17b0f1
@@ -4291,35 +4325,30 @@ static int show_one(
17b0f1
 
17b0f1
         r = 0;
17b0f1
 
17b0f1
-        if (!show_properties) {
17b0f1
-                if (streq(verb, "help"))
17b0f1
-                        show_unit_help(&info;;
17b0f1
+        if (show_properties) {
17b0f1
+                char **pp;
17b0f1
+
17b0f1
+                STRV_FOREACH(pp, arg_properties) {
17b0f1
+                        if (!set_contains(found_properties, *pp)) {
17b0f1
+                                log_warning("Property %s does not exist.", *pp);
17b0f1
+                                r = -ENXIO;
17b0f1
+                        }
17b0f1
+                }
17b0f1
+        } else if (streq(verb, "help"))
17b0f1
+                show_unit_help(&info;;
17b0f1
+        else if (streq(verb, "status")) {
17b0f1
+                print_status_info(&info, ellipsized);
17b0f1
+
17b0f1
+                if (info.active_state && STR_IN_SET(info.active_state, "inactive", "failed"))
17b0f1
+                        r = EXIT_PROGRAM_NOT_RUNNING;
17b0f1
                 else
17b0f1
-                        print_status_info(&info, ellipsized);
17b0f1
+                        r = EXIT_PROGRAM_RUNNING_OR_SERVICE_OK;
17b0f1
         }
17b0f1
 
17b0f1
         strv_free(info.documentation);
17b0f1
         strv_free(info.dropin_paths);
17b0f1
         strv_free(info.listen);
17b0f1
 
17b0f1
-        if (!streq_ptr(info.active_state, "active") &&
17b0f1
-            !streq_ptr(info.active_state, "reloading") &&
17b0f1
-            streq(verb, "status")) {
17b0f1
-                /* According to LSB: "program not running" */
17b0f1
-                /* 0: program is running or service is OK
17b0f1
-                 * 1: program is dead and /run PID file exists
17b0f1
-                 * 2: program is dead and /run/lock lock file exists
17b0f1
-                 * 3: program is not running
17b0f1
-                 * 4: program or service status is unknown
17b0f1
-                 */
17b0f1
-                if (info.pid_file && access(info.pid_file, F_OK) == 0)
17b0f1
-                        r = EXIT_PROGRAM_DEAD_AND_PID_EXISTS;
17b0f1
-                else if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive"))
17b0f1
-                        r = EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
17b0f1
-                else
17b0f1
-                        r = EXIT_PROGRAM_NOT_RUNNING;
17b0f1
-        }
17b0f1
-
17b0f1
         while ((p = info.exec)) {
17b0f1
                 LIST_REMOVE(exec, info.exec, p);
17b0f1
                 exec_status_info_free(p);
17b0f1
@@ -4394,7 +4423,7 @@ static int show_all(
17b0f1
                 if (!p)
17b0f1
                         return log_oom();
17b0f1
 
17b0f1
-                r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
17b0f1
+                r = show_one(verb, bus, p, u->id, show_properties, new_line, ellipsized);
17b0f1
                 if (r < 0)
17b0f1
                         return r;
17b0f1
                 else if (r > 0 && ret == 0)
17b0f1
@@ -4481,9 +4510,8 @@ static int show(sd_bus *bus, char **args) {
17b0f1
                 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
17b0f1
 
17b0f1
         /* If no argument is specified inspect the manager itself */
17b0f1
-
17b0f1
         if (show_properties && strv_length(args) <= 1)
17b0f1
-                return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
17b0f1
+                return show_one(args[0], bus, "/org/freedesktop/systemd1", NULL, show_properties, &new_line, &ellipsized);
17b0f1
 
17b0f1
         if (show_status && strv_length(args) <= 1) {
17b0f1
 
17b0f1
@@ -4498,7 +4526,7 @@ static int show(sd_bus *bus, char **args) {
17b0f1
                 char **name;
17b0f1
 
17b0f1
                 STRV_FOREACH(name, args + 1) {
17b0f1
-                        _cleanup_free_ char *unit = NULL;
17b0f1
+                        _cleanup_free_ char *path = NULL, *unit = NULL;
17b0f1
                         uint32_t id;
17b0f1
 
17b0f1
                         if (safe_atou32(*name, &id) < 0) {
17b0f1
@@ -4508,20 +4536,23 @@ static int show(sd_bus *bus, char **args) {
17b0f1
                                 continue;
17b0f1
                         } else if (show_properties) {
17b0f1
                                 /* Interpret as job id */
17b0f1
-                                if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
17b0f1
+                                if (asprintf(&path, "/org/freedesktop/systemd1/job/%u", id) < 0)
17b0f1
                                         return log_oom();
17b0f1
 
17b0f1
                         } else {
17b0f1
                                 /* Interpret as PID */
17b0f1
-                                r = get_unit_dbus_path_by_pid(bus, id, &unit);
17b0f1
+                                r = get_unit_dbus_path_by_pid(bus, id, &path);
17b0f1
                                 if (r < 0) {
17b0f1
                                         ret = r;
17b0f1
                                         continue;
17b0f1
                                 }
17b0f1
+
17b0f1
+                                r = unit_name_from_dbus_path(path, &unit);
17b0f1
+                                if (r < 0)
17b0f1
+                                        return log_oom();
17b0f1
                         }
17b0f1
 
17b0f1
-                        r = show_one(args[0], bus, unit, show_properties,
17b0f1
-                                     &new_line, &ellipsized);
17b0f1
+                        r = show_one(args[0], bus, path, unit, show_properties, &new_line, &ellipsized);
17b0f1
                         if (r < 0)
17b0f1
                                 return r;
17b0f1
                         else if (r > 0 && ret == 0)
17b0f1
@@ -4536,17 +4567,16 @@ static int show(sd_bus *bus, char **args) {
17b0f1
                                 log_error_errno(r, "Failed to expand names: %m");
17b0f1
 
17b0f1
                         STRV_FOREACH(name, names) {
17b0f1
-                                _cleanup_free_ char *unit;
17b0f1
+                                _cleanup_free_ char *path;
17b0f1
 
17b0f1
-                                unit = unit_dbus_path_from_name(*name);
17b0f1
-                                if (!unit)
17b0f1
+                                path = unit_dbus_path_from_name(*name);
17b0f1
+                                if (!path)
17b0f1
                                         return log_oom();
17b0f1
 
17b0f1
-                                r = show_one(args[0], bus, unit, show_properties,
17b0f1
-                                             &new_line, &ellipsized);
17b0f1
+                                r = show_one(args[0], bus, path, *name, show_properties, &new_line, &ellipsized);
17b0f1
                                 if (r < 0)
17b0f1
                                         return r;
17b0f1
-                                else if (r > 0 && ret == 0)
17b0f1
+                                if (r > 0 && ret == 0)
17b0f1
                                         ret = r;
17b0f1
                         }
17b0f1
                 }