[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@redhat.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-09-29 14:20:52 +01:00
1 parent 448496a5e2
commit ada55182d2
4 files changed
+86 -12

No files matched your search

@@ -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)
@@ -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.
+75 -7
View File
@@ -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;
/* <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");
+10
View File
@@ -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
*/
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.