/*
 *  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/>.
 */

/*
 * 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 */
int xen_xc;
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 qemu_free() stuff. */
        ret = qemu_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;
    qemu_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 = qemu_mallocz(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 = xc_evtchn_open();
    if (xendev->evtchndev < 0) {
	xen_be_printf(NULL, 0, "can't open evtchn device\n");
	qemu_free(xendev);
	return NULL;
    }
    fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);

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

    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);
	    qemu_free(xendev->fe);
	}

	if (xendev->evtchndev >= 0)
	    xc_evtchn_close(xendev->evtchndev);
	if (xendev->gnttabdev >= 0)
	    xc_gnttab_close(xendev->gnttabdev);

	QTAILQ_REMOVE(&xendevs, xendev, next);
	qemu_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) {
	qemu_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 connect 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_connect(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->connect)
	rc = xendev->ops->connect(xendev);
    if (rc != 0) {
	xen_be_printf(xendev, 0, "connect() failed\n");
	return rc;
    }

    xen_be_set_state(xendev, XenbusStateConnected);
    return 0;
}

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

    if (0) {
	/* FIXME: detect devices being deleted from xenstore ... */
	xen_be_del_xendev(dom, dev);
    }

    xendev = xen_be_get_xendev(type, dom, dev, ops);
    if (xendev != NULL) {
	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;

    xen_xc = xc_interface_open();
    if (xen_xc == -1) {
	xen_be_printf(NULL, 0, "can't open xen interface\n");
	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();
}
