diff --git a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c index 76bfab82e6..32f8de5bff 100644 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c @@ -419,10 +419,9 @@ static struct file_operations evtchn_fops = { }; 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 --git a/linux-2.6-xen-sparse/include/xen/public/evtchn.h b/linux-2.6-xen-sparse/include/xen/public/evtchn.h index 99e2948240..938d4da2bd 100644 --- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h +++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h @@ -33,9 +33,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. * Return allocated port. diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c index c803b9a827..a70307a542 100644 --- a/tools/libxc/xc_linux.c +++ b/tools/libxc/xc_linux.c @@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall) (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; + + /* /class///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 --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 0a5cfadd3d..d74c1c8c27 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -91,6 +91,16 @@ int xc_interface_open(void); */ 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 */