Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/arch/xen/xenbus Pull up following revision(s) (reques...



details:   https://anonhg.NetBSD.org/src/rev/6aef7f9b5f4d
branches:  netbsd-6
changeset: 774195:6aef7f9b5f4d
user:      riz <riz%NetBSD.org@localhost>
date:      Tue Jun 12 18:30:50 2012 +0000

description:
Pull up following revision(s) (requested by sborrill in ticket #313):
        sys/arch/xen/xenbus/xenbus_probe.c: revision 1.36
        sys/arch/xen/xenbus/xenbus_probe.c: revision 1.37
Sort vif and vbd device IDs numerically so that attach order does not depend
on the order they are passed in through xenstore. While this works for
hand-crafted Xen configuration files, it does not work for XenServer, XCP or
EC2 instances. This means that adding an extra virtual disk can make the
domU unbootable.
ID is actually based on the Linux device major/minor so this approach isn't
entirely correct (for instance, you can specify devices to be non-contiguous
which doesn't fit too well with our autoconf approach), but it works as a
first approximation.
Tested by me on XenServer and riz@ on EC2. OK bouyer@
Fix problem where devices with ID 0 were skipped as invalid as it didn't
distinguish between numerical zero and invalid numeric string.

diffstat:

 sys/arch/xen/xenbus/xenbus_probe.c |  66 +++++++++++++++++++++++++++++++++++--
 1 files changed, 62 insertions(+), 4 deletions(-)

diffs (102 lines):

diff -r 4e5c0ce397b6 -r 6aef7f9b5f4d sys/arch/xen/xenbus/xenbus_probe.c
--- a/sys/arch/xen/xenbus/xenbus_probe.c        Tue Jun 12 18:25:10 2012 +0000
+++ b/sys/arch/xen/xenbus/xenbus_probe.c        Tue Jun 12 18:30:50 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xenbus_probe.c,v 1.35 2011/09/22 23:02:35 jym Exp $ */
+/* $NetBSD: xenbus_probe.c,v 1.35.8.1 2012/06/12 18:30:50 riz Exp $ */
 /******************************************************************************
  * Talks to Xen Store to figure out what devices we have.
  *
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenbus_probe.c,v 1.35 2011/09/22 23:02:35 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenbus_probe.c,v 1.35.8.1 2012/06/12 18:30:50 riz Exp $");
 
 #if 0
 #define DPRINTK(fmt, args...) \
@@ -321,7 +321,8 @@
 xenbus_probe_device_type(const char *path, const char *type,
     int (*create)(struct xenbus_device *))
 {
-       int err, i, msize;
+       int err, i, pos, msize;
+       int *lookup = NULL;
        unsigned long state;
        char **dir;
        unsigned int dir_n = 0;
@@ -335,8 +336,62 @@
        if (err)
                return err;
 
-       for (i = 0; i < dir_n; i++) {
+       /* Only sort frontend devices i.e. create == NULL*/
+       if (dir_n > 1 && create == NULL) {
+               int minp;
+               unsigned long minv;
+               unsigned long *id;
+
+               lookup = malloc(sizeof(int) * dir_n, M_DEVBUF,
+                   M_WAITOK | M_ZERO);
+               if (lookup == NULL)
+                       panic("can't malloc lookup");
+
+               id = malloc(sizeof(unsigned long) * dir_n, M_DEVBUF,
+                   M_WAITOK | M_ZERO);
+               if (id == NULL)
+                       panic("can't malloc id");
+
+               /* Convert string values to numeric; skip invalid */
+               for (i = 0; i < dir_n; i++) {
+                       /*
+                        * Add one to differentiate numerical zero from invalid
+                        * string. Has no effect on sort order.
+                        */
+                       id[i] = strtoul(dir[i], &ep, 10) + 1;
+                       if (dir[i][0] == '\0' || *ep != '\0')
+                               id[i] = 0;
+               }
+               
+               /* Build lookup table in ascending order */
+               for (pos = 0; pos < dir_n; ) {
+                       minv = UINT32_MAX;
+                       minp = -1;
+                       for (i = 0; i < dir_n; i++) {
+                               if (id[i] < minv && id[i] > 0) {
+                                       minv = id[i];
+                                       minp = i;
+                               }
+                       }
+                       if (minp >= 0) {
+                               lookup[pos++] = minp;
+                               id[minp] = 0;
+                       }
+                       else
+                               break;
+               }
+               
+               free(id, M_DEVBUF);
+               /* Adjust in case we had to skip non-numeric entries */
+               dir_n = pos;
+       }
+
+       for (pos = 0; pos < dir_n; pos++) {
                err = 0;
+               if (lookup)
+                       i = lookup[pos];
+               else
+                       i = pos;
                /*
                 * add size of path to size of xenbus_device. xenbus_device
                 * already has room for one char in xbusd_path.
@@ -413,6 +468,9 @@
                watch_otherend(xbusd);
        }
        free(dir, M_DEVBUF);
+       if (lookup)
+               free(lookup, M_DEVBUF);
+       
        return err;
 }
 



Home | Main Index | Thread Index | Old Index