get_sysext_overlay_block -> extension_overlay_block

For re-use in systemd-gpt-auto-generator. This also makes it generic
across sysext/confext - no planned use for this, but to avoid confusion
later when someone tries to use it on a confext.
This commit is contained in:
Kai Wohlfahrt
2026-09-10 13:47:22 +02:00
committed by Kai Wohlfahrt
parent aaab1f107c
commit 31584c62d3
3 changed files with 56 additions and 44 deletions
+50
View File
@@ -1,12 +1,20 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/magic.h>
#include "alloc-util.h"
#include "architecture.h"
#include "blockdev-util.h"
#include "chase.h"
#include "devnum-util.h"
#include "env-util.h"
#include "extension-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "log.h"
#include "os-util.h"
#include "path-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
@@ -178,3 +186,45 @@ int extension_has_forbidden_content(const char *root) {
return 0;
}
int extension_overlay_block(const char *p, ImageClass image_class, dev_t *ret) {
int r;
assert(p);
assert(ret);
/* Tries to read the backing device information systemd-sysext puts in
* the virtual file .systemd-sysext/.systemd-confext */
_cleanup_free_ char *j = path_join(p, image_class == IMAGE_CONFEXT ? ".systemd-confext" : ".systemd-sysext");
if (!j)
return log_oom_debug();
_cleanup_close_ int fd = open(j, O_RDONLY|O_DIRECTORY);
if (fd < 0)
return log_debug_errno(errno, "Failed to open '%s': %m", j);
r = fd_is_fs_type(fd, OVERLAYFS_SUPER_MAGIC);
if (r < 0)
return log_debug_errno(r, "Failed to determine backing file system of '%s': %m", j);
if (r == 0)
return log_debug_errno(
SYNTHETIC_ERRNO(ENOTTY), "Backing file system of '%s' is not an overlayfs.", j);
_cleanup_free_ char *buf = NULL;
r = read_one_line_file_at(fd, "backing", &buf);
if (r < 0)
return log_debug_errno(r, "Failed to read contents of '%s/backing': %m", j);
r = parse_devnum(buf, ret);
if (r < 0)
return log_debug_errno(r, "Failed to parse contents of '%s/backing': %m", j);
if (major(*ret) == 0) { /* not a block device? */
*ret = 0;
return 0;
}
(void) block_get_originating(*ret, ret, /* recursive= */ false);
return 1;
}
+3
View File
@@ -22,3 +22,6 @@ int parse_env_extension_hierarchies(char ***ret_hierarchies, const char *hierarc
/* Insist that extension images do not overwrite the underlying OS release file (it's fine if they place one
* in /etc/os-release, i.e. where things don't matter, as they aren't merged.) */
int extension_has_forbidden_content(const char *root);
/* Find the backing device. Returns >0 on success, 0 if the volume is not an extension, and <0 on error. */
int extension_overlay_block(const char *p, ImageClass image_class, dev_t *ret);
+3 -44
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <linux/magic.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -10,10 +9,10 @@
#include "build-path.h"
#include "chase.h"
#include "device-util.h"
#include "devnum-util.h"
#include "dirent-util.h"
#include "env-util.h"
#include "errno-util.h"
#include "extension-util.h"
#include "fd-util.h"
#include "fdisk-util.h"
#include "fileio.h"
@@ -23,6 +22,7 @@
#include "hexdecoct.h"
#include "import-util.h"
#include "iovec-util.h"
#include "os-util.h"
#include "path-util.h"
#include "pidref.h"
#include "process-util.h"
@@ -766,47 +766,6 @@ Instance* resource_find_instance(Resource *rr, const char *version) {
return *found;
}
static int get_sysext_overlay_block(const char *p, dev_t *ret) {
int r;
assert(p);
assert(ret);
/* Tries to read the backing device information systemd-sysext puts in the virtual file
* /usr/.systemd-sysext/backing */
_cleanup_free_ char *j = path_join(p, ".systemd-sysext");
if (!j)
return log_oom_debug();
_cleanup_close_ int fd = open(j, O_RDONLY|O_DIRECTORY);
if (fd < 0)
return log_debug_errno(errno, "Failed to open '%s': %m", j);
r = fd_is_fs_type(fd, OVERLAYFS_SUPER_MAGIC);
if (r < 0)
return log_debug_errno(r, "Failed to determine backing file system of '%s': %m", j);
if (r == 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTTY), "Backing file system of '%s' is not an overlayfs.", j);
_cleanup_free_ char *buf = NULL;
r = read_one_line_file_at(fd, "backing", &buf);
if (r < 0)
return log_debug_errno(r, "Failed to read contents of '%s/backing': %m", j);
r = parse_devnum(buf, ret);
if (r < 0)
return log_debug_errno(r, "Failed to parse contents of '%s/backing': %m", j);
if (major(*ret) == 0) { /* not a block device? */
*ret = 0;
return 0;
}
(void) block_get_originating(*ret, ret, /* recursive= */ false);
return 1;
}
int resource_resolve_path(
Resource *rr,
const char *root,
@@ -858,7 +817,7 @@ int resource_resolve_path(
/* volatile-root not found */
r = get_block_device_harder("/usr/", &d);
if (r == 0) /* Not backed by a block device? Let's see if this is a sysext overlayfs instance */
r = get_sysext_overlay_block("/usr/", &d);
r = extension_overlay_block("/usr/", IMAGE_SYSEXT, &d);
if (r < 0)
return log_error_errno(r, "Failed to determine block device of file system: %m");
} else if (!S_ISBLK(orig_root_stats.st_mode)) /* symlink was present but not block device */