diff --git a/ChangeLog b/ChangeLog index 5de2a51750..59d3afb865 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Oct 24 12:32:23 BST Daniel P. Berrange + + * src/openvz_conf.c, src/openvz_conf.h: Extract version + info from vzctl tool + * src/openvz_driver.c: Implement the getVersion API call. + Fri Oct 24 12:30:23 BST Daniel P. Berrange Fix mingw build diff --git a/src/openvz_conf.c b/src/openvz_conf.c index 5c70f630ee..9fb867f310 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "openvz_conf.h" #include "uuid.h" @@ -64,6 +65,73 @@ strtoI(const char *str) return val; } + +static int +openvzExtractVersionInfo(const char *cmd, int *retversion) +{ + const char *const vzarg[] = { cmd, "--help", NULL }; + const char *const vzenv[] = { "LC_ALL=C", NULL }; + pid_t child; + int newstdout = -1; + int ret = -1, status; + unsigned int major, minor, micro; + unsigned int version; + + if (retversion) + *retversion = 0; + + if (virExec(NULL, vzarg, vzenv, NULL, + &child, -1, &newstdout, NULL, VIR_EXEC_NONE) < 0) + return -1; + + char *help = NULL; + int len = virFileReadLimFD(newstdout, 512, &help); + if (len < 0) + goto cleanup2; + + if (sscanf(help, "vzctl version %u.%u.%u", + &major, &minor, µ) != 3) { + goto cleanup2; + } + + version = (major * 1000 * 1000) + (minor * 1000) + micro; + + if (retversion) + *retversion = version; + + ret = 0; + +cleanup2: + VIR_FREE(help); + if (close(newstdout) < 0) + ret = -1; + +rewait: + if (waitpid(child, &status, 0) != child) { + if (errno == EINTR) + goto rewait; + ret = -1; + } + + return ret; +} + +int openvzExtractVersion(virConnectPtr conn, + struct openvz_driver *driver) +{ + if (driver->version > 0) + return 0; + + if (openvzExtractVersionInfo(VZCTL, &driver->version) < 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("Cound not extract vzctl version")); + return -1; + } + + return 0; +} + + virCapsPtr openvzCapsInit(void) { struct utsname utsname; diff --git a/src/openvz_conf.h b/src/openvz_conf.h index c02ac98d04..ac604dc518 100644 --- a/src/openvz_conf.h +++ b/src/openvz_conf.h @@ -47,15 +47,18 @@ enum { OPENVZ_WARN, OPENVZ_ERR }; /* OpenVZ commands - Replace with wrapper scripts later? */ -#define VZLIST "vzlist" -#define VZCTL "vzctl" +#define VZLIST "/usr/sbin/vzlist" +#define VZCTL "/usr/sbin/vzctl" struct openvz_driver { virCapsPtr caps; virDomainObjList domains; + int version; }; int openvz_readline(int fd, char *ptr, int maxlen); +int openvzExtractVersion(virConnectPtr conn, + struct openvz_driver *driver); int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen); virCapsPtr openvzCapsInit(void); int openvzLoadDomains(struct openvz_driver *driver); diff --git a/src/openvz_driver.c b/src/openvz_driver.c index 2d0ddaa2b0..b166b0656c 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -172,6 +172,12 @@ static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, return dom; } +static int openvzGetVersion(virConnectPtr conn, unsigned long *version) { + struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; + *version = driver->version; + return 0; +} + static char *openvzGetOSType(virDomainPtr dom) { struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; @@ -777,6 +783,9 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn, if (openvzLoadDomains(driver) < 0) goto cleanup; + if (openvzExtractVersion(conn, driver) < 0) + goto cleanup; + conn->privateData = driver; return VIR_DRV_OPEN_SUCCESS; @@ -961,7 +970,7 @@ static virDriver openvzDriver = { openvzClose, /* close */ NULL, /* supports_feature */ openvzGetType, /* type */ - NULL, /* version */ + openvzGetVersion, /* version */ NULL, /* hostname */ NULL, /* uri */ openvzGetMaxVCPUs, /* getMaxVcpus */