Monitor的作用

QEMU Monitor Protocol (QMP) 是允许应用程序使用json格式与qemu进行通信的协议. Libvirt中的Qemu Monitor是Libvirt与Qemu通信的一种机制. 比如暂停虚拟机,恢复虚拟机,创建快照等. 主要的代码在qemu_monitor_json.c, qemu_monitor.c中.

Monitor的创建

Monitor的创建代码在qemuMonitorOpen中,我们目前使用的类型是AF_UNIX。

Monitor发送消息流程

 

qemu日志路径 qemu monitor命令_json格式

qemu日志路径 qemu monitor命令_json格式_02

1. monitor消息是怎么发出去的

图1的流程图中并没有真正的发送msg给qemu,只是在往pipe里面写了一个消息。 真正的发送流程在qemuMonitorIO -----> qemuMonitorIOWrite流程里面。  那消息是怎么发送出去的呢?这个要看函数qemuMonitorUpdateWatch。它在qemuMonitorIO里面和qemuMonitorSend里面被调用到。 这个函数仔细看就明白了,在qemuMonitorSend里面给它挂载了一个msg,调用qemuMonitorUpdateWatch的时候会给mon加上writeable事件,这么一来下一次调用poll的时候就可以报writeable事件,然后分发给qemuMonitorIO,然后在qemuMonitorIOWrite中把msg写入到monitor的fd中(也就是发给qemu); 在qemuMonitorIO处理monitor io完成以后调用qemuMonitorUpdateWatch,此时很可能msg写完了,所以它只设置了readable,而去掉了writeable,表明不需要关注是否可写入数据了。 这样在下一次poll的时候就不会关注可写入事件了。

2. 什么地方去关闭mon的可读写属性?

答: 其实这里并不是修改mon fd的可读写属性。而是改变poll该fd的时候的需要关注该fd的哪些event事件。这个改变在virEventPollMakePollFDs中,在每次poll之前都去make这些fd和我们希望fd关注的事件。

3. 为什么写pipe?

注意上面蓝色字体部分。如果有消息可写入到与qemu连接的socket中,那怎么触发它呢?平常poll的时候只关注了fd的readable事件,所以poll不到writeable,poll可能一直阻塞在内核中。 如果整个的poll列表中只有monitor fd一个句柄,那么poll可能永远阻塞。所以不管怎么着给poll列表中加入一个pipe fd吧,然后每次qemuMonitorUpdateWatch去写一下这个pipe,让poll返回到用户态(这样就可以在virEventPollMakePollFDs中重新make poll event去关注writebale事件了)。 这也叫self-pipe。

4. 接着上面的问题,是否可以直接send monitor msg呢?

也许吧,但它可能返回失败。

5. 接着上面的问题,是否能一直关注writeable事件呢?

不行,因为它经常处于writeable状态,这么一来poll调用会不断的返回writeable,程序得忙死。

6. Monitor的Watch作用是什么?

答:标识一个唯一的loop handle. 为什么不使用fd来标识一个loop handle? 因为同一个fd可以注册多个event callbk.  为什么nextWatch为什么一直累加就可以了? 想多了,整形最大值21亿,不太可能出现这种翻转的情况.