Bastian Blank
2011-Dec-15 10:41 UTC
[PATCH 1/2] xenstored: Use xenbus_backend device on Linux
xenstored: Use xenbus_backend device on Linux This patch is done on top of 4.1 for now. The kernel part is already merged. diff -r 1c89f7d29fbb tools/include/xen-sys/Linux/xenbus_dev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/include/xen-sys/Linux/xenbus_dev.h Sat Dec 10 19:38:54 2011 +0100 @@ -0,0 +1,41 @@ +/****************************************************************************** + * evtchn.h + * + * Interface to /dev/xen/xenbus_backend. + * + * Copyright (c) 2011 Bastian Blank <waldi@debian.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __LINUX_XEN_XENBUS_DEV_H__ +#define __LINUX_XEN_XENBUS_DEV_H__ + +#include <linux/ioctl.h> + +#define IOCTL_XENBUS_BACKEND_EVTCHN \ + _IOC(_IOC_NONE, ''B'', 0, 0) + +#endif /* __LINUX_XEN_XENBUS_DEV_H__ */ diff -r 1c89f7d29fbb tools/xenstore/xenstored_linux.c --- a/tools/xenstore/xenstored_linux.c Thu Dec 08 16:50:28 2011 +0000 +++ b/tools/xenstore/xenstored_linux.c Sat Dec 10 19:38:54 2011 +0100 @@ -11,17 +11,22 @@ * License. */ +#include <errno.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> +#include <sys/ioctl.h> #include <sys/mman.h> +#include <xen/sys/xenbus_dev.h> + #include "xenstored_core.h" +#define XENSTORED_DEV "/dev/xen/xenbus_backend" #define XENSTORED_PROC_KVA "/proc/xen/xsd_kva" #define XENSTORED_PROC_PORT "/proc/xen/xsd_port" -evtchn_port_t xenbus_evtchn(void) +static evtchn_port_t xenbus_proc_evtchn(void) { int fd; int rc; @@ -48,12 +53,35 @@ return port; } +evtchn_port_t xenbus_evtchn(void) +{ + int fd; + long ret; + + fd = open(XENSTORED_DEV, O_RDONLY); + if (fd == -1) + { + if (errno == ENOENT) + return xenbus_proc_evtchn(); + return -1; + } + + ret = ioctl(fd, IOCTL_XENBUS_BACKEND_EVTCHN); + if (ret == -1) + return -1; + + close(fd); + return ret; +} + void *xenbus_map(void) { int fd; void *addr; - fd = open(XENSTORED_PROC_KVA, O_RDWR); + fd = open(XENSTORED_DEV, O_RDWR); + if (fd == -1 && errno == ENOENT) + fd = open(XENSTORED_PROC_KVA, O_RDWR); if (fd == -1) return NULL; -- Killing is wrong. -- Losira, "That Which Survives", stardate unknown
Ian Campbell
2011-Dec-15 17:07 UTC
Re: [PATCH 1/2] xenstored: Use xenbus_backend device on Linux
On Thu, 2011-12-15 at 10:41 +0000, Bastian Blank wrote:> xenstored: Use xenbus_backend device on Linux > > This patch is done on top of 4.1 for now. The kernel part is already > merged.It compiles and builds on unstable too. I didn''t try it but since this stuff rarely changes I don''t see why it wouldn''t work just as well there too.> diff -r 1c89f7d29fbb tools/xenstore/xenstored_linux.c > --- a/tools/xenstore/xenstored_linux.c Thu Dec 08 16:50:28 2011 +0000 > +++ b/tools/xenstore/xenstored_linux.c Sat Dec 10 19:38:54 2011 +0100We need to make a similar change to tools/ocaml/xenstored/domains.ml:create0 which is tricky since you can''t make an ioctl call from pure ocaml so a C binding is needed. However we already have a low-level library (libxenctrl) which abstracts these sorts of low level differences across platforms and which has existing language bindings so reimplementing this stuff multiple times in multiple languages seems a bit sub-optimal when we could just write it once and extend the language bindings to cover the new functionality. The following doesn''t implement non-Linux or the ocaml side yet but it gives the gist of what I''m thinking. Ian. diff -r 0c92f4561443 tools/libxc/xc_linux_osdep.c --- a/tools/libxc/xc_linux_osdep.c Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/libxc/xc_linux_osdep.c Thu Dec 15 17:04:57 2011 +0000 @@ -35,6 +35,7 @@ #include <xen/sys/evtchn.h> #include <xen/sys/gntdev.h> #include <xen/sys/gntalloc.h> +#include <xen/sys/xenbus_dev.h> #include "xenctrl.h" #include "xenctrlosdep.h" @@ -43,6 +44,10 @@ #define PERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m \ " (%d = %s)", ## _a , errno, xc_strerror(xch, errno)) +#define XENSTORED_DEV "/dev/xen/xenbus_backend" +#define XENSTORED_PROC_KVA "/proc/xen/xsd_kva" +#define XENSTORED_PROC_PORT "/proc/xen/xsd_port" + static xc_osdep_handle linux_privcmd_open(xc_interface *xch) { int flags, saved_errno; @@ -367,6 +372,77 @@ static void *linux_privcmd_map_foreign_r return ret; } +static evtchn_port_t xenbus_proc_evtchn(void) +{ + int fd; + int rc; + evtchn_port_t port; + char str[20]; + + fd = open(XENSTORED_PROC_PORT, O_RDONLY); + if (fd == -1) + return -1; + + rc = read(fd, str, sizeof(str)); + if (rc == -1) + { + int err = errno; + close(fd); + errno = err; + return -1; + } + + str[rc] = ''\0''; + port = strtoul(str, NULL, 0); + + close(fd); + return port; +} + +static int linux_xenbus_backend_interface(xc_interface *xch, xc_osdep_handle h, void **map, evtchn_port_t *port) +{ + int ret, fd; + void *addr; + + fd = open(XENSTORED_DEV, O_RDWR); + if (fd == -1) + { + if ( errno != ENOENT ) + return -1; + + /* Try /proc interface */ + ret = xenbus_proc_evtchn(); + if ( ret < 0 ) + return -1; + + *port = ret; + + fd = open(XENSTORED_PROC_KVA, O_RDWR); + if ( fd == -1 ) + return -1; + } else { + ret = ioctl(fd, IOCTL_XENBUS_BACKEND_EVTCHN); + if ( ret < 0 ) + { + close(fd); + return -1; + } + *port = ret; + } + + addr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if ( addr == MAP_FAILED ) + { + close(fd); + return -1; + } + + *map = addr; + close(fd); + return 0; +} + static struct xc_osdep_ops linux_privcmd_ops = { .open = &linux_privcmd_open, .close = &linux_privcmd_close, @@ -381,6 +457,7 @@ static struct xc_osdep_ops linux_privcmd .map_foreign_bulk = &linux_privcmd_map_foreign_bulk, .map_foreign_range = &linux_privcmd_map_foreign_range, .map_foreign_ranges = &linux_privcmd_map_foreign_ranges, + .xenbus_backend_interface = &linux_xenbus_backend_interface, }, }; diff -r 0c92f4561443 tools/libxc/xc_misc.c --- a/tools/libxc/xc_misc.c Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/libxc/xc_misc.c Thu Dec 15 17:04:57 2011 +0000 @@ -633,6 +633,14 @@ int xc_hvm_inject_trap( return rc; } +int xc_xenbus_backend_interface(xc_interface *xch, void **map, evtchn_port_t *port) +{ + if ( xch->ops->u.privcmd.xenbus_backend_interface ) + return xch->ops->u.privcmd.xenbus_backend_interface + (xch, xch->ops_handle, map, port); + return -ENOSYS; +} + /* * Local variables: * mode: C diff -r 0c92f4561443 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/libxc/xenctrl.h Thu Dec 15 17:04:57 2011 +0000 @@ -324,6 +324,11 @@ int xc_get_cpumap_size(xc_interface *xch xc_cpumap_t xc_cpumap_alloc(xc_interface *xch); /* + * Xenbus backend + */ +int xc_xenbus_backend_interface(xc_interface *xch, void **map, evtchn_port_t *port); + +/* * DOMAIN DEBUGGING FUNCTIONS */ diff -r 0c92f4561443 tools/libxc/xenctrlosdep.h --- a/tools/libxc/xenctrlosdep.h Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/libxc/xenctrlosdep.h Thu Dec 15 17:04:57 2011 +0000 @@ -89,6 +89,7 @@ struct xc_osdep_ops void *(*map_foreign_ranges)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, size_t size, int prot, size_t chunksize, privcmd_mmap_entry_t entries[], int nentries); + int (*xenbus_backend_interface)(xc_interface *xch, xc_osdep_handle h, void **map, evtchn_port_t *port); } privcmd; struct { int (*fd)(xc_evtchn *xce, xc_osdep_handle h); diff -r 0c92f4561443 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/xenstore/xenstored_domain.c Thu Dec 15 17:04:57 2011 +0000 @@ -565,23 +565,20 @@ void restore_existing_connections(void) { } -static int dom0_init(void) +static int dom0_init(xc_interface *xch) { evtchn_port_t port; + void *intf; struct domain *dom0; - port = xenbus_evtchn(); - if (port == -1) + if (xc_xenbus_backend_interface(xch, &intf, &port) < 0) return -1; dom0 = new_domain(NULL, 0, port); if (dom0 == NULL) return -1; - dom0->interface = xenbus_map(); - if (dom0->interface == NULL) - return -1; - + dom0->interface = intf; talloc_steal(dom0->conn, dom0); xc_evtchn_notify(xce_handle, dom0->port); @@ -608,7 +605,7 @@ void domain_init(void) if (xce_handle == NULL) barf_perror("Failed to open evtchn device"); - if (dom0_init() != 0) + if (dom0_init(*xc_handle) != 0) barf_perror("Failed to initialize dom0 state"); if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1) diff -r 0c92f4561443 tools/xenstore/xenstored_linux.c --- a/tools/xenstore/xenstored_linux.c Thu Dec 15 10:41:58 2011 +0000 +++ b/tools/xenstore/xenstored_linux.c Thu Dec 15 17:04:57 2011 +0000 @@ -18,84 +18,8 @@ #include <sys/ioctl.h> #include <sys/mman.h> -#include <xen/sys/xenbus_dev.h> - #include "xenstored_core.h" -#define XENSTORED_DEV "/dev/xen/xenbus_backend" -#define XENSTORED_PROC_KVA "/proc/xen/xsd_kva" -#define XENSTORED_PROC_PORT "/proc/xen/xsd_port" - -static evtchn_port_t xenbus_proc_evtchn(void) -{ - int fd; - int rc; - evtchn_port_t port; - char str[20]; - - fd = open(XENSTORED_PROC_PORT, O_RDONLY); - if (fd == -1) - return -1; - - rc = read(fd, str, sizeof(str)); - if (rc == -1) - { - int err = errno; - close(fd); - errno = err; - return -1; - } - - str[rc] = ''\0''; - port = strtoul(str, NULL, 0); - - close(fd); - return port; -} - -evtchn_port_t xenbus_evtchn(void) -{ - int fd; - long ret; - - fd = open(XENSTORED_DEV, O_RDONLY); - if (fd == -1) - { - if (errno == ENOENT) - return xenbus_proc_evtchn(); - return -1; - } - - ret = ioctl(fd, IOCTL_XENBUS_BACKEND_EVTCHN); - if (ret == -1) - return -1; - - close(fd); - return ret; -} - -void *xenbus_map(void) -{ - int fd; - void *addr; - - fd = open(XENSTORED_DEV, O_RDWR); - if (fd == -1 && errno == ENOENT) - fd = open(XENSTORED_PROC_KVA, O_RDWR); - if (fd == -1) - return NULL; - - addr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); - - if (addr == MAP_FAILED) - addr = NULL; - - close(fd); - - return addr; -} - void xenbus_notify_running(void) { }
Bastian Blank
2011-Dec-15 18:31 UTC
Re: [PATCH 1/2] xenstored: Use xenbus_backend device on Linux
On Thu, Dec 15, 2011 at 05:07:34PM +0000, Ian Campbell wrote:> +static int linux_xenbus_backend_interface(xc_interface *xch, xc_osdep_handle h, void **map, evtchn_port_t *port) > +{ > + int ret, fd; > + void *addr; > + > + fd = open(XENSTORED_DEV, O_RDWR); > + if (fd == -1) > + { > + if ( errno != ENOENT ) > + return -1;This makes the code hard to read. You should first do the stuff on success and then the error handling.> +int xc_xenbus_backend_interface(xc_interface *xch, void **map, evtchn_port_t *port)I prefer returning structs over such pointer stunts, but okay. Bastian -- There are always alternatives. -- Spock, "The Galileo Seven", stardate 2822.3