/*
 * QEMU backup
 *
 * Copyright (C) 2013 Proxmox Server Solutions
 * Copyright (c) 2019 Virtuozzo International GmbH.
 *
 * Authors:
 *  Dietmar Maurer (dietmar@proxmox.com)
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"

#include "trace.h"
#include "block/block.h"
#include "block/block_int.h"
#include "block/blockjob_int.h"
#include "block/block_backup.h"
#include "block/block-copy.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/cutils.h"
#include "sysemu/block-backend.h"
#include "qemu/bitmap.h"
#include "qemu/error-report.h"

#include "block/copy-before-write.h"

typedef struct BackupBlockJob {
    BlockJob common;
    BlockDriverState *cbw;
    BlockDriverState *source_bs;
    BlockDriverState *target_bs;

    BdrvDirtyBitmap *sync_bitmap;

    MirrorSyncMode sync_mode;
    BitmapSyncMode bitmap_mode;
    BlockdevOnError on_source_error;
    BlockdevOnError on_target_error;
    uint64_t len;
    int64_t cluster_size;
    BackupPerf perf;

    BlockCopyState *bcs;

    bool wait;
    BlockCopyCallState *bg_bcs_call;
} BackupBlockJob;

static const BlockJobDriver backup_job_driver;

static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
{
    BdrvDirtyBitmap *bm;
    bool sync = (((ret == 0) || (job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS)) \
                 && (job->bitmap_mode != BITMAP_SYNC_MODE_NEVER));

    if (sync) {
        /*
         * We succeeded, or we always intended to sync the bitmap.
         * Delete this bitmap and install the child.
         */
        bm = bdrv_dirty_bitmap_abdicate(job->sync_bitmap, NULL);
    } else {
        /*
         * We failed, or we never intended to sync the bitmap anyway.
         * Merge the successor back into the parent, keeping all data.
         */
        bm = bdrv_reclaim_dirty_bitmap(job->sync_bitmap, NULL);
    }

    assert(bm);

    if (ret < 0 && job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS) {
        /* If we failed and synced, merge in the bits we didn't copy: */
        bdrv_dirty_bitmap_merge_internal(bm, block_copy_dirty_bitmap(job->bcs),
                                         NULL, true);
    }
}

static void backup_commit(Job *job)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    if (s->sync_bitmap) {
        backup_cleanup_sync_bitmap(s, 0);
    }
}

static void backup_abort(Job *job)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    if (s->sync_bitmap) {
        backup_cleanup_sync_bitmap(s, -1);
    }
}

static void backup_clean(Job *job)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    block_job_remove_all_bdrv(&s->common);
    bdrv_cbw_drop(s->cbw);
}

void backup_do_checkpoint(BlockJob *job, Error **errp)
{
    BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);

    assert(block_job_driver(job) == &backup_job_driver);

    if (backup_job->sync_mode != MIRROR_SYNC_MODE_NONE) {
        error_setg(errp, "The backup job only supports block checkpoint in"
                   " sync=none mode");
        return;
    }

    bdrv_set_dirty_bitmap(block_copy_dirty_bitmap(backup_job->bcs), 0,
                          backup_job->len);
}

static BlockErrorAction backup_error_action(BackupBlockJob *job,
                                            bool read, int error)
{
    if (read) {
        return block_job_error_action(&job->common, job->on_source_error,
                                      true, error);
    } else {
        return block_job_error_action(&job->common, job->on_target_error,
                                      false, error);
    }
}

static void coroutine_fn backup_block_copy_callback(void *opaque)
{
    BackupBlockJob *s = opaque;

    if (s->wait) {
        s->wait = false;
        aio_co_wake(s->common.job.co);
    } else {
        job_enter(&s->common.job);
    }
}

static int coroutine_fn backup_loop(BackupBlockJob *job)
{
    BlockCopyCallState *s = NULL;
    int ret = 0;
    bool error_is_read;
    BlockErrorAction act;

    while (true) { /* retry loop */
        job->bg_bcs_call = s = block_copy_async(job->bcs, 0,
                QEMU_ALIGN_UP(job->len, job->cluster_size),
                job->perf.max_workers, job->perf.max_chunk,
                backup_block_copy_callback, job);

        while (!block_copy_call_finished(s) &&
               !job_is_cancelled(&job->common.job))
        {
            job_yield(&job->common.job);
        }

        if (!block_copy_call_finished(s)) {
            assert(job_is_cancelled(&job->common.job));
            /*
             * Note that we can't use job_yield() here, as it doesn't work for
             * cancelled job.
             */
            block_copy_call_cancel(s);
            job->wait = true;
            qemu_coroutine_yield();
            assert(block_copy_call_finished(s));
            ret = 0;
            goto out;
        }

        if (job_is_cancelled(&job->common.job) ||
            block_copy_call_succeeded(s))
        {
            ret = 0;
            goto out;
        }

        if (block_copy_call_cancelled(s)) {
            /*
             * Job is not cancelled but only block-copy call. This is possible
             * after job pause. Now the pause is finished, start new block-copy
             * iteration.
             */
            block_copy_call_free(s);
            continue;
        }

        /* The only remaining case is failed block-copy call. */
        assert(block_copy_call_failed(s));

        ret = block_copy_call_status(s, &error_is_read);
        act = backup_error_action(job, error_is_read, -ret);
        switch (act) {
        case BLOCK_ERROR_ACTION_REPORT:
            goto out;
        case BLOCK_ERROR_ACTION_STOP:
            /*
             * Go to pause prior to starting new block-copy call on the next
             * iteration.
             */
            job_pause_point(&job->common.job);
            break;
        case BLOCK_ERROR_ACTION_IGNORE:
            /* Proceed to new block-copy call to retry. */
            break;
        default:
            abort();
        }

        block_copy_call_free(s);
    }

out:
    block_copy_call_free(s);
    job->bg_bcs_call = NULL;
    return ret;
}

static void backup_init_bcs_bitmap(BackupBlockJob *job)
{
    bool ret;
    uint64_t estimate;
    BdrvDirtyBitmap *bcs_bitmap = block_copy_dirty_bitmap(job->bcs);

    if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
        bdrv_clear_dirty_bitmap(bcs_bitmap, NULL);
        ret = bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bitmap,
                                               NULL, true);
        assert(ret);
    } else if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
        /*
         * We can't hog the coroutine to initialize this thoroughly.
         * Set a flag and resume work when we are able to yield safely.
         */
        block_copy_set_skip_unallocated(job->bcs, true);
    }

    estimate = bdrv_get_dirty_count(bcs_bitmap);
    job_progress_set_remaining(&job->common.job, estimate);
}

static int coroutine_fn backup_run(Job *job, Error **errp)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    int ret;

    backup_init_bcs_bitmap(s);

    if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
        int64_t offset = 0;
        int64_t count;

        for (offset = 0; offset < s->len; ) {
            if (job_is_cancelled(job)) {
                return -ECANCELED;
            }

            job_pause_point(job);

            if (job_is_cancelled(job)) {
                return -ECANCELED;
            }

            ret = block_copy_reset_unallocated(s->bcs, offset, &count);
            if (ret < 0) {
                return ret;
            }

            offset += count;
        }
        block_copy_set_skip_unallocated(s->bcs, false);
    }

    if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
        /*
         * All bits are set in bcs bitmap to allow any cluster to be copied.
         * This does not actually require them to be copied.
         */
        while (!job_is_cancelled(job)) {
            /*
             * Yield until the job is cancelled.  We just let our before_write
             * notify callback service CoW requests.
             */
            job_yield(job);
        }
    } else {
        return backup_loop(s);
    }

    return 0;
}

static void coroutine_fn backup_pause(Job *job)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);

    if (s->bg_bcs_call && !block_copy_call_finished(s->bg_bcs_call)) {
        block_copy_call_cancel(s->bg_bcs_call);
        s->wait = true;
        qemu_coroutine_yield();
    }
}

static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common);

    /*
     * block_job_set_speed() is called first from block_job_create(), when we
     * don't yet have s->bcs.
     */
    if (s->bcs) {
        block_copy_set_speed(s->bcs, speed);
        if (s->bg_bcs_call) {
            block_copy_kick(s->bg_bcs_call);
        }
    }
}

static bool backup_cancel(Job *job, bool force)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);

    bdrv_cancel_in_flight(s->target_bs);
    return true;
}

static const BlockJobDriver backup_job_driver = {
    .job_driver = {
        .instance_size          = sizeof(BackupBlockJob),
        .job_type               = JOB_TYPE_BACKUP,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .run                    = backup_run,
        .commit                 = backup_commit,
        .abort                  = backup_abort,
        .clean                  = backup_clean,
        .pause                  = backup_pause,
        .cancel                 = backup_cancel,
    },
    .set_speed = backup_set_speed,
};

BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                  BlockDriverState *target, int64_t speed,
                  MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
                  BitmapSyncMode bitmap_mode,
                  bool compress,
                  const char *filter_node_name,
                  BackupPerf *perf,
                  BlockdevOnError on_source_error,
                  BlockdevOnError on_target_error,
                  int creation_flags,
                  BlockCompletionFunc *cb, void *opaque,
                  JobTxn *txn, Error **errp)
{
    int64_t len, target_len;
    BackupBlockJob *job = NULL;
    int64_t cluster_size;
    BlockDriverState *cbw = NULL;
    BlockCopyState *bcs = NULL;

    assert(bs);
    assert(target);

    /* QMP interface protects us from these cases */
    assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
    assert(sync_bitmap || sync_mode != MIRROR_SYNC_MODE_BITMAP);

    if (bs == target) {
        error_setg(errp, "Source and target cannot be the same");
        return NULL;
    }

    if (!bdrv_is_inserted(bs)) {
        error_setg(errp, "Device is not inserted: %s",
                   bdrv_get_device_name(bs));
        return NULL;
    }

    if (!bdrv_is_inserted(target)) {
        error_setg(errp, "Device is not inserted: %s",
                   bdrv_get_device_name(target));
        return NULL;
    }

    if (compress && !bdrv_supports_compressed_writes(target)) {
        error_setg(errp, "Compression is not supported for this drive %s",
                   bdrv_get_device_name(target));
        return NULL;
    }

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
        return NULL;
    }

    if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
        return NULL;
    }

    if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
        error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
        return NULL;
    }

    if (perf->max_chunk < 0) {
        error_setg(errp, "max-chunk must be zero (which means no limit) or "
                   "positive");
        return NULL;
    }

    if (sync_bitmap) {
        /* If we need to write to this bitmap, check that we can: */
        if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
            bdrv_dirty_bitmap_check(sync_bitmap, BDRV_BITMAP_DEFAULT, errp)) {
            return NULL;
        }

        /* Create a new bitmap, and freeze/disable this one. */
        if (bdrv_dirty_bitmap_create_successor(sync_bitmap, errp) < 0) {
            return NULL;
        }
    }

    len = bdrv_getlength(bs);
    if (len < 0) {
        error_setg_errno(errp, -len, "Unable to get length for '%s'",
                         bdrv_get_device_or_node_name(bs));
        goto error;
    }

    target_len = bdrv_getlength(target);
    if (target_len < 0) {
        error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
                         bdrv_get_device_or_node_name(bs));
        goto error;
    }

    if (target_len != len) {
        error_setg(errp, "Source and target image have different sizes");
        goto error;
    }

    cbw = bdrv_cbw_append(bs, target, filter_node_name, &bcs, errp);
    if (!cbw) {
        goto error;
    }

    cluster_size = block_copy_cluster_size(bcs);

    if (perf->max_chunk && perf->max_chunk < cluster_size) {
        error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
                   "cluster size (%" PRIi64 ")", perf->max_chunk, cluster_size);
        goto error;
    }

    /* job->len is fixed, so we can't allow resize */
    job = block_job_create(job_id, &backup_job_driver, txn, cbw,
                           0, BLK_PERM_ALL,
                           speed, creation_flags, cb, opaque, errp);
    if (!job) {
        goto error;
    }

    job->cbw = cbw;
    job->source_bs = bs;
    job->target_bs = target;
    job->on_source_error = on_source_error;
    job->on_target_error = on_target_error;
    job->sync_mode = sync_mode;
    job->sync_bitmap = sync_bitmap;
    job->bitmap_mode = bitmap_mode;
    job->bcs = bcs;
    job->cluster_size = cluster_size;
    job->len = len;
    job->perf = *perf;

    block_copy_set_copy_opts(bcs, perf->use_copy_range, compress);
    block_copy_set_progress_meter(bcs, &job->common.job.progress);
    block_copy_set_speed(bcs, speed);

    /* Required permissions are taken by copy-before-write filter target */
    block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
                       &error_abort);

    return &job->common;

 error:
    if (sync_bitmap) {
        bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL);
    }
    if (cbw) {
        bdrv_cbw_drop(cbw);
    }

    return NULL;
}
