分布式文件系统概述
分布式文件系统提供跨设备的文件访问能力,适用于如下场景:
两台设备组网,A 设备可以无感读取和修改 B 设备的文件。
边缘服务器可以自动同步组网中多个嵌入式设备中的文件数据。
hmdfs 在分布式软总线动态组网的基础上,为网络上各个设备结点提供一个全局一致的访问视图,支持开发者通过基础文件系统接口进行读写访问,具有高性能、低延时等优点。
其包括如下几个核心模块:
distributed_file_daemon:分布式文件管理常驻用户态服务,负责接入设备组网、数据传输能力,并负责挂载 hmdfs。
hmdfs(Harmony Distributed File System):分布式文件系统核心模块,是一种面向移动分布式场景的、高性能的、基于内核实现的、堆叠式文件系统。
约束
接口支持情况
分布式文件管理当前不支持或有限支持如下 VFS 系统调用:
- symlink:不支持。
- mmap:仅支持读。
- rename:仅支持同目录操作。
规格
最大目录层级
与被堆叠文件系统,即 data 分区所用文件系统,如 ext4、f2fs 等保持一致。
最大文件名长度
取决于 680B 与被堆叠文件支持长度的最小值。f2fs 和 ext4 均为 255B。
最大单文件大小
取决于 $2^{64}$B 与被堆叠文件系统支持最大单文件大小的最小值。ext4 单文件最大为 16TB,f2fs 单文件最大为 3.94TB。
环境约束
运行环境的有线网卡名称必须是
eth0
,无线网卡的名称必须是wlan0
。可使用ip a
命令查看当前环境的网卡名称,如果没有eth0
或者wlan0
的网卡,那么 softbus_server 会启动失败,功能失效。解决方案参考 常见问题。不能同时安装 dsoftbus 和 distributed-utils 两个包。dsoftbus 包中是
3.1.2
版本的软总线,distributed-utils 包中包含3.2
版本的软总线,如果想使用3.2
版本的软总线,需要先卸载 dsoftbus 包。运行环境的内核需要开启 binder 的功能,可以通过以下命令来判断内核是否开启 binder 功能。如果未开启,可以通过插入 binder 的 ko 文件或者重编内核来解决,具体解决方法参考 communication_ipc 仓 openEuler-22.03-LTS-SP2 分支的 README 。
openEuler 的内核版本需要是 5.10.x,可以通过使用
uname -r
查看内核版本。openEuler 各个设备在同一个网段中,并且设备之间网络通畅,防火墙未拦截 softbus 的数据包。
说明
安装
说明: 如果碰到步骤未成功执行,可参考后面 常见问题 进行解决。
完整地使用分布式文件系统,需要安装
hmdfs
、distributed-utils
和dfs_service
三个软件包。使用以下命令安装:sudo dnf install hmdfs distributed-utils dfs_service
安装 hmdfs 文件系统。安装 hmdfs 之后会提供一个 hmdfs.ko 文件,其存放在
/lib/modules/$(uname -r)/hmdfs
目录下,需要插入该 ko 来安装 hmdfs 文件系统:cd /lib/modules/$(uname -r)/hmdfs insmod hmdfs.ko
配置
各个 SA 服务是通过 sa_main
二进制来拉起,而 sa_main
拉起服务依赖服务的 profile 配置文件,因此在启动服务之前,需要配置各个服务的 profile 文件,步骤如下:
新建
/system/profile
目录,并新建device_manager
、dfs_service
、huks_service
和huks_service
的 xml 文件。mkdir -p /system/profile cd /system/profile touch device_manager.xml distributedfiledaemon.xml huks_service.xml softbus_server.xml
各个 xml 文件填入以下内容,配置服务的一些基本信息:
- device_manager.xml
<?xml version="1.0" encoding="utf-8"?> <info> <process>device_manager</process> <loadlibs> <libpath>libdevicemanagerservice.z.so</libpath> </loadlibs> <systemability> <name>4802</name> <libpath>libdevicemanagerservice.z.so</libpath> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
- softbus_server.xml
<?xml version="1.0" encoding="utf-8"?> <info> <process>softbus_server</process> <loadlibs> <libpath>libsoftbus_server.z.so</libpath> </loadlibs> <systemability> <name>4700</name> <libpath>libsoftbus_server.z.so</libpath> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
- huks_service.xml
<?xml version="1.0" encoding="utf-8"?> <info> <process>huks_service</process> <loadlibs> <libpath>libhuks_service.z.so</libpath> </loadlibs> <systemability> <name>3510</name> <libpath>libhuks_service.z.so</libpath> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
- distributedfiledaemon.xml
<?xml version="1.0" encoding="utf-8"?> <info> <process>distributedfiledaemon</process> <loadlibs> <libpath>libdistributedfiledaemon.z.so</libpath> </loadlibs> <systemability> <name>5201</name> <libpath>libdistributedfiledaemon.z.so</libpath> <depend>4802;4700</depend> <depend-time-out>60000</depend-time-out> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
- device_manager.xml
后续有服务启动依赖
libsec_shared.z.so
这个动态库,而在 openEuler 下这个动态库叫做libboundscheck.so
(由libboundscheck
软件包提供),因此需要在/usr/lib64
下软链接出一个libsec_shared.z.so
:ln -s /usr/lib64/libboundscheck.so /usr/lib64/libsec_shared.z.so
配置每个设备的 SN 号。目前
softbus_sever
等服务获取设备的udid
还是使用/etc/SN
文件中设置的 SN 号,因此需要在每台 openEuler 设置 不同的 SN 号。echo "111" > /etc/SN # 注意:不同设备设置不同的数值
使用
分布式文件系统的使用分为两块:挂载 hmdfs 目录
和 启动 distributed_file_daemon 服务
。注意:以下步骤需要在每台 openEuler 设备下执行。
挂载 hmdfs 目录
挂载 hmdfs 目录,可以直接使用
mount
命令进行挂载,保持 OpenHarmony 的目录结构一样,挂载/data/service/el2/100/non_account
到/mnt/hmdfs/100/non_account
。mkdir -p /data/service/el2/100/non_account mkdir -p /mnt/hmdfs/100/non_account sudo mount -t hmdfs -o merge,local_dst="/mnt/hmdfs/100/non_account" "/data/service/el2/100//non_account" "/mnt/hmdfs/100/non_account"
挂载之后,可以使用
df -h
命令查看新增了挂载的目录,并且挂载目录下会有device_view
和merge_view
两个目录:├── device_view │ └── local └── merge_view
启动 dfs_service 服务
安装 libdistrbited-utils
和 dfs_service
后,相关的可执行二进制会存放在 /system/bin/
目录下,库文件会存放在 /system/lib64
下。以下操作都在 /system/bin/
目录下操作。
- 启动 samgr
cd /system/bin/ ./samgr
- 启动 huks_service
./sa_main /system/profile/huks_service.xml
- 启动 device_auth_service
./deviceauth_service
- 启动 softbus_server
./sa_main /system/profile/softbus_server.xml
- 启动 device_manager
./sa_main /system/profile/device_manager.xml
- 启动 distributed_file_daemon
./sa_main /system/profile/distributedfiledaemon.xml
功能使用
每台 openEuler 设备启动完 distributed_file_daemon 之后,可以在挂载的 /mnt/hmdfs/100/non_account
下看到远端设备的目录(示例是只有两台 openEuler 设备互联):
├── device_view
│ ├── fceda1e26c36d1dd0ba65c00d71c1ab619fcf088ad2adf33cd1e2f396dc70ee2
│ └── local
└── merge_view
⽬录下会有两个⽂件视图:device_view 是分设备的视图,local 是本地⽂件视图,另外⼀个是远端设备的⽂件视图;merge_view 是合并视图,多个设备的⽂件都在这⼀个⽬录。
后续需要跨设备进行⽂件操作,只需要操作 device_view 下⾯远端设备⽬录下的⽂件即可。
常见问题
启动各个服务日志一直在报错
Binder Driver died
。原因:说明系统未开启 binder,可以查看
/dev/binder
文件是否存在,如果不存在则说明未开启 binder。解决办法:参考 communication_ipc 仓 openEuler-22.03-LTS-SP2 分支的 README 开启 binder。
无法插入
hmdfs.ko
文件,报错insmod: ERROR: could not insert module hmdfs.ko: Invalid parameters
。原因:hmdfs 编译时依赖的 kernel 版本和现在运行环境不一致或者当前系统未开启。
解决方法一:参考 hmdfs 仓库的 README 下关于手动编译生成
hmdfs.ko
的说明,编译一个和运行环境内核匹配的hmdfs.ko
,然后插入该 ko 文件使用。解决方法二:更换和 SP2 的 kernel 版本一致的 openEuler 版本。
softbus_server
服务未成功起来,报错GetNetworkIfIp ifName:eth0 fail
。原因:使用命令
ip a
查看当前系统的网卡名称,查看是否有eth0
有线网卡名。 因为softbus_server
是通过eth0
这个有线网卡名来获取 ip 等信息,如果没有eth0
网卡则无法启动softbus_server
。解决方法一:修改网卡名称为
eth0
。解决方法二:修改
softbus_server
源码,将依赖的有线网卡名称改成当前系统的网卡名。多台 openEuler 设备拉起
softbus_server
服务之后,但是在distributed_file_daemon
服务的日志显示未发现上线设备。原因:设备之间的网络不通,或者开启了防火墙把
softbus
的数据拦截了。解决:检查网络是否通畅。(如果不影响业务,可通过
systemctl stop firewalld.service
暂时关闭防火墙进行测试)。