接前一篇文章:QEMU源码全解析35 —— Machine(5)

本文内容参考:

《趣谈Linux操作系统》 —— 刘超,极客时间

《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)));进行讲解。欲知后事如何,且看下回分解。