xref: /qemu/job-qmp.c (revision 107111bf)
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/job.h"
281a90bc81SKevin Wolf #include "qapi/qapi-commands-job.h"
291a90bc81SKevin Wolf #include "qapi/error.h"
30243af022SPaolo Bonzini #include "trace/trace-root.h"
311a90bc81SKevin Wolf 
3296241124SEmanuele Giuseppe Esposito /*
336f592e5aSEmanuele Giuseppe Esposito  * Get a job using its ID. Called with job_mutex held.
3496241124SEmanuele Giuseppe Esposito  */
find_job_locked(const char * id,Error ** errp)356f592e5aSEmanuele Giuseppe Esposito static Job *find_job_locked(const char *id, Error **errp)
361a90bc81SKevin Wolf {
371a90bc81SKevin Wolf     Job *job;
381a90bc81SKevin Wolf 
3996241124SEmanuele Giuseppe Esposito     job = job_get_locked(id);
401a90bc81SKevin Wolf     if (!job) {
411a90bc81SKevin Wolf         error_setg(errp, "Job not found");
421a90bc81SKevin Wolf         return NULL;
431a90bc81SKevin Wolf     }
441a90bc81SKevin Wolf 
451a90bc81SKevin Wolf     return job;
461a90bc81SKevin Wolf }
471a90bc81SKevin Wolf 
qmp_job_cancel(const char * id,Error ** errp)481a90bc81SKevin Wolf void qmp_job_cancel(const char *id, Error **errp)
491a90bc81SKevin Wolf {
5096241124SEmanuele Giuseppe Esposito     Job *job;
5196241124SEmanuele Giuseppe Esposito 
5296241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
536f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
541a90bc81SKevin Wolf 
551a90bc81SKevin Wolf     if (!job) {
561a90bc81SKevin Wolf         return;
571a90bc81SKevin Wolf     }
581a90bc81SKevin Wolf 
591a90bc81SKevin Wolf     trace_qmp_job_cancel(job);
6096241124SEmanuele Giuseppe Esposito     job_user_cancel_locked(job, true, errp);
611a90bc81SKevin Wolf }
621a90bc81SKevin Wolf 
qmp_job_pause(const char * id,Error ** errp)631a90bc81SKevin Wolf void qmp_job_pause(const char *id, Error **errp)
641a90bc81SKevin Wolf {
6596241124SEmanuele Giuseppe Esposito     Job *job;
6696241124SEmanuele Giuseppe Esposito 
6796241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
686f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
691a90bc81SKevin Wolf 
701a90bc81SKevin Wolf     if (!job) {
711a90bc81SKevin Wolf         return;
721a90bc81SKevin Wolf     }
731a90bc81SKevin Wolf 
741a90bc81SKevin Wolf     trace_qmp_job_pause(job);
7596241124SEmanuele Giuseppe Esposito     job_user_pause_locked(job, errp);
761a90bc81SKevin Wolf }
771a90bc81SKevin Wolf 
qmp_job_resume(const char * id,Error ** errp)781a90bc81SKevin Wolf void qmp_job_resume(const char *id, Error **errp)
791a90bc81SKevin Wolf {
8096241124SEmanuele Giuseppe Esposito     Job *job;
8196241124SEmanuele Giuseppe Esposito 
8296241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
836f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
841a90bc81SKevin Wolf 
851a90bc81SKevin Wolf     if (!job) {
861a90bc81SKevin Wolf         return;
871a90bc81SKevin Wolf     }
881a90bc81SKevin Wolf 
891a90bc81SKevin Wolf     trace_qmp_job_resume(job);
9096241124SEmanuele Giuseppe Esposito     job_user_resume_locked(job, errp);
911a90bc81SKevin Wolf }
921a90bc81SKevin Wolf 
qmp_job_complete(const char * id,Error ** errp)931a90bc81SKevin Wolf void qmp_job_complete(const char *id, Error **errp)
941a90bc81SKevin Wolf {
9596241124SEmanuele Giuseppe Esposito     Job *job;
9696241124SEmanuele Giuseppe Esposito 
9796241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
986f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
991a90bc81SKevin Wolf 
1001a90bc81SKevin Wolf     if (!job) {
1011a90bc81SKevin Wolf         return;
1021a90bc81SKevin Wolf     }
1031a90bc81SKevin Wolf 
1041a90bc81SKevin Wolf     trace_qmp_job_complete(job);
10596241124SEmanuele Giuseppe Esposito     job_complete_locked(job, errp);
1061a90bc81SKevin Wolf }
1071a90bc81SKevin Wolf 
qmp_job_finalize(const char * id,Error ** errp)1081a90bc81SKevin Wolf void qmp_job_finalize(const char *id, Error **errp)
1091a90bc81SKevin Wolf {
11096241124SEmanuele Giuseppe Esposito     Job *job;
11196241124SEmanuele Giuseppe Esposito 
11296241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
1136f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
1141a90bc81SKevin Wolf 
1151a90bc81SKevin Wolf     if (!job) {
1161a90bc81SKevin Wolf         return;
1171a90bc81SKevin Wolf     }
1181a90bc81SKevin Wolf 
1191a90bc81SKevin Wolf     trace_qmp_job_finalize(job);
12096241124SEmanuele Giuseppe Esposito     job_ref_locked(job);
12196241124SEmanuele Giuseppe Esposito     job_finalize_locked(job, errp);
122b660a84bSStefan Reiter 
12396241124SEmanuele Giuseppe Esposito     job_unref_locked(job);
1241a90bc81SKevin Wolf }
1251a90bc81SKevin Wolf 
qmp_job_dismiss(const char * id,Error ** errp)1261a90bc81SKevin Wolf void qmp_job_dismiss(const char *id, Error **errp)
1271a90bc81SKevin Wolf {
12896241124SEmanuele Giuseppe Esposito     Job *job;
12996241124SEmanuele Giuseppe Esposito 
13096241124SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
1316f592e5aSEmanuele Giuseppe Esposito     job = find_job_locked(id, errp);
1321a90bc81SKevin Wolf 
1331a90bc81SKevin Wolf     if (!job) {
1341a90bc81SKevin Wolf         return;
1351a90bc81SKevin Wolf     }
1361a90bc81SKevin Wolf 
1371a90bc81SKevin Wolf     trace_qmp_job_dismiss(job);
13896241124SEmanuele Giuseppe Esposito     job_dismiss_locked(&job, errp);
1391a90bc81SKevin Wolf }
140456273b0SKevin Wolf 
141880eeec6SEmanuele Giuseppe Esposito /* Called with job_mutex held. */
job_query_single_locked(Job * job,Error ** errp)142880eeec6SEmanuele Giuseppe Esposito static JobInfo *job_query_single_locked(Job *job, Error **errp)
143456273b0SKevin Wolf {
144456273b0SKevin Wolf     JobInfo *info;
145a7b4f8fcSEmanuele Giuseppe Esposito     uint64_t progress_current;
146a7b4f8fcSEmanuele Giuseppe Esposito     uint64_t progress_total;
147456273b0SKevin Wolf 
148456273b0SKevin Wolf     assert(!job_is_internal(job));
149a7b4f8fcSEmanuele Giuseppe Esposito     progress_get_snapshot(&job->progress, &progress_current,
150a7b4f8fcSEmanuele Giuseppe Esposito                           &progress_total);
151456273b0SKevin Wolf 
152456273b0SKevin Wolf     info = g_new(JobInfo, 1);
153456273b0SKevin Wolf     *info = (JobInfo) {
154456273b0SKevin Wolf         .id                 = g_strdup(job->id),
155456273b0SKevin Wolf         .type               = job_type(job),
156456273b0SKevin Wolf         .status             = job->status,
157a7b4f8fcSEmanuele Giuseppe Esposito         .current_progress   = progress_current,
158a7b4f8fcSEmanuele Giuseppe Esposito         .total_progress     = progress_total,
159*107111bfSMarkus Armbruster         .error              = job->err ?
1603d1f8b07SJohn Snow                               g_strdup(error_get_pretty(job->err)) : NULL,
161456273b0SKevin Wolf     };
162456273b0SKevin Wolf 
163456273b0SKevin Wolf     return info;
164456273b0SKevin Wolf }
165456273b0SKevin Wolf 
qmp_query_jobs(Error ** errp)166456273b0SKevin Wolf JobInfoList *qmp_query_jobs(Error **errp)
167456273b0SKevin Wolf {
168c3033fd3SEric Blake     JobInfoList *head = NULL, **tail = &head;
169456273b0SKevin Wolf     Job *job;
170456273b0SKevin Wolf 
171880eeec6SEmanuele Giuseppe Esposito     JOB_LOCK_GUARD();
172880eeec6SEmanuele Giuseppe Esposito 
173880eeec6SEmanuele Giuseppe Esposito     for (job = job_next_locked(NULL); job; job = job_next_locked(job)) {
174c3033fd3SEric Blake         JobInfo *value;
175456273b0SKevin Wolf 
176456273b0SKevin Wolf         if (job_is_internal(job)) {
177456273b0SKevin Wolf             continue;
178456273b0SKevin Wolf         }
179880eeec6SEmanuele Giuseppe Esposito         value = job_query_single_locked(job, errp);
180c3033fd3SEric Blake         if (!value) {
181456273b0SKevin Wolf             qapi_free_JobInfoList(head);
182456273b0SKevin Wolf             return NULL;
183456273b0SKevin Wolf         }
184c3033fd3SEric Blake         QAPI_LIST_APPEND(tail, value);
185456273b0SKevin Wolf     }
186456273b0SKevin Wolf 
187456273b0SKevin Wolf     return head;
188456273b0SKevin Wolf }
189