-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-bus.h"
#include "alloc-util.h"
#include "bpf-firewall.h"
#include "bus-common-errors.h"
+#include "bus-get-properties.h"
#include "bus-polkit.h"
-#include "bus-util.h"
#include "cgroup-util.h"
#include "condition.h"
#include "dbus-job.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
static BUS_DEFINE_PROPERTY_GET(property_get_description, "s", Unit, unit_description);
static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_active_state, unit_active_state_to_string);
+static BUS_DEFINE_PROPERTY_GET2(property_get_freezer_state, "s", Unit, unit_freezer_state, freezer_state_to_string);
static BUS_DEFINE_PROPERTY_GET(property_get_sub_state, "s", Unit, unit_sub_state_to_string);
static BUS_DEFINE_PROPERTY_GET2(property_get_unit_file_state, "s", Unit, unit_get_unit_file_state, unit_file_state_to_string);
static BUS_DEFINE_PROPERTY_GET(property_get_can_reload, "b", Unit, unit_can_reload);
static BUS_DEFINE_PROPERTY_GET(property_get_can_start, "b", Unit, unit_can_start_refuse_manual);
static BUS_DEFINE_PROPERTY_GET(property_get_can_stop, "b", Unit, unit_can_stop_refuse_manual);
static BUS_DEFINE_PROPERTY_GET(property_get_can_isolate, "b", Unit, unit_can_isolate_refuse_manual);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_freeze, "b", Unit, unit_can_freeze);
static BUS_DEFINE_PROPERTY_GET(property_get_need_daemon_reload, "b", Unit, unit_need_daemon_reload);
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_strv, "as", 0);
void *userdata,
sd_bus_error *error) {
- Set **s = userdata;
- Iterator i;
+ Unit *u = userdata;
const char *t;
int r;
assert(bus);
assert(reply);
- assert(s);
+ assert(u);
r = sd_bus_message_open_container(reply, 'a', "s");
if (r < 0)
return r;
- SET_FOREACH(t, *s, i) {
+ r = sd_bus_message_append(reply, "s", u->id);
+ if (r < 0)
+ return r;
+
+ SET_FOREACH(t, u->aliases) {
r = sd_bus_message_append(reply, "s", t);
if (r < 0)
return r;
sd_bus_error *error) {
Hashmap **h = userdata;
- Iterator j;
Unit *u;
void *v;
int r;
if (r < 0)
return r;
- HASHMAP_FOREACH_KEY(v, u, *h, j) {
+ HASHMAP_FOREACH_KEY(v, u, *h) {
r = sd_bus_message_append(reply, "s", u->id);
if (r < 0)
return r;
Hashmap **h = userdata;
const char *p;
- Iterator j;
void *v;
int r;
if (r < 0)
return r;
- HASHMAP_FOREACH_KEY(v, p, *h, j) {
+ HASHMAP_FOREACH_KEY(v, p, *h) {
r = sd_bus_message_append(reply, "s", p);
if (r < 0)
return r;
return sd_bus_message_append(reply, "(ss)", NULL, NULL);
}
-static int bus_verify_manage_units_async_full(
- Unit *u,
- const char *verb,
- int capability,
- const char *polkit_message,
- bool interactive,
- sd_bus_message *call,
+static int property_get_markers(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
sd_bus_error *error) {
- const char *details[9] = {
- "unit", u->id,
- "verb", verb,
- };
+ unsigned *markers = userdata;
+ int r;
- if (polkit_message) {
- details[4] = "polkit.message";
- details[5] = polkit_message;
- details[6] = "polkit.gettext_domain";
- details[7] = GETTEXT_PACKAGE;
- }
+ assert(bus);
+ assert(reply);
+ assert(markers);
- return bus_verify_polkit_async(
- call,
- capability,
- "org.freedesktop.systemd1.manage-units",
- details,
- interactive,
- UID_INVALID,
- &u->manager->polkit_registry,
- error);
+ r = sd_bus_message_open_container(reply, 'a', "s");
+ if (r < 0)
+ return r;
+
+ /* Make sure out values fit in the bitfield. */
+ assert_cc(_UNIT_MARKER_MAX <= sizeof(((Unit){}).markers) * 8);
+
+ for (UnitMarker m = 0; m < _UNIT_MARKER_MAX; m++)
+ if (FLAGS_SET(*markers, 1u << m)) {
+ r = sd_bus_message_append(reply, "s", unit_marker_to_string(m));
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(reply);
}
static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = {
}
if (!SIGNAL_VALID(signo))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
r = bus_verify_manage_units_async_full(
u,
r = bus_unit_track_remove_sender(u, message);
if (r == -EUNATCH)
- return sd_bus_error_setf(error, BUS_ERROR_NOT_REFERENCED, "Unit has not been referenced yet.");
+ return sd_bus_error_set(error, BUS_ERROR_NOT_REFERENCED, "Unit has not been referenced yet.");
if (r < 0)
return r;
if (r == -EOPNOTSUPP)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not supporting cleaning.", u->id);
if (r == -EUNATCH)
- return sd_bus_error_setf(error, BUS_ERROR_NOTHING_TO_CLEAN, "No matching resources found.");
+ return sd_bus_error_set(error, BUS_ERROR_NOTHING_TO_CLEAN, "No matching resources found.");
if (r == -EBUSY)
- return sd_bus_error_setf(error, BUS_ERROR_UNIT_BUSY, "Unit is not inactive or has pending job.");
+ return sd_bus_error_set(error, BUS_ERROR_UNIT_BUSY, "Unit is not inactive or has pending job.");
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
+static int bus_unit_method_freezer_generic(sd_bus_message *message, void *userdata, sd_bus_error *error, FreezerAction action) {
+ const char* perm;
+ int (*method)(Unit*);
+ Unit *u = userdata;
+ bool reply_no_delay = false;
+ int r;
+
+ assert(message);
+ assert(u);
+ assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW));
+
+ if (action == FREEZER_FREEZE) {
+ perm = "stop";
+ method = unit_freeze;
+ } else {
+ perm = "start";
+ method = unit_thaw;
+ }
+
+ r = mac_selinux_unit_access_check(u, message, perm, error);
+ if (r < 0)
+ return r;
+
+ r = bus_verify_manage_units_async_full(
+ u,
+ perm,
+ CAP_SYS_ADMIN,
+ N_("Authentication is required to freeze or thaw the processes of '$(unit)' unit."),
+ true,
+ 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 = method(u);
+ if (r == -EOPNOTSUPP)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not support freezing.", u->id);
+ if (r == -EBUSY)
+ return sd_bus_error_set(error, BUS_ERROR_UNIT_BUSY, "Unit has a pending job.");
+ if (r == -EHOSTDOWN)
+ return sd_bus_error_set(error, BUS_ERROR_UNIT_INACTIVE, "Unit is inactive.");
+ if (r == -EALREADY)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Previously requested freezer operation for unit '%s' is still in progress.", u->id);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ reply_no_delay = true;
+
+ assert(!u->pending_freezer_message);
+
+ r = sd_bus_message_new_method_return(message, &u->pending_freezer_message);
+ if (r < 0)
+ return r;
+
+ if (reply_no_delay) {
+ r = bus_unit_send_pending_freezer_message(u);
+ if (r < 0)
+ return r;
+ }
+
+ return 1;
+}
+
+int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_THAW);
+}
+
+int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_FREEZE);
+}
+
static int property_get_refs(
sd_bus *bus,
const char *path,
sd_bus_error *error) {
Unit *u = userdata;
- const char *i;
int r;
assert(bus);
if (r < 0)
return r;
- for (i = sd_bus_track_first(u->bus_track); i; i = sd_bus_track_next(u->bus_track)) {
- int c, k;
+ for (const char *i = sd_bus_track_first(u->bus_track); i; i = sd_bus_track_next(u->bus_track)) {
+ int c;
c = sd_bus_track_count_name(u->bus_track, i);
if (c < 0)
return c;
/* Add the item multiple times if the ref count for each is above 1 */
- for (k = 0; k < c; k++) {
+ for (int k = 0; k < c; k++) {
r = sd_bus_message_append(reply, "s", i);
if (r < 0)
return r;
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Unit, id), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Names", "as", property_get_names, offsetof(Unit, names), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Names", "as", property_get_names, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Following", "s", property_get_following, 0, 0),
SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("FreezerState", "s", property_get_freezer_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("SubState", "s", property_get_sub_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanClean", "as", property_get_can_clean, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("CanFreeze", "b", property_get_can_freeze, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Job", "(uo)", property_get_job, offsetof(Unit, job), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
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("Markers", "as", property_get_markers, offsetof(Unit, markers), 0),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
NULL,,
bus_unit_method_clean,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Freeze",
+ NULL,
+ NULL,
+ bus_unit_method_freeze,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Thaw",
+ NULL,
+ NULL,
+ bus_unit_method_thaw,
+ SD_BUS_VTABLE_UNPRIVILEGED),
/* For dependency types we don't support anymore always return an empty array */
SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
void *userdata,
sd_bus_error *error) {
- uint64_t sz = (uint64_t) -1;
+ uint64_t sz = UINT64_MAX;
Unit *u = userdata;
int r;
void *userdata,
sd_bus_error *error) {
- uint64_t cn = (uint64_t) -1;
+ uint64_t cn = UINT64_MAX;
Unit *u = userdata;
int r;
void *userdata,
sd_bus_error *error) {
- nsec_t ns = (nsec_t) -1;
+ nsec_t ns = NSEC_INFINITY;
Unit *u = userdata;
int r;
}
if (!unit_cgroup_delegate(u))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Process migration not available on non-delegated units.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Process migration not available on non-delegated units.");
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
if (r < 0)
bus_unit_send_change_signal(u);
}
+int bus_unit_send_pending_freezer_message(Unit *u) {
+ int r;
+
+ assert(u);
+
+ if (!u->pending_freezer_message)
+ return 0;
+
+ r = sd_bus_send(NULL, u->pending_freezer_message, NULL);
+ if (r < 0)
+ log_warning_errno(r, "Failed to send queued message, ignoring: %m");
+
+ u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
+
+ return 0;
+}
+
static int send_removed_signal(sd_bus *bus, void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_free_ char *p = NULL;
log_unit_debug_errno(u, r, "Failed to send unit remove signal for %s: %m", u->id);
}
-int bus_unit_queue_job(
+int bus_unit_queue_job_one(
sd_bus_message *message,
Unit *u,
JobType type,
JobMode mode,
BusUnitQueueFlags flags,
+ sd_bus_message *reply,
sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_set_free_ Set *affected = NULL;
_cleanup_free_ char *job_path = NULL, *unit_path = NULL;
- _cleanup_(set_freep) Set *affected = NULL;
- Iterator i;
Job *j, *a;
int r;
- assert(message);
- assert(u);
- assert(type >= 0 && type < _JOB_TYPE_MAX);
- assert(mode >= 0 && mode < _JOB_MODE_MAX);
-
- r = mac_selinux_unit_access_check(
- u, message,
- job_type_to_access_method(type),
- error);
- if (r < 0)
- return r;
-
- if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
- if (type == JOB_RESTART)
- type = JOB_RELOAD_OR_START;
- else if (type == JOB_TRY_RESTART)
- type = JOB_TRY_RELOAD;
- }
-
- if (type == JOB_STOP &&
- IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
- unit_active_state(u) == UNIT_INACTIVE)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
-
- if ((type == JOB_START && u->refuse_manual_start) ||
- (type == JOB_STOP && u->refuse_manual_stop) ||
- (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
- (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
-
if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) {
affected = set_new(NULL);
if (!affected)
/* The classic response is just a job object path */
if (!FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY))
- return sd_bus_reply_method_return(message, "o", job_path);
+ return sd_bus_message_append(reply, "o", job_path);
/* In verbose mode respond with the anchor job plus everything that has been affected */
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
unit_path = unit_dbus_path(j->unit);
if (!unit_path)
if (r < 0)
return r;
- SET_FOREACH(a, affected, i) {
-
+ SET_FOREACH(a, affected) {
if (a->id == j->id)
continue;
return r;
}
- r = sd_bus_message_close_container(reply);
+ return sd_bus_message_close_container(reply);
+}
+
+int bus_unit_queue_job(
+ sd_bus_message *message,
+ Unit *u,
+ JobType type,
+ JobMode mode,
+ BusUnitQueueFlags flags,
+ sd_bus_error *error) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int r;
+
+ assert(message);
+ assert(u);
+ assert(type >= 0 && type < _JOB_TYPE_MAX);
+ assert(mode >= 0 && mode < _JOB_MODE_MAX);
+
+ r = mac_selinux_unit_access_check(
+ u, message,
+ job_type_to_access_method(type),
+ error);
+ if (r < 0)
+ return r;
+
+ if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
+ if (type == JOB_RESTART)
+ type = JOB_RELOAD_OR_START;
+ else if (type == JOB_TRY_RESTART)
+ type = JOB_TRY_RELOAD;
+ }
+
+ if (type == JOB_STOP &&
+ IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
+ unit_active_state(u) == UNIT_INACTIVE)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
+
+ if ((type == JOB_START && u->refuse_manual_start) ||
+ (type == JOB_STOP && u->refuse_manual_stop) ||
+ (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
+ (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
+ return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = bus_unit_queue_job_one(message, u, type, mode, flags, reply, error);
if (r < 0)
return r;
assert(name);
assert(message);
- /* Handles setting properties both "live" (i.e. at any time during runtime), and during creation (for transient
- * units that are being created). */
+ /* Handles setting properties both "live" (i.e. at any time during runtime), and during creation (for
+ * transient units that are being created). */
if (streq(name, "Description")) {
const char *d;
return 1;
}
+ /* A setting that only applies to active units. We don't actually write this to /run, this state is
+ * managed internally. "+foo" sets flag foo, "-foo" unsets flag foo, just "foo" resets flags to
+ * foo. The last type cannot be mixed with "+" or "-". */
+
+ if (streq(name, "Markers")) {
+ unsigned settings = 0, mask = 0;
+ bool some_plus_minus = false, some_absolute = false;
+
+ r = sd_bus_message_enter_container(message, 'a', "s");
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ const char *word;
+ bool b;
+
+ r = sd_bus_message_read(message, "s", &word);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ if (IN_SET(word[0], '+', '-')) {
+ b = word[0] == '+';
+ word++;
+ some_plus_minus = true;
+ } else {
+ b = true;
+ some_absolute = true;
+ }
+
+ UnitMarker m = unit_marker_from_string(word);
+ if (m < 0)
+ return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
+ "Unknown marker \"%s\".", word);
+
+ SET_FLAG(settings, 1u << m, b);
+ SET_FLAG(mask, 1u << m, true);
+ }
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+
+ if (some_plus_minus && some_absolute)
+ return sd_bus_error_set(error, BUS_ERROR_BAD_UNIT_SETTING, "Bad marker syntax.");
+
+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+ if (some_absolute)
+ u->markers = settings;
+ else
+ u->markers = settings | (u->markers & ~mask);
+ }
+
+ return 1;
+ }
+
return 0;
}
return r;
if (k > 255)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Exit status must be in range 0…255 or negative.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Exit status must be in range 0…255 or negative.");
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
*p = k < 0 ? -1 : k;
if (t < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name);
- if (t != CONDITION_NULL) {
- if (isempty(param))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
+ if (isempty(param))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
- if (condition_takes_path(t) && !path_is_absolute(param))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
- } else
- param = NULL;
+ if (condition_takes_path(t) && !path_is_absolute(param))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
Condition *c;
LIST_PREPEND(conditions, *list, c);
- if (t != CONDITION_NULL)
- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
- "%s=%s%s%s", type_name,
- trigger ? "|" : "", negate ? "!" : "", param);
- else
- unit_write_settingf(u, flags, name,
- "%s=%s%s", type_name,
- trigger ? "|" : "", yes_no(!negate));
+ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
+ "%s=%s%s%s", type_name,
+ trigger ? "|" : "", negate ? "!" : "", param);
}
empty = false;
UnitWriteFlags flags,
sd_bus_error *error) {
- UnitDependency d = _UNIT_DEPENDENCY_INVALID;
+ UnitDependency d;
int r;
assert(u);
assert(name);
assert(message);
- /* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
- * has been created. */
+ /* Handles settings when transient units are created. This settings cannot be altered anymore after
+ * the unit has been created. */
if (streq(name, "SourcePath"))
return bus_set_transient_path(u, name, &u->source_path, message, flags, error);
const char *s;
if (!UNIT_HAS_CGROUP_CONTEXT(u))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "The slice property is only available for units with control groups.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "The slice property is only available for units with control groups.");
if (u->type == UNIT_SLICE)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Slice may not be set for slice units.");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Slice may not be set for slice units.");
if (unit_has_name(u, SPECIAL_INIT_SCOPE))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set slice for init.scope");
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set slice for init.scope");
r = sd_bus_message_read(message, "s", &s);
if (r < 0)
return r;
if (!UNIT_VTABLE(u)->bus_set_property)
- return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties.");
+ return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY,
+ "Objects of this type do not support setting properties.");
r = sd_bus_message_enter_container(message, 'v', NULL);
if (r < 0)
return r;
if (r == 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
+ return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY,
+ "Cannot set property %s, or unknown property.", name);
r = sd_bus_message_exit_container(message);
if (r < 0)
return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING, "Unit %s has a bad unit file setting.", u->id);
case UNIT_ERROR: /* Only show .load_error in UNIT_ERROR state */
- return sd_bus_error_set_errnof(error, u->load_error, "Unit %s failed to load properly: %m.", u->id);
+ return sd_bus_error_set_errnof(error, u->load_error,
+ "Unit %s failed to load properly, please adjust/correct and reload service manager: %m", u->id);
case UNIT_MASKED:
return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", u->id);
int bus_unit_track_remove_sender(Unit *u, sd_bus_message *m) {
assert(u);
- /* If we haven't allocated the bus track object yet, then there's definitely no reference taken yet, return an
- * error */
+ /* If we haven't allocated the bus track object yet, then there's definitely no reference taken yet,
+ * return an error */
if (!u->bus_track)
return -EUNATCH;