ryantimwilson / rpms / systemd

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