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