summaryrefslogtreecommitdiff
path: root/src/systemctl/systemctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r--src/systemctl/systemctl.c235
1 files changed, 123 insertions, 112 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 784c1cd7b5..0dfdae4538 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -588,7 +588,8 @@ static int get_unit_list(
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
+ if (r < 0 && (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD) ||
+ sd_bus_error_has_name(&error, SD_BUS_ERROR_ACCESS_DENIED))) {
/* Fallback to legacy ListUnitsFiltered method */
fallback = true;
log_debug_errno(r, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error, r));
@@ -734,12 +735,12 @@ static int list_units(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
r = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (r < 0)
return r;
@@ -946,12 +947,12 @@ static int list_sockets(int argc, char *argv[], void *userdata) {
int r = 0, n;
sd_bus *bus;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -1253,12 +1254,12 @@ static int list_timers(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r = 0;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -1424,8 +1425,6 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
int r;
bool fallback = false;
- pager_open(arg_no_pager, false);
-
if (install_client_side()) {
Hashmap *h;
UnitFileList *u;
@@ -1540,6 +1539,8 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
return bus_log_parse_error(r);
}
+ pager_open(arg_no_pager, false);
+
qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
output_unit_file_list(units, c);
@@ -1788,12 +1789,12 @@ static int list_dependencies(int argc, char *argv[], void *userdata) {
} else
u = SPECIAL_DEFAULT_TARGET;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
puts(u);
return list_dependencies_one(bus, u, 0, &units, 0);
@@ -2019,8 +2020,6 @@ static int list_machines(int argc, char *argv[], void *userdata) {
return -EPERM;
}
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
@@ -2029,6 +2028,8 @@ static int list_machines(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
output_machines_list(machine_infos, r);
free_machines_list(machine_infos, r);
@@ -2232,8 +2233,6 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
int r;
bool skipped = false;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
@@ -2274,6 +2273,8 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
+ pager_open(arg_no_pager, false);
+
output_jobs_list(jobs, c, skipped);
return 0;
}
@@ -2286,12 +2287,12 @@ static int cancel_job(int argc, char *argv[], void *userdata) {
if (argc <= 1)
return trivial_method(argc, argv, userdata);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
STRV_FOREACH(name, strv_skip(argv, 1)) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
uint32_t id;
@@ -2827,13 +2828,13 @@ static int start_unit(int argc, char *argv[], void *userdata) {
char **name;
int r = 0;
- ask_password_agent_open_if_enabled();
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ ask_password_agent_open_if_enabled();
+ polkit_agent_open_if_enabled();
+
if (arg_action == ACTION_SYSTEMCTL) {
enum action action;
@@ -2953,9 +2954,6 @@ static int logind_reboot(enum action a) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
- (void) logind_set_wall_message();
-
r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
@@ -2991,6 +2989,9 @@ static int logind_reboot(enum action a) {
return -EINVAL;
}
+ polkit_agent_open_if_enabled();
+ (void) logind_set_wall_message();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -3337,12 +3338,12 @@ static int kill_unit(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r, q;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
if (!arg_kill_who)
arg_kill_who = "all";
@@ -3847,14 +3848,13 @@ static void print_status_info(
printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
}
- if (i->control_group)
- printf(" CGroup: %s\n", i->control_group);
-
- {
+ if (i->control_group) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
static const char prefix[] = " ";
unsigned c;
+ printf(" CGroup: %s\n", i->control_group);
+
c = columns();
if (c > sizeof(prefix) - 1)
c -= sizeof(prefix) - 1;
@@ -4559,12 +4559,20 @@ static int show_one(
const char *verb,
sd_bus *bus,
const char *path,
+ const char *unit,
bool show_properties,
bool *new_line,
bool *ellipsized) {
+ static const struct bus_properties_map property_map[] = {
+ { "LoadState", "s", NULL, offsetof(UnitStatusInfo, load_state) },
+ { "ActiveState", "s", NULL, offsetof(UnitStatusInfo, active_state) },
+ {}
+ };
+
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_set_free_ Set *found_properties = NULL;
UnitStatusInfo info = {
.memory_current = (uint64_t) -1,
.memory_high = CGROUP_LIMIT_MAX,
@@ -4574,14 +4582,6 @@ static int show_one(
.tasks_current = (uint64_t) -1,
.tasks_max = (uint64_t) -1,
};
- struct property_info {
- const char *load_state, *active_state;
- } property_info = {};
- static const struct bus_properties_map property_map[] = {
- { "LoadState", "s", NULL, offsetof(struct property_info, load_state) },
- { "ActiveState", "s", NULL, offsetof(struct property_info, active_state) },
- {}
- };
ExecStatusInfo *p;
int r;
@@ -4602,16 +4602,24 @@ static int show_one(
if (r < 0)
return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
- r = bus_message_map_all_properties(reply, property_map, &property_info);
- if (r < 0)
- return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
+ if (unit) {
+ r = bus_message_map_all_properties(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(property_info.load_state, "not-found") && streq_ptr(property_info.active_state, "inactive"))
- return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
+ if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
+ log_error("Unit %s could not be found.", unit);
- r = sd_bus_message_rewind(reply, true);
- if (r < 0)
- return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
+ 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)
@@ -4637,9 +4645,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;
@@ -4661,35 +4677,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(bus, &info, ellipsized);
+
+ if (info.active_state && STR_IN_SET(info.active_state, "inactive", "failed"))
+ r = EXIT_PROGRAM_NOT_RUNNING;
else
- print_status_info(bus, &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);
@@ -4762,7 +4773,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)
@@ -4844,6 +4855,10 @@ static int show(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
pager_open(arg_no_pager, false);
if (show_status)
@@ -4852,17 +4867,12 @@ static int show(int argc, char *argv[], void *userdata) {
* be split up into many files. */
setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
- r = acquire_bus(BUS_MANAGER, &bus);
- if (r < 0)
- return r;
-
/* If no argument is specified inspect the manager itself */
if (show_properties && argc <= 1)
- return show_one(argv[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
+ return show_one(argv[0], bus, "/org/freedesktop/systemd1", NULL, show_properties, &new_line, &ellipsized);
if (show_status && argc <= 1) {
- pager_open(arg_no_pager, false);
show_system_status(bus);
new_line = true;
@@ -4873,7 +4883,7 @@ static int show(int argc, char *argv[], void *userdata) {
char **name;
STRV_FOREACH(name, strv_skip(argv, 1)) {
- _cleanup_free_ char *unit = NULL;
+ _cleanup_free_ char *path = NULL, *unit = NULL;
uint32_t id;
if (safe_atou32(*name, &id) < 0) {
@@ -4883,19 +4893,23 @@ static int show(int argc, char *argv[], void *userdata) {
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(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
+ r = show_one(argv[0], bus, path, unit, show_properties, &new_line, &ellipsized);
if (r < 0)
return r;
else if (r > 0 && ret == 0)
@@ -4910,20 +4924,17 @@ static int show(int argc, char *argv[], void *userdata) {
return 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(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
+ r = show_one(argv[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;
-
- if (r == EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN)
- log_error("Can't display property %s. Unit %s does not exist.", *patterns, *name);
}
}
}
@@ -5018,12 +5029,12 @@ static int set_property(int argc, char *argv[], void *userdata) {
char **i;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5070,12 +5081,12 @@ static int daemon_reload(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
switch (arg_action) {
case ACTION_RELOAD:
@@ -5130,12 +5141,12 @@ static int trivial_method(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
method =
streq(argv[0], "clear-jobs") ||
streq(argv[0], "cancel") ? "ClearJobs" :
@@ -5173,12 +5184,12 @@ static int reset_failed(int argc, char *argv[], void *userdata) {
if (argc <= 1)
return trivial_method(argc, argv, userdata);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
@@ -5212,12 +5223,12 @@ static int show_environment(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
r = sd_bus_get_property(
bus,
"org.freedesktop.systemd1",
@@ -5321,12 +5332,12 @@ static int set_environment(int argc, char *argv[], void *userdata) {
assert(argc > 1);
assert(argv);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
method = streq(argv[0], "set-environment")
? "SetEnvironment"
: "UnsetEnvironment";
@@ -5358,12 +5369,12 @@ static int import_environment(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5655,12 +5666,12 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
const char *method;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
if (streq(verb, "enable")) {
method = "EnableUnitFiles";
expect_carries_install_info = true;
@@ -5821,12 +5832,12 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5883,12 +5894,12 @@ static int preset_all(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -7709,8 +7720,6 @@ static int logind_schedule_shutdown(void) {
sd_bus *bus;
int r;
- (void) logind_set_wall_message();
-
r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
@@ -7737,6 +7746,8 @@ static int logind_schedule_shutdown(void) {
if (arg_dry)
action = strjoina("dry-", action);
+ (void) logind_set_wall_message();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -7927,6 +7938,8 @@ int main(int argc, char*argv[]) {
}
finish:
+ release_busses();
+
pager_close();
ask_password_agent_close();
polkit_agent_close();
@@ -7938,8 +7951,6 @@ finish:
strv_free(arg_wall);
free(arg_root);
- release_busses();
-
/* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
return r < 0 ? EXIT_FAILURE : r;
}