首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[qemu][block]qemu-nbd技术分析

[qemu][block]qemu-nbd技术分析

作者头像
皮振伟
发布2018-04-09 11:14:13
6.2K0
发布2018-04-09 11:14:13
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏

前言: 想要修改Guest中的文件,第一种办法可以把虚拟机启动虚拟机,在虚拟机内部修改。 还有一种办法,使用qemu的nbd功能。准确来说,是使用linux提供的nbd(Network Block Device),加上qemu提供的qemu-nbd作为后端的server共同实现。 本文先提供使用qemu-nbd修改镜像文件的方法,再分析qemu-nbd的实现。 分析: 1,qemu-nbd 使用qemu-nbd之前,需要先确认当前环境上是不是支持linux nbd: ls /dev/nbd*来确认是不是已经支持nbd了。如果支持,下面加载部分的操作可以省略。 modinfo nbd命令来确认nbd模块是不是在当前环境中已经存在。 modprobe nbd nbds_max=64命令用来加载nbd模块,后面的参数nbds_max=64是为了告诉linux默认生成64个nbd device。 qemu-nbd -c /dev/nbd0 ubuntu-server.qcow2命令是让/dev/nbd0连接到ubuntu-server.qcow2上。 那么,如果已经安装过操作系统的情况下,就可以看到/dev/nbd0p1,/dev/nbd0p2,/dev/nbd0p5类似的分区。这个分区情况和从操作系统内部看来是相同的。 继续执行,mkdir guest-root; mount -o rw /dev/nbd0p1 guest-root;就可以在guest-root目录下编辑镜像信息了。 编辑完成后,执行sync,再umount guest-root,最后qemu-nbd -d /dev/nbd0断开nbd连接。 2,detail 以向镜像中写数据为例子,如下图:

a,在挂载的nbd分区中写入数据,那么经过系统调用到kernel。 b,kernel找到对应的inode,并把它写入文件所在的分区,也就是nbd0。 c,nbd0的write函数被重载,实际上kernel会调用sendmsg写到unix-socket中。 d,qemu-nbd在 执行connect的时候,虽然自己退出了,但是会启动一个子进程作为daemon。daemon收到事件,调用recvmsg得到数据。 e,qemu-nbd daemon调用qcow2的库函数,计算出来对应的位置,把数据写入到ubuntu-server.qcow2文件中。 f,写入到ubuntu-server.qcow2,经过系统调用到vfs,最后把数据写入到真正的存储介质中。 那么,整个路径就走完了一遍,编辑分区中的文件,最后把它落地到存储中。那么接下来再具体分析几个细节。 3,unix socket 上述例子中,nbd使用unix socket,使用tcp行不行?答案是可以。linux的nbd设计上支持tcp后才支持unix socket。 Qemu-nbd的help选项中看起来也支持了,不过作者没有实验。 4,为什么写ndb0就会调用到对应的sendmsg 在qemu2.8/nbd/client.c中,

是qemu-nbd先创建了socket,再通过ioctl告诉kernel:具体的nbd dev绑定到对应的socket上。另外需要注意的是,这里的函数实现需要linux宏,也就是说其他平台上,很可能还没有实现。 5,使用loop行不行 对于raw格式,是可以使用loop的。 但是在loop的情况下,不能解析qcow2格式。 后记: Good luck。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档