openwrt icon indicating copy to clipboard operation
openwrt copied to clipboard

image: add support for EROFS rootfs image generation

Open hsiangkao opened this issue 6 months ago • 24 comments

Add support for generating EROFS rootfs images.

The EROFS filesystem can offer competitive I/O performance while minimizing final image size when using the MicroLZMA compressor.

Target platform: linux-x86_generic (target-i386_pentium4_musl)

Filesystem     Image Size
=============  ==========
root.erofs     4882432
root.ext4      109051904
root.squashfs  4903302

Signed-off-by: Christian Marangi <[email protected]> Signed-off-by: Gao Xiang <[email protected]>

This is a continue of #9968 @aparcar #14457 @Ansuel , and I already tested it works on x86 VMs.

hsiangkao avatar Jun 27 '25 03:06 hsiangkao

@aparcar @Ansuel @hauke could you take a look at this PR? Also there is a fstools patch included to support EROFS + overlayfs, but I'm not sure how to submit upstream.

hsiangkao avatar Jun 27 '25 03:06 hsiangkao

Thanks for continuing the thing... I find it impressive that erofs now is actually smaller than squashfs

Ansuel avatar Jun 27 '25 06:06 Ansuel

.... Resolve a build issue due to the lack of dependency of libtool...

...
checking dependency style of ccache /__w/openwrt/openwrt/openwrt/staging_dir/host/bin/gcc... (cached) gcc3
./configure: line 6150: LT_INIT: command not found
checking pkg-config m4 macros... yes
...
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: error: cannot find input file: 'man/Makefile.in'
make[2]: *** [Makefile:40: /__w/openwrt/openwrt/openwrt/build_dir/host/erofs-utils-1.8.9/.configured] Error 1
time: tools/erofs-utils/compile#5.81#3.34#11.04

need to retrigger the CI... @aparcar @Ansuel ...

hsiangkao avatar Jun 27 '25 06:06 hsiangkao

Thanks for continuing the thing... I find it impressive that erofs now is actually smaller than squashfs

EROFS has landed advanced features like fragments and compressed data deduplication which makes the image size competitive.

But currently EROFS is still lack of metadata compression, and I'm working on it, hopefully it could be resolved this year so that the image sizes can be even smaller.

Also as for LZMA, it seems SquashFS supports to adjust -Xe -Xlc 0 -Xlp 2 -Xpb 2, which I need to support later too.

hsiangkao avatar Jun 27 '25 06:06 hsiangkao

@hsiangkao i feel lzma option should be easy to implement and should be enough to make it on par with squashfs performance.

Ansuel avatar Jun 27 '25 06:06 Ansuel

@hsiangkao i feel lzma option should be easy to implement and should be enough to make it on par with squashfs performance.

Yes, lzma options just need to add some command line option. Another one is the BCJ filter, XZ author @Larhzu already makes a generic interface in xz-utils 5.8.0 so that any compression algorithm in addition to lzma/xz can leverage that: https://github.com/tukaani-project/xz/releases/tag/v5.8.0 but I need to find extra time to support in EROFS. Anyway, those stuffs will make the image size smaller even further and I need more time to do step-by-step.

hsiangkao avatar Jun 27 '25 06:06 hsiangkao

@Ansuel btw, is it possible to depend libuuid for erofs-utils?

logs/tools/erofs-utils/compile.txt-   39 |         for (;;)
logs/tools/erofs-utils/compile.txt-   40 |         {
logs/tools/erofs-utils/compile.txt-   41 |                 ssize_t r;
logs/tools/erofs-utils/compile.txt-   42 |                 int err;
logs/tools/erofs-utils/compile.txt-   43 | 
logs/tools/erofs-utils/compile.txt-   44 | #ifdef HAVE_SYS_RANDOM_H
logs/tools/erofs-utils/compile.txt-   45 |                 r = getrandom(out, size, flags);
logs/tools/erofs-utils/compile.txt-      |                     ~~~~~~~~~
logs/tools/erofs-utils/compile.txt-      |                     s_getrandom
logs/tools/erofs-utils/compile.txt-1 error generated.

I've seen a macos failure which seems macos doesn't have getrandom(). Otherwise I may need a oot patch to work around this..

Another failure seems trivial, I've reran FIXUP=1 to fix up this.

hsiangkao avatar Jun 27 '25 07:06 hsiangkao

why libuuid?

For the getrandom it's not the first time I see that... I remember we have some downstream patch to address that (thank god it's only that on macos)

Ansuel avatar Jun 27 '25 07:06 Ansuel

why libuuid?

For the getrandom it's not the first time I see that...

Random uuid generation needs that, although for openwrt use case, it's -Uclear.

I remember we have some downstream patch to address that (thank god it's only that on macos)

could you give me some pointer?

hsiangkao avatar Jun 27 '25 07:06 hsiangkao

Random uuid generation needs that, although for openwrt use case, it's -Uclear.

ideally if possible it should be optional. But is it for host tool or for the target system? The erofs-utils package is optional right?

For getrandom I have to search let keep it that way currently. Maybe you can post here the oot patch

Ansuel avatar Jun 27 '25 07:06 Ansuel

Random uuid generation needs that, although for openwrt use case, it's -Uclear.

ideally if possible it should be optional. But is it for host tool or for the target system?

I think it's a host tool.

The erofs-utils package is optional right?

Yes, I propose here as an optional one first.

For getrandom I have to search let keep it that way currently. Maybe you can post here the oot patch

I will try to mask off this with a oot patch, since I don't want to release a new erofs-utils version due to this.

hsiangkao avatar Jun 27 '25 07:06 hsiangkao

I think it's a host tool.

if it's only host tool then we don't really care about dependency. Totally ok to depend on that

Ansuel avatar Jun 27 '25 07:06 Ansuel

I think it's a host tool.

if it's only host tool then we don't really care about dependency. Totally ok to depend on that

But I know little about the openwrt Makefile style, how to add libuuid dependency? Anyway, I already write a patch to disable getrandom() on MacOS, I will try this way first.

hsiangkao avatar Jun 27 '25 07:06 hsiangkao

repushed (need another CI trigger), hopefully all CI issues are resolved. @Ansuel @aparcar could you also help review?

hsiangkao avatar Jun 27 '25 07:06 hsiangkao

EROFS per-cpu decompression kthread workers (EROFS_FS_PCPU_KTHREAD) [N/y/?] (NEW) 
EROFS high priority per-CPU kthread workers (EROFS_FS_PCPU_KTHREAD_HIPRI) [Y/n/?] (NEW) 

Kernel stills seems to ask some questions

aparcar avatar Jun 27 '25 10:06 aparcar

Run . .github/workflows/scripts/ci_helpers.sh
tools/erofs-utils/Makefile
tools/erofs-utils/patches/0001-erofs-utils-fix-missing-getrandom-on-some-macOS-plat.patch
Some package Makefiles requires fix. (run 'make package/check FIXUP=1' and force push this pr)
You can also check the provided artifacts with the refreshed patch from this CI run.

What's wrong with that? I ran both make tools/erofs-utils/check FIXUP=1 and make package/check FIXUP=1 but they change nothing.

hsiangkao avatar Jun 27 '25 10:06 hsiangkao

EROFS per-cpu decompression kthread workers (EROFS_FS_PCPU_KTHREAD) [N/y/?] (NEW) 
EROFS high priority per-CPU kthread workers (EROFS_FS_PCPU_KTHREAD_HIPRI) [Y/n/?] (NEW) 

Kernel stills seems to ask some questions

Hi @aparcar! Oh, I forgot 6.6 has the kconfigs, will fix.

hsiangkao avatar Jun 27 '25 10:06 hsiangkao

❯ git diff
diff --git i/tools/erofs-utils/Makefile w/tools/erofs-utils/Makefile
index 9014e208da4..4fa77944462 100644
--- i/tools/erofs-utils/Makefile
+++ w/tools/erofs-utils/Makefile
@@ -12,7 +12,7 @@ PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
-PKG_MIRROR_HASH:=b9f054afc4cbba76ce889df9e4108b2a3a8ad266c9bcd94e4ca36680939d9c02
+PKG_MIRROR_HASH:=feab7386de6faf11cb29af5bfa240ea119b14bfd66c14d80de0509c1ab16dcc6
 PKG_SOURCE_DATE:=2025-06-26
 PKG_SOURCE_VERSION:=81169bf3cfd26b8f2b3aa3b20da23971168a90a9

aparcar avatar Jun 27 '25 10:06 aparcar

❯ git diff
diff --git i/tools/erofs-utils/Makefile w/tools/erofs-utils/Makefile
index 9014e208da4..4fa77944462 100644
--- i/tools/erofs-utils/Makefile
+++ w/tools/erofs-utils/Makefile
@@ -12,7 +12,7 @@ PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
-PKG_MIRROR_HASH:=b9f054afc4cbba76ce889df9e4108b2a3a8ad266c9bcd94e4ca36680939d9c02
+PKG_MIRROR_HASH:=feab7386de6faf11cb29af5bfa240ea119b14bfd66c14d80de0509c1ab16dcc6
 PKG_SOURCE_DATE:=2025-06-26
 PKG_SOURCE_VERSION:=81169bf3cfd26b8f2b3aa3b20da23971168a90a9

repushed with kconfig changes and PKG_MIRROR_HASH.

hsiangkao avatar Jun 27 '25 10:06 hsiangkao

@hsiangkao @Ansuel what about the initramfs, can't we compress that via erofs, too?

aparcar avatar Jun 27 '25 11:06 aparcar

@hsiangkao @Ansuel what about the initramfs, can't we compress that via erofs, too?

Do you mean erofs in the initramfs or the initrd one? I don't dig into how openwrt works on this so sorry about my limited knowledge. I suggest landing rootfs first since it takes too long and I found an extra slot these days. As for the initrd one, that is quite a long story, see: https://lore.kernel.org/all/[email protected]/ https://lore.kernel.org/all/[email protected]/ I think it needs more time to support initrd since hch doesn't allow a simple change.

hsiangkao avatar Jun 27 '25 11:06 hsiangkao

@aparcar why it still fails? I've already replaced the patch and it makes me no way to debug this issue...

hsiangkao avatar Jun 27 '25 11:06 hsiangkao

@hsiangkao please ignore it for no I will take care of fixing in free cycle :D

Ansuel avatar Jun 27 '25 11:06 Ansuel

@hsiangkao please ignore it for no I will take care of fixing in free cycle :D

It seems other than the style failure, the other CIs are passed now. Could you consider merging it now? @aparcar @Ansuel Without that, users have no chance to try this filesystem.

hsiangkao avatar Jun 30 '25 03:06 hsiangkao

Without that, users have no chance to try this filesystem.

What platforms are expected to boot with EROFS currently? I tried ramips (Xiaomi Router 3G), and encountered a boot failure.

Currently have no means of getting logs though, sorry. Lost my serial cable somewhere. I'm assuming it failed to mount the system and panicked.

timocapa avatar Jul 02 '25 06:07 timocapa

Without that, users have no chance to try this filesystem.

What platforms are expected to boot with EROFS currently? I tried ramips (Xiaomi Router 3G), and encountered a boot failure.

Currently have no means of getting logs though, sorry. Lost my serial cable somewhere. I'm assuming it failed to mount the system and panicked.

I only tried the x86 platform and it can successfully boot. image and the mount result: image I don't have a real router to test this for now.

hsiangkao avatar Jul 02 '25 06:07 hsiangkao

Update:

[    0.000000] MIPS: machine is Xiaomi Mi Router 3G
[    0.000000] Kernel command line: console=ttyS0,115200n8 rootfstype=erofs,jffs2
[    5.670326] erofs: (device ubiblock0_0): mounted with root inode @ nid 37.
[    5.677448] VFS: Mounted root (erofs filesystem) readonly on device 254:0.

/dev/root on /rom type erofs (ro,relatime,user_xattr,acl,cache_strategy=readaround)

Kernel config files had squashfs hardcoded in the cmdline, and I'm 99% sure that was the cause of the boot failure.

timocapa avatar Jul 02 '25 17:07 timocapa

@Ansuel @aparcar @nbd168 @hauke @robimarko ping? It just adds EROFS alternative support for now, and users should enable it via configuration. Or is there some other concern on this work? It has been pending for almost 3 years.

hsiangkao avatar Jul 03 '25 00:07 hsiangkao

hi @robimarko , it seems all CI passed now, could you take another look, many thanks!

hsiangkao avatar Jul 05 '25 00:07 hsiangkao

I gave it a spin on mvebu/cortexa9 on a Linksys WRT1900ACS.

Just modified the target makefile

--- a/target/linux/mvebu/Makefile
+++ b/target/linux/mvebu/Makefile
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 BOARD:=mvebu
 BOARDNAME:=Marvell EBU Armada
-FEATURES:=fpu usb pci pcie gpio nand squashfs ramdisk boot-part rootfs-part legacy-sdcard targz
+FEATURES:=fpu usb pci pcie gpio nand erofs ramdisk boot-part rootfs-part legacy-sdcard targz
 SUBTARGETS:=cortexa9 cortexa53 cortexa72

build it, flash it via sysupgrade and here we go

 -----------------------------------------------------
OpenWrt SNAPSHOT, r30269+5-f955716341
 -----------------------------------------------------

root@openwrt:~# uname -r
6.12.35

root@openwrt:~# dmesg | grep "Kernel command line:"
[    0.000000] Kernel command line: console=ttyS0,115200 root=/dev/mtdblock5 ro rootdelay=1 rootfstype=jffs2 earlyprintk mtdparts=armada-nand:2048K(uboot)ro,256K(u_env),256K(s_env),1m@9m(devinfo),40m@10m(kernel),34m@16m(rootfs),40m@50m(alt_kernel),34m@56m(alt_rootfs),80m@10m(ubifs),-@90m(syscfg)

root@openwrt:~# mount | grep rom
/dev/root on /rom type erofs (ro,relatime,user_xattr,acl,cache_strategy=readaround)

No further tests so far, but it just boots as if it has never done anything else :+1:


Output size comparison

11754047  squashfs-initramfs-kernel.bin
11782967  erofs-initramfs-kernel.bin    (+28920 +0.2%)

15990784  squashfs-factory.img
16384000  erofs-factory.img             (+393216, +2%)

12504228  squashfs-sysupgrade.bin
12872868  erofs-sysupgrade.bin          (+368640, +2%)

stklcode avatar Jul 05 '25 08:07 stklcode