QEMU源码全解析36 —— Machine(6)

88 篇文章 19 订阅
本文深入探讨QEMU的select_machine函数,解析如何通过find_machine和find_default_machine来确定MachineClass,介绍了这两种方式在QEMU命令行参数与系统默认设置中的应用。文章以代码示例解释了函数的工作原理,并预告了对qemu_create_machine函数后续步骤的讨论。
摘要由CSDN通过智能技术生成

接前一篇文章: 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中,如下:

  1. static MachineClass *select_machine(QDict *qdict, Error **errp)
  2. {
  3. const char *optarg = qdict_get_try_str(qdict, "type");
  4. GSList *machines = object_class_get_list(TYPE_MACHINE, false);
  5. MachineClass *machine_class;
  6. Error *local_err = NULL;
  7. if (optarg) {
  8. machine_class = find_machine(optarg, machines);
  9. qdict_del(qdict, "type");
  10. if (!machine_class) {
  11. error_setg(&local_err, "unsupported machine type");
  12. }
  13. } else {
  14. machine_class = find_default_machine(machines);
  15. if (!machine_class) {
  16. error_setg(&local_err, "No machine specified, and there is no default");
  17. }
  18. }
  19. g_slist_free(machines);
  20. if (local_err) {
  21. error_append_hint(&local_err, "Use -machine help to list supported machines\n");
  22. error_propagate(errp, local_err);
  23. }
  24. return machine_class;
  25. }

前文书提到,在select_machine函数中,有两种方式可以生成MachineClass:一种方式是调用find_machine函数,通过解析 QEMU 命令行参数生成MachineClass,即用户指定方式;另一种方式是通过find_default_machine函数找一个默认的MachineClass,即系统默认方式。一个一个来看:

  • 命令行指定方式

find_machine函数在softmmu/vl.c中,代码如下:

  1. static MachineClass *find_machine(const char *name, GSList *machines)
  2. {
  3. GSList *el;
  4. for (el = machines; el; el = el->next) {
  5. MachineClass *mc = el->data;
  6. if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
  7. return mc;
  8. }
  9. }
  10. return NULL;
  11. }

如果在命令行中指定的名字与已创建的MachineClass的名字或者别名相同,则返回此MachineClass对象mc;否则返回NULL,表示没有找到。

  • 系统默认方式

find_default_machine函数同样在softmmu/vl.c中(实际上就在find_machine函数下边),代码如下:

  1. static MachineClass *find_default_machine(GSList *machines)
  2. {
  3. GSList *el;
  4. MachineClass *default_machineclass = NULL;
  5. for (el = machines; el; el = el->next) {
  6. MachineClass *mc = el->data;
  7. if (mc->is_default) {
  8. assert(default_machineclass == NULL && "Multiple default machines");
  9. default_machineclass = mc;
  10. }
  11. }
  12. return default_machineclass;
  13. }

可以看到,意思和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)));进行讲解。欲知后事如何,且看下回分解。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他