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

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

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132266301