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