/*
 * Declarations for background jobs
 *
 * Copyright (c) 2011 IBM Corp.
 * Copyright (c) 2012, 2018 Red Hat, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef JOB_H
#define JOB_H

#include "qapi/qapi-types-job.h"
#include "qemu/queue.h"
#include "qemu/progress_meter.h"
#include "qemu/coroutine.h"
#include "block/aio.h"

typedef struct JobDriver JobDriver;
typedef struct JobTxn JobTxn;


/**
 * Long-running operation.
 */
typedef struct Job {

    /* Fields set at initialization (job_create), and never modified */

    /** The ID of the job. May be NULL for internal jobs. */
    char *id;

    /**
     * The type of this job.
     * All callbacks are called with job_mutex *not* held.
     */
    const JobDriver *driver;

    /**
     * The coroutine that executes the job.  If not NULL, it is reentered when
     * busy is false and the job is cancelled.
     * Initialized in job_start()
     */
    Coroutine *co;

    /** True if this job should automatically finalize itself */
    bool auto_finalize;

    /** True if this job should automatically dismiss itself */
    bool auto_dismiss;

    /**
     * The completion function that will be called when the job completes.
     * Called with AioContext lock held, since many callback implementations
     * use bdrv_* functions that require to hold the lock.
     */
    BlockCompletionFunc *cb;

    /** The opaque value that is passed to the completion function.  */
    void *opaque;

    /* ProgressMeter API is thread-safe */
    ProgressMeter progress;

    /**
     * AioContext to run the job coroutine in.
     * The job Aiocontext can be read when holding *either*
     * the BQL (so we are in the main loop) or the job_mutex.
     * It can only be written when we hold *both* BQL
     * and the job_mutex.
     */
    AioContext *aio_context;


    /** Protected by job_mutex */

    /** Reference count of the block job */
    int refcnt;

    /** Current state; See @JobStatus for details. */
    JobStatus status;

    /**
     * Timer that is used by @job_sleep_ns. Accessed under job_mutex (in
     * job.c).
     */
    QEMUTimer sleep_timer;

    /**
     * Counter for pause request. If non-zero, the block job is either paused,
     * or if busy == true will pause itself as soon as possible.
     */
    int pause_count;

    /**
     * Set to false by the job while the coroutine has yielded and may be
     * re-entered by job_enter(). There may still be I/O or event loop activity
     * pending. Accessed under job_mutex.
     *
     * When the job is deferred to the main loop, busy is true as long as the
     * bottom half is still pending.
     */
    bool busy;

    /**
     * Set to true by the job while it is in a quiescent state, where
     * no I/O or event loop activity is pending.
     */
    bool paused;

    /**
     * Set to true if the job is paused by user.  Can be unpaused with the
     * block-job-resume QMP command.
     */
    bool user_paused;

    /**
     * Set to true if the job should cancel itself.  The flag must
     * always be tested just before toggling the busy flag from false
     * to true.  After a job has been cancelled, it should only yield
     * if #aio_poll will ("sooner or later") reenter the coroutine.
     */
    bool cancelled;

    /**
     * Set to true if the job should abort immediately without waiting
     * for data to be in sync.
     */
    bool force_cancel;

    /** Set to true when the job has deferred work to the main loop. */
    bool deferred_to_main_loop;

    /**
     * Return code from @run and/or @prepare callback(s).
     * Not final until the job has reached the CONCLUDED status.
     * 0 on success, -errno on failure.
     */
    int ret;

    /**
     * Error object for a failed job.
     * If job->ret is nonzero and an error object was not set, it will be set
     * to strerror(-job->ret) during job_completed.
     */
    Error *err;

    /** Notifiers called when a cancelled job is finalised */
    NotifierList on_finalize_cancelled;

    /** Notifiers called when a successfully completed job is finalised */
    NotifierList on_finalize_completed;

    /** Notifiers called when the job transitions to PENDING */
    NotifierList on_pending;

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

    /** Notifiers called when the job coroutine yields or terminates */
    NotifierList on_idle;

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

    /** Transaction this job is part of */
    JobTxn *txn;

    /** Element of the list of jobs in a job transaction */
    QLIST_ENTRY(Job) txn_list;
} Job;

/**
 * Callbacks and other information about a Job driver.
 * All callbacks are invoked with job_mutex *not* held.
 */
struct JobDriver {

    /*
     * These fields are initialized when this object is created,
     * and are never changed afterwards
     */

    /** Derived Job struct size */
    size_t instance_size;

    /** Enum describing the operation */
    JobType job_type;

    /**
     * Mandatory: Entrypoint for the Coroutine.
     *
     * This callback will be invoked when moving from CREATED to RUNNING.
     *
     * If this callback returns nonzero, the job transaction it is part of is
     * aborted. If it returns zero, the job moves into the WAITING state. If it
     * is the last job to complete in its transaction, all jobs in the
     * transaction move from WAITING to PENDING.
     *
     * This callback must be run in the job's context.
     */
    int coroutine_fn (*run)(Job *job, Error **errp);

    /*
     * Functions run without regard to the BQL that may run in any
     * arbitrary thread. These functions do not need to be thread-safe
     * because the caller ensures that they are invoked from one
     * thread at time.
     */

    /**
     * If the callback is not NULL, it will be invoked when the job transitions
     * into the paused state.  Paused jobs must not perform any asynchronous
     * I/O or event loop activity.  This callback is used to quiesce jobs.
     */
    void coroutine_fn (*pause)(Job *job);

    /**
     * If the callback is not NULL, it will be invoked when the job transitions
     * out of the paused state.  Any asynchronous I/O or event loop activity
     * should be restarted from this callback.
     */
    void coroutine_fn (*resume)(Job *job);

    /*
     * Global state (GS) API. These functions run under the BQL.
     *
     * See include/block/block-global-state.h for more information about
     * the GS API.
     */

    /**
     * Called when the job is resumed by the user (i.e. user_paused becomes
     * false). .user_resume is called before .resume.
     */
    void (*user_resume)(Job *job);

    /**
     * Optional callback for job types whose completion must be triggered
     * manually.
     */
    void (*complete)(Job *job, Error **errp);

    /**
     * If the callback is not NULL, prepare will be invoked when all the jobs
     * belonging to the same transaction complete; or upon this job's completion
     * if it is not in a transaction.
     *
     * This callback will not be invoked if the job has already failed.
     * If it fails, abort and then clean will be called.
     *
     * Called with AioContext lock held, since many callbacs implementations
     * use bdrv_* functions that require to hold the lock.
     */
    int (*prepare)(Job *job);

    /**
     * If the callback is not NULL, it will be invoked when all the jobs
     * belonging to the same transaction complete; or upon this job's
     * completion if it is not in a transaction. Skipped if NULL.
     *
     * All jobs will complete with a call to either .commit() or .abort() but
     * never both.
     *
     * Called with AioContext lock held, since many callback implementations
     * use bdrv_* functions that require to hold the lock.
     */
    void (*commit)(Job *job);

    /**
     * If the callback is not NULL, it will be invoked when any job in the
     * same transaction fails; or upon this job's failure (due to error or
     * cancellation) if it is not in a transaction. Skipped if NULL.
     *
     * All jobs will complete with a call to either .commit() or .abort() but
     * never both.
     *
     * Called with AioContext lock held, since many callback implementations
     * use bdrv_* functions that require to hold the lock.
     */
    void (*abort)(Job *job);

    /**
     * If the callback is not NULL, it will be invoked after a call to either
     * .commit() or .abort(). Regardless of which callback is invoked after
     * completion, .clean() will always be called, even if the job does not
     * belong to a transaction group.
     *
     * Called with AioContext lock held, since many callbacs implementations
     * use bdrv_* functions that require to hold the lock.
     */
    void (*clean)(Job *job);

    /**
     * If the callback is not NULL, it will be invoked in job_cancel_async
     *
     * This function must return true if the job will be cancelled
     * immediately without any further I/O (mandatory if @force is
     * true), and false otherwise.  This lets the generic job layer
     * know whether a job has been truly (force-)cancelled, or whether
     * it is just in a special completion mode (like mirror after
     * READY).
     * (If the callback is NULL, the job is assumed to terminate
     * without I/O.)
     *
     * Called with AioContext lock held, since many callback implementations
     * use bdrv_* functions that require to hold the lock.
     */
    bool (*cancel)(Job *job, bool force);


    /**
     * Called when the job is freed.
     * Called with AioContext lock held, since many callback implementations
     * use bdrv_* functions that require to hold the lock.
     */
    void (*free)(Job *job);
};

typedef enum JobCreateFlags {
    /* Default behavior */
    JOB_DEFAULT = 0x00,
    /* Job is not QMP-created and should not send QMP events */
    JOB_INTERNAL = 0x01,
    /* Job requires manual finalize step */
    JOB_MANUAL_FINALIZE = 0x02,
    /* Job requires manual dismiss step */
    JOB_MANUAL_DISMISS = 0x04,
} JobCreateFlags;

extern QemuMutex job_mutex;

#define JOB_LOCK_GUARD() QEMU_LOCK_GUARD(&job_mutex)

#define WITH_JOB_LOCK_GUARD() WITH_QEMU_LOCK_GUARD(&job_mutex)

/**
 * job_lock:
 *
 * Take the mutex protecting the list of jobs and their status.
 * Most functions called by the monitor need to call job_lock
 * and job_unlock manually.  On the other hand, function called
 * by the block jobs themselves and by the block layer will take the
 * lock for you.
 */
void job_lock(void);

/**
 * job_unlock:
 *
 * Release the mutex protecting the list of jobs and their status.
 */
void job_unlock(void);

/**
 * Allocate and return a new job transaction. Jobs can be added to the
 * transaction using job_txn_add_job().
 *
 * The transaction is automatically freed when the last job completes or is
 * cancelled.
 *
 * All jobs in the transaction either complete successfully or fail/cancel as a
 * group.  Jobs wait for each other before completing.  Cancelling one job
 * cancels all jobs in the transaction.
 */
JobTxn *job_txn_new(void);

/**
 * Release a reference that was previously acquired with job_txn_add_job or
 * job_txn_new. If it's the last reference to the object, it will be freed.
 *
 * Called with job lock *not* held.
 */
void job_txn_unref(JobTxn *txn);

/*
 * Same as job_txn_unref(), but called with job lock held.
 * Might release the lock temporarily.
 */
void job_txn_unref_locked(JobTxn *txn);

/**
 * Create a new long-running job and return it.
 * Called with job_mutex *not* held.
 *
 * @job_id: The id of the newly-created job, or %NULL for internal jobs
 * @driver: The class object for the newly-created job.
 * @txn: The transaction this job belongs to, if any. %NULL otherwise.
 * @ctx: The AioContext to run the job coroutine in.
 * @flags: Creation flags for the job. See @JobCreateFlags.
 * @cb: Completion function for the job.
 * @opaque: Opaque pointer value passed to @cb.
 * @errp: Error object.
 */
void *job_create(const char *job_id, const JobDriver *driver, JobTxn *txn,
                 AioContext *ctx, int flags, BlockCompletionFunc *cb,
                 void *opaque, Error **errp);

/**
 * Add a reference to Job refcnt, it will be decreased with job_unref, and then
 * be freed if it comes to be the last reference.
 *
 * Called with job lock held.
 */
void job_ref_locked(Job *job);

/**
 * Release a reference that was previously acquired with job_ref_locked() or
 * job_create(). If it's the last reference to the object, it will be freed.
 *
 * Takes AioContext lock internally to invoke a job->driver callback.
 * Called with job lock held.
 */
void job_unref_locked(Job *job);

/**
 * @job: The job that has made progress
 * @done: How much progress the job made since the last call
 *
 * Updates the progress counter of the job.
 *
 * May be called with mutex held or not held.
 */
void job_progress_update(Job *job, uint64_t done);

/**
 * @job: The job whose expected progress end value is set
 * @remaining: Missing progress (on top of the current progress counter value)
 *             until the new expected end value is reached
 *
 * Sets the expected end value of the progress counter of a job so that a
 * completion percentage can be calculated when the progress is updated.
 *
 * May be called with mutex held or not held.
 */
void job_progress_set_remaining(Job *job, uint64_t remaining);

/**
 * @job: The job whose expected progress end value is updated
 * @delta: Value which is to be added to the current expected end
 *         value
 *
 * Increases the expected end value of the progress counter of a job.
 * This is useful for parenthesis operations: If a job has to
 * conditionally perform a high-priority operation as part of its
 * progress, it calls this function with the expected operation's
 * length before, and job_progress_update() afterwards.
 * (So the operation acts as a parenthesis in regards to the main job
 * operation running in background.)
 *
 * May be called with mutex held or not held.
 */
void job_progress_increase_remaining(Job *job, uint64_t delta);

/**
 * Conditionally enter the job coroutine if the job is ready to run, not
 * already busy and fn() returns true. fn() is called while under the job_lock
 * critical section.
 *
 * Called with job lock held, but might release it temporarily.
 */
void job_enter_cond_locked(Job *job, bool(*fn)(Job *job));

/**
 * @job: A job that has not yet been started.
 *
 * Begins execution of a job.
 * Takes ownership of one reference to the job object.
 *
 * Called with job_mutex *not* held.
 */
void job_start(Job *job);

/**
 * @job: The job to enter.
 *
 * Continue the specified job by entering the coroutine.
 * Called with job_mutex *not* held.
 */
void job_enter(Job *job);

/**
 * @job: The job that is ready to pause.
 *
 * Pause now if job_pause() has been called. Jobs that perform lots of I/O
 * must call this between requests so that the job can be paused.
 *
 * Called with job_mutex *not* held.
 */
void coroutine_fn GRAPH_UNLOCKED job_pause_point(Job *job);

/**
 * @job: The job that calls the function.
 *
 * Yield the job coroutine.
 * Called with job_mutex *not* held.
 */
void coroutine_fn job_yield(Job *job);

/**
 * @job: The job that calls the function.
 * @ns: How many nanoseconds to stop for.
 *
 * Put the job to sleep (assuming that it wasn't canceled) for @ns
 * %QEMU_CLOCK_REALTIME nanoseconds.  Canceling the job will immediately
 * interrupt the wait.
 *
 * Called with job_mutex *not* held.
 */
void coroutine_fn job_sleep_ns(Job *job, int64_t ns);

/** Returns the JobType of a given Job. */
JobType job_type(const Job *job);

/** Returns the enum string for the JobType of a given Job. */
const char *job_type_str(const Job *job);

/** Returns true if the job should not be visible to the management layer. */
bool job_is_internal(Job *job);

/**
 * Returns whether the job is being cancelled.
 * Called with job_mutex *not* held.
 */
bool job_is_cancelled(Job *job);

/* Same as job_is_cancelled(), but called with job lock held. */
bool job_is_cancelled_locked(Job *job);

/**
 * Returns whether the job is scheduled for cancellation (at an
 * indefinite point).
 * Called with job_mutex *not* held.
 */
bool job_cancel_requested(Job *job);

/**
 * Returns whether the job is in a completed state.
 * Called with job lock held.
 */
bool job_is_completed_locked(Job *job);

/**
 * Returns whether the job is ready to be completed.
 * Called with job_mutex *not* held.
 */
bool job_is_ready(Job *job);

/* Same as job_is_ready(), but called with job lock held. */
bool job_is_ready_locked(Job *job);

/**
 * Request @job to pause at the next pause point. Must be paired with
 * job_resume(). If the job is supposed to be resumed by user action, call
 * job_user_pause_locked() instead.
 *
 * Called with job lock *not* held.
 */
void job_pause(Job *job);

/* Same as job_pause(), but called with job lock held. */
void job_pause_locked(Job *job);

/** Resumes a @job paused with job_pause. Called with job lock *not* held. */
void job_resume(Job *job);

/*
 * Same as job_resume(), but called with job lock held.
 * Might release the lock temporarily.
 */
void job_resume_locked(Job *job);

/**
 * Asynchronously pause the specified @job.
 * Do not allow a resume until a matching call to job_user_resume.
 * Called with job lock held.
 */
void job_user_pause_locked(Job *job, Error **errp);

/**
 * Returns true if the job is user-paused.
 * Called with job lock held.
 */
bool job_user_paused_locked(Job *job);

/**
 * Resume the specified @job.
 * Must be paired with a preceding job_user_pause_locked.
 * Called with job lock held, but might release it temporarily.
 */
void job_user_resume_locked(Job *job, Error **errp);

/**
 * Get the next element from the list of block jobs after @job, or the
 * first one if @job is %NULL.
 *
 * Returns the requested job, or %NULL if there are no more jobs left.
 * Called with job lock *not* held.
 */
Job *job_next(Job *job);

/* Same as job_next(), but called with job lock held. */
Job *job_next_locked(Job *job);

/**
 * Get the job identified by @id (which must not be %NULL).
 *
 * Returns the requested job, or %NULL if it doesn't exist.
 * Called with job lock held.
 */
Job *job_get_locked(const char *id);

/**
 * Check whether the verb @verb can be applied to @job in its current state.
 * Returns 0 if the verb can be applied; otherwise errp is set and -EPERM
 * returned.
 *
 * Called with job lock held.
 */
int job_apply_verb_locked(Job *job, JobVerb verb, Error **errp);

/**
 * The @job could not be started, free it.
 * Called with job_mutex *not* held.
 */
void job_early_fail(Job *job);

/**
 * Moves the @job from RUNNING to READY.
 * Called with job_mutex *not* held.
 */
void job_transition_to_ready(Job *job);

/**
 * Asynchronously complete the specified @job.
 * Called with job lock held, but might release it temporarily.
 */
void job_complete_locked(Job *job, Error **errp);

/**
 * Asynchronously cancel the specified @job. If @force is true, the job should
 * be cancelled immediately without waiting for a consistent state.
 * Called with job lock held.
 */
void job_cancel_locked(Job *job, bool force);

/**
 * Cancels the specified job like job_cancel_locked(), but may refuse
 * to do so if the operation isn't meaningful in the current state of the job.
 * Called with job lock held.
 */
void job_user_cancel_locked(Job *job, bool force, Error **errp);

/**
 * Synchronously cancel the @job.  The completion callback is called
 * before the function returns.  If @force is false, the job may
 * actually complete instead of canceling itself; the circumstances
 * under which this happens depend on the kind of job that is active.
 *
 * Returns the return value from the job if the job actually completed
 * during the call, or -ECANCELED if it was canceled.
 *
 * Called with job_lock *not* held.
 */
int job_cancel_sync(Job *job, bool force);

/* Same as job_cancel_sync, but called with job lock held. */
int job_cancel_sync_locked(Job *job, bool force);

/**
 * Synchronously force-cancels all jobs using job_cancel_sync_locked().
 *
 * Called with job_lock *not* held.
 */
void job_cancel_sync_all(void);

/**
 * @job: The job to be completed.
 * @errp: Error object which may be set by job_complete_locked(); this is not
 *        necessarily set on every error, the job return value has to be
 *        checked as well.
 *
 * Synchronously complete the job.  The completion callback is called before the
 * function returns, unless it is NULL (which is permissible when using this
 * function).
 *
 * Returns the return value from the job.
 * Called with job_lock held.
 */
int job_complete_sync_locked(Job *job, Error **errp);

/**
 * For a @job that has finished its work and is pending awaiting explicit
 * acknowledgement to commit its work, this will commit that work.
 *
 * FIXME: Make the below statement universally true:
 * For jobs that support the manual workflow mode, all graph changes that occur
 * as a result will occur after this command and before a successful reply.
 *
 * Called with job lock held.
 */
void job_finalize_locked(Job *job, Error **errp);

/**
 * Remove the concluded @job from the query list and resets the passed pointer
 * to %NULL. Returns an error if the job is not actually concluded.
 *
 * Called with job lock held.
 */
void job_dismiss_locked(Job **job, Error **errp);

/**
 * Synchronously finishes the given @job. If @finish is given, it is called to
 * trigger completion or cancellation of the job.
 *
 * Returns 0 if the job is successfully completed, -ECANCELED if the job was
 * cancelled before completing, and -errno in other error cases.
 *
 * Called with job_lock held, but might release it temporarily.
 */
int job_finish_sync_locked(Job *job, void (*finish)(Job *, Error **errp),
                           Error **errp);

/**
 * Sets the @job->aio_context.
 * Called with job_mutex *not* held.
 *
 * This function must run in the main thread to protect against
 * concurrent read in job_finish_sync_locked(), takes the job_mutex
 * lock to protect against the read in job_do_yield_locked(), and must
 * be called when the job is quiescent.
 */
void job_set_aio_context(Job *job, AioContext *ctx);

#endif
