当前位置: 首页 > news >正文

QEMU源码全解析29 —— QOM介绍(18)

接前一篇文章: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 node's 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 backend""Valid 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相关的内容就简要介绍完了。欲知后事如何,且看下回分解。

相关文章:

QEMU源码全解析29 —— QOM介绍(18)

接前一篇文章:QEMU源码全解析28 —— QOM介绍(17) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 特此致谢! 前文讲解了类…...

从入门到精通——【初识网络】

文章目录 前言1.网络发展背景2.计算机网络分类3.通信协议4.协议分层5. TCP/IP协议6.网络协议支持7. 封装&分用8. 客户端&服务端 前言 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统…...

MySQL alter命令修改表详解

目录 ALTER TABLE 语法 ALTER TABLE 实例 添加一列 添加多列 重命名列 修改列定义 修改列名和定义 添加主键 删除列 重命名表 修改表的存储引擎 结论 在使用表的过程中,如果您需要对表进行修改,您可以使用 ALTER TABLE 语句。通过 ALTER TAB…...

Vulnhub: ColddWorld: Immersion靶机

kali:192.168.111.111 靶机:192.168.111.183 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.183 查看login的源码发现提示:page和文件/var/carls.txt 漏洞利用 wfuzz探测account.php页面发现文件包含&am…...

Redis 总结【6.0版本的】

还差什么?【按照这个为基础,对照他的Redis路线图,冲冲冲】 Redis的常见操作和命令:Redis基本操作命令(图文详解)_redis 命令_进击小高的博客-CSDN博客 Redis的持久化,一致性:AOF&…...

状态模式(C++)

定义 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。 应用场景 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写…...

承泰科技Q3再获30多个智驾项目,新增订单0.86亿!累计近11亿!

中国毫米波雷达市场正处于高速发展期,以承泰科技为代表的本土供应商在前装量产赛道上展示出加速度。 高工智能汽车研究院预测,随着L2及L2持续处于市场增长的高速期,对应毫米波雷达上车量将在2023年实现30-50%的同比增速。 根据高工智能汽车…...

以太网Ethernet通信协议

一、以太网简介 计算机网络可分为局域网(LAN)、 城域网(MAN)、广域网(WAN)、互联网(Initernet)。局域网按传输介质所使用的访问控制方法可分为:以太网(Ethernet)、光纤分布式数据接口(FDDI)、异步传输模式(ATM)、令牌环网(Token Ring)、交换网(Switching) 等&#x…...

内网横向移动—资源约束委派

内网横向移动—资源约束委派 1. 资源约束委派1.1. 基于资源的约束委派的优势1.2. 约束性委派和基于资源的约束性委派配置的差别1.3. 利用条件1.3.1. 什么用户能够修改msDS-AllowedToActOnBehalfOfOtherIdentity属性1.3.2. 将机器加入域的域用户 2. 案例操作2.1. 获取目标信息2.…...

Spring Boot Logback日志格式改为JSON

在阿里云、或者日志分析时使用JSON格式输出日志更加方便。 依赖 增加Logbak JSON解析依赖。 另外需要注意的是JSON格式输出依赖Jackson&#xff0c;根据工程情况按需添加Jackson依赖。 <!--日志--><dependency><groupId>ch.qos.logback.contrib</grou…...

Linux 块设备操作函数

和字符设备的fil_operations一样&#xff0c;块设备也有操作集&#xff0c;为结构体block_device_operations&#xff0c;此结构体定义在include/linux/blkdev.h中&#xff0c;结构体内容如下&#xff1a; struct block_device_operations {int (*open) (struct block_device …...

linux c++网络编程基础:服务端与客户端的实现

在Linux环境下,我们可以使用socket编程来实现网络通信。下面是一个简单的C++版本的客户端和服务端的示例代码。 服务端代码: #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #...

坐标转换-使用geotools读取和转换地理空间表的坐标系(sqlserver、postgresql)

前言&#xff1a; 业务上通过GIS软件将空间数据导入到数据库时&#xff0c;因为不同的数据来源和软件设置&#xff0c;可能导入到数据库的空间表坐标系是各种各样的。 如果要把数据库空间表发布到geoserver并且统一坐标系&#xff0c;只是在geoserver单纯的设置坐标系只是改了…...

JavaScript的主要应用场景有哪些?请描述一下JavaScript的基本数据类型和引用数据类型分别是哪些?

1、JavaScript的主要应用场景有哪些&#xff1f; JavaScript是一种广泛使用的编程语言&#xff0c;它主要用于Web开发、移动应用开发、游戏开发、物联网设备开发等场景。以下是JavaScript的主要应用场景&#xff1a; Web开发&#xff1a;JavaScript是Web开发中最常用的编程语…...

webpack性能优化

文章目录 1. 性能优化-分包2. 动态导入3. 自定义分包4. Prefetch和Preload5. CDN加载配置6. CSS的提取7. terser压缩7.1 Terser在webpack中配置7.2 css压缩 8. Tree Shaking 消除未使用的代码8.1 usedExports 配置8.2 sideEffects配置8.3 CSS实现Tree Shaking 9. Scope Hoistin…...

保存和读取带有透明通道的视频

保存带有透明通道的视频&#xff1a; import osimport imageio from rembg import remove as removBg,new_session from PIL import Image import numpy as np import cv2 from tqdm import tqdmclass cls_rembg():def __init__(self,model_pth):self.session new_session(mo…...

bilibili的评论ip属地显示未知

现象 出于某些原因&#xff0c;我们在日常使用中的大部分平台都开启了IP地址显示&#xff0c;一般会显示当事人所在的地址&#xff0c;这其中就有一些奇怪的地址&#xff0c;&#xff08;在此不谈魔法&#xff09;就比如我最近在刷B站的时候&#xff0c;就在评论区发现了一些显…...

[BabysqliV3.0]phar反序列化

文章目录 [BabysqliV3.0]phar反序列化 [BabysqliV3.0]phar反序列化 开始以为是sql注入 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ST1jvadM-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032140269.png)…...

数据库架构演变过程

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…...

webpack 静态模块打包工具

webpack 为什么? 把静态模块内容&#xff0c;压缩&#xff0c;整合&#xff0c;转译等(前端工程化) 把less/sass转成css代码把ES6 降级成ES5支持多种模块文件类型&#xff0c;多种模块标准语法 vite 为什么不直接学习vite 而学习webpack 因为很多项目还是基于webpack来进…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...