现在的位置: 首页 > 综合 > 正文

为QEMU添加新的QMP命令

2013年05月10日 ⁄ 综合 ⁄ 共 1783字 ⁄ 字号 评论关闭

http://blog.sina.com.cn/s/blog_6b19f21d0100v07z.html

QMP命令由结构mon_cmd_t定义,该结构在monitor.c的开头被定义。注意查看它的成员以及该结构上面的注释。

为了添加新的QMP命令,需要修改qemu-monitor.hx
注意查看最开始的说明:
DEFHEADING() 用于在help text和texi中增加标题头
处于STEXI和ETEXI之间的内容会被拷贝到texi版本中,但不会出现在C版本中
处于SQMP和EQMP之间的内容会被拷贝到QMP文档中,但不会出现在其它格式的版本中
DEF(command, args, callback, arg_string,help)用于构造monitor命令
HXCOMM用于注释
为了增加新的命令,我们需要在qemu-monitor.hx中增加mon_cmd_t结构的实例。实际的写法如何可以
参照qemu-monitor.hx中已有命令以及monitor.c开头的注释。下面是drive_del命令对应的mon_cmd_t
{
.name      = RFQDN_REDHAT "drive_del",
.args_type  = "id:s", 
.params     ="device",
.help      = "remove host block device",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_drive_del,
},
这里的RFQDN_REDHAT在monitor.h中定义,
#define RFQDN_REDHAT "__com.redhat_"
添加前缀是为了保证当有多个组织往QMP中添加命令的时候不会重复。
为什么要加前缀,以及为什么以两个下划线开头,可以参见QMP/qmp-spec.txt
QMP命令的处理过程:
在qemu-monitor.hx中的命令,经过预处理之后会生成x86_64-softmmu/qemu-monitor.h
这里的x86_64-softmmu跟CPU架构有关,不同的架构可能会生成不同的目录名称。
在qemu-monitor.h中就不会出现包含在STEXI, ETEXI以及SQMP,EQMP之间的内容,它的内容
就是所有命令所对应的mon_cmd_t结构列表
在monitor.c中,有以下的代码
static const mon_cmd_t mon_cmds[] = {
#include "qemu-monitor.h"
    { NULL, NULL, },
};
通过这样的步骤,qemu-monitor.hx中的命令最终就进入到了QEMU的代码中。
qemu中,对于info命令,有一些特别的处理。在qemu-monitor.hx中已经定义了info命令,
其handler为do_info。在do_info中,又会去查找info_cmds(在monitor.c)中定义的
子命令。因此,如果需要添加一条新的info xxx命令,只需要在monitor.c中的
info_cmds中添加mon_cmd_t结构就行了。而不是在qemu-monitor.hx中添加mon_cmd_t结构。
但是记得在qmp-monitor.hx中要把相应的说明添加进去。
对于支持QMP的命令,必须设置mon_cmd_t的user_print函数,该函数用于将返回的对象打印到
monitor控制台上。而且对于info命令,必须设置mhandler.info_new,其它命令则设置
mhandler.cmd_new,这两个函数返回一个对象,但是不打印任何内容。
返回的对象是json的对象表示。如果返回内容是一个列表,那么可以先list = qlist_new(),
然后使用qlist_append_obj往里面添加对象,最后 *ret_data = QOBJECT(list)
如果返回内容是一个字典,那么可以使用qobject_from_jsonf。一个较复杂的例子可以参见
info block的处理函数bdrv_info
user_print函数则将返回的对象打印到monitor控制台,可以使用monitor_printf等函数。
对于只支持HMP,不支持QMP的命令,则将user_print设置为NULL,并且设置相应的mhandler.info和
mhandler.cmd函数。

抱歉!评论已关闭.