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.
234 lines
10 KiB
234 lines
10 KiB
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; |
|
} |
|
}
|
|
|