<para>The following dependencies are added unless <varname>DefaultDependencies=no</varname> is set:</para>
<itemizedlist>
- <listitem><para>Swap units automatically acquire a <varname>Conflicts=</varname> and a
+ <listitem><para>Local swap units automatically acquire a <varname>Conflicts=</varname> and a
<varname>Before=</varname> dependency on <filename>umount.target</filename> so that they are deactivated at
shutdown as well as a <varname>Before=swap.target</varname> dependency.</para></listitem>
+
+ <listitem><para>Network swap units (those with <option>_netdev</option> in their options) automatically acquire
+ <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename> and
+ <filename>network.target</filename>, plus <varname>After=</varname> and <varname>Wants=</varname> dependencies
+ on <filename>network-online.target</filename>, and a <varname>Before=</varname> dependency on
+ <filename>remote-fs.target</filename> instead of <filename>swap.target</filename>.</para></listitem>
</itemizedlist>
</refsect2>
</refsect1>
<listitem><para>With <option>noauto</option>, the swap unit
will not be added as a dependency for
- <filename>swap.target</filename>. This means that it will not
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap devices,
+ see <option>_netdev</option> below). This means that it will not
be activated automatically during boot, unless it is pulled in
by some other unit. The <option>auto</option> option has the
opposite meaning and is the default.</para>
<listitem><para>With <option>nofail</option>, the swap unit
will be only wanted, not required by
- <filename>swap.target</filename>. This means that the boot
- will continue even if this swap device is not activated
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap
+ devices). This means that the boot will continue even if this swap device is not activated
successfully.</para>
<xi:include href="version-info.xml" xpointer="v218"/>
<xi:include href="version-info.xml" xpointer="v240"/></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>_netdev</option></term>
+
+ <listitem><para>Marks this swap device as requiring network access. This is useful for swap on
+ network block devices (e.g. iSCSI).</para>
+
+ <para>Network swap units are ordered between <filename>remote-fs-pre.target</filename> and
+ <filename>remote-fs.target</filename>, instead of being ordered before
+ <filename>swap.target</filename>. They also pull in <filename>network-online.target</filename> and
+ are ordered after it and <filename>network.target</filename>.</para>
+
+ <xi:include href="version-info.xml" xpointer="v261"/>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
}
static int swap_add_default_dependencies(Swap *s) {
+ SwapParameters *p;
int r;
assert(s);
if (detect_container() > 0)
return 0;
- /* swap units generated for the swap dev links are missing the
- * ordering dep against the swap target. */
- r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
- if (r < 0)
- return r;
+ p = swap_get_parameters(s);
+
+ if (p && fstab_test_option(p->options, "_netdev\0")) {
+ /* Network swap devices (those with _netdev in options) are routed through
+ * remote-fs.target instead of swap.target, mirroring how network mounts use
+ * remote-fs.target instead of local-fs.target. This avoids an ordering cycle:
+ * swap.target is pulled in at sysinit.target time, but network-online.target
+ * only comes after basic.target which is after sysinit.target. */
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOTE_FS_PRE_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
+ if (r < 0)
+ return r;
+
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
+ if (r < 0)
+ return r;
+
+ /* Pull in and order after network-online.target, analogous to
+ * mount_add_default_network_dependencies() for network mounts. */
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_NETWORK_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
+ if (r < 0)
+ return r;
+
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
+ if (r < 0)
+ return r;
+ } else {
+ /* swap units generated for the swap dev links are missing the
+ * ordering dep against the swap target. */
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
+ if (r < 0)
+ return r;
+ }
- return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
+ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
}
static int swap_verify(Swap *s) {
_cleanup_free_ char *name = NULL;
_cleanup_fclose_ FILE *f = NULL;
+ bool is_network;
int r;
assert(what);
return true;
}
- log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s validatefs=%s noauto=%s nofail=%s",
+ is_network = fstab_test_option(options, "_netdev\0");
+
+ log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s validatefs=%s noauto=%s nofail=%s netdev=%s",
what,
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
yes_no(flags & MOUNT_PCRFS), yes_no(flags & MOUNT_VALIDATEFS),
- yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
+ yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL),
+ yes_no(is_network));
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
if (r < 0)
return r;
+ if (is_network) {
+ r = generator_write_network_device_deps(arg_dest, what, /* where= */ NULL, options);
+ if (r < 0)
+ return r;
+ }
+
if (flags & MOUNT_MAKEFS) {
r = generator_hook_up_mkswap(arg_dest, what);
if (r < 0)
log_warning("%s: validating swap devices is currently unsupported.", what);
if (!(flags & MOUNT_NOAUTO)) {
- r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
+ const char *target = is_network ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_SWAP_TARGET;
+ r = generator_add_symlink(arg_dest, target,
(flags & MOUNT_NOFAIL) ? "wants" : "requires", name);
if (r < 0)
return r;
assert(dir);
assert(what);
- assert(where);
- if (fstab_is_extrinsic(where, opts))
+ if (where && fstab_is_extrinsic(where, opts))
return 0;
if (!fstab_test_option(opts, "_netdev\0"))
--- /dev/null
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+After=network-online.target network.target
+Wants=network-online.target
--- /dev/null
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx1.target
+
+[Swap]
+What=/dev/sdx1
+Options=_netdev
--- /dev/null
+../dev-sdx1.swap
\ No newline at end of file
--- /dev/null
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+After=network-online.target network.target
+Wants=network-online.target
--- /dev/null
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx1.target
+
+[Swap]
+What=/dev/sdx1
+Options=_netdev
--- /dev/null
+../dev-sdx1.swap
\ No newline at end of file
--- /dev/null
+/dev/sdx1 none swap _netdev 0 0