提交 c386d974 编写于 作者: D Daniel Veillard

* proxy/libvirt_proxy.c proxy/proxy.h proxy/proxy_client.c: more

  progresses on the proxy implementation.
* src/xend_internal.c src/xend_internal.h: exported one routine
Daniel
上级 27b7a8be
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
progresses on the proxy implementation.
* src/xend_internal.c src/xend_internal.h: exported one routine
Wed Jun 28 19:23:25 CEST 2006 Daniel Veillard <veillard@redhat.com>
* configure.in Makefile.am proxy/Makefile.am proxy/libvirt_proxy.c
......
......@@ -20,9 +20,11 @@
#include "proxy.h"
#include "internal.h"
#include "xen_internal.h"
#include "xend_internal.h"
static int fdServer = -1;
static int debug = 0;
static int persist = 0;
static int done = 0;
#define MAX_CLIENT 64
......@@ -33,6 +35,8 @@ static struct pollfd pollInfos[MAX_CLIENT + 1];
static virConnect conninfos;
static virConnectPtr conn = &conninfos;
static unsigned long xenVersion = 0;
/************************************************************************
* *
* Interfaces with the Xen hypervisor *
......@@ -49,17 +53,34 @@ static virConnectPtr conn = &conninfos;
static int
proxyInitXen(void) {
int ret;
unsigned long xenVersion2;
ret = xenHypervisorOpen(conn, NULL, VIR_DRV_OPEN_QUIET);
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 = 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);
}
......@@ -342,7 +363,7 @@ retry:
goto comm_error;
if (debug)
fprintf(stderr, "Gor command %d from client %d\n", req->command, nr);
fprintf(stderr, "Got command %d from client %d\n", req->command, nr);
switch (req->command) {
case VIR_PROXY_NONE:
......@@ -352,17 +373,39 @@ retry:
case VIR_PROXY_VERSION:
if (req->len != sizeof(virProxyPacket))
goto comm_error;
TODO;
req->data.larg = 3 * 1000000 + 2;
req->data.larg = xenVersion;
break;
case VIR_PROXY_NODE_INFO:
case VIR_PROXY_LIST:
case VIR_PROXY_LIST: {
int maxids;
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);
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:
case VIR_PROXY_DOMAIN_INFO:
case VIR_PROXY_NODE_INFO:
case VIR_PROXY_LOOKUP_ID:
case VIR_PROXY_LOOKUP_UUID:
case VIR_PROXY_LOOKUP_NAME:
case VIR_PROXY_MAX_MEMORY:
case VIR_PROXY_DOMAIN_INFO:
TODO;
break;
default:
goto comm_error;
......@@ -399,7 +442,7 @@ proxyProcessRequests(void) {
*/
ret = poll(&pollInfos[0], nbClients + 1, 1000);
if (ret == 0) { /* timeout */
if (nbClients == 0) {
if ((nbClients == 0) && (persist == 0)) {
exit_timeout--;
if (exit_timeout == 0) {
done = 1;
......@@ -465,10 +508,8 @@ proxyMainLoop(void) {
if (proxyListenUnixSocket(PROXY_SOCKET_PATH) < 0)
break;
proxyProcessRequests();
proxyCloseUnixSocket();
}
proxyCloseClientSockets();
proxyCloseUnixSocket();
}
/**
......@@ -497,6 +538,8 @@ int main(int argc, char **argv) {
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);
......@@ -508,7 +551,22 @@ int main(int argc, char **argv) {
/* exit(1); */
}
proxyInitXen();
proxyMainLoop();
/*
* 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);
}
......@@ -56,6 +56,29 @@ struct _virProxyPacket {
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
*/
......
......@@ -42,12 +42,12 @@ static int debug = 1;
static void
virProxyError(virConnectPtr conn, virErrorNumber error, const char *info)
{
const char *errmsg;
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);
......@@ -71,8 +71,7 @@ virProxyFindServerPath(void)
{
static const char *serverPaths[] = {
#ifdef STANDALONE
"./libvirt_proxy",
BUILDDIR "/proxy/libvirt_proxy",
"/usr/bin/libvirt_proxy_dbg",
#endif
BINDIR "/libvirt_proxy",
NULL
......@@ -320,11 +319,10 @@ xenProxyClose(virConnectPtr conn) {
static int
xenProxyCommand(virConnectPtr conn, virProxyPacketPtr request,
virProxyPacketPtr *answer) {
virProxyFullPacketPtr answer) {
static int serial = 0;
int ret;
virProxyPacketPtr res = NULL;
char packet[4096];
if ((conn == NULL) || (conn->proxy < 0))
return(-1);
......@@ -364,8 +362,8 @@ retry:
return(-1);
}
} else {
/* read in packet and duplicate if needed */
ret = virProxyReadClientSocket(conn->proxy, &packet[0],
/* read in packet provided */
ret = virProxyReadClientSocket(conn->proxy, (char *) answer,
sizeof(virProxyPacket));
if (ret < 0)
return(-1);
......@@ -376,9 +374,9 @@ retry:
xenProxyClose(conn);
return(-1);
}
res = (virProxyPacketPtr) &packet[0];
res = (virProxyPacketPtr) answer;
if ((res->len < sizeof(virProxyPacket)) ||
(res->len > sizeof(packet))) {
(res->len > sizeof(virProxyFullPacket))) {
fprintf(stderr,
"Communication error with proxy: got %d bytes packet\n",
res->len);
......@@ -386,7 +384,8 @@ retry:
return(-1);
}
if (res->len > sizeof(virProxyPacket)) {
ret = virProxyReadClientSocket(conn->proxy, &packet[ret],
ret = virProxyReadClientSocket(conn->proxy,
&(answer->extra.arg[0]),
res->len - ret);
if (ret != (int) (res->len - sizeof(virProxyPacket))) {
fprintf(stderr,
......@@ -412,8 +411,6 @@ retry:
fprintf(stderr, "gor asynchronous packet number %d\n", res->serial);
goto retry;
}
if (answer != NULL)
*answer = res;
return(0);
}
......@@ -431,9 +428,10 @@ xenProxyInit(virConnectPtr conn) {
int ret;
int fd;
if (conn == NULL)
return(-1);
if (!VIR_IS_CONNECT(conn)) {
virProxyError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
}
if (conn->proxy <= 0) {
fd = virProxyOpenClientSocket(PROXY_SOCKET_PATH);
......@@ -517,14 +515,41 @@ xenProxyNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) {
* @maxids: size of @ids
*
* Collect the list of active domains, and store their ID in @maxids
* TODO: this is quite expensive at the moment since there isn't one
* xend RPC providing both name and id for all domains.
*
* 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);
}
/**
......@@ -538,6 +563,23 @@ xenProxyListDomains(virConnectPtr conn, int *ids, int maxids)
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);
}
/**
......@@ -617,13 +659,26 @@ int main(int argc, char **argv) {
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);
}
......
......@@ -38,7 +38,6 @@
static const char * xenDaemonGetType(virConnectPtr conn);
static int xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
static int xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer);
static int xenDaemonListDomains(virConnectPtr conn, int *ids, int maxids);
static int xenDaemonNumOfDomains(virConnectPtr conn);
static virDomainPtr xenDaemonLookupByID(virConnectPtr conn, int id);
......@@ -885,24 +884,24 @@ urlencode(const char *string)
* Returns 0 in case of success, -1 in case of error.
*/
int
xenDaemonOpen_unix(virConnectPtr xend, const char *path)
xenDaemonOpen_unix(virConnectPtr conn, const char *path)
{
struct sockaddr_un *addr;
if ((xend == NULL) || (path == NULL))
if ((conn == NULL) || (path == NULL))
return (-1);
addr = &xend->addr_un;
addr = &conn->addr_un;
addr->sun_family = AF_UNIX;
memset(addr->sun_path, 0, sizeof(addr->sun_path));
strncpy(addr->sun_path, path, sizeof(addr->sun_path));
xend->len = sizeof(addr->sun_family) + strlen(addr->sun_path);
if ((unsigned int) xend->len > sizeof(addr->sun_path))
xend->len = sizeof(addr->sun_path);
conn->len = sizeof(addr->sun_family) + strlen(addr->sun_path);
if ((unsigned int) conn->len > sizeof(addr->sun_path))
conn->len = sizeof(addr->sun_path);
xend->addr = (struct sockaddr *) addr;
xend->type = PF_UNIX;
conn->addr = (struct sockaddr *) addr;
conn->type = PF_UNIX;
return (0);
}
......@@ -919,18 +918,18 @@ xenDaemonOpen_unix(virConnectPtr xend, const char *path)
* Returns 0 in case of success, -1 in case of error.
*/
int
xenDaemonOpen_tcp(virConnectPtr xend, const char *host, int port)
xenDaemonOpen_tcp(virConnectPtr conn, const char *host, int port)
{
struct in_addr ip;
struct hostent *pent;
if ((xend == NULL) || (host == NULL) || (port <= 0))
if ((conn == NULL) || (host == NULL) || (port <= 0))
return (-1);
pent = gethostbyname(host);
if (pent == NULL) {
if (inet_aton(host, &ip) == 0) {
virXendError(xend, VIR_ERR_UNKNOWN_HOST, host);
virXendError(conn, VIR_ERR_UNKNOWN_HOST, host);
errno = ESRCH;
return (-1);
}
......@@ -938,13 +937,13 @@ xenDaemonOpen_tcp(virConnectPtr xend, const char *host, int port)
memcpy(&ip, pent->h_addr_list[0], sizeof(ip));
}
xend->len = sizeof(struct sockaddr_in);
xend->addr = (struct sockaddr *) &xend->addr_in;
xend->type = PF_INET;
conn->len = sizeof(struct sockaddr_in);
conn->addr = (struct sockaddr *) &conn->addr_in;
conn->type = PF_INET;
xend->addr_in.sin_family = AF_INET;
xend->addr_in.sin_port = htons(port);
memcpy(&xend->addr_in.sin_addr, &ip, sizeof(ip));
conn->addr_in.sin_family = AF_INET;
conn->addr_in.sin_port = htons(port);
memcpy(&conn->addr_in.sin_addr, &ip, sizeof(ip));
return (0);
}
......@@ -2128,7 +2127,7 @@ xenDaemonGetType(virConnectPtr conn)
* 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
int
xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer)
{
static unsigned long version = 0;
......
......@@ -600,6 +600,7 @@ int xenDaemonDomainLookupByName_ids(virConnectPtr xend,
void xenDaemonRegister(void);
int xenDaemonOpen(virConnectPtr conn, const char *name, int flags);
int xenDaemonClose(virConnectPtr conn);
int xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer);
int xenDaemonDomainSuspend(virDomainPtr domain);
int xenDaemonDomainResume(virDomainPtr domain);
int xenDaemonDomainShutdown(virDomainPtr domain);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册