[PATCH 0 of 3] Add function to persist a guest on migration.

Also include a function that undefines a guest from the source system once the migration is complete.

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1205453394 25200 # Node ID 2fa4dbe7b38189aeb1ddb4b770c531a75df788d3 # Parent 311b85abee28e75975e4758b6bc0a5974d3de937 Define guest before migrating. This step ensures that the guest will persist even when the guest is shutdown / destroyed. Since prepare_offline_migration() already has most of the code for this, the re_offline_migration() function can be removed and a common define_gest function can be used instead. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 311b85abee28 -r 2fa4dbe7b381 src/Virt_VSMigrationService.c --- a/src/Virt_VSMigrationService.c Thu Mar 13 08:06:29 2008 -0700 +++ b/src/Virt_VSMigrationService.c Thu Mar 13 17:09:54 2008 -0700 @@ -578,6 +578,51 @@ static void migrate_job_set_state(struct CU_DEBUG("Failed to raise indication"); } +static CMPIStatus define_guest_on_target(virConnectPtr dconn, + virDomainPtr dom, + struct migration_job *job, + bool is_offline_migrate) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + virDomainPtr ddom = NULL; + char *xml = NULL; + + if (!is_offline_migrate) { + ddom = virDomainLookupByName(dconn, job->domain); + if (ddom == NULL) { + CU_DEBUG("Failed to lookup `%s'", job->domain); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to lookup domain `%s'", job->domain); + goto out; + } + + xml = virDomainGetXMLDesc(ddom, 0); + } + else + xml = virDomainGetXMLDesc(dom, 0); + + if (xml == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to retrieve domain XML."); + goto out; + } + + ddom = virDomainDefineXML(dconn, xml); + if (ddom == NULL) { + CU_DEBUG("Failed to define domain from XML"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to create domain"); + } + + out: + free(xml); + virDomainFree(ddom); + return s; +} + static CMPIStatus handle_migrate(virConnectPtr dconn, virDomainPtr dom, char *uri, @@ -601,8 +646,10 @@ static CMPIStatus handle_migrate(virConn return s; } -static CMPIStatus prepare_offline_migrate(virDomainPtr dom, - char **xml) +static CMPIStatus handle_offline_migrate(virConnectPtr dconn, + virDomainPtr dom, + char *uri, + struct migration_job *job) { CMPIStatus s = {CMPI_RC_OK, NULL}; virDomainInfo info; @@ -623,41 +670,13 @@ static CMPIStatus prepare_offline_migrat goto out; } - *xml = virDomainGetXMLDesc(dom, 0); - if (*xml == NULL) { - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "Unable to retrieve domain XML."); - goto out; - } - - out: - return s; -} - -static CMPIStatus handle_offline_migrate(virConnectPtr dconn, - virDomainPtr dom, - char *uri, - char *xml, - struct migration_job *job) -{ - CMPIStatus s = {CMPI_RC_OK, NULL}; - virDomainPtr new_dom; - - if (domain_exists(dconn, job->domain)) { - CU_DEBUG("This domain already exists on the target system."); - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "This domain already exists on the target system"); - goto out; - } - - new_dom = virDomainDefineXML(dconn, xml); - if (new_dom == NULL) { - CU_DEBUG("Failed to define domain from XML"); - cu_statusf(_BROKER, &s, - CMPI_RC_ERR_FAILED, - "Failed to create domain"); + s = define_guest_on_target(dconn, dom, job, true); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Define failed"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to define guest on target system"); + goto out; } out: @@ -670,7 +689,6 @@ static CMPIStatus migrate_vs(struct migr virConnectPtr conn = NULL; virDomainPtr dom = NULL; char *uri = NULL; - char *xml = NULL; conn = connect_by_classname(_BROKER, job->ref_cn, &s); if (conn == NULL) @@ -685,16 +703,10 @@ static CMPIStatus migrate_vs(struct migr goto out; } - if (job->type == CIM_MIGRATE_OTHER) { - s = prepare_offline_migrate(dom, &xml); - if (s.rc != CMPI_RC_OK) - goto out; - } - switch(job->type) { case CIM_MIGRATE_OTHER: CU_DEBUG("Preparing for offline migration"); - s = handle_offline_migrate(job->conn, dom, uri, xml, job); + s = handle_offline_migrate(job->conn, dom, uri, job); break; case CIM_MIGRATE_LIVE: CU_DEBUG("Preparing for live migration"); @@ -717,6 +729,15 @@ static CMPIStatus migrate_vs(struct migr goto out; CU_DEBUG("Migration succeeded"); + + s = define_guest_on_target(job->conn, NULL, job, false); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Define failed"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to define guest on target system"); + } + cu_statusf(_BROKER, &s, CMPI_RC_OK, ""); @@ -725,7 +746,6 @@ static CMPIStatus migrate_vs(struct migr raise_deleted_ind(job); free(uri); - free(xml); virDomainFree(dom); virConnectClose(conn);

KR> +static CMPIStatus define_guest_on_target(virConnectPtr dconn, KR> + virDomainPtr dom, KR> + struct migration_job *job, KR> + bool is_offline_migrate) KR> +{ KR> + CMPIStatus s = {CMPI_RC_OK, NULL}; KR> + virDomainPtr ddom = NULL; KR> + char *xml = NULL; KR> + KR> + if (!is_offline_migrate) { KR> + ddom = virDomainLookupByName(dconn, job->domain); KR> + if (ddom == NULL) { KR> + CU_DEBUG("Failed to lookup `%s'", job->domain); KR> + cu_statusf(_BROKER, &s, KR> + CMPI_RC_ERR_FAILED, KR> + "Failed to lookup domain `%s'", job->domain); KR> + goto out; KR> + } KR> + KR> + xml = virDomainGetXMLDesc(ddom, 0); KR> + } KR> + else That 'else' is broken. KR> + xml = virDomainGetXMLDesc(dom, 0); KR> + KR> + if (xml == NULL) { KR> + cu_statusf(_BROKER, &s, KR> + CMPI_RC_ERR_FAILED, KR> + "Unable to retrieve domain XML."); KR> + goto out; KR> + } KR> + KR> + ddom = virDomainDefineXML(dconn, xml); KR> + if (ddom == NULL) { KR> + CU_DEBUG("Failed to define domain from XML"); KR> + cu_statusf(_BROKER, &s, KR> + CMPI_RC_ERR_FAILED, KR> + "Failed to create domain"); KR> + } KR> + KR> + out: KR> + free(xml); KR> + virDomainFree(ddom); KR> + return s; KR> +} KR> + I really don't like the way this function re-defines an existing guest on the remote or copies one from local to remote depending on the flag. To me it looks like it should be able to just fail if it can't virDomainGetXMLDesc(dom). If you pass in a remote dom then it will do the redefine. If you pass in a local dom, it will effectively copy. KR> switch(job->type) { KR> case CIM_MIGRATE_OTHER: KR> CU_DEBUG("Preparing for offline migration"); KR> - s = handle_offline_migrate(job->conn, dom, uri, xml, job); KR> + s = handle_offline_migrate(job->conn, dom, uri, job); KR> break; KR> case CIM_MIGRATE_LIVE: KR> CU_DEBUG("Preparing for live migration"); KR> @@ -717,6 +729,15 @@ static CMPIStatus migrate_vs(struct migr KR> goto out; KR> CU_DEBUG("Migration succeeded"); KR> + KR> + s = define_guest_on_target(job->conn, NULL, job, false); KR> + if (s.rc != CMPI_RC_OK) { KR> + CU_DEBUG("Define failed"); KR> + cu_statusf(_BROKER, &s, KR> + CMPI_RC_ERR_FAILED, KR> + "Unable to define guest on target system"); KR> + } KR> + KR> cu_statusf(_BROKER, &s, KR> CMPI_RC_OK, KR> ""); It seems to me that a migration of any sort has now become like an offline migration, but with a little extra goo in the middle. So, I wonder if we can't change the switch above to something like this: xml = virDomainGetXMLDesc(local_dom); switch (type) { case CIM_MIGRATE_OTHER: /* Offline */ break; case CIM_MIGRATE_LIVE: s = handle_migration(dconn, dom) break; default: /* ERROR */ } if (s.rc == CMPI_RC_OK) define_guest_on_target(dconn, xml); Thus, offline migration is mostly just a fall-through, but the other migration types have actual work in the middle. Thoughts? Since Kaitlin is out, I'll pick this up and re-swizzle. -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1205453395 25200 # Node ID 9905f7a33ed9ef02ff6ecfc0d1b5b335dcd16580 # Parent 2fa4dbe7b38189aeb1ddb4b770c531a75df788d3 Clean up uri param in VSMigrationService. Now that the connection pointer is a part of the job struct, we don't have a uri parameter to pass around. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 2fa4dbe7b381 -r 9905f7a33ed9 src/Virt_VSMigrationService.c --- a/src/Virt_VSMigrationService.c Thu Mar 13 17:09:54 2008 -0700 +++ b/src/Virt_VSMigrationService.c Thu Mar 13 17:09:55 2008 -0700 @@ -625,12 +625,14 @@ static CMPIStatus define_guest_on_target static CMPIStatus handle_migrate(virConnectPtr dconn, virDomainPtr dom, - char *uri, int type, struct migration_job *job) { CMPIStatus s = {CMPI_RC_OK, NULL}; virDomainPtr ddom = NULL; + char *uri; + + uri = virConnectGetURI(dconn); CU_DEBUG("Migrating %s -> %s", job->domain, uri); ddom = virDomainMigrate(dom, dconn, type, NULL, NULL, 0); @@ -642,13 +644,13 @@ static CMPIStatus handle_migrate(virConn } virDomainFree(ddom); + free(uri); return s; } static CMPIStatus handle_offline_migrate(virConnectPtr dconn, virDomainPtr dom, - char *uri, struct migration_job *job) { CMPIStatus s = {CMPI_RC_OK, NULL}; @@ -688,7 +690,6 @@ static CMPIStatus migrate_vs(struct migr CMPIStatus s; virConnectPtr conn = NULL; virDomainPtr dom = NULL; - char *uri = NULL; conn = connect_by_classname(_BROKER, job->ref_cn, &s); if (conn == NULL) @@ -706,16 +707,16 @@ static CMPIStatus migrate_vs(struct migr switch(job->type) { case CIM_MIGRATE_OTHER: CU_DEBUG("Preparing for offline migration"); - s = handle_offline_migrate(job->conn, dom, uri, job); + s = handle_offline_migrate(job->conn, dom, job); break; case CIM_MIGRATE_LIVE: CU_DEBUG("Preparing for live migration"); - s = handle_migrate(job->conn, dom, uri, VIR_MIGRATE_LIVE, job); + s = handle_migrate(job->conn, dom, VIR_MIGRATE_LIVE, job); break; case CIM_MIGRATE_RESUME: case CIM_MIGRATE_RESTART: CU_DEBUG("Preparing for static migration"); - s = handle_migrate(job->conn, dom, uri, 0, job); + s = handle_migrate(job->conn, dom, 0, job); break; default: CU_DEBUG("Unsupported migration type (%d)", job->type); @@ -745,7 +746,6 @@ static CMPIStatus migrate_vs(struct migr out: raise_deleted_ind(job); - free(uri); virDomainFree(dom); virConnectClose(conn);

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1205453397 25200 # Node ID 8a689c81d44016468f58f10df8026f729c1cb2aa # Parent 9905f7a33ed9ef02ff6ecfc0d1b5b335dcd16580 Remove the system from the source guest. If the guest is still defined on the source after the migrate, remove the guest. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 9905f7a33ed9 -r 8a689c81d440 src/Virt_VSMigrationService.c --- a/src/Virt_VSMigrationService.c Thu Mar 13 17:09:55 2008 -0700 +++ b/src/Virt_VSMigrationService.c Thu Mar 13 17:09:57 2008 -0700 @@ -685,6 +685,24 @@ static CMPIStatus handle_offline_migrate return s; } +static CMPIStatus remove_guest(char *dom_name, + virDomainPtr dom, + virConnectPtr conn) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (!domain_exists(conn, dom_name)) + goto out; + + if (virDomainUndefine(dom)) + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to remove guest from target system."); + + out: + return s; +} + static CMPIStatus migrate_vs(struct migration_job *job) { CMPIStatus s; @@ -729,6 +747,10 @@ static CMPIStatus migrate_vs(struct migr if (s.rc != CMPI_RC_OK) goto out; + s = remove_guest(job->domain, dom, conn); + if (s.rc != CMPI_RC_OK) + CU_DEBUG("Undefine of guest on source system failed"); + CU_DEBUG("Migration succeeded"); s = define_guest_on_target(job->conn, NULL, job, false);
participants (2)
-
Dan Smith
-
Kaitlin Rupert