[libvirt] [PATCH 1/2] qemu: Break out function to check if we can create/define/restore
Daniel Veillard
veillard at redhat.com
Fri Nov 6 13:21:25 UTC 2009
On Wed, Nov 04, 2009 at 03:06:58PM -0500, Cole Robinson wrote:
> Use this function in the qemu, uml, lxc, and test drivers.
>
> Signed-off-by: Cole Robinson <crobinso at redhat.com>
> ---
> src/conf/domain_conf.c | 64 +++++++++++++++++++++++++++++
> src/conf/domain_conf.h | 4 ++
> src/libvirt_private.syms | 1 +
> src/lxc/lxc_driver.c | 68 +++----------------------------
> src/qemu/qemu_driver.c | 102 ++++------------------------------------------
> src/test/test_driver.c | 14 ++++++-
> src/uml/uml_driver.c | 20 ++-------
> 7 files changed, 100 insertions(+), 173 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 7dd3ce7..37209d4 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -5014,6 +5014,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 8599ee7..9d3e9e2 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -788,6 +788,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 15d75fd..451a883 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 9ab94bf..4c237f2 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);
>
> @@ -1273,38 +1247,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 5ff7e94..20621d1 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -2638,38 +2638,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,
> @@ -3699,38 +3669,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,
> @@ -4177,7 +4117,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,
> @@ -4187,34 +4127,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;
> @@ -4239,7 +4153,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 343834c..fb367c9 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 212cd8f..0604742 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,
ACK, very nice cleanup, plus that improves the test driver :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list