mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #14398 from poettering/mount-prep
This commit is contained in:
commit
dc9fd22d3d
3
TODO
3
TODO
@ -44,6 +44,9 @@ Features:
|
||||
* cryptsetup: allow encoding key directly in /etc/crypttab, maybe with a
|
||||
"base64:" prefix. Useful in particular for pkcs11 mode.
|
||||
|
||||
* cryptsetup: reimplement the mkswap/mke2fs in cryptsetup-generator to use
|
||||
systemd-makefs.service instead.
|
||||
|
||||
* socket units: allow creating a udev monitor socket with ListenDevices= or so,
|
||||
with matches, then actviate app thorugh that passing socket oveer
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
<filename>cryptsetup-pre.target</filename>,
|
||||
<filename>cryptsetup.target</filename>,
|
||||
<filename>ctrl-alt-del.target</filename>,
|
||||
<filename>blockdev@.target</filename>,
|
||||
<filename>boot-complete.target</filename>,
|
||||
<filename>default.target</filename>,
|
||||
<filename>emergency.target</filename>,
|
||||
@ -845,6 +846,23 @@
|
||||
not useful as only unit within a transaction.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>blockdev@.target</filename></term>
|
||||
<listitem><para>This template unit may be used to order mount units and other consumers of block
|
||||
devices against services that synthesize these block devices. This is intended to be used to order
|
||||
storage services (such as
|
||||
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
|
||||
that allocate and manage a virtual block device against mount units and other consumers of
|
||||
it. Specifically, the storage services are supposed to be orderd before an instance of
|
||||
<filename>blockdev@.target</filename>, and the mount unit (or other consuming unit, such as a swap
|
||||
unit) after it. The ordering is particular relevant during shutdown, as it ensures that the mount
|
||||
is deactivated first and the service backing the mount only deactivated after that completed. The
|
||||
<filename>blockdev@.target</filename> instance should be pulled in via a <option>Wants=</option>
|
||||
dependency of the storage daemon and thus generally not be part of any transaction unless a storage
|
||||
daemon is used. The instance name for instances of this template unit is supposed to be the
|
||||
properly escaped bock device node path, e.g. <filename>blockdev@dev-mapper-foobar.target</filename>
|
||||
for a storage device <filename>/dev/mapper/foobar</filename>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>cryptsetup-pre.target</filename></term>
|
||||
<listitem>
|
||||
|
@ -217,7 +217,7 @@ static void mount_done(Unit *u) {
|
||||
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
|
||||
}
|
||||
|
||||
_pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
|
||||
static MountParameters* get_mount_parameters_fragment(Mount *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->from_fragment)
|
||||
@ -226,7 +226,7 @@ _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_pure_ static MountParameters* get_mount_parameters(Mount *m) {
|
||||
static MountParameters* get_mount_parameters(Mount *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->from_proc_self_mountinfo)
|
||||
@ -342,20 +342,18 @@ static int mount_add_device_dependencies(Mount *m) {
|
||||
if (!is_device_path(p->what))
|
||||
return 0;
|
||||
|
||||
/* /dev/root is a really weird thing, it's not a real device,
|
||||
* but just a path the kernel exports for the root file system
|
||||
* specified on the kernel command line. Ignore it here. */
|
||||
if (path_equal(p->what, "/dev/root"))
|
||||
/* /dev/root is a really weird thing, it's not a real device, but just a path the kernel exports for
|
||||
* the root file system specified on the kernel command line. Ignore it here. */
|
||||
if (PATH_IN_SET(p->what, "/dev/root", "/dev/nfs"))
|
||||
return 0;
|
||||
|
||||
if (path_equal(m->where, "/"))
|
||||
return 0;
|
||||
|
||||
/* Mount units from /proc/self/mountinfo are not bound to devices
|
||||
* by default since they're subject to races when devices are
|
||||
* unplugged. But the user can still force this dep with an
|
||||
* appropriate option (or udev property) so the mount units are
|
||||
* automatically stopped when the device disappears suddenly. */
|
||||
/* Mount units from /proc/self/mountinfo are not bound to devices by default since they're subject to
|
||||
* races when devices are unplugged. But the user can still force this dep with an appropriate option
|
||||
* (or udev property) so the mount units are automatically stopped when the device disappears
|
||||
* suddenly. */
|
||||
dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
|
||||
|
||||
/* We always use 'what' from /proc/self/mountinfo if mounted */
|
||||
@ -365,7 +363,7 @@ static int mount_add_device_dependencies(Mount *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return unit_add_blockdev_dependency(UNIT(m), p->what, mask);
|
||||
}
|
||||
|
||||
static int mount_add_quota_dependencies(Mount *m) {
|
||||
|
@ -184,21 +184,45 @@ static int swap_arm_timer(Swap *s, usec_t usec) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SwapParameters* swap_get_parameters(Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (s->from_proc_swaps)
|
||||
return &s->parameters_proc_swaps;
|
||||
|
||||
if (s->from_fragment)
|
||||
return &s->parameters_fragment;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int swap_add_device_dependencies(Swap *s) {
|
||||
UnitDependencyMask mask;
|
||||
SwapParameters *p;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!s->what)
|
||||
return 0;
|
||||
|
||||
if (!s->from_fragment)
|
||||
p = swap_get_parameters(s);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (is_device_path(s->what))
|
||||
return unit_add_node_dependency(UNIT(s), s->what, UNIT_BINDS_TO, UNIT_DEPENDENCY_FILE);
|
||||
mask = s->from_proc_swaps ? UNIT_DEPENDENCY_PROC_SWAP : UNIT_DEPENDENCY_FILE;
|
||||
|
||||
/* File based swap devices need to be ordered after systemd-remount-fs.service,
|
||||
* since they might need a writable file system. */
|
||||
return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, true, UNIT_DEPENDENCY_FILE);
|
||||
if (is_device_path(p->what)) {
|
||||
r = unit_add_node_dependency(UNIT(s), p->what, UNIT_REQUIRES, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return unit_add_blockdev_dependency(UNIT(s), p->what, mask);
|
||||
}
|
||||
|
||||
/* File based swap devices need to be ordered after systemd-remount-fs.service, since they might need
|
||||
* a writable file system. */
|
||||
return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, true, mask);
|
||||
}
|
||||
|
||||
static int swap_add_default_dependencies(Swap *s) {
|
||||
|
@ -3866,8 +3866,8 @@ int unit_deserialize_skip(FILE *f) {
|
||||
}
|
||||
|
||||
int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, UnitDependencyMask mask) {
|
||||
Unit *device;
|
||||
_cleanup_free_ char *e = NULL;
|
||||
Unit *device;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
@ -3879,8 +3879,7 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit
|
||||
if (!is_device_path(what))
|
||||
return 0;
|
||||
|
||||
/* When device units aren't supported (such as in a
|
||||
* container), don't create dependencies on them. */
|
||||
/* When device units aren't supported (such as in a container), don't create dependencies on them. */
|
||||
if (!unit_type_supported(UNIT_DEVICE))
|
||||
return 0;
|
||||
|
||||
@ -3900,6 +3899,33 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit
|
||||
device, true, mask);
|
||||
}
|
||||
|
||||
int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask mask) {
|
||||
_cleanup_free_ char *escaped = NULL, *target = NULL;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
if (isempty(what))
|
||||
return 0;
|
||||
|
||||
if (!path_startswith(what, "/dev/"))
|
||||
return 0;
|
||||
|
||||
/* If we don't support devices, then also don't bother with blockdev@.target */
|
||||
if (!unit_type_supported(UNIT_DEVICE))
|
||||
return 0;
|
||||
|
||||
r = unit_name_path_escape(what, &escaped);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_name_build("blockdev", escaped, ".target", &target);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return unit_add_dependency_by_name(u, UNIT_AFTER, target, true, mask);
|
||||
}
|
||||
|
||||
int unit_coldplug(Unit *u) {
|
||||
int r = 0, q;
|
||||
char **i;
|
||||
|
@ -743,6 +743,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
|
||||
int unit_deserialize_skip(FILE *f);
|
||||
|
||||
int unit_add_node_dependency(Unit *u, const char *what, UnitDependency d, UnitDependencyMask mask);
|
||||
int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask mask);
|
||||
|
||||
int unit_coldplug(Unit *u);
|
||||
void unit_catchup(Unit *u);
|
||||
|
@ -99,7 +99,14 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) {
|
||||
static int generate_keydev_mount(
|
||||
const char *name,
|
||||
const char *keydev,
|
||||
const char *keydev_timeout,
|
||||
bool canfail,
|
||||
char **unit,
|
||||
char **mount) {
|
||||
|
||||
_cleanup_free_ char *u = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
@ -223,8 +230,8 @@ static int create_disk(
|
||||
const char *options) {
|
||||
|
||||
_cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
|
||||
*keydev_mount = NULL, *keyfile_timeout_value = NULL, *password_escaped = NULL,
|
||||
*filtered = NULL, *u_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *header_path = NULL;
|
||||
*keydev_mount = NULL, *keyfile_timeout_value = NULL,
|
||||
*filtered = NULL, *u_escaped = NULL, *name_escaped = NULL, *header_path = NULL, *password_buffer = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *dmname;
|
||||
bool noauto, nofail, tmp, swap, netdev, attach_in_initrd;
|
||||
@ -285,39 +292,29 @@ static int create_disk(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"[Unit]\n"
|
||||
"Description=Cryptography Setup for %%I\n"
|
||||
"Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
|
||||
"SourcePath=%s\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"IgnoreOnIsolate=true\n"
|
||||
"After=%s\n",
|
||||
arg_crypttab,
|
||||
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
|
||||
r = generator_write_cryptsetup_unit_section(f, arg_crypttab);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (netdev)
|
||||
fprintf(f, "After=remote-fs-pre.target\n");
|
||||
|
||||
/* If initrd takes care of attaching the disk then it should also detach it during shutdown. */
|
||||
if (!attach_in_initrd)
|
||||
fprintf(f, "Conflicts=umount.target\n");
|
||||
|
||||
if (password) {
|
||||
password_escaped = specifier_escape(password);
|
||||
if (!password_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (keydev) {
|
||||
_cleanup_free_ char *unit = NULL, *p = NULL;
|
||||
_cleanup_free_ char *unit = NULL;
|
||||
|
||||
r = generate_keydev_mount(name, keydev, keyfile_timeout_value, keyfile_can_timeout > 0, &unit, &keydev_mount);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate keydev mount unit: %m");
|
||||
|
||||
p = path_join(keydev_mount, password_escaped);
|
||||
if (!p)
|
||||
password_buffer = path_join(keydev_mount, password);
|
||||
if (!password_buffer)
|
||||
return log_oom();
|
||||
|
||||
free_and_replace(password_escaped, p);
|
||||
password = password_buffer;
|
||||
|
||||
fprintf(f, "After=%s\n", unit);
|
||||
if (keyfile_can_timeout > 0)
|
||||
@ -344,17 +341,13 @@ static int create_disk(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (path_startswith(u, "/dev/")) {
|
||||
if (path_startswith(u, "/dev/"))
|
||||
fprintf(f,
|
||||
"BindsTo=%s\n"
|
||||
"After=%s\n"
|
||||
"Before=umount.target\n",
|
||||
d, d);
|
||||
|
||||
if (swap)
|
||||
fputs("Before=dev-mapper-%i.swap\n",
|
||||
f);
|
||||
} else
|
||||
else
|
||||
/* For loopback devices, add systemd-tmpfiles-setup-dev.service
|
||||
dependency to ensure that loopback support is available in
|
||||
the kernel (/dev/loop-control needs to exist) */
|
||||
@ -368,23 +361,9 @@ static int create_disk(
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to write device timeout drop-in: %m");
|
||||
|
||||
if (filtered) {
|
||||
filtered_escaped = specifier_escape(filtered);
|
||||
if (!filtered_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"\n[Service]\n"
|
||||
"Type=oneshot\n"
|
||||
"RemainAfterExit=yes\n"
|
||||
"TimeoutSec=0\n" /* the binary handles timeouts anyway */
|
||||
"KeyringMode=shared\n" /* make sure we can share cached keys among instances */
|
||||
"OOMScoreAdjust=500\n" /* unlocking can allocate a lot of memory if Argon2 is used */
|
||||
"ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
|
||||
"ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
|
||||
name_escaped, u_escaped, strempty(password_escaped), strempty(filtered_escaped),
|
||||
name_escaped);
|
||||
r = generator_write_cryptsetup_service_section(f, name, u, password, filtered);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (tmp)
|
||||
fprintf(f,
|
||||
|
@ -118,11 +118,18 @@ static int add_swap(
|
||||
|
||||
fprintf(f,
|
||||
"[Unit]\n"
|
||||
"SourcePath=%s\n"
|
||||
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
|
||||
"[Swap]\n",
|
||||
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n"
|
||||
"SourcePath=%s\n",
|
||||
fstab_path());
|
||||
|
||||
r = generator_write_blockdev_dependency(f, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Swap]\n");
|
||||
|
||||
r = write_what(f, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -174,8 +181,13 @@ static bool mount_in_initrd(struct mntent *me) {
|
||||
streq(me->mnt_dir, "/usr");
|
||||
}
|
||||
|
||||
static int write_timeout(FILE *f, const char *where, const char *opts,
|
||||
const char *filter, const char *variable) {
|
||||
static int write_timeout(
|
||||
FILE *f,
|
||||
const char *where,
|
||||
const char *opts,
|
||||
const char *filter,
|
||||
const char *variable) {
|
||||
|
||||
_cleanup_free_ char *timeout = NULL;
|
||||
char timespan[FORMAT_TIMESPAN_MAX];
|
||||
usec_t u;
|
||||
@ -208,8 +220,12 @@ static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
|
||||
"x-systemd.mount-timeout\0", "TimeoutSec");
|
||||
}
|
||||
|
||||
static int write_dependency(FILE *f, const char *opts,
|
||||
const char *filter, const char *format) {
|
||||
static int write_dependency(
|
||||
FILE *f,
|
||||
const char *opts,
|
||||
const char *filter,
|
||||
const char *format) {
|
||||
|
||||
_cleanup_strv_free_ char **names = NULL, **units = NULL;
|
||||
_cleanup_free_ char *res = NULL;
|
||||
char **s;
|
||||
@ -230,6 +246,7 @@ static int write_dependency(FILE *f, const char *opts,
|
||||
r = unit_name_mangle_with_suffix(*s, "as dependency", 0, ".mount", &x);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
r = strv_consume(&units, x);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
@ -249,7 +266,8 @@ static int write_dependency(FILE *f, const char *opts,
|
||||
}
|
||||
|
||||
static int write_after(FILE *f, const char *opts) {
|
||||
return write_dependency(f, opts, "x-systemd.after", "After=%1$s\n");
|
||||
return write_dependency(f, opts,
|
||||
"x-systemd.after", "After=%1$s\n");
|
||||
}
|
||||
|
||||
static int write_requires_after(FILE *f, const char *opts) {
|
||||
@ -363,8 +381,8 @@ static int add_mount(
|
||||
|
||||
fprintf(f,
|
||||
"[Unit]\n"
|
||||
"SourcePath=%s\n"
|
||||
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
|
||||
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n"
|
||||
"SourcePath=%s\n",
|
||||
source);
|
||||
|
||||
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not
|
||||
@ -411,7 +429,14 @@ static int add_mount(
|
||||
return r;
|
||||
}
|
||||
|
||||
fprintf(f, "\n[Mount]\n");
|
||||
r = generator_write_blockdev_dependency(f, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Mount]\n");
|
||||
|
||||
if (original_where)
|
||||
fprintf(f, "# Canonicalized from %s\n", original_where);
|
||||
|
||||
|
@ -105,9 +105,8 @@ static int open_parent_block_device(dev_t devnum, int *ret_fd) {
|
||||
}
|
||||
|
||||
static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
|
||||
_cleanup_free_ char *e = NULL, *n = NULL, *d = NULL, *id_escaped = NULL, *what_escaped = NULL;
|
||||
_cleanup_free_ char *e = NULL, *n = NULL, *d = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(id);
|
||||
@ -125,44 +124,28 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
id_escaped = specifier_escape(id);
|
||||
if (!id_escaped)
|
||||
return log_oom();
|
||||
r = generator_open_unit_file(arg_dest, NULL, n, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
what_escaped = specifier_escape(what);
|
||||
if (!what_escaped)
|
||||
return log_oom();
|
||||
|
||||
p = prefix_roota(arg_dest, n);
|
||||
f = fopen(p, "wxe");
|
||||
if (!f)
|
||||
return log_error_errno(errno, "Failed to create unit file %s: %m", p);
|
||||
r = generator_write_cryptsetup_unit_section(f, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"# Automatically generated by systemd-gpt-auto-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"Description=Cryptography Setup for %%I\n"
|
||||
"Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"Conflicts=umount.target\n"
|
||||
"BindsTo=dev-mapper-%%i.device %s\n"
|
||||
"Before=umount.target cryptsetup.target\n"
|
||||
"After=%s\n"
|
||||
"IgnoreOnIsolate=true\n"
|
||||
"[Service]\n"
|
||||
"Type=oneshot\n"
|
||||
"RemainAfterExit=yes\n"
|
||||
"TimeoutSec=0\n" /* the binary handles timeouts anyway */
|
||||
"KeyringMode=shared\n" /* make sure we can share cached keys among instances */
|
||||
"ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
|
||||
"ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
|
||||
d, d,
|
||||
id_escaped, what_escaped, rw ? "" : "read-only",
|
||||
id_escaped);
|
||||
"Conflicts=umount.target\n"
|
||||
"BindsTo=%s\n"
|
||||
"After=%s\n",
|
||||
d, d);
|
||||
|
||||
r = generator_write_cryptsetup_service_section(f, id, what, NULL, rw ? NULL : "read-only");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = fflush_and_check(f);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write file %s: %m", p);
|
||||
return log_error_errno(r, "Failed to write file %s: %m", n);
|
||||
|
||||
r = generator_add_symlink(arg_dest, d, "wants", n);
|
||||
if (r < 0)
|
||||
@ -227,7 +210,6 @@ static int add_mount(
|
||||
log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
|
||||
|
||||
if (streq_ptr(fstype, "crypto_LUKS")) {
|
||||
|
||||
r = add_cryptsetup(id, what, rw, true, &crypto_what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -262,6 +244,10 @@ static int add_mount(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_write_blockdev_dependency(f, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Mount]\n"
|
||||
@ -370,7 +356,14 @@ static int add_swap(const char *path) {
|
||||
"# Automatically generated by systemd-gpt-auto-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"Description=Swap Partition\n"
|
||||
"Documentation=man:systemd-gpt-auto-generator(8)\n\n"
|
||||
"Documentation=man:systemd-gpt-auto-generator(8)\n");
|
||||
|
||||
r = generator_write_blockdev_dependency(f, path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Swap]\n"
|
||||
"What=%s\n",
|
||||
path);
|
||||
|
@ -519,6 +519,103 @@ int generator_enable_remount_fs_service(const char *dir) {
|
||||
SYSTEM_DATA_UNIT_PATH "/" SPECIAL_REMOUNT_FS_SERVICE);
|
||||
}
|
||||
|
||||
int generator_write_blockdev_dependency(
|
||||
FILE *f,
|
||||
const char *what) {
|
||||
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(what);
|
||||
|
||||
if (!path_startswith(what, "/dev/"))
|
||||
return 0;
|
||||
|
||||
r = unit_name_path_escape(what, &escaped);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to escape device node path %s: %m", what);
|
||||
|
||||
fprintf(f,
|
||||
"After=blockdev@%s.target\n",
|
||||
escaped);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generator_write_cryptsetup_unit_section(
|
||||
FILE *f,
|
||||
const char *source) {
|
||||
|
||||
assert(f);
|
||||
|
||||
fprintf(f,
|
||||
"[Unit]\n"
|
||||
"Description=Cryptography Setup for %%I\n"
|
||||
"Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n");
|
||||
|
||||
if (source)
|
||||
fprintf(f, "SourcePath=%s\n", source);
|
||||
|
||||
fprintf(f,
|
||||
"DefaultDependencies=no\n"
|
||||
"IgnoreOnIsolate=true\n"
|
||||
"After=cryptsetup-pre.target\n"
|
||||
"Before=blockdev@dev-mapper-%%i.target\n"
|
||||
"Wants=blockdev@dev-mapper-%%i.target\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generator_write_cryptsetup_service_section(
|
||||
FILE *f,
|
||||
const char *name,
|
||||
const char *what,
|
||||
const char *password,
|
||||
const char *options) {
|
||||
|
||||
_cleanup_free_ char *name_escaped = NULL, *what_escaped = NULL, *password_escaped = NULL, *options_escaped = NULL;
|
||||
|
||||
assert(f);
|
||||
assert(name);
|
||||
assert(what);
|
||||
|
||||
name_escaped = specifier_escape(name);
|
||||
if (!name_escaped)
|
||||
return log_oom();
|
||||
|
||||
what_escaped = specifier_escape(what);
|
||||
if (!what_escaped)
|
||||
return log_oom();
|
||||
|
||||
if (password) {
|
||||
password_escaped = specifier_escape(password);
|
||||
if (!password_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (options) {
|
||||
options_escaped = specifier_escape(options);
|
||||
if (!options_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Service]\n"
|
||||
"Type=oneshot\n"
|
||||
"RemainAfterExit=yes\n"
|
||||
"TimeoutSec=0\n" /* The binary handles timeouts on its own */
|
||||
"KeyringMode=shared\n" /* Make sure we can share cached keys among instances */
|
||||
"OOMScoreAdjust=500\n" /* Unlocking can allocate a lot of memory if Argon2 is used */
|
||||
"ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
|
||||
"ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
|
||||
name_escaped, what_escaped, strempty(password_escaped), strempty(options_escaped),
|
||||
name_escaped);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void log_setup_generator(void) {
|
||||
log_set_prohibit_ipc(true);
|
||||
log_setup_service();
|
||||
|
@ -27,6 +27,21 @@ int generator_write_timeouts(
|
||||
const char *opts,
|
||||
char **filtered);
|
||||
|
||||
int generator_write_blockdev_dependency(
|
||||
FILE *f,
|
||||
const char *what);
|
||||
|
||||
int generator_write_cryptsetup_unit_section(
|
||||
FILE *f,
|
||||
const char *source);
|
||||
|
||||
int generator_write_cryptsetup_service_section(
|
||||
FILE *f,
|
||||
const char *name,
|
||||
const char *what,
|
||||
const char *password,
|
||||
const char *options);
|
||||
|
||||
int generator_write_device_deps(
|
||||
const char *dir,
|
||||
const char *what,
|
||||
|
13
units/blockdev@.target
Normal file
13
units/blockdev@.target
Normal file
@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# 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=Block Device Preparation for %f
|
||||
Documentation=man:systemd.special(7)
|
||||
StopWhenUnneeded=yes
|
@ -2,6 +2,7 @@
|
||||
|
||||
units = [
|
||||
['basic.target', ''],
|
||||
['blockdev@.target', ''],
|
||||
['bluetooth.target', ''],
|
||||
['boot-complete.target', ''],
|
||||
['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
||||
|
Loading…
Reference in New Issue
Block a user