mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-02 09:47:03 +03:00
unit: add new dependency type RequiresMountsFor=
RequiresMountsFor= is a shortcut for adding requires and after dependencies to all mount units neeed for the specified paths. This solves a couple of issues regarding dep loop cycles for encrypted swap.
This commit is contained in:
parent
a8ad0f8928
commit
7c8fa05c4d
@ -2889,6 +2889,7 @@ SED_PROCESS = \
|
|||||||
-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
|
-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
|
||||||
-e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
|
-e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
|
||||||
-e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \
|
-e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \
|
||||||
|
-e 's,@RANDOM_SEED\@,$(localstatedir)/lib/random-seed,g' \
|
||||||
-e 's,@prefix\@,$(prefix),g' \
|
-e 's,@prefix\@,$(prefix),g' \
|
||||||
-e 's,@exec_prefix\@,$(exec_prefix),g' \
|
-e 's,@exec_prefix\@,$(exec_prefix),g' \
|
||||||
-e 's,@libdir\@,$(libdir),g' \
|
-e 's,@libdir\@,$(libdir),g' \
|
||||||
|
@ -525,6 +525,18 @@
|
|||||||
settings.</para></listitem>
|
settings.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>RequiresMountsFor=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes a space
|
||||||
|
separated list of paths. Automatically
|
||||||
|
adds dependencies of type
|
||||||
|
<varname>Requires=</varname> and
|
||||||
|
<varname>After=</varname> for all
|
||||||
|
mount units required to access the
|
||||||
|
specified path.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>OnFailureIsolate=</varname></term>
|
<term><varname>OnFailureIsolate=</varname></term>
|
||||||
|
|
||||||
|
@ -810,6 +810,7 @@ const BusProperty bus_unit_properties[] = {
|
|||||||
{ "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true },
|
{ "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true },
|
||||||
{ "PropagateReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]), true },
|
{ "PropagateReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]), true },
|
||||||
{ "PropagateReloadFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]), true },
|
{ "PropagateReloadFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]), true },
|
||||||
|
{ "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true },
|
||||||
{ "Description", bus_unit_append_description, "s", 0 },
|
{ "Description", bus_unit_append_description, "s", 0 },
|
||||||
{ "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) },
|
{ "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) },
|
||||||
{ "ActiveState", bus_unit_append_active_state, "s", 0 },
|
{ "ActiveState", bus_unit_append_active_state, "s", 0 },
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
" <property name=\"TriggeredBy\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"TriggeredBy\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"PropagateReloadTo\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"PropagateReloadTo\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
|
||||||
|
" <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
|
||||||
|
@ -104,6 +104,7 @@ Unit.After, config_parse_unit_deps, UNIT_AFTER,
|
|||||||
Unit.OnFailure, config_parse_unit_deps, UNIT_ON_FAILURE, 0
|
Unit.OnFailure, config_parse_unit_deps, UNIT_ON_FAILURE, 0
|
||||||
Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_TO, 0
|
Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_TO, 0
|
||||||
Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_FROM, 0
|
Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_FROM, 0
|
||||||
|
Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, offsetof(Unit, requires_mounts_for)
|
||||||
Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded)
|
Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded)
|
||||||
Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start)
|
Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start)
|
||||||
Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop)
|
Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop)
|
||||||
|
@ -2032,6 +2032,35 @@ int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_unit_requires_mounts_for(
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
Unit *u = userdata;
|
||||||
|
int r;
|
||||||
|
bool empty_before;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
empty_before = !u->requires_mounts_for;
|
||||||
|
|
||||||
|
r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
|
||||||
|
|
||||||
|
/* Make it easy to find units with requires_mounts set */
|
||||||
|
if (empty_before && u->requires_mounts_for)
|
||||||
|
LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#define FOLLOW_MAX 8
|
#define FOLLOW_MAX 8
|
||||||
|
|
||||||
@ -2394,6 +2423,7 @@ void unit_dump_config_items(FILE *f) {
|
|||||||
{ config_parse_socket_bindtodevice, "NETWORKINTERFACE" },
|
{ config_parse_socket_bindtodevice, "NETWORKINTERFACE" },
|
||||||
{ config_parse_usec, "SECONDS" },
|
{ config_parse_usec, "SECONDS" },
|
||||||
{ config_parse_path_strv, "PATH [...]" },
|
{ config_parse_path_strv, "PATH [...]" },
|
||||||
|
{ config_parse_unit_requires_mounts_for, "PATH [...]" },
|
||||||
{ config_parse_exec_mount_flags, "MOUNTFLAG [...]" },
|
{ config_parse_exec_mount_flags, "MOUNTFLAG [...]" },
|
||||||
{ config_parse_unit_string_printf, "STRING" },
|
{ config_parse_unit_string_printf, "STRING" },
|
||||||
{ config_parse_timer, "TIMER" },
|
{ config_parse_timer, "TIMER" },
|
||||||
|
@ -83,6 +83,7 @@ int config_parse_unit_memory_limit(const char *filename, unsigned line, const ch
|
|||||||
int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
int config_parse_unit_requires_mounts_for(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
|
||||||
/* gperf prototypes */
|
/* gperf prototypes */
|
||||||
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
|
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
|
||||||
|
@ -104,6 +104,9 @@ struct Manager {
|
|||||||
* type we maintain a per type linked list */
|
* type we maintain a per type linked list */
|
||||||
LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
|
LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
|
||||||
|
|
||||||
|
/* To optimize iteration of units that have requires_mounts_for set */
|
||||||
|
LIST_HEAD(Unit, has_requires_mounts_for);
|
||||||
|
|
||||||
/* Units that need to be loaded */
|
/* Units that need to be loaded */
|
||||||
LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
|
LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
|
||||||
|
|
||||||
|
@ -263,6 +263,21 @@ static int mount_add_socket_links(Mount *m) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mount_add_requires_mounts_links(Mount *m) {
|
||||||
|
Unit *other;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) {
|
||||||
|
r = unit_add_one_mount_link(other, m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static char* mount_test_option(const char *haystack, const char *needle) {
|
static char* mount_test_option(const char *haystack, const char *needle) {
|
||||||
struct mntent me;
|
struct mntent me;
|
||||||
|
|
||||||
@ -614,6 +629,10 @@ static int mount_load(Unit *u) {
|
|||||||
if ((r = mount_add_path_links(m)) < 0)
|
if ((r = mount_add_path_links(m)) < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = mount_add_requires_mounts_links(m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
if ((r = mount_add_automount_links(m)) < 0)
|
if ((r = mount_add_automount_links(m)) < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -370,6 +370,11 @@ void unit_free(Unit *u) {
|
|||||||
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
|
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
|
||||||
bidi_set_free(u, u->dependencies[d]);
|
bidi_set_free(u, u->dependencies[d]);
|
||||||
|
|
||||||
|
if (u->requires_mounts_for) {
|
||||||
|
LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
|
||||||
|
strv_free(u->requires_mounts_for);
|
||||||
|
}
|
||||||
|
|
||||||
if (u->type != _UNIT_TYPE_INVALID)
|
if (u->type != _UNIT_TYPE_INVALID)
|
||||||
LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
|
LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
|
||||||
|
|
||||||
@ -691,6 +696,18 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
|||||||
fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
|
fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strv_isempty(u->requires_mounts_for)) {
|
||||||
|
char **j;
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"%s\tRequiresMountsFor:", prefix);
|
||||||
|
|
||||||
|
STRV_FOREACH(j, u->requires_mounts_for)
|
||||||
|
fprintf(f, " %s", *j);
|
||||||
|
|
||||||
|
fputs("\n", f);
|
||||||
|
}
|
||||||
|
|
||||||
if (u->load_state == UNIT_LOADED) {
|
if (u->load_state == UNIT_LOADED) {
|
||||||
CGroupBonding *b;
|
CGroupBonding *b;
|
||||||
CGroupAttribute *a;
|
CGroupAttribute *a;
|
||||||
@ -869,6 +886,12 @@ int unit_load(Unit *u) {
|
|||||||
if ((r = unit_add_default_dependencies(u)) < 0)
|
if ((r = unit_add_default_dependencies(u)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
r = unit_add_mount_links(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (u->on_failure_isolate &&
|
if (u->on_failure_isolate &&
|
||||||
set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
|
set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
|
||||||
|
|
||||||
@ -2685,6 +2708,45 @@ void unit_ref_unset(UnitRef *ref) {
|
|||||||
ref->unit = NULL;
|
ref->unit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int unit_add_one_mount_link(Unit *u, Mount *m) {
|
||||||
|
char **i;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
if (u->load_state != UNIT_LOADED ||
|
||||||
|
UNIT(m)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
STRV_FOREACH(i, u->requires_mounts_for) {
|
||||||
|
|
||||||
|
if (UNIT(m) == u)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!path_startswith(*i, m->where))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unit_add_mount_links(Unit *u) {
|
||||||
|
Unit *other;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
|
||||||
|
LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
|
||||||
|
r = unit_add_one_mount_link(u, MOUNT(other));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
|
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
|
||||||
[UNIT_STUB] = "stub",
|
[UNIT_STUB] = "stub",
|
||||||
[UNIT_LOADED] = "loaded",
|
[UNIT_LOADED] = "loaded",
|
||||||
|
@ -153,6 +153,8 @@ struct Unit {
|
|||||||
Set *names;
|
Set *names;
|
||||||
Set *dependencies[_UNIT_DEPENDENCY_MAX];
|
Set *dependencies[_UNIT_DEPENDENCY_MAX];
|
||||||
|
|
||||||
|
char **requires_mounts_for;
|
||||||
|
|
||||||
char *description;
|
char *description;
|
||||||
|
|
||||||
char *fragment_path; /* if loaded from a config file this is the primary path to it */
|
char *fragment_path; /* if loaded from a config file this is the primary path to it */
|
||||||
@ -186,6 +188,9 @@ struct Unit {
|
|||||||
/* Per type list */
|
/* Per type list */
|
||||||
LIST_FIELDS(Unit, units_by_type);
|
LIST_FIELDS(Unit, units_by_type);
|
||||||
|
|
||||||
|
/* All units which have requires_mounts_for set */
|
||||||
|
LIST_FIELDS(Unit, has_requires_mounts_for);
|
||||||
|
|
||||||
/* Load queue */
|
/* Load queue */
|
||||||
LIST_FIELDS(Unit, load_queue);
|
LIST_FIELDS(Unit, load_queue);
|
||||||
|
|
||||||
@ -554,6 +559,9 @@ void unit_ref_unset(UnitRef *ref);
|
|||||||
|
|
||||||
#define UNIT_DEREF(ref) ((ref).unit)
|
#define UNIT_DEREF(ref) ((ref).unit)
|
||||||
|
|
||||||
|
int unit_add_one_mount_link(Unit *u, Mount *m);
|
||||||
|
int unit_add_mount_links(Unit *u);
|
||||||
|
|
||||||
const char *unit_load_state_to_string(UnitLoadState i);
|
const char *unit_load_state_to_string(UnitLoadState i);
|
||||||
UnitLoadState unit_load_state_from_string(const char *s);
|
UnitLoadState unit_load_state_from_string(const char *s);
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Load Random Seed
|
Description=Load Random Seed
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
Wants=local-fs.target
|
|
||||||
Conflicts=shutdown.target
|
Conflicts=shutdown.target
|
||||||
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
|
After=systemd-readahead-collect.service systemd-readahead-replay.service
|
||||||
Before=sysinit.target shutdown.target
|
Before=sysinit.target shutdown.target
|
||||||
|
RequiresMountsFor=@RANDOM_SEED@
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
@ -11,6 +11,7 @@ DefaultDependencies=no
|
|||||||
After=systemd-random-seed-load.service
|
After=systemd-random-seed-load.service
|
||||||
Before=shutdown.target
|
Before=shutdown.target
|
||||||
Conflicts=systemd-random-seed-load.service
|
Conflicts=systemd-random-seed-load.service
|
||||||
|
RequiresMountsFor=@RANDOM_SEED@
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user