WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Switch block device setup/teardown over to xenbus/xensto

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Switch block device setup/teardown over to xenbus/xenstore.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 19 Aug 2005 08:22:13 -0400
Delivery-date: Fri, 19 Aug 2005 12:22:54 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID b399599f2ff83fe438c66f23bb1eb8490f55a0b1
# Parent  2d7a9bae9814bae5151c9a7823fbaf3dfbd37fa2
Switch block device setup/teardown over to xenbus/xenstore.
Remove device probing support over the device channel.
g/c all the control message code.
Simplify and cleanup internal function calling code (explicit arguments
instead of passing structs around).
Also includes:
Changed "readonly" to "read-only". "backend" is still not hyphenated, but
that seems to be fairly common usage.
Block backends use xenbus_dev_error, making debugging nicer.
The block front end is told explicitly what domid to use to talk to the
backend. There's speculation that fake domid-like tokens may be given
for cluster purposes in future, so deriving from the backend dir name is
not guaranteed to work. Backends still derive front-end ids, using a
xenbus helper (xenbus_uuid_to_domid).
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 2d7a9bae9814 -r b399599f2ff8 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- /dev/null   Fri Aug 19 10:59:47 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Aug 19 12:13:31 2005
@@ -0,0 +1,309 @@
+/*  Xenbus code for blkif backend
+    Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
+
+    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; either version 2 of the License, or
+    (at your option) any later version.
+
+    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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdarg.h>
+#include <linux/module.h>
+#include <asm-xen/xenbus.h>
+#include "common.h"
+
+struct backend_info
+{
+       struct xenbus_device *dev;
+
+       /* our communications channel */
+       blkif_t *blkif;
+       struct vbd *vbd;
+
+       long int frontend_id;
+       long int pdev;
+       long int readonly;
+
+       /* watch back end for changes */
+       struct xenbus_watch backend_watch;
+
+       /* watch front end for changes */
+       struct xenbus_watch watch;
+       char *frontpath;
+};
+
+static int blkback_remove(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev->data;
+
+       unregister_xenbus_watch(&be->watch);
+       unregister_xenbus_watch(&be->backend_watch);
+       vbd_free(be->blkif, be->vbd);
+       blkif_put(be->blkif);
+       kfree(be->frontpath);
+       kfree(be);
+       return 0;
+}
+
+/* Front end tells us frame. */
+static void frontend_changed(struct xenbus_watch *watch, const char *node)
+{
+       unsigned long sharedmfn;
+       unsigned int evtchn;
+       int err;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, watch);
+
+       // printk("Got front end event on %s (%s)\n", node, be->frontpath);
+
+       if (vbd_is_active(be->vbd)) {
+               /* If other end is gone, delete ourself. */
+               if (!xenbus_exists(be->frontpath, "")) {
+                       // printk("Removing...\n");
+                       xenbus_rm(be->dev->nodename, "");
+                       device_unregister(&be->dev->dev);
+               }
+               return;
+       }
+
+#ifndef CONFIG_XEN_BLKDEV_GRANT
+       err = xenbus_gather(be->frontpath, "shared-frame", "%lu", &sharedmfn,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err, 
+                                "reading %s/shared-frame and event-channel",
+                                be->frontpath);
+               return;
+       }
+#else
+       err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err, 
+                                "reading %s/grant-id and event-channel",
+                                be->frontpath);
+               return;
+       }
+#endif
+
+       /* Domains must use same shared frame for all vbds. */
+       if (be->blkif->status == CONNECTED &&
+           (evtchn != be->blkif->remote_evtchn ||
+            sharedmfn != be->blkif->shmem_frame)) {
+               xenbus_dev_error(be->dev, err,
+                                "Shared frame/evtchn %li/%u not same as"
+                                " old %li/%u",
+                                sharedmfn, evtchn,
+                                be->blkif->shmem_frame,
+                                be->blkif->remote_evtchn);
+               return;
+       }
+
+       /* Supply the information about the device the frontend needs */
+       err = xenbus_transaction_start(be->dev->nodename);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "starting transaction");
+               return;
+       }
+
+       err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
+                           vbd_size(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sectors",
+                                be->dev->nodename);
+               goto abort;
+       }
+
+       /* FIXME: use a typename instead */
+       err = xenbus_printf(be->dev->nodename, "info", "%u",
+                           vbd_info(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/info",
+                                be->dev->nodename);
+               goto abort;
+       }
+       err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
+                           vbd_secsize(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sector-size",
+                                be->dev->nodename);
+               goto abort;
+       }
+
+       /* First vbd?  We need to map the shared frame, irq etc. */
+       if (be->blkif->status != CONNECTED) {
+               err = blkif_map(be->blkif, sharedmfn, evtchn);
+               if (err) {
+                       xenbus_dev_error(be->dev, err,
+                                        "mapping shared-frame %lu port %u",
+                                        sharedmfn, evtchn);
+                       goto abort;
+               }
+       }
+
+       /* We're ready, activate. */
+       vbd_activate(be->blkif, be->vbd);
+
+       xenbus_transaction_end(0);
+       xenbus_dev_ok(be->dev);
+
+       return;
+
+abort:
+       xenbus_transaction_end(1);
+}
+
+/* 
+   Setup supplies physical device.  
+   We provide event channel and device details to front end.
+   Frontend supplies shared frame and event channel.
+ */
+static void backend_changed(struct xenbus_watch *watch, const char *node)
+{
+       int err;
+       char *p;
+       char *frontend;
+       long int handle, pdev;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+
+       err = xenbus_scanf(dev->nodename, "frontend-id", "%li",
+                          &be->frontend_id);
+       if (err == -ENOENT || err == -ERANGE)
+               goto out;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "Reading frontend-id");
+               goto out;
+       }
+
+       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
+       if (err == -ENOENT || err == -ERANGE)
+               goto out;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "Reading physical-device");
+               goto out;
+       }
+       if (be->pdev && be->pdev != pdev) {
+               printk(KERN_WARNING
+                      "changing physical-device not supported\n");
+               return;
+       }
+       be->pdev = pdev;
+
+       frontend = xenbus_read(dev->nodename, "frontend", NULL);
+       if (IS_ERR(frontend))
+               return;
+       if (strlen(frontend) == 0) {
+               kfree(frontend);
+               return;
+       }
+
+       /* If there's a read-only node, we're read only. */
+       p = xenbus_read(dev->nodename, "read-only", NULL);
+       if (!IS_ERR(p)) {
+               be->readonly = 1;
+               kfree(p);
+       }
+
+       if (!be->frontpath || strcmp(frontend, be->frontpath)) {
+               if (be->watch.node)
+                       unregister_xenbus_watch(&be->watch);
+               if (be->frontpath)
+                       kfree(be->frontpath);
+               be->frontpath = frontend;
+               be->watch.node = be->frontpath;
+               be->watch.callback = frontend_changed;
+               err = register_xenbus_watch(&be->watch);
+               if (err)
+                       goto out;
+
+               /* Front end dir is a number, which is used as the handle. */
+               p = strrchr(be->frontpath, '/') + 1;
+               handle = simple_strtoul(p, NULL, 0);
+
+               be->blkif = blkif_find(be->frontend_id);
+               if (IS_ERR(be->blkif)) {
+                       err = PTR_ERR(be->blkif);
+                       be->blkif = NULL;
+                       goto free_watch;
+               }
+
+               be->vbd = vbd_create(be->blkif, handle, be->pdev,
+                                    be->readonly);
+               if (IS_ERR(be->vbd)) {
+                       err = PTR_ERR(be->vbd);
+                       blkif_put(be->blkif);
+                       be->blkif = NULL;
+                       be->vbd = NULL;
+                       goto free_watch;
+               }
+
+               frontend_changed(&be->watch, be->frontpath);
+       } else
+               kfree(frontend);
+
+       return;
+
+ free_watch:
+       unregister_xenbus_watch(&be->watch);
+       be->watch.node = NULL;
+       kfree(be->frontpath);
+       be->frontpath = NULL;
+ out:
+       return;
+}
+
+static int blkback_probe(struct xenbus_device *dev,
+                        const struct xenbus_device_id *id)
+{
+       struct backend_info *be;
+       int err;
+
+       be = kmalloc(sizeof(*be), GFP_KERNEL);
+       if (!be)
+               return -ENOMEM;
+
+       memset(be, 0, sizeof(*be));
+
+       be->dev = dev;
+       be->backend_watch.node = dev->nodename;
+       be->backend_watch.callback = backend_changed;
+       err = register_xenbus_watch(&be->backend_watch);
+       if (err)
+               goto free_be;
+
+       dev->data = be;
+
+       backend_changed(&be->backend_watch, dev->nodename);
+       return err;
+ free_be:
+       kfree(be);
+       return err;
+}
+
+static struct xenbus_device_id blkback_ids[] = {
+       { "vbd" },
+       { "" }
+};
+
+static struct xenbus_driver blkback = {
+       .name = __stringify(KBUILD_MODNAME),
+       .owner = THIS_MODULE,
+       .ids = blkback_ids,
+       .probe = blkback_probe,
+       .remove = blkback_remove,
+};
+
+void blkif_xenbus_init(void)
+{
+       xenbus_register_backend(&blkback);
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>