[libvirt] [PATCH v3 1/2] qemu: Resolve data loss and data corruption of domain restoring.

Osier Yang jyang at redhat.com
Thu Apr 7 02:01:35 UTC 2011


于 2011年04月07日 03:30, Eric Blake 写道:
> On 04/06/2011 12:17 AM, Osier Yang wrote:
>> Both "qemuDomainStartWithFlags" and "qemuAutostartDomain" try to
>> restore the domain from managedsave'ed image if it exists (by
>> invoking "qemuDomainObjRestore"), but it unlinks the image even
>> if restoring fails, which causes data loss. (This problem exists
>> for "virsh managedsave dom; virsh start dom").
>>
>> And keeping the saved state will cause data corruption if the
>> user modified his disks and restore the domain second time from
>> the saved state. (Problem exists for "virsh save dom; virsh
>> restore dom").
>
> Based on subsequent conversation on v2, we need v4.
>
>>
>> The fix is to:
>>     * Don't unlink()s the managed saved state if the restoring
>>       fails.
>
> Good
>
>>     * Remove the saved state if restoring succeeded.
>
> Bad
>
>> +++ b/src/qemu/qemu_driver.c
>> @@ -3171,6 +3171,9 @@ qemuDomainRestore(virConnectPtr conn,
>>           vm = NULL;
>>       }
>>
>> +    if ((ret == 0)&&  (unlink(path)<  0))
>> +        VIR_WARN("Failed to remove the saved state %s", path);
>
> Drop this hunk.
>

Hum

>> +
>>   cleanup:
>>       virDomainDefFree(def);
>>       VIR_FORCE_CLOSE(fd);
>> @@ -3423,18 +3426,22 @@ static int qemudDomainObjStart(virConnectPtr conn,
>>
>>       /*
>>        * If there is a managed saved state restore it instead of starting
>> -     * from scratch. In any case the old state is removed.
>> +     * from scratch.
>>        */
>>       managed_save = qemuDomainManagedSavePath(driver, vm);
>>       if ((managed_save)&&  (virFileExists(managed_save))) {
>
> If managed_save is NULL, then we should be skipping to cleanup
> (qemuDomainManagedSavePath already reported OOM), rather than silently
> falling back to normal startup.

No, qemuDomainObjStart is also used by qemuDomainStartWithFlags,
skipping to cleanup when managed_save is NULL will break the
starting of all domains which don't have managed state file.

That's risky.

>
>>           ret = qemuDomainObjRestore(conn, driver, vm, managed_save);
>>
>> -        if (unlink(managed_save)<  0) {
>> -            VIR_WARN("Failed to remove the managed state %s", managed_save);
>> +        if (ret == 0) {
>> +            if (unlink(managed_save)<  0)
>> +                VIR_WARN("Failed to remove the managed state %s", managed_save);
>> +        } else {
>> +            qemuReportError(VIR_ERR_INTERNAL_ERROR,
>> +                            _("Failed to restore from the managed state %s"),
>> +                            managed_save);
>
> This overwrites the error message from qemuDomainObjRestore, possibly
> losing useful information.  I think you can just drop this else clause.

This makes sense. Thanks

>
>>           }
>>
>> -        if (ret == 0)
>> -            goto cleanup;
>> +        goto cleanup;
>>       }
>>
>>       ret = qemuProcessStart(conn, driver, vm, NULL, start_paused, -1, NULL,
>> --
>> 1.7.4
>>
>>
>




More information about the libvir-list mailing list