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 */ 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 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 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 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 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 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 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. */ 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 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