static int add_swap(
                const char *what,
                struct mntent *me,
                bool noauto,
                bool nofail) {

        _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *filtered = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r, pri = -1;
        const char *opts;

        assert(what);
        assert(me);

        if (access("/proc/swaps", F_OK) < 0) {
                log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        if (detect_container(NULL) > 0) {
                log_info("Running in a container, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        opts = me->mnt_opts;
        r = fstab_find_pri(opts, &pri);
        if (r < 0) {
                log_error_errno(r, "Failed to parse priority, ignoring: %m");

                /* Remove invalid pri field */
                r = fstab_filter_options(opts, "pri\0", NULL, NULL, &filtered);
                if (r < 0)
                        return log_error_errno(r, "Failed to parse options: %m");
                opts = filtered;
        }

        name = unit_name_from_path(what, ".swap");
        if (!name)
                return log_oom();

        unit = strjoin(arg_dest, "/", name, NULL);
        if (!unit)
                return log_oom();

        f = fopen(unit, "wxe");
        if (!f) {
                if (errno == EEXIST)
                        log_error("Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
                else
                        log_error_errno(errno, "Failed to create unit file %s: %m", unit);
                return -errno;
        }

        fprintf(f,
                "# Automatically generated by systemd-fstab-generator\n\n"
                "[Unit]\n"
                "SourcePath=/etc/fstab\n"
                "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
                "[Swap]\n"
                "What=%s\n",
                what);

        /* Note that we currently pass the priority field twice, once
         * in Priority=, and once in Options= */
        if (pri >= 0)
                fprintf(f, "Priority=%i\n", pri);

        if (!isempty(opts) && !streq(opts, "defaults"))
                fprintf(f, "Options=%s\n", opts);

        r = fflush_and_check(f);
        if (r < 0)
                return log_error_errno(r, "Failed to write unit file %s: %m", unit);

        /* use what as where, to have a nicer error message */
        r = generator_write_timeouts(arg_dest, what, what, opts, NULL);
        if (r < 0)
                return r;

        if (!noauto) {
                lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET,
                              nofail ? ".wants/" : ".requires/", name, NULL);
                if (!lnk)
                        return log_oom();

                mkdir_parents_label(lnk, 0755);
                if (symlink(unit, lnk) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
        }

        return 0;
}
示例#2
0
static int add_swap(
    const char *what,
    struct mntent *me,
    bool noauto,
    bool nofail) {

    _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
    _cleanup_fclose_ FILE *f = NULL;
    int r;

    assert(what);
    assert(me);

    if (access("/proc/swaps", F_OK) < 0) {
        log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
        return 0;
    }

    if (detect_container() > 0) {
        log_info("Running in a container, ignoring fstab swap entry for %s.", what);
        return 0;
    }

    r = unit_name_from_path(what, ".swap", &name);
    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);

    fprintf(f,
            "# Automatically generated by systemd-fstab-generator\n\n"
            "[Unit]\n"
            "SourcePath=/etc/fstab\n"
            "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
            "[Swap]\n"
            "What=%s\n",
            what);

    if (!isempty(me->mnt_opts) && !streq(me->mnt_opts, "defaults"))
        fprintf(f, "Options=%s\n", me->mnt_opts);

    r = fflush_and_check(f);
    if (r < 0)
        return log_error_errno(r, "Failed to write unit file %s: %m", unit);

    /* use what as where, to have a nicer error message */
    r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
    if (r < 0)
        return r;

    if (!noauto) {
        lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET,
                      nofail ? ".wants/" : ".requires/", name, NULL);
        if (!lnk)
            return log_oom();

        mkdir_parents_label(lnk, 0755);
        if (symlink(unit, lnk) < 0)
            return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
    }

    return 0;
}
static int add_mount(
                const char *what,
                const char *where,
                const char *fstype,
                const char *opts,
                int passno,
                bool noauto,
                bool nofail,
                bool automount,
                const char *post,
                const char *source) {

        _cleanup_free_ char
                *name = NULL, *unit = NULL, *lnk = NULL,
                *automount_name = NULL, *automount_unit = NULL,
                *filtered = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(what);
        assert(where);
        assert(opts);
        assert(source);

        if (streq_ptr(fstype, "autofs"))
                return 0;

        if (!is_path(where)) {
                log_warning("Mount point %s is not a valid path, ignoring.", where);
                return 0;
        }

        if (mount_point_is_api(where) ||
            mount_point_ignore(where))
                return 0;

        if (path_equal(where, "/")) {
                /* The root disk is not an option */
                automount = false;
                noauto = false;
                nofail = false;
        }

        name = unit_name_from_path(where, ".mount");
        if (!name)
                return log_oom();

        unit = strjoin(arg_dest, "/", name, NULL);
        if (!unit)
                return log_oom();

        f = fopen(unit, "wxe");
        if (!f) {
                if (errno == EEXIST)
                        log_error("Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
                else
                        log_error_errno(errno, "Failed to create unit file %s: %m", unit);
                return -errno;
        }

        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",
                source);

        if (post && !noauto && !nofail && !automount)
                fprintf(f, "Before=%s\n", post);

        if (passno != 0) {
                r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
                if (r < 0)
                        return r;
        }

        fprintf(f,
                "\n"
                "[Mount]\n"
                "What=%s\n"
                "Where=%s\n",
                what,
                where);

        if (!isempty(fstype) && !streq(fstype, "auto"))
                fprintf(f, "Type=%s\n", fstype);

        r = generator_write_timeouts(arg_dest, what, where, opts, &filtered);
        if (r < 0)
                return r;

        if (!isempty(filtered) && !streq(filtered, "defaults"))
                fprintf(f, "Options=%s\n", filtered);

        fflush(f);
        if (ferror(f))
                return log_error_errno(errno, "Failed to write unit file %s: %m", unit);

        if (!noauto && post) {
                lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
                if (!lnk)
                        return log_oom();

                mkdir_parents_label(lnk, 0755);
                if (symlink(unit, lnk) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
        }

        if (automount) {
                automount_name = unit_name_from_path(where, ".automount");
                if (!automount_name)
                        return log_oom();

                automount_unit = strjoin(arg_dest, "/", automount_name, NULL);
                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);

                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",
                        source);

                if (post)
                        fprintf(f,
                                "Before=%s\n",
                                post);

                fprintf(f,
                        "[Automount]\n"
                        "Where=%s\n",
                        where);

                fflush(f);
                if (ferror(f))
                        return log_error_errno(errno, "Failed to write unit file %s: %m", automount_unit);

                free(lnk);
                lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
                if (!lnk)
                        return log_oom();

                mkdir_parents_label(lnk, 0755);
                if (symlink(automount_unit, lnk) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
        }

        return 0;
}
示例#4
0
static int create_disk(
                const char *name,
                const char *device,
                const char *password,
                const char *options) {

        _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;
        char *from;
        int r;

        assert(name);
        assert(device);

        noauto = fstab_test_yes_no_option(options, "noauto\0" "auto\0");
        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");

        if (tmp && swap) {
                log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name);
                return -EINVAL;
        }

        e = unit_name_escape(name);
        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, NULL);
        if (!p)
                return log_oom();

        u = fstab_node_to_udev_node(device);
        if (!u)
                return log_oom();

        r = unit_name_from_path(u, ".device", &d);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");

        f = fopen(p, "wxe");
        if (!f)
                return log_error_errno(errno, "Failed to create unit file %s: %m", p);

        fputs(
                "# 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:[email protected](8)\n"
                "SourcePath=/etc/crypttab\n"
                "DefaultDependencies=no\n"
                "Conflicts=umount.target\n"
                "BindsTo=dev-mapper-%i.device\n"
                "IgnoreOnIsolate=true\n"
                "After=cryptsetup-pre.target\n",
                f);

        if (!nofail)
                fprintf(f,
                        "Before=cryptsetup.target\n");

        if (password) {
                if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
                        fputs("After=systemd-random-seed.service\n", f);
                else if (!streq(password, "-") && !streq(password, "none")) {
                        _cleanup_free_ char *uu;

                        uu = fstab_node_to_udev_node(password);
                        if (!uu)
                                return log_oom();

                        if (!path_equal(uu, "/dev/null")) {

                                if (is_device_path(uu)) {
                                        _cleanup_free_ char *dd = NULL;

                                        r = unit_name_from_path(uu, ".device", &dd);
                                        if (r < 0)
                                                return log_error_errno(r, "Failed to generate unit name: %m");

                                        fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
                                } else
                                        fprintf(f, "RequiresMountsFor=%s\n", password);
                        }
                }
        }

        if (is_device_path(u))
                fprintf(f,
                        "BindsTo=%s\n"
                        "After=%s\n"
                        "Before=umount.target\n",
                        d, d);
        else
                fprintf(f,
                        "RequiresMountsFor=%s\n",
                        u);

        r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
        if (r < 0)
                return r;

        fprintf(f,
                "\n[Service]\n"
                "Type=oneshot\n"
                "RemainAfterExit=yes\n"
                "TimeoutSec=0\n" /* the binary handles timeouts anyway */
                "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
                "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
                name, u, strempty(password), strempty(filtered),
                name);

        if (tmp)
                fprintf(f,
                        "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
                        name);

        if (swap)
                fprintf(f,
                        "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
                        name);

        r = fflush_and_check(f);
        if (r < 0)
                return log_error_errno(r, "Failed to write file %s: %m", p);

        from = strjoina("../", n);

        if (!noauto) {

                to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
                if (!to)
                        return log_oom();

                mkdir_parents_label(to, 0755);
                if (symlink(from, to) < 0)
                        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 (!to)
                        return log_oom();

                mkdir_parents_label(to, 0755);
                if (symlink(from, to) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", to);
        }

        free(to);
        to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
        if (!to)
                return log_oom();

        mkdir_parents_label(to, 0755);
        if (symlink(from, to) < 0)
                return log_error_errno(errno, "Failed to create symlink %s: %m", to);

        if (!noauto && !nofail) {
                _cleanup_free_ char *dmname;
                dmname = strjoin("dev-mapper-", e, ".device", NULL);
                if (!dmname)
                        return log_oom();

                r = write_drop_in(arg_dest, dmname, 90, "device-timeout",
                                  "# Automatically generated by systemd-cryptsetup-generator \n\n"
                                  "[Unit]\nJobTimeoutSec=0");
                if (r < 0)
                        return log_error_errno(r, "Failed to write device drop-in: %m");
        }

        return 0;
}
示例#5
0
static int add_swap(const char *what, struct mntent *me) {
        _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_free_ char *discard = NULL;

        bool noauto;
        int r, pri = -1;

        assert(what);
        assert(me);

        if (detect_container(NULL) > 0) {
                log_info("Running in a container, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        r = mount_find_pri(me, &pri);
        if (r < 0) {
                log_error("Failed to parse priority");
                return r;
        }

        r = mount_find_discard(me, &discard);
        if (r < 0) {
                log_error("Failed to parse discard");
                return r;
        }

        noauto = !!hasmntopt(me, "noauto");

        name = unit_name_from_path(what, ".swap");
        if (!name)
                return log_oom();

        unit = strjoin(arg_dest, "/", name, NULL);
        if (!unit)
                return log_oom();

        f = fopen(unit, "wxe");
        if (!f) {
                if (errno == EEXIST)
                        log_error("Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
                else
                        log_error("Failed to create unit file %s: %m", unit);
                return -errno;
        }

        fprintf(f,
                "# Automatically generated by systemd-fstab-generator\n\n"
                "[Unit]\n"
                "SourcePath=/etc/fstab\n"
                "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
                "[Swap]\n"
                "What=%s\n",
                what);

        if (pri >= 0)
                fprintf(f, "Priority=%i\n", pri);

        if (discard)
                fprintf(f, "Discard=%s\n", discard);

        fflush(f);
        if (ferror(f)) {
                log_error("Failed to write unit file %s: %m", unit);
                return -errno;
        }

        /* use what as where, to have a nicer error message */
        r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
        if (r < 0)
                return r;

        if (!noauto) {
                lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
                if (!lnk)
                        return log_oom();

                mkdir_parents_label(lnk, 0755);
                if (symlink(unit, lnk) < 0) {
                        log_error("Failed to create symlink %s: %m", lnk);
                        return -errno;
                }
        }

        return 0;
}
示例#6
0
static int add_swap(
                const char *what,
                struct mntent *me,
                MountpointFlags flags) {

        _cleanup_free_ char *name = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(what);
        assert(me);

        if (access("/proc/swaps", F_OK) < 0) {
                log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        if (detect_container() > 0) {
                log_info("Running in a container, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        r = unit_name_from_path(what, ".swap", &name);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");

        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"
              "SourcePath=/etc/fstab\n"
              "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
              "[Swap]\n", f);

        r = write_what(f, what);
        if (r < 0)
                return r;

        r = write_options(f, me->mnt_opts);
        if (r < 0)
                return r;

        r = fflush_and_check(f);
        if (r < 0)
                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);
        if (r < 0)
                return r;

        if (flags & MAKEFS) {
                r = generator_hook_up_mkswap(arg_dest, what);
                if (r < 0)
                        return r;
        }

        if (flags & GROWFS)
                /* TODO: swap devices must be wiped and recreated */
                log_warning("%s: growing swap devices is currently unsupported.", what);

        if (!(flags & NOAUTO)) {
                r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
                                          (flags & NOFAIL) ? "wants" : "requires", name);
                if (r < 0)
                        return r;
        }

        return 0;
}
示例#7
0
static int create_disk(
                const char *name,
                const char *device,
                const char *password,
                const char *options) {

        _cleanup_free_ char *p = NULL, *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;
        bool noauto, nofail, tmp, swap, netdev;
        int r;

        assert(name);
        assert(device);

        noauto = fstab_test_yes_no_option(options, "noauto\0" "auto\0");
        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);
                return -EINVAL;
        }

        name_escaped = specifier_escape(name);
        if (!name_escaped)
                return log_oom();

        e = unit_name_escape(name);
        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();

        u_escaped = specifier_escape(u);
        if (!u_escaped)
                return log_oom();

        r = unit_name_from_path(u, ".device", &d);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");

        password_escaped = specifier_escape(password);
        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);

        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:[email protected](8)\n"
                "SourcePath=/etc/crypttab\n"
                "DefaultDependencies=no\n"
                "Conflicts=umount.target\n"
                "IgnoreOnIsolate=true\n"
                "After=%s\n",
                netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");

        if (!nofail)
                fprintf(f,
                        "Before=%s\n",
                        netdev ? "remote-cryptsetup.target" : "cryptsetup.target");

        if (password) {
                if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
                        fputs_unlocked("After=systemd-random-seed.service\n", f);
                else if (!STR_IN_SET(password, "-", "none")) {
                        _cleanup_free_ char *uu;

                        uu = fstab_node_to_udev_node(password);
                        if (!uu)
                                return log_oom();

                        if (!path_equal(uu, "/dev/null")) {

                                if (path_startswith(uu, "/dev/")) {
                                        _cleanup_free_ char *dd = NULL;

                                        r = unit_name_from_path(uu, ".device", &dd);
                                        if (r < 0)
                                                return log_error_errno(r, "Failed to generate unit name: %m");

                                        fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
                                } else
                                        fprintf(f, "RequiresMountsFor=%s\n", password_escaped);
                        }
                }
        }

        if (path_startswith(u, "/dev/")) {
                fprintf(f,
                        "BindsTo=%s\n"
                        "After=%s\n"
                        "Before=umount.target\n",
                        d, d);

                if (swap)
                        fputs_unlocked("Before=dev-mapper-%i.swap\n",
                                       f);
        } else
                fprintf(f,
                        "RequiresMountsFor=%s\n",
                        u_escaped);


        r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
        if (r < 0)
                return r;

        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 */
                "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)
                fprintf(f,
                        "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
                        name_escaped);

        if (swap)
                fprintf(f,
                        "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
                        name_escaped);

        r = fflush_and_check(f);
        if (r < 0)
                return log_error_errno(r, "Failed to write file %s: %m", p);

        if (!noauto) {
                r = generator_add_symlink(arg_dest, d, "wants", n);
                if (r < 0)
                        return r;

                r = generator_add_symlink(arg_dest,
                                          netdev ? "remote-cryptsetup.target" : "cryptsetup.target",
                                          nofail ? "wants" : "requires", n);
                if (r < 0)
                        return r;
        }

        dmname = strjoina("dev-mapper-", e, ".device");
        r = generator_add_symlink(arg_dest, dmname, "requires", n);
        if (r < 0)
                return r;

        if (!noauto && !nofail) {
                r = write_drop_in(arg_dest, dmname, 90, "device-timeout",
                                  "# Automatically generated by systemd-cryptsetup-generator \n\n"
                                  "[Unit]\nJobTimeoutSec=0");
                if (r < 0)
                        return log_error_errno(r, "Failed to write device drop-in: %m");
        }

        return 0;
}