mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-02 04:15:46 +00:00
* 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
This commit is contained in:
parent
27b7a8be52
commit
c386d9747b
@ -1,3 +1,9 @@
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user