网站设计 cdc,网站开启速度变慢了,长沙有哪些大公司,互联网公司排名2022销售额接前一篇文章#xff1a;QEMU源码全解析28 —— QOM介绍#xff08;17#xff09; 本文内容参考#xff1a;
《趣谈Linux操作系统》 —— 刘超#xff0c;极客时间
《QEMU/KVM》源码解析与应用 —— 李强#xff0c;机械工业出版社
特此致谢#xff01; 前文讲解了类…接前一篇文章QEMU源码全解析28 —— QOM介绍17 本文内容参考
《趣谈Linux操作系统》 —— 刘超极客时间
《QEMU/KVM》源码解析与应用 —— 李强机械工业出版社
特此致谢 前文讲解了类属性的添加接口。本文讲解类属性的设置及获取接口。
每一种类属性都有自己的add函数如布尔bool、字符串str、enum枚举等。它们都在qom/object.c中逐个来看
ObjectProperty *
object_class_property_add_bool(ObjectClass *klass, const char *name,bool (*get)(Object *, Error **),void (*set)(Object *, bool, Error **))
{BoolProperty *prop g_malloc0(sizeof(*prop));prop-get get;prop-set set;return object_class_property_add(klass, name, bool,get ? property_get_bool : NULL,set ? property_set_bool : NULL,NULL,prop);
}
ObjectProperty *
object_class_property_add_enum(ObjectClass *klass, const char *name,const char *typename,const QEnumLookup *lookup,int (*get)(Object *, Error **),void (*set)(Object *, int, Error **))
{EnumProperty *prop g_malloc(sizeof(*prop));prop-lookup lookup;prop-get get;prop-set set;return object_class_property_add(klass, name, typename,get ? property_get_enum : NULL,set ? property_set_enum : NULL,NULL,prop);
}
ObjectProperty *
object_class_property_add_str(ObjectClass *klass, const char *name,char *(*get)(Object *, Error **),void (*set)(Object *, const char *,Error **))
{StringProperty *prop g_malloc0(sizeof(*prop));prop-get get;prop-set set;return object_class_property_add(klass, name, string,get ? property_get_str : NULL,set ? property_set_str : NULL,NULL,prop);
}
这次以str为例进行讲解。上一回已经讲过类属性的添加是通过object_class_property_add接口完成的。而str类型属性的添加object_class_property_add_str函数则是调用了此接口。为了便于理解再次贴出object_class_property_add函数代码在qom/object.c中如下
ObjectProperty *
object_class_property_add(ObjectClass *klass,const char *name,const char *type,ObjectPropertyAccessor *get,ObjectPropertyAccessor *set,ObjectPropertyRelease *release,void *opaque)
{ObjectProperty *prop;assert(!object_class_property_find(klass, name));prop g_malloc0(sizeof(*prop));prop-name g_strdup(name);prop-type g_strdup(type);prop-get get;prop-set set;prop-release release;prop-opaque opaque;g_hash_table_insert(klass-properties, prop-name, prop);return prop;
}
property_set_str和property_get_str函数在前文都已给出过这里再贴一下在同文件qom/object.c中
static void property_set_str(Object *obj, Visitor *v, const char *name,void *opaque, Error **errp)
{StringProperty *prop opaque;char *value;if (!visit_type_str(v, name, value, errp)) {return;}prop-set(obj, value, errp);g_free(value);
}
static void property_get_str(Object *obj, Visitor *v, const char *name,void *opaque, Error **errp)
{StringProperty *prop opaque;char *value;Error *err NULL;value prop-get(obj, err);if (err) {error_propagate(errp, err);return;}visit_type_str(v, name, value, errp);g_free(value);
}
从这两个函数中就可以看到StringProperty结构的set和get成员函数为调用object_class_property_add_str函数时传入的参数形参分别为void (*set)(Object *, const char *, Error **))和char *(*get)(Object *, Error **)。在object_property_add_str函数中使用了上边的property_set_str和property_get_str函数。在property_set_str函数中最终调用了形参void (*set)(Object *, const char *, Error **)对应的实参即真正类型属性的设置函数在property_get_str函数中最终调用了形参char *(*get)(Object *, Error **)对应的实参即真正的类型属性的获取函数。
仍以machine为例hw/core/machine.c的machine_class_init函数代码如下
static void machine_class_init(ObjectClass *oc, void *data)
{MachineClass *mc MACHINE_CLASS(oc);/* Default 128 MB as guest ram size */mc-default_ram_size 128 * MiB;mc-rom_file_has_mr true;/* numa node memory size aligned on 8MB by default.* On Linux, each nodes border has to be 8MB aligned*/mc-numa_mem_align_shift 23;object_class_property_add_str(oc, kernel,machine_get_kernel, machine_set_kernel);object_class_property_set_description(oc, kernel,Linux kernel image file);object_class_property_add_str(oc, initrd,machine_get_initrd, machine_set_initrd);object_class_property_set_description(oc, initrd,Linux initial ramdisk file);object_class_property_add_str(oc, append,machine_get_append, machine_set_append);object_class_property_set_description(oc, append,Linux kernel command line);object_class_property_add_str(oc, dtb,machine_get_dtb, machine_set_dtb);object_class_property_set_description(oc, dtb,Linux kernel device tree file);object_class_property_add_str(oc, dumpdtb,machine_get_dumpdtb, machine_set_dumpdtb);object_class_property_set_description(oc, dumpdtb,Dump current dtb to a file and quit);object_class_property_add(oc, boot, BootConfiguration,machine_get_boot, machine_set_boot,NULL, NULL);object_class_property_set_description(oc, boot,Boot configuration);object_class_property_add(oc, smp, SMPConfiguration,machine_get_smp, machine_set_smp,NULL, NULL);object_class_property_set_description(oc, smp,CPU topology);object_class_property_add(oc, phandle-start, int,machine_get_phandle_start, machine_set_phandle_start,NULL, NULL);object_class_property_set_description(oc, phandle-start,The first phandle ID we may generate dynamically);object_class_property_add_str(oc, dt-compatible,machine_get_dt_compatible, machine_set_dt_compatible);object_class_property_set_description(oc, dt-compatible,Overrides the \compatible\ property of the dt root node);object_class_property_add_bool(oc, dump-guest-core,machine_get_dump_guest_core, machine_set_dump_guest_core);object_class_property_set_description(oc, dump-guest-core,Include guest memory in a core dump);object_class_property_add_bool(oc, mem-merge,machine_get_mem_merge, machine_set_mem_merge);object_class_property_set_description(oc, mem-merge,Enable/disable memory merge support);object_class_property_add_bool(oc, usb,machine_get_usb, machine_set_usb);object_class_property_set_description(oc, usb,Set on/off to enable/disable usb);object_class_property_add_bool(oc, graphics,machine_get_graphics, machine_set_graphics);object_class_property_set_description(oc, graphics,Set on/off to enable/disable graphics emulation);object_class_property_add_str(oc, firmware,machine_get_firmware, machine_set_firmware);object_class_property_set_description(oc, firmware,Firmware image);object_class_property_add_bool(oc, suppress-vmdesc,machine_get_suppress_vmdesc, machine_set_suppress_vmdesc);object_class_property_set_description(oc, suppress-vmdesc,Set on to disable self-describing migration);object_class_property_add_link(oc, confidential-guest-support,TYPE_CONFIDENTIAL_GUEST_SUPPORT,offsetof(MachineState, cgs),machine_check_confidential_guest_support,OBJ_PROP_LINK_STRONG);object_class_property_set_description(oc, confidential-guest-support,Set confidential guest scheme to support);/* For compatibility */object_class_property_add_str(oc, memory-encryption,machine_get_memory_encryption, machine_set_memory_encryption);object_class_property_set_description(oc, memory-encryption,Set memory encryption object to use);object_class_property_add_link(oc, memory-backend, TYPE_MEMORY_BACKEND,offsetof(MachineState, memdev), object_property_allow_set_link,OBJ_PROP_LINK_STRONG);object_class_property_set_description(oc, memory-backend,Set RAM backendValid value is ID of hostmem based backend);object_class_property_add(oc, memory, MemorySizeConfiguration,machine_get_mem, machine_set_mem,NULL, NULL);object_class_property_set_description(oc, memory,Memory size configuration);
}
此函数中很多地方调用了object_class_property_add_str函数以其中之一为例
object_class_property_add_str(oc, kernel,machine_get_kernel, machine_set_kernel);
代码中的machine_set_kernel和machine_get_kernel函数就是传入object_class_property_add_str函数的与形参对应的实参也即对于machine类的属性进行设置和获取时实际调用的函数。
至此QEMU中的QOM相关的内容就简要介绍完了。欲知后事如何且看下回分解。