diff -r d676d6414f07 Makefile.am --- a/Makefile.am Tue Sep 18 14:23:22 2007 -0400 +++ b/Makefile.am Tue Sep 18 14:29:40 2007 -0400 @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = src qemud proxy include docs @PYTHON_SUBDIR@ tests po m4 scripts +SUBDIRS = src qemud include docs @PYTHON_SUBDIR@ tests po m4 scripts ACLOCAL_AMFLAGS = -I m4 diff -r d676d6414f07 proxy/.cvsignore --- a/proxy/.cvsignore Tue Sep 18 14:23:22 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -Makefile -Makefile.in -.deps -.libs -libvirt_proxy diff -r d676d6414f07 proxy/Makefile.am --- a/proxy/Makefile.am Tue Sep 18 14:23:22 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -## Process this file with automake to produce Makefile.in - -INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include \ - -I@top_srcdir@/proxy -I@top_srcdir@/src @LIBXML_CFLAGS@ \ - -DPROXY -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - -DGETTEXT_PACKAGE=\"$(PACKAGE)\" $(WARN_CFLAGS) $(LIBVIRT_FEATURES) - -libexec_PROGRAMS = libvirt_proxy - -libvirt_proxy_SOURCES = libvirt_proxy.c @top_srcdir@/src/xend_internal.c \ - @top_srcdir@/src/xen_internal.c @top_srcdir@/src/virterror.c \ - @top_srcdir@/src/sexpr.c @top_srcdir@/src/xml.c \ - @top_srcdir@/src/xs_internal.c @top_srcdir@/src/buf.c @top_srcdir@/src/uuid.c -libvirt_proxy_LDFLAGS = $(WARN_CFLAGS) -libvirt_proxy_DEPENDENCIES = -libvirt_proxy_LDADD = - -install-exec-hook: - chmod u+s $(DESTDIR)$(libexecdir)/libvirt_proxy diff -r d676d6414f07 proxy/libvirt_proxy.c --- a/proxy/libvirt_proxy.c Tue Sep 18 14:23:22 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,852 +0,0 @@ -/* - * proxy_svr.c: root suid proxy server for Xen access to APIs with no - * side effects from unauthenticated clients. - * - * Copyright (C) 2006 Red Hat, Inc. - * - * See COPYING.LIB for the License of this software - * - * Daniel Veillard - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "internal.h" - -#ifdef WITH_XEN -#include "proxy_internal.h" -#include "xen_internal.h" -#include "xend_internal.h" -#include "xs_internal.h" -#include "xen_unified.h" - -static int fdServer = -1; -static int debug = 0; -static int persist = 0; -static int done = 0; - -#define MAX_CLIENT 64 - -static int nbClients = 0; /* client 0 is the unix listen socket */ -static struct pollfd pollInfos[MAX_CLIENT + 1]; - -static virConnect conninfos; -static virConnectPtr conn = &conninfos; - -static unsigned long xenVersion = 0; - -/************************************************************************ - * * - * Interfaces with the Xen hypervisor * - * * - ************************************************************************/ - -/** - * proxyInitXen: - * - * Initialize the communication layer with Xen - * - * Returns 0 or -1 in case of error - */ -static int -proxyInitXen(void) { - int ret; - unsigned long xenVersion2; - xenUnifiedPrivatePtr priv; - - /* Allocate per-connection private data. */ - priv = malloc (sizeof *priv); - if (!priv) { - fprintf(stderr, "Failed to allocate private data\n"); - return(-1); - } - conn->privateData = priv; - - priv->handle = -1; - priv->xendConfigVersion = -1; - priv->type = -1; - priv->len = -1; - priv->addr = NULL; - priv->xshandle = NULL; - priv->proxy = -1; - - ret = xenHypervisorOpen(conn, NULL, 0); - if (ret < 0) { - fprintf(stderr, "Failed to open Xen hypervisor\n"); - return(-1); - } else { - ret = xenHypervisorGetVersion(conn, &xenVersion); - if (ret != 0) { - fprintf(stderr, "Failed to get Xen hypervisor version\n"); - return(-1); - } - } - ret = xenDaemonOpen_unix(conn, "/var/lib/xend/xend-socket"); - if (ret < 0) { - fprintf(stderr, "Failed to connect to Xen daemon\n"); - return(-1); - } - ret = xenStoreOpen(conn, NULL, VIR_DRV_OPEN_RO); - if (ret < 0) { - fprintf(stderr, "Failed to open XenStore connection"); - return (-1); - } - ret = xenDaemonGetVersion(conn, &xenVersion2); - if (ret != 0) { - fprintf(stderr, "Failed to get Xen daemon version\n"); - return(-1); - } - if (debug) - fprintf(stderr, "Connected to hypervisor %lu and daemon %lu\n", - xenVersion, xenVersion2); - if (xenVersion2 > xenVersion) - xenVersion = xenVersion2; - return(0); -} - -/************************************************************************ - * * - * Processing of the unix socket to listen for clients * - * * - ************************************************************************/ - -/** - * proxyCloseUnixSocket: - * - * close the unix socket - * - * Returns 0 or -1 in case of error - */ -static int -proxyCloseUnixSocket(void) { - int ret; - - if (fdServer < 0) - return(0); - - ret = close(fdServer); - if (debug > 0) - fprintf(stderr, "closing unix socket %d: %d\n", fdServer, ret); - fdServer = -1; - pollInfos[0].fd = -1; - return(ret); -} - -/** - * proxyListenUnixSocket: - * @path: the fileame for the socket - * - * create a new abstract socket based on that path and listen on it - * - * Returns the associated file descriptor or -1 in case of failure - */ -static int -proxyListenUnixSocket(const char *path) { - int fd; - struct sockaddr_un addr; - - if (fdServer >= 0) - return(fdServer); - - fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - fprintf(stderr, "Failed to create unix socket"); - return(-1); - } - - /* - * Abstract socket do not hit the filesystem, way more secure and - * garanteed to be atomic - */ - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - addr.sun_path[0] = '\0'; - strncpy(&addr.sun_path[1], path, (sizeof(addr) - 4) - 2); - - /* - * now bind the socket to that address and listen on it - */ - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - fprintf(stderr, "Failed to bind to socket %s\n", path); - close(fd); - return (-1); - } - if (listen(fd, 30 /* backlog */ ) < 0) { - fprintf(stderr, "Failed to listen to socket %s\n", path); - close(fd); - return (-1); - } - - if (debug > 0) - fprintf(stderr, "opened and bound unix socket %d\n", fd); - - fdServer = fd; - pollInfos[0].fd = fd; - pollInfos[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; - return (fd); -} - -/** - * proxyAcceptClientSocket: - * - * Process a request to the unix socket - * - * Returns the filedescriptor of the new client or -1 in case of error - */ -static int -proxyAcceptClientSocket(void) { - int client; - socklen_t client_addrlen; - struct sockaddr client_addr; - -retry: - client_addrlen = sizeof(client_addr); - client = accept(pollInfos[0].fd, &client_addr, &client_addrlen); - if (client < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "accept connection on socket %d interrupted\n", - pollInfos[0].fd); - goto retry; - } - fprintf(stderr, "Failed to accept incoming connection on socket %d\n", - pollInfos[0].fd); - done = 1; - return(-1); - } - - if (nbClients >= MAX_CLIENT) { - fprintf(stderr, "Too many client registered\n"); - close(client); - return(-1); - } - nbClients++; - pollInfos[nbClients].fd = client; - pollInfos[nbClients].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; - if (debug > 0) - fprintf(stderr, "accept connection on socket %d for client %d\n", - client, nbClients); - return(client); -} - -/************************************************************************ - * * - * Processing of client sockets * - * * - ************************************************************************/ - -/** - * proxyCloseClientSocket: - * @nr: client number - * - * Close the socket from that client, and recompact the pollInfo array - * - * Returns 0 in case of success and -1 in case of error - */ -static int -proxyCloseClientSocket(int nr) { - int ret; - - ret = close(pollInfos[nr].fd); - if (ret != 0) - fprintf(stderr, "Failed to close socket %d from client %d\n", - pollInfos[nr].fd, nr); - else if (debug > 0) - fprintf(stderr, "Closed socket %d from client %d\n", - pollInfos[nr].fd, nr); - if (nr < nbClients) { - memmove(&pollInfos[nr], &pollInfos[nr + 1], - (nbClients - nr) * sizeof(pollInfos[0])); - } - nbClients--; - return(ret); -} - -/** - * proxyCloseClientSockets: - * - * Close all the sockets from the clients - */ -static void -proxyCloseClientSockets(void) { - int i, ret; - - for (i = 1;i <= nbClients;i++) { - ret = close(pollInfos[i].fd); - if (ret != 0) - fprintf(stderr, "Failed to close socket %d from client %d\n", - pollInfos[i].fd, i); - else if (debug > 0) - fprintf(stderr, "Closed socket %d from client %d\n", - pollInfos[i].fd, i); - } - nbClients = 0; -} - -/** - * proxyWriteClientSocket: - * @nr: the client number - * @req: pointer to the packet - * - * Send back a packet to the client. If it seems write would be blocking - * then try to disconnect from it. - * - * Return 0 in case of success and -1 in case of error. - */ -static int -proxyWriteClientSocket(int nr, virProxyPacketPtr req) { - int ret; - - if ((nr <= 0) || (nr > nbClients) || (req == NULL) || - (req->len < sizeof(virProxyPacket)) || - (req->len > sizeof(virProxyFullPacket)) || - (pollInfos[nr].fd < 0)) { - fprintf(stderr, "write to client %d in error", nr); - proxyCloseClientSocket(nr); - return(-1); - } - -retry: - ret = write(pollInfos[nr].fd, (char *) req, req->len); - if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "write socket %d to client %d interrupted\n", - pollInfos[nr].fd, nr); - goto retry; - } - fprintf(stderr, "write %d bytes to socket %d from client %d failed\n", - req->len, pollInfos[nr].fd, nr); - proxyCloseClientSocket(nr); - return(-1); - } - if (ret == 0) { - if (debug) - fprintf(stderr, "end of stream from client %d on socket %d\n", - nr, pollInfos[nr].fd); - proxyCloseClientSocket(nr); - return(-1); - } - - if (ret != req->len) { - fprintf(stderr, "write %d of %d bytes to socket %d from client %d\n", - ret, req->len, pollInfos[nr].fd, nr); - proxyCloseClientSocket(nr); - return(-1); - } - if (debug) - fprintf(stderr, "wrote %d bytes to client %d on socket %d\n", - ret, nr, pollInfos[nr].fd); - - return(0); -} -/** - * proxyReadClientSocket: - * @nr: the client number - * - * Process a read from a client socket - */ -static int -proxyReadClientSocket(int nr) { - virProxyFullPacket request; - virProxyPacketPtr req = (virProxyPacketPtr) &request; - int ret; - char *xml, *ostype; - -retry: - ret = read(pollInfos[nr].fd, req, sizeof(virProxyPacket)); - if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "read socket %d from client %d interrupted\n", - pollInfos[nr].fd, nr); - goto retry; - } - fprintf(stderr, "Failed to read socket %d from client %d\n", - pollInfos[nr].fd, nr); - proxyCloseClientSocket(nr); - return(-1); - } - if (ret == 0) { - if (debug) - fprintf(stderr, "end of stream from client %d on socket %d\n", - nr, pollInfos[nr].fd); - proxyCloseClientSocket(nr); - return(-1); - } - - if (debug) - fprintf(stderr, "read %d bytes from client %d on socket %d\n", - ret, nr, pollInfos[nr].fd); - - if ((req->version != PROXY_PROTO_VERSION) || - (req->len < sizeof(virProxyPacket)) || - (req->len > sizeof(virProxyFullPacket))) - goto comm_error; - - - if (debug) - fprintf(stderr, "Got command %d from client %d\n", req->command, nr); - - /* - * complete reading the packet. - * TODO: we should detect when blocking and abort connection if this happen - */ - if (req->len > ret) { - int total, extra; - char *base = (char *) &request; - - total = ret; - while (total < req->len) { - extra = req->len - total; -retry2: - ret = read(pollInfos[nr].fd, base + total, extra); - if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, - "read socket %d from client %d interrupted\n", - pollInfos[nr].fd, nr); - goto retry2; - } - fprintf(stderr, "Failed to read socket %d from client %d\n", - pollInfos[nr].fd, nr); - proxyCloseClientSocket(nr); - return(-1); - } - if (ret == 0) { - if (debug) - fprintf(stderr, - "end of stream from client %d on socket %d\n", - nr, pollInfos[nr].fd); - proxyCloseClientSocket(nr); - return(-1); - } - total += ret; - } - } - switch (req->command) { - case VIR_PROXY_NONE: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - break; - case VIR_PROXY_VERSION: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - req->data.larg = xenVersion; - break; - case VIR_PROXY_LIST: { - int maxids; - - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - maxids = sizeof(request.extra.arg) / sizeof(int); - ret = xenHypervisorListDomains(conn, &request.extra.arg[0], - maxids); - if (ret < 0) { - req->len = sizeof(virProxyPacket); - req->data.arg = 0; - } else { - req->len = sizeof(virProxyPacket) + ret * sizeof(int); - req->data.arg = ret; - } - break; - } - case VIR_PROXY_NUM_DOMAIN: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - req->data.arg = xenHypervisorNumOfDomains(conn); - break; - case VIR_PROXY_MAX_MEMORY: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - req->data.larg = xenHypervisorGetDomMaxMemory(conn, req->data.arg); - break; - case VIR_PROXY_DOMAIN_INFO: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - memset(&request.extra.dinfo, 0, sizeof(virDomainInfo)); - ret = xenHypervisorGetDomInfo(conn, req->data.arg, - &request.extra.dinfo); - if (ret < 0) { - req->data.arg = -1; - } else { - req->len += sizeof(virDomainInfo); - } - break; - case VIR_PROXY_LOOKUP_ID: { - char *name = NULL; - unsigned char uuid[VIR_UUID_BUFLEN]; - int len; - - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - - if (xenDaemonDomainLookupByID(conn, req->data.arg, &name, uuid) < 0) { - req->data.arg = -1; - } else { - len = strlen(name); - if (len > 1000) { - len = 1000; - name[1000] = 0; - } - req->len += VIR_UUID_BUFLEN + len + 1; - memcpy(&request.extra.str[0], uuid, VIR_UUID_BUFLEN); - strcpy(&request.extra.str[VIR_UUID_BUFLEN], name); - } - if (name) - free(name); - break; - } - case VIR_PROXY_LOOKUP_UUID: { - char **names; - char **tmp; - int ident, len; - char *name = NULL; - unsigned char uuid[VIR_UUID_BUFLEN]; - - if (req->len != sizeof(virProxyPacket) + VIR_UUID_BUFLEN) - goto comm_error; - - /* - * Xend API forces to collect the full domain list by names, and - * then query each of them until the id is found - */ - names = xenDaemonListDomainsOld(conn); - tmp = names; - - if (names != NULL) { - while (*tmp != NULL) { - ident = xenDaemonDomainLookupByName_ids(conn, *tmp, &uuid[0]); - if (!memcmp(uuid, &request.extra.str[0], VIR_UUID_BUFLEN)) { - name = *tmp; - break; - } - tmp++; - } - } - if (name == NULL) { - /* not found */ - req->data.arg = -1; - req->len = sizeof(virProxyPacket); - } else { - len = strlen(name); - if (len > 1000) { - len = 1000; - name[1000] = 0; - } - req->len = sizeof(virProxyPacket) + len + 1; - strcpy(&request.extra.str[0], name); - req->data.arg = ident; - } - free(names); - break; - } - case VIR_PROXY_LOOKUP_NAME: { - int ident; - unsigned char uuid[VIR_UUID_BUFLEN]; - - if (req->len > sizeof(virProxyPacket) + 1000) - goto comm_error; - - ident = xenDaemonDomainLookupByName_ids(conn, - &request.extra.str[0], &uuid[0]); - if (ident < 0) { - /* not found */ - req->data.arg = -1; - req->len = sizeof(virProxyPacket); - } else { - req->len = sizeof(virProxyPacket) + VIR_UUID_BUFLEN; - memcpy(&request.extra.str[0], uuid, VIR_UUID_BUFLEN); - req->data.arg = ident; - } - break; - } - case VIR_PROXY_NODE_INFO: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - - /* - * Hum, could we expect those informations to be unmutable and - * cache them ? Since it's probably an unfrequent call better - * not make assumption and do the xend RPC each call. - */ - ret = xenDaemonNodeGetInfo(conn, &request.extra.ninfo); - if (ret < 0) { - req->data.arg = -1; - req->len = sizeof(virProxyPacket); - } else { - req->data.arg = 0; - req->len = sizeof(virProxyPacket) + sizeof(virNodeInfo); - } - break; - - case VIR_PROXY_GET_CAPABILITIES: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - - xml = xenHypervisorGetCapabilities (conn); - if (!xml) { - req->data.arg = -1; - req->len = sizeof (virProxyPacket); - } else { - int xmllen = strlen (xml); - if (xmllen > (int) sizeof (request.extra.str)) { - req->data.arg = -2; - req->len = sizeof (virProxyPacket); - } else { - req->data.arg = 0; - memmove (request.extra.str, xml, xmllen); - req->len = sizeof (virProxyPacket) + xmllen; - } - free (xml); - } - break; - - case VIR_PROXY_DOMAIN_XML: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - - xml = xenDaemonDomainDumpXMLByID(conn, request.data.arg); - if (!xml) { - req->data.arg = -1; - req->len = sizeof(virProxyPacket); - } else { - int xmllen = strlen(xml); - if (xmllen > (int) sizeof(request.extra.str)) { - req->data.arg = -2; - req->len = sizeof(virProxyPacket); - } else { - req->data.arg = 0; - memmove(&request.extra.str[0], xml, xmllen); - req->len = sizeof(virProxyPacket) + xmllen; - } - free(xml); - } - break; - case VIR_PROXY_DOMAIN_OSTYPE: - if (req->len != sizeof(virProxyPacket)) - goto comm_error; - - ostype = xenStoreDomainGetOSTypeID(conn, request.data.arg); - if (!ostype) { - req->data.arg = -1; - req->len = sizeof(virProxyPacket); - } else { - int ostypelen = strlen(ostype); - if (ostypelen > (int) sizeof(request.extra.str)) { - req->data.arg = -2; - req->len = sizeof(virProxyPacket); - } else { - req->data.arg = 0; - memmove(&request.extra.str[0], ostype, ostypelen); - req->len = sizeof(virProxyPacket) + ostypelen; - } - free(ostype); - } - break; - default: - goto comm_error; - } - ret = proxyWriteClientSocket(nr, req); - return(ret); - -comm_error: - fprintf(stderr, - "Communication error with client %d: malformed packet\n", nr); - proxyCloseClientSocket(nr); - return(-1); -} - -/************************************************************************ - * * - * Main loop processing * - * * - ************************************************************************/ - -/** - * proxyProcessRequests: - * - * process requests and timers - */ -static void -proxyProcessRequests(void) { - int exit_timeout = 30; - int ret, i; - - while (!done) { - /* - * wait for requests, with a one second timeout - */ - ret = poll(&pollInfos[0], nbClients + 1, 1000); - if (ret == 0) { /* timeout */ - if ((nbClients == 0) && (persist == 0)) { - exit_timeout--; - if (exit_timeout == 0) { - done = 1; - if (debug > 0) { - fprintf(stderr, "Exitting after 30s without clients\n"); - } - } - } else - exit_timeout = 30; - if (debug > 1) - fprintf(stderr, "poll timeout\n"); - continue; - } else if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "poll syscall interrupted\n"); - continue; - } - fprintf(stderr, "poll syscall failed\n"); - break; - } - /* - * there have been I/O to process - */ - exit_timeout = 30; - if (pollInfos[0].revents != 0) { - if (pollInfos[0].revents & POLLIN) { - proxyAcceptClientSocket(); - } else { - fprintf(stderr, "Got an error %d on incoming socket %d\n", - pollInfos[0].revents, pollInfos[0].fd); - break; - } - } - - /* - * process the clients in reverse order since on error or disconnect - * pollInfos is compacted to remove the given client. - */ - for (i = nbClients;i > 0;i--) { - if (pollInfos[i].revents & POLLIN) { - proxyReadClientSocket(i); - } else if (pollInfos[i].revents != 0) { - fprintf(stderr, "Got an error %d on client %d socket %d\n", - pollInfos[i].revents, i, pollInfos[i].fd); - proxyCloseClientSocket(i); - } - } - - } -} - -/** - * proxyMainLoop: - * - * main loop for the proxy, continually try to keep the unix socket - * open, serve client requests, and process timing events. - */ - -static void -proxyMainLoop(void) { - while (! done) { - if (proxyListenUnixSocket(PROXY_SOCKET_PATH) < 0) - break; - proxyProcessRequests(); - } - proxyCloseClientSockets(); -} - -/** - * usage: - * - * dump on stdout informations about the program - */ -static void -usage(const char *progname) { - printf("Usage: %s [-v] [-v]\n", progname); - printf(" option -v increase the verbosity level for debugging\n"); - printf("This is a proxy for xen services used by libvirt to offer\n"); - printf("safe and fast status information on the Xen virtualization.\n"); - printf("This need not be run manually it's started automatically.\n"); -} - -/** - * main: - * - * Check that we are running with root priviledges, initialize the - * connections to the daemon and or hypervisor, and then run the main loop - */ -int main(int argc, char **argv) { - int i; - - if (!setlocale(LC_ALL, "")) { - perror("setlocale"); - return -1; - } - if (!bindtextdomain(GETTEXT_PACKAGE, LOCALEBASEDIR)) { - perror("bindtextdomain"); - return -1; - } - if (!textdomain(GETTEXT_PACKAGE)) { - perror("textdomain"); - return -1; - } - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-v")) { - debug++; - } else if (!strcmp(argv[i], "-no-timeout")) { - persist = 1; - } else { - usage(argv[0]); - exit(1); - } - } - - - if (geteuid() != 0) { - fprintf(stderr, "%s must be run as root or suid\n", argv[0]); - /* exit(1); */ - } - - /* - * setup a connection block - */ - memset(conn, 0, sizeof(conninfos)); - conn->magic = VIR_CONNECT_MAGIC; - - /* - * very fist thing, use the socket as an exclusive lock, this then - * allow to do timed exits, avoiding constant CPU usage in case of - * failure. - */ - if (proxyListenUnixSocket(PROXY_SOCKET_PATH) < 0) - exit(0); - if (proxyInitXen() == 0) - proxyMainLoop(); - sleep(1); - proxyCloseUnixSocket(); - exit(0); -} - -#else /* WITHOUT_XEN */ -int main(void) { - fprintf(stderr, "libvirt was compiled without Xen support\n"); - exit(1); -} -#endif /* WITH_XEN */ - -/* - * vim: set tabstop=4: - * vim: set shiftwidth=4: - * vim: set expandtab: - */ -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff -r d676d6414f07 src/Makefile.am --- a/src/Makefile.am Tue Sep 18 14:23:22 2007 -0400 +++ b/src/Makefile.am Tue Sep 18 14:29:40 2007 -0400 @@ -41,7 +41,6 @@ CLIENT_SOURCES = \ sexpr.c sexpr.h \ virterror.c \ driver.h \ - proxy_internal.c proxy_internal.h \ conf.c conf.h \ xm_internal.c xm_internal.h \ remote_internal.c remote_internal.h \ diff -r d676d6414f07 src/proxy_internal.c --- a/src/proxy_internal.c Tue Sep 18 14:23:22 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1124 +0,0 @@ -/* - * proxy_client.c: client side of the communication with the libvirt proxy. - * - * Copyright (C) 2006 Red Hat, Inc. - * - * See COPYING.LIB for the License of this software - * - * Daniel Veillard - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "internal.h" -#include "driver.h" -#include "proxy_internal.h" -#include "xen_unified.h" - -#define STANDALONE - -static int debug = 0; - -static int xenProxyClose(virConnectPtr conn); -static int xenProxyOpen(virConnectPtr conn, const char *name, int flags); -static int xenProxyGetVersion(virConnectPtr conn, unsigned long *hvVer); -static int xenProxyNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); -static char *xenProxyGetCapabilities(virConnectPtr conn); -static int xenProxyListDomains(virConnectPtr conn, int *ids, int maxids); -static int xenProxyNumOfDomains(virConnectPtr conn); -static unsigned long xenProxyDomainGetMaxMemory(virDomainPtr domain); -static int xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); -static char *xenProxyDomainDumpXML(virDomainPtr domain, int flags); -static char *xenProxyDomainGetOSType(virDomainPtr domain); - -struct xenUnifiedDriver xenProxyDriver = { - xenProxyOpen, /* open */ - xenProxyClose, /* close */ - NULL, /* type */ - xenProxyGetVersion, /* version */ - NULL, /* hostname */ - NULL, /* URI */ - xenProxyNodeGetInfo, /* nodeGetInfo */ - xenProxyGetCapabilities, /* getCapabilities */ - xenProxyListDomains, /* listDomains */ - xenProxyNumOfDomains, /* numOfDomains */ - NULL, /* domainCreateLinux */ - NULL, /* domainSuspend */ - NULL, /* domainResume */ - NULL, /* domainShutdown */ - NULL, /* domainReboot */ - NULL, /* domainDestroy */ - xenProxyDomainGetOSType, /* domainGetOSType */ - xenProxyDomainGetMaxMemory, /* domainGetMaxMemory */ - NULL, /* domainSetMaxMemory */ - NULL, /* domainSetMemory */ - xenProxyDomainGetInfo, /* domainGetInfo */ - NULL, /* domainSave */ - NULL, /* domainRestore */ - NULL, /* domainCoreDump */ - NULL, /* domainSetVcpus */ - NULL, /* domainPinVcpu */ - NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ - xenProxyDomainDumpXML, /* domainDumpXML */ - NULL, /* listDefinedDomains */ - NULL, /* numOfDefinedDomains */ - NULL, /* domainCreate */ - NULL, /* domainDefineXML */ - NULL, /* domainUndefine */ - NULL, /* domainAttachDevice */ - NULL, /* domainDetachDevice */ - NULL, /* domainGetAutostart */ - NULL, /* domainSetAutostart */ - NULL, /* domainGetSchedulerType */ - NULL, /* domainGetSchedulerParameters */ - NULL, /* domainSetSchedulerParameters */ -}; - -/** - * xenProxyInit: - * - * Initialise the xen proxy driver. - */ -int -xenProxyInit (void) -{ - return 0; -} - -/************************************************************************ - * * - * Error handling * - * * - ************************************************************************/ - -/** - * virProxyError: - * @conn: the connection if available - * @error: the error noumber - * @info: extra information string - * - * Handle an error at the xend daemon interface - */ -static void -virProxyError(virConnectPtr conn, virErrorNumber error, const char *info) -{ - const char *errmsg; - - if (error == VIR_ERR_OK) - return; - - errmsg = __virErrorMsg(error, info); - __virRaiseError(conn, NULL, NULL, VIR_FROM_PROXY, error, VIR_ERR_ERROR, - errmsg, info, NULL, 0, 0, errmsg, info); -} - -/************************************************************************ - * * - * Automatic startup of the proxy server if it is not running * - * * - ************************************************************************/ -/** - * virProxyFindServerPath: - * - * Tries to find the path to the gam_server binary. - * - * Returns path on success or NULL in case of error. - */ -static const char * -virProxyFindServerPath(void) -{ - static const char *serverPaths[] = { - BINDIR "/libvirt_proxy", - "/usr/bin/libvirt_proxy_dbg", - NULL - }; - int i; - const char *debugProxy = getenv("LIBVIRT_DEBUG_PROXY"); - - if (debugProxy) - return(debugProxy); - - for (i = 0; serverPaths[i]; i++) { - if (access(serverPaths[i], X_OK | R_OK) == 0) { - return serverPaths[i]; - } - } - return NULL; -} - -/** - * virProxyForkServer: - * - * Forks and try to launch the proxy server processing the requests for - * libvirt when communicating with Xen. - * - * Returns 0 in case of success or -1 in case of detected error. - */ -static int -virProxyForkServer(void) -{ - const char *proxyPath = virProxyFindServerPath(); - int ret, pid, status; - - if (!proxyPath) { - fprintf(stderr, "failed to find libvirt_proxy\n"); - return(-1); - } - - if (debug) - fprintf(stderr, "Asking to launch %s\n", proxyPath); - - /* Become a daemon */ - pid = fork(); - if (pid == 0) { - long open_max; - long i; - - /* don't hold open fd opened from the client of the library */ - open_max = sysconf (_SC_OPEN_MAX); - for (i = 0; i < open_max; i++) - fcntl (i, F_SETFD, FD_CLOEXEC); - - setsid(); - if (fork() == 0) { - execl(proxyPath, proxyPath, NULL); - fprintf(stderr, _("failed to exec %s\n"), proxyPath); - } - /* - * calling exit() generate troubles for termination handlers - */ - _exit(0); - } - - /* - * do a waitpid on the intermediate process to avoid zombies. - */ -retry_wait: - ret = waitpid(pid, &status, 0); - if (ret < 0) { - if (errno == EINTR) - goto retry_wait; - } - - return (0); -} - -/************************************************************************ - * * - * Processing of client sockets * - * * - ************************************************************************/ - -/** - * virProxyOpenClientSocket: - * @path: the fileame for the socket - * - * try to connect to the socket open by libvirt_proxy - * - * Returns the associated file descriptor or -1 in case of failure - */ -static int -virProxyOpenClientSocket(const char *path) { - int fd; - struct sockaddr_un addr; - int trials = 0; - -retry: - fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - return(-1); - } - - /* - * Abstract socket do not hit the filesystem, way more secure and - * garanteed to be atomic - */ - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - addr.sun_path[0] = '\0'; - strncpy(&addr.sun_path[1], path, (sizeof(addr) - 4) - 2); - - /* - * now bind the socket to that address and listen on it - */ - if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(fd); - if (trials < 3) { - if (virProxyForkServer() < 0) - return(-1); - trials++; - usleep(5000 * trials * trials); - goto retry; - } - return (-1); - } - - if (debug > 0) - fprintf(stderr, "connected to unix socket %s via %d\n", path, fd); - - return (fd); -} - -/** - * virProxyCloseClientSocket: - * @fd: the file descriptor for the socket - * - * Close the socket from that client - * - * Returns 0 in case of success and -1 in case of error - */ -static int -virProxyCloseClientSocket(int fd) { - int ret; - - if (fd < 0) - return(-1); - - ret = close(fd); - if (ret != 0) - fprintf(stderr, _("Failed to close socket %d\n"), fd); - else if (debug > 0) - fprintf(stderr, "Closed socket %d\n", fd); - return(ret); -} - -/** - * virProxyReadClientSocket: - * @fd: the socket - * @buffer: the target memory area - * @len: the lenght in bytes - * @quiet: quiet access - * - * Process a read from a client socket - * - * Returns the number of byte read or -1 in case of error. - */ -static int -virProxyReadClientSocket(int fd, char *buffer, int len, int quiet) { - int ret; - - if ((fd < 0) || (buffer == NULL) || (len < 0)) - return(-1); - -retry: - ret = read(fd, buffer, len); - if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "read socket %d interrupted\n", fd); - goto retry; - } - if (!quiet) - fprintf(stderr, _("Failed to read socket %d\n"), fd); - return(-1); - } - - if (debug) - fprintf(stderr, "read %d bytes from socket %d\n", - ret, fd); - return(ret); -} - -/** - * virProxyWriteClientSocket: - * @fd: the socket - * @data: the data - * @len: the lenght of data in bytes - * - * Process a read from a client socket - */ -static int -virProxyWriteClientSocket(int fd, const char *data, int len) { - int ret; - - if ((fd < 0) || (data == NULL) || (len < 0)) - return(-1); - -retry: - ret = write(fd, data, len); - if (ret < 0) { - if (errno == EINTR) { - if (debug > 0) - fprintf(stderr, "write socket %d, %d bytes interrupted\n", - fd, len); - goto retry; - } - fprintf(stderr, _("Failed to write to socket %d\n"), fd); - return(-1); - } - if (debug) - fprintf(stderr, "wrote %d bytes to socket %d\n", - len, fd); - - return(0); -} - -/************************************************************************ - * * - * Proxy commands processing * - * * - ************************************************************************/ - -/** - * xenProxyClose: - * @conn: pointer to the hypervisor connection - * - * Shutdown the Xen proxy communication layer - */ -static int -xenProxyClose(virConnectPtr conn) -{ - xenUnifiedPrivatePtr priv; - - if (conn == NULL) { - virProxyError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); - return -1; - } - - priv = (xenUnifiedPrivatePtr) conn->privateData; - if (!priv) { - virProxyError (NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__); - return -1; - } - - /* Fail silently. */ - if (priv->proxy == -1) - return -1; - - virProxyCloseClientSocket (priv->proxy); - priv->proxy = -1; - - return 0; -} - -static int -xenProxyCommand(virConnectPtr conn, virProxyPacketPtr request, - virProxyFullPacketPtr answer, int quiet) { - static int serial = 0; - int ret; - virProxyPacketPtr res = NULL; - xenUnifiedPrivatePtr priv; - - if (conn == NULL) { - virProxyError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); - return -1; - } - - priv = (xenUnifiedPrivatePtr) conn->privateData; - if (!priv) { - virProxyError (NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__); - return -1; - } - - /* Fail silently. */ - if (priv->proxy == -1) - return -1; - - /* - * normal communication serial numbers are in 0..4095 - */ - ++serial; - if (serial >= 4096) - serial = 0; - request->version = PROXY_PROTO_VERSION; - request->serial = serial; - ret = virProxyWriteClientSocket(priv->proxy, (const char *) request, - request->len); - if (ret < 0) - return(-1); -retry: - if (answer == NULL) { - /* read in situ */ - ret = virProxyReadClientSocket(priv->proxy, (char *) request, - sizeof(virProxyPacket), quiet); - if (ret < 0) - return(-1); - if (ret != sizeof(virProxyPacket)) { - fprintf(stderr, - _("Communication error with proxy: got %d bytes of %d\n"), - ret, (int) sizeof(virProxyPacket)); - xenProxyClose(conn); - return(-1); - } - res = request; - if (res->len != sizeof(virProxyPacket)) { - fprintf(stderr, - _("Communication error with proxy: expected %d bytes got %d\n"), - (int) sizeof(virProxyPacket), res->len); - xenProxyClose(conn); - return(-1); - } - } else { - /* read in packet provided */ - ret = virProxyReadClientSocket(priv->proxy, (char *) answer, - sizeof(virProxyPacket), quiet); - if (ret < 0) - return(-1); - if (ret != sizeof(virProxyPacket)) { - fprintf(stderr, - _("Communication error with proxy: got %d bytes of %d\n"), - ret, (int) sizeof(virProxyPacket)); - xenProxyClose(conn); - return(-1); - } - res = (virProxyPacketPtr) answer; - if ((res->len < sizeof(virProxyPacket)) || - (res->len > sizeof(virProxyFullPacket))) { - fprintf(stderr, - _("Communication error with proxy: got %d bytes packet\n"), - res->len); - xenProxyClose(conn); - return(-1); - } - if (res->len > sizeof(virProxyPacket)) { - ret = virProxyReadClientSocket(priv->proxy, - (char *) &(answer->extra.arg[0]), - res->len - ret, quiet); - if (ret != (int) (res->len - sizeof(virProxyPacket))) { - fprintf(stderr, - _("Communication error with proxy: got %d bytes of %d\n"), - ret, (int) sizeof(virProxyPacket)); - xenProxyClose(conn); - return(-1); - } - } - } - /* - * do more checks on the incoming packet. - */ - if ((res == NULL) || (res->version != PROXY_PROTO_VERSION) || - (res->len < sizeof(virProxyPacket))) { - fprintf(stderr, - _("Communication error with proxy: malformed packet\n")); - xenProxyClose(conn); - return(-1); - } - if (res->serial != serial) { - TODO /* Asynchronous communication */ - fprintf(stderr, _("got asynchronous packet number %d\n"), res->serial); - goto retry; - } - return(0); -} - -/** - * xenProxyOpen: - * @conn: pointer to the hypervisor connection - * @name: URL for the target, NULL for local - * @flags: combination of virDrvOpenFlag(s) - * - * Try to initialize the Xen proxy communication layer - * This can be opened only for a read-only kind of access - * - * Returns 0 in case of success, and -1 in case of failure - */ -int -xenProxyOpen(virConnectPtr conn, const char *name ATTRIBUTE_UNUSED, int flags) -{ - virProxyPacket req; - int ret; - int fd; - xenUnifiedPrivatePtr priv; - - if (!(flags & VIR_DRV_OPEN_RO)) - return(-1); - - priv = (xenUnifiedPrivatePtr) conn->privateData; - priv->proxy = -1; - - fd = virProxyOpenClientSocket(PROXY_SOCKET_PATH); - if (fd < 0) { - virProxyError(NULL, VIR_ERR_NO_XEN, PROXY_SOCKET_PATH); - return(-1); - } - priv->proxy = fd; - - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_NONE; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, NULL, 1); - if ((ret < 0) || (req.command != VIR_PROXY_NONE)) { - virProxyError(NULL, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - xenProxyClose(conn); - return(-1); - } - return(0); -} - -/************************************************************************ - * * - * Driver entry points * - * * - ************************************************************************/ - -/** - * xenProxyGetVersion: - * @conn: pointer to the Xen Daemon block - * @hvVer: return value for the version of the running hypervisor (OUT) - * - * Get the version level of the Hypervisor running. - * - * Returns -1 in case of error, 0 otherwise. if the version can't be - * extracted by lack of capacities returns 0 and @hvVer is 0, otherwise - * @hvVer value is major * 1,000,000 + minor * 1,000 + release - */ -static int -xenProxyGetVersion(virConnectPtr conn, unsigned long *hvVer) -{ - virProxyPacket req; - int ret; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (-1); - } - if (hvVer == NULL) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (-1); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_VERSION; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, NULL, 0); - if (ret < 0) { - xenProxyClose(conn); - return(-1); - } - *hvVer = req.data.larg; - return(0); -} - -/** - * xenProxyListDomains: - * @conn: pointer to the hypervisor connection - * @ids: array to collect the list of IDs of active domains - * @maxids: size of @ids - * - * Collect the list of active domains, and store their ID in @maxids - * - * Returns the number of domain found or -1 in case of error - */ -static int -xenProxyListDomains(virConnectPtr conn, int *ids, int maxids) -{ - virProxyPacket req; - virProxyFullPacket ans; - int ret; - int nb; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (-1); - } - if ((ids == NULL) || (maxids <= 0)) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (-1); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_LIST; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(conn); - return(-1); - } - nb = ans.data.arg; - if ((nb > 1020) || (nb <= 0) || - (ans.len <= sizeof(virProxyPacket)) || - (ans.len > sizeof(virProxyFullPacket))) { - virProxyError(conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - return(-1); - } - if (nb > maxids) - nb = maxids; - memmove(ids, &ans.extra.arg[0], nb * sizeof(int)); - - return(nb); -} - -/** - * xenProxyNumOfDomains: - * @conn: pointer to the hypervisor connection - * - * Provides the number of active domains. - * - * Returns the number of domain found or -1 in case of error - */ -static int -xenProxyNumOfDomains(virConnectPtr conn) -{ - virProxyPacket req; - int ret; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (-1); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_NUM_DOMAIN; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, NULL, 0); - if (ret < 0) { - xenProxyClose(conn); - return(-1); - } - return(req.data.arg); -} - - -/** - * xenProxyDomainGetDomMaxMemory: - * @conn: pointer to the hypervisor connection - * @id: the domain ID number - * - * Ask the Xen Daemon for the maximum memory allowed for a domain - * - * Returns the memory size in kilobytes or 0 in case of error. - */ -static unsigned long -xenProxyDomainGetDomMaxMemory(virConnectPtr conn, int id) -{ - virProxyPacket req; - int ret; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (0); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_MAX_MEMORY; - req.data.arg = id; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, NULL, 0); - if (ret < 0) { - xenProxyClose(conn); - return(0); - } - return(req.data.larg); -} - -/** - * xenProxyDomainGetMaxMemory: - * @domain: pointer to the domain block - * - * Ask the Xen Daemon for the maximum memory allowed for a domain - * - * Returns the memory size in kilobytes or 0 in case of error. - */ -static unsigned long -xenProxyDomainGetMaxMemory(virDomainPtr domain) -{ - if (!VIR_IS_CONNECTED_DOMAIN(domain)) { - if (domain == NULL) - virProxyError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - else - virProxyError(domain->conn, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - return (0); - } - if (domain->id < 0) - return (0); - return(xenProxyDomainGetDomMaxMemory(domain->conn, domain->id)); -} - -/** - * xenProxyDomainGetInfo: - * @domain: a domain object - * @info: pointer to a virDomainInfo structure allocated by the user - * - * This method looks up information about a domain and update the - * information block provided. - * - * Returns 0 in case of success, -1 in case of error - */ -static int -xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) -{ - virProxyPacket req; - virProxyFullPacket ans; - int ret; - - if (!VIR_IS_CONNECTED_DOMAIN(domain)) { - if (domain == NULL) - virProxyError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - else - virProxyError(domain->conn, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - return (-1); - } - if (domain->id < 0) - return (-1); - if (info == NULL) { - virProxyError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (-1); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_DOMAIN_INFO; - req.data.arg = domain->id; - req.len = sizeof(req); - ret = xenProxyCommand(domain->conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(domain->conn); - return(-1); - } - if (ans.len != sizeof(virProxyPacket) + sizeof(virDomainInfo)) { - virProxyError(domain->conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - return (-1); - } - memmove(info, &ans.extra.dinfo, sizeof(virDomainInfo)); - - return(0); -} - -/** - * xenProxyLookupByID: - * @conn: pointer to the hypervisor connection - * @id: the domain ID number - * - * Try to find a domain based on the hypervisor ID number - * - * Returns a new domain object or NULL in case of failure - */ -virDomainPtr -xenProxyLookupByID(virConnectPtr conn, int id) -{ - virProxyPacket req; - virProxyFullPacket ans; - unsigned char uuid[VIR_UUID_BUFLEN]; - const char *name; - int ret; - virDomainPtr res; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (NULL); - } - if (id < 0) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (NULL); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_LOOKUP_ID; - req.data.arg = id; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(conn); - return(NULL); - } - if (ans.data.arg == -1) { - return(NULL); - } - memcpy(uuid, &ans.extra.str[0], VIR_UUID_BUFLEN); - name = &ans.extra.str[VIR_UUID_BUFLEN]; - res = virGetDomain(conn, name, uuid); - if (res) res->id = id; - return(res); -} - -/** - * xenProxyLookupByUUID: - * @conn: pointer to the hypervisor connection - * @uuid: the raw UUID for the domain - * - * Try to lookup a domain on xend based on its UUID. - * - * Returns a new domain object or NULL in case of failure - */ -virDomainPtr -xenProxyLookupByUUID(virConnectPtr conn, const unsigned char *uuid) -{ - virProxyFullPacket req; - const char *name; - int ret; - virDomainPtr res; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (NULL); - } - if (uuid == NULL) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (NULL); - } - memset(&req, 0, sizeof(virProxyPacket)); - req.command = VIR_PROXY_LOOKUP_UUID; - req.len = sizeof(virProxyPacket) + VIR_UUID_BUFLEN; - memcpy(&req.extra.str[0], uuid, VIR_UUID_BUFLEN); - - ret = xenProxyCommand(conn, (virProxyPacketPtr) &req, &req, 0); - if (ret < 0) { - xenProxyClose(conn); - return(NULL); - } - if (req.data.arg == -1) { - return(NULL); - } - name = &req.extra.str[0]; - res = virGetDomain(conn, name, uuid); - if (res) res->id = req.data.arg; - return(res); -} - -/** - * xenProxyLookupByName: - * @conn: A xend instance - * @name: The name of the domain - * - * This method looks up information about a domain based on its name - * - * Returns a new domain object or NULL in case of failure - */ -virDomainPtr -xenProxyLookupByName(virConnectPtr conn, const char *name) -{ - virProxyFullPacket req; - int ret, len; - virDomainPtr res; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (NULL); - } - if (name == NULL) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (NULL); - } - len = strlen(name); - if (len > 1000) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (NULL); - } - memset(&req, 0, sizeof(virProxyPacket)); - req.command = VIR_PROXY_LOOKUP_NAME; - req.len = sizeof(virProxyPacket) + len + 1; - strcpy(&req.extra.str[0], name); - ret = xenProxyCommand(conn, (virProxyPacketPtr) &req, &req, 0); - if (ret < 0) { - xenProxyClose(conn); - return(NULL); - } - if (req.data.arg == -1) { - return(NULL); - } - res = virGetDomain(conn, name, (const unsigned char *)&req.extra.str[0]); - if (res) res->id = req.data.arg; - return(res); -} - -/** - * xenProxyNodeGetInfo: - * @conn: pointer to the Xen Daemon block - * @info: pointer to a virNodeInfo structure allocated by the user - * - * Extract hardware information about the node. - * - * Returns 0 in case of success and -1 in case of failure. - */ -static int -xenProxyNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) { - virProxyPacket req; - virProxyFullPacket ans; - int ret; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (-1); - } - if (info == NULL) { - virProxyError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (-1); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_NODE_INFO; - req.data.arg = 0; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(conn); - return(-1); - } - if (ans.data.arg == -1) { - return(-1); - } - if (ans.len != sizeof(virProxyPacket) + sizeof(virNodeInfo)) { - return(-1); - } - memcpy(info, &ans.extra.ninfo, sizeof(virNodeInfo)); - return(0); -} - -/** - * xenProxyGetCapabilities: - * @conn: pointer to the Xen Daemon block - * - * Extract capabilities of the hypervisor. - * - * Returns capabilities in case of success (freed by caller) - * and NULL in case of failure. - */ -static char * -xenProxyGetCapabilities (virConnectPtr conn) -{ - virProxyPacket req; - virProxyFullPacket ans; - int ret, xmllen; - char *xml; - - if (!VIR_IS_CONNECT(conn)) { - virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); - return NULL; - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_GET_CAPABILITIES; - req.data.arg = 0; - req.len = sizeof(req); - ret = xenProxyCommand(conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(conn); - return NULL; - } - if (ans.data.arg == -1) - return NULL; - if (ans.len <= sizeof(virProxyPacket)) { - virProxyError(conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - return NULL; - } - - xmllen = ans.len - sizeof (virProxyPacket); - xml = malloc (xmllen+1); - if (!xml) { - virProxyError (conn, VIR_ERR_NO_MEMORY, __FUNCTION__); - return NULL; - } - memmove (xml, ans.extra.str, xmllen); - xml[xmllen] = '\0'; - - return xml; -} - -/** - * xenProxyDomainDumpXML: - * @domain: a domain object - * @flags: xml generation flags - * - * This method generates an XML description of a domain. - * - * Returns the XML document on success, NULL otherwise. - */ -static char * -xenProxyDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) -{ - virProxyPacket req; - virProxyFullPacket ans; - int ret; - int xmllen; - char *xml; - - if (!VIR_IS_CONNECTED_DOMAIN(domain)) { - if (domain == NULL) - virProxyError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - else - virProxyError(domain->conn, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - return (NULL); - } - if (domain->id < 0) - return (NULL); - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_DOMAIN_XML; - req.data.arg = domain->id; - req.len = sizeof(req); - ret = xenProxyCommand(domain->conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(domain->conn); - return(NULL); - } - if (ans.len <= sizeof(virProxyPacket)) { - virProxyError(domain->conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - return (NULL); - } - xmllen = ans.len - sizeof(virProxyPacket); - if (!(xml = malloc(xmllen+1))) { - virProxyError(domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); - return NULL; - } - memmove(xml, &ans.extra.dinfo, xmllen); - xml[xmllen] = '\0'; - - return(xml); -} - -/** - * xenProxyDomainGetOSType: - * @domain: a domain object - * - * Get the type of domain operation system. - * - * Returns the new string or NULL in case of error, the string must be - * freed by the caller. - */ -static char * -xenProxyDomainGetOSType(virDomainPtr domain) -{ - virProxyPacket req; - virProxyFullPacket ans; - int ret; - int oslen; - char *ostype; - - if (!VIR_IS_CONNECTED_DOMAIN(domain)) { - if (domain == NULL) - virProxyError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - else - virProxyError(domain->conn, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); - return (NULL); - } - memset(&req, 0, sizeof(req)); - req.command = VIR_PROXY_DOMAIN_OSTYPE; - req.data.arg = domain->id; - req.len = sizeof(req); - ret = xenProxyCommand(domain->conn, &req, &ans, 0); - if (ret < 0) { - xenProxyClose(domain->conn); - return(NULL); - } - if ((ans.len == sizeof(virProxyPacket)) && (ans.data.arg < 0)) { - return(NULL); - } - - if (ans.len <= sizeof(virProxyPacket)) { - virProxyError(domain->conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); - return (NULL); - } - oslen = ans.len - sizeof(virProxyPacket); - if (!(ostype = malloc(oslen+1))) { - virProxyError(domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); - return NULL; - } - memmove(ostype, &ans.extra.dinfo, oslen); - ostype[oslen] = '\0'; - - return(ostype); -} - -/* - * vim: set tabstop=4: - * vim: set shiftwidth=4: - * vim: set expandtab: - */ -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff -r d676d6414f07 src/proxy_internal.h --- a/src/proxy_internal.h Tue Sep 18 14:23:22 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * proxy.h: common definitions for proxy usage - * - * Copyright (C) 2006 Red Hat, Inc. - * - * See COPYING.LIB for the License of this software - * - * Daniel Veillard - */ - - -#ifndef __LIBVIR_PROXY_H__ -#define __LIBVIR_PROXY_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PROXY_SOCKET_PATH "/tmp/livirt_proxy_conn" -#define PROXY_PROTO_VERSION 1 - -/* - * the command allowed though the proxy - */ -typedef enum { - VIR_PROXY_NONE = 0, - VIR_PROXY_VERSION = 1, - VIR_PROXY_NODE_INFO = 2, - VIR_PROXY_LIST = 3, - VIR_PROXY_NUM_DOMAIN = 4, - VIR_PROXY_LOOKUP_ID = 5, - VIR_PROXY_LOOKUP_UUID = 6, - VIR_PROXY_LOOKUP_NAME = 7, - VIR_PROXY_MAX_MEMORY = 8, - VIR_PROXY_DOMAIN_INFO = 9, - VIR_PROXY_DOMAIN_XML = 10, - VIR_PROXY_DOMAIN_OSTYPE = 11, - VIR_PROXY_GET_CAPABILITIES = 12 -} virProxyCommand; - -/* - * structure used by the client to make a request to the proxy - * and by the proxy when answering the client. - * the size may not be fixed, it's passed as len. - */ -struct _virProxyPacket { - unsigned short version; /* version of the proxy protocol */ - unsigned short command; /* command number a virProxyCommand */ - unsigned short serial; /* command serial number */ - unsigned short len; /* the length of the request */ - union { - char string[8]; /* string data */ - int arg; /* or int argument */ - long larg; /* or long argument */ - } data; -}; -typedef struct _virProxyPacket virProxyPacket; -typedef virProxyPacket *virProxyPacketPtr; - -/* - * If there is extra data sent from the proxy to the client, - * they are appended after the packet. - * the size may not be fixed, it's passed as len and includes the - * extra data. - */ -struct _virProxyFullPacket { - unsigned short version; /* version of the proxy protocol */ - unsigned short command; /* command number a virProxyCommand */ - unsigned short serial; /* command serial number */ - unsigned short len; /* the length of the request */ - union { - char string[8]; /* string data */ - int arg; /* or int argument */ - long larg; /* or long argument */ - } data; - /* that should be aligned on a 16bytes boundary */ - union { - char str[4080]; /* extra char array */ - int arg[1020]; /* extra int array */ - virDomainInfo dinfo; /* domain information */ - virNodeInfo ninfo; /* node information */ - } extra; -}; -typedef struct _virProxyFullPacket virProxyFullPacket; -typedef virProxyFullPacket *virProxyFullPacketPtr; - -/* xen_unified makes direct calls or indirect calls through here. */ -extern struct xenUnifiedDriver xenProxyDriver; -extern int xenProxyInit (void); - -extern virDomainPtr xenProxyLookupByID(virConnectPtr conn, int id); -extern virDomainPtr xenProxyLookupByUUID(virConnectPtr conn, - const unsigned char *uuid); -extern virDomainPtr xenProxyLookupByName(virConnectPtr conn, - const char *domname); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* __LIBVIR_PROXY_H__ */ - -/* - * vim: set tabstop=4: - * vim: set shiftwidth=4: - * vim: set expandtab: - */ -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff -r d676d6414f07 src/xen_unified.c --- a/src/xen_unified.c Tue Sep 18 14:23:22 2007 -0400 +++ b/src/xen_unified.c Tue Sep 18 14:29:40 2007 -0400 @@ -12,10 +12,10 @@ /* Note: * - * This driver provides a unified interface to the five - * separate underlying Xen drivers (xen_internal, proxy_internal, + * This driver provides a unified interface to the four + * separate underlying Xen drivers (xen_internal, * xend_internal, xs_internal and xm_internal). Historically - * the body of libvirt.c handled the five Xen drivers, + * the body of libvirt.c handled the four Xen drivers, * and contained Xen-specific code. */ @@ -32,7 +32,6 @@ #include "xen_unified.h" #include "xen_internal.h" -#include "proxy_internal.h" #include "xend_internal.h" #include "xs_internal.h" #include "xm_internal.h" @@ -40,7 +39,6 @@ /* The five Xen drivers below us. */ static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = { [XEN_UNIFIED_HYPERVISOR_OFFSET] = &xenHypervisorDriver, - [XEN_UNIFIED_PROXY_OFFSET] = &xenProxyDriver, [XEN_UNIFIED_XEND_OFFSET] = &xenDaemonDriver, [XEN_UNIFIED_XS_OFFSET] = &xenStoreDriver, [XEN_UNIFIED_XM_OFFSET] = &xenXMDriver, @@ -78,7 +76,7 @@ static int static int xenUnifiedOpen (virConnectPtr conn, const char *name, int flags) { - int i, j; + int i, j, success = 0; xenUnifiedPrivatePtr priv; xmlURIPtr uri; @@ -134,7 +132,6 @@ xenUnifiedOpen (virConnectPtr conn, cons priv->len = -1; priv->addr = NULL; priv->xshandle = NULL; - priv->proxy = -1; for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) { priv->opened[i] = 0; @@ -144,16 +141,14 @@ xenUnifiedOpen (virConnectPtr conn, cons priv->xendConfigVersion > 2) continue; - /* Ignore proxy for root */ - if (i == XEN_UNIFIED_PROXY_OFFSET && getuid() == 0) - continue; - if (drivers[i]->open) { #ifdef ENABLE_DEBUG fprintf (stderr, "libvirt: xenUnifiedOpen: trying Xen sub-driver %d\n", i); #endif - if (drivers[i]->open (conn, name, flags) == VIR_DRV_OPEN_SUCCESS) + if (drivers[i]->open (conn, name, flags) == VIR_DRV_OPEN_SUCCESS) { priv->opened[i] = 1; + success = 1; + } #ifdef ENABLE_DEBUG fprintf (stderr, "libvirt: xenUnifiedOpen: Xen sub-driver %d open %s\n", i, priv->opened[i] ? "ok" : "failed"); @@ -161,9 +156,8 @@ xenUnifiedOpen (virConnectPtr conn, cons } /* If as root, then all drivers must succeed. - If non-root, then only proxy must succeed */ - if (!priv->opened[i] && - (getuid() == 0 || i == XEN_UNIFIED_PROXY_OFFSET)) { + If non-root, then pass off to remote driver */ + if (!priv->opened[i] && getuid() == 0) { for (j = 0; j < i; ++j) if (priv->opened[j]) drivers[j]->close (conn); free (priv->name); @@ -175,7 +169,7 @@ xenUnifiedOpen (virConnectPtr conn, cons } } - return VIR_DRV_OPEN_SUCCESS; + return success ? VIR_DRV_OPEN_SUCCESS : VIR_DRV_OPEN_DECLINED; } #define GET_PRIVATE(conn) \ @@ -239,9 +233,6 @@ xenUnifiedVersion (virConnectPtr conn, u return -1; } -/* NB: Even if connected to the proxy, we're still on the - * same machine. - */ static char * xenUnifiedGetHostname (virConnectPtr conn) { @@ -394,13 +385,6 @@ xenUnifiedDomainLookupByID (virConnectPt return ret; } - /* Try proxy. */ - if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) { - ret = xenProxyLookupByID (conn, id); - if (ret || conn->err.code != VIR_ERR_OK) - return ret; - } - /* Try xend. */ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) { ret = xenDaemonLookupByID (conn, id); @@ -432,13 +416,6 @@ xenUnifiedDomainLookupByUUID (virConnect return ret; } - /* Try proxy. */ - if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) { - ret = xenProxyLookupByUUID (conn, uuid); - if (ret || conn->err.code != VIR_ERR_OK) - return ret; - } - /* Try xend. */ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) { ret = xenDaemonLookupByUUID (conn, uuid); @@ -469,13 +446,6 @@ xenUnifiedDomainLookupByName (virConnect * there is one hanging around from a previous call. */ virConnResetLastError (conn); - - /* Try proxy. */ - if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) { - ret = xenProxyLookupByName (conn, name); - if (ret || conn->err.code != VIR_ERR_OK) - return ret; - } /* Try xend. */ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) { @@ -1127,7 +1097,6 @@ xenUnifiedRegister (void) { /* Ignore failures here. */ (void) xenHypervisorInit (); - (void) xenProxyInit (); (void) xenDaemonInit (); (void) xenStoreInit (); (void) xenXMInit (); diff -r d676d6414f07 src/xen_unified.h --- a/src/xen_unified.h Tue Sep 18 14:23:22 2007 -0400 +++ b/src/xen_unified.h Tue Sep 18 14:29:40 2007 -0400 @@ -20,11 +20,10 @@ extern int xenUnifiedRegister (void); extern int xenUnifiedRegister (void); #define XEN_UNIFIED_HYPERVISOR_OFFSET 0 -#define XEN_UNIFIED_PROXY_OFFSET 1 -#define XEN_UNIFIED_XEND_OFFSET 2 -#define XEN_UNIFIED_XS_OFFSET 3 -#define XEN_UNIFIED_XM_OFFSET 4 -#define XEN_UNIFIED_NR_DRIVERS 5 +#define XEN_UNIFIED_XEND_OFFSET 1 +#define XEN_UNIFIED_XS_OFFSET 2 +#define XEN_UNIFIED_XM_OFFSET 3 +#define XEN_UNIFIED_NR_DRIVERS 4 /* _xenUnifiedDriver: *