接前一篇文章: QEMU源码全解析 —— 块设备虚拟化(2)
本文内容参考:
《 QEMU /KVM源码解析与应用》 —— 李强,机械工业出版社
特此致谢!
上一回从宏观上讲解了virtio的基本原理,先大致了解一下就好,后面具体用到的时候再从围观、细微处着手进行详解,到时候宏观与微观相结合,就会完全掌握virtio了。本回回到主线中,开始讲解在QEMU初始化阶段的存储虚拟化即设备虚拟化。
QEMU初始化阶段的块设备虚拟化
如果看过笔者“QEMU源码全解析 —— virtio”系列文章的读者,对于QEMU中的使用C语言实现面向对象思想的机制应该不陌生。那么对于磁盘即块设备来说,机制也是相同的。先来看一下QEMU中virtio block device的相关源码,在hw/block/virtio-blk.c中,如下:
static const TypeInfo virtio_blk_info = {
.name = TYPE_VIRTIO_BLK,
.parent = TYPE_VIRTIO_DEVICE,
.instance_size = sizeof(VirtIOBlock),
.instance_init = virtio_blk_instance_init,
.class_init = virtio_blk_class_init,
};
static void virtio_register_types(void)
{
type_register_static(&virtio_blk_info);
}
type_init(virtio_register_types)
virtio block device这个类的定义是有多层继承关系的。TYPE_VIRTIO_BLK的父类是TYPE_VIRTIO_DEVICE。那么,TYPE_VIRTIO_DEVICE的父类又是谁呢?在hw/virtio/virtio.c中:
static const TypeInfo virtio_device_info = {
.name = TYPE_VIRTIO_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(VirtIODevice),
.class_init = virtio_device_class_init,
.instance_finalize = virtio_device_instance_finalize,
.abstract = true,
.class_size = sizeof(VirtioDeviceClass),
};
static void virtio_register_types(void)
{
type_register_static(&virtio_device_info);
}
type_init(virtio_register_types)
可见,TYPE_VIRTIO_DEVICE的父类是TYPE_DEVICE。而TYPE_DEVICE的父类是TYPE_OBJECT,参见hw/core/qdev.c中的代码:
static const TypeInfo device_type_info = {
.name = TYPE_DEVICE,
.parent = TYPE_OBJECT,
.instance_size = sizeof(DeviceState),
.instance_init = device_initfn,
.instance_post_init = device_post_init,
.instance_finalize = device_finalize,
.class_base_init = device_class_base_init,
.class_init = device_class_init,
.abstract = true,
.class_size = sizeof(DeviceClass),
.interfaces = (InterfaceInfo[]) {
{ TYPE_VMSTATE_IF },
{ TYPE_RESETTABLE_INTERFACE },
{ }
}
};
static void qdev_register_types(void)
{
type_register_static(&device_type_info);
}
type_init(qdev_register_types)
到了TYPE_OBJECT就到头了,它是“创始元灵”,没有父类了,所有类都是它的子孙。参见hw/core/object.c中的代码:
static void register_types(void)
{
static const TypeInfo interface_info = {
.name = TYPE_INTERFACE,
.class_size = sizeof(InterfaceClass),
.abstract = true,
};
static const TypeInfo object_info = {
.name = TYPE_OBJECT,
.instance_size = sizeof(Object),
.class_init = object_class_init,
.abstract = true,
};
type_interface = type_register_internal(&interface_info);
type_register_internal(&object_info);
}
type_init(register_types)
回到virtio block device中来,继承关系总览如下:
TYPE_OBJECT
---> TYPE_DEVICE
---> TYPE_VIRTIO_DEVICE
---> TYPE_VIRTIO_BLK
type_init函数用于注册类。每一层都有class_init,用于从TypeImpl生产xxxClass。TYPE_OBJECT的class_init是object_class_init;TYPE_DEVICE的class_init是device_class_init;TYPE_VIRTIO_DEVICE的class_init是virtio_device_class_init;TYPE_VIRTIO_BLK的class_init是virtio_blk_class_init。
每一层还可能有instance_init(也可能没有),用于将xxxClass初始化为实例。TYPE_DEVICE的instance_init为device_initfn;TYPE_VIRTIO_BLK的instance_init为virtio_blk_instance_init。
更多内容请看下回。