From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeremy Fitzhardinge Subject: [PATCH] xc: deal with xen/evtchn and xen/gntdev device names Date: Fri, 28 May 2010 18:08:27 -0700 Message-ID: <4C00690B.2020303@goop.org> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Xen-devel Cc: Bastian Blank List-Id: xen-devel@lists.xenproject.org This patch makes xc_linux properly deal with: 1. discovering and creating device nodes if necessary 2. the new form of xen/ 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 diff -r f146aa75120c tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Thu May 27 12:14:32 2010 -0700 +++ b/tools/libxc/xc_linux.c Fri May 28 16:33:11 2010 -0700 @@ -378,34 +378,73 @@ return makedev(major, minor); } -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" +#define DEVXEN "/dev/xen" + +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; + char *devname, *devpath; + + devname = devpath = NULL; + fd = -1; + + if (asprintf(&devname, "xen!%s", dev) == 0) + goto fail; + + if (asprintf(&devpath, "%s/%s", DEVXEN, dev) == 0) + goto fail; + + 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) + goto fail; + + if (mknod(devpath, S_IFCHR|0600, devnum) != 0) { + PERROR("Couldn't make %s", devpath); + goto fail; + } + } + + fd = open(devpath, O_RDWR); + + if (fd == -1) + PERROR("Could not open %s", devpath); + +fail: + free(devname); + free(devpath); + + return fd; +} + 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 != devnum) ) - (void)unlink(EVTCHN_DEV_NAME); - - 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; - - PERROR("Could not open event channel interface"); - return -1; - } - - return fd; + return xendev_open("evtchn"); } int xc_evtchn_close(int xce_handle) @@ -519,34 +558,9 @@ errno = saved_errno; } -#define GNTTAB_DEV_NAME "/dev/xen/gntdev" - int xc_gnttab_open(void) { - 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(int xcg_handle)