core: add WantsMountsFor=
This is the equivalent of RequiresMountsFor=, but adds Wants= instead of Requires=. It will be useful for example for the autogenerated systemd-cryptsetup units. Fixes https://github.com/systemd/systemd/issues/11646
This commit is contained in:
@@ -1979,6 +1979,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
|||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly as RequiresMountsFor = ['...', ...];
|
readonly as RequiresMountsFor = ['...', ...];
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
readonly as WantsMountsFor = ['...', ...];
|
||||||
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly as Documentation = ['...', ...];
|
readonly as Documentation = ['...', ...];
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly s Description = '...';
|
readonly s Description = '...';
|
||||||
@@ -2135,6 +2137,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
|||||||
|
|
||||||
<!--property SliceOf is not documented!-->
|
<!--property SliceOf is not documented!-->
|
||||||
|
|
||||||
|
<!--property WantsMountsFor is not documented!-->
|
||||||
|
|
||||||
<!--property FreezerState is not documented!-->
|
<!--property FreezerState is not documented!-->
|
||||||
|
|
||||||
<!--property DropInPaths is not documented!-->
|
<!--property DropInPaths is not documented!-->
|
||||||
@@ -2295,6 +2299,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
|||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="RequiresMountsFor"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="RequiresMountsFor"/>
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="WantsMountsFor"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="Documentation"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="Documentation"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="Description"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="Description"/>
|
||||||
@@ -11829,6 +11835,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
|||||||
<varname>ActivationDetails</varname> were added in version 252.</para>
|
<varname>ActivationDetails</varname> were added in version 252.</para>
|
||||||
<para><function>QueueSignal()</function> was added in version 254.</para>
|
<para><function>QueueSignal()</function> was added in version 254.</para>
|
||||||
<para><varname>SurviveFinalKillSignal</varname> was added in version 255.</para>
|
<para><varname>SurviveFinalKillSignal</varname> was added in version 255.</para>
|
||||||
|
<para><varname>WantsMountsFor</varname> was added in version 256.</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
<refsect2>
|
<refsect2>
|
||||||
<title>Service Unit Objects</title>
|
<title>Service Unit Objects</title>
|
||||||
|
|||||||
@@ -255,13 +255,14 @@
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
<term><option>x-systemd.wants-mounts-for=</option></term>
|
||||||
<term><option>x-systemd.requires-mounts-for=</option></term>
|
<term><option>x-systemd.requires-mounts-for=</option></term>
|
||||||
|
|
||||||
<listitem><para>Configures a
|
<listitem><para>Configures a
|
||||||
<varname>RequiresMountsFor=</varname> dependency between the
|
<varname>RequiresMountsFor=</varname> or <varname>WantsMountsFor=</varname>
|
||||||
created mount unit and other mount units. The argument must be
|
dependency between the created mount unit and other mount units. The
|
||||||
an absolute path. This option may be specified more than once.
|
argument must be an absolute path. This option may be specified more than
|
||||||
See <varname>RequiresMountsFor=</varname> in
|
once. See <varname>RequiresMountsFor=</varname> or <varname>WantsMountsFor=</varname> in
|
||||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
for details.</para>
|
for details.</para>
|
||||||
|
|
||||||
|
|||||||
@@ -919,6 +919,16 @@
|
|||||||
<xi:include href="version-info.xml" xpointer="v201"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v201"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>WantsMountsFor=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Same as <varname>RequiresMountsFor=</varname>,
|
||||||
|
but adds dependencies of type <varname>Wants=</varname> instead
|
||||||
|
of <varname>Requires=</varname>.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>OnSuccessJobMode=</varname></term>
|
<term><varname>OnSuccessJobMode=</varname></term>
|
||||||
<term><varname>OnFailureJobMode=</varname></term>
|
<term><varname>OnFailureJobMode=</varname></term>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ static int automount_add_mount_dependencies(Automount *a) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return unit_require_mounts_for(UNIT(a), parent, UNIT_DEPENDENCY_IMPLICIT);
|
return unit_add_mounts_for(UNIT(a), parent, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int automount_add_default_dependencies(Automount *a) {
|
static int automount_add_default_dependencies(Automount *a) {
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ static int property_get_dependencies(
|
|||||||
return sd_bus_message_close_container(reply);
|
return sd_bus_message_close_container(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int property_get_requires_mounts_for(
|
static int property_get_mounts_for(
|
||||||
sd_bus *bus,
|
sd_bus *bus,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
@@ -879,7 +879,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
|||||||
SD_BUS_PROPERTY("StopPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("StopPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("SliceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("SliceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_requires_mounts_for, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_mounts_for, offsetof(Unit, mounts_for[UNIT_MOUNT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("WantsMountsFor", "as", property_get_mounts_for, offsetof(Unit, mounts_for[UNIT_MOUNT_WANTS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("AccessSELinuxContext", "s", NULL, offsetof(Unit, access_selinux_context), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("AccessSELinuxContext", "s", NULL, offsetof(Unit, access_selinux_context), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
@@ -2308,7 +2309,7 @@ static int bus_unit_set_transient_property(
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else if (streq(name, "RequiresMountsFor")) {
|
} else if (STR_IN_SET(name, "RequiresMountsFor", "WantsMountsFor")) {
|
||||||
_cleanup_strv_free_ char **l = NULL;
|
_cleanup_strv_free_ char **l = NULL;
|
||||||
|
|
||||||
r = sd_bus_message_read_strv(message, &l);
|
r = sd_bus_message_read_strv(message, &l);
|
||||||
@@ -2328,9 +2329,9 @@ static int bus_unit_set_transient_property(
|
|||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not normalized: %s", name, *p);
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not normalized: %s", name, *p);
|
||||||
|
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, *p, UNIT_DEPENDENCY_FILE, unit_mount_dependency_type_from_string(name));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p);
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add requested mount \"%s\": %m", *p);
|
||||||
|
|
||||||
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,8 @@ Unit.PartOf, config_parse_unit_deps,
|
|||||||
Unit.JoinsNamespaceOf, config_parse_unit_deps, UNIT_JOINS_NAMESPACE_OF, 0
|
Unit.JoinsNamespaceOf, config_parse_unit_deps, UNIT_JOINS_NAMESPACE_OF, 0
|
||||||
Unit.RequiresOverridable, config_parse_obsolete_unit_deps, UNIT_REQUIRES, 0
|
Unit.RequiresOverridable, config_parse_obsolete_unit_deps, UNIT_REQUIRES, 0
|
||||||
Unit.RequisiteOverridable, config_parse_obsolete_unit_deps, UNIT_REQUISITE, 0
|
Unit.RequisiteOverridable, config_parse_obsolete_unit_deps, UNIT_REQUISITE, 0
|
||||||
Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, 0
|
Unit.RequiresMountsFor, config_parse_unit_mounts_for, 0, 0
|
||||||
|
Unit.WantsMountsFor, config_parse_unit_mounts_for, 0, 0
|
||||||
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)
|
||||||
|
|||||||
@@ -3152,7 +3152,7 @@ int config_parse_unit_condition_string(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_unit_requires_mounts_for(
|
int config_parse_unit_mounts_for(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
@@ -3171,6 +3171,7 @@ int config_parse_unit_requires_mounts_for(
|
|||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(data);
|
assert(data);
|
||||||
|
assert(STR_IN_SET(lvalue, "RequiresMountsFor", "WantsMountsFor"));
|
||||||
|
|
||||||
for (const char *p = rvalue;;) {
|
for (const char *p = rvalue;;) {
|
||||||
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
||||||
@@ -3196,9 +3197,9 @@ int config_parse_unit_requires_mounts_for(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = unit_require_mounts_for(u, resolved, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, resolved, UNIT_DEPENDENCY_FILE, unit_mount_dependency_type_from_string(lvalue));
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to add required mount '%s', ignoring: %m", resolved);
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to add requested mount '%s', ignoring: %m", resolved);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6301,8 +6302,7 @@ void unit_dump_config_items(FILE *f) {
|
|||||||
{ config_parse_nsec, "NANOSECONDS" },
|
{ config_parse_nsec, "NANOSECONDS" },
|
||||||
{ config_parse_namespace_path_strv, "PATH [...]" },
|
{ config_parse_namespace_path_strv, "PATH [...]" },
|
||||||
{ config_parse_bind_paths, "PATH[:PATH[:OPTIONS]] [...]" },
|
{ config_parse_bind_paths, "PATH[:PATH[:OPTIONS]] [...]" },
|
||||||
{ config_parse_unit_requires_mounts_for,
|
{ config_parse_unit_mounts_for, "PATH [...]" },
|
||||||
"PATH [...]" },
|
|
||||||
{ config_parse_exec_mount_propagation_flag,
|
{ config_parse_exec_mount_propagation_flag,
|
||||||
"MOUNTFLAG" },
|
"MOUNTFLAG" },
|
||||||
{ config_parse_unit_string_printf, "STRING" },
|
{ config_parse_unit_string_printf, "STRING" },
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_string);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_kill_mode);
|
CONFIG_PARSER_PROTOTYPE(config_parse_kill_mode);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_notify_access);
|
CONFIG_PARSER_PROTOTYPE(config_parse_notify_access);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_emergency_action);
|
CONFIG_PARSER_PROTOTYPE(config_parse_emergency_action);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_unit_requires_mounts_for);
|
CONFIG_PARSER_PROTOTYPE(config_parse_unit_mounts_for);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_filter);
|
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_filter);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_archs);
|
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_archs);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_errno);
|
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_errno);
|
||||||
|
|||||||
+7
-4
@@ -1691,8 +1691,10 @@ Manager* manager_free(Manager *m) {
|
|||||||
|
|
||||||
unit_defaults_done(&m->defaults);
|
unit_defaults_done(&m->defaults);
|
||||||
|
|
||||||
assert(hashmap_isempty(m->units_requiring_mounts_for));
|
FOREACH_ARRAY(map, m->units_needing_mounts_for, _UNIT_MOUNT_DEPENDENCY_TYPE_MAX) {
|
||||||
hashmap_free(m->units_requiring_mounts_for);
|
assert(hashmap_isempty(*map));
|
||||||
|
hashmap_free(*map);
|
||||||
|
}
|
||||||
|
|
||||||
hashmap_free(m->uid_refs);
|
hashmap_free(m->uid_refs);
|
||||||
hashmap_free(m->gid_refs);
|
hashmap_free(m->gid_refs);
|
||||||
@@ -4478,14 +4480,15 @@ void manager_status_printf(Manager *m, StatusType type, const char *status, cons
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set* manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
|
Set* manager_get_units_needing_mounts_for(Manager *m, const char *path, UnitMountDependencyType t) {
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(path);
|
assert(path);
|
||||||
|
assert(t >= 0 && t < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX);
|
||||||
|
|
||||||
if (path_equal(path, "/"))
|
if (path_equal(path, "/"))
|
||||||
path = "";
|
path = "";
|
||||||
|
|
||||||
return hashmap_get(m->units_requiring_mounts_for, path);
|
return hashmap_get(m->units_needing_mounts_for[t], path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
|
int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
|
||||||
|
|||||||
+5
-5
@@ -137,6 +137,7 @@ typedef enum WatchdogType {
|
|||||||
#include "path-lookup.h"
|
#include "path-lookup.h"
|
||||||
#include "show-status.h"
|
#include "show-status.h"
|
||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
|
#include "unit.h"
|
||||||
|
|
||||||
typedef enum ManagerTestRunFlags {
|
typedef enum ManagerTestRunFlags {
|
||||||
MANAGER_TEST_NORMAL = 0, /* run normally */
|
MANAGER_TEST_NORMAL = 0, /* run normally */
|
||||||
@@ -438,10 +439,9 @@ struct Manager {
|
|||||||
/* This is true before and after switching root. */
|
/* This is true before and after switching root. */
|
||||||
bool switching_root;
|
bool switching_root;
|
||||||
|
|
||||||
/* This maps all possible path prefixes to the units needing
|
/* These map all possible path prefixes to the units needing them. They are hashmaps with a path
|
||||||
* them. It's a hashmap with a path string as key and a Set as
|
* string as key, and a Set as value where Unit objects are contained. */
|
||||||
* value where Unit objects are contained. */
|
Hashmap *units_needing_mounts_for[_UNIT_MOUNT_DEPENDENCY_TYPE_MAX];
|
||||||
Hashmap *units_requiring_mounts_for;
|
|
||||||
|
|
||||||
/* Used for processing polkit authorization responses */
|
/* Used for processing polkit authorization responses */
|
||||||
Hashmap *polkit_registry;
|
Hashmap *polkit_registry;
|
||||||
@@ -596,7 +596,7 @@ double manager_get_progress(Manager *m);
|
|||||||
|
|
||||||
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
|
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
|
||||||
|
|
||||||
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
|
Set* manager_get_units_needing_mounts_for(Manager *m, const char *path, UnitMountDependencyType t);
|
||||||
|
|
||||||
ManagerState manager_state(Manager *m);
|
ManagerState manager_state(Manager *m);
|
||||||
|
|
||||||
|
|||||||
+28
-17
@@ -281,8 +281,6 @@ static int update_parameters_proc_self_mountinfo(
|
|||||||
|
|
||||||
static int mount_add_mount_dependencies(Mount *m) {
|
static int mount_add_mount_dependencies(Mount *m) {
|
||||||
MountParameters *pm;
|
MountParameters *pm;
|
||||||
Unit *other;
|
|
||||||
Set *s;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
@@ -296,7 +294,7 @@ static int mount_add_mount_dependencies(Mount *m) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = unit_require_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT);
|
r = unit_add_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -308,30 +306,43 @@ static int mount_add_mount_dependencies(Mount *m) {
|
|||||||
path_is_absolute(pm->what) &&
|
path_is_absolute(pm->what) &&
|
||||||
(mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
|
(mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
|
||||||
|
|
||||||
r = unit_require_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds in dependencies to other units that use this path or paths further down in the hierarchy */
|
/* Adds in dependencies to other units that use this path or paths further down in the hierarchy */
|
||||||
s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
|
for (UnitMountDependencyType t = 0; t < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX; ++t) {
|
||||||
SET_FOREACH(other, s) {
|
Unit *other;
|
||||||
|
Set *s = manager_get_units_needing_mounts_for(UNIT(m)->manager, m->where, t);
|
||||||
|
|
||||||
if (other->load_state != UNIT_LOADED)
|
SET_FOREACH(other, s) {
|
||||||
continue;
|
if (other->load_state != UNIT_LOADED)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (other == UNIT(m))
|
if (other == UNIT(m))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true, UNIT_DEPENDENCY_PATH);
|
r = unit_add_dependency(
|
||||||
if (r < 0)
|
other,
|
||||||
return r;
|
UNIT_AFTER,
|
||||||
|
UNIT(m),
|
||||||
if (UNIT(m)->fragment_path) {
|
/* add_reference= */ true,
|
||||||
/* If we have fragment configuration, then make this dependency required */
|
UNIT_DEPENDENCY_PATH);
|
||||||
r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true, UNIT_DEPENDENCY_PATH);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (UNIT(m)->fragment_path) {
|
||||||
|
/* If we have fragment configuration, then make this dependency required/wanted */
|
||||||
|
r = unit_add_dependency(
|
||||||
|
other,
|
||||||
|
unit_mount_dependency_type_to_dependency_type(t),
|
||||||
|
UNIT(m),
|
||||||
|
/* add_reference= */ true,
|
||||||
|
UNIT_DEPENDENCY_PATH);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -309,7 +309,7 @@ static int path_add_mount_dependencies(Path *p) {
|
|||||||
assert(p);
|
assert(p);
|
||||||
|
|
||||||
LIST_FOREACH(spec, s, p->specs) {
|
LIST_FOREACH(spec, s, p->specs) {
|
||||||
r = unit_require_mounts_for(UNIT(p), s->path, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(UNIT(p), s->path, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -221,7 +221,7 @@ static int socket_add_mount_dependencies(Socket *s) {
|
|||||||
if (!path)
|
if (!path)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = unit_require_mounts_for(UNIT(s), path, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(UNIT(s), path, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -321,7 +321,7 @@ static int swap_add_extras(Swap *s) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = unit_require_mounts_for(UNIT(s), s->what, UNIT_DEPENDENCY_IMPLICIT);
|
r = unit_add_mounts_for(UNIT(s), s->what, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ static int timer_setup_persistent(Timer *t) {
|
|||||||
|
|
||||||
if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
|
if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
|
||||||
|
|
||||||
r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers", UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(UNIT(t), "/var/lib/systemd/timers", UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -831,21 +831,26 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hashmap_isempty(u->requires_mounts_for)) {
|
for (UnitMountDependencyType type = 0; type < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX; type++)
|
||||||
UnitDependencyInfo di;
|
if (!hashmap_isempty(u->mounts_for[type])) {
|
||||||
const char *path;
|
UnitDependencyInfo di;
|
||||||
|
const char *path;
|
||||||
|
|
||||||
HASHMAP_FOREACH_KEY(di.data, path, u->requires_mounts_for) {
|
HASHMAP_FOREACH_KEY(di.data, path, u->mounts_for[type]) {
|
||||||
bool space = false;
|
bool space = false;
|
||||||
|
|
||||||
fprintf(f, "%s\tRequiresMountsFor: %s (", prefix, path);
|
fprintf(f,
|
||||||
|
"%s\t%s: %s (",
|
||||||
|
prefix,
|
||||||
|
unit_mount_dependency_type_to_string(type),
|
||||||
|
path);
|
||||||
|
|
||||||
print_unit_dependency_mask(f, "origin", di.origin_mask, &space);
|
print_unit_dependency_mask(f, "origin", di.origin_mask, &space);
|
||||||
print_unit_dependency_mask(f, "destination", di.destination_mask, &space);
|
print_unit_dependency_mask(f, "destination", di.destination_mask, &space);
|
||||||
|
|
||||||
fputs(")\n", f);
|
fputs(")\n", f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (u->load_state == UNIT_LOADED) {
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
|
||||||
|
|||||||
+102
-54
@@ -689,38 +689,39 @@ static void unit_remove_transient(Unit *u) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_free_requires_mounts_for(Unit *u) {
|
static void unit_free_mounts_for(Unit *u) {
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
for (;;) {
|
for (UnitMountDependencyType t = 0; t < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX; ++t) {
|
||||||
_cleanup_free_ char *path = NULL;
|
for (;;) {
|
||||||
|
_cleanup_free_ char *path = NULL;
|
||||||
|
|
||||||
|
path = hashmap_steal_first_key(u->mounts_for[t]);
|
||||||
|
if (!path)
|
||||||
|
break;
|
||||||
|
|
||||||
path = hashmap_steal_first_key(u->requires_mounts_for);
|
|
||||||
if (!path)
|
|
||||||
break;
|
|
||||||
else {
|
|
||||||
char s[strlen(path) + 1];
|
char s[strlen(path) + 1];
|
||||||
|
|
||||||
PATH_FOREACH_PREFIX_MORE(s, path) {
|
PATH_FOREACH_PREFIX_MORE(s, path) {
|
||||||
char *y;
|
char *y;
|
||||||
Set *x;
|
Set *x;
|
||||||
|
|
||||||
x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
|
x = hashmap_get2(u->manager->units_needing_mounts_for[t], s, (void**) &y);
|
||||||
if (!x)
|
if (!x)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
(void) set_remove(x, u);
|
(void) set_remove(x, u);
|
||||||
|
|
||||||
if (set_isempty(x)) {
|
if (set_isempty(x)) {
|
||||||
(void) hashmap_remove(u->manager->units_requiring_mounts_for, y);
|
assert_se(hashmap_remove(u->manager->units_needing_mounts_for[t], y));
|
||||||
free(y);
|
free(y);
|
||||||
set_free(x);
|
set_free(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
u->requires_mounts_for = hashmap_free(u->requires_mounts_for);
|
u->mounts_for[t] = hashmap_free(u->mounts_for[t]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_done(Unit *u) {
|
static void unit_done(Unit *u) {
|
||||||
@@ -769,7 +770,7 @@ Unit* unit_free(Unit *u) {
|
|||||||
u->deserialized_refs = strv_free(u->deserialized_refs);
|
u->deserialized_refs = strv_free(u->deserialized_refs);
|
||||||
u->pending_freezer_invocation = sd_bus_message_unref(u->pending_freezer_invocation);
|
u->pending_freezer_invocation = sd_bus_message_unref(u->pending_freezer_invocation);
|
||||||
|
|
||||||
unit_free_requires_mounts_for(u);
|
unit_free_mounts_for(u);
|
||||||
|
|
||||||
SET_FOREACH(t, u->aliases)
|
SET_FOREACH(t, u->aliases)
|
||||||
hashmap_remove_value(u->manager->units, t, u);
|
hashmap_remove_value(u->manager->units, t, u);
|
||||||
@@ -1278,19 +1279,19 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
|
|||||||
/* Unlike unit_add_dependency() or friends, this always returns 0 on success. */
|
/* Unlike unit_add_dependency() or friends, this always returns 0 on success. */
|
||||||
|
|
||||||
if (c->working_directory && !c->working_directory_missing_ok) {
|
if (c->working_directory && !c->working_directory_missing_ok) {
|
||||||
r = unit_require_mounts_for(u, c->working_directory, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, c->working_directory, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->root_directory) {
|
if (c->root_directory) {
|
||||||
r = unit_require_mounts_for(u, c->root_directory, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, c->root_directory, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->root_image) {
|
if (c->root_image) {
|
||||||
r = unit_require_mounts_for(u, c->root_image, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, c->root_image, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -1306,7 +1307,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
|
|||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, p, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -1335,7 +1336,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = unit_require_mounts_for(u, "/var/tmp", UNIT_DEPENDENCY_FILE);
|
r = unit_add_mounts_for(u, "/var/tmp", UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -1536,51 +1537,72 @@ static int unit_add_slice_dependencies(Unit *u) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int unit_add_mount_dependencies(Unit *u) {
|
static int unit_add_mount_dependencies(Unit *u) {
|
||||||
UnitDependencyInfo di;
|
|
||||||
const char *path;
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
HASHMAP_FOREACH_KEY(di.data, path, u->requires_mounts_for) {
|
for (UnitMountDependencyType t = 0; t < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX; ++t) {
|
||||||
char prefix[strlen(path) + 1];
|
UnitDependencyInfo di;
|
||||||
|
const char *path;
|
||||||
|
|
||||||
PATH_FOREACH_PREFIX_MORE(prefix, path) {
|
HASHMAP_FOREACH_KEY(di.data, path, u->mounts_for[t]) {
|
||||||
_cleanup_free_ char *p = NULL;
|
|
||||||
Unit *m;
|
|
||||||
|
|
||||||
r = unit_name_from_path(prefix, ".mount", &p);
|
char prefix[strlen(ASSERT_PTR(path)) + 1];
|
||||||
if (r == -EINVAL)
|
|
||||||
continue; /* If the path cannot be converted to a mount unit name, then it's
|
|
||||||
* not manageable as a unit by systemd, and hence we don't need a
|
|
||||||
* dependency on it. Let's thus silently ignore the issue. */
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
m = manager_get_unit(u->manager, p);
|
PATH_FOREACH_PREFIX_MORE(prefix, path) {
|
||||||
if (!m) {
|
_cleanup_free_ char *p = NULL;
|
||||||
/* Make sure to load the mount unit if it exists. If so the dependencies on
|
Unit *m;
|
||||||
* this unit will be added later during the loading of the mount unit. */
|
|
||||||
(void) manager_load_unit_prepare(u->manager, p, NULL, NULL, &m);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (m == u)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (m->load_state != UNIT_LOADED)
|
r = unit_name_from_path(prefix, ".mount", &p);
|
||||||
continue;
|
if (r == -EINVAL)
|
||||||
|
continue; /* If the path cannot be converted to a mount unit name,
|
||||||
|
* then it's not manageable as a unit by systemd, and
|
||||||
|
* hence we don't need a dependency on it. Let's thus
|
||||||
|
* silently ignore the issue. */
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = unit_add_dependency(u, UNIT_AFTER, m, true, di.origin_mask);
|
m = manager_get_unit(u->manager, p);
|
||||||
if (r < 0)
|
if (!m) {
|
||||||
return r;
|
/* Make sure to load the mount unit if it exists. If so the
|
||||||
changed = changed || r > 0;
|
* dependencies on this unit will be added later during the loading
|
||||||
|
* of the mount unit. */
|
||||||
|
(void) manager_load_unit_prepare(
|
||||||
|
u->manager,
|
||||||
|
p,
|
||||||
|
/* path= */NULL,
|
||||||
|
/* e= */NULL,
|
||||||
|
&m);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (m == u)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (m->fragment_path) {
|
if (m->load_state != UNIT_LOADED)
|
||||||
r = unit_add_dependency(u, UNIT_REQUIRES, m, true, di.origin_mask);
|
continue;
|
||||||
|
|
||||||
|
r = unit_add_dependency(
|
||||||
|
u,
|
||||||
|
UNIT_AFTER,
|
||||||
|
m,
|
||||||
|
/* add_reference= */ true,
|
||||||
|
di.origin_mask);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
changed = changed || r > 0;
|
changed = changed || r > 0;
|
||||||
|
|
||||||
|
if (m->fragment_path) {
|
||||||
|
r = unit_add_dependency(
|
||||||
|
u,
|
||||||
|
unit_mount_dependency_type_to_dependency_type(t),
|
||||||
|
m,
|
||||||
|
/* add_reference= */ true,
|
||||||
|
di.origin_mask);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
changed = changed || r > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4942,11 +4964,16 @@ int unit_kill_context(
|
|||||||
return wait_for_exit;
|
return wait_for_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) {
|
int unit_add_mounts_for(Unit *u, const char *path, UnitDependencyMask mask, UnitMountDependencyType type) {
|
||||||
|
Hashmap **unit_map, **manager_map;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(path);
|
assert(path);
|
||||||
|
assert(type >= 0 && type < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX);
|
||||||
|
|
||||||
|
unit_map = &u->mounts_for[type];
|
||||||
|
manager_map = &u->manager->units_needing_mounts_for[type];
|
||||||
|
|
||||||
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these
|
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these
|
||||||
* paths in the unit (from the path to the UnitDependencyInfo structure indicating how to the
|
* paths in the unit (from the path to the UnitDependencyInfo structure indicating how to the
|
||||||
@@ -4956,7 +4983,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
|
|||||||
if (!path_is_absolute(path))
|
if (!path_is_absolute(path))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (hashmap_contains(u->requires_mounts_for, path)) /* Exit quickly if the path is already covered. */
|
if (hashmap_contains(*unit_map, path)) /* Exit quickly if the path is already covered. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Use the canonical form of the path as the stored key. We call path_is_normalized()
|
/* Use the canonical form of the path as the stored key. We call path_is_normalized()
|
||||||
@@ -4975,7 +5002,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
|
|||||||
.origin_mask = mask
|
.origin_mask = mask
|
||||||
};
|
};
|
||||||
|
|
||||||
r = hashmap_ensure_put(&u->requires_mounts_for, &path_hash_ops, p, di.data);
|
r = hashmap_ensure_put(unit_map, &path_hash_ops, p, di.data);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
assert(r > 0);
|
assert(r > 0);
|
||||||
@@ -4985,11 +5012,11 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
|
|||||||
PATH_FOREACH_PREFIX_MORE(prefix, path) {
|
PATH_FOREACH_PREFIX_MORE(prefix, path) {
|
||||||
Set *x;
|
Set *x;
|
||||||
|
|
||||||
x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
|
x = hashmap_get(*manager_map, prefix);
|
||||||
if (!x) {
|
if (!x) {
|
||||||
_cleanup_free_ char *q = NULL;
|
_cleanup_free_ char *q = NULL;
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&u->manager->units_requiring_mounts_for, &path_hash_ops);
|
r = hashmap_ensure_allocated(manager_map, &path_hash_ops);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -5001,7 +5028,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
|
|||||||
if (!x)
|
if (!x)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
|
r = hashmap_put(*manager_map, q, x);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
set_free(x);
|
set_free(x);
|
||||||
return r;
|
return r;
|
||||||
@@ -6615,3 +6642,24 @@ int activation_details_append_pair(ActivationDetails *details, char ***strv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(ActivationDetails, activation_details, activation_details_free);
|
DEFINE_TRIVIAL_REF_UNREF_FUNC(ActivationDetails, activation_details, activation_details_free);
|
||||||
|
|
||||||
|
static const char* const unit_mount_dependency_type_table[_UNIT_MOUNT_DEPENDENCY_TYPE_MAX] = {
|
||||||
|
[UNIT_MOUNT_WANTS] = "WantsMountsFor",
|
||||||
|
[UNIT_MOUNT_REQUIRES] = "RequiresMountsFor",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(unit_mount_dependency_type, UnitMountDependencyType);
|
||||||
|
|
||||||
|
UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependencyType t) {
|
||||||
|
switch (t) {
|
||||||
|
|
||||||
|
case UNIT_MOUNT_WANTS:
|
||||||
|
return UNIT_WANTS;
|
||||||
|
|
||||||
|
case UNIT_MOUNT_REQUIRES:
|
||||||
|
return UNIT_REQUIRES;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+17
-4
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -8,6 +9,14 @@
|
|||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
/* Circular dependency with manager.h, needs to be defined before local includes */
|
||||||
|
typedef enum UnitMountDependencyType {
|
||||||
|
UNIT_MOUNT_WANTS,
|
||||||
|
UNIT_MOUNT_REQUIRES,
|
||||||
|
_UNIT_MOUNT_DEPENDENCY_TYPE_MAX,
|
||||||
|
_UNIT_MOUNT_DEPENDENCY_TYPE_INVALID = -EINVAL,
|
||||||
|
} UnitMountDependencyType;
|
||||||
|
|
||||||
#include "bpf-program.h"
|
#include "bpf-program.h"
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
#include "condition.h"
|
#include "condition.h"
|
||||||
@@ -216,9 +225,9 @@ typedef struct Unit {
|
|||||||
* Hashmap(UnitDependency → Hashmap(Unit* → UnitDependencyInfo)) */
|
* Hashmap(UnitDependency → Hashmap(Unit* → UnitDependencyInfo)) */
|
||||||
Hashmap *dependencies;
|
Hashmap *dependencies;
|
||||||
|
|
||||||
/* Similar, for RequiresMountsFor= path dependencies. The key is the path, the value the
|
/* Similar, for RequiresMountsFor= and WantsMountsFor= path dependencies. The key is the path, the
|
||||||
* UnitDependencyInfo type */
|
* value the UnitDependencyInfo type */
|
||||||
Hashmap *requires_mounts_for;
|
Hashmap *mounts_for[_UNIT_MOUNT_DEPENDENCY_TYPE_MAX];
|
||||||
|
|
||||||
char *description;
|
char *description;
|
||||||
char **documentation;
|
char **documentation;
|
||||||
@@ -1001,7 +1010,7 @@ int unit_kill_context(Unit *u, KillContext *c, KillOperation k, PidRef *main_pid
|
|||||||
|
|
||||||
int unit_make_transient(Unit *u);
|
int unit_make_transient(Unit *u);
|
||||||
|
|
||||||
int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask);
|
int unit_add_mounts_for(Unit *u, const char *path, UnitDependencyMask mask, UnitMountDependencyType type);
|
||||||
|
|
||||||
bool unit_type_supported(UnitType t);
|
bool unit_type_supported(UnitType t);
|
||||||
|
|
||||||
@@ -1101,6 +1110,10 @@ int unit_arm_timer(Unit *u, sd_event_source **source, bool relative, usec_t usec
|
|||||||
|
|
||||||
int unit_compare_priority(Unit *a, Unit *b);
|
int unit_compare_priority(Unit *a, Unit *b);
|
||||||
|
|
||||||
|
UnitMountDependencyType unit_mount_dependency_type_from_string(const char *s) _const_;
|
||||||
|
const char* unit_mount_dependency_type_to_string(UnitMountDependencyType t) _const_;
|
||||||
|
UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependencyType t) _pure_;
|
||||||
|
|
||||||
/* Macros which append UNIT= or USER_UNIT= to the message */
|
/* Macros which append UNIT= or USER_UNIT= to the message */
|
||||||
|
|
||||||
#define log_unit_full_errno_zerook(unit, level, error, ...) \
|
#define log_unit_full_errno_zerook(unit, level, error, ...) \
|
||||||
|
|||||||
@@ -416,15 +416,17 @@ static int write_before(FILE *f, const char *opts) {
|
|||||||
"x-systemd.before\0", "Before=%1$s\n");
|
"x-systemd.before\0", "Before=%1$s\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_requires_mounts_for(FILE *f, const char *opts) {
|
static int write_mounts_for(const char *x_opt, const char *unit_setting, FILE *f, const char *opts) {
|
||||||
_cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
|
_cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
|
||||||
_cleanup_free_ char *res = NULL;
|
_cleanup_free_ char *res = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
assert(x_opt);
|
||||||
|
assert(unit_setting);
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(opts);
|
assert(opts);
|
||||||
|
|
||||||
r = fstab_filter_options(opts, "x-systemd.requires-mounts-for\0", NULL, NULL, &paths, NULL);
|
r = fstab_filter_options(opts, x_opt, NULL, NULL, &paths, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(r, "Failed to parse options: %m");
|
return log_warning_errno(r, "Failed to parse options: %m");
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@@ -438,7 +440,7 @@ static int write_requires_mounts_for(FILE *f, const char *opts) {
|
|||||||
if (!res)
|
if (!res)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
fprintf(f, "RequiresMountsFor=%s\n", res);
|
fprintf(f, "%s=%s\n", unit_setting, res);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -458,7 +460,10 @@ static int write_extra_dependencies(FILE *f, const char *opts) {
|
|||||||
r = write_before(f, opts);
|
r = write_before(f, opts);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
r = write_requires_mounts_for(f, opts);
|
r = write_mounts_for("x-systemd.requires-mounts-for\0", "RequiresMountsFor", f, opts);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
r = write_mounts_for("x-systemd.wants-mounts-for\0", "WantsMountsFor", f, opts);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2643,6 +2643,7 @@ static int bus_append_unit_property(sd_bus_message *m, const char *field, const
|
|||||||
if (unit_dependency_from_string(field) >= 0 ||
|
if (unit_dependency_from_string(field) >= 0 ||
|
||||||
STR_IN_SET(field, "Documentation",
|
STR_IN_SET(field, "Documentation",
|
||||||
"RequiresMountsFor",
|
"RequiresMountsFor",
|
||||||
|
"WantsMountsFor",
|
||||||
"Markers"))
|
"Markers"))
|
||||||
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
||||||
|
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ User=
|
|||||||
WakeSystem=
|
WakeSystem=
|
||||||
WantedBy=
|
WantedBy=
|
||||||
Wants=
|
Wants=
|
||||||
|
WantsMountsFor=
|
||||||
WatchdogSec=
|
WatchdogSec=
|
||||||
What=
|
What=
|
||||||
Where=
|
Where=
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ After=sysinit.target sockets.target paths.target slices.target tmp.mount
|
|||||||
# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as
|
# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as
|
||||||
# we support that unit being masked, and this should not be considered an error.
|
# we support that unit being masked, and this should not be considered an error.
|
||||||
RequiresMountsFor=/var /var/tmp
|
RequiresMountsFor=/var /var/tmp
|
||||||
Wants=tmp.mount
|
WantsMountsFor=/tmp
|
||||||
|
|||||||
Reference in New Issue
Block a user