sysext: export backing devnum in metadata dir

This commit is contained in:
Lennart Poettering
2025-03-05 15:22:45 +01:00
parent 42c589eae5
commit 02d0848df3

View File

@@ -11,6 +11,7 @@
#include "sd-bus.h"
#include "sd-varlink.h"
#include "blockdev-util.h"
#include "build.h"
#include "bus-error.h"
#include "bus-locator.h"
@@ -1198,19 +1199,24 @@ static int hierarchy_as_lower_dir(OverlayFSPaths *op) {
return 0;
}
static int determine_bottom_lower_dirs(OverlayFSPaths *op) {
static int determine_bottom_lower_dirs(OverlayFSPaths *op, dev_t *ret_backing_devnum) {
int r;
assert(op);
assert(ret_backing_devnum);
r = hierarchy_as_lower_dir(op);
if (r < 0)
return r;
if (!r) {
r = strv_extend(&op->lower_dirs, op->resolved_hierarchy);
if (r < 0)
if (strv_extend(&op->lower_dirs, op->resolved_hierarchy) < 0)
return log_oom();
}
r = get_block_device(op->resolved_hierarchy, ret_backing_devnum);
if (r < 0)
return log_error_errno(r, "Failed to get block device of '%s': %m", op->resolved_hierarchy);
} else
*ret_backing_devnum = 0;
return 0;
}
@@ -1218,12 +1224,14 @@ static int determine_bottom_lower_dirs(OverlayFSPaths *op) {
static int determine_lower_dirs(
OverlayFSPaths *op,
char **paths,
const char *meta_path) {
const char *meta_path,
dev_t *ret_backing_devnum) {
int r;
assert(op);
assert(meta_path);
assert(ret_backing_devnum);
r = determine_top_lower_dirs(op, meta_path);
if (r < 0)
@@ -1233,7 +1241,7 @@ static int determine_lower_dirs(
if (r < 0)
return r;
r = determine_bottom_lower_dirs(op);
r = determine_bottom_lower_dirs(op, ret_backing_devnum);
if (r < 0)
return r;
@@ -1420,6 +1428,35 @@ static int write_dev_file(ImageClass image_class, const char *meta_path, const c
return 0;
}
static int write_backing_file(ImageClass image_class, const char *meta_path, const char *overlay_path, const char *hierarchy, dev_t backing) {
int r;
assert(meta_path);
assert(overlay_path);
assert(hierarchy);
if (backing == 0)
return 0;
/* Let's also store away the backing file system dev_t, so that applications can trace back what they are looking at here */
_cleanup_free_ char *f = path_join(meta_path, image_class_info[image_class].dot_directory_name, "backing");
if (!f)
return log_oom();
/* Modifying the underlying layers while the overlayfs is mounted is technically undefined, but at
* least it won't crash or deadlock, as per the kernel docs about overlayfs:
* https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#changes-to-underlying-filesystems */
_cleanup_free_ char *hierarchy_path = path_join(hierarchy, image_class_info[image_class].dot_directory_name, image_class_info[image_class].short_identifier_plural);
if (!hierarchy_path)
return log_oom();
r = write_string_file_full(AT_FDCWD, f, FORMAT_DEVNUM(backing), WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_LABEL, /* ts= */ NULL, hierarchy_path);
if (r < 0)
return log_error_errno(r, "Failed to write '%s': %m", f);
return 0;
}
static int write_work_dir_file(ImageClass image_class, const char *meta_path, const char *work_dir, const char* hierarchy) {
_cleanup_free_ char *escaped_work_dir_in_root = NULL, *f = NULL;
char *work_dir_in_root = NULL;
@@ -1465,7 +1502,8 @@ static int store_info_in_meta(
const char *meta_path,
const char *overlay_path,
const char *work_dir,
const char *hierarchy) {
const char *hierarchy,
dev_t backing) {
int r;
@@ -1501,6 +1539,10 @@ static int store_info_in_meta(
if (r < 0)
return r;
r = write_backing_file(image_class, meta_path, overlay_path, hierarchy, backing);
if (r < 0)
return r;
/* Make sure the top-level dir has an mtime marking the point we established the merge */
if (utimensat(AT_FDCWD, meta_path, NULL, AT_SYMLINK_NOFOLLOW) < 0)
return log_error_errno(r, "Failed fix mtime of '%s': %m", meta_path);
@@ -1575,7 +1617,8 @@ static int merge_hierarchy(
if (r < 0)
return r;
r = determine_lower_dirs(op, used_paths, meta_path);
dev_t backing;
r = determine_lower_dirs(op, used_paths, meta_path, &backing);
if (r < 0)
return r;
@@ -1591,7 +1634,7 @@ static int merge_hierarchy(
if (r < 0)
return r;
r = store_info_in_meta(image_class, extensions, meta_path, overlay_path, op->work_dir, op->hierarchy);
r = store_info_in_meta(image_class, extensions, meta_path, overlay_path, op->work_dir, op->hierarchy, backing);
if (r < 0)
return r;