From: Cole Robinson Date: Mon, 2 Nov 2009 18:37:38 +0000 (-0500) Subject: qemu: Break out function to check if we can create/define/restore X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e02f691a9089f2a6ffb53797f968cd3a6d6d3514;p=libvirt.git qemu: Break out function to check if we can create/define/restore Use this function in the qemu, uml, lxc, and test drivers. --- diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 90bd0e2bfb..918a5d738f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5218,6 +5218,70 @@ virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def) return NULL; } +/* + * virDomainObjIsDuplicate: + * @doms : virDomainObjListPtr to search + * @def : virDomainDefPtr definition of domain to lookup + * @check_active: If true, ensure that domain is not active + * + * Returns: -1 on error + * 0 if domain is new + * 1 if domain is a duplicate + */ +int +virDomainObjIsDuplicate(virDomainObjListPtr doms, + virDomainDefPtr def, + unsigned int check_active) +{ + int ret = -1; + int dupVM = 0; + virDomainObjPtr vm = NULL; + + /* See if a VM with matching UUID already exists */ + vm = virDomainFindByUUID(doms, def->uuid); + if (vm) { + /* UUID matches, but if names don't match, refuse it */ + if (STRNEQ(vm->def->name, def->name)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + virDomainReportError(NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + vm->def->name, uuidstr); + goto cleanup; + } + + if (check_active) { + /* UUID & name match, but if VM is already active, refuse it */ + if (virDomainObjIsActive(vm)) { + virDomainReportError(NULL, VIR_ERR_OPERATION_INVALID, + _("domain is already active as '%s'"), + vm->def->name); + goto cleanup; + } + } + + dupVM = 1; + virDomainObjUnlock(vm); + } else { + /* UUID does not match, but if a name matches, refuse it */ + vm = virDomainFindByName(doms, def->name); + if (vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + virDomainReportError(NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' already exists with uuid %s"), + def->name, uuidstr); + goto cleanup; + } + } + + ret = dupVM; +cleanup: + if (vm) + virDomainObjUnlock(vm); + return ret; +} + void virDomainObjLock(virDomainObjPtr obj) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e826cc765d..fadf43f023 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -807,6 +807,10 @@ virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def); int virDomainVideoDefaultType(virDomainDefPtr def); int virDomainVideoDefaultRAM(virDomainDefPtr def, int type); +int virDomainObjIsDuplicate(virDomainObjListPtr doms, + virDomainDefPtr def, + unsigned int check_active); + void virDomainObjLock(virDomainObjPtr obj); void virDomainObjUnlock(virDomainObjPtr obj); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 215addbc08..5b9968438c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -146,6 +146,7 @@ virDomainObjLock; virDomainObjUnlock; virDomainStateTypeToString; virDomainStateTypeFromString; +virDomainObjIsDuplicate; virDomainObjListGetInactiveNames; virDomainObjListGetActiveIDs; virDomainObjListNumOfDomains; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index a917a46e53..0fd7a17bd8 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -273,41 +273,15 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; virDomainEventPtr event = NULL; - int newVM = 1; + int dupVM; lxcDriverLock(driver); if (!(def = virDomainDefParseString(conn, driver->caps, xml, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; - /* See if a VM with matching UUID already exists */ - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(vm->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED, - _("Domain '%s' is already defined with uuid %s"), - vm->def->name, uuidstr); - goto cleanup; - } - - /* UUID & name match */ - virDomainObjUnlock(vm); - newVM = 0; - } else { - /* UUID does not match, but if a name matches, refuse it */ - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED, - _("Domain '%s' is already defined with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - } + if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0) + goto cleanup; if ((def->nets != NULL) && !(driver->have_netns)) { lxcError(conn, NULL, VIR_ERR_NO_SUPPORT, @@ -331,7 +305,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_DEFINED, - newVM ? + !dupVM ? VIR_DOMAIN_EVENT_DEFINED_ADDED : VIR_DOMAIN_EVENT_DEFINED_UPDATED); @@ -1279,38 +1253,8 @@ lxcDomainCreateAndStart(virConnectPtr conn, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; - /* See if a VM with matching UUID already exists */ - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(vm->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED, - _("Domain '%s' is already defined with uuid %s"), - vm->def->name, uuidstr); - goto cleanup; - } - - /* UUID & name match, but if VM is already active, refuse it */ - if (virDomainObjIsActive(vm)) { - lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED, - _("Domain is already active as '%s'"), vm->def->name); - goto cleanup; - } - virDomainObjUnlock(vm); - } else { - /* UUID does not match, but if a name matches, refuse it */ - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED, - _("Domain '%s' is already defined with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - } + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) + goto cleanup; if ((def->nets != NULL) && !(driver->have_netns)) { lxcError(conn, NULL, VIR_ERR_NO_SUPPORT, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9f67ddf09b..dd766bf44d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2657,38 +2657,8 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (virSecurityDriverVerify(conn, def) < 0) goto cleanup; - /* See if a VM with matching UUID already exists */ - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(vm->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - vm->def->name, uuidstr); - goto cleanup; - } - - /* UUID & name match, but if VM is already active, refuse it */ - if (virDomainObjIsActive(vm)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain is already active as '%s'"), vm->def->name); - goto cleanup; - } - virDomainObjUnlock(vm); - } else { - /* UUID does not match, but if a name matches, refuse it */ - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - } + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) + goto cleanup; if (!(vm = virDomainAssignDef(conn, driver->caps, @@ -3718,38 +3688,8 @@ static int qemudDomainRestore(virConnectPtr conn, goto cleanup; } - /* See if a VM with matching UUID already exists */ - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(vm->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - vm->def->name, uuidstr); - goto cleanup; - } - - /* UUID & name match, but if VM is already active, refuse it */ - if (virDomainObjIsActive(vm)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_INVALID, - _("domain is already active as '%s'"), vm->def->name); - goto cleanup; - } - virDomainObjUnlock(vm); - } else { - /* UUID does not match, but if a name matches, refuse it */ - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - } + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) + goto cleanup; if (!(vm = virDomainAssignDef(conn, driver->caps, @@ -4196,7 +4136,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; virDomainEventPtr event = NULL; - int newVM = 1; + int dupVM; qemuDriverLock(driver); if (!(def = virDomainDefParseString(conn, driver->caps, xml, @@ -4206,34 +4146,8 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { if (virSecurityDriverVerify(conn, def) < 0) goto cleanup; - /* See if a VM with matching UUID already exists */ - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(vm->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - vm->def->name, uuidstr); - goto cleanup; - } - - /* UUID & name match */ - virDomainObjUnlock(vm); - newVM = 0; - } else { - /* UUID does not match, but if a name matches, refuse it */ - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - } + if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0) + goto cleanup; if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; @@ -4258,7 +4172,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_DEFINED, - newVM ? + !dupVM ? VIR_DOMAIN_EVENT_DEFINED_ADDED : VIR_DOMAIN_EVENT_DEFINED_UPDATED); diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 343834c924..fb367c9f42 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1242,6 +1242,9 @@ testDomainCreateXML(virConnectPtr conn, const char *xml, VIR_DOMAIN_XML_INACTIVE)) == NULL) goto cleanup; + if (virDomainObjIsDuplicate(&privconn->domains, def, 1) < 0) + goto cleanup; + if (testDomainGenerateIfnames(conn, def) < 0) goto cleanup; if (!(dom = virDomainAssignDef(conn, privconn->caps, @@ -1785,6 +1788,9 @@ static int testDomainRestore(virConnectPtr conn, if (!def) goto cleanup; + if (virDomainObjIsDuplicate(&privconn->domains, def, 1) < 0) + goto cleanup; + if (testDomainGenerateIfnames(conn, def) < 0) goto cleanup; if (!(dom = virDomainAssignDef(conn, privconn->caps, @@ -2224,12 +2230,16 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn, virDomainDefPtr def; virDomainObjPtr dom = NULL; virDomainEventPtr event = NULL; + int dupVM; testDriverLock(privconn); if ((def = virDomainDefParseString(conn, privconn->caps, xml, VIR_DOMAIN_XML_INACTIVE)) == NULL) goto cleanup; + if ((dupVM = virDomainObjIsDuplicate(&privconn->domains, def, 0)) < 0) + goto cleanup; + if (testDomainGenerateIfnames(conn, def) < 0) goto cleanup; if (!(dom = virDomainAssignDef(conn, privconn->caps, @@ -2240,7 +2250,9 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn, event = virDomainEventNewFromObj(dom, VIR_DOMAIN_EVENT_DEFINED, - VIR_DOMAIN_EVENT_DEFINED_ADDED); + !dupVM ? + VIR_DOMAIN_EVENT_DEFINED_ADDED : + VIR_DOMAIN_EVENT_DEFINED_UPDATED); ret = virGetDomain(conn, dom->def->name, dom->def->uuid); if (ret) diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index e2525c496d..6214ef8514 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1178,23 +1178,8 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - umlReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined"), - def->name); + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; - } - vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(def->uuid, uuidstr); - umlReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain with uuid '%s' is already defined"), - uuidstr); - goto cleanup; - } if (!(vm = virDomainAssignDef(conn, driver->caps, @@ -1531,6 +1516,9 @@ static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) { VIR_DOMAIN_XML_INACTIVE))) goto cleanup; + if (virDomainObjIsDuplicate(&driver->domains, def, 0) < 0) + goto cleanup; + if (!(vm = virDomainAssignDef(conn, driver->caps, &driver->domains, diff --git a/tests/read-bufsiz b/tests/read-bufsiz index 5baa7c5903..f4f8f19c82 100755 --- a/tests/read-bufsiz +++ b/tests/read-bufsiz @@ -32,6 +32,9 @@ fail=0 # Output a valid definition, to be used as input. $abs_top_builddir/tools/virsh -c test:///default dumpxml 1 > xml || fail=1 +# Change the VM name +sed -i -e "s|test|newtest|g" xml + for i in before after; do # The largest BUFSIZ I've seen is 128K. This is slightly larger. printf %132000s ' ' > sp || fail=1 @@ -40,7 +43,7 @@ for i in before after; do ( test $i = before && cat sp xml || cat xml sp ) > $in || fail=1 $abs_top_builddir/tools/virsh --connect test:///default define $in > out || fail=1 - printf "Domain test defined from $in\n\n" > exp || fail=1 + printf "Domain newtest defined from $in\n\n" > exp || fail=1 compare exp out || fail=1 done