summaryrefslogtreecommitdiff
path: root/src/machine/image-dbus.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-11-14 23:27:14 +0100
committerLennart Poettering <lennart@poettering.net>2017-11-20 16:43:15 +0100
commitcf30a8c1ed2de720dee935d552011aa9ba596d31 (patch)
treee3ceb56134511501de55b7c0d076fb21db5a4977 /src/machine/image-dbus.c
parentc7664c071ec935f67fed7aceebc296513d17ea15 (diff)
downloadsystemd-cf30a8c1ed2de720dee935d552011aa9ba596d31.tar.gz
machined: port machined's bus APIs to use new image metadata API
Let's rework the D-Bus APIs GetImageOSRelease() to use the new internal metadata API, to query what it needs to know. Augment it with GetImageHostname(), GetImageMachineID(), GetImageMachineInfo(), that expose the other new APIS.
Diffstat (limited to 'src/machine/image-dbus.c')
-rw-r--r--src/machine/image-dbus.c173
1 files changed, 51 insertions, 122 deletions
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c
index c868d623ba..3d2fdd496c 100644
--- a/src/machine/image-dbus.c
+++ b/src/machine/image-dbus.c
@@ -290,159 +290,85 @@ int bus_image_method_set_limit(
return sd_bus_reply_method_return(message, NULL);
}
-#define EXIT_NOT_FOUND 2
-
-static int directory_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
+int bus_image_method_get_hostname(
+ sd_bus_message *message,
+ void *userdata,
+ sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Image *image = userdata;
int r;
- assert(image);
- assert(ret);
-
- r = chase_symlinks("/etc/os-release", image->path, CHASE_PREFIX_ROOT, &path);
- if (r == -ENOENT)
- r = chase_symlinks("/usr/lib/os-release", image->path, CHASE_PREFIX_ROOT, &path);
- if (r == -ENOENT)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to resolve %s: %m", image->path);
-
- r = load_env_file_pairs(NULL, path, NULL, ret);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to open %s: %m", path);
+ if (!image->metadata_valid) {
+ r = image_read_metadata(image);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
+ }
- return 0;
+ return sd_bus_reply_method_return(message, "s", image->hostname);
}
-static int raw_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
- _cleanup_(rmdir_and_freep) char *t = NULL;
- _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
- _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
- _cleanup_(sigkill_waitp) pid_t child = 0;
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_strv_free_ char **v = NULL;
- siginfo_t si;
- int r;
-
- assert(image);
- assert(ret);
-
- r = mkdtemp_malloc("/tmp/machined-root-XXXXXX", &t);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to create temporary directory: %m");
-
- r = loop_device_make_by_path(image->path, O_RDONLY, &d);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to set up loop block device for %s: %m", image->path);
-
- r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
- if (r == -ENOPKG)
- return sd_bus_error_set_errnof(error, r, "Disk image %s not understood: %m", image->path);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to dissect image %s: %m", image->path);
-
- if (pipe2(pair, O_CLOEXEC) < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create communication pipe: %m");
-
- child = raw_clone(SIGCHLD|CLONE_NEWNS);
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- int fd;
-
- pair[0] = safe_close(pair[0]);
-
- /* Make sure we never propagate to the host */
- if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
- _exit(EXIT_FAILURE);
-
- r = dissected_image_mount(m, t, DISSECT_IMAGE_READ_ONLY);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- r = mount_move_root(t);
- if (r < 0)
- _exit(EXIT_FAILURE);
+int bus_image_method_get_machine_id(
+ sd_bus_message *message,
+ void *userdata,
+ sd_bus_error *error) {
- fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0 && errno == ENOENT) {
- fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0 && errno == ENOENT)
- _exit(EXIT_NOT_FOUND);
- }
- if (fd < 0)
- _exit(EXIT_FAILURE);
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Image *image = userdata;
+ int r;
- r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
+ if (!image->metadata_valid) {
+ r = image_read_metadata(image);
if (r < 0)
- _exit(EXIT_FAILURE);
-
- _exit(EXIT_SUCCESS);
+ return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}
- pair[1] = safe_close(pair[1]);
-
- f = fdopen(pair[0], "re");
- if (!f)
- return -errno;
-
- pair[0] = -1;
-
- r = load_env_file_pairs(f, "os-release", NULL, &v);
+ r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return r;
- r = wait_for_terminate(child, &si);
+ if (sd_id128_is_null(image->machine_id)) /* Add an empty array if the ID is zero */
+ r = sd_bus_message_append(reply, "ay", 0);
+ else
+ r = sd_bus_message_append_array(reply, 'y', image->machine_id.bytes, 16);
if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
- child = 0;
- if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
- if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
-
- *ret = v;
- v = NULL;
+ return r;
- return 0;
+ return sd_bus_send(NULL, reply, NULL);
}
-int bus_image_method_get_os_release(
+int bus_image_method_get_machine_info(
sd_bus_message *message,
void *userdata,
sd_bus_error *error) {
- _cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
- _cleanup_strv_free_ char **v = NULL;
Image *image = userdata;
int r;
- r = image_path_lock(image->path, LOCK_SH|LOCK_NB, &tree_global_lock, &tree_local_lock);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to lock image: %m");
+ if (!image->metadata_valid) {
+ r = image_read_metadata(image);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
+ }
- switch (image->type) {
+ return bus_reply_pair_array(message, image->machine_info);
+}
- case IMAGE_DIRECTORY:
- case IMAGE_SUBVOLUME:
- r = directory_image_get_os_release(image, &v, error);
- break;
+int bus_image_method_get_os_release(
+ sd_bus_message *message,
+ void *userdata,
+ sd_bus_error *error) {
- case IMAGE_RAW:
- case IMAGE_BLOCK:
- r = raw_image_get_os_release(image, &v, error);
- break;
+ Image *image = userdata;
+ int r;
- default:
- assert_not_reached("Unknown image type");
+ if (!image->metadata_valid) {
+ r = image_read_metadata(image);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}
- if (r < 0)
- return r;
- return bus_reply_pair_array(message, v);
+ return bus_reply_pair_array(message, image->os_release);
}
const sd_bus_vtable image_vtable[] = {
@@ -462,6 +388,9 @@ const sd_bus_vtable image_vtable[] = {
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};