davfs 移植到android 踩坑之旅

    1、davfs 简介

             davfs 是一个支持webdav 协议的库,可以将支持webdav 协议的网盘等挂载到本地文件系统,目前国内支持webdav 协议的知道的只有坚果云。davfs 基于neon 库,neon 库实现webdav 协议的交互,davfs 则实现本地文件和网络文件的同步,将远程网络文件mount 到本地。

    2、编译以及移植

    2.1、编译安装

          我是在arm 64的ubuntu开发板上编译的,所以编译方面没有遇到太多的问题(用NDK 编译更好,不过要解决编译一大堆依赖)。ubuntu 下安装neon ,configure、make  一步到位。

  

apt install libneon27-dev
#apt-get install autoconf automake libtool autopoint

./configure
make && make install

    挂载测试

mount -t davfs https://dav.jianguoyun.com/dav/ /home/jianguoyun/

  输入用户名和密码,在ubuntu 上可以正常挂载,接下来就是将davfs 移植到安卓下了。

  2.2 安卓部署测试

    安卓下需配置configure ,重新编译, 修改configure 文件,修改dav_localstatedir 变量,将dav_localstatedir 默认值 /var/run 、/var/cache 改为/data 目录下(因为android 根目录下可能没有var 目录)

 9172     if test -z "$dav_localstatedir"; then dav_localstatedir="/data/run"; fi
 9173 
 9174 
 9175     if test -z "$dav_syscachedir"; then dav_syscachedir="/data/cache"; fi

 然后执行(同样是在arm 版ubuntu 上编译)

/configure --sysconfdir=/data
make && make install

  编译后的执行文件位于 src/mount.davfs ,src/umount.davfs ,使用ldd 命令,查找mount,.davfs 所有依赖库,根据路径提取出相应的so库

linux-vdso.so.1 =>  (0x0000007e4c81d000)
	libneon.so.27 => /usr/lib/aarch64-linux-gnu/libneon.so.27 (0x0000007e4c7af000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007e4c669000)
	/lib/ld-linux-aarch64.so.1 (0x0000007e4c7f2000)
	libz.so.1 => /lib/aarch64-linux-gnu/libz.so.1 (0x0000007e4c642000)
	libssl.so.1.0.0 => /lib/aarch64-linux-gnu/libssl.so.1.0.0 (0x0000007e4c5d9000)
	libcrypto.so.1.0.0 => /lib/aarch64-linux-gnu/libcrypto.so.1.0.0 (0x0000007e4c436000)
	libgssapi_krb5.so.2 => /usr/lib/aarch64-linux-gnu/libgssapi_krb5.so.2 (0x0000007e4c3e7000)
	libxml2.so.2 => /usr/lib/aarch64-linux-gnu/libxml2.so.2 (0x0000007e4c255000)
	libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007e4c242000)
	libkrb5.so.3 => /usr/lib/aarch64-linux-gnu/libkrb5.so.3 (0x0000007e4c179000)
	libk5crypto.so.3 => /usr/lib/aarch64-linux-gnu/libk5crypto.so.3 (0x0000007e4c13e000)
	libcom_err.so.2 => /lib/aarch64-linux-gnu/libcom_err.so.2 (0x0000007e4c12a000)
	libkrb5support.so.0 => /usr/lib/aarch64-linux-gnu/libkrb5support.so.0 (0x0000007e4c110000)
	libicuuc.so.55 => /usr/lib/aarch64-linux-gnu/libicuuc.so.55 (0x0000007e4bf6f000)
	liblzma.so.5 => /lib/aarch64-linux-gnu/liblzma.so.5 (0x0000007e4bf42000)
	libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007e4be95000)
	libkeyutils.so.1 => /lib/aarch64-linux-gnu/libkeyutils.so.1 (0x0000007e4be81000)
	libresolv.so.2 => /lib/aarch64-linux-gnu/libresolv.so.2 (0x0000007e4be5c000)
	libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007e4be30000)
	libicudata.so.55 => /usr/lib/aarch64-linux-gnu/libicudata.so.55 (0x0000007e4a569000)
	libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007e4a3da000)
	libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007e4a3b9000)

 修改davfs2.conf 

ignore_dav_header 1

 使用adb 命令,连接到Android 板卡,板卡必须有root 权限

adb root
adb remount 


#如果出现push 出现read only file system,先adb shell 进入板卡,然后执行mount -o rw,remount / #之后就可以读写lib 文件夹


adb push .\lib\ /lib
adb push mount.davfs /system/bin
adb push umount.davfs /system/bin

# 拷贝配置文件
adb push .\davfs2\ /data 

#进入android 板卡
adb shell

#创建mount.davfs 需要用到的文件和文件夹
mkdir /data/run -p
mkdir /data/cache -p
touch /data/mtab


#权限赋予
chmod u+x /lib/* 
chmod u+x /system/bin/mount.davfs
chmod u+x /system/bin/umount.davfs

#运行测试
mount.davfs https://dav.jianguoyun.com/dav/ /mnt
ls /mnt

2.3 遇到的一些问题

     1、运行程序各种Permission denied

           有两种情况,要么权限不够,要么缺so 库了,给lib 目录相应的读写权限,查看是否缺库

     2、运行报错,mount.davfs: Warning: can't write entry into /etc/mtab, but will mount the file system anyway

          出现这个问题是因为android 系统是没有etc/mtab 这个文件的,mtab 保存着文件系统的一些信息,davfs 会读写这个文件,手动创建一个空白文件就行(其实还是能挂载上去,只是报错看着不爽)

    3、运行报错 Could not resolve hostname

        这问题还是让我挺困扰的,追踪源码发现gethostbyname这个函数报错,DNS 解析失败,直接填ip 是能挂载上去的,新建一个文本命名为resolv.conf,里面信息如下,放到板卡/system/etc/ 目录下,注意libnss_dns.so.2、libnss_dns-2.23.so 丢失也会报这个错误,我猜测是libc dns解析不走android 那一套。

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 114.114.114.114

 解决办法

adb push ./resolve.conf /ststem/etc

 以上都是在adb 上测试的,部署的时候就不能用adb 了,需要修改rc 文件制作镜像,编写脚本等,这些都是题外话了。

 

写在结尾

  其实这种做法有点邪道,毕竟移植没有用NDK 工具编译,始终是不太妥当的,但也不失为一种方案。因为同事接下任务时是用arm gcc 编译的(就是个大坑,公司都没人懂arm-gcc 移植到android),我接手的时候要么重新NDK 编译,要么继续用他以前的方案,很纠结,最后还是偷懒选择arm gcc 方案,算是一条路走到黑了。

相关链接:

davfs官网: https://savannah.nongnu.org/projects/davfs2

neon 官网 :http://www.webdav.org/neon/doc/html/index.html

上一篇:下载安装ARM交叉编译器


下一篇:aarch64的TCR寄存器介绍