diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-06-01 07:04:35 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-06-01 07:04:35 +0100 |
commit | f6a50a21e5b9819494fa24f9778bb422e27b3e69 (patch) | |
tree | cdcb8559f90456cc0421acd413d98a3a7c7f22ed /tools/libxc/xc_linux.c | |
parent | 0b086b2583584fe0f8313250bc436164f937fd35 (diff) | |
download | xen-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.c | 92 |
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) |