Nova 到 Qemu 的调用
Nova 侧
# nova/virt/libvirt/driver.py
class LibvirtDriver(driver.ComputeDriver):
def power_on
self._hard_reboot
self._get_guest_xml
self._create_domain_and_network
self._create_domain
guest = libvirt_guest.Guest.create
guest.launch
# nova/virt/libvirt/guest.py
class Guest(object):
def create
guest = host.write_instance_config(xml)
return guest
def launch
self._domain.createWithFlags
def attach_device(self, conf, persistent=False, live=False):
device_xml = conf.to_xml()
self._domain.attachDeviceFlags(device_xml, flags=flags)
# nova/virt/libvirt/host.py
class Host(object):
def write_instance_config(self, xml):
domain = self.get_connection().defineXML(xml)
conn = self._get_connection()
self._get_new_connection()
self._connect
libvirt.openAuth
return libvirt_guest.Guest(domain)
libvirt Python 绑定
https://github.com/libvirt/libvirt-python
代码引用以 libvirt-python 构建后的目录结构为例。
# build/libvirt.py
def openAuth(uri, auth, flags=0):
ret = libvirtmod.virConnectOpenAuth(uri, auth, flags)
// libvirt-override.c
static PyObject *
libvirt_virConnectOpenAuth {
virConnectOpenAuth
}
# build/libvirt.py
class virConnect(object):
def defineXML(self, xml):
ret = libvirtmod.virDomainDefineXML(self._o, xml)
__tmp = virDomain(self,_obj=ret)
return __tmp
# build/libvirt.py
class virDomain(object):
def createWithFlags(self, flags=0):
libvirtmod.virDomainCreateWithFlags(self._o, flags)
def attachDeviceFlags(self, xml, flags=0):
libvirtmod.virDomainAttachDeviceFlags(self._o, xml, flags)
// build/libvirt.c
PyObject *
libvirt_virDomainCreateWithFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{
virDomainCreateWithFlags(domain, flags);
}
PyObject *
libvirt_virDomainAttachDeviceFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{
virDomainAttachDeviceFlags(domain, xml, flags);
}
libvirt 侧
https://github.com/libvirt/libvirt
// src/libvirt-domain.c
int
virDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
{
conn->driver->domainCreateWithFlags(domain, flags);
}
int
virDomainAttachDeviceFlags(virDomainPtr domain,
const char *xml, unsigned int flags)
{
conn->driver->domainAttachDeviceFlags(domain, xml, flags);
}
// src/qemu/qemu_driver.c
static int
qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
{
qemuDomainObjStart
}
static int
qemuDomainAttachDeviceFlags(virDomainPtr dom,
const char *xml,
unsigned int flags)
{
qemuDomainAttachDeviceLiveAndConfig(vm, driver, xml, flags)
}
qemu 侧
// hmp.c
void hmp_device_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
qmp_device_add((QDict *)qdict, NULL, &err);
hmp_handle_error(mon, &err);
}
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
{
Error *local_err = NULL;
QemuOpts *opts;
DeviceState *dev;
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
qemu_opts_del(opts);
return;
}
dev = qdev_device_add(opts, &local_err);
if (!dev) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return;
}
object_unref(OBJECT(dev));
}
最后修改于 2019-07-20