OpenWrt Forum Archive

Topic: Does Openwrt support pivot root/overlay on Ubifs?

The content of this topic has been archived on 25 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi all,

I hope this is the proper forum for this question.

I've been trying to figure out why pivot overlay does not work on the Armada XP platform, in particular a WRT1900AC. I am suspecting it has something to do with ubifs.

I am currently running trunk release r43336 and cannot get this to work no matter what I place in /etc/config/fstab ( I have tried everything in the extroot wiki page)

During console bootup I see the following when i have the target set to /overlay in the fstab file. The error it comes back with is "block: extroot: unable to retrieve rootfs information"

[    2.420925] xhci_hcd 0000:01:00.0: xHCI Host Controller
[    2.426201] xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 2
[    2.434414] hub 2-0:1.0: USB hub found
[    2.438204] hub 2-0:1.0: 2 ports detected
[    2.442426] xhci_hcd 0000:01:00.0: xHCI Host Controller
[    2.447691] xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 3
[    2.455669] hub 3-0:1.0: USB hub found
[    2.459459] hub 3-0:1.0: 2 ports detected
[    2.466644] usbcore: registered new interface driver usb-storage
procd: WDT failed to write: Bad file descriptor
procd: - preinit -
[    2.738049] random: nonblocking pool is initialized
[    2.764267] usb 2-2: new high-speed USB device number 2 using xhci_hcd
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[    2.908613] usb-storage 2-2:1.0: USB Mass Storage device detected
[    2.914912] scsi1 : usb-storage 2-2:1.0
[    3.915104] scsi 1:0:0:0: Direct-Access              Patriot Memory   PMAP PQ: 0 ANSI: 0 CCS
[    3.925331] sd 1:0:0:0: [sda] 15663104 512-byte logical blocks: (8.01 GB/7.46 GiB)
[    3.933106] sd 1:0:0:0: [sda] Write Protect is off
[    3.938147] sd 1:0:0:0: [sda] No Caching mode page found
[    3.943477] sd 1:0:0:0: [sda] Assuming drive cache: write through
[    3.952313] sd 1:0:0:0: [sda] No Caching mode page found
[    3.957660] sd 1:0:0:0: [sda] Assuming drive cache: write through
[    3.964836]  sda: sda1
[    3.968354] sd 1:0:0:0: [sda] No Caching mode page found
[    3.973684] sd 1:0:0:0: [sda] Assuming drive cache: write through
[    3.979814] sd 1:0:0:0: [sda] Attached SCSI removable disk
block: extroot: unable to retrie[    6.066777] UBIFS: background thread "ubifs_bgt0_1" started, PID 438
ve rootfs information
[    6.091855] UBIFS: recovery needed
[    6.155276] UBIFS: recovery completed
[    6.159011] UBIFS: mounted UBI device 0, volume 1, name "rootfs_data"
[    6.165485] UBIFS: LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[    6.174652] UBIFS: FS size: 25522176 bytes (24 MiB, 201 LEBs), journal size 1269760 bytes (1 MiB, 10 LEBs)
[    6.184349] UBIFS: reserved for root: 1205474 bytes (1177 KiB)
[    6.190204] UBIFS: media format: w4/r0 (latest is w4/r0), UUID 31B4D870-7D62-4475-8C9A-BF8A2D9CF46F, small LPT model
switching to overlay
[    6.250775] UBI: attaching mtd8 to ubi1
[    6.341414] UBI: scanning is finished
[    6.349104] UBI warning: print_rsvd_warning: cannot reserve enough PEBs for bad PEB handling, reserved 2, need 12
[    6.359943] UBI: attached mtd8 (name "syscfg", size 38 MiB) to ubi1
[    6.366247] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    6.373053] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    6.379781] UBI: VID header offset: 2048 (aligned 2048), data offset: 4096
[    6.386682] UBI: good PEBs: 296, bad PEBs: 8, corrupted PEBs: 0
[    6.392618] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
[    6.399780] UBI: max/mean erase counter: 25/21, WL threshold: 4096, image sequence number: 750244846
[    6.408944] UBI: available PEBs: 0, total reserved PEBs: 296, PEBs reserved for bad PEB handling: 2
[    6.418032] UBI: background thread "ubi_bgt1d" started, PID 445
UBI device number 1, total 296 LEBs (37584896 by[    6.428336] UBIFS: background thread "ubifs_bgt1_0" started, PID 448
tes, 35.8 MiB), available 0 LEBs (0 bytes), LEB size 126976 bytes (124.0 KiB)
[    6.470084] UBIFS: mounted UBI device 1, volume 0, name "syscfg"
[    6.476139] UBIFS: LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[    6.485308] UBIFS: FS size: 35680256 bytes (34 MiB, 281 LEBs), journal size 1777664 bytes (1 MiB, 14 LEBs)
[    6.494995] UBIFS: reserved for root: 1685265 bytes (1645 KiB)
[    6.500846] UBIFS: media format: w4/r0 (latest is w4/r0), UUID 6C76BEAD-F1CC-46B1-9B9B-CCDD36A50A02, small LPT model
procd: - early -
Failed to connect to ubus
procd: - ubus -
procd: - init -
Please press Enter to activate this console.
[    8.564013] NET: Registered protocol family 10
[    8.581819] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    8.592625] leds-tlc59116: Using tlc59116 16-bit LED driver at slave address 0x68

After bootup I can make this volume mount to the /mnt/sda1 directory by typing "block mount" without issue. If I change it back to /overlay target and type the following I get the same error as during bootup:

root@OpenWrt:/etc/config# export PREINIT=1
root@OpenWrt:/etc/config# block extroot
block: extroot: unable to retrieve rootfs information
root@OpenWrt:/etc/config#

contents of /etc/config/fstab

config 'global'
        option  anon_swap       '0'
        option  anon_mount      '0'
        option  auto_swap       '1'
        option  auto_mount      '1'
        option  delay_root      '5'
        option  check_fs        '0'

config 'mount'
        option  target  '/overlay'
        option  uuid    '675adbeb-75bf-4975-b64b-a8772e8cee9f'
        option  enabled '1'
root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                   21.8M    440.0K     20.3M   2% /
/dev/root                 7.5M      7.5M         0 100% /rom
tmpfs                   124.9M    240.0K    124.7M   0% /tmp
/dev/ubi0_1              21.8M    440.0K     20.3M   2% /overlay
overlayfs:/overlay       21.8M    440.0K     20.3M   2% /
ubi1:syscfg              30.8M    272.0K     28.9M   1% /tmp/syscfg
tmpfs                   512.0K         0    512.0K   0% /dev
root@OpenWrt:/# mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
/dev/ubi0_1 on /overlay type ubifs (rw,noatime)
overlayfs:/overlay on / type overlayfs (rw,noatime,lowerdir=/,upperdir=/overlay)
ubi1:syscfg on /tmp/syscfg type ubifs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)

Any help would be greatly appreciated!

(Last edited by tusc on 21 Nov 2014, 00:42)

Hi tusc,

I had met a same problem on NetGear WNDR4300.
I think extroot isn't considering ubifs.

Here is my monkey patch:

*** build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt.orig   2014-11-23 15:16:26.000000000 +0900
--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt        2014-12-06 11:24:03.393736772 +0900
***************
*** 48,54 ****
  INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin)

  ADD_EXECUTABLE(block block.c)
! TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json)
  INSTALL(TARGETS block RUNTIME DESTINATION sbin)

  ADD_EXECUTABLE(jffs2reset jffs2reset.c)
--- 48,54 ----
  INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin)

  ADD_EXECUTABLE(block block.c)
! TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ubi-utils)
  INSTALL(TARGETS block RUNTIME DESTINATION sbin)

  ADD_EXECUTABLE(jffs2reset jffs2reset.c)
*** build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c.orig  2014-11-23 15:16:26.000000000 +0900
--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c       2014-12-06 16:19:51.085736772 +0900
***************
*** 35,40 ****
--- 35,41 ----
  #include <libubox/avl-cmp.h>

  #include "libblkid-tiny/libblkid-tiny.h"
+ #include "libubi/libubi.h"

  #define ERROR(fmt, ...) do { \
                syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
***************
*** 822,834 ****
        return 0;
  }

  static int check_extroot(char *path)
  {
        struct blkid_struct_probe *pr = NULL;
        char fs[32];

!       if (find_block_mtd("rootfs", fs, sizeof(fs)))
!               return -1;

        list_for_each_entry(pr, &devices, list) {
                if (!strcmp(pr->dev, fs)) {
--- 823,873 ----
        return 0;
  }

+ static int find_block_ubi(libubi_t libubi, char *name, char *ret)
+ {
+       int ubi = 0;
+       int i;
+
+         while (ubi_dev_present(libubi, ubi))
+         {
+                 struct ubi_dev_info dev_info;
+
+                 if (ubi_get_dev_info1(libubi, ubi++, &dev_info))
+                         continue;
+
+               for (i = dev_info.lowest_vol_id; i<= dev_info.highest_vol_id; i++)
+               {
+                       struct ubi_vol_info vol_info;
+
+                       if(ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info))
+                               continue;
+
+                       sprintf(ret, "/dev/ubi%d_%d", dev_info.dev_num, vol_info.vol_id);
+
+                       return 0;
+               }
+         }
+
+         return -1;
+ }
+
  static int check_extroot(char *path)
  {
        struct blkid_struct_probe *pr = NULL;
        char fs[32];

!       if (find_block_mtd("rootfs", fs, sizeof(fs))) {
!               char ubi_dev[32] = { 0 };
!               libubi_t libubi;
!
!               libubi = libubi_open();
!               find_block_ubi(libubi, "rootfs", ubi_dev);
!               libubi_close(libubi);
!               if (!ubi_dev[0])
!                       return -1;
!               strncpy(fs, "/dev/ubiblock", sizeof(fs));
!               strncpy(fs + 13, ubi_dev + 8, sizeof(fs) - 13);
!       }

        list_for_each_entry(pr, &devices, list) {
                if (!strcmp(pr->dev, fs)) {
***************
*** 929,937 ****
  static int main_extroot(int argc, char **argv)
  {
        struct blkid_struct_probe *pr;
!       char fs[32] = { 0 };
        char fs_data[32] = { 0 };
        int err = -1;

        if (!getenv("PREINIT"))
                return -1;
--- 968,977 ----
  static int main_extroot(int argc, char **argv)
  {
        struct blkid_struct_probe *pr;
!       /* char fs[32] = { 0 }; */
        char fs_data[32] = { 0 };
        int err = -1;
+       libubi_t libubi;

        if (!getenv("PREINIT"))
                return -1;
***************
*** 944,949 ****
--- 984,990 ----
        mkblkdev();
        cache_load(1);

+       /*
        find_block_mtd("rootfs", fs, sizeof(fs));
        if (!fs[0]) {
                ERROR("extroot: unable to locate rootfs mtdblock\n");
***************
*** 955,965 ****
--- 996,1009 ----
                ERROR("extroot: unable to retrieve rootfs information\n");
                return -3;
        }
+       */

        find_block_mtd("rootfs_data", fs_data, sizeof(fs_data));
        if (fs_data[0]) {
                pr = find_block_info(NULL, NULL, fs_data);
                if (pr && !strcmp(pr->id->name, "jffs2")) {
+                       /* ERROR("extroot: rootfs_data=%s\n", fs_data); */
+
                        char cfg[] = "/tmp/jffs_cfg";

                        mkdir_p(cfg);
***************
*** 974,979 ****
--- 1018,1042 ----
                }
        }

+       memset(fs_data, 0, sizeof(fs_data));
+       libubi = libubi_open();
+       find_block_ubi(libubi, "rootfs_data", fs_data);
+       libubi_close(libubi);
+       if (fs_data[0]) {
+               /* ERROR("extroot: rootfs_data=%s\n", fs_data); */
+
+               char cfg[] = "/tmp/ubifs_cfg";
+               mkdir_p(cfg);
+               if (!mount(fs_data, cfg, "ubifs", MS_NOATIME, NULL)) {
+                       err = mount_extroot(cfg);
+                       umount2(cfg, MNT_DETACH);
+               }
+               if (err < 0)
+                       rmdir("/tmp/overlay");
+               rmdir(cfg);
+               return err;
+       }
+
        return mount_extroot(NULL);
  }

And, /etc/config/fstab file is here:

config 'global'
        option  anon_swap       '0'
        option  anon_mount      '0'
        option  auto_swap       '1'
        option  auto_mount      '1'
        option  delay_root      '15'
        option  check_fs        '0'

config 'mount'
        option  target          '/overlay'
        option  uuid            'f67b27e3-163f-4ded-8e32-e7c693591f6f'
        option  fstype          'ext4'
        option  options         'rw,sync,noatime,nodiratime'
        option  enabled_fsck    '1'
        option  enabled         '1'

Then, df output is this:

root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                   28.8G     44.2M     27.3G   0% /
/dev/root                 3.3M      3.3M         0 100% /rom
tmpfs                    61.5M     56.0K     61.5M   0% /tmp
/dev/sda1                28.8G     44.2M     27.3G   0% /overlay
overlayfs:/overlay       28.8G     44.2M     27.3G   0% /
tmpfs                   512.0K         0    512.0K   0% /dev

I have tested it only on my NetGear WNDR4300.
But, It maybe works on other ubifs HWs.

Try it!

I forgot to say.
This patch works with both pivot root / pivot overlay.

I have exactly the same issue with the same router model.

Mounting to "/" or "/overlay" does not work regardless of any settings specified in /etc/config/fstab.

Thanks for sharing the patch, Hiro.AK47!

Hi all,

I refined previous patch.
More robuster and shorter.

I tested it only on my WNDR4300, and it will work with both pivot root / pivot overlay like before.

--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt.orig   2014-11-23 15:16:26.000000000 +0900
+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt        2014-12-06 11:24:03.393736772 +0900
@@ -48,7 +48,7 @@ TARGET_LINK_LIBRARIES(mount_root fstools
 INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin)

 ADD_EXECUTABLE(block block.c)
-TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json)
+TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ubi-utils)
 INSTALL(TARGETS block RUNTIME DESTINATION sbin)

 ADD_EXECUTABLE(jffs2reset jffs2reset.c)
--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c.orig  2014-11-23 15:16:26.000000000 +0900
+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c       2014-12-08 19:42:52.906194992 +0900
@@ -35,6 +35,7 @@
 #include <libubox/avl-cmp.h>

 #include "libblkid-tiny/libblkid-tiny.h"
+#include "libubi/libubi.h"

 #define ERROR(fmt, ...) do { \
                syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
@@ -822,13 +823,70 @@ static int find_block_mtd(char *name, ch
        return 0;
 }

+static int find_ubi_vol(libubi_t libubi, char *name, int *dev_num, int *vol_id)
+{
+       int dev = 0;
+
+       while (ubi_dev_present(libubi, dev))
+       {
+               struct ubi_dev_info dev_info;
+               struct ubi_vol_info vol_info;
+
+               if (ubi_get_dev_info1(libubi, dev++, &dev_info))
+                       continue;
+               if (ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info))
+                       continue;
+
+               *dev_num = dev_info.dev_num;
+               *vol_id = vol_info.vol_id;
+
+               return 0;
+       }
+
+       return -1;
+}
+
+static int find_block_ubi(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubi%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
+static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubiblock%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
 static int check_extroot(char *path)
 {
        struct blkid_struct_probe *pr = NULL;
        char fs[32];

-       if (find_block_mtd("rootfs", fs, sizeof(fs)))
-               return -1;
+       if (find_block_mtd("rootfs", fs, sizeof(fs))) {
+               int err = -1;
+               libubi_t libubi;
+
+               libubi = libubi_open();
+               err = find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (err)
+                       return -1;
+       }

        list_for_each_entry(pr, &devices, list) {
                if (!strcmp(pr->dev, fs)) {
@@ -932,6 +990,7 @@ static int main_extroot(int argc, char *
        char fs[32] = { 0 };
        char fs_data[32] = { 0 };
        int err = -1;
+       libubi_t libubi;

        if (!getenv("PREINIT"))
                return -1;
@@ -946,8 +1005,13 @@ static int main_extroot(int argc, char *

        find_block_mtd("rootfs", fs, sizeof(fs));
        if (!fs[0]) {
-               ERROR("extroot: unable to locate rootfs mtdblock\n");
-               return -2;
+               libubi = libubi_open();
+               find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (!fs[0]) {
+                       ERROR("extroot: unable to locate rootfs mtdblock / ubiblock\n");
+                       return -2;
+               }
        }

        pr = find_block_info(NULL, NULL, fs);
@@ -974,6 +1038,24 @@ static int main_extroot(int argc, char *
                }
        }

+       memset(fs_data, 0, sizeof(fs_data));
+       libubi = libubi_open();
+       find_block_ubi(libubi, "rootfs_data", fs_data, sizeof(fs_data));
+       libubi_close(libubi);
+       if (fs_data[0]) {
+               char cfg[] = "/tmp/ubifs_cfg";
+
+               mkdir_p(cfg);
+               if (!mount(fs_data, cfg, "ubifs", MS_NOATIME, NULL)) {
+                       err = mount_extroot(cfg);
+                       umount2(cfg, MNT_DETACH);
+               }
+               if (err < 0)
+                       rmdir("/tmp/overlay");
+               rmdir(cfg);
+               return err;
+       }
+
        return mount_extroot(NULL);
 }

Thanks, Hiro.AK47, your patch works perfectly on my box, too. Tested with both overlay and pivot root mode, both work fine.

Here's an updated version of the patch to make it work with the master branch:

diff -rupN fstools.old/block.c fstools.new/block.c
--- fstools.old/block.c    2014-12-12 17:32:23.833641055 +0100
+++ fstools.new/block.c    2014-12-12 17:36:59.532478289 +0100
@@ -35,6 +35,7 @@
 #include <libubox/avl-cmp.h>
 
 #include "libblkid-tiny/libblkid-tiny.h"
+#include "libubi/libubi.h"
 
 #define ERROR(fmt, ...) do { \
         syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
@@ -823,13 +824,70 @@ static int find_block_mtd(char *name, ch
     return 0;
 }
 
+static int find_ubi_vol(libubi_t libubi, char *name, int *dev_num, int *vol_id)
+{
+       int dev = 0;
+
+       while (ubi_dev_present(libubi, dev))
+       {
+               struct ubi_dev_info dev_info;
+               struct ubi_vol_info vol_info;
+
+               if (ubi_get_dev_info1(libubi, dev++, &dev_info))
+                       continue;
+               if (ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info))
+                       continue;
+
+               *dev_num = dev_info.dev_num;
+               *vol_id = vol_info.vol_id;
+
+               return 0;
+       }
+
+       return -1;
+}
+
+static int find_block_ubi(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubi%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
+static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubiblock%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
 static int check_extroot(char *path)
 {
     struct blkid_struct_probe *pr = NULL;
     char fs[32];
 
-    if (find_block_mtd("rootfs", fs, sizeof(fs)))
-        return -1;
+       if (find_block_mtd("rootfs", fs, sizeof(fs))) {
+               int err = -1;
+               libubi_t libubi;
+
+               libubi = libubi_open();
+               err = find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (err)
+                       return -1;
+       }
 
     list_for_each_entry(pr, &devices, list) {
         if (!strcmp(pr->dev, fs)) {
@@ -933,6 +991,7 @@ static int main_extroot(int argc, char *
     char fs[32] = { 0 };
     char fs_data[32] = { 0 };
     int err = -1;
+    libubi_t libubi;
 
     if (!getenv("PREINIT"))
         return -1;
@@ -947,8 +1006,13 @@ static int main_extroot(int argc, char *
 
     find_block_mtd("rootfs", fs, sizeof(fs));
     if (!fs[0]) {
-        ERROR("extroot: unable to locate rootfs mtdblock\n");
-        return -2;
+               libubi = libubi_open();
+               find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (!fs[0]) {
+                       ERROR("extroot: unable to locate rootfs mtdblock / ubiblock\n");
+                       return -2;
+               }
     }
 
     pr = find_block_info(NULL, NULL, fs);
@@ -975,6 +1039,24 @@ static int main_extroot(int argc, char *
         }
     }
 
+       memset(fs_data, 0, sizeof(fs_data));
+       libubi = libubi_open();
+       find_block_ubi(libubi, "rootfs_data", fs_data, sizeof(fs_data));
+       libubi_close(libubi);
+       if (fs_data[0]) {
+               char cfg[] = "/tmp/ubifs_cfg";
+
+               mkdir_p(cfg);
+               if (!mount(fs_data, cfg, "ubifs", MS_NOATIME, NULL)) {
+                       err = mount_extroot(cfg);
+                       umount2(cfg, MNT_DETACH);
+               }
+               if (err < 0)
+                       rmdir("/tmp/overlay");
+               rmdir(cfg);
+               return err;
+       }
+
     return mount_extroot(NULL);
 }
 
diff -rupN fstools.old/CMakeLists.txt fstools.new/CMakeLists.txt
--- fstools.old/CMakeLists.txt    2014-12-12 17:32:23.833641055 +0100
+++ fstools.new/CMakeLists.txt    2014-12-12 17:31:48.729637303 +0100
@@ -48,7 +48,7 @@ TARGET_LINK_LIBRARIES(mount_root fstools
 INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin)
 
 ADD_EXECUTABLE(block block.c)
-TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json)
+TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ubi-utils)
 INSTALL(TARGETS block RUNTIME DESTINATION sbin)
 
 ADD_EXECUTABLE(jffs2reset jffs2reset.c)

Your modifications seem to be generic enough so I guess this could be pulled into the master branch as a patch for the fstools package.

I'm going to create a properly formatted patch with quilt and send that to the devs, indicating - of course - that the patch was provided by you originally.

Thanks, again!

(Last edited by geryhun on 12 Dec 2014, 21:48)

Hi geryhun,

You're welcome.
Thank you for committing patch!

Just wanted to clarify one thing about this thread. Its name was really confusing for me.

What you did/discussed there was support for *reading* extroot configuration from ubifs "rootfs_data" partition. It was *not* about using some "ubifs" partition *as* extroot.

@Zajec,

given the clarification, has this patch been applied to trunk? Thanks.

Support for reading configuration from "rootfs_data" UBI volume has been added to the fstools directly, see:
http://nbd.name/gitweb.cgi?p=fstools.gi … 7695f78853

My patches adding support for using UBI volume with ubifs as overlay were not accepted yet.

Hiro.AK47 wrote:

Hi all,

I refined previous patch.
More robuster and shorter.

I tested it only on my WNDR4300, and it will work with both pivot root / pivot overlay like before.

--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt.orig   2014-11-23 15:16:26.000000000 +0900
+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt        2014-12-06 11:24:03.393736772 +0900
@@ -48,7 +48,7 @@ TARGET_LINK_LIBRARIES(mount_root fstools
 INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin)

 ADD_EXECUTABLE(block block.c)
-TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json)
+TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ubi-utils)
 INSTALL(TARGETS block RUNTIME DESTINATION sbin)

 ADD_EXECUTABLE(jffs2reset jffs2reset.c)
--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c.orig  2014-11-23 15:16:26.000000000 +0900
+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c       2014-12-08 19:42:52.906194992 +0900
@@ -35,6 +35,7 @@
 #include <libubox/avl-cmp.h>

 #include "libblkid-tiny/libblkid-tiny.h"
+#include "libubi/libubi.h"

 #define ERROR(fmt, ...) do { \
                syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
@@ -822,13 +823,70 @@ static int find_block_mtd(char *name, ch
        return 0;
 }

+static int find_ubi_vol(libubi_t libubi, char *name, int *dev_num, int *vol_id)
+{
+       int dev = 0;
+
+       while (ubi_dev_present(libubi, dev))
+       {
+               struct ubi_dev_info dev_info;
+               struct ubi_vol_info vol_info;
+
+               if (ubi_get_dev_info1(libubi, dev++, &dev_info))
+                       continue;
+               if (ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info))
+                       continue;
+
+               *dev_num = dev_info.dev_num;
+               *vol_id = vol_info.vol_id;
+
+               return 0;
+       }
+
+       return -1;
+}
+
+static int find_block_ubi(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubi%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
+static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen)
+{
+       int dev_num;
+       int vol_id;
+       int err = -1;
+
+       err = find_ubi_vol(libubi, name, &dev_num, &vol_id);
+       if (!err)
+               snprintf(part, plen, "/dev/ubiblock%d_%d", dev_num, vol_id);
+
+       return err;
+}
+
 static int check_extroot(char *path)
 {
        struct blkid_struct_probe *pr = NULL;
        char fs[32];

-       if (find_block_mtd("rootfs", fs, sizeof(fs)))
-               return -1;
+       if (find_block_mtd("rootfs", fs, sizeof(fs))) {
+               int err = -1;
+               libubi_t libubi;
+
+               libubi = libubi_open();
+               err = find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (err)
+                       return -1;
+       }

        list_for_each_entry(pr, &devices, list) {
                if (!strcmp(pr->dev, fs)) {
@@ -932,6 +990,7 @@ static int main_extroot(int argc, char *
        char fs[32] = { 0 };
        char fs_data[32] = { 0 };
        int err = -1;
+       libubi_t libubi;

        if (!getenv("PREINIT"))
                return -1;
@@ -946,8 +1005,13 @@ static int main_extroot(int argc, char *

        find_block_mtd("rootfs", fs, sizeof(fs));
        if (!fs[0]) {
-               ERROR("extroot: unable to locate rootfs mtdblock\n");
-               return -2;
+               libubi = libubi_open();
+               find_block_ubi_RO(libubi, "rootfs", fs, sizeof(fs));
+               libubi_close(libubi);
+               if (!fs[0]) {
+                       ERROR("extroot: unable to locate rootfs mtdblock / ubiblock\n");
+                       return -2;
+               }
        }

        pr = find_block_info(NULL, NULL, fs);
@@ -974,6 +1038,24 @@ static int main_extroot(int argc, char *
                }
        }

+       memset(fs_data, 0, sizeof(fs_data));
+       libubi = libubi_open();
+       find_block_ubi(libubi, "rootfs_data", fs_data, sizeof(fs_data));
+       libubi_close(libubi);
+       if (fs_data[0]) {
+               char cfg[] = "/tmp/ubifs_cfg";
+
+               mkdir_p(cfg);
+               if (!mount(fs_data, cfg, "ubifs", MS_NOATIME, NULL)) {
+                       err = mount_extroot(cfg);
+                       umount2(cfg, MNT_DETACH);
+               }
+               if (err < 0)
+                       rmdir("/tmp/overlay");
+               rmdir(cfg);
+               return err;
+       }
+
        return mount_extroot(NULL);
 }

@Hiro.AK47, hoping you can help.. I'm trying to apply your patch to my WNDR4300 in BreakerBarrier but get the following error :

Applying patch platform/903-extroot_fix.patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt.orig   2014-11-23 15:16:26.000000000 +0900
|+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/CMakeLists.txt        2014-12-06 11:24:03.393736772 +0900
--------------------------
No file to patch.  Skipping patch.
1 out of 1 hunk ignored
can't find file to patch at input line 14
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|--- build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c.orig  2014-11-23 15:16:26.000000000 +0900
|+++ build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c       2014-12-08 19:42:52.906194992 +0900
--------------------------
No file to patch.  Skipping patch.



If I look at line 14 in your patch file, it references "build_dir/target-mips_34kc_uClibc-0.9.33.2/fstools-2014-06-22/block.c.orig".  However, I don't have a /fstools-... path at that location but I do have fstools selected as a package in make menuconfig.

Any ideas?  I REALLY appreciate any help you or anyone else can provide on this.  Thanks so much!

(Last edited by 8ce881ca on 24 Jan 2015, 12:53)

tusc wrote:

@Zajec,

given the clarification, has this patch been applied to trunk? Thanks.

@tusc,do you finally figure out getting pivot root working on CC of wrt1900ac?

tangsoft wrote:
tusc wrote:

@Zajec,

given the clarification, has this patch been applied to trunk? Thanks.

@tusc,do you finally figure out getting pivot root working on CC of wrt1900ac?

Hi,@tusc, as you may knew, it looks like Jow fixed the ubifs extroot bug in trunk44538, I get extroot running on my wrt1900ac.

------------------------------------------


BusyBox v1.22.1 (2015-02-26 17:07:50 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
|       |.-----.-----.-----.|  |  |  |.----.|  |_
|   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
|_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
-----------------------------------------------------
CHAOS CALMER (Bleeding Edge, r44541)
-----------------------------------------------------

  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
-----------------------------------------------------
root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                   28.4G     53.5M     26.9G   0% /
/dev/root                 2.8M      2.8M         0 100% /rom
tmpfs                   124.8M     64.0K    124.7M   0% /tmp
/dev/sda1                28.4G     53.5M     26.9G   0% /
ubi1:syscfg              30.8M    248.0K     28.9M   1% /tmp/syscfg
tmpfs                   512.0K         0    512.0K   0% /dev

So I'm a newbie to OpenWRT.  I have a Netgear WNDR4300 (v1) that I flashed with Barrier Breaker (14.07, r42625) via https://downloads.openwrt.org/barrier_b … actory.img

I'm getting the same error in that my USB drive mounts to /mnt/sda2 instead of /overlay because /dev/ubi0_1 is already mounted to /overlay.  I understand from reading the thread that there is a patch to fix this but I'm not sure 1) where to get the patch 2) how to apply the patch.  Can someone please help?

Zajec wrote:

Support for reading configuration from "rootfs_data" UBI volume has been added to the fstools directly, see:
http://nbd.name/gitweb.cgi?p=fstools.gi … 7695f78853

My patches adding support for using UBI volume with ubifs as overlay were not accepted yet.

What is the status with patches with support for UBI/UBIFS ?

I downloaded latest OpenWrt git sources and don't see such option in Buildroot menuconfig, so any information is much appreciated.

WIKI says that UBIFS is used for OpenWrt NAND targets [1], then please enable UBIFS also as an option for NOR flash targets also.

[1] http://wiki.openwrt.org/doc/techref/filesystems#ubifs

(Last edited by valentt on 18 May 2015, 15:46)

@Zajec I see your patched are signed off, so they should be applied to latest trunk, right?

Please just clarify how to enable UBI/UBIFS for example - for ar71xx targets. I started menuconfig and expected to have UBIFS option for root filesystem but can't find it. Can you please clarify. Thanks.

valentt wrote:

@Zajec I see your patched are signed off, so they should be applied to latest trunk, right?

Signing patches doesn't imply having them accepted anyhow. But yes, my patches were accepted.

valentt wrote:

Please just clarify how to enable UBI/UBIFS for example - for ar71xx targets. I started menuconfig and expected to have UBIFS option for root filesystem but can't find it. Can you please clarify. Thanks.

I don't think you really understand UBI / UBIFS / rootfs / overlay or at least your questions aren't clear enough. This thread was already messy (using UBIFS as overlay vs. reading overlay info from UBIFS volume). I can only guess you want to achieve something even else and your question probably doesn't belong to this thread at all (hint: create new thread, DESCRIBE what do you want).

The discussion might have continued from here.