[systemd-commits] 5 commits - Makefile.am TODO src/core src/libsystemd src/machine src/shared src/sysv-generator src/tty-ask-password-agent
Lennart Poettering
lennart at kemper.freedesktop.org
Fri Dec 19 11:45:02 PST 2014
Makefile.am | 3
TODO | 4
src/core/manager.c | 2
src/libsystemd/sd-bus/bus-common-errors.c | 1
src/libsystemd/sd-bus/bus-common-errors.h | 1
src/machine/image-dbus.c | 234 +++++++++++++++++
src/machine/image.c | 266 +++++++++++---------
src/machine/image.h | 14 -
src/machine/machine-dbus.c | 23 -
src/machine/machined-dbus.c | 28 ++
src/machine/machined.c | 11
src/machine/machined.h | 1
src/machine/org.freedesktop.machine1.conf | 4
src/shared/dropin.c | 2
src/shared/fdset.c | 2
src/shared/install.c | 8
src/shared/util.c | 33 +-
src/shared/util.h | 5
src/sysv-generator/Makefile | 2
src/sysv-generator/sysv-generator.c | 4
src/tty-ask-password-agent/tty-ask-password-agent.c | 2
21 files changed, 482 insertions(+), 168 deletions(-)
New commits:
commit 2cd3aa24820e5d82375c8cc3e4446d884ee4fee0
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 19 20:44:49 2014 +0100
update TODO
diff --git a/TODO b/TODO
index c58f503..fedcf59 100644
--- a/TODO
+++ b/TODO
@@ -39,8 +39,6 @@ Features:
* "machinectl start/enable/disable foo" as aliases for "systemctl start/enable/disable systemd-nspawn at foo.service"
-* "machinectl list-images" for showing a list of container trees collected from /var/lib/containers
-
* "machinectl snapshot" to make a snapshot of a tree or container into /var/lib/containers
* "machinectl rm" to remove a container tree from /var/lib/containers
@@ -51,6 +49,8 @@ Features:
* "machinectl status" should show 10 most recent log lines of both the host logs of the unit of the machine, plus the logs generated in the machine
+* make "machinectl login" use a new machined call AllocateMachinePty() or so to get a pty in a machine. That would open up logins to unprivileged clients
+
* add transparent btrfs pool in a loopback file in /var if btrfs operations (such as systemd-import pull-dck) are used and /var is not a btrfs file system
* machined: open up certain commands to unprivileged clients via polkit
commit ebeccf9eecf5939a2ef772c3160e89efcad96194
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 19 20:43:18 2014 +0100
machined: add a full bus object for images
diff --git a/Makefile.am b/Makefile.am
index 840b871..9edc235 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5039,7 +5039,8 @@ libsystemd_machine_core_la_SOURCES = \
src/machine/image.c \
src/machine/image.h \
src/machine/machined-dbus.c \
- src/machine/machine-dbus.c
+ src/machine/machine-dbus.c \
+ src/machine/image-dbus.c
libsystemd_machine_core_la_LIBADD = \
libsystemd-label.la \
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c
new file mode 100644
index 0000000..afb849b
--- /dev/null
+++ b/src/machine/image-dbus.c
@@ -0,0 +1,234 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ 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 <http://www.gnu.org/licenses/>.
+***/
+
+#include "bus-label.h"
+#include "bus-common-errors.h"
+#include "strv.h"
+#include "image.h"
+
+static int image_find_by_bus_path(const char *path, Image **ret) {
+ _cleanup_free_ char *e = NULL;
+ const char *p;
+
+ assert(path);
+
+ p = startswith(path, "/org/freedesktop/machine1/image/");
+ if (!p)
+ return 0;
+
+ e = bus_label_unescape(p);
+ if (!e)
+ return -ENOMEM;
+
+ return image_find(e, ret);
+}
+
+static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
+ int r;
+
+ assert(path);
+
+ r = image_find_by_bus_path(path, ret);
+ if (r == 0)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
+
+ return r;
+}
+
+static int property_get_name(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ _cleanup_(image_unrefp) Image *image = NULL;
+ int r;
+
+ assert(bus);
+ assert(reply);
+
+ r = image_find_by_bus_path_with_error(path, &image, error);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "s", image->name);
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+static int property_get_path(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ _cleanup_(image_unrefp) Image *image = NULL;
+ int r;
+
+ assert(bus);
+ assert(reply);
+
+ r = image_find_by_bus_path_with_error(path, &image, error);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "s", image->path);
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+static int property_get_type(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ _cleanup_(image_unrefp) Image *image = NULL;
+ int r;
+
+ assert(bus);
+ assert(reply);
+
+ r = image_find_by_bus_path_with_error(path, &image, error);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+static int property_get_read_only(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ _cleanup_(image_unrefp) Image *image = NULL;
+ int r;
+
+ assert(bus);
+ assert(reply);
+
+ r = image_find_by_bus_path_with_error(path, &image, error);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "b", image->read_only);
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+const sd_bus_vtable image_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_PROPERTY("Name", "s", property_get_name, 0, 0),
+ SD_BUS_PROPERTY("Path", "s", property_get_path, 0, 0),
+ SD_BUS_PROPERTY("Type", "s", property_get_type, 0, 0),
+ SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
+ SD_BUS_VTABLE_END
+};
+
+int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
+ int r;
+
+ assert(bus);
+ assert(path);
+ assert(interface);
+ assert(found);
+
+ r = image_find_by_bus_path(path, NULL);
+ if (r <= 0)
+ return r;
+
+ *found = NULL;
+ return 1;
+}
+
+char *image_bus_path(const char *name) {
+ _cleanup_free_ char *e = NULL;
+
+ assert(name);
+
+ e = bus_label_escape(name);
+ if (!e)
+ return NULL;
+
+ return strappend("/org/freedesktop/machine1/image/", e);
+}
+
+int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
+ _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ Image *image;
+ Iterator i;
+ int r;
+
+ assert(bus);
+ assert(path);
+ assert(nodes);
+
+ images = hashmap_new(&string_hash_ops);
+ if (!images)
+ return -ENOMEM;
+
+ r = image_discover(images);
+ if (r < 0)
+ return r;
+
+ HASHMAP_FOREACH(image, images, i) {
+ char *p;
+
+ p = image_bus_path(image->name);
+ if (!p)
+ return -ENOMEM;
+
+ r = strv_consume(&l, p);
+ if (r < 0)
+ return r;
+ }
+
+ *nodes = l;
+ l = NULL;
+
+ return 1;
+}
diff --git a/src/machine/image.c b/src/machine/image.c
index 8f577ad..c81c5f6 100644
--- a/src/machine/image.c
+++ b/src/machine/image.c
@@ -24,8 +24,8 @@
#include "strv.h"
#include "utf8.h"
#include "btrfs-util.h"
+#include "path-util.h"
#include "image.h"
-#include "bus-label.h"
static const char image_search_path[] =
"/var/lib/container\0"
@@ -71,9 +71,11 @@ static int image_new(
return -ENOMEM;
if (path) {
- i->path = strdup(path);
+ i->path = strjoin(path, "/", name, NULL);
if (!i->path)
return -ENOMEM;
+
+ path_kill_slashes(i->path);
}
*ret = i;
@@ -264,18 +266,6 @@ void image_hashmap_free(Hashmap *map) {
hashmap_free(map);
}
-char *image_bus_path(const char *name) {
- _cleanup_free_ char *e = NULL;
-
- assert(name);
-
- e = bus_label_escape(name);
- if (!e)
- return NULL;
-
- return strappend("/org/freedesktop/machine1/image/", e);
-}
-
static const char* const image_type_table[_IMAGE_TYPE_MAX] = {
[IMAGE_DIRECTORY] = "directory",
[IMAGE_SUBVOLUME] = "subvolume",
diff --git a/src/machine/image.h b/src/machine/image.h
index f298fc3..f04be23 100644
--- a/src/machine/image.h
+++ b/src/machine/image.h
@@ -5,7 +5,7 @@
/***
This file is part of systemd.
- Copyright 2013 Lennart Poettering
+ 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
@@ -23,6 +23,7 @@
#include "time-util.h"
#include "hashmap.h"
+#include "machined.h"
typedef enum ImageType {
IMAGE_DIRECTORY,
@@ -43,16 +44,20 @@ typedef struct Image {
} 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);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free);
+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 163c73d..f6fd9cf 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -32,7 +32,6 @@
#include "fileio.h"
#include "in-addr-util.h"
#include "local-addresses.h"
-#include "image.h"
#include "machine.h"
static int property_get_id(
@@ -476,11 +475,9 @@ char *machine_bus_path(Machine *m) {
}
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
- Image *image;
Iterator i;
int r;
@@ -500,26 +497,6 @@ int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
return r;
}
- images = hashmap_new(&string_hash_ops);
- if (!images)
- return -ENOMEM;
-
- r = image_discover(images);
- if (r < 0)
- return r;
-
- HASHMAP_FOREACH(image, images, i) {
- char *p;
-
- p = image_bus_path(image->name);
- if (!p)
- return -ENOMEM;
-
- r = strv_consume(&l, p);
- if (r < 0)
- return r;
- }
-
*nodes = l;
l = NULL;
diff --git a/src/machine/machined.c b/src/machine/machined.c
index ef59497..82cfcf0 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -27,15 +27,14 @@
#include <sys/epoll.h>
#include "sd-daemon.h"
-
#include "strv.h"
#include "conf-parser.h"
#include "cgroup-util.h"
#include "mkdir.h"
#include "bus-util.h"
#include "bus-error.h"
-#include "machined.h"
#include "label.h"
+#include "machined.h"
Manager *manager_new(void) {
Manager *m;
@@ -152,6 +151,14 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to add machine enumerator: %m");
+ r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add image object vtable: %m");
+
+ r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add image enumerator: %m");
+
r = sd_bus_add_match(m->bus,
NULL,
"type='signal',"
diff --git a/src/machine/machined.h b/src/machine/machined.h
index 2dba303..ed0bd70 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -33,6 +33,7 @@
typedef struct Manager Manager;
#include "machine.h"
+#include "image.h"
struct Manager {
sd_event *event;
commit c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 19 20:07:23 2014 +0100
machined: add new GetImage() bus call for retrieving the bus path for an image
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index 3dc00b5..8e90738 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -45,6 +45,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_SCOPE_NOT_RUNNING, EHOSTDOWN),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_MACHINE, ENXIO),
+ SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_IMAGE, ENOENT),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_MACHINE_FOR_PID, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_MACHINE_EXISTS, EEXIST),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_PRIVATE_NETWORKING, ENOSYS),
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index 5b7f41e..9007b85 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -43,6 +43,7 @@
#define BUS_ERROR_SCOPE_NOT_RUNNING "org.freedesktop.systemd1.ScopeNotRunning"
#define BUS_ERROR_NO_SUCH_MACHINE "org.freedesktop.machine1.NoSuchMachine"
+#define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage"
#define BUS_ERROR_NO_MACHINE_FOR_PID "org.freedesktop.machine1.NoMachineForPID"
#define BUS_ERROR_MACHINE_EXISTS "org.freedesktop.machine1.MachineExists"
#define BUS_ERROR_NO_PRIVATE_NETWORKING "org.freedesktop.machine1.NoPrivateNetworking"
diff --git a/src/machine/image.c b/src/machine/image.c
index 0ba9652..8f577ad 100644
--- a/src/machine/image.c
+++ b/src/machine/image.c
@@ -27,6 +27,10 @@
#include "image.h"
#include "bus-label.h"
+static const char image_search_path[] =
+ "/var/lib/container\0"
+ "/var/lib/machine\0";
+
Image *image_unref(Image *i) {
if (!i)
return NULL;
@@ -37,24 +41,23 @@ Image *image_unref(Image *i) {
return NULL;
}
-static int add_image(
- Hashmap *h,
+static int image_new(
ImageType t,
const char *name,
const char *path,
bool read_only,
usec_t mtime,
- usec_t btime) {
+ usec_t btime,
+ Image **ret) {
_cleanup_(image_unrefp) Image *i = NULL;
- int r;
- assert(h);
assert(t >= 0);
assert(t < _IMAGE_TYPE_MAX);
assert(name);
+ assert(ret);
- i = new(Image, 1);
+ i = new0(Image, 1);
if (!i)
return -ENOMEM;
@@ -73,136 +76,179 @@ static int add_image(
return -ENOMEM;
}
- r = hashmap_put(h, i->name, i);
- if (r < 0)
- return r;
-
+ *ret = i;
i = NULL;
+
return 0;
}
-int image_discover(Hashmap *h) {
- const char *path;
+static int image_make(int dfd, const char *name, const char *path, Image **ret) {
+ struct stat st;
int r;
- assert(h);
+ assert(dfd >= 0);
+ assert(name);
- FOREACH_STRING(path, "/var/lib/container", "/var/lib/machine") {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
+ /* We explicitly *do* follow symlinks here, since we want to
+ * allow symlinking trees into /var/lib/container/, and treat
+ * them normally. */
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- return 0;
+ if (fstatat(dfd, name, &st, 0) < 0)
+ return -errno;
- return -errno;
- }
+ if (S_ISDIR(st.st_mode)) {
- FOREACH_DIRENT_ALL(de, d, return -errno) {
- struct stat st;
+ if (!ret)
+ return 1;
- if (STR_IN_SET(de->d_name, ".", ".."))
- continue;
+ /* btrfs subvolumes have inode 256 */
+ if (st.st_ino == 256) {
+ _cleanup_close_ int fd = -1;
+ struct statfs sfs;
- /* Temporary files for atomically creating new files */
- if (startswith(de->d_name, ".#"))
- continue;
+ fd = openat(dfd, name, O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
+ if (fd < 0)
+ return -errno;
- if (string_has_cc(de->d_name, NULL))
- continue;
+ if (fstatfs(fd, &sfs) < 0)
+ return -errno;
- if (!utf8_is_valid(de->d_name))
- continue;
+ if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) {
+ usec_t btime = 0;
+ int ro;
- if (hashmap_contains(h, de->d_name))
- continue;
+ /* It's a btrfs subvolume */
- /* We explicitly *do* follow symlinks here,
- * since we want to allow symlinking trees
- * into /var/lib/container/, and treat them
- * normally. */
- if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) {
- if (errno == ENOENT)
- continue;
+ ro = btrfs_subvol_is_read_only_fd(fd);
+ if (ro < 0)
+ return ro;
- return -errno;
+ /* r = btrfs_subvol_get_btime(fd, &btime); */
+ /* if (r < 0) */
+ /* return r; */
+
+ r = image_new(IMAGE_SUBVOLUME,
+ name,
+ path,
+ ro,
+ 0,
+ btime,
+ ret);
+ if (r < 0)
+ return r;
+
+ return 1;
}
+ }
- if (S_ISDIR(st.st_mode)) {
+ /* It's just a normal directory. */
- /* btrfs subvolumes have inode 256 */
- if (st.st_ino == 256) {
- _cleanup_close_ int fd = -1;
- struct statfs sfs;
+ r = image_new(IMAGE_DIRECTORY,
+ name,
+ path,
+ false,
+ 0,
+ 0,
+ ret);
+ if (r < 0)
+ return r;
- fd = openat(dirfd(d), de->d_name, O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
- if (fd < 0) {
- if (errno == ENOENT)
- continue;
+ return 1;
- return -errno;
- }
+ } else if (S_ISREG(st.st_mode) && endswith(name, ".gpt")) {
- if (fstatfs(fd, &sfs) < 0)
- return -errno;
+ /* It's a GPT block device */
- if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) {
- usec_t btime = 0;
- int ro;
+ if (!ret)
+ return 1;
- /* It's a btrfs subvolume */
+ r = image_new(IMAGE_GPT,
+ name,
+ path,
+ !!(st.st_mode & 0111),
+ timespec_load(&st.st_mtim),
+ 0,
+ ret);
+ if (r < 0)
+ return r;
- ro = btrfs_subvol_is_read_only_fd(fd);
- if (ro < 0)
- return ro;
+ return 1;
+ }
- /* r = btrfs_subvol_get_btime(fd, &btime); */
- /* if (r < 0) */
- /* return r; */
+ return 0;
+}
- r = add_image(h,
- IMAGE_SUBVOLUME,
- de->d_name,
- path,
- ro,
- 0,
- btime);
+int image_find(const char *name, Image **ret) {
+ const char *path;
+ int r;
- if (r < 0)
- return r;
+ assert(name);
- continue;
- }
- }
+ /* There are no images with invalid names */
+ if (!image_name_is_valid(name))
+ return 0;
- /* It's just a normal directory. */
+ NULSTR_FOREACH(path, image_search_path) {
+ _cleanup_closedir_ DIR *d = NULL;
- r = add_image(h,
- IMAGE_DIRECTORY,
- de->d_name,
- path,
- false,
- 0,
- 0);
- if (r < 0)
- return r;
+ d = opendir(path);
+ if (!d) {
+ if (errno == ENOENT)
+ continue;
- } else if (S_ISREG(st.st_mode) &&
- endswith(de->d_name, ".gpt")) {
+ return -errno;
+ }
- /* It's a GPT block device */
+ r = image_make(dirfd(d), name, path, ret);
+ if (r == 0 || r == -ENOENT)
+ continue;
+ if (r < 0)
+ return r;
- r = add_image(h,
- IMAGE_GPT,
- de->d_name,
- path,
- !!(st.st_mode & 0111),
- timespec_load(&st.st_mtim),
- 0);
- if (r < 0)
- return r;
- }
+ return 1;
+ }
+
+ 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)
+ return 0;
+
+ 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(dirfd(d), de->d_name, path, &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;
}
}
diff --git a/src/machine/image.h b/src/machine/image.h
index c77fd19..f298fc3 100644
--- a/src/machine/image.h
+++ b/src/machine/image.h
@@ -46,6 +46,7 @@ Image *image_unref(Image *i);
void image_hashmap_free(Hashmap *map);
+int image_find(const char *name, Image **ret);
int image_discover(Hashmap *map);
char *image_bus_path(const char *name);
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 949c7d6..0229564 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -68,6 +68,33 @@ static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userda
return sd_bus_reply_method_return(message, "o", p);
}
+static int method_get_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_free_ char *p = NULL;
+ Manager *m = userdata;
+ const char *name;
+ int r;
+
+ assert(bus);
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ r = image_find(name, NULL);
+ if (r == 0)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
+ if (r < 0)
+ return r;
+
+ p = image_bus_path(name);
+ if (!p)
+ return -ENOMEM;
+
+ return sd_bus_reply_method_return(message, "o", p);
+}
+
static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
@@ -491,6 +518,7 @@ static int method_list_images(sd_bus *bus, sd_bus_message *message, void *userda
const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetImage", "s", "o", method_get_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListImages", NULL, "a(ssbo)", method_list_images, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index 3745c52..bd8fbef 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -54,6 +54,10 @@
<allow send_destination="org.freedesktop.machine1"
send_interface="org.freedesktop.machine1.Manager"
+ send_member="GetImage"/>
+
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Manager"
send_member="GetMachineAddresses"/>
<allow send_destination="org.freedesktop.machine1"
diff --git a/src/shared/util.c b/src/shared/util.c
index 1ad82b2..06b6077 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4257,6 +4257,23 @@ bool machine_name_is_valid(const char *s) {
return true;
}
+bool image_name_is_valid(const char *s) {
+ if (!filename_is_valid(s))
+ return false;
+
+ if (string_has_cc(s, NULL))
+ return false;
+
+ if (!utf8_is_valid(s))
+ return false;
+
+ /* Temporary files for atomically creating new files */
+ if (startswith(s, ".#"))
+ return false;
+
+ return true;
+}
+
int pipe_eof(int fd) {
struct pollfd pollfd = {
.fd = fd,
diff --git a/src/shared/util.h b/src/shared/util.h
index 712f65a..1804b8c 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -545,6 +545,7 @@ bool hostname_is_valid(const char *s) _pure_;
char* hostname_cleanup(char *s, bool lowercase);
bool machine_name_is_valid(const char *s) _pure_;
+bool image_name_is_valid(const char *s) _pure_;
char* strshorten(char *s, size_t l);
commit 821d4b6e068b2afaad94d43db22171c34a30400e
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 19 20:04:55 2014 +0100
sysv-generator: properly add Makefile symlink
diff --git a/src/sysv-generator/Makefile b/src/sysv-generator/Makefile
deleted file mode 100644
index 530e5e9..0000000
--- a/src/sysv-generator/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
diff --git a/src/sysv-generator/Makefile b/src/sysv-generator/Makefile
new file mode 120000
index 0000000..d0b0e8e
--- /dev/null
+++ b/src/sysv-generator/Makefile
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
commit a34bf9db5da0fdd6bdb14459e203dbe41ee99614
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 19 20:03:36 2014 +0100
util: rename ignore_file() to hidden_file()
hidden_file() is a bit more precise, since dot files usually shouldn't
be ignored, but certainly be considered hidden.
diff --git a/src/core/manager.c b/src/core/manager.c
index afd911d..9705e64 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1028,7 +1028,7 @@ static void manager_build_unit_path_cache(Manager *m) {
while ((de = readdir(d))) {
char *p;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index 40e6fee..d1baad6 100644
--- a/src/shared/dropin.c
+++ b/src/shared/dropin.c
@@ -148,7 +148,7 @@ static int iterate_dir(
if (!de)
break;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
f = strjoin(path, "/", de->d_name, NULL);
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
index 37cbd85..46f7773 100644
--- a/src/shared/fdset.c
+++ b/src/shared/fdset.c
@@ -127,7 +127,7 @@ int fdset_new_fill(FDSet **_s) {
while ((de = readdir(d))) {
int fd = -1;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
r = safe_atoi(de->d_name, &fd);
diff --git a/src/shared/install.c b/src/shared/install.c
index efbe61e..3b06544 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -240,7 +240,7 @@ static int remove_marked_symlinks_fd(
if (!de)
break;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
dirent_ensure_type(d, de);
@@ -415,7 +415,7 @@ static int find_symlinks_fd(
if (!de)
return r;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
dirent_ensure_type(d, de);
@@ -2094,7 +2094,7 @@ int unit_file_preset_all(
if (!de)
break;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
@@ -2206,7 +2206,7 @@ int unit_file_get_list(
if (!de)
break;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
diff --git a/src/shared/util.c b/src/shared/util.c
index 5f18d34..1ad82b2 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -1510,7 +1510,7 @@ char *ascii_strlower(char *t) {
return t;
}
-_pure_ static bool ignore_file_allow_backup(const char *filename) {
+_pure_ static bool hidden_file_allow_backup(const char *filename) {
assert(filename);
return
@@ -1527,13 +1527,13 @@ _pure_ static bool ignore_file_allow_backup(const char *filename) {
endswith(filename, ".swp");
}
-bool ignore_file(const char *filename) {
+bool hidden_file(const char *filename) {
assert(filename);
if (endswith(filename, "~"))
return true;
- return ignore_file_allow_backup(filename);
+ return hidden_file_allow_backup(filename);
}
int fd_nonblock(int fd, bool nonblock) {
@@ -1627,7 +1627,7 @@ int close_all_fds(const int except[], unsigned n_except) {
while ((de = readdir(d))) {
int fd = -1;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
if (safe_atoi(de->d_name, &fd) < 0)
@@ -2531,7 +2531,7 @@ int dir_is_empty(const char *path) {
if (!de)
return 1;
- if (!ignore_file(de->d_name))
+ if (!hidden_file(de->d_name))
return 0;
}
}
@@ -3996,7 +3996,7 @@ const char *default_term_for_tty(const char *tty) {
bool dirent_is_file(const struct dirent *de) {
assert(de);
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
return false;
if (de->d_type != DT_REG &&
@@ -4015,7 +4015,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
de->d_type != DT_UNKNOWN)
return false;
- if (ignore_file_allow_backup(de->d_name))
+ if (hidden_file_allow_backup(de->d_name))
return false;
return endswith(de->d_name, suffix);
@@ -5909,7 +5909,7 @@ int on_ac_power(void) {
if (!de)
break;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
diff --git a/src/shared/util.h b/src/shared/util.h
index e783ec6..712f65a 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -317,7 +317,7 @@ char *ascii_strlower(char *path);
bool dirent_is_file(const struct dirent *de) _pure_;
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
-bool ignore_file(const char *filename) _pure_;
+bool hidden_file(const char *filename) _pure_;
bool chars_intersect(const char *a, const char *b) _pure_;
@@ -771,7 +771,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *root
on_error; \
} \
break; \
- } else if (ignore_file((de)->d_name)) \
+ } else if (hidden_file((de)->d_name)) \
continue; \
else
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 45c8b4e..6730843 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -704,7 +704,7 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
_cleanup_free_ char *fpath = NULL, *name = NULL;
int r;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
fpath = strjoin(*path, "/", de->d_name, NULL);
@@ -777,7 +777,7 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
while ((de = readdir(d))) {
int a, b;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
if (de->d_name[0] != 'S' && de->d_name[0] != 'K')
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 5fc27f9..b4405ce 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -438,7 +438,7 @@ static int show_passwords(void) {
if (de->d_type != DT_REG)
continue;
- if (ignore_file(de->d_name))
+ if (hidden_file(de->d_name))
continue;
if (!startswith(de->d_name, "ask."))
More information about the systemd-commits
mailing list