接前一篇文章:QEMU源码全解析35 —— Machine(5)
本文内容参考:
《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
上回书讲解了3个函数:object_class_get_list_tramp、object_foreach_tramp和type_table_get。回到select_machine函数中,继续往下进行。为了便于理解,再次贴出select_machine函数代码,在softmmu/vl.c中,如下:
static MachineClass *select_machine(QDict *qdict, Error **errp)
{
const char *optarg = qdict_get_try_str(qdict, "type");
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
MachineClass *machine_class;
Error *local_err = NULL;
if (optarg) {
machine_class = find_machine(optarg, machines);
qdict_del(qdict, "type");
if (!machine_class) {
error_setg(&local_err, "unsupported machine type");
}
} else {
machine_class = find_default_machine(machines);
if (!machine_class) {
error_setg(&local_err, "No machine specified, and there is no default");
}
}
g_slist_free(machines);
if (local_err) {
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
error_propagate(errp, local_err);
}
return machine_class;
}
前文书提到,在select_machine函数中,有两种方式可以生成MachineClass:一种方式是调用find_machine函数,通过解析QEMU命令行参数生成MachineClass,即用户指定方式;另一种方式是通过find_default_machine函数找一个默认的MachineClass,即系统默认方式。一个一个来看:
- 命令行指定方式
find_machine函数在softmmu/vl.c中,代码如下:
static MachineClass *find_machine(const char *name, GSList *machines)
{
GSList *el;
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
return mc;
}
}
return NULL;
}
如果在命令行中指定的名字与已创建的MachineClass的名字或者别名相同,则返回此MachineClass对象mc;否则返回NULL,表示没有找到。
- 系统默认方式
find_default_machine函数同样在softmmu/vl.c中(实际上就在find_machine函数下边),代码如下:
static MachineClass *find_default_machine(GSList *machines)
{
GSList *el;
MachineClass *default_machineclass = NULL;
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
if (mc->is_default) {
assert(default_machineclass == NULL && "Multiple default machines");
default_machineclass = mc;
}
}
return default_machineclass;
}
可以看到,意思和find_machine函数差不多,也是遍历machines链表,不过这里不用比较名字,而是找is_default属性为true的那一个MachineClass对象mc,经过检查无误后将之返回。
至此,select_machine函数就完成了它的使命,最终返回了所需的MachineClass对象(地址)。
注:本回篇幅较短,主要是由于前一篇文章篇幅较长,为了避免阅读疲劳而有意为之,正所谓“文武之道,一张一弛”,这样可以不至于学习时过于疲惫,保证学习和阅读的积极性。
在下一盘文章中将对qemu_create_machine函数的第2步功能current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));进行讲解。欲知后事如何,且看下回分解。