Merge pull request #7661 from keszybz/slice-cleanups

Slice cleanups and systemd-mount --owner
This commit is contained in:
Lennart Poettering 2017-12-15 20:55:39 +01:00 committed by GitHub
commit 8769525f57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 170 additions and 113 deletions

View file

@ -159,6 +159,14 @@
<listitem><para>Additional mount options for the mount point.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--owner=<replaceable>USER</replaceable></option></term>
<listitem><para>Let the specified user <replaceable>USER</replaceable> own the mounted file system.
This is done by appending <option>uid=</option> and <option>gid=</option> options to the list
of mount options. Only certain file systems support this option.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--fsck=</option></term>

View file

@ -28,6 +28,7 @@
#include "glob-util.h"
#include "hexdecoct.h"
#include "path-util.h"
#include "special.h"
#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
@ -673,7 +674,7 @@ int slice_build_parent_slice(const char *slice, char **ret) {
if (!slice_name_is_valid(slice))
return -EINVAL;
if (streq(slice, "-.slice")) {
if (streq(slice, SPECIAL_ROOT_SLICE)) {
*ret = NULL;
return 0;
}
@ -686,7 +687,7 @@ int slice_build_parent_slice(const char *slice, char **ret) {
if (dash)
strcpy(dash, ".slice");
else {
r = free_and_strdup(&s, "-.slice");
r = free_and_strdup(&s, SPECIAL_ROOT_SLICE);
if (r < 0) {
free(s);
return r;
@ -710,7 +711,7 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) {
if (!unit_prefix_is_valid(name))
return -EINVAL;
if (streq(slice, "-.slice"))
if (streq(slice, SPECIAL_ROOT_SLICE))
subslice = strappend(name, ".slice");
else {
char *e;
@ -735,7 +736,7 @@ bool slice_name_is_valid(const char *name) {
if (!unit_name_is_valid(name, UNIT_NAME_PLAIN))
return false;
if (streq(name, "-.slice"))
if (streq(name, SPECIAL_ROOT_SLICE))
return true;
e = endswith(name, ".slice");

View file

@ -59,30 +59,24 @@ static void slice_set_state(Slice *t, SliceState state) {
}
static int slice_add_parent_slice(Slice *s) {
char *a, *dash;
Unit *parent;
Unit *u = UNIT(s), *parent;
_cleanup_free_ char *a = NULL;
int r;
assert(s);
if (UNIT_ISSET(UNIT(s)->slice))
if (UNIT_ISSET(u->slice))
return 0;
if (unit_has_name(UNIT(s), SPECIAL_ROOT_SLICE))
return 0;
r = slice_build_parent_slice(u->id, &a);
if (r <= 0) /* 0 means root slice */
return r;
a = strdupa(UNIT(s)->id);
dash = strrchr(a, '-');
if (dash)
strcpy(dash, ".slice");
else
a = (char*) SPECIAL_ROOT_SLICE;
r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent);
r = manager_load_unit(u->manager, a, NULL, NULL, &parent);
if (r < 0)
return r;
unit_ref_set(&UNIT(s)->slice, parent);
unit_ref_set(&u->slice, parent);
return 0;
}

View file

@ -61,7 +61,7 @@ static int create_disk(
const char *password,
const char *options) {
_cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL,
_cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
*filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
_cleanup_fclose_ FILE *f = NULL;
const char *dmname;
@ -90,18 +90,14 @@ static int create_disk(
if (!e)
return log_oom();
r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
p = strjoin(arg_dest, "/", n);
if (!p)
return log_oom();
u = fstab_node_to_udev_node(device);
if (!u)
return log_oom();
r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
u_escaped = specifier_escape(u);
if (!u_escaped)
return log_oom();
@ -114,14 +110,11 @@ static int create_disk(
if (!password_escaped)
return log_oom();
f = fopen(p, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", p);
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
r = generator_open_unit_file(arg_dest, NULL, n, &f);
if (r < 0)
return r;
fprintf(f,
"# Automatically generated by systemd-cryptsetup-generator\n\n"
"[Unit]\n"
"Description=Cryptography Setup for %%I\n"
"Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
@ -210,7 +203,7 @@ static int create_disk(
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 unit file %s: %m", n);
if (!noauto) {
r = generator_add_symlink(arg_dest, d, "wants", n);

View file

@ -102,7 +102,7 @@ static int add_swap(
struct mntent *me,
MountpointFlags flags) {
_cleanup_free_ char *name = NULL, *unit = NULL;
_cleanup_free_ char *name = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -123,19 +123,9 @@ static int add_swap(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
unit = strjoin(arg_dest, "/", name);
if (!unit)
return log_oom();
f = fopen(unit, "wxe");
if (!f)
return log_error_errno(errno,
errno == EEXIST ?
"Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?" :
"Failed to create unit file %s: %m",
unit);
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f);
if (r < 0)
return r;
fputs("# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
@ -153,7 +143,7 @@ static int add_swap(
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
return log_error_errno(r, "Failed to write unit file %s: %m", name);
/* use what as where, to have a nicer error message */
r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
@ -323,10 +313,9 @@ static int add_mount(
_cleanup_free_ char
*name = NULL,
*automount_name = NULL, *automount_unit = NULL,
*automount_name = NULL,
*filtered = NULL,
*where_escaped = NULL;
const char *unit;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -363,20 +352,11 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
unit = strjoina(dest, "/", name);
f = fopen(unit, "wxe");
if (!f)
return log_error_errno(errno,
errno == EEXIST ?
"Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?" :
"Failed to create unit file %s: %m",
unit);
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
r = generator_open_unit_file(dest, "/etc/fstab", name, &f);
if (r < 0)
return r;
fprintf(f,
"# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
"SourcePath=%s\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
@ -461,7 +441,7 @@ static int add_mount(
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
return log_error_errno(r, "Failed to write unit file %s: %m", name);
if (flags & MAKEFS) {
r = generator_hook_up_mkfs(dest, what, where, fstype);
@ -487,19 +467,13 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
automount_unit = strjoin(dest, "/", automount_name);
if (!automount_unit)
return log_oom();
fclose(f);
f = fopen(automount_unit, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit);
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f);
if (r < 0)
return r;
fprintf(f,
"# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
"SourcePath=%s\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
@ -534,7 +508,7 @@ static int add_mount(
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
return log_error_errno(r, "Failed to write unit file %s: %m", automount_name);
r = generator_add_symlink(dest, post,
(flags & NOFAIL) ? "wants" : "requires", automount_name);

View file

@ -344,16 +344,13 @@ static int user_mkdir_runtime_path(User *u) {
if (path_is_mount_point(u->runtime_path, NULL, 0) <= 0) {
_cleanup_free_ char *t = NULL;
(void) mkdir_label(u->runtime_path, 0700);
r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu%s",
u->uid, u->gid, u->manager->runtime_dir_size,
mac_smack_use() ? ",smackfsroot=*" : "");
if (r < 0)
return log_oom();
if (mac_smack_use())
r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
else
r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
if (r < 0) {
r = log_oom();
goto fail;
}
(void) mkdir_label(u->runtime_path, 0700);
r = mount("tmpfs", u->runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, t);
if (r < 0) {
@ -461,7 +458,7 @@ int user_start(User *u) {
u->stopping = false;
if (!u->started) {
log_debug("New user %s logged in.", u->name);
log_debug("Starting services for new user %s.", u->name);
/* Make XDG_RUNTIME_DIR */
r = user_mkdir_runtime_path(u);
@ -530,9 +527,7 @@ static int user_stop_service(User *u) {
return r;
}
free(u->service_job);
u->service_job = job;
free_and_replace(u->service_job, job);
return r;
}

View file

@ -37,6 +37,7 @@
#include "machined.h"
#include "process-util.h"
#include "signal-util.h"
#include "special.h"
Manager *manager_new(void) {
Manager *m;
@ -112,7 +113,7 @@ static int manager_add_host_machine(Manager *m) {
if (!rd)
return log_oom();
unit = strdup("-.slice");
unit = strdup(SPECIAL_ROOT_SLICE);
if (!unit)
return log_oom();

View file

@ -41,6 +41,7 @@
#include "strv.h"
#include "udev-util.h"
#include "unit-name.h"
#include "user-util.h"
#include "terminal-util.h"
enum {
@ -69,6 +70,8 @@ static usec_t arg_timeout_idle = USEC_INFINITY;
static bool arg_timeout_idle_set = false;
static char **arg_automount_property = NULL;
static int arg_bind_device = -1;
static uid_t arg_uid = UID_INVALID;
static gid_t arg_gid = GID_INVALID;
static bool arg_fsck = true;
static bool arg_aggressive_gc = false;
@ -89,6 +92,7 @@ static void help(void) {
" --discover Discover mount device metadata\n"
" -t --type=TYPE File system type\n"
" -o --options=OPTIONS Mount options\n"
" --owner=USER Add uid= and gid= options for USER\n"
" --fsck=no Don't run file system check before mount\n"
" --description=TEXT Description for unit\n"
" -p --property=NAME=VALUE Set mount unit property\n"
@ -116,6 +120,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DISCOVER,
ARG_MOUNT_TYPE,
ARG_MOUNT_OPTIONS,
ARG_OWNER,
ARG_FSCK,
ARG_DESCRIPTION,
ARG_TIMEOUT_IDLE,
@ -139,6 +144,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "discover", no_argument, NULL, ARG_DISCOVER },
{ "type", required_argument, NULL, 't' },
{ "options", required_argument, NULL, 'o' },
{ "owner", required_argument, NULL, ARG_OWNER },
{ "fsck", required_argument, NULL, ARG_FSCK },
{ "description", required_argument, NULL, ARG_DESCRIPTION },
{ "property", required_argument, NULL, 'p' },
@ -220,6 +226,18 @@ static int parse_argv(int argc, char *argv[]) {
return log_oom();
break;
case ARG_OWNER: {
const char *user = optarg;
r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL);
if (r < 0)
return log_error_errno(r,
r == -EBADMSG ? "UID or GID of user %s are invalid."
: "Cannot use \"%s\" as owner: %m",
optarg);
break;
}
case ARG_FSCK:
r = parse_boolean(optarg);
if (r < 0)
@ -422,6 +440,7 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) {
}
static int transient_mount_set_properties(sd_bus_message *m) {
_cleanup_free_ char *options = NULL;
int r;
assert(m);
@ -442,11 +461,24 @@ static int transient_mount_set_properties(sd_bus_message *m) {
return r;
}
if (arg_mount_options) {
r = sd_bus_message_append(m, "(sv)", "Options", "s", arg_mount_options);
/* Prepend uid=…,gid=… if arg_uid is set */
if (arg_uid != UID_INVALID) {
r = asprintf(&options,
"uid=" UID_FMT ",gid=" GID_FMT "%s%s",
arg_uid, arg_gid,
arg_mount_options ? "," : "", arg_mount_options);
if (r < 0)
return -ENOMEM;
}
if (options || arg_mount_options) {
log_debug("Using mount options: %s", options ?: arg_mount_options);
r = sd_bus_message_append(m, "(sv)", "Options", "s", options ?: arg_mount_options);
if (r < 0)
return r;
}
} else
log_debug("Not using any mount options");
if (arg_fsck) {
_cleanup_free_ char *fsck = NULL;
@ -1604,6 +1636,23 @@ int main(int argc, char* argv[]) {
}
}
/* The kernel (properly) refuses mounting file systems with unknown uid=,gid= options,
* but not for all filesystem types. Let's try to catch the cases where the option
* would be used if the file system does not support it. It is also possible to
* autodetect the file system, but that's only possible with disk-based file systems
* which incidentally seem to be implemented more carefully and reject unknown options,
* so it's probably OK that we do the check only when the type is specified.
*/
if (arg_mount_type &&
!streq(arg_mount_type, "auto") &&
arg_uid != UID_INVALID &&
!fstype_can_uid_gid(arg_mount_type)) {
log_error("File system type %s is not known to support uid=/gid=, refusing.",
arg_mount_type);
r = -EOPNOTSUPP;
goto finish;
}
switch (arg_action) {
case ACTION_MOUNT:

View file

@ -19,6 +19,7 @@
***/
#include <errno.h>
#include <stdio_ext.h>
#include <unistd.h>
#include "alloc-util.h"
@ -39,6 +40,39 @@
#include "unit-name.h"
#include "util.h"
int generator_open_unit_file(
const char *dest,
const char *source,
const char *name,
FILE **file) {
const char *unit;
FILE *f;
unit = strjoina(dest, "/", name);
f = fopen(unit, "wxe");
if (!f) {
if (source && errno == EEXIST)
return log_error_errno(errno,
"Failed to create unit file %s, as it already exists. Duplicate entry in %s?",
unit, source);
else
return log_error_errno(errno,
"Failed to create unit file %s: %m",
unit);
}
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
fprintf(f,
"# Automatically generated by %s\n\n",
program_invocation_short_name);
*file = f;
return 0;
}
int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src) {
/* Adds a symlink from <dst>.<dep_type>.d/ to ../<src> */

View file

@ -22,6 +22,12 @@
#include <stdio.h>
int generator_open_unit_file(
const char *dest,
const char *source,
const char *name,
FILE **file);
int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src);
int generator_write_fsck_deps(

View file

@ -27,6 +27,7 @@
#include "parse-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "special.h"
#include "stat-util.h"
#include "string-util.h"
#include "test-helper.h"
@ -141,10 +142,10 @@ static void check_p_g_slice(const char *path, int code, const char *result) {
static void test_path_get_slice(void) {
check_p_g_slice("/user.slice", 0, "user.slice");
check_p_g_slice("/foobar", 0, "-.slice");
check_p_g_slice("/foobar", 0, SPECIAL_ROOT_SLICE);
check_p_g_slice("/user.slice/user-waldo.slice", 0, "user-waldo.slice");
check_p_g_slice("", 0, "-.slice");
check_p_g_slice("foobar", 0, "-.slice");
check_p_g_slice("", 0, SPECIAL_ROOT_SLICE);
check_p_g_slice("foobar", 0, SPECIAL_ROOT_SLICE);
check_p_g_slice("foobar.slice", 0, "foobar.slice");
check_p_g_slice("foo.slice/foo-bar.slice/waldo.service", 0, "foo-bar.slice");
}
@ -165,10 +166,10 @@ static void test_path_get_user_slice(void) {
check_p_g_u_slice("foobar.slice", -ENXIO, NULL);
check_p_g_u_slice("foo.slice/foo-bar.slice/waldo.service", -ENXIO, NULL);
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, "-.slice");
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, "-.slice");
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, "-.slice");
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, "-.slice");
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, SPECIAL_ROOT_SLICE);
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, SPECIAL_ROOT_SLICE);
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, SPECIAL_ROOT_SLICE);
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, SPECIAL_ROOT_SLICE);
check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/piep.slice/foo.service", 0, "piep.slice");
check_p_g_u_slice("/foo.slice//foo-bar.slice/user@1000.service/piep.slice//piep-pap.slice//foo.service", 0, "piep-pap.slice");
}
@ -274,7 +275,7 @@ static void test_slice_to_path(void) {
test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
test_slice_to_path_one("-.slice", "", 0);
test_slice_to_path_one(SPECIAL_ROOT_SLICE, "", 0);
test_slice_to_path_one("--.slice", NULL, -EINVAL);
test_slice_to_path_one("-", NULL, -EINVAL);
test_slice_to_path_one("-foo-.slice", NULL, -EINVAL);

View file

@ -32,6 +32,7 @@
#include "manager.h"
#include "path-util.h"
#include "rm-rf.h"
#include "special.h"
#include "specifier.h"
#include "string-util.h"
#include "test-helper.h"
@ -338,7 +339,7 @@ static void test_unit_name_build(void) {
}
static void test_slice_name_is_valid(void) {
assert_se(slice_name_is_valid("-.slice"));
assert_se(slice_name_is_valid(SPECIAL_ROOT_SLICE));
assert_se(slice_name_is_valid("foo.slice"));
assert_se(slice_name_is_valid("foo-bar.slice"));
assert_se(slice_name_is_valid("foo-bar-baz.slice"));
@ -356,7 +357,7 @@ static void test_build_subslice(void) {
char *a;
char *b;
assert_se(slice_build_subslice("-.slice", "foo", &a) >= 0);
assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0);
assert_se(slice_build_subslice(a, "bar", &b) >= 0);
free(a);
assert_se(slice_build_subslice(b, "barfoo", &a) >= 0);
@ -378,8 +379,8 @@ static void test_build_parent_slice_one(const char *name, const char *expect, in
}
static void test_build_parent_slice(void) {
test_build_parent_slice_one("-.slice", NULL, 0);
test_build_parent_slice_one("foo.slice", "-.slice", 1);
test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0);
test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1);
test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1);
test_build_parent_slice_one("foo-bar-baz.slice", "foo-bar.slice", 1);
test_build_parent_slice_one("foo-bar--baz.slice", NULL, -EINVAL);

View file

@ -27,6 +27,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fstab-util.h"
#include "generator.h"
#include "hexdecoct.h"
#include "id128-util.h"
#include "mkdir.h"
@ -36,6 +37,8 @@
#include "string-util.h"
#include "unit-name.h"
#define SYSTEMD_VERITYSETUP_SERVICE "systemd-veritysetup@root.service"
static char *arg_dest = NULL;
static bool arg_enabled = true;
static char *arg_root_hash = NULL;
@ -45,7 +48,7 @@ static char *arg_hash_what = NULL;
static int create_device(void) {
_cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL;
_cleanup_fclose_ FILE *f = NULL;
const char *p, *to;
const char *to;
int r;
/* If all three pieces of information are missing, then verity is turned off */
@ -67,8 +70,6 @@ static int create_device(void) {
" hash device %s,\n"
" and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash);
p = strjoina(arg_dest, "/systemd-veritysetup@root.service");
u = fstab_node_to_udev_node(arg_data_what);
if (!u)
return log_oom();
@ -94,12 +95,11 @@ static int create_device(void) {
if (!root_hash_escaped)
return log_oom();
f = fopen(p, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", p);
r = generator_open_unit_file(arg_dest, NULL, SYSTEMD_VERITYSETUP_SERVICE, &f);
if (r < 0)
return r;
fprintf(f,
"# Automatically generated by systemd-veritysetup-generator\n\n"
"[Unit]\n"
"Description=Integrity Protection Setup for %%I\n"
"Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
@ -121,12 +121,12 @@ static int create_device(void) {
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 unit "SYSTEMD_VERITYSETUP_SERVICE": %m");
to = strjoina(arg_dest, "/cryptsetup.target.requires/systemd-veritysetup@root.service");
to = strjoina(arg_dest, "/cryptsetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE);
(void) mkdir_parents(to, 0755);
if (symlink("../systemd-veritysetup@root.service", to) < 0)
if (symlink("../" SYSTEMD_VERITYSETUP_SERVICE, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
return 0;