/*
 *  xen backend driver infrastructure
 *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 *  Contributions after 2012-01-13 are licensed under the terms of the
 *  GNU GPL, version 2 or (at your option) any later version.
 */

/*
 * TODO: add some xenbus / xenstore concepts overview here.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/signal.h>

#include <xs.h>
#include <xenctrl.h>
#include <xen/grant_table.h>

#include "hw.h"
#include "qemu-char.h"
#include "qemu-log.h"
#include "xen_backend.h"

/* ------------------------------------------------------------- */

/* public */
XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
struct xs_handle *xenstore = NULL;
const char *xen_protocol;

/* private */
static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
static int debug = 0;

/* ------------------------------------------------------------- */

int xenstore_write_str(const char *base, const char *node, const char *val)
{
    char abspath[XEN_BUFSIZE];

    snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
    if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
        return -1;
    }
    return 0;
}

char *xenstore_read_str(const char *base, const char *node)
{
    char abspath[XEN_BUFSIZE];
    unsigned int len;
    char *str, *ret = NULL;

    snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
    str = xs_read(xenstore, 0, abspath, &len);
    if (str != NULL) {
        /* move to qemu-allocated memory to make sure
         * callers can savely g_free() stuff. */
        ret = g_strdup(str);
        free(str);
    }
    return ret;
}

int xenstore_write_int(const char *base, const char *node, int ival)
{
    char val[32];

    snprintf(val, sizeof(val), "%d", ival);
    return xenstore_write_str(base, node, val);
}

int xenstore_read_int(const char *base, const char *node, int *ival)
{
    char *val;
    int rc = -1;

    val = xenstore_read_str(base, node);
    if (val && 1 == sscanf(val, "%d", ival)) {
        rc = 0;
    }
    g_free(val);
    return rc;
}

int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
{
    return xenstore_write_str(xendev->be, node, val);
}

int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
{
    return xenstore_write_int(xendev->be, node, ival);
}

char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
{
    return xenstore_read_str(xendev->be, node);
}

int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
{
    return xenstore_read_int(xendev->be, node, ival);
}

char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
{
    return xenstore_read_str(xendev->fe, node);
}

int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
{
    return xenstore_read_int(xendev->fe, node, ival);
}

/* ------------------------------------------------------------- */

const char *xenbus_strstate(enum xenbus_state state)
{
    static const char *const name[] = {
        [ XenbusStateUnknown      ] = "Unknown",
        [ XenbusStateInitialising ] = "Initialising",
        [ XenbusStateInitWait     ] = "InitWait",
        [ XenbusStateInitialised  ] = "Initialised",
        [ XenbusStateConnected    ] = "Connected",
        [ XenbusStateClosing      ] = "Closing",
        [ XenbusStateClosed       ] = "Closed",
    };
    return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
}

int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
{
    int rc;

    rc = xenstore_write_be_int(xendev, "state", state);
    if (rc < 0) {
        return rc;
    }
    xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
                  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
    xendev->be_state = state;
    return 0;
}

/* ------------------------------------------------------------- */

struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
{
    struct XenDevice *xendev;

    QTAILQ_FOREACH(xendev, &xendevs, next) {
        if (xendev->dom != dom) {
            continue;
        }
        if (xendev->dev != dev) {
            continue;
        }
        if (strcmp(xendev->type, type) != 0) {
            continue;
        }
        return xendev;
    }
    return NULL;
}

/*
 * get xen backend device, allocate a new one if it doesn't exist.
 */
static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
                                           struct XenDevOps *ops)
{
    struct XenDevice *xendev;
    char *dom0;

    xendev = xen_be_find_xendev(type, dom, dev);
    if (xendev) {
        return xendev;
    }

    /* init new xendev */
    xendev = g_malloc0(ops->size);
    xendev->type  = type;
    xendev->dom   = dom;
    xendev->dev   = dev;
    xendev->ops   = ops;

    dom0 = xs_get_domain_path(xenstore, 0);
    snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
             dom0, xendev->type, xendev->dom, xendev->dev);
    snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
             xendev->type, xendev->dev);
    free(dom0);

    xendev->debug      = debug;
    xendev->local_port = -1;

    xendev->evtchndev = xen_xc_evtchn_open(NULL, 0);
    if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) {
        xen_be_printf(NULL, 0, "can't open evtchn device\n");
        g_free(xendev);
        return NULL;
    }
    fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);

    if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
        xendev->gnttabdev = xen_xc_gnttab_open(NULL, 0);
        if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) {
            xen_be_printf(NULL, 0, "can't open gnttab device\n");
            xc_evtchn_close(xendev->evtchndev);
            g_free(xendev);
            return NULL;
        }
    } else {
        xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE;
    }

    QTAILQ_INSERT_TAIL(&xendevs, xendev, next);

    if (xendev->ops->alloc) {
        xendev->ops->alloc(xendev);
    }

    return xendev;
}

/*
 * release xen backend device.
 */
static struct XenDevice *xen_be_del_xendev(int dom, int dev)
{
    struct XenDevice *xendev, *xnext;

    /*
     * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but
     * we save the next pointer in xnext because we might free xendev.
     */
    xnext = xendevs.tqh_first;
    while (xnext) {
        xendev = xnext;
        xnext = xendev->next.tqe_next;

        if (xendev->dom != dom) {
            continue;
        }
        if (xendev->dev != dev && dev != -1) {
            continue;
        }

        if (xendev->ops->free) {
            xendev->ops->free(xendev);
        }

        if (xendev->fe) {
            char token[XEN_BUFSIZE];
            snprintf(token, sizeof(token), "fe:%p", xendev);
            xs_unwatch(xenstore, xendev->fe, token);
            g_free(xendev->fe);
        }

        if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) {
            xc_evtchn_close(xendev->evtchndev);
        }
        if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) {
            xc_gnttab_close(xendev->gnttabdev);
        }

        QTAILQ_REMOVE(&xendevs, xendev, next);
        g_free(xendev);
    }
    return NULL;
}

/*
 * Sync internal data structures on xenstore updates.
 * Node specifies the changed field.  node = NULL means
 * update all fields (used for initialization).
 */
static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
{
    if (node == NULL  ||  strcmp(node, "online") == 0) {
        if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
            xendev->online = 0;
        }
    }

    if (node) {
        xen_be_printf(xendev, 2, "backend update: %s\n", node);
        if (xendev->ops->backend_changed) {
            xendev->ops->backend_changed(xendev, node);
        }
    }
}

static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
{
    int fe_state;

    if (node == NULL  ||  strcmp(node, "state") == 0) {
        if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) {
            fe_state = XenbusStateUnknown;
        }
        if (xendev->fe_state != fe_state) {
            xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
                          xenbus_strstate(xendev->fe_state),
                          xenbus_strstate(fe_state));
        }
        xendev->fe_state = fe_state;
    }
    if (node == NULL  ||  strcmp(node, "protocol") == 0) {
        g_free(xendev->protocol);
        xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
        if (xendev->protocol) {
            xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
        }
    }

    if (node) {
        xen_be_printf(xendev, 2, "frontend update: %s\n", node);
        if (xendev->ops->frontend_changed) {
            xendev->ops->frontend_changed(xendev, node);
        }
    }
}

/* ------------------------------------------------------------- */
/* Check for possible state transitions and perform them.        */

/*
 * Initial xendev setup.  Read frontend path, register watch for it.
 * Should succeed once xend finished setting up the backend device.
 *
 * Also sets initial state (-> Initializing) when done.  Which
 * only affects the xendev->be_state variable as xenbus should
 * already be put into that state by xend.
 */
static int xen_be_try_setup(struct XenDevice *xendev)
{
    char token[XEN_BUFSIZE];
    int be_state;

    if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
        xen_be_printf(xendev, 0, "reading backend state failed\n");
        return -1;
    }

    if (be_state != XenbusStateInitialising) {
        xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
                      xenbus_strstate(be_state));
        return -1;
    }

    xendev->fe = xenstore_read_be_str(xendev, "frontend");
    if (xendev->fe == NULL) {
        xen_be_printf(xendev, 0, "reading frontend path failed\n");
        return -1;
    }

    /* setup frontend watch */
    snprintf(token, sizeof(token), "fe:%p", xendev);
    if (!xs_watch(xenstore, xendev->fe, token)) {
        xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
                      xendev->fe);
        return -1;
    }
    xen_be_set_state(xendev, XenbusStateInitialising);

    xen_be_backend_changed(xendev, NULL);
    xen_be_frontend_changed(xendev, NULL);
    return 0;
}

/*
 * Try initialize xendev.  Prepare everything the backend can do
 * without synchronizing with the frontend.  Fakes hotplug-status.  No
 * hotplug involved here because this is about userspace drivers, thus
 * there are kernel backend devices which could invoke hotplug.
 *
 * Goes to InitWait on success.
 */
static int xen_be_try_init(struct XenDevice *xendev)
{
    int rc = 0;

    if (!xendev->online) {
        xen_be_printf(xendev, 1, "not online\n");
        return -1;
    }

    if (xendev->ops->init) {
        rc = xendev->ops->init(xendev);
    }
    if (rc != 0) {
        xen_be_printf(xendev, 1, "init() failed\n");
        return rc;
    }

    xenstore_write_be_str(xendev, "hotplug-status", "connected");
    xen_be_set_state(xendev, XenbusStateInitWait);
    return 0;
}

/*
 * Try to initialise xendev.  Depends on the frontend being ready
 * for it (shared ring and evtchn info in xenstore, state being
 * Initialised or Connected).
 *
 * Goes to Connected on success.
 */
static int xen_be_try_initialise(struct XenDevice *xendev)
{
    int rc = 0;

    if (xendev->fe_state != XenbusStateInitialised  &&
        xendev->fe_state != XenbusStateConnected) {
        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
            xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
        } else {
            xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
            return -1;
        }
    }

    if (xendev->ops->initialise) {
        rc = xendev->ops->initialise(xendev);
    }
    if (rc != 0) {
        xen_be_printf(xendev, 0, "initialise() failed\n");
        return rc;
    }

    xen_be_set_state(xendev, XenbusStateConnected);
    return 0;
}

/*
 * Try to let xendev know that it is connected.  Depends on the
 * frontend being Connected.  Note that this may be called more
 * than once since the backend state is not modified.
 */
static void xen_be_try_connected(struct XenDevice *xendev)
{
    if (!xendev->ops->connected) {
        return;
    }

    if (xendev->fe_state != XenbusStateConnected) {
        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
            xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
        } else {
            xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
            return;
        }
    }

    xendev->ops->connected(xendev);
}

/*
 * Teardown connection.
 *
 * Goes to Closed when done.
 */
static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
{
    if (xendev->be_state != XenbusStateClosing &&
        xendev->be_state != XenbusStateClosed  &&
        xendev->ops->disconnect) {
        xendev->ops->disconnect(xendev);
    }
    if (xendev->be_state != state) {
        xen_be_set_state(xendev, state);
    }
}

/*
 * Try to reset xendev, for reconnection by another frontend instance.
 */
static int xen_be_try_reset(struct XenDevice *xendev)
{
    if (xendev->fe_state != XenbusStateInitialising) {
        return -1;
    }

    xen_be_printf(xendev, 1, "device reset (for re-connect)\n");
    xen_be_set_state(xendev, XenbusStateInitialising);
    return 0;
}

/*
 * state change dispatcher function
 */
void xen_be_check_state(struct XenDevice *xendev)
{
    int rc = 0;

    /* frontend may request shutdown from almost anywhere */
    if (xendev->fe_state == XenbusStateClosing ||
        xendev->fe_state == XenbusStateClosed) {
        xen_be_disconnect(xendev, xendev->fe_state);
        return;
    }

    /* check for possible backend state transitions */
    for (;;) {
        switch (xendev->be_state) {
        case XenbusStateUnknown:
            rc = xen_be_try_setup(xendev);
            break;
        case XenbusStateInitialising:
            rc = xen_be_try_init(xendev);
            break;
        case XenbusStateInitWait:
            rc = xen_be_try_initialise(xendev);
            break;
        case XenbusStateConnected:
            /* xendev->be_state doesn't change */
            xen_be_try_connected(xendev);
            rc = -1;
            break;
        case XenbusStateClosed:
            rc = xen_be_try_reset(xendev);
            break;
        default:
            rc = -1;
        }
        if (rc != 0) {
            break;
        }
    }
}

/* ------------------------------------------------------------- */

static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
{
    struct XenDevice *xendev;
    char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
    char **dev = NULL, *dom0;
    unsigned int cdev, j;

    /* setup watch */
    dom0 = xs_get_domain_path(xenstore, 0);
    snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
    snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
    free(dom0);
    if (!xs_watch(xenstore, path, token)) {
        xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
        return -1;
    }

    /* look for backends */
    dev = xs_directory(xenstore, 0, path, &cdev);
    if (!dev) {
        return 0;
    }
    for (j = 0; j < cdev; j++) {
        xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
        if (xendev == NULL) {
            continue;
        }
        xen_be_check_state(xendev);
    }
    free(dev);
    return 0;
}

static void xenstore_update_be(char *watch, char *type, int dom,
                               struct XenDevOps *ops)
{
    struct XenDevice *xendev;
    char path[XEN_BUFSIZE], *dom0, *bepath;
    unsigned int len, dev;

    dom0 = xs_get_domain_path(xenstore, 0);
    len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
    free(dom0);
    if (strncmp(path, watch, len) != 0) {
        return;
    }
    if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
        strcpy(path, "");
        if (sscanf(watch+len, "/%u", &dev) != 1) {
            dev = -1;
        }
    }
    if (dev == -1) {
        return;
    }

    xendev = xen_be_get_xendev(type, dom, dev, ops);
    if (xendev != NULL) {
        bepath = xs_read(xenstore, 0, xendev->be, &len);
        if (bepath == NULL) {
            xen_be_del_xendev(dom, dev);
        } else {
            free(bepath);
            xen_be_backend_changed(xendev, path);
            xen_be_check_state(xendev);
        }
    }
}

static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
{
    char *node;
    unsigned int len;

    len = strlen(xendev->fe);
    if (strncmp(xendev->fe, watch, len) != 0) {
        return;
    }
    if (watch[len] != '/') {
        return;
    }
    node = watch + len + 1;

    xen_be_frontend_changed(xendev, node);
    xen_be_check_state(xendev);
}

static void xenstore_update(void *unused)
{
    char **vec = NULL;
    intptr_t type, ops, ptr;
    unsigned int dom, count;

    vec = xs_read_watch(xenstore, &count);
    if (vec == NULL) {
        goto cleanup;
    }

    if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
               &type, &dom, &ops) == 3) {
        xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
    }
    if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
        xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
    }

cleanup:
    free(vec);
}

static void xen_be_evtchn_event(void *opaque)
{
    struct XenDevice *xendev = opaque;
    evtchn_port_t port;

    port = xc_evtchn_pending(xendev->evtchndev);
    if (port != xendev->local_port) {
        xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
                      port, xendev->local_port);
        return;
    }
    xc_evtchn_unmask(xendev->evtchndev, port);

    if (xendev->ops->event) {
        xendev->ops->event(xendev);
    }
}

/* -------------------------------------------------------------------- */

int xen_be_init(void)
{
    xenstore = xs_daemon_open();
    if (!xenstore) {
        xen_be_printf(NULL, 0, "can't connect to xenstored\n");
        return -1;
    }

    if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) {
        goto err;
    }

    if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
        /* Check if xen_init() have been called */
        goto err;
    }
    return 0;

err:
    qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
    xs_daemon_close(xenstore);
    xenstore = NULL;

    return -1;
}

int xen_be_register(const char *type, struct XenDevOps *ops)
{
    return xenstore_scan(type, xen_domid, ops);
}

int xen_be_bind_evtchn(struct XenDevice *xendev)
{
    if (xendev->local_port != -1) {
        return 0;
    }
    xendev->local_port = xc_evtchn_bind_interdomain
        (xendev->evtchndev, xendev->dom, xendev->remote_port);
    if (xendev->local_port == -1) {
        xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n");
        return -1;
    }
    xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
    qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev),
                        xen_be_evtchn_event, NULL, xendev);
    return 0;
}

void xen_be_unbind_evtchn(struct XenDevice *xendev)
{
    if (xendev->local_port == -1) {
        return;
    }
    qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
    xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
    xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
    xendev->local_port = -1;
}

int xen_be_send_notify(struct XenDevice *xendev)
{
    return xc_evtchn_notify(xendev->evtchndev, xendev->local_port);
}

/*
 * msg_level:
 *  0 == errors (stderr + logfile).
 *  1 == informative debug messages (logfile only).
 *  2 == noisy debug messages (logfile only).
 *  3 == will flood your log (logfile only).
 */
void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
{
    va_list args;

    if (xendev) {
        if (msg_level > xendev->debug) {
            return;
        }
        qemu_log("xen be: %s: ", xendev->name);
        if (msg_level == 0) {
            fprintf(stderr, "xen be: %s: ", xendev->name);
        }
    } else {
        if (msg_level > debug) {
            return;
        }
        qemu_log("xen be core: ");
        if (msg_level == 0) {
            fprintf(stderr, "xen be core: ");
        }
    }
    va_start(args, fmt);
    qemu_log_vprintf(fmt, args);
    va_end(args);
    if (msg_level == 0) {
        va_start(args, fmt);
        vfprintf(stderr, fmt, args);
        va_end(args);
    }
    qemu_log_flush();
}
