summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2021-01-27 13:03:37 +0000
committerLuca Boccassi <luca.boccassi@microsoft.com>2021-02-17 21:45:31 +0000
commit7718ac97219d3bcfcc79b5a10e3e46c2099154d5 (patch)
tree9d3d2b48d93c9139397ea4e6ed233e8e766dbea0 /src/shared
parent593fe6c04df0a9f9a2d93390837c4c756729d2cf (diff)
downloadsystemd-7718ac97219d3bcfcc79b5a10e3e46c2099154d5.tar.gz
dissect: parse, store and show extension-release info
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/dissect-image.c62
-rw-r--r--src/shared/dissect-image.h1
2 files changed, 50 insertions, 13 deletions
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index d557b46e90..2799f4f268 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -23,6 +23,7 @@
#include "def.h"
#include "device-nodes.h"
#include "device-util.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "dm-util.h"
#include "env-file.h"
@@ -1230,6 +1231,7 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
free(m->hostname);
strv_free(m->machine_info);
strv_free(m->os_release);
+ strv_free(m->extension_release);
return mfree(m);
}
@@ -1400,7 +1402,7 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
/* Returns:
*
* -ENXIO → No root partition found
- * -EMEDIUMTYPE → DISSECT_IMAGE_VALIDATE_OS set but no os-release file found
+ * -EMEDIUMTYPE → DISSECT_IMAGE_VALIDATE_OS set but no os-release/extension-release file found
* -EUNATCH → Encrypted partition found for which no dm-crypt was set up yet
* -EUCLEAN → fsck for file system failed
* -EBUSY → File system already mounted/used elsewhere (kernel)
@@ -1430,8 +1432,13 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
r = path_is_os_tree(where);
if (r < 0)
return r;
- if (r == 0)
- return -EMEDIUMTYPE;
+ if (r == 0) {
+ r = path_is_extension_tree(where, m->image_name);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -EMEDIUMTYPE;
+ }
}
}
@@ -1511,7 +1518,7 @@ int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t u
if (r == -ENXIO)
return log_error_errno(r, "Not root file system found in image.");
if (r == -EMEDIUMTYPE)
- return log_error_errno(r, "No suitable os-release file in image found.");
+ return log_error_errno(r, "No suitable os-release/extension-release file in image found.");
if (r == -EUNATCH)
return log_error_errno(r, "Encrypted file system discovered, but decryption not requested.");
if (r == -EUCLEAN)
@@ -2237,18 +2244,20 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
META_MACHINE_ID,
META_MACHINE_INFO,
META_OS_RELEASE,
+ META_EXTENSION_RELEASE,
_META_MAX,
};
- static const char *const paths[_META_MAX] = {
- [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"),
+ static const char *paths[_META_MAX] = {
+ [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_EXTENSION_RELEASE] = NULL,
};
- _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL;
+ _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **extension_release = NULL;
_cleanup_close_pair_ int error_pipe[2] = { -1, -1 };
_cleanup_(rmdir_and_freep) char *t = NULL;
_cleanup_(sigkill_waitp) pid_t child = 0;
@@ -2262,11 +2271,21 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
assert(m);
- for (; n_meta_initialized < _META_MAX; n_meta_initialized ++)
+ /* 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/ */
+ if (m->image_name)
+ paths[META_EXTENSION_RELEASE] = strjoina("/usr/lib/extension-release.d/extension-release.", m->image_name);
+ else
+ log_debug("No image name available, will skip extension-release metadata");
+
+ for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) {
+ if (!paths[n_meta_initialized])
+ continue;
if (pipe2(fds + 2*n_meta_initialized, O_CLOEXEC) < 0) {
r = -errno;
goto finish;
}
+ }
r = mkdtemp_malloc("/tmp/dissect-XXXXXX", &t);
if (r < 0)
@@ -2296,6 +2315,9 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
_cleanup_close_ int fd = -ENOENT;
const char *p;
+ if (!paths[k])
+ continue;
+
fds[2*k] = safe_close(fds[2*k]);
NULSTR_FOREACH(p, paths[k]) {
@@ -2326,6 +2348,9 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
for (k = 0; k < _META_MAX; k++) {
_cleanup_fclose_ FILE *f = NULL;
+ if (!paths[k])
+ continue;
+
fds[2*k+1] = safe_close(fds[2*k+1]);
f = take_fdopen(&fds[2*k], "r");
@@ -2376,6 +2401,13 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
log_debug_errno(r, "Failed to read OS release file: %m");
break;
+
+ case META_EXTENSION_RELEASE:
+ r = load_env_file_pairs(f, "extension-release", &extension_release);
+ if (r < 0)
+ log_debug_errno(r, "Failed to read extension release file: %m");
+
+ break;
}
}
@@ -2399,10 +2431,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
m->machine_id = machine_id;
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);
finish:
- for (k = 0; k < n_meta_initialized; k++)
+ for (k = 0; k < n_meta_initialized; k++) {
+ if (!paths[k])
+ continue;
safe_close_pair(fds + 2*k);
+ }
return r;
}
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index fc120b29b4..8907850000 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -102,6 +102,7 @@ struct DissectedImage {
sd_id128_t machine_id;
char **machine_info;
char **os_release;
+ char **extension_release;
};
struct MountOptions {