From: Lennart Poettering Date: Wed, 5 Mar 2025 14:22:45 +0000 (+0100) Subject: sysext: export backing devnum in metadata dir X-Git-Tag: v258-rc1~1164^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=02d0848df3f95a3d1dfffa048875e7987a6f1d3b;p=thirdparty%2Fsystemd.git sysext: export backing devnum in metadata dir --- diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index dec0becda03..420262cd452 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -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;