Nova 侧

1
2
3
4
5
6
7
8
9
10
# 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
1
2
3
4
5
6
7
8
9
10
11
12
13
# 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)
1
2
3
4
5
6
7
8
9
10
# 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 构建后的目录结构为例。

1
2
3
4
5
6
7
8
9
# build/libvirt.py
def openAuth(uri, auth, flags=0):
ret = libvirtmod.virConnectOpenAuth(uri, auth, flags)

// libvirt-override.c
static PyObject *
libvirt_virConnectOpenAuth {
virConnectOpenAuth
}
1
2
3
4
5
6
# build/libvirt.py
class virConnect(object):
def defineXML(self, xml):
ret = libvirtmod.virDomainDefineXML(self._o, xml)
__tmp = virDomain(self,_obj=ret)
return __tmp
1
2
3
4
5
6
7
# 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)
1
2
3
4
5
6
7
8
9
10
11
12
// 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 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 侧

https://github.com/qemu/qemu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 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));
}