From 003dffde2c1b93afbc9aff24b277276f65424406 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Dec 2014 01:57:03 +0100 Subject: machined: Move image discovery logic into src/shared, so that we can make use of it from nspawn --- Makefile.am | 7 +- src/machine/image-dbus.c | 3 +- src/machine/image-dbus.h | 31 +++++ src/machine/image.c | 325 -------------------------------------------- src/machine/image.h | 63 --------- src/machine/machine-dbus.c | 1 + src/machine/machine-dbus.h | 41 ++++++ src/machine/machine.c | 3 +- src/machine/machine.h | 16 --- src/machine/machined-dbus.c | 4 +- src/machine/machined.h | 3 +- src/shared/machine-image.c | 325 ++++++++++++++++++++++++++++++++++++++++++++ src/shared/machine-image.h | 55 ++++++++ 13 files changed, 466 insertions(+), 411 deletions(-) create mode 100644 src/machine/image-dbus.h delete mode 100644 src/machine/image.c delete mode 100644 src/machine/image.h create mode 100644 src/machine/machine-dbus.h create mode 100644 src/shared/machine-image.c create mode 100644 src/shared/machine-image.h diff --git a/Makefile.am b/Makefile.am index f71bc9ac4b..e1e0843086 100644 --- a/Makefile.am +++ b/Makefile.am @@ -899,6 +899,8 @@ libsystemd_shared_la_SOURCES = \ src/shared/btrfs-ctree.h \ src/shared/verbs.c \ src/shared/verbs.h \ + src/shared/machine-image.c \ + src/shared/machine-image.h \ src/shared/build.h if HAVE_UTMP @@ -5039,11 +5041,10 @@ rootlibexec_PROGRAMS += \ libsystemd_machine_core_la_SOURCES = \ src/machine/machine.c \ src/machine/machine.h \ - src/machine/image.c \ - src/machine/image.h \ src/machine/machined-dbus.c \ src/machine/machine-dbus.c \ - src/machine/image-dbus.c + src/machine/image-dbus.c \ + src/machine/image-dbus.h libsystemd_machine_core_la_LIBADD = \ libsystemd-label.la \ diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 8d9ad5589e..c8d1328fe9 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -22,7 +22,8 @@ #include "bus-label.h" #include "bus-common-errors.h" #include "strv.h" -#include "image.h" +#include "machine-image.h" +#include "image-dbus.h" static int image_find_by_bus_path(const char *path, Image **ret) { _cleanup_free_ char *e = NULL; diff --git a/src/machine/image-dbus.h b/src/machine/image-dbus.h new file mode 100644 index 0000000000..d176ff728b --- /dev/null +++ b/src/machine/image-dbus.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "machined.h" + +extern const sd_bus_vtable image_vtable[]; + +char *image_bus_path(const char *name); + +int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); diff --git a/src/machine/image.c b/src/machine/image.c deleted file mode 100644 index 46a216bbb7..0000000000 --- a/src/machine/image.c +++ /dev/null @@ -1,325 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include - -#include "strv.h" -#include "utf8.h" -#include "btrfs-util.h" -#include "path-util.h" -#include "image.h" - -static const char image_search_path[] = - "/var/lib/machines\0" - "/var/lib/container\0" - "/usr/local/lib/machines\0" - "/usr/lib/machines\0"; - -Image *image_unref(Image *i) { - if (!i) - return NULL; - - free(i->name); - free(i->path); - free(i); - return NULL; -} - -static int image_new( - ImageType t, - const char *pretty, - const char *path, - const char *filename, - bool read_only, - usec_t crtime, - usec_t mtime, - Image **ret) { - - _cleanup_(image_unrefp) Image *i = NULL; - - assert(t >= 0); - assert(t < _IMAGE_TYPE_MAX); - assert(pretty); - assert(filename); - assert(ret); - - i = new0(Image, 1); - if (!i) - return -ENOMEM; - - i->type = t; - i->read_only = read_only; - i->crtime = crtime; - i->mtime = mtime; - - i->name = strdup(pretty); - if (!i->name) - return -ENOMEM; - - if (path) - i->path = strjoin(path, "/", filename, NULL); - else - i->path = strdup(filename); - - if (!i->path) - return -ENOMEM; - - path_kill_slashes(i->path); - - *ret = i; - i = NULL; - - return 0; -} - -static int image_make( - const char *pretty, - int dfd, - const char *path, - const char *filename, - Image **ret) { - - struct stat st; - bool read_only; - int r; - - assert(filename); - - /* We explicitly *do* follow symlinks here, since we want to - * allow symlinking trees into /var/lib/container/, and treat - * them normally. */ - - if (fstatat(dfd, filename, &st, 0) < 0) - return -errno; - - read_only = - (path && path_startswith(path, "/usr")) || - (faccessat(dfd, filename, W_OK, AT_EACCESS) < 0 && errno == EROFS); - - if (S_ISDIR(st.st_mode)) { - - if (!ret) - return 1; - - if (!pretty) - pretty = filename; - - /* btrfs subvolumes have inode 256 */ - if (st.st_ino == 256) { - _cleanup_close_ int fd = -1; - struct statfs sfs; - - fd = openat(dfd, filename, O_CLOEXEC|O_NOCTTY|O_DIRECTORY); - if (fd < 0) - return -errno; - - if (fstatfs(fd, &sfs) < 0) - return -errno; - - if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) { - BtrfsSubvolInfo info; - - /* It's a btrfs subvolume */ - - r = btrfs_subvol_get_info_fd(fd, &info); - if (r < 0) - return r; - - r = image_new(IMAGE_SUBVOLUME, - pretty, - path, - filename, - info.read_only || read_only, - info.otime, - 0, - ret); - if (r < 0) - return r; - - return 1; - } - } - - /* It's just a normal directory. */ - - r = image_new(IMAGE_DIRECTORY, - pretty, - path, - filename, - read_only, - 0, - 0, - ret); - if (r < 0) - return r; - - return 1; - - } else if (S_ISREG(st.st_mode) && endswith(filename, ".gpt")) { - usec_t crtime = 0; - - /* It's a GPT block device */ - - if (!ret) - return 1; - - fd_getcrtime_at(dfd, filename, &crtime, 0); - - if (!pretty) - pretty = strndupa(filename, strlen(filename) - 4); - - r = image_new(IMAGE_GPT, - pretty, - path, - filename, - !(st.st_mode & 0222) || read_only, - crtime, - timespec_load(&st.st_mtim), - ret); - if (r < 0) - return r; - - return 1; - } - - return 0; -} - -int image_find(const char *name, Image **ret) { - const char *path; - int r; - - assert(name); - - /* There are no images with invalid names */ - if (!image_name_is_valid(name)) - return 0; - - NULSTR_FOREACH(path, image_search_path) { - _cleanup_closedir_ DIR *d = NULL; - - d = opendir(path); - if (!d) { - if (errno == ENOENT) - continue; - - return -errno; - } - - r = image_make(NULL, dirfd(d), path, name, ret); - if (r == 0 || r == -ENOENT) { - _cleanup_free_ char *gpt = NULL; - - gpt = strappend(name, ".gpt"); - if (!gpt) - return -ENOMEM; - - r = image_make(NULL, dirfd(d), path, gpt, ret); - if (r == 0 || r == -ENOENT) - continue; - } - if (r < 0) - return r; - - return 1; - } - - if (streq(name, ".host")) - return image_make(".host", AT_FDCWD, NULL, "/", ret); - - return 0; -}; - -int image_discover(Hashmap *h) { - const char *path; - int r; - - assert(h); - - NULSTR_FOREACH(path, image_search_path) { - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; - - d = opendir(path); - if (!d) { - if (errno == ENOENT) - continue; - - return -errno; - } - - FOREACH_DIRENT_ALL(de, d, return -errno) { - _cleanup_(image_unrefp) Image *image = NULL; - - if (!image_name_is_valid(de->d_name)) - continue; - - if (hashmap_contains(h, de->d_name)) - continue; - - r = image_make(NULL, dirfd(d), path, de->d_name, &image); - if (r == 0 || r == -ENOENT) - continue; - if (r < 0) - return r; - - r = hashmap_put(h, image->name, image); - if (r < 0) - return r; - - image = NULL; - } - } - - if (!hashmap_contains(h, ".host")) { - _cleanup_(image_unrefp) Image *image = NULL; - - r = image_make(".host", AT_FDCWD, NULL, "/", &image); - if (r < 0) - return r; - - r = hashmap_put(h, image->name, image); - if (r < 0) - return r; - - image = NULL; - - } - - return 0; -} - -void image_hashmap_free(Hashmap *map) { - Image *i; - - while ((i = hashmap_steal_first(map))) - image_unref(i); - - hashmap_free(map); -} - -static const char* const image_type_table[_IMAGE_TYPE_MAX] = { - [IMAGE_DIRECTORY] = "directory", - [IMAGE_SUBVOLUME] = "subvolume", - [IMAGE_GPT] = "gpt", -}; - -DEFINE_STRING_TABLE_LOOKUP(image_type, ImageType); diff --git a/src/machine/image.h b/src/machine/image.h deleted file mode 100644 index 2e8f78147c..0000000000 --- a/src/machine/image.h +++ /dev/null @@ -1,63 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include "time-util.h" -#include "hashmap.h" -#include "machined.h" - -typedef enum ImageType { - IMAGE_DIRECTORY, - IMAGE_SUBVOLUME, - IMAGE_GPT, - _IMAGE_TYPE_MAX, - _IMAGE_TYPE_INVALID = -1 -} ImageType; - -typedef struct Image { - ImageType type; - char *name; - char *path; - bool read_only; - - usec_t crtime; - usec_t mtime; -} Image; - -Image *image_unref(Image *i); -void image_hashmap_free(Hashmap *map); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free); - -int image_find(const char *name, Image **ret); -int image_discover(Hashmap *map); - -extern const sd_bus_vtable image_vtable[]; - -char *image_bus_path(const char *name); - -int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); - -const char* image_type_to_string(ImageType t) _const_; -ImageType image_type_from_string(const char *s) _pure_; diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 31a6fc4715..cbdbc52a14 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -34,6 +34,7 @@ #include "path-util.h" #include "bus-internal.h" #include "machine.h" +#include "machine-dbus.h" static int property_get_id( sd_bus *bus, diff --git a/src/machine/machine-dbus.h b/src/machine/machine-dbus.h new file mode 100644 index 0000000000..601252722d --- /dev/null +++ b/src/machine/machine-dbus.h @@ -0,0 +1,41 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "sd-bus.h" +#include "machine.h" + +extern const sd_bus_vtable machine_vtable[]; + +char *machine_bus_path(Machine *s); +int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); + +int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); + +int machine_send_signal(Machine *m, bool new_machine); +int machine_send_create_reply(Machine *m, sd_bus_error *error); diff --git a/src/machine/machine.c b/src/machine/machine.c index 0d84213eea..8dec716d71 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -32,9 +32,10 @@ #include "fileio.h" #include "special.h" #include "unit-name.h" -#include "machine.h" #include "bus-util.h" #include "bus-error.h" +#include "machine.h" +#include "machine-dbus.h" Machine* machine_new(Manager *manager, const char *name) { Machine *m; diff --git a/src/machine/machine.h b/src/machine/machine.h index 3a78ab4484..64accda8b1 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -94,22 +94,6 @@ int machine_kill(Machine *m, KillWho who, int signo); MachineState machine_get_state(Machine *u); -extern const sd_bus_vtable machine_vtable[]; - -char *machine_bus_path(Machine *s); -int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); - -int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); - -int machine_send_signal(Machine *m, bool new_machine); -int machine_send_create_reply(Machine *m, sd_bus_error *error); - const char* machine_class_to_string(MachineClass t) _const_; MachineClass machine_class_from_string(const char *s) _pure_; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 1ca2c95898..66594ab0b1 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -38,8 +38,10 @@ #include "bus-common-errors.h" #include "time-util.h" #include "cgroup-util.h" -#include "image.h" +#include "machine-image.h" +#include "image-dbus.h" #include "machined.h" +#include "machine-dbus.h" static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_free_ char *p = NULL; diff --git a/src/machine/machined.h b/src/machine/machined.h index 5fc1bd17b3..695ba297cc 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -33,7 +33,8 @@ typedef struct Manager Manager; #include "machine.h" -#include "image.h" +#include "machine-dbus.h" +#include "image-dbus.h" struct Manager { sd_event *event; diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c new file mode 100644 index 0000000000..51f89d5921 --- /dev/null +++ b/src/shared/machine-image.c @@ -0,0 +1,325 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "strv.h" +#include "utf8.h" +#include "btrfs-util.h" +#include "path-util.h" +#include "machine-image.h" + +static const char image_search_path[] = + "/var/lib/machines\0" + "/var/lib/container\0" + "/usr/local/lib/machines\0" + "/usr/lib/machines\0"; + +Image *image_unref(Image *i) { + if (!i) + return NULL; + + free(i->name); + free(i->path); + free(i); + return NULL; +} + +static int image_new( + ImageType t, + const char *pretty, + const char *path, + const char *filename, + bool read_only, + usec_t crtime, + usec_t mtime, + Image **ret) { + + _cleanup_(image_unrefp) Image *i = NULL; + + assert(t >= 0); + assert(t < _IMAGE_TYPE_MAX); + assert(pretty); + assert(filename); + assert(ret); + + i = new0(Image, 1); + if (!i) + return -ENOMEM; + + i->type = t; + i->read_only = read_only; + i->crtime = crtime; + i->mtime = mtime; + + i->name = strdup(pretty); + if (!i->name) + return -ENOMEM; + + if (path) + i->path = strjoin(path, "/", filename, NULL); + else + i->path = strdup(filename); + + if (!i->path) + return -ENOMEM; + + path_kill_slashes(i->path); + + *ret = i; + i = NULL; + + return 0; +} + +static int image_make( + const char *pretty, + int dfd, + const char *path, + const char *filename, + Image **ret) { + + struct stat st; + bool read_only; + int r; + + assert(filename); + + /* We explicitly *do* follow symlinks here, since we want to + * allow symlinking trees into /var/lib/container/, and treat + * them normally. */ + + if (fstatat(dfd, filename, &st, 0) < 0) + return -errno; + + read_only = + (path && path_startswith(path, "/usr")) || + (faccessat(dfd, filename, W_OK, AT_EACCESS) < 0 && errno == EROFS); + + if (S_ISDIR(st.st_mode)) { + + if (!ret) + return 1; + + if (!pretty) + pretty = filename; + + /* btrfs subvolumes have inode 256 */ + if (st.st_ino == 256) { + _cleanup_close_ int fd = -1; + struct statfs sfs; + + fd = openat(dfd, filename, O_CLOEXEC|O_NOCTTY|O_DIRECTORY); + if (fd < 0) + return -errno; + + if (fstatfs(fd, &sfs) < 0) + return -errno; + + if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) { + BtrfsSubvolInfo info; + + /* It's a btrfs subvolume */ + + r = btrfs_subvol_get_info_fd(fd, &info); + if (r < 0) + return r; + + r = image_new(IMAGE_SUBVOLUME, + pretty, + path, + filename, + info.read_only || read_only, + info.otime, + 0, + ret); + if (r < 0) + return r; + + return 1; + } + } + + /* It's just a normal directory. */ + + r = image_new(IMAGE_DIRECTORY, + pretty, + path, + filename, + read_only, + 0, + 0, + ret); + if (r < 0) + return r; + + return 1; + + } else if (S_ISREG(st.st_mode) && endswith(filename, ".gpt")) { + usec_t crtime = 0; + + /* It's a GPT block device */ + + if (!ret) + return 1; + + fd_getcrtime_at(dfd, filename, &crtime, 0); + + if (!pretty) + pretty = strndupa(filename, strlen(filename) - 4); + + r = image_new(IMAGE_GPT, + pretty, + path, + filename, + !(st.st_mode & 0222) || read_only, + crtime, + timespec_load(&st.st_mtim), + ret); + if (r < 0) + return r; + + return 1; + } + + return 0; +} + +int image_find(const char *name, Image **ret) { + const char *path; + int r; + + assert(name); + + /* There are no images with invalid names */ + if (!image_name_is_valid(name)) + return 0; + + NULSTR_FOREACH(path, image_search_path) { + _cleanup_closedir_ DIR *d = NULL; + + d = opendir(path); + if (!d) { + if (errno == ENOENT) + continue; + + return -errno; + } + + r = image_make(NULL, dirfd(d), path, name, ret); + if (r == 0 || r == -ENOENT) { + _cleanup_free_ char *gpt = NULL; + + gpt = strappend(name, ".gpt"); + if (!gpt) + return -ENOMEM; + + r = image_make(NULL, dirfd(d), path, gpt, ret); + if (r == 0 || r == -ENOENT) + continue; + } + if (r < 0) + return r; + + return 1; + } + + if (streq(name, ".host")) + return image_make(".host", AT_FDCWD, NULL, "/", ret); + + return 0; +}; + +int image_discover(Hashmap *h) { + const char *path; + int r; + + assert(h); + + NULSTR_FOREACH(path, image_search_path) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + + d = opendir(path); + if (!d) { + if (errno == ENOENT) + continue; + + return -errno; + } + + FOREACH_DIRENT_ALL(de, d, return -errno) { + _cleanup_(image_unrefp) Image *image = NULL; + + if (!image_name_is_valid(de->d_name)) + continue; + + if (hashmap_contains(h, de->d_name)) + continue; + + r = image_make(NULL, dirfd(d), path, de->d_name, &image); + if (r == 0 || r == -ENOENT) + continue; + if (r < 0) + return r; + + r = hashmap_put(h, image->name, image); + if (r < 0) + return r; + + image = NULL; + } + } + + if (!hashmap_contains(h, ".host")) { + _cleanup_(image_unrefp) Image *image = NULL; + + r = image_make(".host", AT_FDCWD, NULL, "/", &image); + if (r < 0) + return r; + + r = hashmap_put(h, image->name, image); + if (r < 0) + return r; + + image = NULL; + + } + + return 0; +} + +void image_hashmap_free(Hashmap *map) { + Image *i; + + while ((i = hashmap_steal_first(map))) + image_unref(i); + + hashmap_free(map); +} + +static const char* const image_type_table[_IMAGE_TYPE_MAX] = { + [IMAGE_DIRECTORY] = "directory", + [IMAGE_SUBVOLUME] = "subvolume", + [IMAGE_GPT] = "gpt", +}; + +DEFINE_STRING_TABLE_LOOKUP(image_type, ImageType); diff --git a/src/shared/machine-image.h b/src/shared/machine-image.h new file mode 100644 index 0000000000..646598f9c8 --- /dev/null +++ b/src/shared/machine-image.h @@ -0,0 +1,55 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "time-util.h" +#include "hashmap.h" + +typedef enum ImageType { + IMAGE_DIRECTORY, + IMAGE_SUBVOLUME, + IMAGE_GPT, + _IMAGE_TYPE_MAX, + _IMAGE_TYPE_INVALID = -1 +} ImageType; + +typedef struct Image { + ImageType type; + char *name; + char *path; + bool read_only; + + usec_t crtime; + usec_t mtime; +} Image; + +Image *image_unref(Image *i); +void image_hashmap_free(Hashmap *map); + +DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free); + +int image_find(const char *name, Image **ret); +int image_discover(Hashmap *map); + +const char* image_type_to_string(ImageType t) _const_; +ImageType image_type_from_string(const char *s) _pure_; -- cgit v1.2.3-54-g00ecf