virtio-fs

本文详细描述了如何在Ubuntu20.04主机和基于AOSP的虚拟机中启用Virtio-FS,利用Hostrootfs功能,并在Cuttlefish环境中设置Sandbox,以实现~/cuttlefish_runtime/shared与/mnt/vendor/shared之间的映射,旨在进行深入的测试和分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

软件环境:ubuntu20.04 aosp
硬件环境:x86 PC
目标:在host ubuntu20.04和linux虚拟机间测试virtio-fs

1. 原理

  • Guest VM通过virtiofs使用Host rootfs
    参考:https://crosvm.dev/book/running_crosvm/advanced_usage.html#virtiofs-as-rootfs

2. cuttlefish开启virtio-fs

  1. 打开sandbox的情况下
  2. cuttlefish_runtime/shared 映射到Android /mount/vendor/shared
  3. 启动命令添加参数: --enable_sandbox=true
  4. host目录位置:~/cuttlefish_runtime.1/shared/,android目录位置:/mnt/vendor/shared

3. Qemu开启virtfs

  1. qemu启动支持virtfs虚拟机
qemu-system-aarch64 -cpu cortex-a72 -machine virt -nographic -smp 1 -m 256M -kernel Image -append "console=ttyAMA0,38400 keep_bootcon root=/dev/vda2 noaslr" -initrd ./rootfs.cpio.gz 
-virtfs local,path=/home/kmodules,mount_tag=host0,security_model=mapped,id=host0
-virtfs local:指定使用本地文件共享。
id=myfs:标识这个文件系统,必须是唯一的。
path=/path/to/shared/folder:主机上要共享的目录路径。
security_model=passthrough:允许虚拟机中的用户直接使用主机的权限访问文件。也可以使用 mapped 方式将主机的用户权限映射到虚拟机中。
  passthrough:虚拟机用户直接使用主机的 UID/GID 操作文件,适用于主机和虚拟机用户权限相同的情况。
  mapped:主机和虚拟机的用户权限通过映射表进行对应。
mount_tag=hostshare:虚拟机中用于挂载这个文件系统的标识。
  • 在VM执行lspci:1af4代表virtio设备,1000代表net,1009代表9p

在这里插入图片描述

  1. 在vm中挂载共享目录
mkdir -p /mnt/shared
mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/shared
  1. 查看挂载成功
$ cd shared/
$ ls
1 test.txt
$ cat test.txt
this is a virtio-9p test 

3.1 源码说明

  1. 后端qemu源码:qemu/hw/9pfs
  2. 前端Linux源码:
头文件:include/uapi/linux/virtio_9p.h
9p协议层实现源码:net/9p/ 
vfs调用9p实现源码:fs/9p/  

3.2 调用流程

fs ->  fs-9p -> net-9p-client -> net-9p-virtio driver ---> qemu virtio-9p dev

3.3 qemu 9pfs

virtio_9p_device_realize
  virtio_init
  virtio_add_queue #创建一个vq添加回调handle_9p_output
handle_9p_output #从virtq中取Element,并进行处理 
  virtqueue_pop
pdu_submit
    qemu_coroutine_create #创建协程进行处理
携程handler有3种
v9fs_op_not_supp
  pdu_complete #不支持
    pdu_marshal
      virtio_pdu_vmarshal
        v9fs_iov_vmarshal
    push_and_notify
      virtio_9p_push_and_notify
        virtio_notify #pdu入队virtio通知
v9fs_fs_ro
  pdu_complete #只读文件系统
pdu_co_handlers #定义了P9协议各种文件操作对应的回调,由pdu->id指定
  • pdu_co_handlers定义的P9文件处理操作回调如下
static CoroutineEntry *pdu_co_handlers[] = {
[P9_TREADDIR] = v9fs_readdir,
[P9_TSTATFS] = v9fs_statfs,
[P9_TGETATTR] = v9fs_getattr,
[P9_TSETATTR] = v9fs_setattr,
[P9_TXATTRWALK] = v9fs_xattrwalk,
[P9_TXATTRCREATE] = v9fs_xattrcreate,
[P9_TMKNOD] = v9fs_mknod,
[P9_TRENAME] = v9fs_rename,
[P9_TLOCK] = v9fs_lock,
[P9_TGETLOCK] = v9fs_getlock,
[P9_TRENAMEAT] = v9fs_renameat,
[P9_TREADLINK] = v9fs_readlink,
[P9_TUNLINKAT] = v9fs_unlinkat,
[P9_TMKDIR] = v9fs_mkdir,
[P9_TVERSION] = v9fs_version,
[P9_TLOPEN] = v9fs_open,
[P9_TATTACH] = v9fs_attach,
[P9_TSTAT] = v9fs_stat,
[P9_TWALK] = v9fs_walk,
[P9_TCLUNK] = v9fs_clunk,
[P9_TFSYNC] = v9fs_fsync,
[P9_TOPEN] = v9fs_open,
[P9_TREAD] = v9fs_read,
#if 0
[P9_TAUTH] = v9fs_auth,
#endif
[P9_TFLUSH] = v9fs_flush,
[P9_TLINK] = v9fs_link,
[P9_TSYMLINK] = v9fs_symlink,
[P9_TCREATE] = v9fs_create,
[P9_TLCREATE] = v9fs_lcreate,
[P9_TWRITE] = v9fs_write,
[P9_TWSTAT] = v9fs_wstat,
[P9_TREMOVE] = v9fs_remove,
}; 

3.4 Linux 9P

  1. 内核编译9P
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y #编译9p virtio驱动
CONFIG_NET_9P_DEBUG=y (Optional)
CONFIG_9P_FS=y           #编译9p对vfs支持
CONFIG_9P_FS_POSIX_ACL=y 
  1. P9驱动初始化
p9_virtio_init
  v9fs_register_trans() #注册协议p9_virtio_trans
  register_virtio_driver() #注册virtio驱动p9_virtio_drv
p9_virtio_probe #p9驱动初始化
  virtio_find_single_vq #设置回调为req_done
init_waitqueue_head #初始化vc_wq等待队列
  1. vq回调函数req_done
req_done
  virtqueue_get_buf #从vq取req
  p9_client_cb #将req回调给client处理
    p9_req_put #先内存屏障,再将req传递
      p9_tag_remove(c, r) #不一定能进来
     p9_fcall_fini(&r->tc)
     p9_fcall_fini(&r->rc)
  1. 以VM中mount为例,req_done调用栈
#0 req_done (vq=0xffff00000536ff00) at net/9p/trans_virtio.c:129
#1 0xffff8000807b3664 in vring_interrupt (irq=<optimized out>, _vq=<optimized out>) at drivers/virtio/virtio_ring.c:2595
#2 vring_interrupt (irq=<optimized out>, _vq=<optimized out>) at drivers/virtio/virtio_ring.c:2570
#3 0xffff8000800fa158 in __handle_irq_event_percpu (desc=desc@entry=0xffff0000053c6c00) at kernel/irq/handle.c:158
#4 0xffff8000800fa2f0 in handle_irq_event_percpu (desc=0xffff0000053c6c00) at kernel/irq/handle.c:210
#5 handle_irq_event (desc=desc@entry=0xffff0000053c6c00) at kernel/irq/handle.c:210
#6 0xffff8000800ffb70 in handle_fasteoi_irq (desc=0xffff0000053c6c00) at kernel/irq/chip.c:720
#7 0xffff8000800f9384 in generic_handle_irq_desc (desc=<error reading variable: dwarf2_find_location_expression: Corrupted DWARF expression.>) at ./include/linux/irqdesc.h:161
#8 handle_irq_desc (desc=<optimized out>) at kernel/irq/irqdesc.c:672
#9 generic_handle_domain_irq (domain=<optimized out>, hwirq=<optimized out>) at kernel/irq/irqdesc.c:728
#10 0xffff800080010198 in gic_handle_irq (regs=<optimized out>) at drivers/irqchip/irq-gic.c:373
#11 0xffff800080015df0 in call_on_irq_stack () at ./include/linux/mm.h:3108
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
  1. 一个req结构为
(gdb) p *req
$2 = {status = 2, t_err = 0, refcount = {refs = {counter = 2}}, wq = {lock = {{rlock = {raw_lock = {{val = {counter = 0}, {locked = 0 '\000', pending = 0 '\000'}, {
locked_pending = 0, tail = 0}}}}}}, head = {next = 0xffff800082a6bac8, prev = 0xffff800082a6bac8}}, tc = {size = 21, id = 100 'd', tag = 65535, offset = 0,
capacity = 4096, cache = 0x0, sdata = 0xffff000005376000 "\025", zc = false}, rc = {size = 21, id = 0 '\000', tag = 65535, offset = 0, capacity = 4096, cache = 0x0,
sdata = 0xffff000005377000 "\025", zc = false}, req_list = {next = 0xffff0000084a1088, prev = 0xffff0000084a1088}} 
  1. P9_Virtio驱动提供很多p9_client_xx 供fs/9p调用
  p9_client_create
  p9_client_attach #mount ls命令调用
  p9_client_getattr_dotl #ls
  p9_client_walk #ls
  p9_client_open  #cd
... 
  1. VM中执行mount后函数调用栈
#0 p9_req_put (r=0xffff0000084a1000, c=0xffff00000848b600) at net/9p/client.c:402
#1 p9_req_put (c=0xffff00000848b600, r=0xffff0000084a1000) at net/9p/client.c:399
#2 0xffff800080fdbaa8 in p9_client_version (c=0xffff00000848b600) at net/9p/client.c:967
#3 p9_client_create (dev_name=dev_name@entry=0xffff0000053be478 "host0", options=options@entry=0xffff000005375000 "trans=virtio,version=9p2000.L") at net/9p/client.c:1029 #很多其他调用也会走到p9_req_put
#4 0xffff80008046fe58 in v9fs_session_init (v9ses=v9ses@entry=0xffff0000053e9c80, dev_name=dev_name@entry=0xffff0000053be478 "host0",
data=data@entry=0xffff000005375000 "trans=virtio,version=9p2000.L") at fs/9p/v9fs.c:410
#5 0xffff800080469b9c in v9fs_mount (fs_type=0xffff800082446270 <v9fs_fs_type>, flags=32768, dev_name=0xffff0000053be478 "host0", data=0xffff000005375000) at fs/9p/vfs_super.c:123
#6 0xffff800080305a80 in legacy_get_tree (fc=0xffff00000854c480) at fs/fs_context.c:662
#7 0xffff8000802c39a4 in vfs_get_tree (fc=fc@entry=0xffff00000854c480) at fs/super.c:1750
#8 0xffff8000802f06b4 in do_new_mount (data=0xffff000005375000, name=0xffff0000053be440 "host0", mnt_flags=32, sb_flags=32768,
fstype=0xffff800082446270 <v9fs_fs_type> "h\221\211\201", path=0xffff800082a6bdf8) at fs/namespace.c:3335
#9 path_mount (dev_name=dev_name@entry=0xffff0000053be440 "host0", path=path@entry=0xffff800082a6bdf8, type_page=type_page@entry=0xffff0000053be438 "9p", flags=<optimized out>,
flags@entry=32768, data_page=data_page@entry=0xffff000005375000) at fs/namespace.c:3662
#10 0xffff8000802f1400 in do_mount (data_page=0xffff000005375000, flags=32768, type_page=0xffff0000053be438 "9p",
dir_name=<error reading variable: dwarf2_find_location_expression: Corrupted DWARF expression.>, dev_name=0xffff0000053be440 "host0") at fs/namespace.c:3675
#11 __do_sys_mount (data=<optimized out>, flags=32768, type=<optimized out>, dir_name=<optimized out>, dev_name=<optimized out>) at fs/namespace.c:3884
#12 __se_sys_mount (data=<optimized out>, flags=32768, type=<optimized out>, dir_name=<optimized out>, dev_name=<optimized out>) at fs/namespace.c:3861
#13 __arm64_sys_mount (regs=<optimized out>) at fs/namespace.c:3861 
<think>好的,我现在需要处理用户关于VIOFS驱动程序服务器中g_user配置或信息的问题。首先,我需要明确VIOFS是什么。根据用户提到的“viofs驱动程序”,这可能与虚拟化环境中的文件系统相关。例如,QEMU或KVM这类虚拟化工具可能会使用类似的技术来共享主机和虚拟机之间的文件。 接下来,用户提到的“g_user”可能是一个配置参数或者结构体中的字段。我需要回想是否有相关的文档提到过这个术语。根据提供的引用内容,引用[2]提到了打开/dev/kvm的操作,这可能与虚拟化驱动有关,而引用[3]列出了Vector驱动的硬件相关特性,可能涉及驱动程序配置。但具体到VIOFS的g_user,可能需要更具体的资料。 首先,我应该检查是否有关于VIOFS的官方文档。例如,微软的Virtual Hard Disk (VHD)或类似技术是否有相关配置。不过用户提到的VIOFS可能与Linux虚拟化环境更相关,比如QEMU或virtio-fs。这里可能需要查阅virtio-fs的文档,因为VirtIO是常见的虚拟化设备标准。 如果virtio-fs中没有g_user的配置,可能需要考虑用户是否混淆了术语。比如,g_user可能是指某个用户空间组件或守护进程的配置参数。例如,在virtio-fs中,daemon(如virtiofsd)可能会使用配置文件,其中可能包含用户相关的设置。 另外,用户提供的引用[4]提到了Python和PySpark的版本信息,这可能与问题无关,但引用[3]提到的驱动特性表可能涉及配置选项。需要查看该表是否有类似g_user的条目。 如果找不到直接的信息,可能需要建议用户检查相关驱动程序的配置文件、源代码或日志文件。例如,在Linux系统中,驱动程序配置可能位于/etc目录下的某个文件,或者在内核模块参数中设置。此外,查看系统日志(如使用dmesg)可能有助于发现g_user相关的信息。 最后,如果以上途径都无法确定,建议用户提供更多上下文或检查相关文档的更新版本,因为某些配置参数可能在新版本中被引入或重命名。</think>关于VIOFSVirtIO文件系统)驱动程序服务器中`g_user`的配置信息,根据虚拟化技术文档和驱动开发规范,以下是关键要点分析: 1. **VirtIO-fs架构特性** - VirtIO-fs通过共享文件系统实现宿主机与虚拟机的高速数据交互,其核心组件`virtiofsd`守护进程使用FUSE协议通信[^3] - 典型配置示例: ```bash /usr/libexec/virtiofsd \ --socket-path=/var/run/virtiofsd.sock \ --shared-dir=/path/to/share \ --cache=auto ``` 2. **用户身份映射配置** - `g_user`可能涉及以下两种配置场景: - *POSIX用户映射*:在`virtiofsd`启动参数中指定`-o uid_map`和`-o gid_map`实现用户权限转换 ```bash -o uid_map=1000:1000:1 -o gid_map=1000:1000:1 ``` - *Windows ACL映射*:在Hyper-V环境中通过安全描述符实现跨系统用户映射[^1] 3. **安全配置建议** - 遵循最小权限原则配置共享目录访问权限 - 使用TLS加密通信时需要配置证书路径和用户验证参数: ```bash --tls-cert-file=/etc/pki/server-cert.pem \ --tls-key-file=/etc/pki/server-key.pem ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值