[libvirt] [PATCH v2 03/15] vbox: Cleanup partially-defined VM on failure
John Ferlan
jferlan at redhat.com
Fri Nov 3 13:41:44 UTC 2017
On 10/24/2017 03:35 PM, Dawid Zamirski wrote:
> 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.
> ---
> src/vbox/vbox_common.c | 41 +++++++++++++++++++++++++++--------------
> 1 file changed, 27 insertions(+), 14 deletions(-)
>
> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index 92ee37164..812c940e6 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c
> @@ -1853,6 +1853,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);
>
> @@ -1862,12 +1864,12 @@ 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;
> + return ret;
> }
Existing, but the { } here aren't necessary since there's only one
statement after the if. It escapes the syntax-check check because
there's two lines in the function call...
>
> + VBOX_IID_INITIALIZE(&mchiid);
> virUUIDFormat(def->uuid, uuidstr);
>
> rc = gVBoxAPI.UIVirtualBox.CreateMachine(data, def, &machine, uuidstr);
And as I assume you know - having this go to cleanup is going to cause a
problem since it's designed to clean up on failure assuming that this
succeeded, right?
I would have been OK with a posted diff to squash in...
In any case, at this point only @def and @mchiid would need to be
cleaned up. If you move the mchiid generation to after this line, then
the failure scenario here could be virDomainDefFree(def) and return ret;
(or NULL).
Whichever way works - the rest of the code looks OK, but I can wait for
the next version.
Since Patches 1 & 2 are OK and for the most part Patches 4-9 are fine
and would seem to be "movable" to just before current patch 10. That
patch also adjusts vboxDomainDefineXMLFlags, so for me it became a logic
point to at least be able to push some of the patches before you post a
a v3. For the nits found in patch 4-9 - I can make the simple
adjustments noted before pushing. That way the next series is smaller.
John
> @@ -1959,30 +1961,41 @@ 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:
> + /* 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);
> -
> - ret = virGetDomain(conn, def->name, def->uuid, -1);
> - VBOX_RELEASE(machine);
>
> - virDomainDefFree(def);
> + if (machineReady) {
> + ret = virGetDomain(conn, def->name, def->uuid, -1);
> + } else {
> + /* Unregister incompletely configured VM to not leave garbage behind */
> + rc = gVBoxAPI.unregisterMachine(data, &mchiid, &machine);
>
> - return ret;
> + if (NS_SUCCEEDED(rc))
> + gVBoxAPI.deleteConfig(machine);
> + else
> + VIR_WARN("Could not cleanup partially created VM after failure, "
> + "rc=%08x", rc);
> + }
>
> - cleanup:
> + vboxIIDUnalloc(&mchiid);
> VBOX_RELEASE(machine);
> virDomainDefFree(def);
> - return NULL;
> +
> + return ret;
> }
>
> static virDomainPtr
>
More information about the libvir-list
mailing list