[libvirt] [PATCH 2/3 v5] qemu: allow the client to choose the vmcore's format

Wen Congyang ghostwcy at gmail.com
Fri Jun 15 12:38:33 UTC 2012


On 06/13/2012 08:57 PM, Martin Kletzander wrote:
> On 06/12/2012 05:06 AM, Wen Congyang wrote:
>> This patch updates qemu driver to allow the client to choose the
>> vmcore's format: memory only or including device state.
>> ---
>>   include/libvirt/libvirt.h.in |    1 +
>>   src/qemu/qemu_capabilities.c |    5 +++
>>   src/qemu/qemu_capabilities.h |    1 +
>>   src/qemu/qemu_domain.c       |    1 +
>>   src/qemu/qemu_domain.h       |    1 +
>>   src/qemu/qemu_driver.c       |   60 ++++++++++++++++++++++++++++++++---------
>>   6 files changed, 56 insertions(+), 13 deletions(-)
>>
>> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
>> index fcb6695..120ed14 100644
>> --- a/include/libvirt/libvirt.h.in
>> +++ b/include/libvirt/libvirt.h.in
>> @@ -927,6 +927,7 @@ typedef enum {
>>       VIR_DUMP_LIVE         = (1<<  1), /* live dump */
>>       VIR_DUMP_BYPASS_CACHE = (1<<  2), /* avoid file system cache pollution */
>>       VIR_DUMP_RESET        = (1<<  3), /* reset domain after dump finishes */
>> +    VIR_DUMP_MEMORY_ONLY  = (1<<  4), /* use dump-guest-memory */
>>   } virDomainCoreDumpFlags;
>>
>>   /* Domain migration flags. */
>> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
>> index b410648..6eee8cd 100644
>> --- a/src/qemu/qemu_capabilities.c
>> +++ b/src/qemu/qemu_capabilities.c
>> @@ -164,6 +164,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
>>                 "no-user-config",
>>
>>                 "hda-micro", /* 95 */
>> +              "dump-guest-memory",
>>
>>       );
>>
>> @@ -1237,6 +1238,10 @@ qemuCapsComputeCmdFlags(const char *help,
>>
>>       if (version>= 11000)
>>           qemuCapsSet(flags, QEMU_CAPS_CPU_HOST);
>> +
>> +    if (version>= 1001050)
>> +        qemuCapsSet(flags, QEMU_CAPS_DUMP_GUEST_MEMORY);
>> +
>>       return 0;
>>   }
>>
>
> Sorry for bothering you with this, but I tried newest qemu and it shows
> the proper list of commands with query-commands in qmp. Instead of this
> one hunk, I'd use this:
>
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 6ca01c5..7d2da21 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -991,6 +991,8 @@ qemuMonitorJSONCheckCommands(qemuMonitorPtr mon,
>               qemuCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_SYNC);
>           else if (STREQ(name, "block-job-cancel"))
>               qemuCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC);
> +        else if (STREQ(name, "dump-guest-memory"))
> +            qemuCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY);
>       }
>
>       ret = 0;
>
>> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
>> index 64831e2..640f7f5 100644
>> --- a/src/qemu/qemu_capabilities.h
>> +++ b/src/qemu/qemu_capabilities.h
>> @@ -131,6 +131,7 @@ enum qemuCapsFlags {
>>       QEMU_CAPS_IDE_CD             = 93, /* -device ide-cd */
>>       QEMU_CAPS_NO_USER_CONFIG     = 94, /* -no-user-config */
>>       QEMU_CAPS_HDA_MICRO          = 95, /* -device hda-micro */
>> +    QEMU_CAPS_DUMP_GUEST_MEMORY  = 96, /* dump-guest-memory command */
>>
>>       QEMU_CAPS_LAST,                   /* this must always be the last item */
>>   };
>> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
>> index 3752ddf..91c0645 100644
>> --- a/src/qemu/qemu_domain.c
>> +++ b/src/qemu/qemu_domain.c
>> @@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
>>       job->phase = 0;
>>       job->mask = DEFAULT_JOB_MASK;
>>       job->start = 0;
>> +    job->dump_memory_only = false;
>>       memset(&job->info, 0, sizeof(job->info));
>>   }
>>
>> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
>> index 1256c4e..3a5f1f3 100644
>> --- a/src/qemu/qemu_domain.h
>> +++ b/src/qemu/qemu_domain.h
>> @@ -104,6 +104,7 @@ struct qemuDomainJobObj {
>>       int phase;                          /* Job phase (mainly for migrations) */
>>       unsigned long long mask;            /* Jobs allowed during async job */
>>       unsigned long long start;           /* When the async job started */
>> +    bool dump_memory_only;              /* use dump-guest-memory to do dump */
>>       virDomainJobInfo info;              /* Async job progress data */
>>   };
>>
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index d3f74d2..b2da838 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -2986,12 +2986,39 @@ cleanup:
>>       return ret;
>>   }
>>
>> +static int qemuDumpToFd(struct qemud_driver *driver, virDomainObjPtr vm,
>> +                        int fd, enum qemuDomainAsyncJob asyncJob)
>> +{
>> +    qemuDomainObjPrivatePtr priv = vm->privateData;
>> +    int ret = -1;
>> +
>> +    if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) {
>> +        qemuReportError(VIR_ERR_NO_SUPPORT, "%s",
>> +                        _("dump-guest-memory is not supported"));
>> +        return -1;
>> +    }
>> +
>> +    if (virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def,
>> +                                          fd)<  0)
>> +        return -1;
>> +
>> +    priv->job.dump_memory_only = true;
>> +
>> +    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob)<  0)
>> +        return -1;
>> +
>> +    ret = qemuMonitorDumpToFd(priv->mon, 0, fd, 0, 0);
>> +    qemuDomainObjExitMonitorWithDriver(driver, vm);
>> +
>> +    return ret;
>> +}
>> +
>>   static int
>>   doCoreDump(struct qemud_driver *driver,
>>              virDomainObjPtr vm,
>>              const char *path,
>>              enum qemud_save_formats compress,
>> -           bool bypass_cache)
>> +           unsigned int dump_flags)
>>   {
>>       int fd = -1;
>>       int ret = -1;
>> @@ -3000,7 +3027,7 @@ doCoreDump(struct qemud_driver *driver,
>>       unsigned int flags = VIR_FILE_WRAPPER_NON_BLOCKING;
>>
>>       /* Create an empty file with appropriate ownership.  */
>> -    if (bypass_cache) {
>> +    if (dump_flags&  VIR_DUMP_BYPASS_CACHE) {
>>           flags |= VIR_FILE_WRAPPER_BYPASS_CACHE;
>>           directFlag = virFileDirectFdFlag();
>>           if (directFlag<  0) {
>> @@ -3020,14 +3047,20 @@ doCoreDump(struct qemud_driver *driver,
>>       if (!(wrapperFd = virFileWrapperFdNew(&fd, path, flags)))
>>           goto cleanup;
>>
>> -    if (qemuMigrationToFile(driver, vm, fd, 0, path,
>> -                            qemuCompressProgramName(compress), false,
>> -                            QEMU_ASYNC_JOB_DUMP)<  0)
>> +    if (dump_flags&  VIR_DUMP_MEMORY_ONLY) {
>> +        ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP);
>> +    } else {
>> +        ret = qemuMigrationToFile(driver, vm, fd, 0, path,
>> +                                  qemuCompressProgramName(compress), false,
>> +                                  QEMU_ASYNC_JOB_DUMP);
>> +    }
>> +
>> +    if (ret<  0)
>>           goto cleanup;
>>
>>       if (VIR_CLOSE(fd)<  0) {
>>           virReportSystemError(errno,
>> -                             _("unable to save file %s"),
>> +                             _("unable to close file %s"),
>>                                path);
>>           goto cleanup;
>>       }
>> @@ -3085,7 +3118,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
>>       virDomainEventPtr event = NULL;
>>
>>       virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
>> -                  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET, -1);
>> +                  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET |
>> +                  VIR_DUMP_MEMORY_ONLY, -1);
>>
>>       qemuDriverLock(driver);
>>       vm = virDomainFindByUUID(&driver->domains, dom->uuid);
>> @@ -3127,8 +3161,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
>>           }
>>       }
>>
>> -    ret = doCoreDump(driver, vm, path, getCompressionType(driver),
>> -                     (flags&  VIR_DUMP_BYPASS_CACHE) != 0);
>> +    ret = doCoreDump(driver, vm, path, getCompressionType(driver), flags);
>>       if (ret<  0)
>>           goto endjob;
>>
>> @@ -3289,6 +3322,7 @@ static void processWatchdogEvent(void *data, void *opaque)
>>       case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
>>           {
>>               char *dumpfile;
>> +            unsigned int flags = 0;
>>
>>               if (virAsprintf(&dumpfile, "%s/%s-%u",
>>                               driver->autoDumpPath,
>> @@ -3311,9 +3345,9 @@ static void processWatchdogEvent(void *data, void *opaque)
>>                   goto endjob;
>>               }
>>
>> +            flags |= driver->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
>>               ret = doCoreDump(driver, wdEvent->vm, dumpfile,
>> -                             getCompressionType(driver),
>> -                             driver->autoDumpBypassCache);
>> +                             getCompressionType(driver), flags);
>>               if (ret<  0)
>>                   qemuReportError(VIR_ERR_OPERATION_FAILED,
>>                                   "%s", _("Dump failed"));
>> @@ -9402,7 +9436,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom,
>>       priv = vm->privateData;
>>
>>       if (virDomainObjIsActive(vm)) {
>> -        if (priv->job.asyncJob) {
>> +        if (priv->job.asyncJob&&  !priv->job.dump_memory_only) {
>>               memcpy(info,&priv->job.info, sizeof(*info));
>>
>>               /* Refresh elapsed time again just to ensure it
>> @@ -9460,7 +9494,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) {
>>
>>       priv = vm->privateData;
>>
>> -    if (!priv->job.asyncJob) {
>> +    if (!priv->job.asyncJob || priv->job.dump_memory_only) {
>>           qemuReportError(VIR_ERR_OPERATION_INVALID,
>>                           "%s", _("no job is active on the domain"));
>>           goto endjob;
>>
>
> , so ACK with that one hunk changed.

Thanks, pushed with this hunck changed

Wen Congyang

>
> Martin
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>




More information about the libvir-list mailing list