Example #1
0
int generator_hook_up_growfs(
                const char *dir,
                const char *where,
                const char *target) {

        _cleanup_free_ char *unit = NULL, *escaped = NULL, *where_unit = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        const char *unit_file;
        int r;

        escaped = cescape(where);
        if (!escaped)
                return log_oom();

        r = unit_name_from_path_instance("systemd-growfs", where, ".service", &unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
                                       where);

        r = unit_name_from_path(where, ".mount", &where_unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
                                       where);

        unit_file = strjoina(dir, "/", unit);
        log_debug("Creating %s", unit_file);

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

        fprintf(f,
                "# Automatically generated by %s\n\n"
                "[Unit]\n"
                "Description=Grow File System on %%f\n"
                "Documentation=man:[email protected](8)\n"
                "DefaultDependencies=no\n"
                "BindsTo=%%i.mount\n"
                "After=%%i.mount\n"
                "Before=shutdown.target\n"
                "Before=%s\n"
                "\n"
                "[Service]\n"
                "Type=oneshot\n"
                "RemainAfterExit=yes\n"
                "ExecStart="SYSTEMD_GROWFS_PATH " %s\n"
                "TimeoutSec=0\n",
                program_invocation_short_name,
                target,
                escaped);

        return generator_add_symlink(dir, where_unit, "wants", unit);
}
Example #2
0
static int add_container_getty(const char *tty) {
        _cleanup_free_ char *n = NULL;
        int r;

        assert(tty);

        log_debug("Automatically adding container getty for /dev/pts/%s.", tty);

        r = unit_name_from_path_instance("container-getty", tty, ".service", &n);
        if (r < 0)
                return log_error_errno(r, "Failed to generate service name: %m");

        return add_symlink("[email protected]", n);
}
Example #3
0
static void test_u_n_f_p_i_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) {
        _cleanup_free_ char *t = NULL;

        assert_se(unit_name_from_path_instance(pattern, path, suffix, &t) == ret);
        puts(strna(t));
        assert_se(streq_ptr(t, expected));

        if (t) {
                _cleanup_free_ char *k = NULL, *v = NULL;

                assert_se(unit_name_to_instance(t, &k) > 0);
                assert_se(unit_name_path_unescape(k, &v) == 0);
                assert_se(path_equal(v, isempty(path) ? "/" : path));
        }
}
Example #4
0
static int add_fsck(FILE *f, const char *what, const char *where, const char *type, int passno) {
        assert(f);

        if (passno == 0)
                return 0;

        if (type && !streq(type, "auto")) {
                int r;
                const char *checker;

                checker = strappenda("/sbin/fsck.", type);
                r = access(checker, X_OK);
                if (r < 0) {
                        log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker);

                        /* treat missing check as essentially OK */
                        return errno == ENOENT ? 0 : -errno;
                }
        }

        if (streq(where, "/")) {
                char *lnk;

                lnk = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
                mkdir_parents_label(lnk, 0755);
                if (symlink("systemd-fsck-root.service", lnk) < 0) {
                        log_error("Failed to create symlink %s: %m", lnk);
                        return -errno;
                }
        } else {
                _cleanup_free_ char *fsck = NULL;

                fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
                if (!fsck)
                        return log_oom();

                fprintf(f,
                        "RequiresOverridable=%s\n"
                        "After=%s\n",
                        fsck,
                        fsck);
        }

        return 0;
}
static int process_resume(void) {
    _cleanup_free_ char *name = NULL, *lnk = NULL;

    if (!arg_resume_dev)
        return 0;

    name = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_dev, ".service");
    if (!name)
        return log_oom();

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

    mkdir_parents_label(lnk, 0755);
    if (symlink(SYSTEM_DATA_UNIT_PATH "/[email protected]", lnk) < 0)
        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);

    return 0;
}
Example #6
0
int generator_hook_up_mkfs(
                const char *dir,
                const char *what,
                const char *where,
                const char *type) {

        _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        const char *unit_file;
        int r;

        node = fstab_node_to_udev_node(what);
        if (!node)
                return log_oom();

        /* Nothing to work on. */
        if (!is_device_path(node)) {
                log_error("Cannot format something that is not a device node: %s", node);
                return -EINVAL;
        }

        if (!type || streq(type, "auto")) {
                log_error("Cannot format partition %s, filesystem type is not specified", node);
                return -EINVAL;
        }

        r = unit_name_from_path_instance("systemd-mkfs", node, ".service", &unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
                                       node);

        unit_file = strjoina(dir, "/", unit);
        log_debug("Creating %s", unit_file);

        escaped = cescape(node);
        if (!escaped)
                return log_oom();

        r = unit_name_from_path(where, ".mount", &where_unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
                                       where);

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

        fprintf(f,
                "# Automatically generated by %s\n\n"
                "[Unit]\n"
                "Description=Make File System on %%f\n"
                "Documentation=man:[email protected](8)\n"
                "DefaultDependencies=no\n"
                "BindsTo=%%i.device\n"
                "After=%%i.device\n"
                /* fsck might or might not be used, so let's be safe and order
                 * ourselves before both [email protected] and the mount unit. */
                "Before=systemd-fsck@%%i.service\n"
                "Before=%s\n"
                "Before=shutdown.target\n"
                "\n"
                "[Service]\n"
                "Type=oneshot\n"
                "RemainAfterExit=yes\n"
                "ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
                "TimeoutSec=0\n",
                program_invocation_short_name,
                where_unit,
                type,
                escaped);
        // XXX: what about local-fs-pre.target?

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

        return generator_add_symlink(dir, where_unit, "requires", unit);
}
Example #7
0
int generator_hook_up_mkswap(
                const char *dir,
                const char *what) {

        _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        const char *unit_file;
        int r;

        node = fstab_node_to_udev_node(what);
        if (!node)
                return log_oom();

        /* Nothing to work on. */
        if (!is_device_path(node)) {
                log_error("Cannot format something that is not a device node: %s", node);
                return -EINVAL;
        }

        r = unit_name_from_path_instance("systemd-mkswap", node, ".service", &unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
                                       node);

        unit_file = strjoina(dir, "/", unit);
        log_debug("Creating %s", unit_file);

        escaped = cescape(node);
        if (!escaped)
                return log_oom();

        r = unit_name_from_path(what, ".swap", &where_unit);
        if (r < 0)
                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
                                       what);

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

        fprintf(f,
                "# Automatically generated by %s\n\n"
                "[Unit]\n"
                "Description=Make Swap on %%f\n"
                "Documentation=man:[email protected](8)\n"
                "DefaultDependencies=no\n"
                "BindsTo=%%i.device\n"
                "After=%%i.device\n"
                "Before=%s\n"
                "Before=shutdown.target\n"
                "\n"
                "[Service]\n"
                "Type=oneshot\n"
                "RemainAfterExit=yes\n"
                "ExecStart="SYSTEMD_MAKEFS_PATH " swap %s\n"
                "TimeoutSec=0\n",
                program_invocation_short_name,
                where_unit,
                escaped);

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

        return generator_add_symlink(dir, where_unit, "requires", unit);
}
Example #8
0
int generator_write_fsck_deps(
                FILE *f,
                const char *dir,
                const char *what,
                const char *where,
                const char *fstype) {

        int r;

        assert(f);
        assert(dir);
        assert(what);
        assert(where);

        if (!is_device_path(what)) {
                log_warning("Checking was requested for \"%s\", but it is not a device.", what);
                return 0;
        }

        if (!isempty(fstype) && !streq(fstype, "auto")) {
                r = fsck_exists(fstype);
                if (r < 0)
                        log_warning_errno(r, "Checking was requested for %s, but couldn't detect if fsck.%s may be used, proceeding: %m", what, fstype);
                else if (r == 0) {
                        /* treat missing check as essentially OK */
                        log_debug("Checking was requested for %s, but fsck.%s does not exist.", what, fstype);
                        return 0;
                }
        }

        if (path_equal(where, "/")) {
                const char *lnk;

                lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");

                mkdir_parents(lnk, 0755);
                if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);

        } else {
                _cleanup_free_ char *_fsck = NULL;
                const char *fsck;

                if (in_initrd() && path_equal(where, "/sysroot")) {
                        r = write_fsck_sysroot_service(dir, what);
                        if (r < 0)
                                return r;

                        fsck = "systemd-fsck-root.service";
                } else {
                        r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
                        if (r < 0)
                                return log_error_errno(r, "Failed to create fsck service name: %m");

                        fsck = _fsck;
                }

                fprintf(f,
                        "Requires=%1$s\n"
                        "After=%1$s\n",
                        fsck);
        }

        return 0;
}
Example #9
0
static int add_mount(
                const char *what,
                const char *where,
                const char *type,
                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;
        _cleanup_fclose_ FILE *f = NULL;

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

        if (streq(type, "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;

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

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

        if (passno > 0) {
                if (streq(where, "/")) {
                        lnk = strjoin(arg_dest, "/", SPECIAL_LOCAL_FS_TARGET, ".wants/", "systemd-fsck-root.service", NULL);
                        if (!lnk)
                                return log_oom();

                        mkdir_parents_label(lnk, 0755);
                        if (symlink("systemd-fsck-root.service", lnk) < 0) {
                                log_error("Failed to create symlink %s: %m", lnk);
                                return -errno;
                        }
                } else {
                        _cleanup_free_ char *fsck = NULL;

                        fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
                        if (!fsck)
                                return log_oom();

                        fprintf(f,
                                "Requires=%s\n"
                                "After=%s\n",
                                fsck,
                                fsck);
                }
        }


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

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

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

        if (!noauto) {
                if (post) {
                        free(lnk);
                        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) {
                                log_error("Failed to create symlink %s: %m", lnk);
                                return -errno;
                        }
                }
        }

        if (automount && !path_equal(where, "/")) {
                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) {
                        log_error("Failed to create unit file %s: %m", automount_unit);
                        return -errno;
                }

                fprintf(f,
                        "# Automatically generated by systemd-fstab-generator\n\n"
                        "[Unit]\n"
                        "SourcePath=%s\n",
                        source);

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

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

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

                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) {
                        log_error("Failed to create symlink %s: %m", lnk);
                        return -errno;
                }
        }

        return 0;
}
Example #10
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, *from = NULL, *to = NULL, *e = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        bool noauto, nofail, tmp, swap;

        assert(name);
        assert(device);

        noauto = has_option(options, "noauto");
        nofail = has_option(options, "nofail");
        tmp = has_option(options, "tmp");
        swap = has_option(options, "swap");

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

        n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
        if (!n)
                return log_oom();

        p = strjoin(arg_dest, "/", n, NULL);
        if (!p)
                return log_oom();

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

        d = unit_name_from_path(u, ".device");
        if (!d)
                return log_oom();

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

        fputs(
                "# Automatically generated by systemd-cryptsetup-generator\n\n"
                "[Unit]\n"
                "Description=Cryptography Setup for %I\n"
                "Documentation=man:[email protected](8) man:crypttab(5)\n"
                "SourcePath=/etc/crypttab\n"
                "Conflicts=umount.target\n"
                "DefaultDependencies=no\n"
                "BindsTo=dev-mapper-%i.device\n"
                "IgnoreOnIsolate=true\n"
                "After=systemd-readahead-collect.service systemd-readahead-replay.service\n",
                f);

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

        if (password) {
                if (streq(password, "/dev/urandom") ||
                    streq(password, "/dev/random") ||
                    streq(password, "/dev/hw_random"))
                        fputs("After=systemd-random-seed.service\n", f);
                else if (!streq(password, "-") &&
                         !streq(password, "none"))
                        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);

        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(options),
                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);

        fflush(f);

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

        if (asprintf(&from, "../%s", n) < 0)
                return log_oom();

        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) {
                        log_error("Failed to create symlink %s: %m", to);
                        return -errno;
                }

                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) {
                        log_error("Failed to create symlink %s: %m", to);
                        return -errno;
                }
        }

        e = unit_name_escape(name);
        if (!e)
                return log_oom();

        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) {
                log_error("Failed to create symlink %s: %m", to);
                return -errno;
        }

        if (!noauto && !nofail) {
                int r;
                free(p);
                p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
                if (!p)
                        return log_oom();

                mkdir_parents_label(p, 0755);

                r = write_string_file(p,
                                "# Automatically generated by systemd-cryptsetup-generator\n\n"
                                "[Unit]\n"
                                "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
                if (r)
                        return r;
        }

        return 0;
}