一,前言

本节主要分析option相关的搜索API。

二,源码分析

时常看到如下的opts使用API。那么就来分析下。
qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, NULL);

  1. 最开始搜索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;
}
  1. qemu_opts_foreach主要就是对一个list中的所有Opts进行归递处理。若为空就直接退出了,否则要执行func函数

Qemu源码分析(4)—Apple的学习笔记_qemu

  1. 我在rc=func执行的语句打断点,第一个执行的是chardev_init_func说明这类语句的含义就是通过搜索opt的存在性来执行相关option的初始化函数


if (qemu_opts_foreach(qemu_find_opts("chardev"),
 chardev_init_func, NULL, NULL)) {
 exit(1);
}
  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;
}
  1. 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;
}
  1. 再关注下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;
 }
}

类型定义

Qemu源码分析(4)—Apple的学习笔记_qemu_02

  1. 关于类图主要关系如下

Qemu源码分析(4)—Apple的学习笔记_qemu_03

三,小结

本节主要内容就是分析option相关的搜索API了解结构体设计和它的搜索算法。说不定我将来也能用到这类设计手法。