From d762148aafd186a499c1a919ac4b13620e0792d7 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 7 Nov 2006 16:28:16 +0000 Subject: [PATCH] * libvirt.spec.in: libvirt-devel depends on pkgconfig * proxy/libvirt_proxy.c src/libvirt.c src/proxy_internal.[ch] src/xs_internal.[ch]: the virtGetOsType entry point was calling the xenstore directly instead of going though driver, refactored and implemented a specific new RPC with the proxy when this is called as non-root fixes rhbz#214264 . Daniel --- ChangeLog | 9 ++++++ libvirt.spec.in | 1 + po/en_GB.po | 58 +++++++++++++++++------------------ po/libvirt.pot | 58 +++++++++++++++++------------------ proxy/libvirt_proxy.c | 23 +++++++++++++- src/libvirt.c | 15 ++++++--- src/proxy_internal.c | 55 +++++++++++++++++++++++++++++++-- src/proxy_internal.h | 1 + src/xs_internal.c | 71 ++++++++++++++++++++++++++++++++++++++++++- src/xs_internal.h | 9 ++++-- 10 files changed, 231 insertions(+), 69 deletions(-) diff --git a/ChangeLog b/ChangeLog index db6b39ba6..a170060bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Tue Nov 7 16:33:43 CET 2006 Daniel Veillard + + * libvirt.spec.in: libvirt-devel depends on pkgconfig + * proxy/libvirt_proxy.c src/libvirt.c src/proxy_internal.[ch] + src/xs_internal.[ch]: the virtGetOsType entry point was calling + the xenstore directly instead of going though driver, refactored + and implemented a specific new RPC with the proxy when this is + called as non-root fixes rhbz#214264 . + Tue Oct 31 10:31:34 CET 2006 Daniel Veillard * src/xend_internal.c: when getting informations about a non diff --git a/libvirt.spec.in b/libvirt.spec.in index 2361f90e3..7eb8f0e33 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -30,6 +30,7 @@ and the virsh command line tool to control virtual domains. Summary: Libraries, includes, etc. to compile with the libvirt library Group: Development/Libraries Requires: libvirt = %{version} +Requires: pkgconfig Obsoletes: libvir-devel %description devel diff --git a/po/en_GB.po b/po/en_GB.po index 443524e14..d59e4b382 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: libvirt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-16 17:09+0200\n" +"POT-Creation-Date: 2006-11-07 16:20+0100\n" "PO-Revision-Date: 2006-09-20 10:20-0400\n" "Last-Translator: Daniel Berrange \n" "Language-Team: English \n" @@ -369,9 +369,9 @@ msgid "allocate new context" msgstr "" #: src/hash.c:628 src/hash.c:634 src/test.c:725 src/test.c:750 src/test.c:773 -#: src/test.c:797 src/xend_internal.c:1911 src/xend_internal.c:2607 -#: src/xend_internal.c:2818 src/xs_internal.c:592 src/proxy_internal.c:790 -#: src/proxy_internal.c:837 src/proxy_internal.c:888 +#: src/test.c:797 src/xend_internal.c:1912 src/xend_internal.c:2608 +#: src/xend_internal.c:2819 src/xs_internal.c:594 src/proxy_internal.c:791 +#: src/proxy_internal.c:838 src/proxy_internal.c:889 msgid "allocating domain" msgstr "" @@ -491,7 +491,7 @@ msgstr "" msgid "growing buffer" msgstr "" -#: src/xml.c:116 src/xend_internal.c:1602 src/xend_internal.c:1621 +#: src/xml.c:116 src/xend_internal.c:1603 src/xend_internal.c:1622 msgid "allocate new buffer" msgstr "" @@ -511,61 +511,61 @@ msgstr "" msgid "failed to read from Xen Daemon" msgstr "" -#: src/xend_internal.c:1056 +#: src/xend_internal.c:1057 msgid "failed to urlencode the create S-Expr" msgstr "" -#: src/xend_internal.c:1097 +#: src/xend_internal.c:1098 msgid "domain information incomplete, missing domid" msgstr "" -#: src/xend_internal.c:1103 +#: src/xend_internal.c:1104 msgid "domain information incorrect domid not numeric" msgstr "" -#: src/xend_internal.c:1110 src/xend_internal.c:1159 +#: src/xend_internal.c:1111 src/xend_internal.c:1160 msgid "domain information incomplete, missing uuid" msgstr "" -#: src/xend_internal.c:1150 src/xend_internal.c:1491 +#: src/xend_internal.c:1151 src/xend_internal.c:1492 msgid "domain information incomplete, missing name" msgstr "" -#: src/xend_internal.c:1408 src/xend_internal.c:1433 +#: src/xend_internal.c:1409 src/xend_internal.c:1434 msgid "domain information incomplete, missing kernel" msgstr "" -#: src/xend_internal.c:1581 +#: src/xend_internal.c:1582 msgid "domain information incomplete, vbd has no src" msgstr "" -#: src/xend_internal.c:1587 +#: src/xend_internal.c:1588 msgid "domain information incomplete, vbd has no dev" msgstr "" -#: src/xend_internal.c:1595 +#: src/xend_internal.c:1596 msgid "cannot parse vbd filename, missing driver name" msgstr "" -#: src/xend_internal.c:1614 +#: src/xend_internal.c:1615 msgid "cannot parse vbd filename, missing driver type" msgstr "" -#: src/xend_internal.c:1922 +#: src/xend_internal.c:1923 msgid "failed to parse Xend domain information" msgstr "" -#: src/xend_internal.c:2882 +#: src/xend_internal.c:2883 #, c-format msgid "Failed to create domain %s\n" msgstr "" -#: src/xend_internal.c:2888 +#: src/xend_internal.c:2889 #, c-format msgid "Failed to get devices for domain %s\n" msgstr "" -#: src/xend_internal.c:2899 +#: src/xend_internal.c:2900 #, c-format msgid "Failed to resume new domain %s\n" msgstr "" @@ -1370,51 +1370,51 @@ msgstr "" msgid "failed to save content" msgstr "" -#: src/xs_internal.c:318 +#: src/xs_internal.c:320 msgid "failed to connect to Xen Store" msgstr "" -#: src/proxy_internal.c:193 +#: src/proxy_internal.c:194 #, c-format msgid "failed to exec %s\n" msgstr "" -#: src/proxy_internal.c:287 +#: src/proxy_internal.c:288 #, c-format msgid "Failed to close socket %d\n" msgstr "" -#: src/proxy_internal.c:320 +#: src/proxy_internal.c:321 #, c-format msgid "Failed to read socket %d\n" msgstr "" -#: src/proxy_internal.c:354 +#: src/proxy_internal.c:355 #, c-format msgid "Failed to write to socket %d\n" msgstr "" -#: src/proxy_internal.c:416 src/proxy_internal.c:437 src/proxy_internal.c:457 +#: src/proxy_internal.c:417 src/proxy_internal.c:438 src/proxy_internal.c:458 #, c-format msgid "Communication error with proxy: got %d bytes of %d\n" msgstr "" -#: src/proxy_internal.c:424 +#: src/proxy_internal.c:425 #, c-format msgid "Communication error with proxy: expected %d bytes got %d\n" msgstr "" -#: src/proxy_internal.c:446 +#: src/proxy_internal.c:447 #, c-format msgid "Communication error with proxy: got %d bytes packet\n" msgstr "" -#: src/proxy_internal.c:470 +#: src/proxy_internal.c:471 #, c-format msgid "Communication error with proxy: malformed packet\n" msgstr "" -#: src/proxy_internal.c:476 +#: src/proxy_internal.c:477 #, c-format msgid "got asynchronous packet number %d\n" msgstr "" diff --git a/po/libvirt.pot b/po/libvirt.pot index 8ac1c5c5e..beb3f74de 100644 --- a/po/libvirt.pot +++ b/po/libvirt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-16 17:09+0200\n" +"POT-Creation-Date: 2006-11-07 16:20+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -369,9 +369,9 @@ msgid "allocate new context" msgstr "" #: src/hash.c:628 src/hash.c:634 src/test.c:725 src/test.c:750 src/test.c:773 -#: src/test.c:797 src/xend_internal.c:1911 src/xend_internal.c:2607 -#: src/xend_internal.c:2818 src/xs_internal.c:592 src/proxy_internal.c:790 -#: src/proxy_internal.c:837 src/proxy_internal.c:888 +#: src/test.c:797 src/xend_internal.c:1912 src/xend_internal.c:2608 +#: src/xend_internal.c:2819 src/xs_internal.c:594 src/proxy_internal.c:791 +#: src/proxy_internal.c:838 src/proxy_internal.c:889 msgid "allocating domain" msgstr "" @@ -491,7 +491,7 @@ msgstr "" msgid "growing buffer" msgstr "" -#: src/xml.c:116 src/xend_internal.c:1602 src/xend_internal.c:1621 +#: src/xml.c:116 src/xend_internal.c:1603 src/xend_internal.c:1622 msgid "allocate new buffer" msgstr "" @@ -511,61 +511,61 @@ msgstr "" msgid "failed to read from Xen Daemon" msgstr "" -#: src/xend_internal.c:1056 +#: src/xend_internal.c:1057 msgid "failed to urlencode the create S-Expr" msgstr "" -#: src/xend_internal.c:1097 +#: src/xend_internal.c:1098 msgid "domain information incomplete, missing domid" msgstr "" -#: src/xend_internal.c:1103 +#: src/xend_internal.c:1104 msgid "domain information incorrect domid not numeric" msgstr "" -#: src/xend_internal.c:1110 src/xend_internal.c:1159 +#: src/xend_internal.c:1111 src/xend_internal.c:1160 msgid "domain information incomplete, missing uuid" msgstr "" -#: src/xend_internal.c:1150 src/xend_internal.c:1491 +#: src/xend_internal.c:1151 src/xend_internal.c:1492 msgid "domain information incomplete, missing name" msgstr "" -#: src/xend_internal.c:1408 src/xend_internal.c:1433 +#: src/xend_internal.c:1409 src/xend_internal.c:1434 msgid "domain information incomplete, missing kernel" msgstr "" -#: src/xend_internal.c:1581 +#: src/xend_internal.c:1582 msgid "domain information incomplete, vbd has no src" msgstr "" -#: src/xend_internal.c:1587 +#: src/xend_internal.c:1588 msgid "domain information incomplete, vbd has no dev" msgstr "" -#: src/xend_internal.c:1595 +#: src/xend_internal.c:1596 msgid "cannot parse vbd filename, missing driver name" msgstr "" -#: src/xend_internal.c:1614 +#: src/xend_internal.c:1615 msgid "cannot parse vbd filename, missing driver type" msgstr "" -#: src/xend_internal.c:1922 +#: src/xend_internal.c:1923 msgid "failed to parse Xend domain information" msgstr "" -#: src/xend_internal.c:2882 +#: src/xend_internal.c:2883 #, c-format msgid "Failed to create domain %s\n" msgstr "" -#: src/xend_internal.c:2888 +#: src/xend_internal.c:2889 #, c-format msgid "Failed to get devices for domain %s\n" msgstr "" -#: src/xend_internal.c:2899 +#: src/xend_internal.c:2900 #, c-format msgid "Failed to resume new domain %s\n" msgstr "" @@ -1370,51 +1370,51 @@ msgstr "" msgid "failed to save content" msgstr "" -#: src/xs_internal.c:318 +#: src/xs_internal.c:320 msgid "failed to connect to Xen Store" msgstr "" -#: src/proxy_internal.c:193 +#: src/proxy_internal.c:194 #, c-format msgid "failed to exec %s\n" msgstr "" -#: src/proxy_internal.c:287 +#: src/proxy_internal.c:288 #, c-format msgid "Failed to close socket %d\n" msgstr "" -#: src/proxy_internal.c:320 +#: src/proxy_internal.c:321 #, c-format msgid "Failed to read socket %d\n" msgstr "" -#: src/proxy_internal.c:354 +#: src/proxy_internal.c:355 #, c-format msgid "Failed to write to socket %d\n" msgstr "" -#: src/proxy_internal.c:416 src/proxy_internal.c:437 src/proxy_internal.c:457 +#: src/proxy_internal.c:417 src/proxy_internal.c:438 src/proxy_internal.c:458 #, c-format msgid "Communication error with proxy: got %d bytes of %d\n" msgstr "" -#: src/proxy_internal.c:424 +#: src/proxy_internal.c:425 #, c-format msgid "Communication error with proxy: expected %d bytes got %d\n" msgstr "" -#: src/proxy_internal.c:446 +#: src/proxy_internal.c:447 #, c-format msgid "Communication error with proxy: got %d bytes packet\n" msgstr "" -#: src/proxy_internal.c:470 +#: src/proxy_internal.c:471 #, c-format msgid "Communication error with proxy: malformed packet\n" msgstr "" -#: src/proxy_internal.c:476 +#: src/proxy_internal.c:477 #, c-format msgid "got asynchronous packet number %d\n" msgstr "" diff --git a/proxy/libvirt_proxy.c b/proxy/libvirt_proxy.c index 37f987b08..22b1ac08a 100644 --- a/proxy/libvirt_proxy.c +++ b/proxy/libvirt_proxy.c @@ -337,7 +337,7 @@ proxyReadClientSocket(int nr) { virProxyFullPacket request; virProxyPacketPtr req = (virProxyPacketPtr) &request; int ret; - char *xml; + char *xml, *ostype; retry: ret = read(pollInfos[nr].fd, req, sizeof(virProxyPacket)); @@ -587,6 +587,27 @@ retry2: 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; } diff --git a/src/libvirt.c b/src/libvirt.c index bedd4346a..bb4edb310 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1239,18 +1239,23 @@ virDomainGetID(virDomainPtr domain) char * virDomainGetOSType(virDomainPtr domain) { - char *vm, *str = NULL; + char *str = NULL; + int i; if (!VIR_IS_DOMAIN(domain)) { virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); return (NULL); } - vm = virDomainGetVM(domain); - if (vm) { - str = virDomainGetVMInfo(domain, vm, "image/ostype"); - free(vm); + for (i = 0;i < domain->conn->nb_drivers;i++) { + if ((domain->conn->drivers[i] != NULL) && + (domain->conn->drivers[i]->domainGetOSType != NULL)) { + str = domain->conn->drivers[i]->domainGetOSType(domain); + if (str != NULL) + break; + } } + if (str == NULL) str = strdup("linux"); diff --git a/src/proxy_internal.c b/src/proxy_internal.c index 7d3d8471f..8ef2511c3 100644 --- a/src/proxy_internal.c +++ b/src/proxy_internal.c @@ -40,6 +40,7 @@ static virDomainPtr xenProxyDomainLookupByName(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); static virDriver xenProxyDriver = { VIR_DRV_XEN_PROXY, @@ -66,7 +67,7 @@ static virDriver xenProxyDriver = { NULL, /* domainGetName */ NULL, /* domainGetID */ NULL, /* domainGetUUID */ - NULL, /* domainGetOSType */ + xenProxyDomainGetOSType, /* domainGetOSType */ xenProxyDomainGetMaxMemory, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ NULL, /* domainSetMemory */ @@ -974,10 +975,60 @@ xenProxyDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) } xmllen = ans.len - sizeof(virProxyPacket); if (!(xml = malloc(xmllen+1))) { - return NULL; + 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->handle; + 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); + } + 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); +} diff --git a/src/proxy_internal.h b/src/proxy_internal.h index 1e5940e25..936cfb6dc 100644 --- a/src/proxy_internal.h +++ b/src/proxy_internal.h @@ -36,6 +36,7 @@ typedef enum { VIR_PROXY_MAX_MEMORY = 8, VIR_PROXY_DOMAIN_INFO = 9, VIR_PROXY_DOMAIN_XML = 10, + VIR_PROXY_DOMAIN_OSTYPE = 11 } virProxyCommand; /* diff --git a/src/xs_internal.c b/src/xs_internal.c index 3f4f7d89b..a687ea9a5 100644 --- a/src/xs_internal.c +++ b/src/xs_internal.c @@ -32,6 +32,8 @@ #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd" #ifndef PROXY +static char *xenStoreDomainGetOSType(virDomainPtr domain); + static virDriver xenStoreDriver = { VIR_DRV_XEN_STORE, "XenStore", @@ -59,7 +61,7 @@ static virDriver xenStoreDriver = { NULL, /* domainGetName */ NULL, /* domainGetID */ NULL, /* domainGetUUID */ - NULL, /* domainGetOSType */ + xenStoreDomainGetOSType, /* domainGetOSType */ xenStoreDomainGetMaxMemory, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ xenStoreDomainSetMemory, /* domainSetMemory */ @@ -656,6 +658,34 @@ xenStoreDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED) */ return(virDomainDoStoreWrite(domain, "control/shutdown", "reboot")); } + +/* + * xenStoreDomainGetOSType: + * @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 * +xenStoreDomainGetOSType(virDomainPtr domain) { + char *vm, *str = NULL; + + if ((domain == NULL) || (domain->conn == NULL)) { + virXenStoreError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return(NULL); + } + + vm = virDomainGetVM(domain); + if (vm) { + str = virDomainGetVMInfo(domain, vm, "image/ostype"); + free(vm); + } + + return (str); +} #endif /* ! PROXY */ /** @@ -698,3 +728,42 @@ int xenStoreDomainGetVNCPort(virConnectPtr conn, int domid) { char * xenStoreDomainGetConsolePath(virConnectPtr conn, int domid) { return virDomainDoStoreQuery(conn, domid, "console/tty"); } + +#ifdef PROXY +/* + * xenStoreDomainGetOSTypeID: + * @conn: pointer to the connection. + * @id: the domain id + * + * 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. + */ +char * +xenStoreDomainGetOSTypeID(virConnectPtr conn, int id) { + char *vm, *str = NULL; + char query[200]; + unsigned int len; + + if (id < 0) + return(NULL); + + + if (conn->xshandle == NULL) + return (NULL); + + snprintf(query, 199, "/local/domain/%d/vm", id); + query[199] = 0; + + vm = xs_read(conn->xshandle, 0, &query[0], &len); + + if (vm) { + snprintf(query, 199, "%s/image/ostype", vm); + str = xs_read(conn->xshandle, 0, &query[0], &len); + free(vm); + } + + return (str); +} +#endif /* PROXY */ diff --git a/src/xs_internal.h b/src/xs_internal.h index ff33357c1..06e023388 100644 --- a/src/xs_internal.h +++ b/src/xs_internal.h @@ -36,8 +36,13 @@ int xenStoreDomainShutdown (virDomainPtr domain); int xenStoreDomainReboot (virDomainPtr domain, unsigned int flags); -int xenStoreDomainGetVNCPort(virConnectPtr conn, int domid); -char * xenStoreDomainGetConsolePath(virConnectPtr conn, int domid); +/* those are entry point for the proxy */ +int xenStoreDomainGetVNCPort(virConnectPtr conn, + int domid); +char * xenStoreDomainGetConsolePath(virConnectPtr conn, + int domid); +char * xenStoreDomainGetOSTypeID(virConnectPtr conn, + int id); #ifdef __cplusplus } -- 2.39.5