[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MINI-OS PATCH 15/19] 9pfs: refactor init_9pfront()



Move the Xenstore and backend interface related handling into a
sub-function in order to prepare supporting reconnecting to an active
9pfs device after kexec.

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
 9pfront.c | 136 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 86 insertions(+), 50 deletions(-)

diff --git a/9pfront.c b/9pfront.c
index 2bfc49b1..8da2f726 100644
--- a/9pfront.c
+++ b/9pfront.c
@@ -1097,68 +1097,65 @@ static void free_9pfront(struct dev_9pfs *dev)
     free(dev);
 }
 
-void *init_9pfront(unsigned int id, const char *mnt)
+static bool issue_err(struct dev_9pfs *dev, char *msg, char *reason)
+{
+    if ( msg )
+    {
+        printk("9pfsfront add %u failed, error %s accessing Xenstore\n",
+               dev->id, msg);
+        free(msg);
+    }
+    else
+        printk("9pfsfront add %u failed, %s\n", dev->id, reason);
+
+    return false;
+}
+
+static bool read_config_xs(struct dev_9pfs *dev)
 {
-    struct dev_9pfs *dev;
     char *msg;
     char *reason = "";
-    xenbus_transaction_t xbt;
-    int retry = 1;
     XenbusState state;
-    unsigned int i;
-    void *addr;
+    xenbus_transaction_t xbt;
     char *version;
     char *v;
-
-    printk("9pfsfront add %u, for mount at %s\n", id, mnt);
-    dev = malloc(sizeof(*dev));
-    memset(dev, 0, sizeof(*dev));
-    snprintf(dev->nodename, sizeof(dev->nodename), "device/9pfs/%u", id);
-    dev->id = id;
-    init_waitqueue_head(&dev->waitq);
-    init_SEMAPHORE(&dev->ring_out_sem, 1);
-    init_SEMAPHORE(&dev->ring_in_sem, 1);
-    dev->fid_mask = ~0ULL;
-
-    for ( i = 0; i < N_REQS; i++ )
-    {
-        dev->req[i].id = i;
-        dev->req[i].next_free = i + 1;
-    }
-    dev->free_reqs = 0;
+    void *addr;
+    unsigned int i;
+    int retry = 1;
 
     msg = xenbus_read_unsigned(XBT_NIL, dev->nodename, "backend-id", 
&dev->dom);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
     msg = xenbus_read_string(XBT_NIL, dev->nodename, "backend", &dev->backend);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
     msg = xenbus_read_string(XBT_NIL, dev->nodename, "tag", &dev->tag);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
 
     snprintf(dev->bepath, sizeof(dev->bepath), "%s/state", dev->backend);
     free(xenbus_watch_path_token(XBT_NIL, dev->bepath, dev->bepath,
                                  &dev->events));
+
     state = xenbus_read_integer(dev->bepath);
     while ( msg == NULL && state < XenbusStateInitWait )
         msg = xenbus_wait_for_state_change(dev->bepath, &state, &dev->events);
     if ( msg || state != XenbusStateInitWait )
     {
         reason = "illegal backend state";
-        goto err;
+        return issue_err(dev, msg, reason);
     }
 
     msg = xenbus_read_unsigned(XBT_NIL, dev->backend, "max-ring-page-order",
                                &dev->ring_order);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
     if ( dev->ring_order > DEFAULT_9PFS_RING_ORDER )
         dev->ring_order = DEFAULT_9PFS_RING_ORDER;
 
     msg = xenbus_read_string(XBT_NIL, dev->backend, "versions", &version);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
     for ( v = version; *v; v++ )
     {
         if ( strtoul(v, &v, 10) == 1 && (*v == ',' || *v == 0) )
@@ -1170,25 +1167,36 @@ void *init_9pfront(unsigned int id, const char *mnt)
         {
             reason = "backend published illegal version string";
             free(version);
-            goto err;
+            return issue_err(dev, msg, reason);
         }
     }
     free(version);
     if ( v )
     {
         reason = "backend doesn't support version 1";
-        goto err;
+        return issue_err(dev, msg, reason);
     }
 
-    dev->ring_ref = gnttab_alloc_and_grant((void **)&dev->intf);
+    dev->intf = (void *)alloc_page();
+    if ( !dev->intf )
+    {
+        reason = "couldn't allocate shared interface page";
+        return issue_err(dev, msg, reason);
+    }
     memset(dev->intf, 0, PAGE_SIZE);
+    dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->intf), 0);
     if ( evtchn_alloc_unbound(dev->dom, intr_9pfs, dev, &dev->evtchn) )
     {
         reason = "no event channel";
-        goto err;
+        return issue_err(dev, msg, reason);
     }
     dev->intf->ring_order = dev->ring_order;
     dev->data.in = (void *)alloc_pages(dev->ring_order);
+    if ( !dev->data.in )
+    {
+        reason = "couldn't allocate ring pages";
+        return issue_err(dev, msg, reason);
+    }
     dev->data.out = dev->data.in + XEN_FLEX_RING_SIZE(dev->ring_order);
     for ( i = 0; i < (1 << dev->ring_order); i++ )
     {
@@ -1204,30 +1212,35 @@ void *init_9pfront(unsigned int id, const char *mnt)
             free(msg);
             msg = NULL;
             reason = "starting transaction";
-            goto err;
+            return issue_err(dev, msg, reason);
         }
 
         msg = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
         if ( msg )
-            goto err_tr;
+            break;
         msg = xenbus_printf(xbt, dev->nodename, "num-rings", "%u", 1);
         if ( msg )
-            goto err_tr;
+            break;
         msg = xenbus_printf(xbt, dev->nodename, "ring-ref0", "%u",
                             dev->ring_ref);
         if ( msg )
-            goto err_tr;
+            break;
         msg = xenbus_printf(xbt, dev->nodename, "event-channel-0", "%u",
                             dev->evtchn);
         if ( msg )
-            goto err_tr;
+            break;
         msg = xenbus_printf(xbt, dev->nodename, "state", "%u",
                             XenbusStateInitialised);
         if ( msg )
-            goto err_tr;
+            break;
 
         free(xenbus_transaction_end(xbt, 0, &retry));
     }
+    if ( msg )
+    {
+        free(xenbus_transaction_end(xbt, 1, &retry));
+        return issue_err(dev, msg, reason);
+    }
 
     state = xenbus_read_integer(dev->bepath);
     while ( msg == NULL && state < XenbusStateConnected )
@@ -1235,13 +1248,42 @@ void *init_9pfront(unsigned int id, const char *mnt)
     if ( msg || state != XenbusStateConnected )
     {
         reason = "illegal backend state";
-        goto err;
+        return issue_err(dev, msg, reason);
     }
 
     msg = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u",
                         XenbusStateConnected);
     if ( msg )
-        goto err;
+        return issue_err(dev, msg, reason);
+
+    return true;
+}
+
+void *init_9pfront(unsigned int id, const char *mnt)
+{
+    struct dev_9pfs *dev;
+    char *reason = "";
+    unsigned int i;
+
+    printk("9pfsfront add %u, for mount at %s\n", id, mnt);
+    dev = malloc(sizeof(*dev));
+    memset(dev, 0, sizeof(*dev));
+    snprintf(dev->nodename, sizeof(dev->nodename), "device/9pfs/%u", id);
+    dev->id = id;
+    init_waitqueue_head(&dev->waitq);
+    init_SEMAPHORE(&dev->ring_out_sem, 1);
+    init_SEMAPHORE(&dev->ring_in_sem, 1);
+    dev->fid_mask = ~0ULL;
+
+    for ( i = 0; i < N_REQS; i++ )
+    {
+        dev->req[i].id = i;
+        dev->req[i].next_free = i + 1;
+    }
+    dev->free_reqs = 0;
+
+    if ( !read_config_xs(dev) )
+        goto err_out;
 
     unmask_evtchn(dev->evtchn);
 
@@ -1260,17 +1302,11 @@ void *init_9pfront(unsigned int id, const char *mnt)
 
     return dev;
 
- err_tr:
-    free(xenbus_transaction_end(xbt, 1, &retry));
-
  err:
-    if ( msg )
-        printk("9pfsfront add %u failed, error %s accessing Xenstore\n",
-               id, msg);
-    else
-        printk("9pfsfront add %u failed, %s\n", id, reason);
+    printk("9pfsfront add %u failed, %s\n", id, reason);
+
+ err_out:
     free_9pfront(dev);
-    free(msg);
     return NULL;
 }
 EXPORT_SYMBOL(init_9pfront);
-- 
2.43.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.