+Thu Jun 29 22:19:51 EDT 2006 Daniel Veillard <veillard@redhat.com>
+
+ * src/proxy_internal.c src/proxy_internal.h src/driver.h src/libvirt.c
+ src/Makefile.am: moved proxy/proxy.h and proxy/proxy_client.c as
+ proxy_internal.[ch] and integrated them as a new driver.
+ * proxy/Makefile.am proxy/libvirt_proxy.c src/xen_internal.c
+ src/xen_internal.h src/xend_internal.c: various related cleanups.
+
Thu Jun 29 14:53:01 EDT 2006 Daniel Veillard <veillard@redhat.com>
* proxy/libvirt_proxy.c proxy/proxy.h proxy/proxy_client.c: more
INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include \
-I@top_srcdir@/proxy -I@top_srcdir@/src @LIBXML_CFLAGS@ \
- -DBINDIR=\""$(libexecdir)"\" \
- -DBUILDDIR=\""$(top_builddir)"\" \
-DXEN_RO
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
-
libvirt_proxy_LDFLAGS =
libvirt_proxy_DEPENDENCIES =
libvirt_proxy_LDADD =
-noinst_PROGRAMS= test_proxy
-test_proxy_SOURCES = proxy_client.c
-test_proxy_LDFLAGS =
-test_proxy_DEPENDENCIES =
-test_proxy_LDADD =
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include "proxy.h"
#include "internal.h"
+#include "proxy_internal.h"
#include "xen_internal.h"
#include "xend_internal.h"
int ret;
if ((nr <= 0) || (nr > nbClients) || (req == NULL) ||
- (req->len < sizeof(virProxyPacket)) || (req->len > 4096) ||
+ (req->len < sizeof(virProxyPacket)) ||
+ (req->len > sizeof(virProxyFullPacket)) ||
(pollInfos[nr].fd < 0)) {
fprintf(stderr, "write to client %d in error", nr);
proxyCloseClientSocket(nr);
*/
static int
proxyReadClientSocket(int nr) {
- char buffer[4096];
- virProxyPacketPtr req;
+ virProxyFullPacket request;
+ virProxyPacketPtr req = (virProxyPacketPtr) &request;
int ret;
retry:
- ret = read(pollInfos[nr].fd, buffer, sizeof(virProxyPacket));
+ ret = read(pollInfos[nr].fd, req, sizeof(virProxyPacket));
if (ret < 0) {
if (errno == EINTR) {
if (debug > 0)
fprintf(stderr, "read %d bytes from client %d on socket %d\n",
ret, nr, pollInfos[nr].fd);
- req = (virProxyPacketPtr) &buffer[0];
if ((req->version != PROXY_PROTO_VERSION) ||
(req->len < sizeof(virProxyPacket)))
goto comm_error;
if (req->len != sizeof(virProxyPacket))
goto comm_error;
- maxids = (sizeof(buffer) - sizeof(virProxyPacket)) / sizeof(int);
- maxids -= 10; /* just to be sure that should still be plenty */
- ret = xenHypervisorListDomains(conn,
- (int *) &buffer[sizeof(virProxyPacket)],
+ 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 = 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:
case VIR_PROXY_NODE_INFO:
case VIR_PROXY_LOOKUP_ID:
+++ /dev/null
-/*
- * proxy.h: common definitions for proxy usage
- *
- * Copyright (C) 2006 Red Hat, Inc.
- *
- * See COPYING.LIB for the License of this software
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-
-#ifndef __LIBVIR_PROXY_H__
-#define __LIBVIR_PROXY_H__
-
-#include <libvirt/libvirt.h>
-
-#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
-} 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 {
- int arg[1020]; /* extra int array */
- } extra;
-};
-typedef struct _virProxyFullPacket virProxyFullPacket;
-typedef virProxyFullPacket *virProxyFullPacketPtr;
-/*
- * Functions callable from libvirt library
- */
-int xenProxyInit(virConnectPtr conn);
-void xenProxyClose(virConnectPtr conn);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __LIBVIR_PROXY_H__ */
+++ /dev/null
-/*
- * 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 <veillard@redhat.com>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include "proxy.h"
-#include "internal.h"
-
-#define STANDALONE
-
-static int debug = 1;
-
-/************************************************************************
- * *
- * 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)
-{
- if (error == VIR_ERR_OK)
- return;
-
-#if 0
- const char *errmsg;
-
- errmsg = __virErrorMsg(error, info);
- __virRaiseError(conn, NULL, VIR_FROM_XEND, error, VIR_ERR_ERROR,
- errmsg, info, NULL, 0, 0, errmsg, info);
-#endif
-}
-
-/************************************************************************
- * *
- * 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[] = {
-#ifdef STANDALONE
- "/usr/bin/libvirt_proxy_dbg",
-#endif
- BINDIR "/libvirt_proxy",
- 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) {
- 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 (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- fprintf(stderr, "Failed to connect to socket %s\n", path);
- 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
- *
- * 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 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;
- }
- 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
- */
-void
-xenProxyClose(virConnectPtr conn) {
- if ((conn == NULL) || (conn->proxy < 0))
- return;
- virProxyCloseClientSocket(conn->proxy);
- conn->proxy = -1;
-}
-
-static int
-xenProxyCommand(virConnectPtr conn, virProxyPacketPtr request,
- virProxyFullPacketPtr answer) {
- static int serial = 0;
- int ret;
- virProxyPacketPtr res = NULL;
-
- if ((conn == NULL) || (conn->proxy < 0))
- 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(conn->proxy, (const char *) request,
- request->len);
- if (ret < 0)
- return(-1);
-retry:
- if (answer == NULL) {
- /* read in situ */
- ret = virProxyReadClientSocket(conn->proxy, (char *) request,
- sizeof(virProxyPacket));
- if (ret < 0)
- return(-1);
- if (ret != sizeof(virProxyPacket)) {
- fprintf(stderr,
- "Communication error with proxy: got %d bytes of %d\n",
- ret, 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",
- sizeof(virProxyPacket), res->len);
- xenProxyClose(conn);
- return(-1);
- }
- } else {
- /* read in packet provided */
- ret = virProxyReadClientSocket(conn->proxy, (char *) answer,
- sizeof(virProxyPacket));
- if (ret < 0)
- return(-1);
- if (ret != sizeof(virProxyPacket)) {
- fprintf(stderr,
- "Communication error with proxy: got %d bytes of %d\n",
- ret, 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(conn->proxy,
- &(answer->extra.arg[0]),
- res->len - ret);
- if (ret != (int) (res->len - sizeof(virProxyPacket))) {
- fprintf(stderr,
- "Communication error with proxy: got %d bytes of %d\n",
- ret, 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, "gor asynchronous packet number %d\n", res->serial);
- goto retry;
- }
- return(0);
-}
-
-/**
- * xenProxyInit:
- * @conn: pointer to the hypervisor connection
- *
- * Try to initialize the Xen proxy communication layer
- *
- * Returns 0 in case of success, and -1 in case of failure
- */
-int
-xenProxyInit(virConnectPtr conn) {
- virProxyPacket req;
- int ret;
- int fd;
-
- if (!VIR_IS_CONNECT(conn)) {
- virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->proxy <= 0) {
- fd = virProxyOpenClientSocket(PROXY_SOCKET_PATH);
- if (fd < 0) {
- return(-1);
- }
- conn->proxy = fd;
- }
-
- memset(&req, 0, sizeof(req));
- req.command = VIR_PROXY_NONE;
- req.len = sizeof(req);
- ret = xenProxyCommand(conn, &req, NULL);
- if ((ret < 0) || (req.command != VIR_PROXY_NONE)) {
- 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);
- if (ret < 0) {
- xenProxyClose(conn);
- return(-1);
- }
- *hvVer = req.data.larg;
- return(0);
-}
-
-/**
- * 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) {
-}
-
-/**
- * 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);
- if (ret < 0) {
- xenProxyClose(conn);
- return(-1);
- }
- nb = ans.data.arg;
- if ((nb > 1020) || (nb <= 0))
- 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;
- int nb;
-
- 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);
- if (ret < 0) {
- xenProxyClose(conn);
- return(-1);
- }
- return(req.data.arg);
-}
-
-/**
- * xenProxyLookupByID:
- * @conn: pointer to the hypervisor connection
- * @id: the domain ID number
- *
- * Try to find a domain based on the hypervisor ID number
- *
- * Returns the domain name (to be freed) or NULL in case of failure
- */
-static char *
-xenProxyLookupByID(virConnectPtr conn, int id) {
-}
-
-/**
- * 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 the domain id or -1 in case of error
- */
-static int
-xenProxyLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
-{
-}
-
-/**
- * xenProxyDomainLookupByName:
- * @conn: A xend instance
- * @name: The name of the domain
- *
- * This method looks up information about a domain based on its name
- *
- * Returns domain id or -1 in case of error
- */
-static int
-xenProxyDomainLookupByName(virConnectPtr conn, const char *domname)
-{
-}
-
-
-/**
- * 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.
- */
-unsigned long
-xenProxyDomainGetMaxMemory(virDomainPtr domain)
-{
-}
-
-/**
- * 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
- */
-int
-xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
-{
-}
-
-#ifdef STANDALONE
-int main(int argc, char **argv) {
- int ret;
- unsigned long ver;
- virConnect conn;
-
- memset(&conn, 0, sizeof(conn));
- conn.magic = VIR_CONNECT_MAGIC;
- ret = xenProxyInit(&conn);
- if (ret == 0) {
- ret = xenProxyGetVersion(&conn, &ver);
- if (ret != 0) {
- fprintf(stderr, "Failed to get version from proxy\n");
- } else {
- int ids[50], i;
-
- printf("Proxy running with version %lu\n", ver);
- ret = xenProxyNumOfDomains(&conn);
- printf("There is %d running domains:", ret);
- ret = xenProxyListDomains(&conn, &ids, 50);
- if (ret < 0) {
- fprintf(stderr, "Failed to list domains\n");
- }
- for (i = 0;i < ret;i++)
- printf(" %d", ids[i]);
- printf("\n");
-
- }
- xenProxyClose(&conn);
- }
- exit(0);
-}
-#endif
## Process this file with automake to produce Makefile.in
-INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include @LIBXML_CFLAGS@
+INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include @LIBXML_CFLAGS@ \
+ -DBINDIR=\""$(libexecdir)"\"
DEPS = libvirt.la
LDADDS = @STATIC_BINARIES@ libvirt.la
VIRSH_LIBS = @VIRSH_LIBS@
xend_internal.c xend_internal.h \
sexpr.c sexpr.h \
virterror.c \
- driver.h
+ driver.h \
+ proxy_internal.c proxy_internal.h
bin_PROGRAMS = virsh
VIR_DRV_XEN_HYPERVISOR = 1,
VIR_DRV_XEN_STORE = 2,
VIR_DRV_XEN_DAEMON = 3,
- VIR_DRV_TEST = 4
+ VIR_DRV_TEST = 4,
+ VIR_DRV_XEN_PROXY = 5
} virDrvNo;
#include "xen_internal.h"
#include "xend_internal.h"
#include "xs_internal.h"
+#include "proxy_internal.h"
#include "xml.h"
#include "test.h"
* Note that the order is important the first ones have a higher priority
*/
xenHypervisorRegister();
+ xenProxyRegister();
xenDaemonRegister();
xenStoreRegister();
testRegister();
* all related drivers.
*/
if ((res < 0) && (for_xen) &&
- (!strncasecmp(virDriverTab[i]->name, "xen", 3)))
+ (!strncasecmp(virDriverTab[i]->name, "xen", 3)) &&
+ (virDriverTab[i]->no != VIR_DRV_XEN_PROXY))
goto failed;
if (res == 0)
ret->drivers[ret->nb_drivers++] = virDriverTab[i];
--- /dev/null
+/*
+ * 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 <veillard@redhat.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include "internal.h"
+#include "driver.h"
+#include "proxy_internal.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 int xenProxyListDomains(virConnectPtr conn, int *ids, int maxids);
+static int xenProxyNumOfDomains(virConnectPtr conn);
+static virDomainPtr xenProxyLookupByID(virConnectPtr conn, int id);
+static virDomainPtr xenProxyLookupByUUID(virConnectPtr conn,
+ const unsigned char *uuid);
+static virDomainPtr xenProxyDomainLookupByName(virConnectPtr conn,
+ const char *domname);
+static unsigned long xenProxyDomainGetMaxMemory(virDomainPtr domain);
+static int xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info);
+
+static virDriver xenProxyDriver = {
+ VIR_DRV_XEN_PROXY,
+ "XenProxy",
+ 0,
+ NULL, /* init */
+ xenProxyOpen, /* open */
+ xenProxyClose, /* close */
+ NULL, /* type */
+ xenProxyGetVersion, /* version */
+ NULL, /* nodeGetInfo */
+ xenProxyListDomains, /* listDomains */
+ xenProxyNumOfDomains, /* numOfDomains */
+ NULL, /* domainCreateLinux */
+ xenProxyLookupByID, /* domainLookupByID */
+ xenProxyLookupByUUID, /* domainLookupByUUID */
+ xenProxyDomainLookupByName, /* domainLookupByName */
+ NULL, /* domainSuspend */
+ NULL, /* domainResume */
+ NULL, /* domainShutdown */
+ NULL, /* domainReboot */
+ NULL, /* domainDestroy */
+ NULL, /* domainFree */
+ NULL, /* domainGetName */
+ NULL, /* domainGetID */
+ NULL, /* domainGetUUID */
+ NULL, /* domainGetOSType */
+ xenProxyDomainGetMaxMemory, /* domainGetMaxMemory */
+ NULL, /* domainSetMaxMemory */
+ NULL, /* domainSetMemory */
+ xenProxyDomainGetInfo, /* domainGetInfo */
+ NULL, /* domainSave */
+ NULL /* domainRestore */
+};
+
+/**
+ * xenProxyRegister:
+ *
+ * Registers the xenHypervisor driver
+ */
+void xenProxyRegister(void)
+{
+ virRegisterDriver(&xenProxyDriver);
+}
+/************************************************************************
+ * *
+ * 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, VIR_FROM_XEND, 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
+ *
+ * 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 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;
+ }
+ 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) {
+ if ((conn == NULL) || (conn->proxy < 0))
+ return(-1);
+ virProxyCloseClientSocket(conn->proxy);
+ conn->proxy = -1;
+ return (0);
+}
+
+static int
+xenProxyCommand(virConnectPtr conn, virProxyPacketPtr request,
+ virProxyFullPacketPtr answer) {
+ static int serial = 0;
+ int ret;
+ virProxyPacketPtr res = NULL;
+
+ if ((conn == NULL) || (conn->proxy < 0))
+ 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(conn->proxy, (const char *) request,
+ request->len);
+ if (ret < 0)
+ return(-1);
+retry:
+ if (answer == NULL) {
+ /* read in situ */
+ ret = virProxyReadClientSocket(conn->proxy, (char *) request,
+ sizeof(virProxyPacket));
+ if (ret < 0)
+ return(-1);
+ if (ret != sizeof(virProxyPacket)) {
+ fprintf(stderr,
+ "Communication error with proxy: got %d bytes of %d\n",
+ ret, 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",
+ sizeof(virProxyPacket), res->len);
+ xenProxyClose(conn);
+ return(-1);
+ }
+ } else {
+ /* read in packet provided */
+ ret = virProxyReadClientSocket(conn->proxy, (char *) answer,
+ sizeof(virProxyPacket));
+ if (ret < 0)
+ return(-1);
+ if (ret != sizeof(virProxyPacket)) {
+ fprintf(stderr,
+ "Communication error with proxy: got %d bytes of %d\n",
+ ret, 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(conn->proxy,
+ (char *) &(answer->extra.arg[0]),
+ res->len - ret);
+ if (ret != (int) (res->len - sizeof(virProxyPacket))) {
+ fprintf(stderr,
+ "Communication error with proxy: got %d bytes of %d\n",
+ ret, 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, "gor asynchronous packet number %d\n", res->serial);
+ goto retry;
+ }
+ return(0);
+}
+
+/**
+ * xenProxyInit:
+ * @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, int flags)
+{
+ virProxyPacket req;
+ int ret;
+ int fd;
+
+ if ((name != NULL) && (strcasecmp(name, "xen")))
+ return(-1);
+ if (!(flags & VIR_DRV_OPEN_RO))
+ return(-1);
+
+ conn->proxy = -1;
+ fd = virProxyOpenClientSocket(PROXY_SOCKET_PATH);
+ if (fd < 0) {
+ if (!(flags & VIR_DRV_OPEN_QUIET))
+ virProxyError(conn, VIR_ERR_NO_XEN, PROXY_SOCKET_PATH);
+ return(-1);
+ }
+ conn->proxy = fd;
+
+ memset(&req, 0, sizeof(req));
+ req.command = VIR_PROXY_NONE;
+ req.len = sizeof(req);
+ ret = xenProxyCommand(conn, &req, NULL);
+ if ((ret < 0) || (req.command != VIR_PROXY_NONE)) {
+ virProxyError(conn, 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);
+ 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);
+ 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);
+ 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 (-1);
+ }
+ memset(&req, 0, sizeof(req));
+ req.command = VIR_PROXY_MAX_MEMORY;
+ req.data.arg = id;
+ req.len = sizeof(req);
+ ret = xenProxyCommand(conn, &req, NULL);
+ if (ret < 0) {
+ xenProxyClose(conn);
+ return(-1);
+ }
+ 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);
+ }
+ return(xenProxyDomainGetDomMaxMemory(domain->conn, domain->handle));
+}
+
+/**
+ * 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 (0);
+ }
+ 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.len = sizeof(req);
+ ret = xenProxyCommand(domain->conn, &req, &ans);
+ 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
+ */
+static virDomainPtr
+xenProxyLookupByID(virConnectPtr conn, int id)
+{
+ TODO
+ return(NULL);
+}
+
+/**
+ * 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
+ */
+static virDomainPtr
+xenProxyLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
+{
+ TODO
+ return(NULL);
+}
+
+/**
+ * xenProxyDomainLookupByName:
+ * @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
+ */
+static virDomainPtr
+xenProxyDomainLookupByName(virConnectPtr conn, const char *domname)
+{
+ TODO
+ return(NULL);
+}
+
+/**
+ * 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) {
+ TODO
+ return(-1);
+}
+
--- /dev/null
+/*
+ * proxy.h: common definitions for proxy usage
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ *
+ * See COPYING.LIB for the License of this software
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+
+#ifndef __LIBVIR_PROXY_H__
+#define __LIBVIR_PROXY_H__
+
+#include <libvirt/libvirt.h>
+
+#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
+} 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 informations */
+ } extra;
+};
+typedef struct _virProxyFullPacket virProxyFullPacket;
+typedef virProxyFullPacket *virProxyFullPacketPtr;
+/*
+ * Functions callable from libvirt library
+ */
+void xenProxyRegister(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __LIBVIR_PROXY_H__ */
}
/**
- * xenHypervisorGetMaxMemory:
- * @domain: a domain object or NULL
+ * xenHypervisorGetDomMaxMemory:
+ * @conn: connection data
+ * @id: domain id
*
* Retrieve the maximum amount of physical memory allocated to a
- * domain. If domain is NULL, then this get the amount of memory reserved
- * to Domain0 i.e. the domain where the application runs.
+ * domain.
*
* Returns the memory size in kilobytes or 0 in case of error.
*/
-static unsigned long
-xenHypervisorGetMaxMemory(virDomainPtr domain)
+unsigned long
+xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id)
{
dom0_op_t op;
dom0_getdomaininfo_t dominfo;
int ret;
- if ((domain == NULL) || (domain->conn == NULL) ||
- (domain->conn->handle < 0))
+ if ((conn == NULL) || (conn->handle < 0))
return (0);
memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t));
}
op.cmd = DOM0_GETDOMAININFOLIST;
- op.u.getdomaininfolist.first_domain = (domid_t) domain->handle;
+ op.u.getdomaininfolist.first_domain = (domid_t) id;
op.u.getdomaininfolist.max_domains = 1;
op.u.getdomaininfolist.buffer = &dominfo;
op.u.getdomaininfolist.num_domains = 1;
- dominfo.domain = domain->handle;
+ dominfo.domain = id;
- ret = xenHypervisorDoOp(domain->conn->handle, &op);
+ ret = xenHypervisorDoOp(conn->handle, &op);
if (munlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release",
return((unsigned long) dominfo.max_pages * 4);
}
+/**
+ * xenHypervisorGetMaxMemory:
+ * @domain: a domain object or NULL
+ *
+ * Retrieve the maximum amount of physical memory allocated to a
+ * domain. If domain is NULL, then this get the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ *
+ * Returns the memory size in kilobytes or 0 in case of error.
+ */
+static unsigned long
+xenHypervisorGetMaxMemory(virDomainPtr domain)
+{
+ if ((domain == NULL) || (domain->conn == NULL) ||
+ (domain->conn->handle < 0))
+ return (0);
+
+ return(xenHypervisorGetDomMaxMemory(domain->conn, domain->handle));
+}
+
/**
* xenHypervisorGetDomainInfo:
* @domain: pointer to the domain block
int xenHypervisorClose (virConnectPtr conn);
int xenHypervisorGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+unsigned long
+ xenHypervisorGetDomMaxMemory (virConnectPtr conn,
+ int id);
int xenHypervisorNumOfDomains (virConnectPtr conn);
int xenHypervisorListDomains (virConnectPtr conn,
int *ids,
}
if (connect(s, xend->addr, xend->len) == -1) {
- virXendError(xend, VIR_ERR_NO_CONNECT, "Xen Daemon");
serrno = errno;
close(s);
errno = serrno;
return (ret);
}
+#ifndef XEN_RO
/**
* xenDaemonGetType:
* @conn: pointer to the Xen Daemon block
}
return("XenDaemon");
}
+#endif
/**
* xenDaemonGetVersion:
return(ret);
}
+#ifndef XEN_RO
/**
* xenDaemonLookupByID:
* @conn: pointer to the hypervisor connection
return (NULL);
}
+#endif
+