units: introduce remote-fs-setup.target to pull in dependencies from remote mounts

This introduces remote-fs-setup.target independently of
remote-fs-pre.target. The former is only for pulling things in, the
latter only for ordering.

The new semantics:

remote-fs-setup.target: is pulled in automatically by all remote mounts.
Shall be used to pull in other units that want to run when at least one
remote mount is set up. Is not ordered against the actual mount units,
in order to allow activation of its dependencies even 'a posteriori',
i.e. when a mount is established outside of systemd and is only picked
up by it.

remote-fs-pre.target: needs to be pulled in automatically by the
implementing service, is otherwise not part of the initial transaction.
This is ordered before all remote mount units.

A service that wants to be pulled in and run before all remote mounts
should hence have:

a) WantedBy=remote-fs-setup.target -- so that it is pulled in

b) Wants=remote-fs-pre.target + Before=remote-fs-pre.target -- so that
   it is ordered before the mount point, normally.
This commit is contained in:
Lennart Poettering 2013-03-25 22:04:40 +01:00
parent a69fe051b8
commit e8d2f6cde0
7 changed files with 102 additions and 18 deletions

View File

@ -79,6 +79,7 @@
<filename>reboot.target</filename>,
<filename>remote-fs.target</filename>,
<filename>remote-fs-pre.target</filename>,
<filename>remote-fs-setup.target</filename>,
<filename>rescue.target</filename>,
<filename>initrd-root-fs.target</filename>,
<filename>rpcbind.target</filename>,
@ -565,11 +566,52 @@
<listitem>
<para>This target unit is
automatically ordered before
all remote mount points marked
with <option>auto</option>
all remote mount point units
(see above). It can be used to
execute certain units before
all remote mounts.</para>
run certain units before the
remote mounts are
established. Note that this
unit is generally not part of
the initial transaction,
unless the unit that wants to
be ordered before all remote
mounts pulls it in via a
<varname>Wants=</varname> type
dependency. If the unit wants
to be pulled in by the first
remote mount showing up it
should use
<filename>remote-fs-setup.target</filename>
(see below).</para>
<para>Again, this target unit
is <emphasis>not</emphasis>
suitable for pulling in other
units, it is only useful for
ordering.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>remote-fs-setup.target</filename></term>
<listitem>
<para>This target unit is
automatically pulled in (by a
<varname>Wants=</varname> type
dependency) by all remote
mount points. It can be used
to run certain units when at
least one remote file system
is to be mounted. Note that
this target is not ordered
against the remote mounts, use
<filename>remote-fs-pre.target</filename>
for that.</para>
<para>Again, this target unit
is <emphasis>not</emphasis>
suitable for ordering, it is
only useful for pulling in
other units.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -441,7 +441,7 @@ static int mount_add_quota_links(Mount *m) {
static int mount_add_default_dependencies(Mount *m) {
int r;
MountParameters *p;
const char *after;
const char *after, *setup;
assert(m);
@ -456,15 +456,24 @@ static int mount_add_default_dependencies(Mount *m) {
if (path_equal(m->where, "/"))
return 0;
if (mount_is_network(p))
if (mount_is_network(p)) {
after = SPECIAL_REMOTE_FS_PRE_TARGET;
else
setup = SPECIAL_REMOTE_FS_SETUP_TARGET;
} else {
after = SPECIAL_LOCAL_FS_PRE_TARGET;
setup = NULL;
}
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true);
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
if (r < 0)
return r;
if (setup) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_WANTS, setup, NULL, true);
if (r < 0)
return r;
}
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
if (r < 0)
return r;

View File

@ -54,6 +54,7 @@
#define SPECIAL_INITRD_ROOT_FS_TARGET "initrd-root-fs.target"
#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */
#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"
#define SPECIAL_REMOTE_FS_SETUP_TARGET "remote-fs-setup.target"
#define SPECIAL_SWAP_TARGET "swap.target"
#define SPECIAL_BASIC_TARGET "basic.target"

View File

@ -205,9 +205,20 @@ static bool mount_is_rootfs(struct mntent *me) {
return hasmntopt(me, "x-initrd.rootfs");
}
static int add_mount(const char *what, const char *where, const char *type, const char *opts,
int passno, bool noauto, bool nofail, bool automount, bool isbind,
const char *pre, const char *post, const char *source) {
static int add_mount(
const char *what,
const char *where,
const char *type,
const char *opts,
int passno,
bool noauto,
bool nofail,
bool automount,
bool isbind,
const char *pre,
const char *post,
const char *setup,
const char *source) {
char _cleanup_free_
*name = NULL, *unit = NULL, *lnk = NULL, *device = NULL,
*automount_name = NULL, *automount_unit = NULL;
@ -259,10 +270,14 @@ static int add_mount(const char *what, const char *where, const char *type, cons
if (!path_equal(where, "/")) {
if (pre)
fprintf(f,
"After=%s\n"
"Wants=%s\n",
pre,
"After=%s\n",
pre);
if (setup)
fprintf(f,
"Wants=%s\n",
setup);
fprintf(f,
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
"Before=" SPECIAL_UMOUNT_TARGET "\n");
@ -430,7 +445,7 @@ static int parse_fstab(const char *prefix, bool initrd) {
k = add_swap(what, me);
else {
bool noauto, nofail, automount, isbind;
const char *pre, *post;
const char *pre, *post, *setup;
noauto = !!hasmntopt(me, "noauto");
nofail = !!hasmntopt(me, "nofail");
@ -442,20 +457,24 @@ static int parse_fstab(const char *prefix, bool initrd) {
if (initrd) {
post = SPECIAL_INITRD_FS_TARGET;
pre = NULL;
setup = NULL;
} else if (mount_is_rootfs(me)) {
post = SPECIAL_INITRD_ROOT_FS_TARGET;
pre = NULL;
setup = NULL;
} else if (mount_is_network(me)) {
post = SPECIAL_REMOTE_FS_TARGET;
pre = SPECIAL_REMOTE_FS_PRE_TARGET;
setup = SPECIAL_REMOTE_FS_SETUP_TARGET;
} else {
post = SPECIAL_LOCAL_FS_TARGET;
pre = SPECIAL_LOCAL_FS_PRE_TARGET;
setup = NULL;
}
k = add_mount(what, where, me->mnt_type, me->mnt_opts,
me->mnt_passno, noauto, nofail, automount,
isbind, pre, post, fstab_path);
me->mnt_passno, noauto, nofail, automount,
isbind, pre, post, setup, fstab_path);
}
if (k < 0)
@ -539,7 +558,7 @@ static int parse_new_root_from_proc_cmdline(void) {
log_debug("Found entry what=%s where=/sysroot type=%s", what, type);
r = add_mount(what, "/sysroot", type, opts, 0, false, false, false,
false, NULL, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline");
false, NULL, SPECIAL_INITRD_ROOT_FS_TARGET, NULL, "/proc/cmdline");
return (r < 0) ? r : 0;
}

View File

@ -8,5 +8,6 @@
[Unit]
Description=Local File Systems
Documentation=man:systemd.special(7)
After=local-fs-pre.target
OnFailure=emergency.target
OnFailureIsolate=yes

View File

@ -0,0 +1,11 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Remote File System Setup
Documentation=man:systemd.special(7)
DefaultDependencies=no

View File

@ -8,6 +8,7 @@
[Unit]
Description=Remote File Systems
Documentation=man:systemd.special(7)
After=remote-fs-pre.target remote-fs-setup.target
[Install]
WantedBy=multi-user.target