Qemu虚拟机与宿主机之间实现文件传输,大概有四类方法:

1.虚拟机与宿主机之间,使用网络来进行文件传输。这个需要先在宿主机上配置网络桥架,在qemu-kvm启动配置网卡就可以实现文件传输。

2.使用9psetup协议实现虚拟机与宿主机之间文件传输。该方法先要宿主机需要在内核中配置了9p选项,qemu在编译时需要支持ATTR/XATTR。

3.通过在Qemu虚拟机中挂载宿主机中的一个文件为硬盘。

4.第四类方法是一种新方法,是用virtio-fs通过FUSE协议进行传输。

通过挂载硬盘的方法

1.用dd创建一个文件,作为虚拟机和宿主机之间传输桥梁
1$ dd if=/dev/zero of=$PWD/share.img bs=1M count=500
bs:一次读入/输出的块大小
count:拷贝块的个数
上述例子中最大可以传输的文件大小为500M。
2.格式化share.img文件
1$ mkfs.ext4 $PWD/share.img
3.在宿主机上创建一个文件夹
1
2$ mkdir /tmp/share
$ sudo mount -o loop $PWD/share.img /tmp/share
现在把宿主机上需要传输给虚拟机的文件放到/tmp/share下即可。
4.启动Qemu虚拟机,额外为虚拟机添加一块硬盘
1-drive file=$PWD/share.img,if=virtio
5.在虚拟机中mount上刚添加的硬盘,即可获得宿主机上放在/tmp/share文件夹下的文件。具体做法是:通过dmesg的输出找到新挂载的硬盘,然后将硬盘mount上来。
1$ mount -t ext4 /dev/vda /mnt/
该方法的缺点是宿主机和虚拟机文件传输不能实时进行,如果要传输新文件,需要重启虚拟机。
virtio-fs
需要编译的组件如下:
一个支持virtio-fs的客户机内核(Linux 5.4+)
一个支持virtio-fs的QEMU(QEMU 5.0+)
1.在客户机中编译Linux内核,启动下面的选项:
1
2
3
4
5
6CONFIG_VIRTIO
CONFIG_VIRTIO_FS
CONFIG_DAX
CONFIG_FS_DAX
CONFIG_DAX_DRIVER
CONFIG_ZONE_DEVICE
1make -j 8 && make -j 8 modules && make -j 8 modules_install && make -j 8 install
我用的主机是Ubuntu18.04,客户机系统是Debian10.5.0,在主机上编译好内核拷贝到客户机中进行安装。
2.编译QEMU
这里想要编译出virtiofsd需要安装一个libcap-ng的包,这个是从Makefile中看出来的,需要几个CONFIG_,在configure中可以看到,configure之后会生成config-host.mak,里面需要包含Makefile中所需的CONFIG_:
1
2
3$ sudo apt install libcap-ng-dev
$ ./configure --enable-kvm --enable-debug --enable-cap-ng --target-list=x86_64-softmmu
$ make all
3.启动QEMU
先要启动virtiofsd守护进程:
1./virtiofsd -o vhost_user_socket=/tmp/vhostqemu -o source=/tmp/shared -o cache=always
启动qemu:
1
2
3
4$ ./qemu-5.1.0/x86_64-softmmu/qemu-system-x86_64 -M pc -cpu host --enable-kvm -smp 2 \
-m 4G -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on -numa node,memdev=mem \
-chardev socket,id=char0,path=/tmp/vhostqemu -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=myfs \
-drive if=virtio,file=debian.qcow2
在客户机中挂载设备:
1$ mount -t virtiofs myfs /mnt