xref: /qemu/job-qmp.c (revision 3d1f8b07)
11a90bc81SKevin Wolf /*
21a90bc81SKevin Wolf  * QMP interface for background jobs
31a90bc81SKevin Wolf  *
41a90bc81SKevin Wolf  * Copyright (c) 2011 IBM Corp.
51a90bc81SKevin Wolf  * Copyright (c) 2012, 2018 Red Hat, Inc.
61a90bc81SKevin Wolf  *
71a90bc81SKevin Wolf  * Permission is hereby granted, free of charge, to any person obtaining a copy
81a90bc81SKevin Wolf  * of this software and associated documentation files (the "Software"), to deal
91a90bc81SKevin Wolf  * in the Software without restriction, including without limitation the rights
101a90bc81SKevin Wolf  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
111a90bc81SKevin Wolf  * copies of the Software, and to permit persons to whom the Software is
121a90bc81SKevin Wolf  * furnished to do so, subject to the following conditions:
131a90bc81SKevin Wolf  *
141a90bc81SKevin Wolf  * The above copyright notice and this permission notice shall be included in
151a90bc81SKevin Wolf  * all copies or substantial portions of the Software.
161a90bc81SKevin Wolf  *
171a90bc81SKevin Wolf  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
181a90bc81SKevin Wolf  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
191a90bc81SKevin Wolf  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
201a90bc81SKevin Wolf  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211a90bc81SKevin Wolf  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
221a90bc81SKevin Wolf  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
231a90bc81SKevin Wolf  * THE SOFTWARE.
241a90bc81SKevin Wolf  */
251a90bc81SKevin Wolf 
261a90bc81SKevin Wolf #include "qemu/osdep.h"
271a90bc81SKevin Wolf #include "qemu-common.h"
281a90bc81SKevin Wolf #include "qemu/job.h"
291a90bc81SKevin Wolf #include "qapi/qapi-commands-job.h"
301a90bc81SKevin Wolf #include "qapi/error.h"
311a90bc81SKevin Wolf #include "trace-root.h"
321a90bc81SKevin Wolf 
331a90bc81SKevin Wolf /* Get a job using its ID and acquire its AioContext */
341a90bc81SKevin Wolf static Job *find_job(const char *id, AioContext **aio_context, Error **errp)
351a90bc81SKevin Wolf {
361a90bc81SKevin Wolf     Job *job;
371a90bc81SKevin Wolf 
381a90bc81SKevin Wolf     *aio_context = NULL;
391a90bc81SKevin Wolf 
401a90bc81SKevin Wolf     job = job_get(id);
411a90bc81SKevin Wolf     if (!job) {
421a90bc81SKevin Wolf         error_setg(errp, "Job not found");
431a90bc81SKevin Wolf         return NULL;
441a90bc81SKevin Wolf     }
451a90bc81SKevin Wolf 
461a90bc81SKevin Wolf     *aio_context = job->aio_context;
471a90bc81SKevin Wolf     aio_context_acquire(*aio_context);
481a90bc81SKevin Wolf 
491a90bc81SKevin Wolf     return job;
501a90bc81SKevin Wolf }
511a90bc81SKevin Wolf 
521a90bc81SKevin Wolf void qmp_job_cancel(const char *id, Error **errp)
531a90bc81SKevin Wolf {
541a90bc81SKevin Wolf     AioContext *aio_context;
551a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
561a90bc81SKevin Wolf 
571a90bc81SKevin Wolf     if (!job) {
581a90bc81SKevin Wolf         return;
591a90bc81SKevin Wolf     }
601a90bc81SKevin Wolf 
611a90bc81SKevin Wolf     trace_qmp_job_cancel(job);
621a90bc81SKevin Wolf     job_user_cancel(job, true, errp);
631a90bc81SKevin Wolf     aio_context_release(aio_context);
641a90bc81SKevin Wolf }
651a90bc81SKevin Wolf 
661a90bc81SKevin Wolf void qmp_job_pause(const char *id, Error **errp)
671a90bc81SKevin Wolf {
681a90bc81SKevin Wolf     AioContext *aio_context;
691a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
701a90bc81SKevin Wolf 
711a90bc81SKevin Wolf     if (!job) {
721a90bc81SKevin Wolf         return;
731a90bc81SKevin Wolf     }
741a90bc81SKevin Wolf 
751a90bc81SKevin Wolf     trace_qmp_job_pause(job);
761a90bc81SKevin Wolf     job_user_pause(job, errp);
771a90bc81SKevin Wolf     aio_context_release(aio_context);
781a90bc81SKevin Wolf }
791a90bc81SKevin Wolf 
801a90bc81SKevin Wolf void qmp_job_resume(const char *id, Error **errp)
811a90bc81SKevin Wolf {
821a90bc81SKevin Wolf     AioContext *aio_context;
831a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
841a90bc81SKevin Wolf 
851a90bc81SKevin Wolf     if (!job) {
861a90bc81SKevin Wolf         return;
871a90bc81SKevin Wolf     }
881a90bc81SKevin Wolf 
891a90bc81SKevin Wolf     trace_qmp_job_resume(job);
901a90bc81SKevin Wolf     job_user_resume(job, errp);
911a90bc81SKevin Wolf     aio_context_release(aio_context);
921a90bc81SKevin Wolf }
931a90bc81SKevin Wolf 
941a90bc81SKevin Wolf void qmp_job_complete(const char *id, Error **errp)
951a90bc81SKevin Wolf {
961a90bc81SKevin Wolf     AioContext *aio_context;
971a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
981a90bc81SKevin Wolf 
991a90bc81SKevin Wolf     if (!job) {
1001a90bc81SKevin Wolf         return;
1011a90bc81SKevin Wolf     }
1021a90bc81SKevin Wolf 
1031a90bc81SKevin Wolf     trace_qmp_job_complete(job);
1041a90bc81SKevin Wolf     job_complete(job, errp);
1051a90bc81SKevin Wolf     aio_context_release(aio_context);
1061a90bc81SKevin Wolf }
1071a90bc81SKevin Wolf 
1081a90bc81SKevin Wolf void qmp_job_finalize(const char *id, Error **errp)
1091a90bc81SKevin Wolf {
1101a90bc81SKevin Wolf     AioContext *aio_context;
1111a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
1121a90bc81SKevin Wolf 
1131a90bc81SKevin Wolf     if (!job) {
1141a90bc81SKevin Wolf         return;
1151a90bc81SKevin Wolf     }
1161a90bc81SKevin Wolf 
1171a90bc81SKevin Wolf     trace_qmp_job_finalize(job);
1181a90bc81SKevin Wolf     job_finalize(job, errp);
1191a90bc81SKevin Wolf     aio_context_release(aio_context);
1201a90bc81SKevin Wolf }
1211a90bc81SKevin Wolf 
1221a90bc81SKevin Wolf void qmp_job_dismiss(const char *id, Error **errp)
1231a90bc81SKevin Wolf {
1241a90bc81SKevin Wolf     AioContext *aio_context;
1251a90bc81SKevin Wolf     Job *job = find_job(id, &aio_context, errp);
1261a90bc81SKevin Wolf 
1271a90bc81SKevin Wolf     if (!job) {
1281a90bc81SKevin Wolf         return;
1291a90bc81SKevin Wolf     }
1301a90bc81SKevin Wolf 
1311a90bc81SKevin Wolf     trace_qmp_job_dismiss(job);
1321a90bc81SKevin Wolf     job_dismiss(&job, errp);
1331a90bc81SKevin Wolf     aio_context_release(aio_context);
1341a90bc81SKevin Wolf }
135456273b0SKevin Wolf 
136456273b0SKevin Wolf static JobInfo *job_query_single(Job *job, Error **errp)
137456273b0SKevin Wolf {
138456273b0SKevin Wolf     JobInfo *info;
139456273b0SKevin Wolf 
140456273b0SKevin Wolf     assert(!job_is_internal(job));
141456273b0SKevin Wolf 
142456273b0SKevin Wolf     info = g_new(JobInfo, 1);
143456273b0SKevin Wolf     *info = (JobInfo) {
144456273b0SKevin Wolf         .id                 = g_strdup(job->id),
145456273b0SKevin Wolf         .type               = job_type(job),
146456273b0SKevin Wolf         .status             = job->status,
147456273b0SKevin Wolf         .current_progress   = job->progress_current,
148456273b0SKevin Wolf         .total_progress     = job->progress_total,
149*3d1f8b07SJohn Snow         .has_error          = !!job->err,
150*3d1f8b07SJohn Snow         .error              = job->err ? \
151*3d1f8b07SJohn Snow                               g_strdup(error_get_pretty(job->err)) : NULL,
152456273b0SKevin Wolf     };
153456273b0SKevin Wolf 
154456273b0SKevin Wolf     return info;
155456273b0SKevin Wolf }
156456273b0SKevin Wolf 
157456273b0SKevin Wolf JobInfoList *qmp_query_jobs(Error **errp)
158456273b0SKevin Wolf {
159456273b0SKevin Wolf     JobInfoList *head = NULL, **p_next = &head;
160456273b0SKevin Wolf     Job *job;
161456273b0SKevin Wolf 
162456273b0SKevin Wolf     for (job = job_next(NULL); job; job = job_next(job)) {
163456273b0SKevin Wolf         JobInfoList *elem;
164456273b0SKevin Wolf         AioContext *aio_context;
165456273b0SKevin Wolf 
166456273b0SKevin Wolf         if (job_is_internal(job)) {
167456273b0SKevin Wolf             continue;
168456273b0SKevin Wolf         }
169456273b0SKevin Wolf         elem = g_new0(JobInfoList, 1);
170456273b0SKevin Wolf         aio_context = job->aio_context;
171456273b0SKevin Wolf         aio_context_acquire(aio_context);
172456273b0SKevin Wolf         elem->value = job_query_single(job, errp);
173456273b0SKevin Wolf         aio_context_release(aio_context);
174456273b0SKevin Wolf         if (!elem->value) {
175456273b0SKevin Wolf             g_free(elem);
176456273b0SKevin Wolf             qapi_free_JobInfoList(head);
177456273b0SKevin Wolf             return NULL;
178456273b0SKevin Wolf         }
179456273b0SKevin Wolf         *p_next = elem;
180456273b0SKevin Wolf         p_next = &elem->next;
181456273b0SKevin Wolf     }
182456273b0SKevin Wolf 
183456273b0SKevin Wolf     return head;
184456273b0SKevin Wolf }
185