/*
 * 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);
    GLOBAL_STATE_CODE();

    /* 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;
}
