前言

华为作为中国代表性的技术型企业,一直在不断推出自己的技术实现,并努力推广到世界,这一点是非常值得称赞的。从大概上游Linux 4.19左右,邮件列表开始出现一个EROFS的东西,不断有邮件的往来。因为太小众,所以当时没有太留意,只是因为EROFS这个名字和写只读文件系统时返回的错误名字一样,所以就留下了印象,其实都没注意到是华为的人做的。最近华为推出新手机,并宣扬自己为手机系统新写的文件系统的新闻不断发酵。我才开始注意到EROFS原来是华为的人写的,并且已经被merge到了Linux内核主线。

作为一个从事操作系统行业,文件系统方向的人,面对这样一个由国人推出的已经进了Linux项目主线的新文件系统,我觉得我有必要稍微关注一下。于是在晚上刚开完会后,现在是2019-03-27晚上21:18分,我开始了第一次对EROFS的初探。为什么要写上时间?因为我下面的一些操作可能会在项目日趋完善后出现变化,所以时间点变相代表我操作的“版本号”。

获得信息

这是一个全新的项目,所以怎么使用我也毫无头绪,网上文档及其少,用Google搜索Linux EROFS得到的大部分是Linux怎么处理EROFS错误,或者华为发布EROFS的新闻。新闻内容没什么参考价值,所以erofs在邮件列表的邮件成了重要的信息来源:

https://marc.info/?l=linux-fsdevel&m=152776480425624

还有一个LWN上关于EROFS的介绍:

https://lwn.net/Articles/760964/

但是因为我是付费的用户,所以能打开这个文章,不知道一般用户是不是能打开。如果打不开也没关系,内容并不多,还不如看上面的邮件列表的邮件。

从一些内容上我们知道了EROFS还有一个用户态工具,我找了一下,项目地址在:

https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git

有用的信息我暂时就找到这三个,这已经够我看一阵子了,今晚是肯定看不完。我们下面还是先完成初探的内容,将这个新的文件系统用起来。

尝试使用

因为EROFS已经进的Linux的主线,所以找到并编译安装它是使用它第一件要做的事情

# git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# make menuconfig

在进入config界面后,我并不知道EROFS的编译选项在哪,所以先搜索EROFS,看到如下图所示:

从描述可以看出那个EROFSFS基本就是我们要找的,它没有在filesystem目录下,而是在Device Drivers下面,而且目前还作为Staging drivers存在。嗯……看来我要冒着很大的Crash的风险来试试它了。按照上面所示我们找到EROFS_FS的编译选项的位置:

我们选择将其编译为模块<M>。由于第一次使用,下面的编译子选项我就先默认了。保存退出,开始编译安装:

# make -j32 && make -j16 modules_install && make install
(此处省略一个小时,/me 先小睡一会。。。)

。。。。

。。。。

好了,编译好了,没有出现编译错误。由于当前正是Linux的5.1.0-rc2阶段,所以装的kernel默认是/boot/vmlinuz-5.1.0-rc2+,我们选择将其默认启动后重启系统:

# grubby --set-default=/boot/vmlinuz-5.1.0-rc2+
# shutdown -r now

系统boot起新的kernel后erofs不是被自动加载的(毕竟它还是个staging阶段的driver),我们把它加载上来:

# find /lib/modules/`uname -r` -name erofs*
/lib/modules/5.1.0-rc2+/kernel/drivers/staging/erofs
/lib/modules/5.1.0-rc2+/kernel/drivers/staging/erofs/erofs.ko
# lsmod|grep erofs
# modprobe erofs
# dmesg|tail
...
[19474.968155] erofs: module is from the staging directory, the quality is unknown, you have been warned.
[19474.987076] erofs: initializing erofs 1.0pre1
[19474.992463] erofs: successfully to initialize erofs
# lsmod|grep erofs
erofs                 147456  0

嗯....加载上了,它“贴心”的还提示我"the quality is unknown, you have been warned"。下面该做什么呢?有了这样一个module,我们要想办法用起来。正好作者还提供了一个用户层工具erofs-utils,我们把那个项目也clone下来:

# git clone git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
Cloning into 'erofs-utils'...
remote: Counting objects: 147, done.
remote: Compressing objects: 100% (143/143), done.
remote: Total 147 (delta 83), reused 2 (delta 0)
Receiving objects: 100% (147/147), 55.02 KiB | 678.00 KiB/s, done.
Resolving deltas: 100% (83/83), done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.
# ls
# git branch
# git branch -aremotes/origin/mkfs-dev

空的?作者也真是心大,看来这确实是一个初级阶段的项目,连HEAD refer都没弄好。好在作者没有忘记push mkfs-dev分支,我们切到这个分支上看看。

# git checkout -b mkfs-dev remotes/origin/mkfs-dev
Branch 'mkfs-dev' set up to track remote branch 'mkfs-dev' from 'origin'.
Switched to a new branch 'mkfs-dev'
# ls
AUTHORS  autogen.sh  ChangeLog  configure.ac  COPYING  include  Makefile.am  mkfs  NEWS  README

嗯,这回有东西了。老规矩,未知的东西先看文档。也没有什么特别的manual文档,那就看README吧:

下面引用的文档内容版权归文档作者所有:

mkfs.erofs

mkfs.erofs is a user-space tool to create erofs filesystem images.

It can create 2 main types of erofs images, compressed and uncompressed:
 - For compressed images, it is able to integrate several compression
   algorithms, lz4 is supported according to the current erofs kernel
   implementation.
 - For uncompressed images, it can decide whether the last page of
   a file should be inlined or not properly [1].

Note that mkfs.erofs can only be linked statically with lz4 library
due to the dependency of experimental lz4hc apis which were added in
lz4 1.8.0. Anyway, it's a good start to begin with building the latest
lz4 library statically first. :)

Dependencies
 lz4-1.8.0 or above

How to build with lz4 static library
        ./configure --with-lz4=<lz4 install path>
eg. if lz4 lib has been installed into fold of /usr/local/lib
        ./configure --with-lz4=/usr/local/lib && make
On Fedora, static lz4 can be installed using:
        yum install lz4-static.x86_64
To build you should run this first:
        $ ./autogen.sh
        $ ./configure
        $ make

先看介绍和编译部分,需要lz4的库,版本要求lz4-1.8.0以上。我先看看我的repo里有没有:

# yum info lz4
....
Available Packages
Name         : lz4
Version      : 1.8.1.2
Release      : 4.el8
Arch         : x86_64
Size         : 92 k
Source       : lz4-1.8.1.2-4.el8.src.rpm
Repo         : beaker-BaseOS
Summary      : Extremely fast compression algorithm
URL          : https://lz4.github.io/lz4/
License      : GPLv2+ and BSD
Description  : LZ4 is an extremely fast loss-less compression algorithm, providing compression: speed at 400 MB/s per core, scalable with multi-core CPU. It also features: an extremely fast decoder, with speed in multiple GB/s per core, typically: reaching RAM speed limits on multi-core systems.

嗯,很不错,我大Red Hat (已经被IBM买走了 T_T )的最新系统支持这个库,版本正好在1.8以上。省去我自己下载编译的功夫了,我们将lz4及其库文件都装上:

# yum install lz4 lz4-libs lz4-devel lz4-static

然后尝试编译erofs-utils,文档上写的很清楚,我们照着执行一下试试看有没有问题:

# cd erofs-utils
# ./autogen.sh
# ./configure
# make -j4

Lucky! 没有问题!我们得到了重要的mkfs文件:

# ls mkfs/mkfs.erofs -l
-rwxr-xr-x. 1 root root 239480 Mar 27 11:36 mkfs/mkfs.erofs
# ./mkfs/mkfs.erofs
mkfs.erofs 0.1   Mar 27 2019 11:36:50Usage:[-z <compr_algri>] [-d <dbglvl>][target path] [source directory]

好吧,虽然它没有--help/-h这个选项,但是它还是大方的告诉了我自己的版本号和usage。再来看文档:

Usage:
$ ./mkfs.erofs
mkfs.erofs v1.0   Nov 17 2018 19:47:21

Usage:
    [-z <compr_algri>] [-d <dbglvl>]
    [target path] [source directory]

-d -- set debugging level <dbglvl>
 -z -- enable <compr_algri> compression (only lz4hc is supported)

Target path, source directory are both needed.

Usage:
$ ./mkfs.erofs
mkfs.erofs v1.0   Nov 17 2018 19:47:21

Usage:
    [-z <compr_algri>] [-d <dbglvl>]
    [target path] [source directory]

-d -- set debugging level <dbglvl>
 -z -- enable <compr_algri> compression (only lz4hc is supported)

Target path, source directory are both needed.

文档解释了-d和-z两个选项的意思,一个是设置debug的级别,一个是选择压缩算法,但是好像目前就只有lz4hc一个被支持,所以这两个选项我们先都不尝试了。然后target path和source directory是都需要的。那我们就试一下好了:

  • 先准备一个测试用文件(虚拟设备用),和一个测试用目录。对应上面的target path和source directory。为了测试,我们给新目录里随便拷贝一些内容:
# dd if=/dev/zero of=/home/erofs_disk bs=512 count=23000
23000+0 records in
23000+0 records out
11776000 bytes (12 MB, 11 MiB) copied, 0.306837 s, 38.4 MB/s
# mkdir /home/srcd
# cp README /home/srcd
# cp COPYING /home/srcd
# cp ChangeLog /home/srcd
# cp Makefile /home/srcd
  • 使用mkfs.erofs,将目录的内容“压缩”到文件image里:
# ./mkfs/mkfs.erofs /home/erofs_disk /home/srcd/c_version:           [0.1   Mar 27 2019 11:36:50]c_img_path:          [/home/erofs_disk]c_src_path:          [/home/srcd]c_dbg_lvl:           [       0]c_dry_run:           [       0]c_alg_name:          [    none]c_compr_maxsz:       [  921600]c_compr_lvl:         [       0]c_compr_boundary:    [     128]c_compr_ratio_limit: [     100]
  • 上面我们已经加载了erofs模块,现在我们可以挂载我们这个文件系统来看看了。因为是用文件虚拟的设备,所以做loop设备使用:
# mount -t erofs /home/erofs_disk /mnt/scratch -oloop
# dmesg|tail
[21656.252653] loop: module loaded
[21656.288268] erofs: read_super, device -> /dev/loop0
[21656.293824] erofs: options -> (null)
[21656.298229] erofs: root inode @ nid 0
[21656.302805] erofs: mounted on /dev/loop0 with opts: (null).
# mount|grep erofs
/home/erofs_disk on /mnt/scratch type erofs (ro,relatime,user_xattr,acl)
  • 挂载成功了,可以看到里面我们拷贝过的文件。
# ls -li /mnt/scratch
total 4879 -rw-r--r--. 1 root root     0 Mar 27 11:51 ChangeLog4 -rw-r--r--. 1 root root 18729 Mar 27 11:51 COPYING80 -rw-r--r--. 1 root root 25649 Mar 27 11:51 Makefile
1408 -rw-r--r--. 1 root root  3744 Mar 27 11:51 README
  • 下面我们尝试在这个只读文件系统上做一些写操作:
# echo > /mnt/scratch/file
bash: /mnt/scratch/file: Read-only file system
  • 果然不能写。再尝试以读写的方式重新挂载试试:
# mount -t erofs /home/erofs_disk /mnt/scratch -oremount,rw
# cat /proc/mounts |grep erofs
/dev/loop0 /mnt/scratch erofs ro,relatime,user_xattr,acl 0 0
# dmesg|tail
# echo > /mnt/scratch/file
bash: /mnt/scratch/file: Read-only file system

没报什么错,但是也没有被改成rw。

  • 不死心,卸载文件系统重新尝试以指定rw的方式直接挂载试试:

# umount /mnt/scratch
# dmesg|tail
[22737.057138] erofs: unmounted for /dev/loop0
# mount -t erofs /home/erofs_disk /mnt/scratch -oloop,rw
# echo $?
0
# dmesg
[22818.902072] erofs: read_super, device -> /dev/loop0
[22818.907548] erofs: options -> (null)
[22818.911625] erofs: root inode @ nid 0
[22818.915838] erofs: mounted on /dev/loop0 with opts: (null).
# cat /proc/mounts |grep erofs
/dev/loop0 /mnt/scratch erofs ro,relatime,user_xattr,acl 0 0
# echo > /mnt/scratch/file
bash: /mnt/scratch/file: Read-only file system

嗯,很坚挺,打死不动^_^

结束语

作为初探,今天就先放过它吧,改天再想办法让他panic(如果我有时间的话)。原理性的东西其实也并不是多新的技术,应该也不会跳出一直以来compression filesystem的圈。实现细节也还没怎么看,好像和ext4对metadata的组织有点类似,但是因为是只读的,所以可以省去很多东西,但是因为压缩功能,要新增一些东西。总之今天就先到这吧,熄灯,睡觉。

Huawei EROFS 初探相关推荐

  1. 华为鸿蒙系统初探之HUAWEI DevEco Studio Hello World

    2020年9月10日,华为鸿蒙系统升级至华为鸿蒙系统2.0版本. 探索之路开始 首先进入首页 https://developer.harmonyos.com/  点击快速入门 发现跳转到这个页面,页面 ...

  2. 初探数通网络开放可编程简介

    文章目录 网络运维面困难与挑战 行业趋势 面临困难 数通网络可开放编程简介 应用场景 多厂商设备快速适配 新业务快 网络变更可靠 管控析全栈可编程 特性介绍 动态加载软件包 事务机制 数据一致性 用户 ...

  3. LWN: 华为EROFS文件系统

    点击上方蓝色"Linux News搬运工"关注我们~ erofs: promote erofs from staging 从LWN上看到,华为的Gao Xiang正在向文件系统维护 ...

  4. JavaScript初探 三 (学习js数组)

    JavaScript初探 (三) JavaScript数组 定义 创建数组 var 数组名 = [元素0,元素1,元素2,--] ; var arr = ["Huawei",&qu ...

  5. 2021年大数据Flink(九):Flink原理初探

    Flink原理初探 Flink角色分工 在实际生产中,Flink 都是以集群在运行,在运行的过程中包含了两类进程. JobManager: 它扮演的是集群管理者的角色,负责调度任务.协调 checkp ...

  6. 从壹开始微服务 [ DDD ] 之一 ║ D3模式设计初探 与 我的计划书

    缘起 哈喽大家周四好!又是开心的一天,时间过的真快,我们的 <从壹开始 .net core 2.1 + vue 2.5 >前后端分离系列共 34 篇已经完结了,当然以后肯定还会有更新和修改 ...

  7. 经典算法研究系列:二、Dijkstra 算法初探

    经典算法研究系列:二.Dijkstra 算法初探  July   二零一一年一月 ====================== 本文主要参考:算法导论 第二版.维基百科. 写的不好之处,还望见谅. 本 ...

  8. zabbix 监控项自动发现过滤_Zabbix5.2由浅入深之官方自动发现规则初探(网络篇)

    今天的主题是官方模板的自动发现规则分析,在监控工作中常常会遇到一些可变化的OID值,也就是父OID+索引,而索引本身是变化的,如果监控设备数量固定,一个个写问题不大,但在规模增加到一定程度手动添加已然 ...

  9. las格式测井曲线_邹榕,等:顺北和托甫台区块奥陶系断裂结构单元测井响应特征初探...

    引用格式:邹榕,徐中祥,张晓明,等.顺北和托甫台区块奥陶系断裂结构单测井响应特征初探[J].油气藏评价与开发,2020,10(2):18-23.ZOUR, XU Z X, ZHANG X M, et ...

最新文章

  1. 网站关键词优化从这几方面下手效果会更好!
  2. python全栈-Day 2
  3. 从基础设施到云原生应用,全方位解读阿里云原生新锐开源项目
  4. 程序图形化界面刷新以及如何从tkinter窗口中正确读出数据
  5. Android开发之原生定位的方法(GPS,网络定位)
  6. P4445 最长回文串
  7. 牛客网C++面经 类和数据抽象
  8. Berkeley DB(六) -- DB Replication (HA)上部
  9. 重启Windows的PowerShell
  10. 鼎博电梯门禁数据分析
  11. 常见笔顺错误的字_容易出错的汉字|汉字中哪些字笔顺容易错
  12. 控制面板打开后立即自动关闭
  13. 1. 一文看懂奇异值分解
  14. 腾讯视频网页版无法连接服务器失败怎么办,腾讯视频突然不能投屏怎么解决 腾讯视频突然不能投屏解决方法...
  15. MOS管开关使用方法
  16. 带你Git从入门到精通
  17. 内存数据库-H2简介与实践
  18. python func函数用法_python函数局部变量用法实例分析
  19. Spring-全面详解(基础知识)
  20. redis安装及部署模式

热门文章

  1. Windows内网穿透远程桌面:公网远程桌面控制内网电脑 2/3
  2. 颈椎牵引器的介绍-颈托护颈
  3. 小说分享《Mehul和我》结尾篇
  4. connect的中文意思是什么_connect是什么意思?
  5. 方便易拆信封设计制作
  6. mysql动力节点百度云_动力节点MySQL数据库视频 百度云 网盘 下载
  7. 中国书法艺术会消亡吗?
  8. 7-1 定期存款 (10 分)
  9. UI自动化工具Cypress测试案例、生成报告---Linux版
  10. Linux升级gcc到最新版本--gcc-9.1.0