summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/os-util.h2
-rw-r--r--src/dissect/dissect.c86
-rw-r--r--src/shared/discover-image.c23
-rw-r--r--src/shared/discover-image.h14
-rw-r--r--src/shared/dissect-image.c105
-rw-r--r--src/shared/dissect-image.h4
-rw-r--r--src/sysext/sysext.c2
7 files changed, 143 insertions, 93 deletions
diff --git a/src/basic/os-util.h b/src/basic/os-util.h
index 11afc4c6ca..7cee3dd119 100644
--- a/src/basic/os-util.h
+++ b/src/basic/os-util.h
@@ -10,7 +10,9 @@ typedef enum ImageClass {
IMAGE_MACHINE,
IMAGE_PORTABLE,
IMAGE_SYSEXT,
+ _IMAGE_CLASS_EXTENSION_FIRST = IMAGE_SYSEXT, /* First "extension" image type, so that we can easily generically iterate through them */
IMAGE_CONFEXT,
+ _IMAGE_CLASS_EXTENSION_LAST = IMAGE_CONFEXT, /* Last "extension image type */
_IMAGE_CLASS_MAX,
_IMAGE_CLASS_INVALID = -EINVAL,
} ImageClass;
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 28cced4173..a03f9a64db 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -765,24 +765,40 @@ static void strv_pair_print(char **l, const char *prefix) {
printf("%*s %s=%s\n", (int) strlen(prefix), "", *p, *q);
}
-static int get_extension_scopes(DissectedImage *m, char ***ret_scopes) {
+static int get_extension_scopes(DissectedImage *m, ImageClass class, char ***ret_scopes) {
_cleanup_strv_free_ char **l = NULL;
- const char *e;
+ const char *e, *field_name;
+ char **release_data;
assert(m);
assert(ret_scopes);
+ switch (class) {
+
+ case IMAGE_SYSEXT:
+ release_data = m->sysext_release;
+ field_name = "SYSEXT_SCOPE";
+ break;
+
+ case IMAGE_CONFEXT:
+ release_data = m->confext_release;
+ field_name = "CONFEXT_SCOPE";
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
/* If there's no extension-release file its not a system extension. Otherwise the SYSEXT_SCOPE
* field for sysext images and the CONFEXT_SCOPE field for confext images indicates which scope
* it is for — and it defaults to "system" + "portable" if unset. */
- if (!m->extension_release) {
+
+ if (!release_data) {
*ret_scopes = NULL;
return 0;
}
- e = strv_env_pairs_get(m->extension_release, "SYSEXT_SCOPE");
- if (!e)
- e = strv_env_pairs_get(m->extension_release, "CONFEXT_SCOPE");
+ e = strv_env_pairs_get(release_data, field_name);
if (e)
l = strv_split(e, WHITESPACE);
else
@@ -843,7 +859,6 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
else if (r < 0)
return log_error_errno(r, "Failed to acquire image metadata: %m");
else if (arg_json_format_flags & JSON_FORMAT_OFF) {
- _cleanup_strv_free_ char **extension_scopes = NULL;
if (!sd_id128_is_null(m->image_uuid))
printf("Image UUID: %s\n", SD_ID128_TO_UUID_STRING(m->image_uuid));
@@ -860,15 +875,18 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
"OS Release:");
strv_pair_print(m->initrd_release,
"initrd R.:");
- strv_pair_print(m->extension_release,
- " Ext. Rel.:");
+ strv_pair_print(m->sysext_release,
+ " sysext R.:");
+ strv_pair_print(m->confext_release,
+ "confext R.:");
if (m->hostname ||
!sd_id128_is_null(m->machine_id) ||
!strv_isempty(m->machine_info) ||
!strv_isempty(m->os_release) ||
!strv_isempty(m->initrd_release) ||
- !strv_isempty(m->extension_release))
+ !strv_isempty(m->sysext_release) ||
+ !strv_isempty(m->confext_release))
putc('\n', stdout);
printf(" Use As: %s bootable system for UEFI\n", COLOR_MARK_BOOL(m->partitions[PARTITION_ESP].found));
@@ -881,26 +899,33 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
printf(" %s initrd\n",
COLOR_MARK_BOOL(!strv_isempty(m->initrd_release)));
- r = get_extension_scopes(m, &extension_scopes);
- if (r < 0)
- return log_error_errno(r, "Failed to parse scope: %m");
+ for (ImageClass c = _IMAGE_CLASS_EXTENSION_FIRST; c <= _IMAGE_CLASS_EXTENSION_LAST; c++) {
+ const char *string_class = image_class_to_string(c);
+ _cleanup_strv_free_ char **extension_scopes = NULL;
- const char *string_class = image_class_to_string(m->image_class);
- printf(" %s %s extension for system\n",
- COLOR_MARK_BOOL(strv_contains(extension_scopes, "system")), string_class);
- printf(" %s %s extension for initrd\n",
- COLOR_MARK_BOOL(strv_contains(extension_scopes, "initrd")), string_class);
- printf(" %s %s extension for portable service\n",
- COLOR_MARK_BOOL(strv_contains(extension_scopes, "portable")), string_class);
+ r = get_extension_scopes(m, c, &extension_scopes);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse scopes: %m");
+
+ printf(" %s %s for system\n",
+ COLOR_MARK_BOOL(strv_contains(extension_scopes, "system")), string_class);
+ printf(" %s %s for portable service\n",
+ COLOR_MARK_BOOL(strv_contains(extension_scopes, "portable")), string_class);
+ printf(" %s %s for initrd\n",
+ COLOR_MARK_BOOL(strv_contains(extension_scopes, "initrd")), string_class);
+ }
putc('\n', stdout);
} else {
- _cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL, *irdr = NULL, *exr = NULL;
- _cleanup_strv_free_ char **extension_scopes = NULL;
+ _cleanup_strv_free_ char **sysext_scopes = NULL, **confext_scopes = NULL;
+
+ r = get_extension_scopes(m, IMAGE_SYSEXT, &sysext_scopes);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse sysext scopes: %m");
- r = get_extension_scopes(m, &extension_scopes);
+ r = get_extension_scopes(m, IMAGE_CONFEXT, &confext_scopes);
if (r < 0)
- return log_error_errno(r, "Failed to parse scope: %m");
+ return log_error_errno(r, "Failed to parse confext scopes: %m");
Architecture a = dissected_image_architecture(m);
@@ -915,15 +940,18 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->machine_info), "machineInfo", JSON_BUILD_STRV_ENV_PAIR(m->machine_info)),
JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->os_release), "osRelease", JSON_BUILD_STRV_ENV_PAIR(m->os_release)),
JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->initrd_release), "initrdRelease", JSON_BUILD_STRV_ENV_PAIR(m->initrd_release)),
- JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->extension_release), "extensionRelease", JSON_BUILD_STRV_ENV_PAIR(m->extension_release)),
+ JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->sysext_release), "sysextRelease", JSON_BUILD_STRV_ENV_PAIR(m->sysext_release)),
+ JSON_BUILD_PAIR_CONDITION(!strv_isempty(m->confext_release), "confextRelease", JSON_BUILD_STRV_ENV_PAIR(m->confext_release)),
JSON_BUILD_PAIR("useBootableUefi", JSON_BUILD_BOOLEAN(m->partitions[PARTITION_ESP].found)),
JSON_BUILD_PAIR_CONDITION(m->has_init_system >= 0, "useBootableContainer", JSON_BUILD_BOOLEAN(m->has_init_system)),
JSON_BUILD_PAIR("useInitrd", JSON_BUILD_BOOLEAN(!strv_isempty(m->initrd_release))),
JSON_BUILD_PAIR("usePortableService", JSON_BUILD_BOOLEAN(strv_env_pairs_get(m->os_release, "PORTABLE_MATCHES"))),
- JSON_BUILD_PAIR("ExtensionType", JSON_BUILD_STRING(image_class_to_string(m->image_class))),
- JSON_BUILD_PAIR("useSystemExtension", JSON_BUILD_BOOLEAN(strv_contains(extension_scopes, "system"))),
- JSON_BUILD_PAIR("useInitRDExtension", JSON_BUILD_BOOLEAN(strv_contains(extension_scopes, "initrd"))),
- JSON_BUILD_PAIR("usePortableExtension", JSON_BUILD_BOOLEAN(strv_contains(extension_scopes, "portable")))));
+ JSON_BUILD_PAIR("useSystemExtension", JSON_BUILD_BOOLEAN(strv_contains(sysext_scopes, "system"))),
+ JSON_BUILD_PAIR("useInitRDSystemExtension", JSON_BUILD_BOOLEAN(strv_contains(sysext_scopes, "initrd"))),
+ JSON_BUILD_PAIR("usePortableSystemExtension", JSON_BUILD_BOOLEAN(strv_contains(sysext_scopes, "portable"))),
+ JSON_BUILD_PAIR("useConfigurationExtension", JSON_BUILD_BOOLEAN(strv_contains(confext_scopes, "system"))),
+ JSON_BUILD_PAIR("useInitRDConfigurationExtension", JSON_BUILD_BOOLEAN(strv_contains(confext_scopes, "initrd"))),
+ JSON_BUILD_PAIR("usePortableConfigurationExtension", JSON_BUILD_BOOLEAN(strv_contains(confext_scopes, "portable")))));
if (r < 0)
return log_oom();
}
diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c
index e407820e18..094337616d 100644
--- a/src/shared/discover-image.c
+++ b/src/shared/discover-image.c
@@ -101,7 +101,8 @@ static Image *image_free(Image *i) {
free(i->hostname);
strv_free(i->machine_info);
strv_free(i->os_release);
- strv_free(i->extension_release);
+ strv_free(i->sysext_release);
+ strv_free(i->confext_release);
return mfree(i);
}
@@ -1180,10 +1181,9 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) {
case IMAGE_SUBVOLUME:
case IMAGE_DIRECTORY: {
- _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **extension_release = NULL;
+ _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **sysext_release = NULL, **confext_release = NULL;
+ _cleanup_free_ char *hostname = NULL, *path = NULL;
sd_id128_t machine_id = SD_ID128_NULL;
- _cleanup_free_ char *hostname = NULL;
- _cleanup_free_ char *path = NULL;
if (i->class == IMAGE_SYSEXT) {
r = extension_has_forbidden_content(i->path);
@@ -1223,16 +1223,20 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) {
if (r < 0)
log_debug_errno(r, "Failed to read os-release in image, ignoring: %m");
- r = load_extension_release_pairs(i->path, i->class, i->name, /* relax_extension_release_check= */ false, &extension_release);
+ r = load_extension_release_pairs(i->path, IMAGE_SYSEXT, i->name, /* relax_extension_release_check= */ false, &sysext_release);
if (r < 0)
- log_debug_errno(r, "Failed to read extension-release in image, ignoring: %m");
+ log_debug_errno(r, "Failed to read sysext-release in image, ignoring: %m");
+
+ r = load_extension_release_pairs(i->path, IMAGE_CONFEXT, i->name, /* relax_extension_release_check= */ false, &confext_release);
+ if (r < 0)
+ log_debug_errno(r, "Failed to read confext-release in image, ignoring: %m");
free_and_replace(i->hostname, hostname);
i->machine_id = machine_id;
strv_free_and_replace(i->machine_info, machine_info);
strv_free_and_replace(i->os_release, os_release);
- strv_free_and_replace(i->extension_release, extension_release);
-
+ strv_free_and_replace(i->sysext_release, sysext_release);
+ strv_free_and_replace(i->confext_release, confext_release);
break;
}
@@ -1271,7 +1275,8 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) {
i->machine_id = m->machine_id;
strv_free_and_replace(i->machine_info, m->machine_info);
strv_free_and_replace(i->os_release, m->os_release);
- strv_free_and_replace(i->extension_release, m->extension_release);
+ strv_free_and_replace(i->sysext_release, m->sysext_release);
+ strv_free_and_replace(i->confext_release, m->confext_release);
break;
}
diff --git a/src/shared/discover-image.h b/src/shared/discover-image.h
index edfb1412a4..bb046fae1e 100644
--- a/src/shared/discover-image.h
+++ b/src/shared/discover-image.h
@@ -45,7 +45,8 @@ typedef struct Image {
sd_id128_t machine_id;
char **machine_info;
char **os_release;
- char **extension_release;
+ char **sysext_release;
+ char **confext_release;
bool metadata_valid:1;
bool discoverable:1; /* true if we know for sure that image_find() would find the image given just the short name */
@@ -80,6 +81,17 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy);
bool image_in_search_path(ImageClass class, const char *root, const char *image);
+static inline char **image_extension_release(Image *image, ImageClass class) {
+ assert(image);
+
+ if (class == IMAGE_SYSEXT)
+ return image->sysext_release;
+ if (class == IMAGE_CONFEXT)
+ return image->confext_release;
+
+ return NULL;
+}
+
static inline bool IMAGE_IS_HIDDEN(const struct Image *i) {
assert(i);
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 278d2291a2..e63545312a 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -1665,7 +1665,8 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
strv_free(m->machine_info);
strv_free(m->os_release);
strv_free(m->initrd_release);
- strv_free(m->extension_release);
+ strv_free(m->confext_release);
+ strv_free(m->sysext_release);
return mfree(m);
}
@@ -3352,7 +3353,8 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
META_MACHINE_INFO,
META_OS_RELEASE,
META_INITRD_RELEASE,
- META_EXTENSION_RELEASE,
+ META_SYSEXT_RELEASE,
+ META_CONFEXT_RELEASE,
META_HAS_INIT_SYSTEM,
_META_MAX,
};
@@ -3361,15 +3363,16 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
[META_HOSTNAME] = "/etc/hostname\0",
[META_MACHINE_ID] = "/etc/machine-id\0",
[META_MACHINE_INFO] = "/etc/machine-info\0",
- [META_OS_RELEASE] = ("/etc/os-release\0"
- "/usr/lib/os-release\0"),
- [META_INITRD_RELEASE] = ("/etc/initrd-release\0"
- "/usr/lib/initrd-release\0"),
- [META_EXTENSION_RELEASE] = "extension-release\0", /* Used only for logging. */
+ [META_OS_RELEASE] = "/etc/os-release\0"
+ "/usr/lib/os-release\0",
+ [META_INITRD_RELEASE] = "/etc/initrd-release\0"
+ "/usr/lib/initrd-release\0",
+ [META_SYSEXT_RELEASE] = "sysext-release\0", /* String used only for logging. */
+ [META_CONFEXT_RELEASE] = "confext-release\0", /* ditto */
[META_HAS_INIT_SYSTEM] = "has-init-system\0", /* ditto */
};
- _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **extension_release = NULL;
+ _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **sysext_release = NULL, **confext_release = NULL;
_cleanup_close_pair_ int error_pipe[2] = PIPE_EBADF;
_cleanup_(rmdir_and_freep) char *t = NULL;
_cleanup_(sigkill_waitp) pid_t child = 0;
@@ -3379,12 +3382,10 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
int fds[2 * _META_MAX], r, v;
int has_init_system = -1;
ssize_t n;
- ImageClass image_class = IMAGE_SYSEXT;
BLOCK_SIGNALS(SIGCHLD);
assert(m);
- assert(image_class);
for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) {
if (!paths[n_meta_initialized]) {
@@ -3439,40 +3440,46 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
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
- * the image names are mangled on deployment and do not match anymore.
- * Unlike other paths this is not fixed, and the image name
- * can be mangled on deployment, so by calling into the helper
- * we allow a fallback that matches on the first extension-release
- * file found in the directory, if one named after the image cannot
- * be found first. */
- ImageClass class = IMAGE_SYSEXT;
- r = open_extension_release(t, IMAGE_SYSEXT, m->image_name, /* relax_extension_release_check= */ false, NULL, &fd);
- if (r == -ENOENT) {
- r = open_extension_release(t, IMAGE_CONFEXT, m->image_name, /* relax_extension_release_check= */ false, NULL, &fd);
- if (r >= 0)
- class = IMAGE_CONFEXT;
- }
+ case META_SYSEXT_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 the image names are mangled on deployment and do not match
+ * anymore. Unlike other paths this is not fixed, and the image name can be
+ * mangled on deployment, so by calling into the helper we allow a fallback
+ * that matches on the first extension-release file found in the directory,
+ * if one named after the image cannot be found first. */
+ r = open_extension_release(
+ t,
+ IMAGE_SYSEXT,
+ m->image_name,
+ /* relax_extension_release_check= */ false,
+ /* ret_path= */ NULL,
+ &fd);
+ if (r < 0)
+ fd = r;
+ break;
+
+ case META_CONFEXT_RELEASE:
+ /* As above */
+ r = open_extension_release(
+ t,
+ IMAGE_CONFEXT,
+ m->image_name,
+ /* relax_extension_release_check= */ false,
+ /* ret_path= */ NULL,
+ &fd);
if (r < 0)
fd = r;
- else {
- r = loop_write(fds[2*k+1], &class, sizeof(class));
- if (r < 0)
- goto inner_fail; /* Propagate the error to the parent */
- }
break;
- }
case META_HAS_INIT_SYSTEM: {
bool found = false;
FOREACH_STRING(init,
- "/usr/lib/systemd/systemd", /* systemd on /usr merged system */
- "/lib/systemd/systemd", /* systemd on /usr non-merged systems */
+ "/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(init, t, CHASE_PREFIX_ROOT, NULL, NULL);
@@ -3587,23 +3594,19 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
break;
- case META_EXTENSION_RELEASE: {
- ImageClass cl = IMAGE_SYSEXT;
- size_t nr;
+ case META_SYSEXT_RELEASE:
+ r = load_env_file_pairs(f, "sysext-release", &sysext_release);
+ if (r < 0)
+ log_debug_errno(r, "Failed to read sysext release file of image: %m");
- errno = 0;
- nr = fread(&cl, 1, sizeof(cl), f);
- if (nr != sizeof(cl))
- log_debug_errno(errno_or_else(EIO), "Failed to read class of extension image: %m");
- else {
- image_class = cl;
- r = load_env_file_pairs(f, "extension-release", &extension_release);
- if (r < 0)
- log_debug_errno(r, "Failed to read extension release file of image: %m");
- }
+ break;
+
+ case META_CONFEXT_RELEASE:
+ r = load_env_file_pairs(f, "confext-release", &confext_release);
+ if (r < 0)
+ log_debug_errno(r, "Failed to read confext release file of image: %m");
break;
- }
case META_HAS_INIT_SYSTEM: {
bool b = false;
@@ -3641,9 +3644,9 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
strv_free_and_replace(m->machine_info, machine_info);
strv_free_and_replace(m->os_release, os_release);
strv_free_and_replace(m->initrd_release, initrd_release);
- strv_free_and_replace(m->extension_release, extension_release);
+ strv_free_and_replace(m->sysext_release, sysext_release);
+ strv_free_and_replace(m->confext_release, confext_release);
m->has_init_system = has_init_system;
- m->image_class = image_class;
finish:
for (unsigned k = 0; k < n_meta_initialized; k++)
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index eb0841bd2e..21a0f22bcc 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -108,9 +108,9 @@ struct DissectedImage {
char **machine_info;
char **os_release;
char **initrd_release;
- char **extension_release;
+ char **confext_release;
+ char **sysext_release;
int has_init_system;
- ImageClass image_class;
};
struct MountOptions {
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 784accc15d..becfbab44e 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -741,7 +741,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
host_os_release_version_id,
host_os_release_api_level,
in_initrd() ? "initrd" : "system",
- img->extension_release,
+ image_extension_release(img, arg_image_class),
arg_image_class);
if (r < 0)
return r;