1
0
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:
Yu Watanabe 2018-01-02 00:26:34 +09:00
parent c075f5fcf8
commit faa781cfcb

View File

@ -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, &param)) > 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;