接前一篇文章: 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)));进行讲解。欲知后事如何,且看下回分解。