/*
 * QEMU Block driver for Veritas HyperScale (VxHS)
 *
 * Copyright (c) 2017 Veritas Technologies LLC.
 *
 * 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 <qnio/qnio_api.h>
#include <sys/param.h>
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "trace.h"
#include "qemu/uri.h"
#include "qapi/error.h"
#include "qemu/uuid.h"
#include "crypto/tlscredsx509.h"

#define VXHS_OPT_FILENAME           "filename"
#define VXHS_OPT_VDISK_ID           "vdisk-id"
#define VXHS_OPT_SERVER             "server"
#define VXHS_OPT_HOST               "host"
#define VXHS_OPT_PORT               "port"

/* Only accessed under QEMU global mutex */
static uint32_t vxhs_ref;

typedef enum {
    VDISK_AIO_READ,
    VDISK_AIO_WRITE,
} VDISKAIOCmd;

/*
 * HyperScale AIO callbacks structure
 */
typedef struct VXHSAIOCB {
    BlockAIOCB common;
    int err;
} VXHSAIOCB;

typedef struct VXHSvDiskHostsInfo {
    void *dev_handle; /* Device handle */
    char *host; /* Host name or IP */
    int port; /* Host's port number */
} VXHSvDiskHostsInfo;

/*
 * Structure per vDisk maintained for state
 */
typedef struct BDRVVXHSState {
    VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
    char *vdisk_guid;
    char *tlscredsid; /* tlscredsid */
} BDRVVXHSState;

static void vxhs_complete_aio_bh(void *opaque)
{
    VXHSAIOCB *acb = opaque;
    BlockCompletionFunc *cb = acb->common.cb;
    void *cb_opaque = acb->common.opaque;
    int ret = 0;

    if (acb->err != 0) {
        trace_vxhs_complete_aio(acb, acb->err);
        ret = (-EIO);
    }

    qemu_aio_unref(acb);
    cb(cb_opaque, ret);
}

/*
 * Called from a libqnio thread
 */
static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
{
    VXHSAIOCB *acb = NULL;

    switch (opcode) {
    case IRP_READ_REQUEST:
    case IRP_WRITE_REQUEST:

        /*
         * ctx is VXHSAIOCB*
         * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
         */
        if (ctx) {
            acb = ctx;
        } else {
            trace_vxhs_iio_callback(error);
            goto out;
        }

        if (error) {
            if (!acb->err) {
                acb->err = error;
            }
            trace_vxhs_iio_callback(error);
        }

        aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
                                vxhs_complete_aio_bh, acb);
        break;

    default:
        if (error == QNIOERROR_HUP) {
            /*
             * Channel failed, spontaneous notification,
             * not in response to I/O
             */
            trace_vxhs_iio_callback_chnfail(error, errno);
        } else {
            trace_vxhs_iio_callback_unknwn(opcode, error);
        }
        break;
    }
out:
    return;
}

static QemuOptsList runtime_opts = {
    .name = "vxhs",
    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
    .desc = {
        {
            .name = VXHS_OPT_FILENAME,
            .type = QEMU_OPT_STRING,
            .help = "URI to the Veritas HyperScale image",
        },
        {
            .name = VXHS_OPT_VDISK_ID,
            .type = QEMU_OPT_STRING,
            .help = "UUID of the VxHS vdisk",
        },
        {
            .name = "tls-creds",
            .type = QEMU_OPT_STRING,
            .help = "ID of the TLS/SSL credentials to use",
        },
        { /* end of list */ }
    },
};

static QemuOptsList runtime_tcp_opts = {
    .name = "vxhs_tcp",
    .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
    .desc = {
        {
            .name = VXHS_OPT_HOST,
            .type = QEMU_OPT_STRING,
            .help = "host address (ipv4 addresses)",
        },
        {
            .name = VXHS_OPT_PORT,
            .type = QEMU_OPT_NUMBER,
            .help = "port number on which VxHSD is listening (default 9999)",
            .def_value_str = "9999"
        },
        { /* end of list */ }
    },
};

/*
 * Parse incoming URI and populate *options with the host
 * and device information
 */
static int vxhs_parse_uri(const char *filename, QDict *options)
{
    URI *uri = NULL;
    char *port;
    int ret = 0;

    trace_vxhs_parse_uri_filename(filename);
    uri = uri_parse(filename);
    if (!uri || !uri->server || !uri->path) {
        uri_free(uri);
        return -EINVAL;
    }

    qdict_put_str(options, VXHS_OPT_SERVER ".host", uri->server);

    if (uri->port) {
        port = g_strdup_printf("%d", uri->port);
        qdict_put_str(options, VXHS_OPT_SERVER ".port", port);
        g_free(port);
    }

    qdict_put_str(options, "vdisk-id", uri->path);

    trace_vxhs_parse_uri_hostinfo(uri->server, uri->port);
    uri_free(uri);

    return ret;
}

static void vxhs_parse_filename(const char *filename, QDict *options,
                                Error **errp)
{
    if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
        error_setg(errp, "vdisk-id/server and a file name may not be specified "
                         "at the same time");
        return;
    }

    if (strstr(filename, "://")) {
        int ret = vxhs_parse_uri(filename, options);
        if (ret < 0) {
            error_setg(errp, "Invalid URI. URI should be of the form "
                       "  vxhs://<host_ip>:<port>/<vdisk-id>");
        }
    }
}

static void vxhs_refresh_limits(BlockDriverState *bs, Error **errp)
{
    /* XXX Does VXHS support AIO on less than 512-byte alignment? */
    bs->bl.request_alignment = 512;
}

static int vxhs_init_and_ref(void)
{
    if (vxhs_ref++ == 0) {
        if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
            return -ENODEV;
        }
    }
    return 0;
}

static void vxhs_unref(void)
{
    if (--vxhs_ref == 0) {
        iio_fini();
    }
}

static void vxhs_get_tls_creds(const char *id, char **cacert,
                               char **key, char **cert, Error **errp)
{
    Object *obj;
    QCryptoTLSCreds *creds;
    QCryptoTLSCredsX509 *creds_x509;

    obj = object_resolve_path_component(
        object_get_objects_root(), id);

    if (!obj) {
        error_setg(errp, "No TLS credentials with id '%s'",
                   id);
        return;
    }

    creds_x509 = (QCryptoTLSCredsX509 *)
        object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509);

    if (!creds_x509) {
        error_setg(errp, "Object with id '%s' is not TLS credentials",
                   id);
        return;
    }

    creds = &creds_x509->parent_obj;

    if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
        error_setg(errp,
                   "Expecting TLS credentials with a client endpoint");
        return;
    }

    /*
     * Get the cacert, client_cert and client_key file names.
     */
    if (!creds->dir) {
        error_setg(errp, "TLS object missing 'dir' property value");
        return;
    }

    *cacert = g_strdup_printf("%s/%s", creds->dir,
                              QCRYPTO_TLS_CREDS_X509_CA_CERT);
    *cert = g_strdup_printf("%s/%s", creds->dir,
                            QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
    *key = g_strdup_printf("%s/%s", creds->dir,
                           QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
}

static int vxhs_open(BlockDriverState *bs, QDict *options,
                     int bdrv_flags, Error **errp)
{
    BDRVVXHSState *s = bs->opaque;
    void *dev_handlep;
    QDict *backing_options = NULL;
    QemuOpts *opts = NULL;
    QemuOpts *tcp_opts = NULL;
    char *of_vsa_addr = NULL;
    Error *local_err = NULL;
    const char *vdisk_id_opt;
    const char *server_host_opt;
    int ret = 0;
    char *cacert = NULL;
    char *client_key = NULL;
    char *client_cert = NULL;

    ret = vxhs_init_and_ref();
    if (ret < 0) {
        ret = -EINVAL;
        goto out;
    }

    /* Create opts info from runtime_opts and runtime_tcp_opts list */
    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        ret = -EINVAL;
        goto out;
    }

    /* vdisk-id is the disk UUID */
    vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
    if (!vdisk_id_opt) {
        error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
        ret = -EINVAL;
        goto out;
    }

    /* vdisk-id may contain a leading '/' */
    if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
        error_setg(&local_err, "vdisk-id cannot be more than %d characters",
                   UUID_FMT_LEN);
        ret = -EINVAL;
        goto out;
    }

    s->vdisk_guid = g_strdup(vdisk_id_opt);
    trace_vxhs_open_vdiskid(vdisk_id_opt);

    /* get the 'server.' arguments */
    qdict_extract_subqdict(options, &backing_options, VXHS_OPT_SERVER".");

    qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
    if (local_err != NULL) {
        ret = -EINVAL;
        goto out;
    }

    server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
    if (!server_host_opt) {
        error_setg(&local_err, QERR_MISSING_PARAMETER,
                   VXHS_OPT_SERVER"."VXHS_OPT_HOST);
        ret = -EINVAL;
        goto out;
    }

    if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
        error_setg(&local_err, "server.host cannot be more than %d characters",
                   MAXHOSTNAMELEN);
        ret = -EINVAL;
        goto out;
    }

    /* check if we got tls-creds via the --object argument */
    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
    if (s->tlscredsid) {
        vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
                           &client_cert, &local_err);
        if (local_err != NULL) {
            ret = -EINVAL;
            goto out;
        }
        trace_vxhs_get_creds(cacert, client_key, client_cert);
    }

    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
    s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
                                                          VXHS_OPT_PORT),
                                                          NULL, 0);

    trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
                             s->vdisk_hostinfo.port);

    of_vsa_addr = g_strdup_printf("of://%s:%d",
                                  s->vdisk_hostinfo.host,
                                  s->vdisk_hostinfo.port);

    /*
     * Open qnio channel to storage agent if not opened before
     */
    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
                           cacert, client_key, client_cert);
    if (dev_handlep == NULL) {
        trace_vxhs_open_iio_open(of_vsa_addr);
        ret = -ENODEV;
        goto out;
    }
    s->vdisk_hostinfo.dev_handle = dev_handlep;

out:
    g_free(of_vsa_addr);
    qobject_unref(backing_options);
    qemu_opts_del(tcp_opts);
    qemu_opts_del(opts);
    g_free(cacert);
    g_free(client_key);
    g_free(client_cert);

    if (ret < 0) {
        vxhs_unref();
        error_propagate(errp, local_err);
        g_free(s->vdisk_hostinfo.host);
        g_free(s->vdisk_guid);
        g_free(s->tlscredsid);
        s->vdisk_guid = NULL;
    }

    return ret;
}

static const AIOCBInfo vxhs_aiocb_info = {
    .aiocb_size = sizeof(VXHSAIOCB)
};

/*
 * This allocates QEMU-VXHS callback for each IO
 * and is passed to QNIO. When QNIO completes the work,
 * it will be passed back through the callback.
 */
static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, uint64_t offset,
                               QEMUIOVector *qiov, uint64_t size,
                               BlockCompletionFunc *cb, void *opaque,
                               VDISKAIOCmd iodir)
{
    VXHSAIOCB *acb = NULL;
    BDRVVXHSState *s = bs->opaque;
    int iio_flags = 0;
    int ret = 0;
    void *dev_handle = s->vdisk_hostinfo.dev_handle;

    acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);

    /*
     * Initialize VXHSAIOCB.
     */
    acb->err = 0;

    iio_flags = IIO_FLAG_ASYNC;

    switch (iodir) {
    case VDISK_AIO_WRITE:
            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
                             offset, size, iio_flags);
            break;
    case VDISK_AIO_READ:
            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
                            offset, size, iio_flags);
            break;
    default:
            trace_vxhs_aio_rw_invalid(iodir);
            goto errout;
    }

    if (ret != 0) {
        trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
                                acb, ret, errno);
        goto errout;
    }
    return &acb->common;

errout:
    qemu_aio_unref(acb);
    return NULL;
}

static BlockAIOCB *vxhs_aio_preadv(BlockDriverState *bs,
                                   uint64_t offset, uint64_t bytes,
                                   QEMUIOVector *qiov, int flags,
                                   BlockCompletionFunc *cb, void *opaque)
{
    return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_READ);
}

static BlockAIOCB *vxhs_aio_pwritev(BlockDriverState *bs,
                                    uint64_t offset, uint64_t bytes,
                                    QEMUIOVector *qiov, int flags,
                                    BlockCompletionFunc *cb, void *opaque)
{
    return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_WRITE);
}

static void vxhs_close(BlockDriverState *bs)
{
    BDRVVXHSState *s = bs->opaque;

    trace_vxhs_close(s->vdisk_guid);

    g_free(s->vdisk_guid);
    s->vdisk_guid = NULL;

    /*
     * Close vDisk device
     */
    if (s->vdisk_hostinfo.dev_handle) {
        iio_close(s->vdisk_hostinfo.dev_handle);
        s->vdisk_hostinfo.dev_handle = NULL;
    }

    vxhs_unref();

    /*
     * Free the dynamically allocated host string etc
     */
    g_free(s->vdisk_hostinfo.host);
    g_free(s->tlscredsid);
    s->tlscredsid = NULL;
    s->vdisk_hostinfo.host = NULL;
    s->vdisk_hostinfo.port = 0;
}

static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
{
    int64_t vdisk_size = -1;
    int ret = 0;
    void *dev_handle = s->vdisk_hostinfo.dev_handle;

    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
    if (ret < 0) {
        trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
        return -EIO;
    }

    trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
    return vdisk_size;
}

/*
 * Returns the size of vDisk in bytes. This is required
 * by QEMU block upper block layer so that it is visible
 * to guest.
 */
static int64_t vxhs_getlength(BlockDriverState *bs)
{
    BDRVVXHSState *s = bs->opaque;
    int64_t vdisk_size;

    vdisk_size = vxhs_get_vdisk_stat(s);
    if (vdisk_size < 0) {
        return -EIO;
    }

    return vdisk_size;
}

static BlockDriver bdrv_vxhs = {
    .format_name                  = "vxhs",
    .protocol_name                = "vxhs",
    .instance_size                = sizeof(BDRVVXHSState),
    .bdrv_file_open               = vxhs_open,
    .bdrv_parse_filename          = vxhs_parse_filename,
    .bdrv_refresh_limits          = vxhs_refresh_limits,
    .bdrv_close                   = vxhs_close,
    .bdrv_getlength               = vxhs_getlength,
    .bdrv_aio_preadv              = vxhs_aio_preadv,
    .bdrv_aio_pwritev             = vxhs_aio_pwritev,
};

static void bdrv_vxhs_init(void)
{
    bdrv_register(&bdrv_vxhs);
}

block_init(bdrv_vxhs_init);
