From ea4f248945f195c3fb9038a02218be1d4ce19ee7 Mon Sep 17 00:00:00 2001 From: Eric Fahlgren Date: Mon, 24 Aug 2026 10:23:34 -0700 Subject: [PATCH] system: provide missing image type information An ongoing chronic pain point when performing upgrades is determining which of several images is the correct one. For most devices, this is a simple choice between "factory" or "sysupgrade", with the latter being the correct choice. On several targets, the choice is not so obvious. For example, on the x86/64 target, we have "combined" and "combined-efi" images, and users must somehow determine which is appropriate. The armsr and loongarch devices are simpler with only "combined-efi", and tegra only has "sdcard". On the ramips/mt7621 target there are five Mikrotik devices that have both "sysupgrade" and "sysupgrade-v7". Further, the new spacemit/k1 target has three: "sdcard", "emmc" and "other". Note that although much of this deals with automated systems (ASU), it will also benefit manual upgrades by providing the user with needed information from a reliable source. Since there is currently no way to determine which image is installed on-device, we are adding a new mechanism to allow per-target definition of that data and exposing it through the system board call. On-device generation of "/tmp/sysinfo/image_type" contents is left open so as to allow flexibility of implementation. Details ------- To illustrate the selection mechanism, we'll provide an example taken from ath79/generic/profiles.json. This is a minimized snippet, all "images" entries are retained, but unrelated field values have been deleted. { "profiles": { "tplink_archer-c7-v4": { "images": [ { "filesystem": "squashfs", "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-sysupgrade.bin", "type": "sysupgrade" }, { "filesystem": "initramfs", "name": "openwrt-ath79-generic-tplink_archer-c7-v4-initramfs-kernel.bin", "type": "kernel" }, { "filesystem": "squashfs", "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-factory.bin", "type": "factory" } ] } } } Currently we can derive two of the three keys easily: ubus call system board | \ jsonfilter -e 'profile=$.board_name' \ -e 'filesystem=$.rootfs_type' Then image selection becomes profiles[$profile].images[@.filesystem = $filesystem && @.type = "sysupgrade"] For most targets, guessing that the profile's image type is 'sysupgrade' works, but for quite a few it fails. Examples from x86/64 and spacemit/generic, in both we've omitted many sections and fields to focus on the issue at hand: "images": [ { "filesystem": "squashfs", "name": "openwrt-x86-64-generic-squashfs-combined.img.gz", "type": "combined" }, { "filesystem": "squashfs", "name": "openwrt-x86-64-generic-squashfs-combined-efi.img.gz", "type": "combined-efi" } ] "images": [ { "filesystem": "erofs", "name": "openwrt-spacemit-k1-generic-erofs-other.img.gz", "type": "other" }, { "filesystem": "erofs", "name": "openwrt-spacemit-k1-generic-erofs-emmc.img.gz", "type": "emmc" }, { "filesystem": "erofs", "name": "openwrt-spacemit-k1-generic-erofs-sdcard.img.gz", "type": "sdcard" } ] Link: https://github.com/efahl/owut/issues/68 Link: https://github.com/openwrt/openwrt/pull/23231#issuecomment-5386675525 Signed-off-by: Eric Fahlgren --- system.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/system.c b/system.c index f6fe444..f748e6f 100644 --- a/system.c +++ b/system.c @@ -251,6 +251,22 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj, if (rootfs_type) blobmsg_add_string(&b, "rootfs_type", rootfs_type); + if ((f = fopen("/tmp/sysinfo/image_type", "r")) != NULL) + { + /* Strictly optional, don't try to guess if it is + * not explicit. + */ + if (fgets(line, sizeof(line), f)) + { + val = strtok(line, "\t\n"); + + if (val) + blobmsg_add_string(&b, "image_type", val); + } + + fclose(f); + } + if ((f = fopen("/usr/lib/os-release", "r")) != NULL) { c = blobmsg_open_table(&b, "release");