Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
include/libvirt/virterror.h | 1 +
src/libvirt.c | 129 +++++++++++++++++++++++++++++++++++++++++++
src/util/virterror.c | 5 ++
3 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 30f88e8..85d562e 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -175,6 +175,7 @@ typedef enum {
VIR_ERR_OPERATION_TIMEOUT, /* timeout occurred during operation */
VIR_ERR_MIGRATE_PERSIST_FAILED, /* a migration worked, but making the
VM persist on the dest host failed */
+ VIR_WAR_NO_CPU, /* failed to start cpu driver */
} virErrorNumber;
/**
diff --git a/src/libvirt.c b/src/libvirt.c
index 008e322..997cdcc 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -87,6 +87,8 @@ static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS];
static int virDeviceMonitorTabCount = 0;
static virSecretDriverPtr virSecretDriverTab[MAX_DRIVERS];
static int virSecretDriverTabCount = 0;
+static virCPUDriverPtr virCPUDriverTab[MAX_DRIVERS];
+static int virCPUDriverTabCount = 0;
#ifdef WITH_LIBVIRTD
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
static int virStateDriverTabCount = 0;
@@ -745,6 +747,37 @@ virRegisterSecretDriver(virSecretDriverPtr driver)
}
/**
+ * virRegisterCPUDriver:
+ * @driver: pointer to a cpu driver block
+ *
+ * Register a CPU driver
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterCPUDriver(virCPUDriverPtr driver)
+{
+ if (virInitialize() < 0)
+ return -1;
+
+ if (driver == NULL) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ if (virCPUDriverTabCount >= MAX_DRIVERS) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ DEBUG ("registering %s as cpu driver %d",
+ driver->name, virCPUDriverTabCount);
+
+ virCPUDriverTab[virCPUDriverTabCount] = driver;
+ return virCPUDriverTabCount++;
+}
+
+/**
* virRegisterDriver:
* @driver: pointer to a driver block
*
@@ -1180,6 +1213,25 @@ do_open (const char *name,
}
}
+ for (i = 0; i < virCPUDriverTabCount; i++) {
+ res = virCPUDriverTab[i]->open (ret, auth, flags);
+ DEBUG("cpu driver %d %s returned %s",
+ i, virCPUDriverTab[i]->name,
+ res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
+ (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
+ (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
+ if (res == VIR_DRV_OPEN_ERROR) {
+ if (STREQ(virCPUDriverTab[i]->name, "remote")) {
+ virLibConnWarning (NULL, VIR_WAR_NO_CPU,
+ "Is the daemon running ?");
+ }
+ break;
+ } else if (res == VIR_DRV_OPEN_SUCCESS) {
+ ret->cpuDriver = virCPUDriverTab[i];
+ break;
+ }
+ }
+
return ret;
failed:
@@ -10701,3 +10753,80 @@ error:
virSetConnError(conn);
return -1;
}
+
+
+/**
+ * virConnectCompareCPU:
+ * @conn: virConnect connection
+ * @xml: XML describing the CPU to compare with host CPU
+ *
+ * Returns comparison result according to enum virCPUCompareResult
+ */
+int
+virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc)
+{
+ VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return VIR_CPU_COMPARE_ERROR;
+ }
+ if (xmlDesc == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->cpuDriver != NULL && conn->cpuDriver->compare != NULL) {
+ int ret;
+
+ ret = conn->cpuDriver->compare(conn, xmlDesc);
+ if (ret == VIR_CPU_COMPARE_ERROR)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatibility */
+ virSetConnError(conn);
+ return VIR_CPU_COMPARE_ERROR;
+}
+
+/**
+ * virConnectGetHostCPU:
+ * @conn: virConnect connection
+ *
+ * Returns XML description of host CPU. The returned <cpu> element contains
+ * data from the <cpu> element of host capabilities which correspond to the
+ * structure of <cpu> element in domain configuration XML.
+ */
+char *
+virConnectGetHostCPU(virConnectPtr conn)
+{
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->driver != NULL && conn->driver->getHostCPU != NULL) {
+ char *ret;
+
+ if ((ret = conn->driver->getHostCPU(conn)) != NULL) {
+ VIR_DEBUG("result=%s", ret);
+ return ret;
+ }
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+ /* Copy to connection error object for back compatibility */
+ virSetConnError(conn);
+ return NULL;
+}
diff --git a/src/util/virterror.c b/src/util/virterror.c
index b1a96f8..e70850b 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1109,6 +1109,11 @@ virErrorMsg(virErrorNumber error, const char *info)
errmsg = _("Failed to make domain persistent after
migration");
else
errmsg = _("Failed to make domain persistent after migration:
%s");
+ case VIR_WAR_NO_CPU:
+ if (info == NULL)
+ errmsg = _("Failed to find a cpu driver");
+ else
+ errmsg = _("Failed to find a cpu driver: %s");
break;
}
return (errmsg);
--
1.6.5.6