创建虚拟机
#0 virDomainDefineXML (conn=0x696e80,
xml=0x697b90 "<domain type='kvm'>\n <name>kvm_win7</name>\n <memory>2097152</memory>\n <currentMemory>2097152</currentMemory>\n <vcpu>2</vcpu>\n <os>\n <type arch='x86_64' machine='pc'>hvm</type>\n <boot dev='c"...)
at libvirt.c:7897
#1 0x0000000000427590 in cmdDefine (ctl=0x7fffffffe240,
cmd=<optimized out>) at virsh.c:2696
#2 0x000000000041cd1e in vshCommandRun (ctl=0x7fffffffe240, cmd=0x696890)
at virsh.c:18449
#3 0x000000000042e2d6 in main (argc=3, argv=0x7fffffffe498)
at virsh.c:20052
remoteDomainDefineXML
#0 virDomainDefineXML (conn=0x7f7a88047160,
xml=0x7f7a6c000a30 "<domain type='kvm'>\n <name>kvm_win7</name>\n <memory>2097152</memory>\n <currentMemory>2097152</currentMemory>\n <vcpu>2</vcpu>\n <os>\n <type arch='x86_64' machine='pc'>hvm</type>\n <boot dev='c"...) at libvirt.c:7897
#1 0x00000000004486dd in remoteDispatchDomainDefineXML (server=0x7bf4e0,
client=0x7c59d0, msg=0x7ca880, rerr=0x7f7a914c8bb0,
args=0x7f7a6c001d70, ret=0x7f7a6c001dd0) at remote_dispatch.h:1010
#2 0x00000000004487f1 in remoteDispatchDomainDefineXMLHelper (
server=0x7bf4e0, client=0x7c59d0, msg=0x7ca880, rerr=0x7f7a914c8bb0,
args=0x7f7a6c001d70, ret=0x7f7a6c001dd0) at remote_dispatch.h:990
#3 0x00007f7a97e3076a in virNetServerProgramDispatchCall (prog=0x7ca6d0,
server=0x7bf4e0, client=0x7c59d0, msg=0x7ca880)
at rpc/virnetserverprogram.c:416
#4 0x00007f7a97e30ba7 in virNetServerProgramDispatch (prog=0x7ca6d0,
server=0x7bf4e0, client=0x7c59d0, msg=0x7ca880)
at rpc/virnetserverprogram.c:289
#5 0x00007f7a97e2bc18 in virNetServerHandleJob (jobOpaque=0x783660,
opaque=0x7bf4e0) at rpc/virnetserver.c:168
#6 0x00007f7a97d37550 in virThreadPoolWorker (opaque=0x7807f0)
at util/threadpool.c:144
#7 0x00007f7a97d36a71 in virThreadHelper (data=0x780750)
at util/threads-pthread.c:161
#8 0x00007f7a9542df05 in start_thread () from /lib64/libpthread.so.0
#9 0x00007f7a94d6953d in clone () from /lib64/libc.so.6
qemudDomainDefine
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
int dupVM;
qemuDriverLock(driver);
检查xml配置文件内容是否合法
if (!(def = virDomainDefParseString(driver->caps, xml,
QEMU_EXPECTED_VIRT_TYPES,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
进行安全管理校验
if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
检查xml配置文件定义的虚拟机是否与已经创建的虚拟机冲突
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
goto cleanup;
规范qemu虚拟机类型
(gdb) p def->os.machine
$30 = 0x7f7a6c001b00 "pc-1.0"
if (qemudCanonicalizeMachine(driver, def) < 0)
goto cleanup;
qemuDomainAssignAddresses ->qemuDomainAssignPCIAddresses ->qemuCapsExtractVersionInfo
->virCommandRun ->virCommandRunAsync ->virExecWithHook
为qemu域分配地址
if (qemuDomainAssignAddresses(def) < 0)
goto cleanup;
if (!(vm = virDomainAssignDef(driver->caps,
&driver->domains,
def, false))) {
goto cleanup;
}
def = NULL;
vm->persistent = 1;
对xml配置文件内容进行格式化后,保存到配置文件目录
if (virDomainSaveConfig(driver->configDir,
vm->newDef ? vm->newDef : vm->def) < 0) {
VIR_INFO("Defining domain '%s'", vm->def->name);
qemuDomainRemoveInactive(driver, vm);
vm = NULL;
goto cleanup;
}
生成创建虚拟机事件
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_DEFINED,
!dupVM ?
VIR_DOMAIN_EVENT_DEFINED_ADDED :
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
VIR_INFO("Creating domain '%s'", vm->def->name);
创建对应当前虚拟机的域指针
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
cleanup:
virDomainDefFree(def);
if (vm)
virDomainObjUnlock(vm);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
return dom;
}
2013年5月24日上传