Compare commits

..

No commits in common. "c0f765cac8b0801612a6aa52bfe968df4d502abb" and "91e50467f5ce8119efc47e5c5637710b9d7f012c" have entirely different histories.

27 changed files with 172 additions and 419 deletions

3
TODO
View File

@ -44,9 +44,6 @@ Features:
* cryptsetup: allow encoding key directly in /etc/crypttab, maybe with a * cryptsetup: allow encoding key directly in /etc/crypttab, maybe with a
"base64:" prefix. Useful in particular for pkcs11 mode. "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, * socket units: allow creating a udev monitor socket with ListenDevices= or so,
with matches, then actviate app thorugh that passing socket oveer with matches, then actviate app thorugh that passing socket oveer

View File

@ -1926,14 +1926,15 @@
<term><varname>EmitDNS=</varname></term> <term><varname>EmitDNS=</varname></term>
<term><varname>DNS=</varname></term> <term><varname>DNS=</varname></term>
<listitem><para><varname>DNS=</varname> specifies a list of recursive DNS server IPv6 addresses <listitem><para><varname>DNS=</varname> specifies a list of recursive
that are distributed via Router Advertisement messages when <varname>EmitDNS=</varname> is DNS server IPv6 addresses that distributed via Router Advertisement
true. <varname>DNS=</varname> also takes special value <literal>_link_local</literal>; in that messages when <varname>EmitDNS=</varname> is true. If <varname>DNS=
case the IPv6 link local address is distributed. If <varname>DNS=</varname> is empty, DNS </varname> is empty, DNS servers are read from the
servers are read from the <literal>[Network]</literal> section. If the <literal>[Network]</literal> section. If the
<literal>[Network]</literal> section does not contain any DNS servers either, DNS servers from <literal>[Network]</literal> section does not contain any DNS servers
the uplink with the highest priority default route are used. When <varname>EmitDNS=</varname> either, DNS servers from the uplink with the highest priority default
is false, no DNS server information is sent in Router Advertisement messages. route are used. When <varname>EmitDNS=</varname> is false, no DNS server
information is sent in Router Advertisement messages.
<varname>EmitDNS=</varname> defaults to true. <varname>EmitDNS=</varname> defaults to true.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>

View File

@ -26,7 +26,6 @@
<filename>cryptsetup-pre.target</filename>, <filename>cryptsetup-pre.target</filename>,
<filename>cryptsetup.target</filename>, <filename>cryptsetup.target</filename>,
<filename>ctrl-alt-del.target</filename>, <filename>ctrl-alt-del.target</filename>,
<filename>blockdev@.target</filename>,
<filename>boot-complete.target</filename>, <filename>boot-complete.target</filename>,
<filename>default.target</filename>, <filename>default.target</filename>,
<filename>emergency.target</filename>, <filename>emergency.target</filename>,
@ -846,23 +845,6 @@
not useful as only unit within a transaction.</para> not useful as only unit within a transaction.</para>
<variablelist> <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> <varlistentry>
<term><filename>cryptsetup-pre.target</filename></term> <term><filename>cryptsetup-pre.target</filename></term>
<listitem> <listitem>

View File

@ -3369,8 +3369,8 @@ if conf.get('ENABLE_EFI') == 1
status += [ status += [
'EFI machine type: @0@'.format(EFI_MACHINE_TYPE_NAME), 'EFI machine type: @0@'.format(EFI_MACHINE_TYPE_NAME),
'EFI CC @0@'.format(' '.join(efi_cc)), 'EFI CC @0@'.format(' '.join(efi_cc)),
'EFI lds: @0@'.format(efi_lds), 'EFI lib directory: @0@'.format(efi_libdir),
'EFI crt0: @0@'.format(efi_crt0), 'EFI lds directory: @0@'.format(efi_ldsdir),
'EFI include directory: @0@'.format(efi_incdir)] 'EFI include directory: @0@'.format(efi_incdir)]
endif endif
endif endif

View File

@ -323,6 +323,8 @@ option('efi-ld', type : 'string',
description : 'the linker to use for EFI modules') description : 'the linker to use for EFI modules')
option('efi-libdir', type : 'string', option('efi-libdir', type : 'string',
description : 'path to the EFI lib directory') description : 'path to the EFI lib directory')
option('efi-ldsdir', type : 'string',
description : 'path to the EFI lds directory')
option('efi-includedir', type : 'string', value : '/usr/include/efi', option('efi-includedir', type : 'string', value : '/usr/include/efi',
description : 'path to the EFI header directory') description : 'path to the EFI header directory')
option('tpm-pcrindex', type : 'integer', value : 8, option('tpm-pcrindex', type : 'integer', value : 8,

View File

@ -64,19 +64,12 @@ if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
efi_libdir = get_option('efi-libdir') efi_libdir = get_option('efi-libdir')
if efi_libdir == '' if efi_libdir == ''
# New location first introduced with gnu-efi 3.0.11 ret = run_command(efi_cc + ['-print-multi-os-directory'])
efi_libdir = join_paths('/usr/lib/gnuefi', EFI_MACHINE_TYPE_NAME) if ret.returncode() == 0
cmd = run_command('test', '-e', efi_libdir) path = join_paths('/usr/lib', ret.stdout().strip())
ret = run_command('realpath', '-e', path)
if cmd.returncode() != 0 if ret.returncode() == 0
# Fall back to the old approach efi_libdir = ret.stdout().strip()
cmd = run_command(efi_cc + ['-print-multi-os-directory'])
if cmd.returncode() == 0
path = join_paths('/usr/lib', cmd.stdout().strip())
cmd = run_command('realpath', '-e', path)
if cmd.returncode() == 0
efi_libdir = cmd.stdout().strip()
endif
endif endif
endif endif
endif endif
@ -102,35 +95,20 @@ if have_gnu_efi
objcopy = find_program('objcopy') objcopy = find_program('objcopy')
efi_location_map = [ efi_ldsdir = get_option('efi-ldsdir')
# New locations first introduced with gnu-efi 3.0.11 arch_lds = 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)
[join_paths(efi_libdir, 'efi.lds'), if efi_ldsdir == ''
join_paths(efi_libdir, 'crt0.o')], efi_ldsdir = join_paths(efi_libdir, 'gnuefi')
# Older locations... cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
[join_paths(efi_libdir, 'gnuefi', 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)), if cmd.returncode() != 0
join_paths(efi_libdir, 'gnuefi', 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))], efi_ldsdir = efi_libdir
[join_paths(efi_libdir, 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)), cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
join_paths(efi_libdir, 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))]] if cmd.returncode() != 0
efi_lds = '' error('Cannot find @0@'.format(arch_lds))
foreach location : efi_location_map
if efi_lds == ''
cmd = run_command('test', '-f', location[0])
if cmd.returncode() == 0
efi_lds = location[0]
efi_crt0 = location[1]
endif endif
endif endif
endforeach
if efi_lds == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but cannot find efi.lds')
else
have_gnu_efi = false
endif endif
endif
endif
if have_gnu_efi
compile_args = ['-Wall', compile_args = ['-Wall',
'-Wextra', '-Wextra',
'-std=gnu90', '-std=gnu90',
@ -167,13 +145,14 @@ if have_gnu_efi
compile_args += ['-O2'] compile_args += ['-O2']
endif endif
efi_ldflags = ['-T', efi_lds, efi_ldflags = ['-T',
join_paths(efi_ldsdir, arch_lds),
'-shared', '-shared',
'-Bsymbolic', '-Bsymbolic',
'-nostdlib', '-nostdlib',
'-znocombreloc', '-znocombreloc',
'-L', efi_libdir, '-L', efi_libdir,
efi_crt0] join_paths(efi_ldsdir, 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))]
if efi_arch == 'aarch64' or efi_arch == 'arm' if efi_arch == 'aarch64' or efi_arch == 'arm'
# Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary' # Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary'
# instead, and add required symbols manually. # instead, and add required symbols manually.
@ -240,9 +219,11 @@ if have_gnu_efi
set_variable(tuple[0].underscorify(), so) set_variable(tuple[0].underscorify(), so)
set_variable(tuple[0].underscorify() + '_stub', stub) set_variable(tuple[0].underscorify() + '_stub', stub)
endforeach endforeach
endif
############################################################ ############################################################
if have_gnu_efi
test_efi_disk_img = custom_target( test_efi_disk_img = custom_target(
'test-efi-disk.img', 'test-efi-disk.img',
input : [systemd_boot_so, stub_so_stub], input : [systemd_boot_so, stub_so_stub],

View File

@ -3,7 +3,6 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "bus-util.h"
#include "dbus-job.h" #include "dbus-job.h"
#include "dbus-unit.h" #include "dbus-unit.h"
#include "dbus.h" #include "dbus.h"

View File

@ -9,7 +9,6 @@
#include "architecture.h" #include "architecture.h"
#include "build.h" #include "build.h"
#include "bus-common-errors.h" #include "bus-common-errors.h"
#include "bus-util.h"
#include "dbus-cgroup.h" #include "dbus-cgroup.h"
#include "dbus-execute.h" #include "dbus-execute.h"
#include "dbus-job.h" #include "dbus-job.h"

View File

@ -6,7 +6,6 @@
#include "bpf-firewall.h" #include "bpf-firewall.h"
#include "bus-common-errors.h" #include "bus-common-errors.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "bus-util.h"
#include "cgroup-util.h" #include "cgroup-util.h"
#include "condition.h" #include "condition.h"
#include "dbus-job.h" #include "dbus-job.h"

View File

@ -11,7 +11,6 @@
#include "bus-error.h" #include "bus-error.h"
#include "bus-internal.h" #include "bus-internal.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "bus-util.h"
#include "dbus-automount.h" #include "dbus-automount.h"
#include "dbus-cgroup.h" #include "dbus-cgroup.h"
#include "dbus-device.h" #include "dbus-device.h"

View File

@ -217,7 +217,7 @@ static void mount_done(Unit *u) {
m->timer_event_source = sd_event_source_unref(m->timer_event_source); m->timer_event_source = sd_event_source_unref(m->timer_event_source);
} }
static MountParameters* get_mount_parameters_fragment(Mount *m) { _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
assert(m); assert(m);
if (m->from_fragment) if (m->from_fragment)
@ -226,7 +226,7 @@ static MountParameters* get_mount_parameters_fragment(Mount *m) {
return NULL; return NULL;
} }
static MountParameters* get_mount_parameters(Mount *m) { _pure_ static MountParameters* get_mount_parameters(Mount *m) {
assert(m); assert(m);
if (m->from_proc_self_mountinfo) if (m->from_proc_self_mountinfo)
@ -342,18 +342,20 @@ static int mount_add_device_dependencies(Mount *m) {
if (!is_device_path(p->what)) if (!is_device_path(p->what))
return 0; return 0;
/* /dev/root is a really weird thing, it's not a real device, but just a path the kernel exports for /* /dev/root is a really weird thing, it's not a real device,
* the root file system specified on the kernel command line. Ignore it here. */ * but just a path the kernel exports for the root file system
if (PATH_IN_SET(p->what, "/dev/root", "/dev/nfs")) * specified on the kernel command line. Ignore it here. */
if (path_equal(p->what, "/dev/root"))
return 0; return 0;
if (path_equal(m->where, "/")) if (path_equal(m->where, "/"))
return 0; return 0;
/* Mount units from /proc/self/mountinfo are not bound to devices by default since they're subject to /* Mount units from /proc/self/mountinfo are not bound to devices
* races when devices are unplugged. But the user can still force this dep with an appropriate option * by default since they're subject to races when devices are
* (or udev property) so the mount units are automatically stopped when the device disappears * unplugged. But the user can still force this dep with an
* suddenly. */ * 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; dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
/* We always use 'what' from /proc/self/mountinfo if mounted */ /* We always use 'what' from /proc/self/mountinfo if mounted */
@ -363,7 +365,7 @@ static int mount_add_device_dependencies(Mount *m) {
if (r < 0) if (r < 0)
return r; return r;
return unit_add_blockdev_dependency(UNIT(m), p->what, mask); return 0;
} }
static int mount_add_quota_dependencies(Mount *m) { static int mount_add_quota_dependencies(Mount *m) {

View File

@ -3,6 +3,7 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "bus-util.h"
#include "manager.h" #include "manager.h"
int mac_selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error); int mac_selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);

View File

@ -184,45 +184,21 @@ static int swap_arm_timer(Swap *s, usec_t usec) {
return 0; 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) { static int swap_add_device_dependencies(Swap *s) {
UnitDependencyMask mask;
SwapParameters *p;
int r;
assert(s); assert(s);
if (!s->what) if (!s->what)
return 0; return 0;
p = swap_get_parameters(s); if (!s->from_fragment)
if (!p)
return 0; return 0;
mask = s->from_proc_swaps ? UNIT_DEPENDENCY_PROC_SWAP : UNIT_DEPENDENCY_FILE; if (is_device_path(s->what))
return unit_add_node_dependency(UNIT(s), s->what, UNIT_BINDS_TO, UNIT_DEPENDENCY_FILE);
if (is_device_path(p->what)) { /* File based swap devices need to be ordered after systemd-remount-fs.service,
r = unit_add_node_dependency(UNIT(s), p->what, UNIT_REQUIRES, mask); * since they might need a writable file system. */
if (r < 0) return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, true, UNIT_DEPENDENCY_FILE);
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) { static int swap_add_default_dependencies(Swap *s) {

View File

@ -3866,8 +3866,8 @@ int unit_deserialize_skip(FILE *f) {
} }
int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, UnitDependencyMask mask) { int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, UnitDependencyMask mask) {
_cleanup_free_ char *e = NULL;
Unit *device; Unit *device;
_cleanup_free_ char *e = NULL;
int r; int r;
assert(u); assert(u);
@ -3879,7 +3879,8 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit
if (!is_device_path(what)) if (!is_device_path(what))
return 0; 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)) if (!unit_type_supported(UNIT_DEVICE))
return 0; return 0;
@ -3899,33 +3900,6 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit
device, true, mask); 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 unit_coldplug(Unit *u) {
int r = 0, q; int r = 0, q;
char **i; char **i;
@ -5803,11 +5777,9 @@ bool unit_needs_console(Unit *u) {
return exec_context_may_touch_console(ec); return exec_context_may_touch_console(ec);
} }
const char *unit_label_path(const Unit *u) { const char *unit_label_path(Unit *u) {
const char *p; const char *p;
assert(u);
/* Returns the file system path to use for MAC access decisions, i.e. the file to read the SELinux label off /* Returns the file system path to use for MAC access decisions, i.e. the file to read the SELinux label off
* when validating access checks. */ * when validating access checks. */

View File

@ -743,7 +743,6 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
int unit_deserialize_skip(FILE *f); int unit_deserialize_skip(FILE *f);
int unit_add_node_dependency(Unit *u, const char *what, UnitDependency d, UnitDependencyMask mask); 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); int unit_coldplug(Unit *u);
void unit_catchup(Unit *u); void unit_catchup(Unit *u);
@ -842,7 +841,7 @@ int unit_warn_leftover_processes(Unit *u);
bool unit_needs_console(Unit *u); bool unit_needs_console(Unit *u);
const char *unit_label_path(const Unit *u); const char *unit_label_path(Unit *u);
int unit_pid_attachable(Unit *unit, pid_t pid, sd_bus_error *error); int unit_pid_attachable(Unit *unit, pid_t pid, sd_bus_error *error);

View File

@ -99,14 +99,7 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
return 0; return 0;
} }
static int generate_keydev_mount( static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **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_free_ char *u = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int r; int r;
@ -230,8 +223,8 @@ static int create_disk(
const char *options) { const char *options) {
_cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL, _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
*keydev_mount = NULL, *keyfile_timeout_value = NULL, *keydev_mount = NULL, *keyfile_timeout_value = NULL, *password_escaped = NULL,
*filtered = NULL, *u_escaped = NULL, *name_escaped = NULL, *header_path = NULL, *password_buffer = NULL; *filtered = NULL, *u_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *header_path = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
const char *dmname; const char *dmname;
bool noauto, nofail, tmp, swap, netdev, attach_in_initrd; bool noauto, nofail, tmp, swap, netdev, attach_in_initrd;
@ -292,29 +285,39 @@ static int create_disk(
if (r < 0) if (r < 0)
return r; return r;
r = generator_write_cryptsetup_unit_section(f, arg_crypttab); fprintf(f,
if (r < 0) "[Unit]\n"
return r; "Description=Cryptography Setup for %%I\n"
"Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
if (netdev) "SourcePath=%s\n"
fprintf(f, "After=remote-fs-pre.target\n"); "DefaultDependencies=no\n"
"IgnoreOnIsolate=true\n"
"After=%s\n",
arg_crypttab,
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
/* If initrd takes care of attaching the disk then it should also detach it during shutdown. */ /* If initrd takes care of attaching the disk then it should also detach it during shutdown. */
if (!attach_in_initrd) if (!attach_in_initrd)
fprintf(f, "Conflicts=umount.target\n"); fprintf(f, "Conflicts=umount.target\n");
if (password) {
password_escaped = specifier_escape(password);
if (!password_escaped)
return log_oom();
}
if (keydev) { if (keydev) {
_cleanup_free_ char *unit = NULL; _cleanup_free_ char *unit = NULL, *p = NULL;
r = generate_keydev_mount(name, keydev, keyfile_timeout_value, keyfile_can_timeout > 0, &unit, &keydev_mount); r = generate_keydev_mount(name, keydev, keyfile_timeout_value, keyfile_can_timeout > 0, &unit, &keydev_mount);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to generate keydev mount unit: %m"); return log_error_errno(r, "Failed to generate keydev mount unit: %m");
password_buffer = path_join(keydev_mount, password); p = path_join(keydev_mount, password_escaped);
if (!password_buffer) if (!p)
return log_oom(); return log_oom();
password = password_buffer; free_and_replace(password_escaped, p);
fprintf(f, "After=%s\n", unit); fprintf(f, "After=%s\n", unit);
if (keyfile_can_timeout > 0) if (keyfile_can_timeout > 0)
@ -341,13 +344,17 @@ static int create_disk(
return r; return r;
} }
if (path_startswith(u, "/dev/")) if (path_startswith(u, "/dev/")) {
fprintf(f, fprintf(f,
"BindsTo=%s\n" "BindsTo=%s\n"
"After=%s\n" "After=%s\n"
"Before=umount.target\n", "Before=umount.target\n",
d, d); d, d);
else
if (swap)
fputs("Before=dev-mapper-%i.swap\n",
f);
} else
/* For loopback devices, add systemd-tmpfiles-setup-dev.service /* For loopback devices, add systemd-tmpfiles-setup-dev.service
dependency to ensure that loopback support is available in dependency to ensure that loopback support is available in
the kernel (/dev/loop-control needs to exist) */ the kernel (/dev/loop-control needs to exist) */
@ -361,9 +368,23 @@ static int create_disk(
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in: %m"); log_warning_errno(r, "Failed to write device timeout drop-in: %m");
r = generator_write_cryptsetup_service_section(f, name, u, password, filtered); if (filtered) {
if (r < 0) filtered_escaped = specifier_escape(filtered);
return r; 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);
if (tmp) if (tmp)
fprintf(f, fprintf(f,

View File

@ -118,18 +118,11 @@ static int add_swap(
fprintf(f, fprintf(f,
"[Unit]\n" "[Unit]\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n" "SourcePath=%s\n"
"SourcePath=%s\n", "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
"[Swap]\n",
fstab_path()); fstab_path());
r = generator_write_blockdev_dependency(f, what);
if (r < 0)
return r;
fprintf(f,
"\n"
"[Swap]\n");
r = write_what(f, what); r = write_what(f, what);
if (r < 0) if (r < 0)
return r; return r;
@ -181,13 +174,8 @@ static bool mount_in_initrd(struct mntent *me) {
streq(me->mnt_dir, "/usr"); streq(me->mnt_dir, "/usr");
} }
static int write_timeout( static int write_timeout(FILE *f, const char *where, const char *opts,
FILE *f, const char *filter, const char *variable) {
const char *where,
const char *opts,
const char *filter,
const char *variable) {
_cleanup_free_ char *timeout = NULL; _cleanup_free_ char *timeout = NULL;
char timespan[FORMAT_TIMESPAN_MAX]; char timespan[FORMAT_TIMESPAN_MAX];
usec_t u; usec_t u;
@ -220,12 +208,8 @@ static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
"x-systemd.mount-timeout\0", "TimeoutSec"); "x-systemd.mount-timeout\0", "TimeoutSec");
} }
static int write_dependency( static int write_dependency(FILE *f, const char *opts,
FILE *f, const char *filter, const char *format) {
const char *opts,
const char *filter,
const char *format) {
_cleanup_strv_free_ char **names = NULL, **units = NULL; _cleanup_strv_free_ char **names = NULL, **units = NULL;
_cleanup_free_ char *res = NULL; _cleanup_free_ char *res = NULL;
char **s; char **s;
@ -246,7 +230,6 @@ static int write_dependency(
r = unit_name_mangle_with_suffix(*s, "as dependency", 0, ".mount", &x); r = unit_name_mangle_with_suffix(*s, "as dependency", 0, ".mount", &x);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m"); return log_error_errno(r, "Failed to generate unit name: %m");
r = strv_consume(&units, x); r = strv_consume(&units, x);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -266,8 +249,7 @@ static int write_dependency(
} }
static int write_after(FILE *f, const char *opts) { static int write_after(FILE *f, const char *opts) {
return write_dependency(f, opts, return write_dependency(f, opts, "x-systemd.after", "After=%1$s\n");
"x-systemd.after", "After=%1$s\n");
} }
static int write_requires_after(FILE *f, const char *opts) { static int write_requires_after(FILE *f, const char *opts) {
@ -381,8 +363,8 @@ static int add_mount(
fprintf(f, fprintf(f,
"[Unit]\n" "[Unit]\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n" "SourcePath=%s\n"
"SourcePath=%s\n", "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source); source);
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not /* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not
@ -429,14 +411,7 @@ static int add_mount(
return r; return r;
} }
r = generator_write_blockdev_dependency(f, what); fprintf(f, "\n[Mount]\n");
if (r < 0)
return r;
fprintf(f,
"\n"
"[Mount]\n");
if (original_where) if (original_where)
fprintf(f, "# Canonicalized from %s\n", original_where); fprintf(f, "# Canonicalized from %s\n", original_where);

View File

@ -105,8 +105,9 @@ 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) { 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; _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL, *id_escaped = NULL, *what_escaped = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
const char *p;
int r; int r;
assert(id); assert(id);
@ -124,28 +125,44 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m"); return log_error_errno(r, "Failed to generate unit name: %m");
r = generator_open_unit_file(arg_dest, NULL, n, &f); id_escaped = specifier_escape(id);
if (r < 0) if (!id_escaped)
return r; return log_oom();
r = generator_write_cryptsetup_unit_section(f, NULL); what_escaped = specifier_escape(what);
if (r < 0) if (!what_escaped)
return r; 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);
fprintf(f, fprintf(f,
"Before=umount.target cryptsetup.target\n" "# 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" "Conflicts=umount.target\n"
"BindsTo=%s\n" "BindsTo=dev-mapper-%%i.device %s\n"
"After=%s\n", "Before=umount.target cryptsetup.target\n"
d, d); "After=%s\n"
"IgnoreOnIsolate=true\n"
r = generator_write_cryptsetup_service_section(f, id, what, NULL, rw ? NULL : "read-only"); "[Service]\n"
if (r < 0) "Type=oneshot\n"
return r; "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);
r = fflush_and_check(f); r = fflush_and_check(f);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to write file %s: %m", n); return log_error_errno(r, "Failed to write file %s: %m", p);
r = generator_add_symlink(arg_dest, d, "wants", n); r = generator_add_symlink(arg_dest, d, "wants", n);
if (r < 0) if (r < 0)
@ -210,6 +227,7 @@ static int add_mount(
log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)"); log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
if (streq_ptr(fstype, "crypto_LUKS")) { if (streq_ptr(fstype, "crypto_LUKS")) {
r = add_cryptsetup(id, what, rw, true, &crypto_what); r = add_cryptsetup(id, what, rw, true, &crypto_what);
if (r < 0) if (r < 0)
return r; return r;
@ -244,10 +262,6 @@ static int add_mount(
if (r < 0) if (r < 0)
return r; return r;
r = generator_write_blockdev_dependency(f, what);
if (r < 0)
return r;
fprintf(f, fprintf(f,
"\n" "\n"
"[Mount]\n" "[Mount]\n"
@ -356,14 +370,7 @@ static int add_swap(const char *path) {
"# Automatically generated by systemd-gpt-auto-generator\n\n" "# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n" "[Unit]\n"
"Description=Swap Partition\n" "Description=Swap Partition\n"
"Documentation=man:systemd-gpt-auto-generator(8)\n"); "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
r = generator_write_blockdev_dependency(f, path);
if (r < 0)
return r;
fprintf(f,
"\n"
"[Swap]\n" "[Swap]\n"
"What=%s\n", "What=%s\n",
path); path);

View File

@ -1514,10 +1514,6 @@ static int link_acquire_ipv6_conf(Link *link) {
log_link_debug(link, "Starting IPv6 Router Advertisements"); log_link_debug(link, "Starting IPv6 Router Advertisements");
r = radv_emit_dns(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure DNS or Domains in IPv6 Router Advertisement: %m");
r = sd_radv_start(link->radv); r = sd_radv_start(link->radv);
if (r < 0 && r != -EBUSY) if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m"); return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");

View File

@ -443,29 +443,20 @@ static int radv_get_ip6dns(Network *network, struct in6_addr **dns,
static int radv_set_dns(Link *link, Link *uplink) { static int radv_set_dns(Link *link, Link *uplink) {
_cleanup_free_ struct in6_addr *dns = NULL; _cleanup_free_ struct in6_addr *dns = NULL;
usec_t lifetime_usec;
size_t n_dns; size_t n_dns;
usec_t lifetime_usec;
int r; int r;
if (!link->network->router_emit_dns) if (!link->network->router_emit_dns)
return 0; return 0;
if (link->network->router_dns) { if (link->network->router_dns) {
struct in6_addr *p; dns = newdup(struct in6_addr, link->network->router_dns,
link->network->n_router_dns);
dns = new(struct in6_addr, link->network->n_router_dns);
if (!dns) if (!dns)
return -ENOMEM; return -ENOMEM;
p = dns; n_dns = link->network->n_router_dns;
for (size_t i = 0; i < link->network->n_router_dns; i++)
if (IN6_IS_ADDR_UNSPECIFIED(&link->network->router_dns[i])) {
if (!IN6_IS_ADDR_UNSPECIFIED(&link->ipv6ll_address))
*(p++) = link->ipv6ll_address;
} else
*(p++) = link->network->router_dns[i];
n_dns = p - dns;
lifetime_usec = link->network->router_dns_lifetime_usec; lifetime_usec = link->network->router_dns_lifetime_usec;
goto set_dns; goto set_dns;
@ -629,7 +620,7 @@ int radv_configure(Link *link) {
} }
return 0; return radv_emit_dns(link);
} }
int config_parse_radv_dns( int config_parse_radv_dns(
@ -667,30 +658,19 @@ int config_parse_radv_dns(
if (r == 0) if (r == 0)
break; break;
if (streq(w, "_link_local")) if (in_addr_from_string(AF_INET6, w, &a) >= 0) {
a = IN_ADDR_NULL;
else {
r = in_addr_from_string(AF_INET6, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DNS server address, ignoring: %s", w);
continue;
}
if (in_addr_is_null(AF_INET6, &a)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"DNS server address is null, ignoring: %s", w);
continue;
}
}
struct in6_addr *m; struct in6_addr *m;
m = reallocarray(n->router_dns, n->n_router_dns + 1, sizeof(struct in6_addr)); m = reallocarray(n->router_dns, n->n_router_dns + 1, sizeof(struct in6_addr));
if (!m) if (!m)
return log_oom(); return log_oom();
m[n->n_router_dns++] = a.in6; m[n->n_router_dns++] = a.in6;
n->router_dns = m; n->router_dns = m;
} else
log_syntax(unit, LOG_ERR, filename, line, 0,
"Failed to parse DNS server address, ignoring: %s", w);
} }
return 0; return 0;

View File

@ -519,103 +519,6 @@ int generator_enable_remount_fs_service(const char *dir) {
SYSTEM_DATA_UNIT_PATH "/" SPECIAL_REMOUNT_FS_SERVICE); 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) { void log_setup_generator(void) {
log_set_prohibit_ipc(true); log_set_prohibit_ipc(true);
log_setup_service(); log_setup_service();

View File

@ -27,21 +27,6 @@ int generator_write_timeouts(
const char *opts, const char *opts,
char **filtered); 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( int generator_write_device_deps(
const char *dir, const char *dir,
const char *what, const char *what,

View File

@ -4,10 +4,6 @@ Name=veth-peer
[Network] [Network]
IPv6PrefixDelegation=yes IPv6PrefixDelegation=yes
[IPv6PrefixDelegation]
DNS=_link_local 2002:da8:1:0::1
DNSLifetimeSec=1min
[IPv6Prefix] [IPv6Prefix]
Prefix=2002:da8:1:0::/64 Prefix=2002:da8:1:0::/64
PreferredLifetimeSec=1000s PreferredLifetimeSec=1000s

View File

@ -2646,11 +2646,6 @@ class NetworkdRATests(unittest.TestCase, Utilities):
start_networkd() start_networkd()
self.wait_online(['veth99:routable', 'veth-peer:degraded']) self.wait_online(['veth99:routable', 'veth-peer:degraded'])
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
print(output)
self.assertRegex(output, 'fe80::')
self.assertRegex(output, '2002:da8:1::1')
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env) output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
print(output) print(output)
self.assertRegex(output, '2002:da8:1:0') self.assertRegex(output, '2002:da8:1:0')

View File

@ -1,13 +0,0 @@
# 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

View File

@ -2,7 +2,6 @@
units = [ units = [
['basic.target', ''], ['basic.target', ''],
['blockdev@.target', ''],
['bluetooth.target', ''], ['bluetooth.target', ''],
['boot-complete.target', ''], ['boot-complete.target', ''],
['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'], ['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'],