+Thu Feb 22 14:06:24 EST 2007 Daniel P. Berrange <berrange@redhat.com>
+
+ * src/xm_internal.c, src/xend_internal.c: Re-arrange VM creation
+ commands to ensure we destroy stillborn domains if device hotplug
+ fails to complete. Fix deletion of inactive VMs from internal
+ cache of domain configs.
+
Thu Feb 22 11:45:24 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/xs_internal.c: Refuse to do shutdown / reboot on
int ret;
char *sexpr;
char *name = NULL;
- virDomainPtr dom;
+ virDomainPtr dom = NULL;
if (!VIR_IS_CONNECT(conn)) {
virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
ret = xenDaemonDomainCreateLinux(conn, sexpr);
free(sexpr);
if (ret != 0) {
- fprintf(stderr, _("Failed to create domain %s\n"), name);
goto error;
}
- ret = xend_wait_for_devices(conn, name);
- if (ret != 0) {
- fprintf(stderr, _("Failed to get devices for domain %s\n"), name);
+ /* This comes before wait_for_devices, to ensure that latter
+ cleanup will destroy the domain upon failure */
+ if (!(dom = virDomainLookupByName(conn, name)))
goto error;
- }
- dom = virDomainLookupByName(conn, name);
- if (dom == NULL) {
+ if ((ret = xend_wait_for_devices(conn, name)) < 0)
goto error;
- }
- ret = xenDaemonDomainResume(dom);
- if (ret != 0) {
- fprintf(stderr, _("Failed to resume new domain %s\n"), name);
- xenDaemonDomainDestroy(dom);
+ if ((ret = xenDaemonDomainResume(dom)) < 0)
goto error;
- }
free(name);
return (dom);
+
error:
+ /* Make sure we don't leave a still-born domain around */
+ if (dom != NULL) {
+ xenDaemonDomainDestroy(dom);
+ virFreeDomain(dom->conn, dom);
+ }
if (name != NULL)
free(name);
return (NULL);
} xenXMConfCache;
static char configDir[PATH_MAX];
+/* Config file name to config object */
static virHashTablePtr configCache = NULL;
+/* Name to config file name */
static virHashTablePtr nameConfigMap = NULL;
static int nconnections = 0;
static time_t lastRefresh = 0;
ret = xenDaemonDomainCreateLinux(domain->conn, sexpr);
free(sexpr);
if (ret != 0) {
- fprintf(stderr, "Failed to create domain %s\n", domain->name);
- return (-1);
- }
-
- ret = xend_wait_for_devices(domain->conn, domain->name);
- if (ret != 0) {
- fprintf(stderr, "Failed to get devices for domain %s\n", domain->name);
return (-1);
}
}
domain->id = ret;
- ret = xenDaemonDomainResume(domain);
- if (ret != 0) {
- fprintf(stderr, "Failed to resume new domain %s\n", domain->name);
+ if ((ret = xend_wait_for_devices(domain->conn, domain->name)) < 0)
+ goto cleanup;
+
+ if ((ret = xenDaemonDomainResume(domain)) < 0)
+ goto cleanup;
+
+ return (0);
+
+ cleanup:
+ if (domain->id != -1) {
xenDaemonDomainDestroy(domain);
domain->id = -1;
- return (-1);
}
-
- return (0);
+ return (-1);
}
if (unlink(entry->filename) < 0)
return (-1);
- if (virHashRemoveEntry(nameConfigMap, entry->filename, NULL) < 0)
+ /* Remove the name -> filename mapping */
+ if (virHashRemoveEntry(nameConfigMap, domain->name, NULL) < 0)
return(-1);
- if (virHashRemoveEntry(configCache, domain->name, xenXMConfigFree) < 0)
+ /* Remove the config record itself */
+ if (virHashRemoveEntry(configCache, entry->filename, xenXMConfigFree) < 0)
return (-1);
return (0);