qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

job-qmp.c (4401B)


      1 /*
      2  * QMP interface for background jobs
      3  *
      4  * Copyright (c) 2011 IBM Corp.
      5  * Copyright (c) 2012, 2018 Red Hat, Inc.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 
     26 #include "qemu/osdep.h"
     27 #include "qemu/job.h"
     28 #include "qapi/qapi-commands-job.h"
     29 #include "qapi/error.h"
     30 #include "trace/trace-root.h"
     31 
     32 /*
     33  * Get a job using its ID. Called with job_mutex held.
     34  */
     35 static Job *find_job_locked(const char *id, Error **errp)
     36 {
     37     Job *job;
     38 
     39     job = job_get_locked(id);
     40     if (!job) {
     41         error_setg(errp, "Job not found");
     42         return NULL;
     43     }
     44 
     45     return job;
     46 }
     47 
     48 void qmp_job_cancel(const char *id, Error **errp)
     49 {
     50     Job *job;
     51 
     52     JOB_LOCK_GUARD();
     53     job = find_job_locked(id, errp);
     54 
     55     if (!job) {
     56         return;
     57     }
     58 
     59     trace_qmp_job_cancel(job);
     60     job_user_cancel_locked(job, true, errp);
     61 }
     62 
     63 void qmp_job_pause(const char *id, Error **errp)
     64 {
     65     Job *job;
     66 
     67     JOB_LOCK_GUARD();
     68     job = find_job_locked(id, errp);
     69 
     70     if (!job) {
     71         return;
     72     }
     73 
     74     trace_qmp_job_pause(job);
     75     job_user_pause_locked(job, errp);
     76 }
     77 
     78 void qmp_job_resume(const char *id, Error **errp)
     79 {
     80     Job *job;
     81 
     82     JOB_LOCK_GUARD();
     83     job = find_job_locked(id, errp);
     84 
     85     if (!job) {
     86         return;
     87     }
     88 
     89     trace_qmp_job_resume(job);
     90     job_user_resume_locked(job, errp);
     91 }
     92 
     93 void qmp_job_complete(const char *id, Error **errp)
     94 {
     95     Job *job;
     96 
     97     JOB_LOCK_GUARD();
     98     job = find_job_locked(id, errp);
     99 
    100     if (!job) {
    101         return;
    102     }
    103 
    104     trace_qmp_job_complete(job);
    105     job_complete_locked(job, errp);
    106 }
    107 
    108 void qmp_job_finalize(const char *id, Error **errp)
    109 {
    110     Job *job;
    111 
    112     JOB_LOCK_GUARD();
    113     job = find_job_locked(id, errp);
    114 
    115     if (!job) {
    116         return;
    117     }
    118 
    119     trace_qmp_job_finalize(job);
    120     job_ref_locked(job);
    121     job_finalize_locked(job, errp);
    122 
    123     job_unref_locked(job);
    124 }
    125 
    126 void qmp_job_dismiss(const char *id, Error **errp)
    127 {
    128     Job *job;
    129 
    130     JOB_LOCK_GUARD();
    131     job = find_job_locked(id, errp);
    132 
    133     if (!job) {
    134         return;
    135     }
    136 
    137     trace_qmp_job_dismiss(job);
    138     job_dismiss_locked(&job, errp);
    139 }
    140 
    141 /* Called with job_mutex held. */
    142 static JobInfo *job_query_single_locked(Job *job, Error **errp)
    143 {
    144     JobInfo *info;
    145     uint64_t progress_current;
    146     uint64_t progress_total;
    147 
    148     assert(!job_is_internal(job));
    149     progress_get_snapshot(&job->progress, &progress_current,
    150                           &progress_total);
    151 
    152     info = g_new(JobInfo, 1);
    153     *info = (JobInfo) {
    154         .id                 = g_strdup(job->id),
    155         .type               = job_type(job),
    156         .status             = job->status,
    157         .current_progress   = progress_current,
    158         .total_progress     = progress_total,
    159         .has_error          = !!job->err,
    160         .error              = job->err ? \
    161                               g_strdup(error_get_pretty(job->err)) : NULL,
    162     };
    163 
    164     return info;
    165 }
    166 
    167 JobInfoList *qmp_query_jobs(Error **errp)
    168 {
    169     JobInfoList *head = NULL, **tail = &head;
    170     Job *job;
    171 
    172     JOB_LOCK_GUARD();
    173 
    174     for (job = job_next_locked(NULL); job; job = job_next_locked(job)) {
    175         JobInfo *value;
    176 
    177         if (job_is_internal(job)) {
    178             continue;
    179         }
    180         value = job_query_single_locked(job, errp);
    181         if (!value) {
    182             qapi_free_JobInfoList(head);
    183             return NULL;
    184         }
    185         QAPI_LIST_APPEND(tail, value);
    186     }
    187 
    188     return head;
    189 }