Пример #1
0
static int link_compatibility(const char *units) {
        const char *f, *t;

        f = strappenda(units, "/systemd-bus-proxyd.socket");
        t = strappenda(arg_dest, "/" SPECIAL_DBUS_SOCKET);
        mkdir_parents_label(t, 0755);
        if (symlink(f, t) < 0) {
                log_error("Failed to create symlink %s: %m", t);
                return -errno;
        }

        f = strappenda(units, "/systemd-bus-proxyd.socket");
        t = strappenda(arg_dest, "/" SPECIAL_SOCKETS_TARGET ".wants/systemd-bus-proxyd.socket");
        mkdir_parents_label(t, 0755);
        if (symlink(f, t) < 0) {
                log_error("Failed to create symlink %s: %m", t);
                return -errno;
        }

        t = strappenda(arg_dest, "/" SPECIAL_DBUS_SERVICE);
        if (symlink("/dev/null", t) < 0) {
                log_error("Failed to mask %s: %m", t);
                return -errno;
        }

        return 0;
}
Пример #2
0
static int tar_import_fork_tar(TarImport *i) {
        int r;

        assert(i);

        assert(!i->final_path);
        assert(!i->temp_path);
        assert(i->tar_fd < 0);

        i->final_path = strjoin(i->image_root, "/", i->local, NULL);
        if (!i->final_path)
                return log_oom();

        r = tempfn_random(i->final_path, &i->temp_path);
        if (r < 0)
                return log_oom();

        (void) mkdir_parents_label(i->temp_path, 0700);

        r = btrfs_subvol_make(i->temp_path);
        if (r == -ENOTTY) {
                if (mkdir(i->temp_path, 0755) < 0)
                        return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path);
        } else if (r < 0)
                return log_error_errno(errno, "Failed to create subvolume %s: %m", i->temp_path);

        i->tar_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
        if (i->tar_fd < 0)
                return i->tar_fd;

        return 0;
}
Пример #3
0
static int add_symlink(const char *service, const char *where) {
        _cleanup_free_ char *from = NULL, *to = NULL;
        int r;

        assert(service);
        assert(where);

        from = strjoin(SYSTEM_DATA_UNIT_PATH, "/", service, NULL);
        if (!from)
                return log_oom();

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

        mkdir_parents_label(to, 0755);

        r = symlink(from, to);
        if (r < 0) {
                if (errno == EEXIST)
                        return 0;

                log_error_errno(errno, "Failed to create symlink %s: %m", to);
                return -errno;
        }

        return 1;
}
Пример #4
0
static int raw_pull_job_on_open_disk_settings(PullJob *j) {
        RawPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->settings_job == j);
        assert(!i->settings_path);
        assert(!i->settings_temp_path);

        r = pull_make_path(j->url, j->etag, i->image_root, ".settings-", NULL, &i->settings_path);
        if (r < 0)
                return log_oom();

        r = tempfn_random(i->settings_path, NULL, &i->settings_temp_path);
        if (r < 0)
                return log_oom();

        mkdir_parents_label(i->settings_temp_path, 0700);

        j->disk_fd = open(i->settings_temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (j->disk_fd < 0)
                return log_error_errno(errno, "Failed to create %s: %m", i->settings_temp_path);

        return 0;
}
Пример #5
0
static int raw_pull_job_on_open_disk_raw(PullJob *j) {
        RawPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->raw_job == j);
        assert(!i->final_path);
        assert(!i->temp_path);

        r = pull_make_path(j->url, j->etag, i->image_root, ".raw-", ".raw", &i->final_path);
        if (r < 0)
                return log_oom();

        r = tempfn_random(i->final_path, NULL, &i->temp_path);
        if (r < 0)
                return log_oom();

        (void) mkdir_parents_label(i->temp_path, 0700);

        j->disk_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (j->disk_fd < 0)
                return log_error_errno(errno, "Failed to create %s: %m", i->temp_path);

        r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL);
        if (r < 0)
                log_warning_errno(errno, "Failed to set file attributes on %s: %m", i->temp_path);

        return 0;
}
Пример #6
0
static int raw_pull_job_on_open_disk_generic(
                RawPull *i,
                PullJob *j,
                const char *extra,
                char **temp_path) {

        int r;

        assert(i);
        assert(j);
        assert(extra);
        assert(temp_path);

        if (!*temp_path) {
                r = tempfn_random_child(i->image_root, extra, temp_path);
                if (r < 0)
                        return log_oom();
        }

        (void) mkdir_parents_label(*temp_path, 0700);

        j->disk_fd = open(*temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (j->disk_fd < 0)
                return log_error_errno(errno, "Failed to create %s: %m", *temp_path);

        return 0;
}
Пример #7
0
static int raw_import_open_disk(RawImport *i) {
        int r;

        assert(i);

        assert(!i->final_path);
        assert(!i->temp_path);
        assert(i->output_fd < 0);

        i->final_path = strjoin(i->image_root, "/", i->local, ".raw");
        if (!i->final_path)
                return log_oom();

        r = tempfn_random(i->final_path, NULL, &i->temp_path);
        if (r < 0)
                return log_oom();

        (void) mkdir_parents_label(i->temp_path, 0700);

        i->output_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (i->output_fd < 0)
                return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path);

        r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL);
        if (r < 0)
                log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path);

        return 0;
}
Пример #8
0
static int tar_pull_job_on_open_disk_tar(PullJob *j) {
        TarPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->tar_job == j);
        assert(i->tar_pid <= 0);

        if (!i->temp_path) {
                r = tempfn_random_child(i->image_root, "tar", &i->temp_path);
                if (r < 0)
                        return log_oom();
        }

        mkdir_parents_label(i->temp_path, 0700);

        r = btrfs_subvol_make(i->temp_path);
        if (r == -ENOTTY) {
                if (mkdir(i->temp_path, 0755) < 0)
                        return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path);
        } else if (r < 0)
                return log_error_errno(r, "Failed to create subvolume %s: %m", i->temp_path);
        else
                (void) import_assign_pool_quota_and_warn(i->temp_path);

        j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
        if (j->disk_fd < 0)
                return j->disk_fd;

        return 0;
}
Пример #9
0
static int add_symlink(const char *service, const char *where) {
        char *from = NULL, *to = NULL;
        int r;

        assert(service);

        asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
        asprintf(&to, "%s/%s.wants/%s", arg_dest, where, service);

        if (!from || !to) {
                r = log_oom();
                goto finish;
        }

        mkdir_parents_label(to, 0755);

        r = symlink(from, to);
        if (r < 0) {
                if (errno == EEXIST)
                        r = 0;
                else {
                        log_error("Failed to create symlink %s: %m", to);
                        r = -errno;
                }
        }

finish:
        free(from);
        free(to);

        return r;
}
Пример #10
0
static int add_symlink(const char *fservice, const char *tservice) {
        char *from = NULL, *to = NULL;
        int r;

        assert(fservice);
        assert(tservice);

        from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice);
        to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL);

        if (!from || !to) {
                r = log_oom();
                goto finish;
        }

        mkdir_parents_label(to, 0755);

        r = symlink(from, to);
        if (r < 0) {
                if (errno == EEXIST)
                        /* In case console=hvc0 is passed this will very likely result in EEXIST */
                        r = 0;
                else {
                        log_error("Failed to create symlink from %s to %s: %m", from, to);
                        r = -errno;
                }
        }

finish:

        free(from);
        free(to);

        return r;
}
Пример #11
0
static int write_data_x11(void) {
        FILE *f;
        char *temp_path;
        int r;

        if (isempty(state.x11_layout) &&
            isempty(state.x11_model) &&
            isempty(state.x11_variant) &&
            isempty(state.x11_options)) {

                if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        mkdir_parents_label("/etc/X11/xorg.conf.d", 0755);

        r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
        if (r < 0)
                return r;

        fchmod(fileno(f), 0644);

        fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
              "# manually too freely.\n"
              "Section \"InputClass\"\n"
              "        Identifier \"system-keyboard\"\n"
              "        MatchIsKeyboard \"on\"\n", f);

        if (!isempty(state.x11_layout))
                fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", state.x11_layout);

        if (!isempty(state.x11_model))
                fprintf(f, "        Option \"XkbModel\" \"%s\"\n", state.x11_model);

        if (!isempty(state.x11_variant))
                fprintf(f, "        Option \"XkbVariant\" \"%s\"\n", state.x11_variant);

        if (!isempty(state.x11_options))
                fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", state.x11_options);

        fputs("EndSection\n", f);
        fflush(f);

        if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
                r = -errno;
                unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
                unlink(temp_path);
        } else
                r = 0;

        fclose(f);
        free(temp_path);

        return r;
}
Пример #12
0
static int link_busnames_target(const char *units) {
        const char *f, *t;

        f = strjoina(units, "/" SPECIAL_BUSNAMES_TARGET);
        t = strjoina(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/" SPECIAL_BUSNAMES_TARGET);

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

        return 0;
}
static int generate_display_manager_alias(void) {

        _cleanup_free_ char *default_dm_path = NULL, *enabled_dm_unit = NULL;
        const char *default_dm = NULL, *in_mem_symlink = NULL, *target_unit_path = NULL;
        bool dm_service_exists = true;
        int r;

        r = read_full_file(default_dm_file, &default_dm_path, NULL);
        if (r < 0) {
                log_debug("No %s file, nothing to generate", default_dm_file);
                return 0;
        }
        default_dm = strstrip(basename(default_dm_path));

        r = readlink_value(dm_service_unit, &enabled_dm_unit);
        if (r < 0) {
                enabled_dm_unit = strdup("");
                dm_service_exists = false;
        }

        /* all is fine if the info matches */
        if (streq(strappenda(default_dm, ".service"), enabled_dm_unit))
                return 0;

        target_unit_path = strappenda(SYSTEM_DATA_UNIT_PATH, "/", default_dm, ".service");

        /* we only create the alias symlink for non sysvinit services */
        if (access(target_unit_path, F_OK) < 0 && (errno == ENOENT)) {
                /* if the dm service was already disabled, nothing to be done */
                if (!dm_service_exists) {
                        log_debug("No %s file, nothing to mask", dm_service_unit);
                        return 0;
                }
                log_warning("%s is not a systemd unit, we disable the systemd enabled display manager", target_unit_path);
                target_unit_path = "/dev/null";
        } else {
                log_warning("%s points at %s while the default systemd unit is %s. Reconfiguring %s as default.",
                            default_dm_file, default_dm, enabled_dm_unit, default_dm);
        }

        in_mem_symlink = strappenda(dest, "/display-manager.service");
        mkdir_parents_label(in_mem_symlink, 0755);
        if (symlink(target_unit_path, in_mem_symlink) < 0) {
                log_error("Failed to create symlink %s: %m", in_mem_symlink);
                return -errno;
        }

        return 0;
}
Пример #14
0
static int add_swap(const char *path) {
        _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
        _cleanup_fclose_ FILE *f = NULL;

        assert(path);

        log_debug("Adding swap: %s", path);

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

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

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

        fprintf(f,
                "# Automatically generated by systemd-gpt-auto-generator\n\n"
                "[Unit]\n"
                "Description=Swap Partition\n"
                "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
                "[Swap]\n"
                "What=%s\n",
                path);

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

        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;
}
Пример #15
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> */

        const char *from, *to;

        from = strjoina("../", src);
        to = strjoina(root, "/", dst, ".", dep_type, "/", src);

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

        return 0;
}
Пример #16
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;
}
Пример #17
0
int cg_create(const char *controller, const char *path, const char *suffix) {
    _cleanup_free_ char *fs = NULL;
    int r;

#ifdef HAVE_CGMANAGER
    /* CGManager support */
    int existed;
    if (cgm_dbus_connect()) {
        if (!controller) {
            cgm_dbus_disconnect();
            return -1;
        }

        r = cgm_create(normalize_controller(controller),
                       path, &existed);

        cgm_dbus_disconnect();

        if (!r)
            return -1;

        return 1;
    }
#endif

    r = cg_get_path_and_check(controller, path, suffix, &fs);
    if (r < 0)
        return r;

    r = mkdir_parents_label(fs, 0755);
    if (r < 0)
        return r;

    if (mkdir(fs, 0755) < 0) {

        if (errno == EEXIST)
            return 0;

        return -errno;
    }

    return 1;
}
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;
}
Пример #19
0
static int add_symlink(const char *service, const char *where) {
        const char *from, *to;
        int r;

        assert(service);
        assert(where);

        from = strjoina(SYSTEM_DATA_UNIT_PATH "/", service);
        to = strjoina(arg_dest, "/", where, ".wants/", service);

        (void) mkdir_parents_label(to, 0755);

        r = symlink(from, to);
        if (r < 0) {
                if (errno == EEXIST)
                        return 0;

                return log_error_errno(errno, "Failed to create symlink %s: %m", to);
        }

        return 1;
}
Пример #20
0
static int add_symlink(const char *fservice, const char *tservice) {
        char *from, *to;
        int r;

        assert(fservice);
        assert(tservice);

        from = strjoina(SYSTEM_DATA_UNIT_PATH "/", fservice);
        to = strjoina(arg_dest, "/getty.target.wants/", tservice);

        mkdir_parents_label(to, 0755);

        r = symlink(from, to);
        if (r < 0) {
                /* In case console=hvc0 is passed this will very likely result in EEXIST */
                if (errno == EEXIST)
                        return 0;

                return log_error_errno(errno, "Failed to create symlink %s: %m", to);
        }

        return 0;
}
Пример #21
0
static int dkr_pull_job_on_open_disk(PullJob *j) {
        const char *base;
        DkrPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->layer_job == j);
        assert(i->final_path);
        assert(!i->temp_path);
        assert(i->tar_pid <= 0);

        r = tempfn_random(i->final_path, &i->temp_path);
        if (r < 0)
                return log_oom();

        mkdir_parents_label(i->temp_path, 0700);

        base = dkr_pull_current_base_layer(i);
        if (base) {
                const char *base_path;

                base_path = strjoina(i->image_root, "/.dkr-", base);
                r = btrfs_subvol_snapshot(base_path, i->temp_path, BTRFS_SNAPSHOT_FALLBACK_COPY);
        } else
                r = btrfs_subvol_make(i->temp_path);
        if (r < 0)
                return log_error_errno(r, "Failed to make btrfs subvolume %s: %m", i->temp_path);

        j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
        if (j->disk_fd < 0)
                return j->disk_fd;

        return 0;
}
Пример #22
0
static int tar_pull_job_on_open_disk(PullJob *j) {
        TarPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->tar_job == j);
        assert(!i->final_path);
        assert(!i->temp_path);
        assert(i->tar_pid <= 0);

        r = pull_make_path(j->url, j->etag, i->image_root, ".tar-", NULL, &i->final_path);
        if (r < 0)
                return log_oom();

        r = tempfn_random(i->final_path, NULL, &i->temp_path);
        if (r < 0)
                return log_oom();

        mkdir_parents_label(i->temp_path, 0700);

        r = btrfs_subvol_make(i->temp_path);
        if (r == -ENOTTY) {
                if (mkdir(i->temp_path, 0755) < 0)
                        return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path);
        } else if (r < 0)
                return log_error_errno(errno, "Failed to create subvolume %s: %m", i->temp_path);

        j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
        if (j->disk_fd < 0)
                return j->disk_fd;

        return 0;
}
Пример #23
0
static int tar_pull_job_on_open_disk_settings(PullJob *j) {
        TarPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->settings_job == j);

        if (!i->settings_temp_path) {
                r = tempfn_random_child(i->image_root, "settings", &i->settings_temp_path);
                if (r < 0)
                        return log_oom();
        }

        mkdir_parents_label(i->settings_temp_path, 0700);

        j->disk_fd = open(i->settings_temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (j->disk_fd < 0)
                return log_error_errno(errno, "Failed to create %s: %m", i->settings_temp_path);

        return 0;
}
Пример #24
0
int main(int argc, char *argv[]) {
        _cleanup_close_ int seed_fd = -1, random_fd = -1;
        _cleanup_free_ void* buf = NULL;
        size_t buf_size = 0;
        ssize_t k;
        int r, open_rw_error;
        FILE *f;
        bool refresh_seed_file = true;

        if (argc != 2) {
                log_error("This program requires one argument.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        /* Read pool size, if possible */
        f = fopen("/proc/sys/kernel/random/poolsize", "re");
        if (f) {
                if (fscanf(f, "%zu", &buf_size) > 0)
                        /* poolsize is in bits on 2.6, but we want bytes */
                        buf_size /= 8;

                fclose(f);
        }

        if (buf_size <= POOL_SIZE_MIN)
                buf_size = POOL_SIZE_MIN;

        buf = malloc(buf_size);
        if (!buf) {
                r = log_oom();
                goto finish;
        }

        r = mkdir_parents_label(RANDOM_SEED, 0755);
        if (r < 0) {
                log_error_errno(r, "Failed to create directory " RANDOM_SEED_DIR ": %m");
                goto finish;
        }

        /* When we load the seed we read it and write it to the device
         * and then immediately update the saved seed with new data,
         * to make sure the next boot gets seeded differently. */

        if (streq(argv[1], "load")) {

                seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600);
                open_rw_error = -errno;
                if (seed_fd < 0) {
                        refresh_seed_file = false;

                        seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY);
                        if (seed_fd < 0) {
                                bool missing = errno == ENOENT;

                                log_full_errno(missing ? LOG_DEBUG : LOG_ERR,
                                               open_rw_error, "Failed to open " RANDOM_SEED " for writing: %m");
                                r = log_full_errno(missing ? LOG_DEBUG : LOG_ERR,
                                                   errno, "Failed to open " RANDOM_SEED " for reading: %m");
                                if (missing)
                                        r = 0;

                                goto finish;
                        }
                }

                random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
                if (random_fd < 0) {
                        random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600);
                        if (random_fd < 0) {
                                r = log_error_errno(errno, "Failed to open /dev/urandom: %m");
                                goto finish;
                        }
                }

                k = loop_read(seed_fd, buf, buf_size, false);
                if (k < 0)
                        r = log_error_errno(k, "Failed to read seed from " RANDOM_SEED ": %m");
                else if (k == 0) {
                        r = 0;
                        log_debug("Seed file " RANDOM_SEED " not yet initialized, proceeding.");
                } else {
                        (void) lseek(seed_fd, 0, SEEK_SET);

                        r = loop_write(random_fd, buf, (size_t) k, false);
                        if (r < 0)
                                log_error_errno(r, "Failed to write seed to /dev/urandom: %m");
                }

        } else if (streq(argv[1], "save")) {

                seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600);
                if (seed_fd < 0) {
                        r = log_error_errno(errno, "Failed to open " RANDOM_SEED ": %m");
                        goto finish;
                }

                random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
                if (random_fd < 0) {
                        r = log_error_errno(errno, "Failed to open /dev/urandom: %m");
                        goto finish;
                }

        } else {
                log_error("Unknown verb '%s'.", argv[1]);
                r = -EINVAL;
                goto finish;
        }

        if (refresh_seed_file) {

                /* This is just a safety measure. Given that we are root and
                 * most likely created the file ourselves the mode and owner
                 * should be correct anyway. */
                (void) fchmod(seed_fd, 0600);
                (void) fchown(seed_fd, 0, 0);

                k = loop_read(random_fd, buf, buf_size, false);
                if (k < 0) {
                        r = log_error_errno(k, "Failed to read new seed from /dev/urandom: %m");
                        goto finish;
                }
                if (k == 0) {
                        log_error("Got EOF while reading from /dev/urandom.");
                        r = -EIO;
                        goto finish;
                }

                r = loop_write(seed_fd, buf, (size_t) k, false);
                if (r < 0)
                        log_error_errno(r, "Failed to write new random seed file: %m");
        }

finish:
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
Пример #25
0
static int create_dbus_files(
                const char *path,
                const char *name,
                const char *service,
                const char *exec,
                const char *user,
                const char *type) {

        _cleanup_free_ char *b = NULL, *s = NULL, *lnk = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(path);
        assert(name);
        assert(service || exec);

        if (!service) {
                _cleanup_free_ char *a = NULL;

                s = strjoin("dbus-", name, ".service", NULL);
                if (!s)
                        return log_oom();

                a = strjoin(arg_dest_late, "/", s, NULL);
                if (!a)
                        return log_oom();

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

                fprintf(f,
                        "# Automatically generated by systemd-dbus1-generator\n\n"
                        "[Unit]\n"
                        "SourcePath=%s\n"
                        "Description=DBUS1: %s\n"
                        "Documentation=man:systemd-dbus1-generator(8)\n\n"
                        "[Service]\n"
                        "ExecStart=%s\n"
                        "Type=dbus\n"
                        "BusName=%s\n",
                        path,
                        name,
                        exec,
                        name);

                if (user)
                        fprintf(f, "User=%s\n", user);


                if (type) {
                        fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type);

                        if (streq(type, "system"))
                                fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_ADDRESS "\n");
                        else if (streq(type, "session")) {
                                char *run;

                                run = getenv("XDG_RUNTIME_DIR");
                                if (!run) {
                                        log_error("XDG_RUNTIME_DIR not set.");
                                        return -EINVAL;
                                }

                                fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT "\n",
                                        getuid(), run);
                        }
                }

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

                f = safe_fclose(f);

                service = s;
        }

        b = strjoin(arg_dest_late, "/", name, ".busname", NULL);
        if (!b)
                return log_oom();

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

        fprintf(f,
                "# Automatically generated by systemd-dbus1-generator\n\n"
                "[Unit]\n"
                "SourcePath=%s\n"
                "Description=DBUS1: %s\n"
                "Documentation=man:systemd-dbus1-generator(8)\n\n"
                "[BusName]\n"
                "Name=%s\n"
                "Service=%s\n"
                "AllowWorld=talk\n",
                path,
                name,
                name,
                service);

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

        lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL);
        if (!lnk)
                return log_oom();

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

        return 0;
}
Пример #26
0
static int add_swap(const char *what, struct mntent *me) {
        _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        bool noauto, nofail;
        int r, pri = -1;

        assert(what);
        assert(me);

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

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

        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;
        }

        fputs("# Automatically generated by systemd-fstab-generator\n\n"
              "[Unit]\n"
              "SourcePath=/etc/fstab\n"
              "DefaultDependencies=no\n"
              "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
              "Before=" SPECIAL_UMOUNT_TARGET "\n", f);

        if (!noauto && !nofail)
                fputs("Before=" SPECIAL_SWAP_TARGET "\n", f);

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

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

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

        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;
                }

                r = device_name(what, &device);
                if (r < 0)
                        return r;

                if (r > 0) {
                        free(lnk);
                        lnk = strjoin(arg_dest, "/", device, ".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;
}
Пример #27
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,
                bool isbind,
                const char *pre,
                const char *pre2,
                const char *online,
                const char *post,
                const char *source) {
        _cleanup_free_ char
                *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL,
                *automount_name = NULL, *automount_unit = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        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"
              "DefaultDependencies=no\n",
              source);

        if (!path_equal(where, "/")) {
                if (pre)
                        fprintf(f,
                                "After=%s\n",
                                pre);

                if (pre2)
                        fprintf(f,
                                "After=%s\n",
                                pre2);

                if (online)
                        fprintf(f,
                                "After=%s\n"
                                "Wants=%s\n",
                                online,
                                online);

                fprintf(f,
                        "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
                        "Before=" SPECIAL_UMOUNT_TARGET "\n");
        }

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

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

        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) {
                /* don't start network mounts automatically, we do that via ifupdown hooks for now */
                if (post && !streq(post, SPECIAL_REMOTE_FS_TARGET)) {
                        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 (!isbind &&
                    !path_equal(where, "/")) {

                        r = device_name(what, &device);
                        if (r < 0)
                                return r;

                        if (r > 0) {
                                free(lnk);
                                lnk = strjoin(arg_dest, "/", device, ".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;
                                }
                        }
                }
        }

        if (automount && !path_equal(where, "/")) {
                automount_name = unit_name_from_path(where, ".automount");
                if (!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"
                        "DefaultDependencies=no\n"
                        "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
                        "Before=" SPECIAL_UMOUNT_TARGET "\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;
}
Пример #28
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;
}
Пример #29
0
static int node_symlink(struct udev_device *dev, const char *node, const char *slink) {
        struct stat stats;
        char target[UTIL_PATH_SIZE];
        char *s;
        size_t l;
        char slink_tmp[UTIL_PATH_SIZE + 32];
        int i = 0;
        int tail = 0;
        int err = 0;

        /* use relative link */
        target[0] = '\0';
        while (node[i] && (node[i] == slink[i])) {
                if (node[i] == '/')
                        tail = i+1;
                i++;
        }
        s = target;
        l = sizeof(target);
        while (slink[i] != '\0') {
                if (slink[i] == '/')
                        l = strpcpy(&s, l, "../");
                i++;
        }
        l = strscpy(s, l, &node[tail]);
        if (l == 0) {
                err = -EINVAL;
                goto exit;
        }

        /* preserve link with correct target, do not replace node of other device */
        if (lstat(slink, &stats) == 0) {
                if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) {
                        log_error("conflicting device node '%s' found, link to '%s' will not be created", slink, node);
                        goto exit;
                } else if (S_ISLNK(stats.st_mode)) {
                        char buf[UTIL_PATH_SIZE];
                        int len;

                        len = readlink(slink, buf, sizeof(buf));
                        if (len > 0 && len < (int)sizeof(buf)) {
                                buf[len] = '\0';
                                if (streq(target, buf)) {
                                        log_debug("preserve already existing symlink '%s' to '%s'", slink, target);
                                        label_fix(slink, true, false);
                                        utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW);
                                        goto exit;
                                }
                        }
                }
        } else {
                log_debug("creating symlink '%s' to '%s'", slink, target);
                do {
                        err = mkdir_parents_label(slink, 0755);
                        if (err != 0 && err != -ENOENT)
                                break;
                        mac_selinux_create_file_prepare(slink, S_IFLNK);
                        err = symlink(target, slink);
                        if (err != 0)
                                err = -errno;
                        mac_selinux_create_file_clear();
                } while (err == -ENOENT);
                if (err == 0)
                        goto exit;
        }

        log_debug("atomically replace '%s'", slink);
        strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL);
        unlink(slink_tmp);
        do {
                err = mkdir_parents_label(slink_tmp, 0755);
                if (err != 0 && err != -ENOENT)
                        break;
                mac_selinux_create_file_prepare(slink_tmp, S_IFLNK);
                err = symlink(target, slink_tmp);
                if (err != 0)
                        err = -errno;
                mac_selinux_create_file_clear();
        } while (err == -ENOENT);
        if (err != 0) {
                log_error_errno(errno, "symlink '%s' '%s' failed: %m", target, slink_tmp);
                goto exit;
        }
        err = rename(slink_tmp, slink);
        if (err != 0) {
                log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink);
                unlink(slink_tmp);
        }
exit:
        return err;
}
Пример #30
0
static int node_symlink(sd_device *dev, const char *node, const char *slink) {
        _cleanup_free_ char *slink_dirname = NULL, *target = NULL;
        const char *id_filename, *slink_tmp;
        struct stat stats;
        int r;

        assert(dev);
        assert(node);
        assert(slink);

        slink_dirname = dirname_malloc(slink);
        if (!slink_dirname)
                return log_oom();

        /* use relative link */
        r = path_make_relative(slink_dirname, node, &target);
        if (r < 0)
                return log_device_error_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, node);

        /* preserve link with correct target, do not replace node of other device */
        if (lstat(slink, &stats) == 0) {
                if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) {
                        log_device_error(dev, "Conflicting device node '%s' found, link to '%s' will not be created.", slink, node);
                        return -EOPNOTSUPP;
                } else if (S_ISLNK(stats.st_mode)) {
                        _cleanup_free_ char *buf = NULL;

                        if (readlink_malloc(slink, &buf) >= 0 &&
                            streq(target, buf)) {
                                log_device_debug(dev, "Preserve already existing symlink '%s' to '%s'", slink, target);
                                (void) label_fix(slink, LABEL_IGNORE_ENOENT);
                                (void) utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW);
                                return 0;
                        }
                }
        } else {
                log_device_debug(dev, "Creating symlink '%s' to '%s'", slink, target);
                do {
                        r = mkdir_parents_label(slink, 0755);
                        if (!IN_SET(r, 0, -ENOENT))
                                break;
                        mac_selinux_create_file_prepare(slink, S_IFLNK);
                        if (symlink(target, slink) < 0)
                                r = -errno;
                        mac_selinux_create_file_clear();
                } while (r == -ENOENT);
                if (r == 0)
                        return 0;
                if (r < 0)
                        log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s', trying to replace '%s': %m", slink, target, slink);
        }

        log_device_debug(dev, "Atomically replace '%s'", slink);
        r = device_get_id_filename(dev, &id_filename);
        if (r < 0)
                return log_device_error_errno(dev, r, "Failed to get id_filename: %m");
        slink_tmp = strjoina(slink, ".tmp-", id_filename);
        (void) unlink(slink_tmp);
        do {
                r = mkdir_parents_label(slink_tmp, 0755);
                if (!IN_SET(r, 0, -ENOENT))
                        break;
                mac_selinux_create_file_prepare(slink_tmp, S_IFLNK);
                if (symlink(target, slink_tmp) < 0)
                        r = -errno;
                mac_selinux_create_file_clear();
        } while (r == -ENOENT);
        if (r < 0)
                return log_device_error_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target);

        if (rename(slink_tmp, slink) < 0) {
                r = log_device_error_errno(dev, errno, "Failed to rename '%s' to '%s' failed: %m", slink_tmp, slink);
                (void) unlink(slink_tmp);
        }

        return r;
}