mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
systemctl: is-*: return correct code when no unit is found
According to systemctl(1), we should use LSB return code 4 (EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN) when the state is "no such unit" for is-{active,failed,enabled} verbs. Fixes #25680
This commit is contained in:
parent
09e917ea4d
commit
43e48a4738
@ -13,8 +13,8 @@ static int check_unit_generic(int code, const UnitActiveState good_states[], int
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
UnitActiveState active_state;
|
||||
sd_bus *bus;
|
||||
bool not_found = true, ok = false;
|
||||
int r;
|
||||
bool found = false;
|
||||
|
||||
r = acquire_bus(BUS_MANAGER, &bus);
|
||||
if (r < 0)
|
||||
@ -25,21 +25,32 @@ static int check_unit_generic(int code, const UnitActiveState good_states[], int
|
||||
return log_error_errno(r, "Failed to expand names: %m");
|
||||
|
||||
STRV_FOREACH(name, names) {
|
||||
_cleanup_free_ char *load_state = NULL;
|
||||
|
||||
r = get_state_one_unit(bus, *name, &active_state);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_load_state(bus, *name, &load_state);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!arg_quiet)
|
||||
puts(unit_active_state_to_string(active_state));
|
||||
|
||||
for (int i = 0; i < nb_states; ++i)
|
||||
if (good_states[i] == active_state)
|
||||
found = true;
|
||||
if (good_states[i] == active_state) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* use the given return code for the case that we won't find
|
||||
* any unit which matches the list */
|
||||
return found ? 0 : code;
|
||||
if (!streq(load_state, "not-found"))
|
||||
not_found = false;
|
||||
}
|
||||
|
||||
/* We use LSB code 4 ("program or service status is unknown")
|
||||
* when the corresponding unit file doesn't exist. */
|
||||
return ok ? EXIT_SUCCESS : not_found ? EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN : code;
|
||||
}
|
||||
|
||||
int verb_is_active(int argc, char *argv[], void *userdata) {
|
||||
|
@ -58,7 +58,7 @@ static int show_installation_targets(sd_bus *bus, const char *name) {
|
||||
|
||||
int verb_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
bool enabled;
|
||||
bool not_found, enabled;
|
||||
int r;
|
||||
|
||||
r = mangle_names("to check", strv_skip(argv, 1), &names);
|
||||
@ -69,15 +69,22 @@ int verb_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
enabled = r > 0;
|
||||
not_found = r == 0; /* Doesn't have SysV support or SYSV_UNIT_NOT_FOUND */
|
||||
enabled = r == SYSV_UNIT_ENABLED;
|
||||
|
||||
if (install_client_side()) {
|
||||
STRV_FOREACH(name, names) {
|
||||
UnitFileState state;
|
||||
|
||||
r = unit_file_get_state(arg_scope, arg_root, *name, &state);
|
||||
if (r < 0)
|
||||
if (r == -ENOENT) {
|
||||
if (!arg_quiet)
|
||||
puts("not-found");
|
||||
continue;
|
||||
} else if (r < 0)
|
||||
return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
|
||||
else
|
||||
not_found = false;
|
||||
|
||||
if (IN_SET(state,
|
||||
UNIT_FILE_ENABLED,
|
||||
@ -112,8 +119,19 @@ int verb_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
const char *s;
|
||||
|
||||
r = bus_call_method(bus, bus_systemd_mgr, "GetUnitFileState", &error, &reply, "s", *name);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
|
||||
if (r == -ENOENT) {
|
||||
sd_bus_error_free(&error);
|
||||
|
||||
if (!arg_quiet)
|
||||
puts("not-found");
|
||||
continue;
|
||||
} else if (r < 0)
|
||||
return log_error_errno(r,
|
||||
"Failed to get unit file state for %s: %s",
|
||||
*name,
|
||||
bus_error_message(&error, r));
|
||||
else
|
||||
not_found = false;
|
||||
|
||||
r = sd_bus_message_read(reply, "s", &s);
|
||||
if (r < 0)
|
||||
@ -133,5 +151,5 @@ int verb_is_enabled(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
}
|
||||
|
||||
return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
return enabled ? EXIT_SUCCESS : not_found ? EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN : EXIT_FAILURE;
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ int enable_sysv_units(const char *verb, char **args) {
|
||||
#if HAVE_SYSV_COMPAT
|
||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||
unsigned f = 0;
|
||||
SysVUnitEnableState enable_state = SYSV_UNIT_NOT_FOUND;
|
||||
|
||||
/* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
|
||||
|
||||
@ -226,10 +227,12 @@ int enable_sysv_units(const char *verb, char **args) {
|
||||
if (j == EXIT_SUCCESS) {
|
||||
if (!arg_quiet)
|
||||
puts("enabled");
|
||||
r = 1;
|
||||
enable_state = SYSV_UNIT_ENABLED;
|
||||
} else {
|
||||
if (!arg_quiet)
|
||||
puts("disabled");
|
||||
if (enable_state != SYSV_UNIT_ENABLED)
|
||||
enable_state = SYSV_UNIT_DISABLED;
|
||||
}
|
||||
|
||||
} else if (j != EXIT_SUCCESS)
|
||||
@ -245,6 +248,8 @@ int enable_sysv_units(const char *verb, char **args) {
|
||||
strv_remove(args + f, name);
|
||||
}
|
||||
|
||||
if (streq(verb, "is-enabled"))
|
||||
return enable_state;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
@ -30,6 +30,12 @@ enum {
|
||||
EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN = 4,
|
||||
};
|
||||
|
||||
typedef enum SysVUnitEnableState {
|
||||
SYSV_UNIT_NOT_FOUND = 0,
|
||||
SYSV_UNIT_DISABLED,
|
||||
SYSV_UNIT_ENABLED,
|
||||
} SysVUnitEnableState;
|
||||
|
||||
int enable_sysv_units(const char *verb, char **args);
|
||||
|
||||
int action_to_runlevel(void) _pure_;
|
||||
|
Loading…
Reference in New Issue
Block a user