最近学习QEMU中VCPU热插特性,需要了解QEMU中VCPU热插的整个流程,VCPU热插是QEMU主板的一个feature。

1:这里先分析一下QEMU的主板模拟,主板在QEMU的设备模型中对应的是一个MachineClass的结构体,其内容如下:

struct MachineClass {
/*< private >*/
ObjectClass parent_class;
/*< public >*/ const char *family; /* NULL iff @name identifies a standalone machtype */
const char *name;
const char *alias;
const char *desc; void (*init)(MachineState *state);            /* 主板的初始化入口函数 */
void (*reset)(void);
void (*hot_add_cpu)(const int64_t id, Error **errp);  /* VCPU 热插的调用入口 */
int (*kvm_type)(const char *arg); BlockInterfaceType block_default_type;
int units_per_default_bus;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
use_virtcon:1,
use_sclp:1,
no_floppy:1,
no_cdrom:1,
no_sdcard:1,
has_dynamic_sysbus:1,
pci_allow_0_address:1,
legacy_fw_cfg_order:1;
int is_default;
const char *default_machine_opts;
const char *default_boot_order;
const char *default_display;
GlobalProperty *compat_props;
const char *hw_version;
ram_addr_t default_ram_size;
bool option_rom_has_mr;
bool rom_file_has_mr; HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
DeviceState *dev);
unsigned (*cpu_index_to_socket_id)(unsigned cpu_index);
CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
};

  在qemu源码vl.c中,做完参数解析之后调用select_machine()获取默认的主板。

static MachineClass *select_machine(void)
{
MachineClass *machine_class = find_default_machine(); /* 寻找默认的主板(qemu有一个支持的主板列表) */
const char *optarg;
QemuOpts *opts;
Location loc; loc_push_none(&loc); opts = qemu_get_machine_opts();
qemu_opts_loc_restore(opts); optarg = qemu_opt_get(opts, "type");
if (optarg) {
machine_class = machine_parse(optarg); /* 解析命令行传入的machine类型,如果命令行传入的machine解析错误,使用默认的主板类型 */
} if (!machine_class) {
error_report("No machine specified, and there is no default");
error_printf("Use -machine help to list supported machines\n");
exit(1);
} loc_pop(&loc);
return machine_class;
}

  不管是find_default_machine还是machine_parse中,都有一个函数叫做 object_class_get_list(),这个函数的作用查找实现了某个Class的object列表,下面对其进行分析。

MachineClass *find_default_machine(void)
{
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); /* 查找 machine 对象的列表 */
MachineClass *mc = NULL; for (el = machines; el; el = el->next) { /* 遍历列表,找到is_default=true的object对象 */                          
MachineClass *temp = el->data; if (temp->is_default) {
mc = temp;
break;
}
} g_slist_free(machines);
return mc;
}

  重点分析object_class_get_list,其入参是指向字符串"machine"的指针 和 false (不查找抽象类的实例)。

GSList *object_class_get_list(const char *implements_type,
bool include_abstract)
{
GSList *list = NULL; object_class_foreach(object_class_get_list_tramp,
implements_type, include_abstract, &list); /* 调用了object_class_foreach方法, 第一个入参是一个函数指针object_class_get_list_tramp,最后一个参数是一个GList指针(默认为NULL)*/
    return list; 
}

  函数object_class_get_list_tramp的作用是将ObjectClass对象指针klass添加到list当中,并将list的头指针放到opaque里面。用来实现将找到的ObjectClass对象指针串起来。

static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
{
GSList **list = opaque; *list = g_slist_prepend(*list, klass); /* add a new element to the start of the list */
}

  下面是object_class_foreach的实现。

typedef struct OCFData
{
void (*fn)(ObjectClass *klass, void *opaque);
const char *implements_type;
bool include_abstract;
void *opaque;
} OCFData; static void object_class_foreach_tramp(gpointer key, gpointer value,
gpointer opaque)
{
OCFData *data = opaque;
TypeImpl *type = value;
ObjectClass *k; type_initialize(type);
k = type->class; if (!data->include_abstract && type->abstract) { /* 抽象类不是查对象 */
return;
} if (data->implements_type && /* 不能动态cast的类对象也不考虑 */
!object_class_dynamic_cast(k, data->implements_type)) {
return;
} data->fn(k, data->opaque); /* 调用object_class_get_list_tramp */
} void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
const char *implements_type, bool include_abstract,
void *opaque)
{
OCFData data = { fn, implements_type, include_abstract, opaque }; enumerating_types = true;
g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
enumerating_types = false;
}
												

QEMU VCPU热插特性的更多相关文章

  1. 启用 webpack 的模块热替换特性

    启用 webpack 的模块热替换特性: module.exports = { //... devServer: { hot: true } } 注意,必须有 webpack.HotModuleRep ...

  2. libvirt/qemu特性之numa

    博客地址:http://blog.csdn.net/halcyonbaby 内容系本人学习.研究和总结,如有雷同,实属荣幸! Numa 查看主机node情况 使用virsh命令查看 virsh # c ...

  3. 深度使用react-native的热更新能力,必须知道的一个shell命令

    开篇之前,先讲一个自己开发中的一个小插曲: 今天周日,iOS版 App 周一提交,周三审核通过上架,很给力.不过,中午11:30的时候,运营就反应某个页面有一个很明显的问题,页面没法拉到底部,部分信息 ...

  4. Unreal Enginer4特性介绍

    转自:http://blog.csdn.net/cartzhang/article/details/39401991 一.特性说明 特性 Ue4是一款专业开发高质量游戏的平台开发工具.Ue4的渲染加快 ...

  5. 手游热更新方案xLua开源:Unity3D下Lua编程解决方案

    C#下Lua编程支持 xLua为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用. xLua的突破 xLua在功能.性能.易用 ...

  6. unreal4特性介绍

    原文地址:   https://www.unrealengine.com/products/unreal-engine-4     unreal enginer介绍 我的UE4学习(一) 你曾想过用连 ...

  7. Unreal Enginer4特性介绍-牛B闪闪的UE4

    声明:转载说明出处! unreal4特性介 原文地址:   https://www.unrealengine.com/products/unreal-engine-4     unreal engin ...

  8. 项目实战13—企业级虚拟化Virtualization-KVM技术

    项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html KVM的介绍.准备工作和qemu-kvm 命令详解 1.介绍 (1)介绍 KVM:就 ...

  9. kvm详细介绍

    KVM详解,太详细太深入了,经典 2016-07-18 19:56:38 分类: 虚拟化 原文地址:KVM详解,太详细太深入了,经典 作者:zzjlzx KVM 介绍(1):简介及安装 http:// ...

随机推荐

  1. 使用parted给大于2T的磁盘分区

    1.使用命令parted /dev/sdb [root@server ~]# parted /dev/sdb GNU Parted 2.1 使用 /dev/sdb Welcome to GNU Par ...

  2. Windows 10下使用U盘安装Ubuntu双系统

    问题描述:在Windows10下安装Ubuntu. 使用工具:Windows10.Ubuntu16.04 LTS安装包.UltraISO.easyBCD. 操作步骤: 1.安装之前要给Ubuntu分出 ...

  3. 在IT择善培训机构的培训心得

    人的一生中都是不断学习来提高 自己,俗话说:“知识是人类不断进步的阶梯”也是“飞向天空的翅膀”.       本人因工作的加入了择善进行学习,能成为择善的学员,不知不觉来到择善1个多月,回想起这1个多 ...

  4. JS--轻松设置获取表单数据

    接触过Angularjs的都知道,ng支持双向绑定,我们可以轻轻松松的通过ngModel将我们的值绑定到界面,当修改了值提交表单的时候不需要再重新通过ID去重新抓取输入框信息了.那对于我们开发前台网站 ...

  5. php 7.0 新特性

    php 7 主题是性能优化  SEO 之前版本:开发效率快,语言本身性能差 普通的php网站:IO密集型,瓶颈在mysql上,体现不出来php的性能劣势,在密集计算方面比C,C++,JAVA差几十倍甚 ...

  6. canvas贝塞尔曲线 - 1

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAvEAAAIcCAIAAADwgGbqAAAgAElEQVR4nOy9a4wb55nn20kOZhq7o8

  7. 【Mysql】 局域网远程连接问题

    设置了 user 表 的 host为‘%’ 为什么局域网还是连接不上: 新建查询-->分别执行 1.GRANT ALL PRIVILEGES ON *.* TO'root'@'%' IDENTI ...

  8. 用vue.js学习es6(五):set和map的使用

    一:Set用法: ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. (1).打印:console.log var data = new Set([1,2,3]); ...

  9. Android基础总结(三)

    测试 黑盒测试 测试逻辑业务 白盒测试 测试逻辑方法 根据测试粒度 方法测试:function test 单元测试:unit test 集成测试:integration test 系统测试:syste ...

  10. java语言 打印素数实例

    //根据定义判断素数---循环n-1次,当n很大时循环n次 public static void main(String[] args) {        // TODO Auto-generated ...