X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=job-qmp.c;h=829a28aa70e3e0a880fe2007ba8ca75a9fc4cbeb;hb=ac4cfdc6f39c06732d27554523f9d5f8a53b4ffa;hp=410775df61870060f3af5768ea45f506b6b1566e;hpb=a3ac12fba028df90f7b3dbec924995c126c41022;p=mirror_qemu.git diff --git a/job-qmp.c b/job-qmp.c index 410775df61..829a28aa70 100644 --- a/job-qmp.c +++ b/job-qmp.c @@ -24,11 +24,10 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "qemu/job.h" #include "qapi/qapi-commands-job.h" #include "qapi/error.h" -#include "trace-root.h" +#include "trace/trace-root.h" /* Get a job using its ID and acquire its AioContext */ static Job *find_job(const char *id, AioContext **aio_context, Error **errp) @@ -115,7 +114,16 @@ void qmp_job_finalize(const char *id, Error **errp) } trace_qmp_job_finalize(job); + job_ref(job); job_finalize(job, errp); + + /* + * Job's context might have changed via job_finalize (and job_txn_apply + * automatically acquires the new one), so make sure we release the correct + * one. + */ + aio_context = job->aio_context; + job_unref(job); aio_context_release(aio_context); } @@ -136,18 +144,23 @@ void qmp_job_dismiss(const char *id, Error **errp) static JobInfo *job_query_single(Job *job, Error **errp) { JobInfo *info; + uint64_t progress_current; + uint64_t progress_total; assert(!job_is_internal(job)); + progress_get_snapshot(&job->progress, &progress_current, + &progress_total); info = g_new(JobInfo, 1); *info = (JobInfo) { .id = g_strdup(job->id), .type = job_type(job), .status = job->status, - .current_progress = job->progress_current, - .total_progress = job->progress_total, - .has_error = !!job->error, - .error = g_strdup(job->error), + .current_progress = progress_current, + .total_progress = progress_total, + .has_error = !!job->err, + .error = job->err ? \ + g_strdup(error_get_pretty(job->err)) : NULL, }; return info; @@ -155,28 +168,25 @@ static JobInfo *job_query_single(Job *job, Error **errp) JobInfoList *qmp_query_jobs(Error **errp) { - JobInfoList *head = NULL, **p_next = &head; + JobInfoList *head = NULL, **tail = &head; Job *job; for (job = job_next(NULL); job; job = job_next(job)) { - JobInfoList *elem; + JobInfo *value; AioContext *aio_context; if (job_is_internal(job)) { continue; } - elem = g_new0(JobInfoList, 1); aio_context = job->aio_context; aio_context_acquire(aio_context); - elem->value = job_query_single(job, errp); + value = job_query_single(job, errp); aio_context_release(aio_context); - if (!elem->value) { - g_free(elem); + if (!value) { qapi_free_JobInfoList(head); return NULL; } - *p_next = elem; - p_next = &elem->next; + QAPI_LIST_APPEND(tail, value); } return head;