mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 16:59:03 +03:00
dbus-unit: support more options in transient units
This commit is contained in:
parent
c075f5fcf8
commit
faa781cfcb
@ -24,12 +24,15 @@
|
|||||||
#include "bpf-firewall.h"
|
#include "bpf-firewall.h"
|
||||||
#include "bus-common-errors.h"
|
#include "bus-common-errors.h"
|
||||||
#include "cgroup-util.h"
|
#include "cgroup-util.h"
|
||||||
|
#include "condition.h"
|
||||||
#include "dbus-job.h"
|
#include "dbus-job.h"
|
||||||
#include "dbus-unit.h"
|
#include "dbus-unit.h"
|
||||||
|
#include "dbus-util.h"
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "path-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "selinux-access.h"
|
#include "selinux-access.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
@ -37,6 +40,7 @@
|
|||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
#include "web-util.h"
|
||||||
|
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
|
||||||
@ -1353,6 +1357,81 @@ static int bus_unit_set_live_property(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string);
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string);
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string);
|
||||||
|
|
||||||
|
static int bus_set_transient_conditions(
|
||||||
|
Unit *u,
|
||||||
|
const char *name,
|
||||||
|
Condition **list,
|
||||||
|
bool is_condition,
|
||||||
|
sd_bus_message *message,
|
||||||
|
UnitWriteFlags flags,
|
||||||
|
sd_bus_error *error) {
|
||||||
|
|
||||||
|
const char *type_name, *param;
|
||||||
|
int trigger, negate, r;
|
||||||
|
bool empty = true;
|
||||||
|
|
||||||
|
assert(list);
|
||||||
|
|
||||||
|
r = sd_bus_message_enter_container(message, 'a', "(sbbs)");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
while ((r = sd_bus_message_read(message, "(sbbs)", &type_name, &trigger, &negate, ¶m)) > 0) {
|
||||||
|
ConditionType t;
|
||||||
|
|
||||||
|
t = is_condition ? condition_type_from_string(type_name) : assert_type_from_string(type_name);
|
||||||
|
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 (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 (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
Condition *c;
|
||||||
|
|
||||||
|
c = condition_new(t, param, trigger, negate);
|
||||||
|
if (!c)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_exit_container(message);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||||
|
*list = condition_free_list(*list);
|
||||||
|
unit_write_settingf(u, flags, name, "%sNull=", is_condition ? "Condition" : "Assert");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int bus_unit_set_transient_property(
|
static int bus_unit_set_transient_property(
|
||||||
Unit *u,
|
Unit *u,
|
||||||
const char *name,
|
const char *name,
|
||||||
@ -1360,6 +1439,7 @@ static int bus_unit_set_transient_property(
|
|||||||
UnitWriteFlags flags,
|
UnitWriteFlags flags,
|
||||||
sd_bus_error *error) {
|
sd_bus_error *error) {
|
||||||
|
|
||||||
|
UnitDependency d = _UNIT_DEPENDENCY_INVALID;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -1369,35 +1449,100 @@ static int bus_unit_set_transient_property(
|
|||||||
/* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
|
/* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
|
||||||
* has been created. */
|
* has been created. */
|
||||||
|
|
||||||
if (streq(name, "DefaultDependencies")) {
|
if (streq(name, "SourcePath"))
|
||||||
int b;
|
return bus_set_transient_path(u, name, &u->source_path, message, flags, error);
|
||||||
|
|
||||||
r = sd_bus_message_read(message, "b", &b);
|
if (streq(name, "StopWhenUnneeded"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->stop_when_unneeded, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "RefuseManualStart"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->refuse_manual_start, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "RefuseManualStop"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->refuse_manual_stop, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "AllowIsolate"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->allow_isolate, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "DefaultDependencies"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "OnFailureJobMode"))
|
||||||
|
return bus_set_transient_job_mode(u, name, &u->on_failure_job_mode, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "IgnoreOnIsolate"))
|
||||||
|
return bus_set_transient_bool(u, name, &u->ignore_on_isolate, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "JobTimeoutUSec")) {
|
||||||
|
r = bus_set_transient_usec_fix_0(u, name, &u->job_timeout, message, flags, error);
|
||||||
|
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags) && !u->job_running_timeout_set)
|
||||||
|
u->job_running_timeout = u->job_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(name, "JobRunningTimeoutUSec")) {
|
||||||
|
r = bus_set_transient_usec_fix_0(u, name, &u->job_running_timeout, message, flags, error);
|
||||||
|
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
|
||||||
|
u->job_running_timeout_set = true;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(name, "JobTimeoutAction"))
|
||||||
|
return bus_set_transient_emergency_action(u, name, &u->job_timeout_action, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "JobTimeoutRebootArgument"))
|
||||||
|
return bus_set_transient_string(u, name, &u->job_timeout_reboot_arg, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "StartLimitIntervalUSec"))
|
||||||
|
return bus_set_transient_usec(u, name, &u->start_limit.interval, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "StartLimitBurst"))
|
||||||
|
return bus_set_transient_unsigned(u, name, &u->start_limit.burst, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "StartLimitAction"))
|
||||||
|
return bus_set_transient_emergency_action(u, name, &u->start_limit_action, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "FailureAction"))
|
||||||
|
return bus_set_transient_emergency_action(u, name, &u->failure_action, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "SuccessAction"))
|
||||||
|
return bus_set_transient_emergency_action(u, name, &u->success_action, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "RebootArgument"))
|
||||||
|
return bus_set_transient_string(u, name, &u->reboot_arg, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "CollectMode"))
|
||||||
|
return bus_set_transient_collect_mode(u, name, &u->collect_mode, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "Conditions"))
|
||||||
|
return bus_set_transient_conditions(u, name, &u->conditions, true, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "Asserts"))
|
||||||
|
return bus_set_transient_conditions(u, name, &u->asserts, false, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "Documentation")) {
|
||||||
|
_cleanup_strv_free_ char **l = NULL;
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
r = sd_bus_message_read_strv(message, &l);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
STRV_FOREACH(p, l) {
|
||||||
u->default_dependencies = b;
|
if (!documentation_url_is_valid(*p))
|
||||||
unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b));
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid URL in %s: %s", name, *p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
} else if (streq(name, "CollectMode")) {
|
|
||||||
const char *s;
|
|
||||||
CollectMode m;
|
|
||||||
|
|
||||||
r = sd_bus_message_read(message, "s", &s);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
m = collect_mode_from_string(s);
|
|
||||||
if (m < 0)
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s);
|
|
||||||
|
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
u->collect_mode = m;
|
if (strv_isempty(l)) {
|
||||||
unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m));
|
u->documentation = strv_free(u->documentation);
|
||||||
|
unit_write_settingf(u, flags, name, "%s=", name);
|
||||||
|
} else {
|
||||||
|
strv_extend_strv(&u->documentation, l, false);
|
||||||
|
|
||||||
|
STRV_FOREACH(p, l)
|
||||||
|
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1440,30 +1585,40 @@ static int bus_unit_set_transient_property(
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else if (STR_IN_SET(name,
|
} else if (streq(name, "RequiresMountsFor")) {
|
||||||
"Requires", "RequiresOverridable",
|
_cleanup_strv_free_ char **l = NULL;
|
||||||
"Requisite", "RequisiteOverridable",
|
char **p;
|
||||||
"Wants",
|
|
||||||
"BindsTo",
|
|
||||||
"Conflicts",
|
|
||||||
"Before", "After",
|
|
||||||
"OnFailure",
|
|
||||||
"PropagatesReloadTo", "ReloadPropagatedFrom",
|
|
||||||
"PartOf")) {
|
|
||||||
|
|
||||||
UnitDependency d;
|
r = sd_bus_message_read_strv(message, &l);
|
||||||
const char *other;
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (streq(name, "RequiresOverridable"))
|
STRV_FOREACH(p, l) {
|
||||||
d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
|
if (!path_is_absolute(*p))
|
||||||
else if (streq(name, "RequisiteOverridable"))
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p);
|
||||||
d = UNIT_REQUISITE; /* same here */
|
|
||||||
else {
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
d = unit_dependency_from_string(name);
|
r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
|
||||||
if (d < 0)
|
if (r < 0)
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit dependency: %s", name);
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p);
|
||||||
|
|
||||||
|
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(name, "RequiresOverridable"))
|
||||||
|
d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
|
||||||
|
else if (streq(name, "RequisiteOverridable"))
|
||||||
|
d = UNIT_REQUISITE; /* same here */
|
||||||
|
else
|
||||||
|
d = unit_dependency_from_string(name);
|
||||||
|
|
||||||
|
if (d >= 0) {
|
||||||
|
const char *other;
|
||||||
|
|
||||||
r = sd_bus_message_enter_container(message, 'a', "s");
|
r = sd_bus_message_enter_container(message, 'a', "s");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1483,7 +1638,7 @@ static int bus_unit_set_transient_property(
|
|||||||
if (!label)
|
if (!label)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
unit_write_settingf(u, flags, label, "%s=%s", name, other);
|
unit_write_settingf(u, flags, label, "%s=%s", unit_dependency_to_string(d), other);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1496,30 +1651,6 @@ static int bus_unit_set_transient_property(
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else if (STR_IN_SET(name, "FailureAction", "SuccessAction")) {
|
|
||||||
EmergencyAction action;
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
r = sd_bus_message_read(message, "s", &s);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
action = emergency_action_from_string(s);
|
|
||||||
if (action < 0)
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s);
|
|
||||||
|
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
||||||
|
|
||||||
if (streq(name, "FailureAction"))
|
|
||||||
u->failure_action = action;
|
|
||||||
else
|
|
||||||
u->success_action = action;
|
|
||||||
|
|
||||||
unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
} else if (streq(name, "AddRef")) {
|
} else if (streq(name, "AddRef")) {
|
||||||
|
|
||||||
int b;
|
int b;
|
||||||
|
Loading…
Reference in New Issue
Block a user