lkml.org 
[lkml]   [2017]   [Jun]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 04/18] xen/pvcalls: xenbus state handling
    Date
    Introduce the code to handle xenbus state changes.

    Implement the probe function for the pvcalls backend. Write the
    supported versions, max-page-order and function-calls nodes to xenstore,
    as required by the protocol.

    Introduce stub functions for disconnecting/connecting to a frontend.

    Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
    Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
    CC: boris.ostrovsky@oracle.com
    CC: jgross@suse.com
    ---
    drivers/xen/pvcalls-back.c | 152 +++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 152 insertions(+)

    diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c
    index 9044cf2..7bce750 100644
    --- a/drivers/xen/pvcalls-back.c
    +++ b/drivers/xen/pvcalls-back.c
    @@ -25,20 +25,172 @@
    #include <xen/xenbus.h>
    #include <xen/interface/io/pvcalls.h>

    +#define PVCALLS_VERSIONS "1"
    +#define MAX_RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
    +
    struct pvcalls_back_global {
    struct list_head frontends;
    struct semaphore frontends_lock;
    } pvcalls_back_global;

    +static int backend_connect(struct xenbus_device *dev)
    +{
    + return 0;
    +}
    +
    +static int backend_disconnect(struct xenbus_device *dev)
    +{
    + return 0;
    +}
    +
    static int pvcalls_back_probe(struct xenbus_device *dev,
    const struct xenbus_device_id *id)
    {
    + int err, abort;
    + struct xenbus_transaction xbt;
    +
    +again:
    + abort = 1;
    +
    + err = xenbus_transaction_start(&xbt);
    + if (err) {
    + pr_warn("%s cannot create xenstore transaction\n", __func__);
    + return err;
    + }
    +
    + err = xenbus_printf(xbt, dev->nodename, "versions", "%s",
    + PVCALLS_VERSIONS);
    + if (err) {
    + pr_warn("%s write out 'version' failed\n", __func__);
    + goto abort;
    + }
    +
    + err = xenbus_printf(xbt, dev->nodename, "max-page-order", "%u",
    + MAX_RING_ORDER);
    + if (err) {
    + pr_warn("%s write out 'max-page-order' failed\n", __func__);
    + goto abort;
    + }
    +
    + err = xenbus_printf(xbt, dev->nodename, "function-calls",
    + XENBUS_FUNCTIONS_CALLS);
    + if (err) {
    + pr_warn("%s write out 'function-calls' failed\n", __func__);
    + goto abort;
    + }
    +
    + abort = 0;
    +abort:
    + err = xenbus_transaction_end(xbt, abort);
    + if (err) {
    + if (err == -EAGAIN && !abort)
    + goto again;
    + pr_warn("%s cannot complete xenstore transaction\n", __func__);
    + return err;
    + }
    +
    + xenbus_switch_state(dev, XenbusStateInitWait);
    +
    return 0;
    }

    +static void set_backend_state(struct xenbus_device *dev,
    + enum xenbus_state state)
    +{
    + while (dev->state != state) {
    + switch (dev->state) {
    + case XenbusStateClosed:
    + switch (state) {
    + case XenbusStateInitWait:
    + case XenbusStateConnected:
    + xenbus_switch_state(dev, XenbusStateInitWait);
    + break;
    + case XenbusStateClosing:
    + xenbus_switch_state(dev, XenbusStateClosing);
    + break;
    + default:
    + __WARN();
    + }
    + break;
    + case XenbusStateInitWait:
    + case XenbusStateInitialised:
    + switch (state) {
    + case XenbusStateConnected:
    + backend_connect(dev);
    + xenbus_switch_state(dev, XenbusStateConnected);
    + break;
    + case XenbusStateClosing:
    + case XenbusStateClosed:
    + xenbus_switch_state(dev, XenbusStateClosing);
    + break;
    + default:
    + __WARN();
    + }
    + break;
    + case XenbusStateConnected:
    + switch (state) {
    + case XenbusStateInitWait:
    + case XenbusStateClosing:
    + case XenbusStateClosed:
    + down(&pvcalls_back_global.frontends_lock);
    + backend_disconnect(dev);
    + up(&pvcalls_back_global.frontends_lock);
    + xenbus_switch_state(dev, XenbusStateClosing);
    + break;
    + default:
    + __WARN();
    + }
    + break;
    + case XenbusStateClosing:
    + switch (state) {
    + case XenbusStateInitWait:
    + case XenbusStateConnected:
    + case XenbusStateClosed:
    + xenbus_switch_state(dev, XenbusStateClosed);
    + break;
    + default:
    + __WARN();
    + }
    + break;
    + default:
    + __WARN();
    + }
    + }
    +}
    +
    static void pvcalls_back_changed(struct xenbus_device *dev,
    enum xenbus_state frontend_state)
    {
    + switch (frontend_state) {
    + case XenbusStateInitialising:
    + set_backend_state(dev, XenbusStateInitWait);
    + break;
    +
    + case XenbusStateInitialised:
    + case XenbusStateConnected:
    + set_backend_state(dev, XenbusStateConnected);
    + break;
    +
    + case XenbusStateClosing:
    + set_backend_state(dev, XenbusStateClosing);
    + break;
    +
    + case XenbusStateClosed:
    + set_backend_state(dev, XenbusStateClosed);
    + if (xenbus_dev_is_online(dev))
    + break;
    + device_unregister(&dev->dev);
    + break;
    + case XenbusStateUnknown:
    + set_backend_state(dev, XenbusStateClosed);
    + device_unregister(&dev->dev);
    + break;
    +
    + default:
    + xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
    + frontend_state);
    + break;
    + }
    }

    static int pvcalls_back_remove(struct xenbus_device *dev)
    --
    1.9.1
    \
     
     \ /
      Last update: 2017-06-15 21:12    [W:3.287 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site