1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-31 14:50:15 +03:00

dissect-image: when extracting metadata from image also check if it contains init system

It's good to know whether we can boot the image.
This commit is contained in:
Lennart Poettering 2021-11-19 15:48:41 +01:00
parent 8570b98b12
commit a4e0d61713
2 changed files with 67 additions and 9 deletions

View File

@ -46,6 +46,7 @@
#include "hostname-setup.h"
#include "id128-util.h"
#include "import-util.h"
#include "io-util.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mountpoint-util.h"
@ -748,10 +749,14 @@ int dissect_image(
if (r != 0)
return errno_or_else(EIO);
m = new0(DissectedImage, 1);
m = new(DissectedImage, 1);
if (!m)
return -ENOMEM;
*m = (DissectedImage) {
.has_init_system = -1,
};
r = sd_device_get_sysname(d, &sysname);
if (r < 0)
return log_debug_errno(r, "Failed to get device sysname: %m");
@ -3012,6 +3017,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
META_MACHINE_INFO,
META_OS_RELEASE,
META_EXTENSION_RELEASE,
META_HAS_INIT_SYSTEM,
_META_MAX,
};
@ -3021,7 +3027,8 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
[META_MACHINE_INFO] = "/etc/machine-info\0",
[META_OS_RELEASE] = ("/etc/os-release\0"
"/usr/lib/os-release\0"),
[META_EXTENSION_RELEASE] = "extension-release\0", /* Used only for logging. */
[META_EXTENSION_RELEASE] = "extension-release\0", /* Used only for logging. */
[META_HAS_INIT_SYSTEM] = "has-init-system\0", /* ditto */
};
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **extension_release = NULL;
@ -3032,6 +3039,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
_cleanup_free_ char *hostname = NULL;
unsigned n_meta_initialized = 0;
int fds[2 * _META_MAX], r, v;
int has_init_system = -1;
ssize_t n;
BLOCK_SIGNALS(SIGCHLD);
@ -3063,6 +3071,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
if (r < 0)
goto finish;
if (r == 0) {
/* Child in a new mount namespace */
error_pipe[0] = safe_close(error_pipe[0]);
r = dissected_image_mount(
@ -3092,7 +3101,9 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
fds[2*k] = safe_close(fds[2*k]);
if (k == META_EXTENSION_RELEASE) {
switch (k) {
case META_EXTENSION_RELEASE:
/* As per the os-release spec, if the image is an extension it will have a file
* named after the image name in extension-release.d/ - we use the image name
* and try to resolve it with the extension-release helpers, as sometimes
@ -3105,12 +3116,42 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
r = open_extension_release(t, m->image_name, NULL, &fd);
if (r < 0)
fd = r; /* Propagate the error. */
} else
break;
case META_HAS_INIT_SYSTEM: {
bool found = false;
const char *init;
FOREACH_STRING(init,
"/usr/lib/systemd/systemd", /* systemd on /usr merged system */
"/lib/systemd/systemd", /* systemd on /usr non-merged systems */
"/sbin/init") { /* traditional path the Linux kernel invokes */
r = chase_symlinks(init, t, CHASE_PREFIX_ROOT, NULL, NULL);
if (r < 0) {
if (r != -ENOENT)
log_debug_errno(r, "Failed to resolve %s, ignoring: %m", init);
} else {
found = true;
break;
}
}
r = loop_write(fds[2*k+1], &found, sizeof(found), false);
if (r < 0)
goto inner_fail;
continue;
}
default:
NULSTR_FOREACH(p, paths[k]) {
fd = chase_symlinks_and_open(p, t, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
if (fd >= 0)
break;
}
}
if (fd < 0) {
log_debug_errno(fd, "Failed to read %s file of image, ignoring: %m", paths[k]);
fds[2*k+1] = safe_close(fds[2*k+1]);
@ -3118,15 +3159,17 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
}
r = copy_bytes(fd, fds[2*k+1], UINT64_MAX, 0);
if (r < 0) {
(void) write(error_pipe[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
}
if (r < 0)
goto inner_fail;
fds[2*k+1] = safe_close(fds[2*k+1]);
}
_exit(EXIT_SUCCESS);
inner_fail:
(void) write(error_pipe[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
}
error_pipe[1] = safe_close(error_pipe[1]);
@ -3194,7 +3237,20 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
log_debug_errno(r, "Failed to read extension release file: %m");
break;
}
case META_HAS_INIT_SYSTEM: {
bool b = false;
size_t nr;
errno = 0;
nr = fread(&b, 1, sizeof(b), f);
if (nr != sizeof(b))
log_debug_errno(errno_or_else(EIO), "Failed to read has-init-system boolean: %m");
else
has_init_system = b;
break;
}}
}
r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
@ -3218,6 +3274,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
strv_free_and_replace(m->machine_info, machine_info);
strv_free_and_replace(m->os_release, os_release);
strv_free_and_replace(m->extension_release, extension_release);
m->has_init_system = has_init_system;
finish:
for (unsigned k = 0; k < n_meta_initialized; k++)

View File

@ -163,6 +163,7 @@ struct DissectedImage {
char **machine_info;
char **os_release;
char **extension_release;
int has_init_system;
};
struct MountOptions {