From d09c35c48005669c4c4663e3ba8a6f979432cead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Sep 2017 11:30:33 +0200 Subject: [PATCH] cryptsetup-generator: use remote-cryptsetup.target when _netdev is present This allows such devices to depend on the network. Their startup will be delayed similarly to network mount units. Fixes #4642. Cherry-picked from: b001ad61e91b6499897f0c977045c7608c233bfa Resolves: #1384014 --- man/crypttab.xml | 13 ++++++++++ src/cryptsetup/cryptsetup-generator.c | 36 ++++++++++++++++++--------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index 3e249ad23..7085a1623 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -189,6 +189,19 @@ . + + + + Marks this cryptsetup device as requiring network. It will be + started after the network is available, similarly to + systemd.mount5 + units marked with . The service unit to set up this device + will be ordered between remote-cryptsetup-pre.target and + remote-cryptsetup.target, instead of + cryptsetup-pre.target and + cryptsetup.target. + + diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index d191def5f..49dc8f14b 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -60,7 +60,7 @@ static int create_disk( _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *to = NULL, *e = NULL, *filtered = NULL; _cleanup_fclose_ FILE *f = NULL; - bool noauto, nofail, tmp, swap; + bool noauto, nofail, tmp, swap, netdev; char *from; int r; @@ -71,6 +71,7 @@ static int create_disk( nofail = fstab_test_yes_no_option(options, "nofail\0" "fail\0"); tmp = fstab_test_option(options, "tmp\0"); swap = fstab_test_option(options, "swap\0"); + netdev = fstab_test_option(options, "_netdev\0"); if (tmp && swap) { log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); @@ -101,22 +102,24 @@ static int create_disk( if (!f) return log_error_errno(errno, "Failed to create unit file %s: %m", p); - fputs( + fprintf(f, "# Automatically generated by systemd-cryptsetup-generator\n\n" "[Unit]\n" - "Description=Cryptography Setup for %I\n" + "Description=Cryptography Setup for %%I\n" "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n" "SourcePath=/etc/crypttab\n" "DefaultDependencies=no\n" "Conflicts=umount.target\n" - "BindsTo=dev-mapper-%i.device\n" + "BindsTo=dev-mapper-%%i.device\n" "IgnoreOnIsolate=true\n" - "After=systemd-readahead-collect.service systemd-readahead-replay.service cryptsetup-pre.target\n", - f); + "After=systemd-readahead-collect.service systemd-readahead-replay.service\n" + "After=%s\n", + netdev ? "remote-cryptsetup-pre.target" : "cryptsetup-pre.target"); if (!nofail) fprintf(f, - "Before=cryptsetup.target\n"); + "Before=%s\n", + netdev ? "remote-cryptsetup.target" : "cryptsetup.target"); if (password) { if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random")) @@ -196,16 +199,25 @@ static int create_disk( return log_error_errno(errno, "Failed to create symlink %s: %m", to); free(to); - if (!nofail) - to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); - else - to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL); + if (!netdev) { + if (!nofail) + to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); + else + to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL); + } else { + if (!nofail) + to = strjoin(arg_dest, "/remote-cryptsetup.target.requires/", n, NULL); + else + to = strjoin(arg_dest, "/remote-cryptsetup.target.wants/", n, NULL); + } if (!to) return log_oom(); mkdir_parents_label(to, 0755); - if (symlink(from, to) < 0) + if (symlink(from, to) < 0) { + free(to); return log_error_errno(errno, "Failed to create symlink %s: %m", to); + } } free(to);