@@ -33,6 +33,10 @@ config HAVE_LIBFDISK
bool
option env="HAVE_LIBFDISK"
+config HAVE_LIBBLKID
+ bool
+ option env="HAVE_LIBBLKID"
+
config HAVE_LIBGPIOD
bool
option env="HAVE_LIBGPIOD"
@@ -18,6 +18,10 @@ ifeq ($(HAVE_LIBFDISK),)
export HAVE_LIBFDISK = y
endif
+ifeq ($(HAVE_LIBBLKID),)
+export HAVE_LIBBLKID = y
+endif
+
ifeq ($(HAVE_LIBGPIOD),)
export HAVE_LIBGPIOD = y
endif
@@ -181,6 +181,10 @@ ifeq ($(CONFIG_DISKPART),y)
LDLIBS += fdisk
endif
+ifeq ($(CONFIG_UNIQUEUUID),y)
+LDLIBS += blkid
+endif
+
ifeq ($(CONFIG_RDIFFHANDLER),y)
LDLIBS += rsync
endif
@@ -835,3 +835,25 @@ MBR Example:
partition-6 = ["size=512M", "start=2234368", "name=part6", "type=0x83"];
}
}
+
+Unique UUID Handler
+-------------------
+
+This handler checks if the device already has a filesystems with a provide UUID. This is helpful
+in case the bootloader chooses the device to boot from the UUID and not from the partition number.
+One use case is with the GRUB bootloader when GRUB_DISABLE_LINUX_UUID is not set, as usual on
+Linux Distro as Debian or Ubuntu.
+
+The handler iterates all UUIDs given in sw-description and raises error if one of them is
+found on the device. It is a partition handler and it runs before any image is installed.
+
+::
+
+ partitions: (
+ {
+ type = "uniqueuuid";
+ properties: {
+ fs-uuid = ["21f16cae-612f-4bc6-8ef5-e68cc9dc4380",
+ "18e12df1-d8e1-4283-8727-37727eb4261d"];
+ }
+ });
@@ -102,6 +102,23 @@ config DISKPART
comment "diskpart support needs libfdisk"
depends on !HAVE_LIBFDISK
+config UNIQUEUUID
+ bool "uniqueuuid"
+ depends on HAVE_LIBBLKID
+ default n
+ help
+ This handler checks that no filesystem on the device has
+ a UUID from a list (list is added as part of "properties"
+ in sw-description) for this handler.
+ This is useful for bootloader (like GRUB) that use UUID to
+ select the partition to be started, and in case two or
+ more filesystem have the same UUID, a wrong one is started.
+ This handler is a partition handler and it is guaranteed that
+ it runs before any image is installed on the device.
+
+comment "uniqueuuid support needs libblkid"
+ depends on !HAVE_LIBBLKID
+
config RAW
bool "raw"
default n
@@ -12,6 +12,7 @@ obj-$(CONFIG_ARCHIVE) += archive_handler.o
obj-$(CONFIG_BOOTLOADERHANDLER) += boot_handler.o
obj-$(CONFIG_CFI) += flash_handler.o
obj-$(CONFIG_DISKPART) += diskpart_handler.o
+obj-$(CONFIG_UNIQUEUUID) += uniqueuuid_handler.o
obj-$(CONFIG_CFIHAMMING1)+= flash_hamming1_handler.o
obj-$(CONFIG_LUASCRIPTHANDLER) += lua_scripthandler.o
obj-$(CONFIG_RAW) += raw_handler.o
new file mode 100644
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2020
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * This handler does not install, but checks that
+ * there is not a filesystem with a specific UUID on the device.
+ * This is useful in case the bootloader choses the partition to be
+ * started with FS-UUID.
+ */
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <blkid/blkid.h>
+#include <sys/types.h>
+#include "swupdate.h"
+#include "handler.h"
+#include "util.h"
+
+void uniqueuuid_handler(void);
+
+static int uniqueuuid(struct img_type *img,
+ void __attribute__ ((__unused__)) *data)
+{
+ struct dict_list *uuids;
+ struct dict_list_elem *uuid;
+ blkid_cache cache = NULL;
+ blkid_dev_iterate iter;
+ blkid_dev dev;
+ int ret = 0;
+
+ uuids = dict_get_list(&img->properties, "fs-uuid");
+ if (!uuids) {
+ ERROR("Check for uuids runs, but not uuid given !");
+ return -EINVAL;
+ }
+
+ blkid_get_cache(&cache, NULL);
+
+ blkid_probe_all(cache);
+
+ LIST_FOREACH(uuid, uuids, next) {
+ iter = blkid_dev_iterate_begin(cache);
+ blkid_dev_set_search(iter, "UUID", uuid->value);
+
+ while (blkid_dev_next(iter, &dev) == 0) {
+ dev = blkid_verify(cache, dev);
+ if (!dev)
+ continue;
+ ERROR("UUID=%s not unique on %s !", uuid->value,
+ blkid_dev_devname(dev));
+ ret = -EAGAIN;
+ }
+ blkid_dev_iterate_end(iter);
+ }
+
+ return ret;
+}
+
+__attribute__((constructor))
+void uniqueuuid_handler(void)
+{
+ register_handler("uniqueuuid", uniqueuuid,
+ PARTITION_HANDLER | NO_DATA_HANDLER, NULL);
+}
+
This handler checks that FS-UUID are unique, that is there is not yet a filesystem on the device with the same UUID as provided in one artefact of the SWU. This is useful in case a bootloader (such as GRUB) will choose the device to boot from the UUID instead of the partition number. Signed-off-by: Stefano Babic <sbabic@denx.de> --- Changes since V1: - fix spelling in doc - rework help text in Config.in Kconfig | 4 ++ Makefile.deps | 4 ++ Makefile.flags | 4 ++ doc/source/handlers.rst | 22 +++++++++++ handlers/Config.in | 17 ++++++++ handlers/Makefile | 1 + handlers/uniqueuuid_handler.c | 74 +++++++++++++++++++++++++++++++++++ 7 files changed, 126 insertions(+) create mode 100644 handlers/uniqueuuid_handler.c