From c510492aeed15975445fa2c37165840c254244fd Mon Sep 17 00:00:00 2001 From: Martin Schwan Date: Wed, 15 Jul 2026 14:40:44 +0200 Subject: [PATCH 1/5] src: utils: Add helper to check for ext4 image Add a helper function to check a file, whether it is an ext4 image. Signed-off-by: Martin Schwan --- src/pu-utils.c | 27 +++++++++++++++++++++++++++ src/pu-utils.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/pu-utils.c b/src/pu-utils.c index 78bfab51..863e3a3b 100644 --- a/src/pu-utils.c +++ b/src/pu-utils.c @@ -408,6 +408,33 @@ pu_is_drive(const gchar *device) return ret; } +gboolean +pu_is_ext234_image(const gchar *path) +{ + blkid_probe pr; + const gchar *type = NULL; + gboolean ret = FALSE; + + g_return_val_if_fail(g_strcmp0(path, "") > 0, FALSE); + + pr = blkid_new_probe_from_filename(path); + if (!pr) { + return ret; + } + + blkid_probe_enable_superblocks(pr, 1); + blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE); + + if (blkid_do_safeprobe(pr) == 0) { + if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0) { + ret = (type && g_regex_match_simple("^ext[234]$", type, 0, 0)); + } + } + + blkid_free_probe(pr); + return ret; +} + gboolean pu_wait_for_partitions(GError **error) { diff --git a/src/pu-utils.h b/src/pu-utils.h index 72e0958c..8b488a98 100644 --- a/src/pu-utils.h +++ b/src/pu-utils.h @@ -47,6 +47,7 @@ gboolean pu_partition_set_partuuid(const gchar *device, const gchar *partuuid, GError **error); gboolean pu_is_drive(const gchar *device); +gboolean pu_is_ext234_image(const gchar *path); gboolean pu_wait_for_partitions(GError **error); gboolean pu_set_hwreset(const gchar *device, const gchar *hwreset, From 17aa5c4e3e0edff25cd3fcc0dfb09544551ee63a Mon Sep 17 00:00:00 2001 From: Martin Schwan Date: Wed, 15 Jul 2026 14:41:36 +0200 Subject: [PATCH 2/5] src: emmc: Detect files for ext4 magic during writing Detect ext4 images not only based on their filename, but also based on whether they contain an actual ext4 filesystem. This is especially needed, as sometimes ext4 images do not have a reliable filename suffix to search for. The only reliable way is to check for the superblock magic. Signed-off-by: Martin Schwan --- src/pu-emmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pu-emmc.c b/src/pu-emmc.c index 13f2f57e..052f13fd 100644 --- a/src/pu-emmc.c +++ b/src/pu-emmc.c @@ -379,7 +379,8 @@ pu_emmc_write_data(PuFlash *flash, return FALSE; if (!pu_umount(part_mount, error)) return FALSE; - } else if (g_regex_match_simple(".ext[234]$", path, 0, 0)) { + } else if (g_regex_match_simple(".ext[234]$", path, 0, 0) || + pu_is_ext234_image(path)) { if (!pu_write_raw(path, part_path, self->device, 0, 0, 0, error)) return FALSE; if (!pu_resize_filesystem(part_path, error)) From 30a7f6b7ef6193e82a704176c9b5ed4215a8ba6f Mon Sep 17 00:00:00 2001 From: Martin Schwan Date: Wed, 15 Jul 2026 14:44:39 +0200 Subject: [PATCH 3/5] tests: utils: Add test for pu_is_ext234_image Add a unit test for pu_is_ext234_image and check different files. Signed-off-by: Martin Schwan --- tests/utils.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/utils.c b/tests/utils.c index bf940e76..3e4431b0 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -194,6 +194,17 @@ test_device_get_partition_pattern(void) g_assert_false(g_regex_match_simple(pattern, "/dev/sdb1", 0, 0)); } +static void +test_is_ext234_image(void) +{ + g_assert_true(pu_is_ext234_image("data/root.ext4")); + g_assert_false(pu_is_ext234_image("data/random.bin")); + g_assert_false(pu_is_ext234_image("data/file-zero.txt")); + g_assert_false(pu_is_ext234_image("data/file-integer.txt")); + g_assert_false(pu_is_ext234_image("data/lorem.tar")); + g_assert_false(pu_is_ext234_image("data/lorem.txt")); +} + int main(int argc, char *argv[]) @@ -223,6 +234,7 @@ main(int argc, test_device_get_partition_path_fail); g_test_add_func("/utils/str_pre_remove", test_str_pre_remove); g_test_add_func("/utils/device_get_partition_pattern", test_device_get_partition_pattern); + g_test_add_func("/utils/is_ext234_image", test_is_ext234_image); return g_test_run(); } From 1ca16ce87ce01bbb0792a683858c22f58da1e0b1 Mon Sep 17 00:00:00 2001 From: Martin Schwan Date: Thu, 16 Jul 2026 11:17:55 +0200 Subject: [PATCH 4/5] src: emmc: Allow writing any binary to partition with fstype null Allow writing arbitrary binaries to partitions with filesystem specified as null and where the input is not an ext4 image. Signed-off-by: Martin Schwan --- src/pu-emmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pu-emmc.c b/src/pu-emmc.c index 052f13fd..1100c172 100644 --- a/src/pu-emmc.c +++ b/src/pu-emmc.c @@ -387,6 +387,9 @@ pu_emmc_write_data(PuFlash *flash, return FALSE; if (!pu_set_ext_label(part_path, part->label, error)) return FALSE; + } else if (!part->filesystem) { + if (!pu_write_raw(path, part_path, self->device, 0, 0, 0, error)) + return FALSE; } else { if (!pu_mount(part_path, part_mount, NULL, NULL, error)) return FALSE; From a5228aa2c685b42159ca3c4a3bedcee7a2da9667 Mon Sep 17 00:00:00 2001 From: Martin Schwan Date: Thu, 16 Jul 2026 11:34:25 +0200 Subject: [PATCH 5/5] src: mount: Print return and status code during mount/umount When mounting or unmounting fails, print the return and status codes for better debugging of the error. Signed-off-by: Martin Schwan --- src/pu-mount.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pu-mount.c b/src/pu-mount.c index 3223c247..a041b940 100644 --- a/src/pu-mount.c +++ b/src/pu-mount.c @@ -92,6 +92,7 @@ pu_mount(const gchar *source, GError **error) { gint ret; + gint status; struct libmnt_context *ctx; g_return_val_if_fail(g_strcmp0(source, "") > 0, FALSE); @@ -116,9 +117,11 @@ pu_mount(const gchar *source, mnt_context_append_options(ctx, options); ret = mnt_context_mount(ctx); - if (ret || mnt_context_get_status(ctx) != 1) { + status = mnt_context_get_status(ctx); + if (ret || status != 1) { g_set_error(error, PU_ERROR, PU_ERROR_MOUNT, - "Failed mounting '%s' to '%s'", source, mount_point); + "Failed mounting '%s' to '%s': ret %d, status %d", + source, mount_point, ret, status); mnt_free_context(ctx); return FALSE; } @@ -132,6 +135,7 @@ pu_umount(const gchar *mount_point, GError **error) { gint ret; + gint status; struct libmnt_context *ctx; g_return_val_if_fail(g_strcmp0(mount_point, "") > 0, FALSE); @@ -148,9 +152,11 @@ pu_umount(const gchar *mount_point, } mnt_context_set_target(ctx, mount_point); ret = mnt_context_umount(ctx); - if (ret || mnt_context_get_status(ctx) != 1) { + status = mnt_context_get_status(ctx); + if (ret || status != 1) { g_set_error(error, PU_ERROR, PU_ERROR_MOUNT, - "Failed unmounting '%s'", mount_point); + "Failed unmounting '%s': ret %d, status %d", + mount_point, ret, status); mnt_free_context(ctx); return FALSE; }