aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_linux.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-06-01 07:04:35 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-06-01 07:04:35 +0100
commitf6a50a21e5b9819494fa24f9778bb422e27b3e69 (patch)
treecdcb8559f90456cc0421acd413d98a3a7c7f22ed /tools/libxc/xc_linux.c
parent0b086b2583584fe0f8313250bc436164f937fd35 (diff)
downloadxen-f6a50a21e5b9819494fa24f9778bb422e27b3e69.tar.gz
xen-f6a50a21e5b9819494fa24f9778bb422e27b3e69.tar.bz2
xen-f6a50a21e5b9819494fa24f9778bb422e27b3e69.zip
xc: deal with xen/evtchn and xen/gntdev device names
This patch makes xc_linux properly deal with: 1. discovering and creating device nodes if necessary 2. the new form of xen/<dev> device names soon to be used by the kernel This changes the logic slightly: - If a device node already exists with the proper name, then it uses it as-is, assuming it has already been correctly created. - If the path doesn't exist, or it exists but isn't a device node, and it has successfully found the major/minor for the device, then (re)create the device node. Since this logic is identical for gntdev and evtchn, make a common function to handle both. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'tools/libxc/xc_linux.c')
-rw-r--r--tools/libxc/xc_linux.c92
1 files changed, 49 insertions, 43 deletions
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c
index 4df8e58e5b..4c1498f2ae 100644
--- a/tools/libxc/xc_linux.c
+++ b/tools/libxc/xc_linux.c
@@ -378,35 +378,66 @@ int xc_find_device_number(const char *name)
return makedev(major, minor);
}
-#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
+#define DEVXEN "/dev/xen"
-int xc_evtchn_open(void)
+static int make_dev_xen(void)
+{
+ if ( mkdir(DEVXEN, 0755) != 0 )
+ {
+ struct stat st;
+ if ( (stat(DEVXEN, &st) != 0) || !S_ISDIR(st.st_mode) )
+ return -1;
+ }
+
+ return 0;
+}
+
+static int xendev_open(const char *dev)
{
+ int fd, devnum;
struct stat st;
- int fd;
- int devnum;
+ char *devname, *devpath;
- devnum = xc_find_device_number("evtchn");
+ devname = devpath = NULL;
+ fd = -1;
- /* 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 != devnum) )
- (void)unlink(EVTCHN_DEV_NAME);
+ if ( asprintf(&devname, "xen!%s", dev) == 0 )
+ goto fail;
- 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, devnum) == 0) )
- goto reopen;
+ if ( asprintf(&devpath, "%s/%s", DEVXEN, dev) == 0 )
+ goto fail;
- return -1;
+ devnum = xc_find_device_number(dev);
+ if ( devnum == -1 )
+ devnum = xc_find_device_number(devname);
+
+ /*
+ * If we know what the correct device is and the path doesn't exist or
+ * isn't a device, then remove it so we can create the device.
+ */
+ if ( (devnum != -1) &&
+ ((stat(devpath, &st) != 0) || !S_ISCHR(st.st_mode)) )
+ {
+ unlink(devpath);
+ if ( (make_dev_xen() == -1) ||
+ (mknod(devpath, S_IFCHR|0600, devnum) != 0) )
+ goto fail;
}
+ fd = open(devpath, O_RDWR);
+
+ fail:
+ free(devname);
+ free(devpath);
+
return fd;
}
+int xc_evtchn_open(void)
+{
+ return xendev_open("evtchn");
+}
+
int xc_evtchn_close(int xce_handle)
{
return close(xce_handle);
@@ -518,34 +549,9 @@ void discard_file_cache(xc_interface *xch, int fd, int flush)
errno = saved_errno;
}
-#define GNTTAB_DEV_NAME "/dev/xen/gntdev"
-
int xc_gnttab_open(xc_interface *xch)
{
- struct stat st;
- int fd;
- int devnum;
-
- devnum = xc_find_device_number("gntdev");
-
- /* Make sure any existing device file links to correct device. */
- if ( (lstat(GNTTAB_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
- (st.st_rdev != devnum) )
- (void)unlink(GNTTAB_DEV_NAME);
-
-reopen:
- if ( (fd = open(GNTTAB_DEV_NAME, O_RDWR)) == -1 )
- {
- if ( (errno == ENOENT) &&
- ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
- (mknod(GNTTAB_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
- goto reopen;
-
- PERROR("Could not open grant table interface");
- return -1;
- }
-
- return fd;
+ return xendev_open("gntdev");
}
int xc_gnttab_close(xc_interface *xch, int xcg_handle)