summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/mount-util.c2
-rw-r--r--src/core/dbus-manager.c81
-rw-r--r--src/core/dbus-service.c6
-rw-r--r--src/core/dbus-unit.c6
-rw-r--r--src/core/emergency-action.c (renamed from src/core/failure-action.c)65
-rw-r--r--src/core/emergency-action.h (renamed from src/core/failure-action.h)28
-rw-r--r--src/core/execute.c238
-rw-r--r--src/core/job.c2
-rw-r--r--src/core/load-fragment-gperf.gperf.m48
-rw-r--r--src/core/load-fragment.c4
-rw-r--r--src/core/load-fragment.h2
-rw-r--r--src/core/main.c9
-rw-r--r--src/core/manager.c33
-rw-r--r--src/core/manager.h13
-rw-r--r--src/core/org.freedesktop.systemd1.conf4
-rw-r--r--src/core/service.c2
-rw-r--r--src/core/service.h2
-rw-r--r--src/core/unit.c6
-rw-r--r--src/core/unit.h6
-rw-r--r--src/journal/journald-server.c2
-rw-r--r--src/network/networkd-ndisc.c28
-rw-r--r--src/nspawn/nspawn-mount.c55
-rw-r--r--src/nspawn/nspawn.c8
-rw-r--r--src/shared/install.c99
-rw-r--r--src/shared/install.h34
-rw-r--r--src/systemctl/systemctl.c102
-rw-r--r--src/test/test-execute.c10
-rw-r--r--src/test/test-install-root.c62
-rw-r--r--src/test/test-install.c38
-rw-r--r--src/test/test-tables.c2
30 files changed, 618 insertions, 339 deletions
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 0ef00676ef..2985cc475a 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -162,7 +162,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
fallback_fdinfo:
r = fd_fdinfo_mnt_id(fd, filename, flags, &mount_id);
- if (r == -EOPNOTSUPP)
+ if (IN_SET(r, -EOPNOTSUPP, -EACCES))
goto fallback_fstat;
if (r < 0)
return r;
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 12eb55cb7f..d7d3d3c8ce 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -47,6 +47,11 @@
#include "virt.h"
#include "watchdog.h"
+static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
+ return (runtime ? UNIT_FILE_RUNTIME : 0) |
+ (force ? UNIT_FILE_FORCE : 0);
+}
+
static int property_get_version(
sd_bus *bus,
const char *path,
@@ -1948,13 +1953,14 @@ static int install_error(
static int method_enable_unit_files_generic(
sd_bus_message *message,
Manager *m,
- int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
+ int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
bool carries_install_info,
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
+ UnitFileFlags flags;
int runtime, force, r;
assert(message);
@@ -1968,13 +1974,15 @@ static int method_enable_unit_files_generic(
if (r < 0)
return r;
+ flags = unit_file_bools_to_flags(runtime, force);
+
r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes);
+ r = call(m->unit_file_scope, flags, NULL, l, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@@ -1993,8 +2001,8 @@ static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bu
return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
}
-static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
- return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
+static int unit_file_preset_without_mode(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes) {
+ return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
}
static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2013,6 +2021,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
Manager *m = userdata;
UnitFilePresetMode mm;
int runtime, force, r;
+ UnitFileFlags flags;
const char *mode;
assert(message);
@@ -2026,6 +2035,8 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r < 0)
return r;
+ flags = unit_file_bools_to_flags(runtime, force);
+
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
else {
@@ -2040,7 +2051,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes);
+ r = unit_file_preset(m->unit_file_scope, flags, NULL, l, mm, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@@ -2050,7 +2061,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
static int method_disable_unit_files_generic(
sd_bus_message *message,
Manager *m,
- int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
+ int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
@@ -2075,7 +2086,7 @@ static int method_disable_unit_files_generic(
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes);
+ r = call(m->unit_file_scope, runtime ? UNIT_FILE_RUNTIME : 0, NULL, l, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@@ -2141,7 +2152,7 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes);
+ r = unit_file_set_default(m->unit_file_scope, force ? UNIT_FILE_FORCE : 0, NULL, name, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@@ -2154,6 +2165,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
Manager *m = userdata;
UnitFilePresetMode mm;
const char *mode;
+ UnitFileFlags flags;
int force, runtime, r;
assert(message);
@@ -2167,6 +2179,8 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r < 0)
return r;
+ flags = unit_file_bools_to_flags(runtime, force);
+
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
else {
@@ -2181,7 +2195,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = unit_file_preset_all(m->unit_file_scope, runtime, NULL, mm, force, &changes, &n_changes);
+ r = unit_file_preset_all(m->unit_file_scope, flags, NULL, mm, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@@ -2196,6 +2210,7 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
int runtime, force, r;
char *target, *type;
UnitDependency dep;
+ UnitFileFlags flags;
assert(message);
assert(m);
@@ -2214,17 +2229,62 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
if (r < 0)
return r;
+ flags = unit_file_bools_to_flags(runtime, force);
+
dep = unit_dependency_from_string(type);
if (dep < 0)
return -EINVAL;
- r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
+ r = unit_file_add_dependency(m->unit_file_scope, flags, NULL, l, target, dep, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
+static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0, i;
+ UnitFileFlags flags;
+ const char *name;
+ char **p;
+ int runtime, r;
+
+ r = sd_bus_message_read(message, "sb", &name, &runtime);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "s");
+ if (r < 0)
+ return r;
+
+ p = STRV_MAKE(name);
+ flags = UNIT_FILE_DRY_RUN |
+ (runtime ? UNIT_FILE_RUNTIME : 0);
+
+ r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get file links for %s: %m", name);
+
+ for (i = 0; i < n_changes; i++)
+ if (changes[i].type == UNIT_FILE_UNLINK) {
+ r = sd_bus_message_append(reply, "s", changes[i].path);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -2370,6 +2430,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUnitFileLinks", "sb", "as", method_get_unit_file_links, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("LookupDynamicUserByName", "s", "u", method_lookup_dynamic_user_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("LookupDynamicUserByUID", "u", "s", method_lookup_dynamic_user_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 3c55e0f7fe..61b83d2d62 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -36,7 +36,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
const sd_bus_vtable bus_service_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -50,7 +50,7 @@ const sd_bus_vtable bus_service_vtable[] = {
SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec, offsetof(Service, runtime_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
- SD_BUS_PROPERTY("FailureAction", "s", property_get_failure_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Service, emergency_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -79,7 +79,7 @@ const sd_bus_vtable bus_service_vtable[] = {
/* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_VTABLE_END
};
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 245912fc0f..8f34fa1a52 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -37,7 +37,7 @@
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
static int property_get_names(
sd_bus *bus,
@@ -750,7 +750,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_failure_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("AssertResult", "b", bus_property_get_bool, offsetof(Unit, assert_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -762,7 +762,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0),
diff --git a/src/core/failure-action.c b/src/core/emergency-action.c
index ddae46190f..90232bc57a 100644
--- a/src/core/failure-action.c
+++ b/src/core/emergency-action.c
@@ -23,59 +23,60 @@
#include "bus-error.h"
#include "bus-util.h"
-#include "failure-action.h"
+#include "emergency-action.h"
#include "special.h"
#include "string-table.h"
#include "terminal-util.h"
-static void log_and_status(Manager *m, const char *message) {
- log_warning("%s", message);
+static void log_and_status(Manager *m, const char *message, const char *reason) {
+ log_warning("%s: %s", message, reason);
manager_status_printf(m, STATUS_TYPE_EMERGENCY,
ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL,
- "%s", message);
+ "%s: %s", message, reason);
}
-int failure_action(
+int emergency_action(
Manager *m,
- FailureAction action,
- const char *reboot_arg) {
+ EmergencyAction action,
+ const char *reboot_arg,
+ const char *reason) {
assert(m);
assert(action >= 0);
- assert(action < _FAILURE_ACTION_MAX);
+ assert(action < _EMERGENCY_ACTION_MAX);
- if (action == FAILURE_ACTION_NONE)
+ if (action == EMERGENCY_ACTION_NONE)
return -ECANCELED;
if (!MANAGER_IS_SYSTEM(m)) {
/* Downgrade all options to simply exiting if we run
* in user mode */
- log_warning("Exiting as result of failure.");
+ log_warning("Exiting: %s", reason);
m->exit_code = MANAGER_EXIT;
return -ECANCELED;
}
switch (action) {
- case FAILURE_ACTION_REBOOT:
- log_and_status(m, "Rebooting as result of failure.");
+ case EMERGENCY_ACTION_REBOOT:
+ log_and_status(m, "Rebooting", reason);
(void) update_reboot_parameter_and_warn(reboot_arg);
(void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
break;
- case FAILURE_ACTION_REBOOT_FORCE:
- log_and_status(m, "Forcibly rebooting as result of failure.");
+ case EMERGENCY_ACTION_REBOOT_FORCE:
+ log_and_status(m, "Forcibly rebooting", reason);
(void) update_reboot_parameter_and_warn(reboot_arg);
m->exit_code = MANAGER_REBOOT;
break;
- case FAILURE_ACTION_REBOOT_IMMEDIATE:
- log_and_status(m, "Rebooting immediately as result of failure.");
+ case EMERGENCY_ACTION_REBOOT_IMMEDIATE:
+ log_and_status(m, "Rebooting immediately", reason);
sync();
@@ -89,18 +90,18 @@ int failure_action(
reboot(RB_AUTOBOOT);
break;
- case FAILURE_ACTION_POWEROFF:
- log_and_status(m, "Powering off as result of failure.");
+ case EMERGENCY_ACTION_POWEROFF:
+ log_and_status(m, "Powering off", reason);
(void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
break;
- case FAILURE_ACTION_POWEROFF_FORCE:
- log_and_status(m, "Forcibly powering off as result of failure.");
+ case EMERGENCY_ACTION_POWEROFF_FORCE:
+ log_and_status(m, "Forcibly powering off", reason);
m->exit_code = MANAGER_POWEROFF;
break;
- case FAILURE_ACTION_POWEROFF_IMMEDIATE:
- log_and_status(m, "Powering off immediately as result of failure.");
+ case EMERGENCY_ACTION_POWEROFF_IMMEDIATE:
+ log_and_status(m, "Powering off immediately", reason);
sync();
@@ -109,19 +110,19 @@ int failure_action(
break;
default:
- assert_not_reached("Unknown failure action");
+ assert_not_reached("Unknown emergency action");
}
return -ECANCELED;
}
-static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
- [FAILURE_ACTION_NONE] = "none",
- [FAILURE_ACTION_REBOOT] = "reboot",
- [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
- [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
- [FAILURE_ACTION_POWEROFF] = "poweroff",
- [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force",
- [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
+static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
+ [EMERGENCY_ACTION_NONE] = "none",
+ [EMERGENCY_ACTION_REBOOT] = "reboot",
+ [EMERGENCY_ACTION_REBOOT_FORCE] = "reboot-force",
+ [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
+ [EMERGENCY_ACTION_POWEROFF] = "poweroff",
+ [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
+ [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
};
-DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
+DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);
diff --git a/src/core/failure-action.h b/src/core/emergency-action.h
index 1adac4ad5c..8804b59752 100644
--- a/src/core/failure-action.h
+++ b/src/core/emergency-action.h
@@ -20,22 +20,22 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef enum FailureAction {
- FAILURE_ACTION_NONE,
- FAILURE_ACTION_REBOOT,
- FAILURE_ACTION_REBOOT_FORCE,
- FAILURE_ACTION_REBOOT_IMMEDIATE,
- FAILURE_ACTION_POWEROFF,
- FAILURE_ACTION_POWEROFF_FORCE,
- FAILURE_ACTION_POWEROFF_IMMEDIATE,
- _FAILURE_ACTION_MAX,
- _FAILURE_ACTION_INVALID = -1
-} FailureAction;
+typedef enum EmergencyAction {
+ EMERGENCY_ACTION_NONE,
+ EMERGENCY_ACTION_REBOOT,
+ EMERGENCY_ACTION_REBOOT_FORCE,
+ EMERGENCY_ACTION_REBOOT_IMMEDIATE,
+ EMERGENCY_ACTION_POWEROFF,
+ EMERGENCY_ACTION_POWEROFF_FORCE,
+ EMERGENCY_ACTION_POWEROFF_IMMEDIATE,
+ _EMERGENCY_ACTION_MAX,
+ _EMERGENCY_ACTION_INVALID = -1
+} EmergencyAction;
#include "macro.h"
#include "manager.h"
-int failure_action(Manager *m, FailureAction action, const char *reboot_arg);
+int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg, const char *reason);
-const char* failure_action_to_string(FailureAction i) _const_;
-FailureAction failure_action_from_string(const char *s) _pure_;
+const char* emergency_action_to_string(EmergencyAction i) _const_;
+EmergencyAction emergency_action_from_string(const char *s) _pure_;
diff --git a/src/core/execute.c b/src/core/execute.c
index 1b7b4a928d..53356c3c06 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -730,74 +730,157 @@ static int ask_for_confirmation(char *response, char **argv) {
return r;
}
-static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
- bool keep_groups = false;
+static int get_fixed_user(const ExecContext *c, const char **user,
+ uid_t *uid, gid_t *gid,
+ const char **home, const char **shell) {
int r;
+ const char *name;
- assert(context);
+ assert(c);
- /* Lookup and set GID and supplementary group list. Here too
- * we avoid NSS lookups for gid=0. */
+ if (!c->user)
+ return 0;
- if (context->group || username) {
- /* First step, initialize groups from /etc/groups */
- if (username && gid != 0) {
- if (initgroups(username, gid) < 0)
- return -errno;
+ /* Note that we don't set $HOME or $SHELL if they are not particularly enlightening anyway
+ * (i.e. are "/" or "/bin/nologin"). */
- keep_groups = true;
- }
+ name = c->user;
+ r = get_user_creds_clean(&name, uid, gid, home, shell);
+ if (r < 0)
+ return r;
- /* Second step, set our gids */
- if (setresgid(gid, gid, gid) < 0)
+ *user = name;
+ return 0;
+}
+
+static int get_fixed_group(const ExecContext *c, const char **group, gid_t *gid) {
+ int r;
+ const char *name;
+
+ assert(c);
+
+ if (!c->group)
+ return 0;
+
+ name = c->group;
+ r = get_group_creds(&name, gid);
+ if (r < 0)
+ return r;
+
+ *group = name;
+ return 0;
+}
+
+static int get_fixed_supplementary_groups(const ExecContext *c,
+ const char *user,
+ const char *group,
+ gid_t gid,
+ gid_t **supplementary_gids, int *ngids) {
+ char **i;
+ int r, k = 0;
+ int ngroups_max;
+ bool keep_groups = false;
+ gid_t *groups = NULL;
+ _cleanup_free_ gid_t *l_gids = NULL;
+
+ assert(c);
+
+ if (!c->supplementary_groups)
+ return 0;
+
+ /*
+ * If SupplementaryGroups= was passed then NGROUPS_MAX has to
+ * be positive, otherwise fail.
+ */
+ errno = 0;
+ ngroups_max = (int) sysconf(_SC_NGROUPS_MAX);
+ if (ngroups_max <= 0) {
+ if (errno > 0)
return -errno;
+ else
+ return -EOPNOTSUPP; /* For all other values */
}
- if (context->supplementary_groups) {
- int ngroups_max, k;
- gid_t *gids;
- char **i;
+ /*
+ * If user is given, then lookup GID and supplementary group list.
+ * We avoid NSS lookups for gid=0.
+ */
+ if (user && gid_is_valid(gid) && gid != 0) {
+ /* First step, initialize groups from /etc/groups */
+ if (initgroups(user, gid) < 0)
+ return -errno;
- /* Final step, initialize any manually set supplementary groups */
- assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
+ keep_groups = true;
+ }
- if (!(gids = new(gid_t, ngroups_max)))
- return -ENOMEM;
+ l_gids = new(gid_t, ngroups_max);
+ if (!l_gids)
+ return -ENOMEM;
- if (keep_groups) {
- k = getgroups(ngroups_max, gids);
- if (k < 0) {
- free(gids);
- return -errno;
- }
- } else
- k = 0;
+ if (keep_groups) {
+ /*
+ * Lookup the list of groups that the user belongs to, we
+ * avoid NSS lookups here too for gid=0.
+ */
+ k = ngroups_max;
+ if (getgrouplist(user, gid, l_gids, &k) < 0)
+ return -EINVAL;
+ } else
+ k = 0;
- STRV_FOREACH(i, context->supplementary_groups) {
- const char *g;
+ STRV_FOREACH(i, c->supplementary_groups) {
+ const char *g;
- if (k >= ngroups_max) {
- free(gids);
- return -E2BIG;
- }
+ if (k >= ngroups_max)
+ return -E2BIG;
- g = *i;
- r = get_group_creds(&g, gids+k);
- if (r < 0) {
- free(gids);
- return r;
- }
+ g = *i;
+ r = get_group_creds(&g, l_gids+k);
+ if (r < 0)
+ return r;
- k++;
- }
+ k++;
+ }
- r = maybe_setgroups(k, gids);
- if (r < 0) {
- free(gids);
+ /*
+ * Sets ngids to zero to drop all supplementary groups, happens
+ * when we are under root and SupplementaryGroups= is empty.
+ */
+ if (k == 0) {
+ *ngids = 0;
+ return 0;
+ }
+
+ /* Otherwise get the final list of supplementary groups */
+ groups = memdup(l_gids, sizeof(gid_t) * k);
+ if (!groups)
+ return -ENOMEM;
+
+ *supplementary_gids = groups;
+ *ngids = k;
+
+ groups = NULL;
+
+ return 0;
+}
+
+static int enforce_groups(const ExecContext *context, gid_t gid,
+ gid_t *supplementary_gids, int ngids) {
+ int r;
+
+ assert(context);
+
+ /* Handle SupplementaryGroups= even if it is empty */
+ if (context->supplementary_groups) {
+ r = maybe_setgroups(ngids, supplementary_gids);
+ if (r < 0)
return r;
- }
+ }
- free(gids);
+ if (gid_is_valid(gid)) {
+ /* Then set our gids */
+ if (setresgid(gid, gid, gid) < 0)
+ return -errno;
}
return 0;
@@ -806,6 +889,9 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
static int enforce_user(const ExecContext *context, uid_t uid) {
assert(context);
+ if (!uid_is_valid(uid))
+ return 0;
+
/* Sets (but doesn't look up) the uid and make sure we keep the
* capabilities while doing so. */
@@ -2175,13 +2261,15 @@ static int exec_child(
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
_cleanup_free_ char *mac_selinux_context_net = NULL;
- const char *username = NULL, *home = NULL, *shell = NULL, *wd;
+ _cleanup_free_ gid_t *supplementary_gids = NULL;
+ const char *username = NULL, *groupname = NULL;
+ const char *home = NULL, *shell = NULL, *wd;
dev_t journal_stream_dev = 0;
ino_t journal_stream_ino = 0;
bool needs_mount_namespace;
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
- int i, r;
+ int i, r, ngids = 0;
assert(unit);
assert(command);
@@ -2273,26 +2361,23 @@ static int exec_child(
username = dcreds->user->name;
} else {
- if (context->user) {
- username = context->user;
- r = get_user_creds_clean(&username, &uid, &gid, &home, &shell);
- if (r < 0) {
- *exit_status = EXIT_USER;
- return r;
- }
-
- /* Note that we don't set $HOME or $SHELL if they are not particularly enlightening anyway
- * (i.e. are "/" or "/bin/nologin"). */
+ r = get_fixed_user(context, &username, &uid, &gid, &home, &shell);
+ if (r < 0) {
+ *exit_status = EXIT_USER;
+ return r;
}
- if (context->group) {
- const char *g = context->group;
+ r = get_fixed_group(context, &groupname, &gid);
+ if (r < 0) {
+ *exit_status = EXIT_GROUP;
+ return r;
+ }
- r = get_group_creds(&g, &gid);
- if (r < 0) {
- *exit_status = EXIT_GROUP;
- return r;
- }
+ r = get_fixed_supplementary_groups(context, username, groupname,
+ gid, &supplementary_gids, &ngids);
+ if (r < 0) {
+ *exit_status = EXIT_GROUP;
+ return r;
}
}
@@ -2558,14 +2643,6 @@ static int exec_child(
}
}
- if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
- r = enforce_groups(context, username, gid);
- if (r < 0) {
- *exit_status = EXIT_GROUP;
- return r;
- }
- }
-
if (context->working_directory_home)
wd = home;
else if (context->working_directory)
@@ -2573,6 +2650,15 @@ static int exec_child(
else
wd = "/";
+ /* Drop group as early as possbile */
+ if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
+ r = enforce_groups(context, gid, supplementary_gids, ngids);
+ if (r < 0) {
+ *exit_status = EXIT_GROUP;
+ return r;
+ }
+ }
+
if (params->flags & EXEC_APPLY_CHROOT) {
if (!needs_mount_namespace && context->root_directory)
if (chroot(context->root_directory) < 0) {
diff --git a/src/core/job.c b/src/core/job.c
index 7faf2ef686..3ecc8a1a73 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -927,7 +927,7 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user
u = j->unit;
job_finish_and_invalidate(j, JOB_TIMEOUT, true, false);
- failure_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg);
+ emergency_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg, "job timed out");
return 0;
}
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 08c88b6b53..af2f9d960b 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -188,13 +188,13 @@ Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0,
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
-Unit.JobTimeoutAction, config_parse_failure_action, 0, offsetof(Unit, job_timeout_action)
+Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg)
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
m4_dnl The following is a legacy alias name for compatibility
Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
-Unit.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
+Unit.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
Unit.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, conditions)
Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, conditions)
@@ -251,9 +251,9 @@ Service.WatchdogSec, config_parse_sec, 0,
m4_dnl The following three only exist for compatibility, they moved into Unit, see above
Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
-Service.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
+Service.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
Service.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
-Service.FailureAction, config_parse_failure_action, 0, offsetof(Service, failure_action)
+Service.FailureAction, config_parse_emergency_action, 0, offsetof(Service, emergency_action)
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
Service.PermissionsStartOnly, config_parse_bool, 0, offsetof(Service, permissions_start_only)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index a69f60097d..6f68e23340 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2523,7 +2523,7 @@ int config_parse_unit_condition_null(
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_failure_action, failure_action, FailureAction, "Failed to parse failure action specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier");
int config_parse_unit_requires_mounts_for(
const char *unit,
@@ -4315,7 +4315,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_unit_slice, "SLICE" },
{ config_parse_documentation, "URL" },
{ config_parse_service_timeout, "SECONDS" },
- { config_parse_failure_action, "ACTION" },
+ { config_parse_emergency_action, "ACTION" },
{ config_parse_set_status, "STATUS" },
{ config_parse_service_sockets, "SOCKETS" },
{ config_parse_environ, "ENVIRON" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 6d1fe55bcd..c05f205c37 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -75,7 +75,7 @@ int config_parse_unit_condition_string(const char *unit, const char *filename, u
int config_parse_unit_condition_null(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_kill_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_notify_access(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_failure_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_emergency_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_syscall_archs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/core/main.c b/src/core/main.c
index ffc7725f16..94602611a7 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -89,6 +89,7 @@
#include "user-util.h"
#include "virt.h"
#include "watchdog.h"
+#include "emergency-action.h"
static enum {
ACTION_RUN,
@@ -131,7 +132,7 @@ static bool arg_default_memory_accounting = false;
static bool arg_default_tasks_accounting = true;
static uint64_t arg_default_tasks_max = UINT64_MAX;
static sd_id128_t arg_machine_id = {};
-static CADBurstAction arg_cad_burst_action = CAD_BURST_ACTION_REBOOT;
+static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
noreturn static void freeze_or_reboot(void) {
@@ -649,8 +650,6 @@ static int config_parse_join_controllers(const char *unit,
return 0;
}
-static DEFINE_CONFIG_PARSE_ENUM(config_parse_cad_burst_action, cad_burst_action, CADBurstAction, "Failed to parse service restart specifier");
-
static int parse_config_file(void) {
const ConfigTableItem items[] = {
@@ -705,7 +704,7 @@ static int parse_config_file(void) {
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
{ "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting },
{ "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max },
- { "Manager", "CtrlAltDelBurstAction", config_parse_cad_burst_action, 0, &arg_cad_burst_action},
+ { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action },
{}
};
@@ -1778,7 +1777,7 @@ int main(int argc, char *argv[]) {
(void) bump_rlimit_nofile(&saved_rlimit_nofile);
if (empty_etc) {
- r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, false, NULL, 0);
+ r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
if (r < 0)
log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r, "Failed to populate /etc with preset unit settings, ignoring: %m");
else
diff --git a/src/core/manager.c b/src/core/manager.c
index 65f163de31..ffccfdcd5e 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1911,28 +1911,11 @@ static void manager_handle_ctrl_alt_del(Manager *m) {
* 7 times within 2s, we reboot/shutdown immediately,
* unless it was disabled in system.conf */
- if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == CAD_BURST_ACTION_IGNORE)
+ if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
- else {
- switch (m->cad_burst_action) {
-
- case CAD_BURST_ACTION_REBOOT:
- m->exit_code = MANAGER_REBOOT;
- break;
-
- case CAD_BURST_ACTION_POWEROFF:
- m->exit_code = MANAGER_POWEROFF;
- break;
-
- default:
- assert_not_reached("Unknown action.");
- }
-
- log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.",
- cad_burst_action_to_string(m->cad_burst_action));
- status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.",
- cad_burst_action_to_string(m->cad_burst_action));
- }
+ else
+ emergency_action(m, m->cad_burst_action, NULL,
+ "Ctrl-Alt-Del was pressed more than 7 times within 2s");
}
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
@@ -3590,11 +3573,3 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
-
-static const char *const cad_burst_action_table[_CAD_BURST_ACTION_MAX] = {
- [CAD_BURST_ACTION_IGNORE] = "ignore",
- [CAD_BURST_ACTION_REBOOT] = "reboot-force",
- [CAD_BURST_ACTION_POWEROFF] = "poweroff-force",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(cad_burst_action, CADBurstAction);
diff --git a/src/core/manager.h b/src/core/manager.h
index 29fe14e10b..35172fdba9 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -62,14 +62,6 @@ typedef enum ManagerExitCode {
_MANAGER_EXIT_CODE_INVALID = -1
} ManagerExitCode;
-typedef enum CADBurstAction {
- CAD_BURST_ACTION_IGNORE,
- CAD_BURST_ACTION_REBOOT,
- CAD_BURST_ACTION_POWEROFF,
- _CAD_BURST_ACTION_MAX,
- _CAD_BURST_ACTION_INVALID = -1
-} CADBurstAction;
-
typedef enum StatusType {
STATUS_TYPE_EPHEMERAL,
STATUS_TYPE_NORMAL,
@@ -315,7 +307,7 @@ struct Manager {
/* When the user hits C-A-D more than 7 times per 2s, do something immediately... */
RateLimit ctrl_alt_del_ratelimit;
- CADBurstAction cad_burst_action;
+ EmergencyAction cad_burst_action;
const char *unit_log_field;
const char *unit_log_format_string;
@@ -411,6 +403,3 @@ void manager_deserialize_gid_refs_one(Manager *m, const char *value);
const char *manager_state_to_string(ManagerState m) _const_;
ManagerState manager_state_from_string(const char *s) _pure_;
-
-const char *cad_burst_action_to_string(CADBurstAction a) _const_;
-CADBurstAction cad_burst_action_from_string(const char *s) _pure_;
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index 6caa15b0b8..a61677e645 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -94,6 +94,10 @@
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="GetUnitFileLinks"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="ListJobs"/>
<allow send_destination="org.freedesktop.systemd1"
diff --git a/src/core/service.c b/src/core/service.c
index 53c26984ca..ee4f4983fc 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1455,7 +1455,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
if (s->result != SERVICE_SUCCESS) {
log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
- failure_action(UNIT(s)->manager, s->failure_action, UNIT(s)->reboot_arg);
+ emergency_action(UNIT(s)->manager, s->emergency_action, UNIT(s)->reboot_arg, "service failed");
}
if (allow_restart && service_shall_restart(s)) {
diff --git a/src/core/service.h b/src/core/service.h
index 888007cc0b..2869144fcb 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -178,7 +178,7 @@ struct Service {
char *status_text;
int status_errno;
- FailureAction failure_action;
+ EmergencyAction emergency_action;
UnitRef accept_socket;
diff --git a/src/core/unit.c b/src/core/unit.c
index 2fa397bd41..cabb1050a8 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -982,8 +982,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
if (u->job_timeout != USEC_INFINITY)
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
- if (u->job_timeout_action != FAILURE_ACTION_NONE)
- fprintf(f, "%s\tJob Timeout Action: %s\n", prefix, failure_action_to_string(u->job_timeout_action));
+ if (u->job_timeout_action != EMERGENCY_ACTION_NONE)
+ fprintf(f, "%s\tJob Timeout Action: %s\n", prefix, emergency_action_to_string(u->job_timeout_action));
if (u->job_timeout_reboot_arg)
fprintf(f, "%s\tJob Timeout Reboot Argument: %s\n", prefix, u->job_timeout_reboot_arg);
@@ -1490,7 +1490,7 @@ int unit_start_limit_test(Unit *u) {
log_unit_warning(u, "Start request repeated too quickly.");
u->start_limit_hit = true;
- return failure_action(u->manager, u->start_limit_action, u->reboot_arg);
+ return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed");
}
/* Errors:
diff --git a/src/core/unit.h b/src/core/unit.h
index a8dd3e602c..adcdee6db6 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -29,7 +29,7 @@ typedef struct UnitRef UnitRef;
typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
#include "condition.h"
-#include "failure-action.h"
+#include "emergency-action.h"
#include "install.h"
#include "list.h"
#include "unit-name.h"
@@ -114,7 +114,7 @@ struct Unit {
/* Job timeout and action to take */
usec_t job_timeout;
- FailureAction job_timeout_action;
+ EmergencyAction job_timeout_action;
char *job_timeout_reboot_arg;
/* References to this */
@@ -178,7 +178,7 @@ struct Unit {
/* Put a ratelimit on unit starting */
RateLimit start_limit;
- FailureAction start_limit_action;
+ EmergencyAction start_limit_action;
char *reboot_arg;
/* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 76c9baf6db..908c7b8eeb 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -131,8 +131,6 @@ static void cache_space_invalidate(JournalStorageSpace *space) {
}
static int cache_space_refresh(Server *s, JournalStorage *storage) {
-
- _cleanup_closedir_ DIR *d = NULL;
JournalStorageSpace *space;
JournalMetrics *metrics;
uint64_t vfs_used, vfs_avail, avail;
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index c2b7970623..b282634e4b 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -57,6 +57,8 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
unsigned preference;
usec_t time_now;
int r;
+ Address *address;
+ Iterator i;
assert(link);
assert(rt);
@@ -75,6 +77,32 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
return;
}
+ SET_FOREACH(address, link->addresses, i) {
+ if (!memcmp(&gateway, &address->in_addr.in6,
+ sizeof(address->in_addr.in6))) {
+ char buffer[INET6_ADDRSTRLEN];
+
+ log_link_debug(link, "No NDisc route added, gateway %s matches local address",
+ inet_ntop(AF_INET6,
+ &address->in_addr.in6,
+ buffer, sizeof(buffer)));
+ return;
+ }
+ }
+
+ SET_FOREACH(address, link->addresses_foreign, i) {
+ if (!memcmp(&gateway, &address->in_addr.in6,
+ sizeof(address->in_addr.in6))) {
+ char buffer[INET6_ADDRSTRLEN];
+
+ log_link_debug(link, "No NDisc route added, gateway %s matches local address",
+ inet_ntop(AF_INET6,
+ &address->in_addr.in6,
+ buffer, sizeof(buffer)));
+ return;
+ }
+ }
+
r = sd_ndisc_router_get_preference(rt, &preference);
if (r < 0) {
log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 44dc9bfcf4..115de64cf9 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -300,6 +300,59 @@ int mount_sysfs(const char *dest) {
MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
}
+static int mkdir_userns(const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+ int r;
+
+ assert(path);
+
+ r = mkdir(path, mode);
+ if (r < 0 && errno != EEXIST)
+ return -errno;
+
+ if (!in_userns) {
+ r = lchown(path, uid_shift, uid_shift);
+ if (r < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int mkdir_userns_p(const char *prefix, const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+ const char *p, *e;
+ int r;
+
+ assert(path);
+
+ if (prefix && !path_startswith(path, prefix))
+ return -ENOTDIR;
+
+ /* create every parent directory in the path, except the last component */
+ p = path + strspn(path, "/");
+ for (;;) {
+ char t[strlen(path) + 1];
+
+ e = p + strcspn(p, "/");
+ p = e + strspn(e, "/");
+
+ /* Is this the last component? If so, then we're done */
+ if (*p == 0)
+ break;
+
+ memcpy(t, path, e - path);
+ t[e-path] = 0;
+
+ if (prefix && path_startswith(prefix, t))
+ continue;
+
+ r = mkdir_userns(t, mode, in_userns, uid_shift);
+ if (r < 0)
+ return r;
+ }
+
+ return mkdir_userns(path, mode, in_userns, uid_shift);
+}
+
int mount_all(const char *dest,
bool use_userns, bool in_userns,
bool use_netns,
@@ -361,7 +414,7 @@ int mount_all(const char *dest,
if (mount_table[k].what && r > 0)
continue;
- r = mkdir_p(where, 0755);
+ r = mkdir_userns_p(dest, where, 0755, in_userns, uid_shift);
if (r < 0 && r != -EEXIST) {
if (mount_table[k].fatal)
return log_error_errno(r, "Failed to create directory %s: %m", where);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 2cbe563953..295293858e 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2684,6 +2684,10 @@ static int inner_child(
}
}
+ r = reset_uid_gid();
+ if (r < 0)
+ return log_error_errno(r, "Couldn't become new root: %m");
+
r = mount_all(NULL,
arg_userns_mode != USER_NAMESPACE_NO,
true,
@@ -2726,10 +2730,6 @@ static int inner_child(
return r;
}
- r = reset_uid_gid();
- if (r < 0)
- return log_error_errno(r, "Couldn't become new root: %m");
-
r = setup_boot_id(NULL);
if (r < 0)
return r;
diff --git a/src/shared/install.c b/src/shared/install.c
index d33a658d0a..96fba6e25b 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -518,6 +518,7 @@ static int remove_marked_symlinks_fd(
const char *path,
const char *config_path,
const LookupPaths *lp,
+ bool dry_run,
bool *restart,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -566,7 +567,7 @@ static int remove_marked_symlinks_fd(
}
/* This will close nfd, regardless whether it succeeds or not */
- q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, restart, changes, n_changes);
+ q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, dry_run, restart, changes, n_changes);
if (q < 0 && r == 0)
r = q;
@@ -603,14 +604,16 @@ static int remove_marked_symlinks_fd(
if (!found)
continue;
- if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
- if (r == 0)
- r = -errno;
- unit_file_changes_add(changes, n_changes, -errno, p, NULL);
- continue;
- }
+ if (!dry_run) {
+ if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
+ if (r == 0)
+ r = -errno;
+ unit_file_changes_add(changes, n_changes, -errno, p, NULL);
+ continue;
+ }
- (void) rmdir_parents(p, config_path);
+ (void) rmdir_parents(p, config_path);
+ }
unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
@@ -621,7 +624,7 @@ static int remove_marked_symlinks_fd(
q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
if (q < 0)
return q;
- if (q > 0)
+ if (q > 0 && !dry_run)
*restart = true;
}
}
@@ -633,6 +636,7 @@ static int remove_marked_symlinks(
Set *remove_symlinks_to,
const char *config_path,
const LookupPaths *lp,
+ bool dry_run,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -659,7 +663,7 @@ static int remove_marked_symlinks(
return -errno;
/* This takes possession of cfd and closes it */
- q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, &restart, changes, n_changes);
+ q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, dry_run, &restart, changes, n_changes);
if (r == 0)
r = q;
} while (restart);
@@ -1805,10 +1809,9 @@ static int install_context_mark_for_removal(
int unit_file_mask(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -1824,7 +1827,7 @@ int unit_file_mask(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
@@ -1840,7 +1843,7 @@ int unit_file_mask(
if (!path)
return -ENOMEM;
- q = create_symlink(&paths, "/dev/null", path, force, changes, n_changes);
+ q = create_symlink(&paths, "/dev/null", path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
if (q < 0 && r >= 0)
r = q;
}
@@ -1850,7 +1853,7 @@ int unit_file_mask(
int unit_file_unmask(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
@@ -1862,6 +1865,7 @@ int unit_file_unmask(
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
+ bool dry_run;
int r, q;
assert(scope >= 0);
@@ -1871,7 +1875,8 @@ int unit_file_unmask(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ dry_run = !!(flags & UNIT_FILE_DRY_RUN);
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
@@ -1908,7 +1913,7 @@ int unit_file_unmask(
if (!path)
return -ENOMEM;
- if (unlink(path) < 0) {
+ if (!dry_run && unlink(path) < 0) {
if (errno != ENOENT) {
if (r >= 0)
r = -errno;
@@ -1926,7 +1931,7 @@ int unit_file_unmask(
return q;
}
- q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, changes, n_changes);
+ q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
if (r >= 0)
r = q;
@@ -1935,10 +1940,9 @@ int unit_file_unmask(
int unit_file_link(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -1956,7 +1960,7 @@ int unit_file_link(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
_cleanup_free_ char *full = NULL;
@@ -2005,7 +2009,7 @@ int unit_file_link(
if (!new_path)
return -ENOMEM;
- q = create_symlink(&paths, *i, new_path, force, changes, n_changes);
+ q = create_symlink(&paths, *i, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
if (q < 0 && r >= 0)
r = q;
}
@@ -2177,11 +2181,11 @@ int unit_file_revert(
return q;
}
- q = remove_marked_symlinks(remove_symlinks_to, paths.runtime_config, &paths, changes, n_changes);
+ q = remove_marked_symlinks(remove_symlinks_to, paths.runtime_config, &paths, false, changes, n_changes);
if (r >= 0)
r = q;
- q = remove_marked_symlinks(remove_symlinks_to, paths.persistent_config, &paths, changes, n_changes);
+ q = remove_marked_symlinks(remove_symlinks_to, paths.persistent_config, &paths, false, changes, n_changes);
if (r >= 0)
r = q;
@@ -2190,12 +2194,11 @@ int unit_file_revert(
int unit_file_add_dependency(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
const char *target,
UnitDependency dep,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2220,7 +2223,7 @@ int unit_file_add_dependency(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS,
&target_info, changes, n_changes);
@@ -2260,15 +2263,14 @@ int unit_file_add_dependency(
return -ENOMEM;
}
- return install_context_apply(scope, &c, &paths, config_path, force, SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
+ return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
}
int unit_file_enable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2286,7 +2288,7 @@ int unit_file_enable(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(f, files) {
r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
@@ -2305,12 +2307,12 @@ int unit_file_enable(
is useful to determine whether the passed files had any
installation data at all. */
- return install_context_apply(scope, &c, &paths, config_path, force, SEARCH_LOAD, changes, n_changes);
+ return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_LOAD, changes, n_changes);
}
int unit_file_disable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
@@ -2330,7 +2332,7 @@ int unit_file_disable(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
@@ -2345,15 +2347,14 @@ int unit_file_disable(
if (r < 0)
return r;
- return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, changes, n_changes);
+ return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
}
int unit_file_reenable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2368,19 +2369,19 @@ int unit_file_reenable(
n[i] = basename(files[i]);
n[i] = NULL;
- r = unit_file_disable(scope, runtime, root_dir, n, changes, n_changes);
+ r = unit_file_disable(scope, flags, root_dir, n, changes, n_changes);
if (r < 0)
return r;
/* But the enable command with the full name */
- return unit_file_enable(scope, runtime, root_dir, files, force, changes, n_changes);
+ return unit_file_enable(scope, flags, root_dir, files, changes, n_changes);
}
int unit_file_set_default(
UnitFileScope scope,
+ UnitFileFlags flags,
const char *root_dir,
const char *name,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2411,7 +2412,7 @@ int unit_file_set_default(
return r;
new_path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
- return create_symlink(&paths, i->path, new_path, force, changes, n_changes);
+ return create_symlink(&paths, i->path, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
}
int unit_file_get_default(
@@ -2735,7 +2736,7 @@ static int execute_preset(
if (r < 0)
return r;
- r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, changes, n_changes);
+ r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
} else
r = 0;
@@ -2803,11 +2804,10 @@ static int preset_prepare_one(
int unit_file_preset(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFilePresetMode mode,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2826,7 +2826,7 @@ int unit_file_preset(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
@@ -2838,15 +2838,14 @@ int unit_file_preset(
return r;
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, force, changes, n_changes);
+ return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
}
int unit_file_preset_all(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
UnitFilePresetMode mode,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -2865,7 +2864,7 @@ int unit_file_preset_all(
if (r < 0)
return r;
- config_path = runtime ? paths.runtime_config : paths.persistent_config;
+ config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
@@ -2906,7 +2905,7 @@ int unit_file_preset_all(
}
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, force, changes, n_changes);
+ return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
}
static void unit_file_list_free_one(UnitFileList *f) {
diff --git a/src/shared/install.h b/src/shared/install.h
index b1f220693b..7a5859e729 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -23,6 +23,7 @@ typedef enum UnitFileScope UnitFileScope;
typedef enum UnitFileState UnitFileState;
typedef enum UnitFilePresetMode UnitFilePresetMode;
typedef enum UnitFileChangeType UnitFileChangeType;
+typedef enum UnitFileFlags UnitFileFlags;
typedef enum UnitFileType UnitFileType;
typedef struct UnitFileChange UnitFileChange;
typedef struct UnitFileList UnitFileList;
@@ -78,6 +79,12 @@ enum UnitFileChangeType {
_UNIT_FILE_CHANGE_INVALID = INT_MIN
};
+enum UnitFileFlags {
+ UNIT_FILE_RUNTIME = 1,
+ UNIT_FILE_FORCE = 1 << 1,
+ UNIT_FILE_DRY_RUN = 1 << 2,
+};
+
/* type can either one of the UnitFileChangeTypes listed above, or a negative error.
* If source is specified, it should be the contents of the path symlink.
* In case of an error, source should be the existing symlink contents or NULL
@@ -144,65 +151,59 @@ bool unit_type_may_template(UnitType type) _const_;
int unit_file_enable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_disable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_reenable(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_preset(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFilePresetMode mode,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_preset_all(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
UnitFilePresetMode mode,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_mask(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_unmask(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_link(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_revert(
@@ -213,9 +214,9 @@ int unit_file_revert(
unsigned *n_changes);
int unit_file_set_default(
UnitFileScope scope,
+ UnitFileFlags flags,
const char *root_dir,
const char *file,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
int unit_file_get_default(
@@ -224,12 +225,11 @@ int unit_file_get_default(
char **name);
int unit_file_add_dependency(
UnitFileScope scope,
- bool runtime,
+ UnitFileFlags flags,
const char *root_dir,
char **files,
const char *target,
UnitDependency dep,
- bool force,
UnitFileChange **changes,
unsigned *n_changes);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 129706d15f..2e3b59af3e 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -189,6 +189,11 @@ typedef enum BusFocus {
static sd_bus *busses[_BUS_FOCUS_MAX] = {};
+static UnitFileFlags args_to_flags(void) {
+ return (arg_runtime ? UNIT_FILE_RUNTIME : 0) |
+ (arg_force ? UNIT_FILE_FORCE : 0);
+}
+
static int acquire_bus(BusFocus focus, sd_bus **ret) {
int r;
@@ -2137,7 +2142,7 @@ static int set_default(int argc, char *argv[], void *userdata) {
return log_error_errno(r, "Failed to mangle unit name: %m");
if (install_client_side()) {
- r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
+ r = unit_file_set_default(arg_scope, UNIT_FILE_FORCE, arg_root, unit, &changes, &n_changes);
unit_file_dump_changes(r, "set default", changes, n_changes, arg_quiet);
if (r > 0)
@@ -5955,22 +5960,25 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
}
if (install_client_side()) {
+ UnitFileFlags flags;
+
+ flags = args_to_flags();
if (streq(verb, "enable")) {
- r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
+ r = unit_file_enable(arg_scope, flags, arg_root, names, &changes, &n_changes);
carries_install_info = r;
} else if (streq(verb, "disable"))
- r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
+ r = unit_file_disable(arg_scope, flags, arg_root, names, &changes, &n_changes);
else if (streq(verb, "reenable")) {
- r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
+ r = unit_file_reenable(arg_scope, flags, arg_root, names, &changes, &n_changes);
carries_install_info = r;
} else if (streq(verb, "link"))
- r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
+ r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
else if (streq(verb, "preset")) {
- r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
+ r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
} else if (streq(verb, "mask"))
- r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
+ r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
else if (streq(verb, "unmask"))
- r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
+ r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
else if (streq(verb, "revert"))
r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
else
@@ -6152,7 +6160,7 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
assert_not_reached("Unknown verb");
if (install_client_side()) {
- r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
+ r = unit_file_add_dependency(arg_scope, args_to_flags(), arg_root, names, target, dep, &changes, &n_changes);
unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
if (r > 0)
@@ -6214,7 +6222,7 @@ static int preset_all(int argc, char *argv[], void *userdata) {
int r;
if (install_client_side()) {
- r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
+ r = unit_file_preset_all(arg_scope, args_to_flags(), arg_root, arg_preset_mode, &changes, &n_changes);
unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
if (r > 0)
@@ -6263,6 +6271,63 @@ finish:
return r;
}
+static int show_installation_targets_client_side(const char *name) {
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0, i;
+ UnitFileFlags flags;
+ char **p;
+ int r;
+
+ p = STRV_MAKE(name);
+ flags = UNIT_FILE_DRY_RUN |
+ (arg_runtime ? UNIT_FILE_RUNTIME : 0);
+
+ r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get file links for %s: %m", name);
+
+ for (i = 0; i < n_changes; i++)
+ if (changes[i].type == UNIT_FILE_UNLINK)
+ printf(" %s\n", changes[i].path);
+
+ return 0;
+}
+
+static int show_installation_targets(sd_bus *bus, const char *name) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ const char *link;
+ int r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "GetUnitFileLinks",
+ &error,
+ &reply,
+ "sb", name, arg_runtime);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get unit file links for %s: %s", name, bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(reply, "s", &link)) > 0)
+ printf(" %s\n", link);
+
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ return 0;
+}
+
static int unit_is_enabled(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
@@ -6281,7 +6346,6 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
enabled = r > 0;
if (install_client_side()) {
-
STRV_FOREACH(name, names) {
UnitFileState state;
@@ -6297,8 +6361,14 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
UNIT_FILE_GENERATED))
enabled = true;
- if (!arg_quiet)
+ if (!arg_quiet) {
puts(unit_file_state_to_string(state));
+ if (arg_full) {
+ r = show_installation_targets_client_side(*name);
+ if (r < 0)
+ return r;
+ }
+ }
}
r = 0;
@@ -6333,8 +6403,14 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
enabled = true;
- if (!arg_quiet)
+ if (!arg_quiet) {
puts(s);
+ if (arg_full) {
+ r = show_installation_targets(bus, *name);
+ if (r < 0)
+ return r;
+ }
+ }
}
}
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index e8ff02adaf..404421a2b8 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -218,6 +218,15 @@ static void test_exec_group(Manager *m) {
log_error_errno(errno, "Skipping test_exec_group, could not find nobody/nfsnobody group: %m");
}
+static void test_exec_supplementary_groups(Manager *m) {
+ test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
+}
+
static void test_exec_environment(Manager *m) {
test(m, "exec-environment.service", 0, CLD_EXITED);
test(m, "exec-environment-multiple.service", 0, CLD_EXITED);
@@ -390,6 +399,7 @@ int main(int argc, char *argv[]) {
test_exec_systemcallerrornumber,
test_exec_user,
test_exec_group,
+ test_exec_supplementary_groups,
test_exec_environment,
test_exec_environmentfile,
test_exec_passenvironment,
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index 1686054d2a..a98de76b43 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -64,7 +64,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_mask(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/dev/null"));
@@ -80,11 +80,11 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_MASKED);
/* Enabling a masked unit should fail! */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == -ERFKILL);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == -ERFKILL);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service");
@@ -92,7 +92,7 @@ static void test_basic_mask_and_enable(const char *root) {
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == 1);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
@@ -107,12 +107,12 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
/* Enabling it again should succeed but be a NOP */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
@@ -126,13 +126,13 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
/* Disabling a disabled unit must suceed but be a NOP */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
/* Let's enable this indirectly via a symlink */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("d.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
@@ -148,7 +148,7 @@ static void test_basic_mask_and_enable(const char *root) {
/* Let's try to reenable */
- assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("b.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
@@ -217,7 +217,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", &state) >= 0 && state == UNIT_FILE_LINKED);
/* First, let's link the unit into the search path */
- assert_se(unit_file_link(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("/opt/linked.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/opt/linked.service"));
@@ -229,7 +229,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED);
/* Let's unlink it from the search path again */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -240,7 +240,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
/* Now, let's not just link it, but also enable it */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("/opt/linked.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -262,7 +262,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
/* And let's unlink it again */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -282,7 +282,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked2.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service");
@@ -301,7 +301,7 @@ static void test_linked_units(const char *root) {
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked3.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(startswith(changes[0].path, root));
@@ -325,7 +325,7 @@ static void test_default(const char *root) {
assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
- assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, root, "idontexist.target", false, &changes, &n_changes) == -ENOENT);
+ assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT);
assert_se(n_changes == 1);
assert_se(changes[0].type == -ENOENT);
assert_se(streq_ptr(changes[0].path, "idontexist.target"));
@@ -334,7 +334,7 @@ static void test_default(const char *root) {
assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
- assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, root, "test-default.target", false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target"));
@@ -364,7 +364,7 @@ static void test_add_dependency(const char *root) {
p = strjoina(root, "/usr/lib/systemd/system/add-dependency-test-service.service");
assert_se(symlink("real-add-dependency-test-service.service", p) >= 0);
- assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
@@ -401,7 +401,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
@@ -417,7 +417,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p));
@@ -431,7 +431,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@foo.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@foo.service");
@@ -446,7 +446,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p));
@@ -462,7 +462,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template-symlink@quux.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@quux.service");
@@ -507,7 +507,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("indirectc.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service"));
@@ -520,7 +520,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service");
@@ -560,7 +560,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service"));
@@ -572,7 +572,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
@@ -583,7 +583,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
@@ -591,7 +591,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, false, root, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes > 0);
@@ -716,7 +716,7 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service"));
@@ -728,7 +728,7 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
diff --git a/src/test/test-install.c b/src/test/test-install.c
index 0ac85f040a..fb36aa83ca 100644
--- a/src/test/test-install.c
+++ b/src/test/test-install.c
@@ -70,12 +70,12 @@ int main(int argc, char* argv[]) {
log_info("/*** enable **/");
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** enable2 **/");
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -89,7 +89,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -103,10 +103,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** mask2 ***/");
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -120,10 +120,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** unmask2 ***/");
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -137,7 +137,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -151,10 +151,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** disable2 ***/");
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -168,7 +168,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -182,7 +182,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -196,7 +196,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -209,7 +209,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -223,7 +223,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -236,7 +236,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -250,7 +250,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_reenable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_reenable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -264,7 +264,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -276,7 +276,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes);
+ r = unit_file_preset(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, UNIT_FILE_PRESET_FULL, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index 0be74921fc..8d4622694e 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
test_table(device_state, DEVICE_STATE);
test_table(exec_input, EXEC_INPUT);
test_table(exec_output, EXEC_OUTPUT);
- test_table(failure_action, FAILURE_ACTION);
+ test_table(emergency_action, EMERGENCY_ACTION);
test_table(job_mode, JOB_MODE);
test_table(job_result, JOB_RESULT);
test_table(job_state, JOB_STATE);