From f14093e5096a64c60ca68b2b5067848082d1f2fc Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Fri, 30 Jun 2006 16:23:16 +0000 Subject: [PATCH] * proxy/libvirt_proxy.c src/proxy_internal.c: more bug fixes, virsh starts to work normally over the proxy. Still one entry point missing but it's minor. Daniel --- ChangeLog | 6 +++ proxy/libvirt_proxy.c | 107 ++++++++++++++++++++++++++++++++++++++++-- src/proxy_internal.c | 80 +++++++++++++++++++++++++++++-- 3 files changed, 185 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8cdd9e10d7..e95d36014a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jun 30 16:31:47 EDT 2006 Daniel Veillard + + * proxy/libvirt_proxy.c src/proxy_internal.c: more bug fixes, + virsh starts to work normally over the proxy. Still one entry + point missing but it's minor. + Thu Jun 29 23:57:35 EDT 2006 Daniel Veillard * proxy/libvirt_proxy.c src/proxy_internal.c src/xen_internal.c diff --git a/proxy/libvirt_proxy.c b/proxy/libvirt_proxy.c index 9505c39bf1..fdd96d6728 100644 --- a/proxy/libvirt_proxy.c +++ b/proxy/libvirt_proxy.c @@ -359,12 +359,51 @@ retry: ret, nr, pollInfos[nr].fd); if ((req->version != PROXY_PROTO_VERSION) || - (req->len < sizeof(virProxyPacket))) + (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)) @@ -456,9 +495,71 @@ retry: free(names); break; } + case VIR_PROXY_LOOKUP_UUID: { + char **names; + char **tmp; + int ident, len; + char *name = NULL; + unsigned char uuid[16]; + + if (req->len != sizeof(virProxyPacket) + 16) + 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], 16)) { + 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[16]; + + 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) + 16; + memcpy(&request.extra.str[0], uuid, 16); + req->data.arg = ident; + } + break; + } case VIR_PROXY_NODE_INFO: - case VIR_PROXY_LOOKUP_UUID: - case VIR_PROXY_LOOKUP_NAME: TODO; req->data.arg = -1; break; diff --git a/src/proxy_internal.c b/src/proxy_internal.c index 76a2296a35..b560ba3e66 100644 --- a/src/proxy_internal.c +++ b/src/proxy_internal.c @@ -752,6 +752,10 @@ xenProxyLookupByID(virConnectPtr conn, int id) 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; @@ -788,8 +792,39 @@ xenProxyLookupByID(virConnectPtr conn, int id) static virDomainPtr xenProxyLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - TODO - return(NULL); + 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) + 16; + ret = xenProxyCommand(conn, (virProxyPacketPtr) &req, &req); + 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 == NULL) + virProxyError(conn, VIR_ERR_NO_MEMORY, "Allocating domain"); + else + res->handle = req.data.arg; + + return(res); } /** @@ -802,10 +837,45 @@ xenProxyLookupByUUID(virConnectPtr conn, const unsigned char *uuid) * Returns a new domain object or NULL in case of failure */ static virDomainPtr -xenProxyDomainLookupByName(virConnectPtr conn, const char *domname) +xenProxyDomainLookupByName(virConnectPtr conn, const char *name) { - TODO - return(NULL); + 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); + 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 == NULL) + virProxyError(conn, VIR_ERR_NO_MEMORY, "Allocating domain"); + else + res->handle = req.data.arg; + + return(res); } /**