mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 18:55:09 +03:00
commit
e1e214c56b
@ -86,6 +86,10 @@
|
||||
<listitem><para>Automount units acquire automatic <varname>Before=</varname> and
|
||||
<varname>Conflicts=</varname> on <filename>umount.target</filename> in order to be stopped during
|
||||
shutdown.</para></listitem>
|
||||
|
||||
<listitem><para>Automount units automatically gain an <varname>After=</varname> dependency
|
||||
on <filename>local-fs-pre.target</filename>, and a <varname>Before=</varname> dependency on
|
||||
<filename>local-fs.target</filename>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
@ -152,6 +152,10 @@ static int automount_add_default_dependencies(Automount *a) {
|
||||
if (!MANAGER_IS_SYSTEM(UNIT(a)->manager))
|
||||
return 0;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(a), UNIT_AFTER, SPECIAL_LOCAL_FS_PRE_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1063,7 +1063,6 @@ const UnitVTable device_vtable = {
|
||||
"Device\0"
|
||||
"Install\0",
|
||||
|
||||
.refuse_after = true,
|
||||
.gc_jobs = true,
|
||||
|
||||
.init = device_init,
|
||||
|
140
src/core/mount.c
140
src/core/mount.c
@ -66,6 +66,14 @@ static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
|
||||
MOUNT_CLEANING);
|
||||
}
|
||||
|
||||
static bool mount_is_automount(const MountParameters *p) {
|
||||
assert(p);
|
||||
|
||||
return fstab_test_option(p->options,
|
||||
"comment=systemd.automount\0"
|
||||
"x-systemd.automount\0");
|
||||
}
|
||||
|
||||
static bool mount_is_network(const MountParameters *p) {
|
||||
assert(p);
|
||||
|
||||
@ -78,6 +86,15 @@ static bool mount_is_network(const MountParameters *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool mount_is_nofail(const Mount *m) {
|
||||
assert(m);
|
||||
|
||||
if (!m->from_fragment)
|
||||
return false;
|
||||
|
||||
return fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0");
|
||||
}
|
||||
|
||||
static bool mount_is_loop(const MountParameters *p) {
|
||||
assert(p);
|
||||
|
||||
@ -400,42 +417,72 @@ static bool mount_is_extrinsic(Mount *m) {
|
||||
MountParameters *p;
|
||||
assert(m);
|
||||
|
||||
/* Returns true for all units that are "magic" and should be excluded from the usual start-up and shutdown
|
||||
* dependencies. We call them "extrinsic" here, as they are generally mounted outside of the systemd dependency
|
||||
* logic. We shouldn't attempt to manage them ourselves but it's fine if the user operates on them with us. */
|
||||
/* Returns true for all units that are "magic" and should be excluded from the usual
|
||||
* start-up and shutdown dependencies. We call them "extrinsic" here, as they are generally
|
||||
* mounted outside of the systemd dependency logic. We shouldn't attempt to manage them
|
||||
* ourselves but it's fine if the user operates on them with us. */
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(UNIT(m)->manager)) /* We only automatically manage mounts if we are in system mode */
|
||||
/* We only automatically manage mounts if we are in system mode */
|
||||
if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
|
||||
return true;
|
||||
|
||||
if (UNIT(m)->perpetual) /* All perpetual units never change state */
|
||||
return true;
|
||||
|
||||
if (PATH_IN_SET(m->where, /* Don't bother with the OS data itself */
|
||||
"/", /* (strictly speaking redundant: should already be covered by the perpetual flag check above) */
|
||||
"/usr",
|
||||
"/etc"))
|
||||
return true;
|
||||
|
||||
if (PATH_STARTSWITH_SET(m->where,
|
||||
"/run/initramfs", /* This should stay around from before we boot until after we shutdown */
|
||||
"/proc", /* All of this is API VFS */
|
||||
"/sys", /* … dito … */
|
||||
"/dev")) /* … dito … */
|
||||
return true;
|
||||
|
||||
/* If this is an initrd mount, and we are not in the initrd, then leave this around forever, too. */
|
||||
p = get_mount_parameters(m);
|
||||
if (p && fstab_test_option(p->options, "x-initrd.mount\0") && !in_initrd())
|
||||
if (p && fstab_is_extrinsic(m->where, p->options))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int mount_add_default_ordering_dependencies(
|
||||
Mount *m,
|
||||
MountParameters *p,
|
||||
UnitDependencyMask mask) {
|
||||
|
||||
const char *after, *before, *e;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
e = path_startswith(m->where, "/sysroot");
|
||||
if (e && in_initrd()) {
|
||||
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW,
|
||||
* it's not technically part of the basic initrd filesystem itself, and so
|
||||
* shouldn't inherit the default Before=local-fs.target dependency. */
|
||||
|
||||
after = NULL;
|
||||
before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
|
||||
|
||||
} else if (mount_is_network(p)) {
|
||||
after = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
before = SPECIAL_REMOTE_FS_TARGET;
|
||||
|
||||
} else {
|
||||
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
before = SPECIAL_LOCAL_FS_TARGET;
|
||||
}
|
||||
|
||||
if (!mount_is_nofail(m) && !mount_is_automount(p)) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (after) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_UMOUNT_TARGET, true, mask);
|
||||
}
|
||||
|
||||
static int mount_add_default_dependencies(Mount *m) {
|
||||
const char *after, *before;
|
||||
UnitDependencyMask mask;
|
||||
MountParameters *p;
|
||||
bool nofail;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -443,9 +490,10 @@ static int mount_add_default_dependencies(Mount *m) {
|
||||
if (!UNIT(m)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are guaranteed to stay
|
||||
* mounted the whole time, since our system is on it. Also, don't bother with anything mounted below virtual
|
||||
* file systems, it's also going to be virtual, and hence not worth the effort. */
|
||||
/* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are
|
||||
* guaranteed to stay mounted the whole time, since our system is on it. Also, don't
|
||||
* bother with anything mounted below virtual file systems, it's also going to be virtual,
|
||||
* and hence not worth the effort. */
|
||||
if (mount_is_extrinsic(m))
|
||||
return 0;
|
||||
|
||||
@ -454,51 +502,31 @@ static int mount_add_default_dependencies(Mount *m) {
|
||||
return 0;
|
||||
|
||||
mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT;
|
||||
nofail = m->from_fragment ? fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0") : false;
|
||||
|
||||
r = mount_add_default_ordering_dependencies(m, p, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (mount_is_network(p)) {
|
||||
/* We order ourselves after network.target. This is
|
||||
* primarily useful at shutdown: services that take
|
||||
* down the network should order themselves before
|
||||
* network.target, so that they are shut down only
|
||||
* after this mount unit is stopped. */
|
||||
/* We order ourselves after network.target. This is primarily useful at shutdown:
|
||||
* services that take down the network should order themselves before
|
||||
* network.target, so that they are shut down only after this mount unit is
|
||||
* stopped. */
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* We pull in network-online.target, and order
|
||||
* ourselves after it. This is useful at start-up to
|
||||
* actively pull in tools that want to be started
|
||||
* before we start mounting network file systems, and
|
||||
* whose purpose it is to delay this until the network
|
||||
* is "up". */
|
||||
/* We pull in network-online.target, and order ourselves after it. This is useful
|
||||
* at start-up to actively pull in tools that want to be started before we start
|
||||
* mounting network file systems, and whose purpose it is to delay this until the
|
||||
* network is "up". */
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
after = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
before = SPECIAL_REMOTE_FS_TARGET;
|
||||
} else {
|
||||
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
before = SPECIAL_LOCAL_FS_TARGET;
|
||||
}
|
||||
|
||||
if (!nofail) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */
|
||||
if (streq_ptr(p->fstype, "tmpfs")) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, mask);
|
||||
|
@ -3028,13 +3028,10 @@ int unit_add_dependency(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (d == UNIT_AFTER && UNIT_VTABLE(u)->refuse_after) {
|
||||
log_unit_warning(u, "Requested dependency After=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(u->type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (d == UNIT_BEFORE && UNIT_VTABLE(other)->refuse_after) {
|
||||
log_unit_warning(u, "Requested dependency Before=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(other->type));
|
||||
/* Note that ordering a device unit after a unit is permitted since it
|
||||
* allows to start its job running timeout at a specific time. */
|
||||
if (d == UNIT_BEFORE && other->type == UNIT_DEVICE) {
|
||||
log_unit_warning(u, "Dependency Before=%s ignored (.device units cannot be delayed)", other->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -615,9 +615,6 @@ typedef struct UnitVTable {
|
||||
/* True if the unit type knows a failure state, and thus can be source of an OnFailure= dependency */
|
||||
bool can_fail:1;
|
||||
|
||||
/* True if After= dependencies should be refused */
|
||||
bool refuse_after:1;
|
||||
|
||||
/* True if units of this type shall be startable only once and then never again */
|
||||
bool once_only:1;
|
||||
|
||||
|
@ -391,12 +391,6 @@ static int add_mount(
|
||||
"SourcePath=%s\n",
|
||||
source);
|
||||
|
||||
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not
|
||||
* technically part of the basic initrd filesystem itself, and so shouldn't inherit the default
|
||||
* Before=local-fs.target dependency. */
|
||||
if (in_initrd() && path_startswith(where, "/sysroot"))
|
||||
fprintf(f, "DefaultDependencies=no\n");
|
||||
|
||||
if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
|
||||
fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
|
||||
/* The default retry timeout that mount.nfs uses for 'bg' mounts
|
||||
@ -411,9 +405,6 @@ static int add_mount(
|
||||
SET_FLAG(flags, NOFAIL, true);
|
||||
}
|
||||
|
||||
if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
|
||||
fprintf(f, "Before=%s\n", post);
|
||||
|
||||
if (!(flags & AUTOMOUNT) && opts) {
|
||||
r = write_after(f, opts);
|
||||
if (r < 0)
|
||||
@ -535,8 +526,6 @@ static int add_mount(
|
||||
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
|
||||
source);
|
||||
|
||||
fprintf(f, "Before=%s\n", post);
|
||||
|
||||
if (opts) {
|
||||
r = write_after(f, opts);
|
||||
if (r < 0)
|
||||
|
@ -35,6 +35,30 @@ int fstab_has_fstype(const char *fstype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fstab_is_extrinsic(const char *mount, const char *opts) {
|
||||
|
||||
/* Don't bother with the OS data itself */
|
||||
if (PATH_IN_SET(mount,
|
||||
"/",
|
||||
"/usr",
|
||||
"/etc"))
|
||||
return true;
|
||||
|
||||
if (PATH_STARTSWITH_SET(mount,
|
||||
"/run/initramfs", /* This should stay around from before we boot until after we shutdown */
|
||||
"/proc", /* All of this is API VFS */
|
||||
"/sys", /* … dito … */
|
||||
"/dev")) /* … dito … */
|
||||
return true;
|
||||
|
||||
/* If this is an initrd mount, and we are not in the initrd, then leave
|
||||
* this around forever, too. */
|
||||
if (opts && fstab_test_option(opts, "x-initrd.mount\0") && !in_initrd())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int fstab_is_mount_point(const char *mount) {
|
||||
_cleanup_endmntent_ FILE *f = NULL;
|
||||
struct mntent *m;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
bool fstab_is_extrinsic(const char *mount, const char *opts);
|
||||
int fstab_is_mount_point(const char *mount);
|
||||
int fstab_has_fstype(const char *fstype);
|
||||
|
||||
|
@ -260,6 +260,9 @@ int generator_write_device_deps(
|
||||
_cleanup_free_ char *node = NULL, *unit = NULL;
|
||||
int r;
|
||||
|
||||
if (fstab_is_extrinsic(where, opts))
|
||||
return 0;
|
||||
|
||||
if (!fstab_test_option(opts, "_netdev\0"))
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user