Commit 2e1795b5 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

job: Add job_transition_to_ready()



The transition to the READY state was still performed in the BlockJob
layer, in the same function that sent the BLOCK_JOB_READY QMP event.

This patch brings the state transition to the Job layer and implements
the QMP event using a notifier called from the Job layer, like we
already do for other events related to state transitions.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
parent df956ae2
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -727,8 +727,8 @@ static void coroutine_fn mirror_run(void *opaque)
    }

    if (s->bdev_length == 0) {
        /* Report BLOCK_JOB_READY and wait for complete. */
        block_job_event_ready(&s->common);
        /* Transition to the READY state and wait for complete. */
        job_transition_to_ready(&s->common.job);
        s->synced = true;
        while (!job_is_cancelled(&s->common.job) && !s->should_complete) {
            job_yield(&s->common.job);
@@ -824,7 +824,7 @@ static void coroutine_fn mirror_run(void *opaque)
                 * report completion.  This way, block-job-cancel will leave
                 * the target in a consistent state.
                 */
                block_job_event_ready(&s->common);
                job_transition_to_ready(&s->common.job);
                s->synced = true;
            }

+18 −15
Original line number Diff line number Diff line
@@ -338,6 +338,22 @@ static void block_job_event_pending(Notifier *n, void *opaque)
                                      &error_abort);
}

static void block_job_event_ready(Notifier *n, void *opaque)
{
    BlockJob *job = opaque;

    if (block_job_is_internal(job)) {
        return;
    }

    qapi_event_send_block_job_ready(job_type(&job->job),
                                    job->job.id,
                                    job->len,
                                    job->offset,
                                    job->speed, &error_abort);
}


/*
 * API for block job drivers and the block layer.  These functions are
 * declared in blockjob_int.h.
@@ -386,12 +402,14 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
    job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
    job->finalize_completed_notifier.notify = block_job_event_completed;
    job->pending_notifier.notify = block_job_event_pending;
    job->ready_notifier.notify = block_job_event_ready;

    notifier_list_add(&job->job.on_finalize_cancelled,
                      &job->finalize_cancelled_notifier);
    notifier_list_add(&job->job.on_finalize_completed,
                      &job->finalize_completed_notifier);
    notifier_list_add(&job->job.on_pending, &job->pending_notifier);
    notifier_list_add(&job->job.on_ready, &job->ready_notifier);

    error_setg(&job->blocker, "block device is in use by block job: %s",
               job_type_str(&job->job));
@@ -433,21 +451,6 @@ void block_job_user_resume(Job *job)
    block_job_iostatus_reset(bjob);
}

void block_job_event_ready(BlockJob *job)
{
    job_state_transition(&job->job, JOB_STATUS_READY);

    if (block_job_is_internal(job)) {
        return;
    }

    qapi_event_send_block_job_ready(job_type(&job->job),
                                    job->job.id,
                                    job->len,
                                    job->offset,
                                    job->speed, &error_abort);
}

BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
                                        int is_read, int error)
{
+3 −0
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ typedef struct BlockJob {
    /** Called when the job transitions to PENDING */
    Notifier pending_notifier;

    /** Called when the job transitions to READY */
    Notifier ready_notifier;

    /** BlockDriverStates that are involved in this block job */
    GSList *nodes;
} BlockJob;
+0 −8
Original line number Diff line number Diff line
@@ -115,14 +115,6 @@ void block_job_drain(Job *job);
 */
int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n);

/**
 * block_job_event_ready:
 * @job: The job which is now ready to be completed.
 *
 * Send a BLOCK_JOB_READY event for the specified job.
 */
void block_job_event_ready(BlockJob *job);

/**
 * block_job_error_action:
 * @job: The job to signal an error for.
+6 −3
Original line number Diff line number Diff line
@@ -132,6 +132,9 @@ typedef struct Job {
    /** Notifiers called when the job transitions to PENDING */
    NotifierList on_pending;

    /** Notifiers called when the job transitions to READY */
    NotifierList on_ready;

    /** Element of the list of jobs */
    QLIST_ENTRY(Job) job_list;

@@ -426,6 +429,9 @@ int job_apply_verb(Job *job, JobVerb verb, Error **errp);
/** The @job could not be started, free it. */
void job_early_fail(Job *job);

/** Moves the @job from RUNNING to READY */
void job_transition_to_ready(Job *job);

/**
 * @job: The job being completed.
 * @ret: The status code.
@@ -522,7 +528,4 @@ void job_defer_to_main_loop(Job *job, JobDeferToMainLoopFn *fn, void *opaque);
 */
int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp);

/* TODO To be removed from the public interface */
void job_state_transition(Job *job, JobStatus s1);

#endif
Loading