fstools: Add support to read-only MTD partitions (eg. recovery images)
authorBruno Pena <brunompena@gmail.com>
Sat, 4 Jan 2020 11:52:08 +0000 (12:52 +0100)
committerPetr Štetiar <ynezz@true.cz>
Sat, 18 Jan 2020 13:43:09 +0000 (14:43 +0100)
This patch enables fstools to open read-only MTD partitions, which in
turn also enables OpenWrt to boot from read-only partitions.

The use of read-only partitions is of special importance for WiFi-only
devices, where a protected read-only recovery image can be used in case
something goes wrong with the main firmware (eg. user gets locked out
due to bad settings, flash of an unbootable dev firmware, etc).

Signed-off-by: Bruno Pena <brunompena@gmail.com>
libfstools/mtd.c

index 77c71eeb29a3ba7a67c42514b5e17e324baf53d4..aae633e6ff1ff2eb29b2178fb22eb9d128bbcb03 100644 (file)
@@ -36,20 +36,31 @@ struct mtd_volume {
 
 static struct driver mtd_driver;
 
+static int mtd_open_device(const char *dev)
+{
+       int ret;
+
+       ret = open(dev, O_RDWR | O_SYNC);
+       if (ret < 0)
+               ret = open(dev, O_RDONLY);
+
+       return ret;
+}
+
 static int mtd_open(const char *mtd, int block)
 {
        FILE *fp;
        char dev[PATH_MAX];
-       int i, ret, flags = O_RDWR | O_SYNC;
+       int i, ret;
 
        if ((fp = fopen("/proc/mtd", "r"))) {
                while (fgets(dev, sizeof(dev), fp)) {
                        if (sscanf(dev, "mtd%d:", &i) && strstr(dev, mtd)) {
                                snprintf(dev, sizeof(dev), "/dev/mtd%s/%d", (block ? "block" : ""), i);
-                               ret = open(dev, flags);
+                               ret = mtd_open_device(dev);
                                if (ret < 0) {
                                        snprintf(dev, sizeof(dev), "/dev/mtd%s%d", (block ? "block" : ""), i);
-                                       ret = open(dev, flags);
+                                       ret = mtd_open_device(dev);
                                }
                                fclose(fp);
                                return ret;
@@ -58,7 +69,7 @@ static int mtd_open(const char *mtd, int block)
                fclose(fp);
        }
 
-       return open(mtd, flags);
+       return mtd_open_device(mtd);
 }
 
 static void mtd_volume_close(struct mtd_volume *p)