diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-12-01 23:24:20 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-12-07 18:38:41 +0100 |
commit | 9153b02bb5030e29d6008992fb74b9028d7c392c (patch) | |
tree | 23746568f265466f93388d66df417f56ceda50a0 /src/machine/machine-dbus.c | |
parent | 676bcb0fc042c24e4335832622ea4104a1295b48 (diff) |
machined: add API for querying the OS release of a machine image
This adds a bus call GetImageOSRelease() to the Manager interface that
retrieves the /etc/os-release file of a machine image. It matches the existing
GetMachineOSRelease() call, however operates on a disk image rather than a
running container.
The backend for this call on .raw images is implemented via the generalized
image dissector, which makes this scheme relatively easy to implement.
Diffstat (limited to 'src/machine/machine-dbus.c')
-rw-r--r-- | src/machine/machine-dbus.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 28e4867cb3..af745b6567 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -356,11 +356,11 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd return sd_bus_send(NULL, reply, NULL); } +#define EXIT_NOT_FOUND 2 + int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_strv_free_ char **l = NULL; Machine *m = userdata; - char **k, **v; int r; assert(message); @@ -394,7 +394,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); if (child == 0) { - _cleanup_close_ int fd = -1; + int fd = -1; pair[0] = safe_close(pair[0]); @@ -402,12 +402,14 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s if (r < 0) _exit(EXIT_FAILURE); - fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); - if (fd < 0) { - fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC); - if (fd < 0) - _exit(EXIT_FAILURE); + 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); r = copy_bytes(fd, pair[1], (uint64_t) -1, false); if (r < 0) @@ -431,6 +433,8 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s r = wait_for_terminate(child, &si); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m"); + if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND) + return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Machine 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."); @@ -441,25 +445,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines."); } - r = sd_bus_message_new_method_return(message, &reply); - if (r < 0) - return r; - - r = sd_bus_message_open_container(reply, 'a', "{ss}"); - if (r < 0) - return r; - - STRV_FOREACH_PAIR(k, v, l) { - r = sd_bus_message_append(reply, "{ss}", *k, *v); - if (r < 0) - return r; - } - - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return sd_bus_send(NULL, reply, NULL); + return bus_reply_pair_array(message, l); } int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) { |