mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
vbox: Cleanup partially-defined VM on failure
Since the VBOX API requires to register an initial VM before proceeding to attach any remaining devices to it, any failure to attach such devices should result in automatic cleanup of the initially registered VM so that the state of VBOX registry remains clean without any leftover "aborted" VMs in it. Failure to cleanup of such partial VMs results in a warning log so that actual define error stays on the top of the error stack.
This commit is contained in:
parent
8fe48f20f8
commit
8442d01a71
@ -1821,6 +1821,8 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virDomainPtr ret = NULL;
|
||||
unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
|
||||
bool machineReady = false;
|
||||
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);
|
||||
|
||||
@ -1830,12 +1832,11 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags
|
||||
if (!data->vboxObj)
|
||||
return ret;
|
||||
|
||||
VBOX_IID_INITIALIZE(&mchiid);
|
||||
if (!(def = virDomainDefParseString(xml, data->caps, data->xmlopt,
|
||||
NULL, parse_flags))) {
|
||||
goto cleanup;
|
||||
}
|
||||
NULL, parse_flags)))
|
||||
return ret;
|
||||
|
||||
VBOX_IID_INITIALIZE(&mchiid);
|
||||
virUUIDFormat(def->uuid, uuidstr);
|
||||
|
||||
rc = gVBoxAPI.UIVirtualBox.CreateMachine(data, def, &machine, uuidstr);
|
||||
@ -1928,30 +1929,49 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags
|
||||
vboxAttachUSB(def, data, machine);
|
||||
vboxAttachSharedFolder(def, data, machine);
|
||||
|
||||
/* Save the machine settings made till now and close the
|
||||
* session. also free up the mchiid variable used.
|
||||
machineReady = true;
|
||||
|
||||
cleanup:
|
||||
/* if machine wasn't even created, cleanup is trivial */
|
||||
if (!machine) {
|
||||
vboxIIDUnalloc(&mchiid);
|
||||
virDomainDefFree(def);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Save the machine settings made till now, even when jumped here on error,
|
||||
* as otherwise unregister won't cleanup properly. For example, it won't
|
||||
* close media that were partially attached. The VBOX SDK docs say that
|
||||
* unregister implicitly calls saveSettings but evidently it's not so...
|
||||
*/
|
||||
rc = gVBoxAPI.UIMachine.SaveSettings(machine);
|
||||
if (NS_FAILED(rc)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed no saving settings, rc=%08x"), (unsigned)rc);
|
||||
goto cleanup;
|
||||
_("Failed to save VM settings, rc=%08x"), rc);
|
||||
machineReady = false;
|
||||
}
|
||||
|
||||
gVBoxAPI.UISession.Close(data->vboxSession);
|
||||
vboxIIDUnalloc(&mchiid);
|
||||
|
||||
if (machineReady) {
|
||||
ret = virGetDomain(conn, def->name, def->uuid, -1);
|
||||
VBOX_RELEASE(machine);
|
||||
} else {
|
||||
/* Unregister incompletely configured VM to not leave garbage behind */
|
||||
rc = gVBoxAPI.unregisterMachine(data, &mchiid, &machine);
|
||||
|
||||
if (NS_SUCCEEDED(rc))
|
||||
gVBoxAPI.deleteConfig(machine);
|
||||
else
|
||||
VIR_WARN("Could not cleanup partially created VM after failure, "
|
||||
"rc=%08x", rc);
|
||||
}
|
||||
|
||||
VBOX_RELEASE(machine);
|
||||
vboxIIDUnalloc(&mchiid);
|
||||
virDomainDefFree(def);
|
||||
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
VBOX_RELEASE(machine);
|
||||
virDomainDefFree(def);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static virDomainPtr
|
||||
|
Loading…
x
Reference in New Issue
Block a user