一,前言
本节主要分析option的搜索API。
二,源码分析
时常看到如下的opts使用API。那么就来分析下。
qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, NULL);
- 最开始搜索QemuOptsList比较容易理解,就是从vm_config_groups数组中找。此list是初始化的时候通过qemu_add_opts一个个加入到list中的。
QemuOptsList *qemu_find_opts(const char *group)
{
QemuOptsList *ret;
Error *local_err = NULL;
ret = find_list(vm_config_groups, group, &local_err);
if (local_err) {
error_report_err(local_err);
}
return ret;
}
- qemu_opts_foreach主要就是对一个list中的所有Opts进行归递处理。若为空就直接退出了,否则要执行func函数。
- 我在rc=func执行的语句打断点,第一个执行的是chardev_init_func说明这类语句的含义就是通过搜索opt的存在性来执行相关option的初始化函数。
if (qemu_opts_foreach(qemu_find_opts("chardev"),
chardev_init_func, NULL, NULL)) {
exit(1);
}
- 光看到此处QemuOpt还没用上,继续看一定会用上的就在qemu_opt_get函数中
const char *qemu_opt_get(QemuOpts *opts, const char *name)
{
QemuOpt *opt;
if (opts == NULL) {
return NULL;
}
opt = qemu_opt_find(opts, name);
if (!opt) {
const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
if (desc && desc->def_value_str) {
return desc->def_value_str;
}
}
return opt ? opt->str : NULL;
}
- qemu_opt_find(opts, name)是否又看到了雷同的链表搜索手法
QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
{
QemuOpt *opt;
QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
if (strcmp(opt->name, name) != 0)
continue;
return opt;
}
return NULL;
}
- 再关注下opts->list->desc,通过opts可以向上找list中的内容。他们算是密切联系的内容。而这些desc描述的用途,我理解可以把字符串为不同的类型,比如如下就是把on和off的描述转为boolean类型的1和0。
static void parse_option_bool(const char *name, const char *value, bool *ret,
Error **errp)
{
if (value != NULL) {
if (!strcmp(value, "on")) {
*ret = 1;
} else if (!strcmp(value, "off")) {
*ret = 0;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name, "'on' or 'off'");
}
} else {
*ret = 1;
}
}
类型定义
- 关于类图主要关系如下
三,小结
本节主要内容就是分析option相关的搜索API,了解结构体设计和它的搜索算法。说不定我将来也能用到这类设计手法。
标签:opt,Apple,Qemu,源码,NULL,qemu,find,opts,name From: https://blog.51cto.com/u_16247275/7494473