# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1159536052 -3600
# Node ID 7e79259c2c170eebe111b2c242c2ed9d17fdd4c3
# Parent 477a0084ff47ac99a8fdd0fdf21dca1cb69e7346
[LINUX] Make evtchn device use a dynamic minor number.
Also update the code in tools to create the device node if udev fails.
The tools now read the sysfs system to find the minor number needed.
Original patch from Steven Rostedt <srostedt@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 3
linux-2.6-xen-sparse/include/xen/public/evtchn.h | 3
tools/libxc/xc_linux.c | 82 +++++++++++++++++++++--
tools/libxc/xenctrl.h | 10 ++
4 files changed, 86 insertions(+), 12 deletions(-)
diff -r 477a0084ff47 -r 7e79259c2c17
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Sep 29 11:57:06
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Sep 29 14:20:52
2006 +0100
@@ -419,10 +419,9 @@ static struct file_operations evtchn_fop
};
static struct miscdevice evtchn_miscdev = {
- .minor = EVTCHN_MINOR,
+ .minor = MISC_DYNAMIC_MINOR,
.name = "evtchn",
.fops = &evtchn_fops,
- .devfs_name = "misc/evtchn",
};
static int __init evtchn_init(void)
diff -r 477a0084ff47 -r 7e79259c2c17
linux-2.6-xen-sparse/include/xen/public/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h Fri Sep 29 11:57:06
2006 +0100
+++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h Fri Sep 29 14:20:52
2006 +0100
@@ -32,9 +32,6 @@
#ifndef __LINUX_PUBLIC_EVTCHN_H__
#define __LINUX_PUBLIC_EVTCHN_H__
-
-/* /dev/xen/evtchn resides at device number major=10, minor=201 */
-#define EVTCHN_MINOR 201
/*
* Bind a fresh port to VIRQ @virq.
diff -r 477a0084ff47 -r 7e79259c2c17 tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c Fri Sep 29 11:57:06 2006 +0100
+++ b/tools/libxc/xc_linux.c Fri Sep 29 14:20:52 2006 +0100
@@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, priv
(unsigned long)hypercall);
}
+#define MTAB "/proc/mounts"
+#define MAX_PATH 255
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+static int find_sysfsdir(char *sysfsdir)
+{
+ FILE *fp;
+ char type[MAX_PATH + 1];
+
+ if ( (fp = fopen(MTAB, "r")) == NULL )
+ return -1;
+
+ while ( fscanf(fp, "%*s %"
+ STR(MAX_PATH)
+ "s %"
+ STR(MAX_PATH)
+ "s %*s %*d %*d\n",
+ sysfsdir, type) == 2 )
+ {
+ if ( strncmp(type, "sysfs", 5) == 0 )
+ break;
+ }
+
+ fclose(fp);
+
+ return ((strncmp(type, "sysfs", 5) == 0) ? 0 : -1);
+}
+
+int xc_find_device_number(const char *name)
+{
+ FILE *fp;
+ int i, major, minor;
+ char sysfsdir[MAX_PATH + 1];
+ static char *classlist[] = { "xen", "misc" };
+
+ for ( i = 0; i < (sizeof(classlist) / sizeof(classlist[0])); i++ )
+ {
+ if ( find_sysfsdir(sysfsdir) < 0 )
+ goto not_found;
+
+ /* <base>/class/<classname>/<devname>/dev */
+ strncat(sysfsdir, "/class/", MAX_PATH);
+ strncat(sysfsdir, classlist[i], MAX_PATH);
+ strncat(sysfsdir, "/", MAX_PATH);
+ strncat(sysfsdir, name, MAX_PATH);
+ strncat(sysfsdir, "/dev", MAX_PATH);
+
+ if ( (fp = fopen(sysfsdir, "r")) != NULL )
+ goto found;
+ }
+
+ not_found:
+ errno = -ENOENT;
+ return -1;
+
+ found:
+ if ( fscanf(fp, "%d:%d", &major, &minor) != 2 )
+ {
+ fclose(fp);
+ goto not_found;
+ }
+
+ fclose(fp);
+
+ return makedev(major, minor);
+}
+
#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
-#define EVTCHN_DEV_MAJOR 10
-#define EVTCHN_DEV_MINOR 201
int xc_evtchn_open(void)
{
struct stat st;
int fd;
+ int devnum;
+
+ devnum = xc_find_device_number("evtchn");
/* Make sure any existing device file links to correct device. */
- if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
- (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
+ if ( (lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
+ (st.st_rdev != devnum) )
(void)unlink(EVTCHN_DEV_NAME);
-reopen:
+ reopen:
if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 )
{
if ( (errno == ENOENT) &&
((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
- (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
- makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) )
+ (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
goto reopen;
PERROR("Could not open event channel interface");
diff -r 477a0084ff47 -r 7e79259c2c17 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Fri Sep 29 11:57:06 2006 +0100
+++ b/tools/libxc/xenctrl.h Fri Sep 29 14:20:52 2006 +0100
@@ -92,6 +92,16 @@ int xc_interface_close(int xc_handle);
int xc_interface_close(int xc_handle);
/*
+ * KERNEL INTERFACES
+ */
+
+/*
+ * Resolve a kernel device name (e.g., "evtchn", "blktap0") into a kernel
+ * device number. Returns -1 on error (and sets errno).
+ */
+int xc_find_device_number(const char *name);
+
+/*
* DOMAIN DEBUGGING FUNCTIONS
*/
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|