cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

job-qmp.c (4997B)


      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/* Get a job using its ID and acquire its AioContext */
     33static Job *find_job(const char *id, AioContext **aio_context, Error **errp)
     34{
     35    Job *job;
     36
     37    *aio_context = NULL;
     38
     39    job = job_get(id);
     40    if (!job) {
     41        error_setg(errp, "Job not found");
     42        return NULL;
     43    }
     44
     45    *aio_context = job->aio_context;
     46    aio_context_acquire(*aio_context);
     47
     48    return job;
     49}
     50
     51void qmp_job_cancel(const char *id, Error **errp)
     52{
     53    AioContext *aio_context;
     54    Job *job = find_job(id, &aio_context, errp);
     55
     56    if (!job) {
     57        return;
     58    }
     59
     60    trace_qmp_job_cancel(job);
     61    job_user_cancel(job, true, errp);
     62    aio_context_release(aio_context);
     63}
     64
     65void qmp_job_pause(const char *id, Error **errp)
     66{
     67    AioContext *aio_context;
     68    Job *job = find_job(id, &aio_context, errp);
     69
     70    if (!job) {
     71        return;
     72    }
     73
     74    trace_qmp_job_pause(job);
     75    job_user_pause(job, errp);
     76    aio_context_release(aio_context);
     77}
     78
     79void qmp_job_resume(const char *id, Error **errp)
     80{
     81    AioContext *aio_context;
     82    Job *job = find_job(id, &aio_context, errp);
     83
     84    if (!job) {
     85        return;
     86    }
     87
     88    trace_qmp_job_resume(job);
     89    job_user_resume(job, errp);
     90    aio_context_release(aio_context);
     91}
     92
     93void qmp_job_complete(const char *id, Error **errp)
     94{
     95    AioContext *aio_context;
     96    Job *job = find_job(id, &aio_context, errp);
     97
     98    if (!job) {
     99        return;
    100    }
    101
    102    trace_qmp_job_complete(job);
    103    job_complete(job, errp);
    104    aio_context_release(aio_context);
    105}
    106
    107void qmp_job_finalize(const char *id, Error **errp)
    108{
    109    AioContext *aio_context;
    110    Job *job = find_job(id, &aio_context, errp);
    111
    112    if (!job) {
    113        return;
    114    }
    115
    116    trace_qmp_job_finalize(job);
    117    job_ref(job);
    118    job_finalize(job, errp);
    119
    120    /*
    121     * Job's context might have changed via job_finalize (and job_txn_apply
    122     * automatically acquires the new one), so make sure we release the correct
    123     * one.
    124     */
    125    aio_context = job->aio_context;
    126    job_unref(job);
    127    aio_context_release(aio_context);
    128}
    129
    130void qmp_job_dismiss(const char *id, Error **errp)
    131{
    132    AioContext *aio_context;
    133    Job *job = find_job(id, &aio_context, errp);
    134
    135    if (!job) {
    136        return;
    137    }
    138
    139    trace_qmp_job_dismiss(job);
    140    job_dismiss(&job, errp);
    141    aio_context_release(aio_context);
    142}
    143
    144static JobInfo *job_query_single(Job *job, Error **errp)
    145{
    146    JobInfo *info;
    147    uint64_t progress_current;
    148    uint64_t progress_total;
    149
    150    assert(!job_is_internal(job));
    151    progress_get_snapshot(&job->progress, &progress_current,
    152                          &progress_total);
    153
    154    info = g_new(JobInfo, 1);
    155    *info = (JobInfo) {
    156        .id                 = g_strdup(job->id),
    157        .type               = job_type(job),
    158        .status             = job->status,
    159        .current_progress   = progress_current,
    160        .total_progress     = progress_total,
    161        .has_error          = !!job->err,
    162        .error              = job->err ? \
    163                              g_strdup(error_get_pretty(job->err)) : NULL,
    164    };
    165
    166    return info;
    167}
    168
    169JobInfoList *qmp_query_jobs(Error **errp)
    170{
    171    JobInfoList *head = NULL, **tail = &head;
    172    Job *job;
    173
    174    for (job = job_next(NULL); job; job = job_next(job)) {
    175        JobInfo *value;
    176        AioContext *aio_context;
    177
    178        if (job_is_internal(job)) {
    179            continue;
    180        }
    181        aio_context = job->aio_context;
    182        aio_context_acquire(aio_context);
    183        value = job_query_single(job, errp);
    184        aio_context_release(aio_context);
    185        if (!value) {
    186            qapi_free_JobInfoList(head);
    187            return NULL;
    188        }
    189        QAPI_LIST_APPEND(tail, value);
    190    }
    191
    192    return head;
    193}