Ejemplo n.º 1
0
static int automount_add_mount_links(Automount *a) {
        _cleanup_free_ char *parent = NULL;

        assert(a);

        parent = dirname_malloc(a->where);
        if (!parent)
                return -ENOMEM;

        return unit_require_mounts_for(UNIT(a), parent);
}
Ejemplo n.º 2
0
static int generate_path(char **var, char **filenames) {
        char **filename;

        _cleanup_strv_free_ char **ans = NULL;
        int r;

        STRV_FOREACH(filename, filenames) {
                char *t;

                t = dirname_malloc(*filename);
                if (!t)
                        return -ENOMEM;

                r = strv_consume(&ans, t);
                if (r < 0)
                        return r;
        }
Ejemplo n.º 3
0
static int prepare_filename(const char *filename, char **ret) {
        int r;
        const char *name;
        _cleanup_free_ char *abspath = NULL;
        _cleanup_free_ char *dir = NULL;
        _cleanup_free_ char *with_instance = NULL;
        char *c;

        assert(filename);
        assert(ret);

        r = path_make_absolute_cwd(filename, &abspath);
        if (r < 0)
                return r;

        name = basename(abspath);
        if (!unit_name_is_valid(name, UNIT_NAME_ANY))
                return -EINVAL;

        if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE)) {
                r = unit_name_replace_instance(name, "i", &with_instance);
                if (r < 0)
                        return r;
        }

        dir = dirname_malloc(abspath);
        if (!dir)
                return -ENOMEM;

        if (with_instance)
                c = path_join(NULL, dir, with_instance);
        else
                c = path_join(NULL, dir, name);
        if (!c)
                return -ENOMEM;

        *ret = c;
        return 0;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static long write_catalog(const char *database, Hashmap *h, struct strbuf *sb,
                          CatalogItem *items, size_t n) {
        CatalogHeader header;
        _cleanup_fclose_ FILE *w = NULL;
        int r;
        _cleanup_free_ char *d, *p = NULL;
        size_t k;

        d = dirname_malloc(database);
        if (!d)
                return log_oom();

        r = mkdir_p(d, 0775);
        if (r < 0) {
                log_error("Recursive mkdir %s: %s", d, strerror(-r));
                return r;
        }

        r = fopen_temporary(database, &w, &p);
        if (r < 0) {
                log_error("Failed to open database for writing: %s: %s",
                          database, strerror(-r));
                return r;
        }

        zero(header);
        memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature));
        header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8));
        header.catalog_item_size = htole64(sizeof(CatalogItem));
        header.n_items = htole64(hashmap_size(h));

        r = -EIO;

        k = fwrite(&header, 1, sizeof(header), w);
        if (k != sizeof(header)) {
                log_error("%s: failed to write header.", p);
                goto error;
        }

        k = fwrite(items, 1, n * sizeof(CatalogItem), w);
        if (k != n * sizeof(CatalogItem)) {
                log_error("%s: failed to write database.", p);
                goto error;
        }

        k = fwrite(sb->buf, 1, sb->len, w);
        if (k != sb->len) {
                log_error("%s: failed to write strings.", p);
                goto error;
        }

        fflush(w);

        if (ferror(w)) {
                log_error("%s: failed to write database.", p);
                goto error;
        }

        fchmod(fileno(w), 0644);

        if (rename(p, database) < 0) {
                log_error("rename (%s -> %s) failed: %m", p, database);
                r = -errno;
                goto error;
        }

        return ftell(w);

error:
        unlink(p);
        return r;
}