Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
daemon/Makefile.am | 2 +
daemon/libvirtd.c | 3 +
src/Makefile.am | 20 +++++-
src/cpu/cpu_driver.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/cpu/cpu_driver.h | 40 +++++++++++
src/datatypes.h | 2 +
6 files changed, 256 insertions(+), 1 deletions(-)
create mode 100644 src/cpu/cpu_driver.c
create mode 100644 src/cpu/cpu_driver.h
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index ab3f238..d239a89 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -110,6 +110,8 @@ endif
if WITH_NODE_DEVICES
libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
endif
+
+ libvirtd_LDADD += ../src/libvirt_driver_cpu.la
endif
libvirtd_LDADD += ../src/libvirt.la
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 6b7e33d..56c16dc 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -94,6 +94,7 @@
#include "node_device/node_device_driver.h"
#endif
#include "secret/secret_driver.h"
+#include "cpu/cpu_driver.h"
#endif
@@ -867,6 +868,7 @@ static struct qemud_server *qemudInitialize(void) {
virDriverLoadModule("lxc");
virDriverLoadModule("uml");
virDriverLoadModule("one");
+ virDriverLoadModule("cpu");
#else
#ifdef WITH_NETWORK
networkRegister();
@@ -893,6 +895,7 @@ static struct qemud_server *qemudInitialize(void) {
#ifdef WITH_ONE
oneRegister();
#endif
+ cpuRegister();
#endif
virEventRegisterImpl(virEventAddHandleImpl,
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d731de..3551a10 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -289,6 +289,9 @@ CPU_SOURCES = \
EXTRA_DIST += cpu/cpu_map.xml
+CPU_DRIVER_SOURCES = \
+ cpu/cpu_driver.h cpu/cpu_driver.c
+
#########################
#
# Build up list of libvirt.la source files based on configure conditions
@@ -696,6 +699,20 @@ libvirt_driver_security_la_CFLAGS += $(APPARMOR_CFLAGS)
libvirt_driver_security_la_LDFLAGS += $(APPARMOR_LIBS)
endif
+
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_cpu.la
+else
+noinst_LTLIBRARIES += libvirt_driver_cpu.la
+libvirt_la_LIBADD += libvirt_driver_cpu.la
+endif
+libvirt_driver_cpu_la_CFLAGS = \
+ -I@top_srcdir@/src/conf
+if WITH_DRIVER_MODULES
+libvirt_driver_cpu_la_LDFLAGS = -module -avoid-version
+endif
+libvirt_driver_cpu_la_SOURCES = $(CPU_DRIVER_SOURCES)
+
# Add all conditional sources just in case...
EXTRA_DIST += \
$(TEST_DRIVER_SOURCES) \
@@ -724,7 +741,8 @@ EXTRA_DIST += \
$(SECURITY_DRIVER_SELINUX_SOURCES) \
$(SECURITY_DRIVER_APPARMOR_SOURCES) \
$(SECRET_DRIVER_SOURCES) \
- $(VBOX_DRIVER_EXTRA_DIST)
+ $(VBOX_DRIVER_EXTRA_DIST) \
+ $(CPU_DRIVER_SOURCES)
check-local:
if WITH_QEMU
diff --git a/src/cpu/cpu_driver.c b/src/cpu/cpu_driver.c
new file mode 100644
index 0000000..60425b4
--- /dev/null
+++ b/src/cpu/cpu_driver.c
@@ -0,0 +1,190 @@
+/*
+ * cpu_driver.c: Unified CPU driver; unified interface to architecture
+ * specific CPU drivers.
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Jiri Denemark <jdenemar(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "memory.h"
+#include "datatypes.h"
+#include "virterror_internal.h"
+#include "logging.h"
+#include "driver.h"
+
+#include "cpu_driver.h"
+#include "cpu.h"
+
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+
+
+struct cpu_driver {
+ virMutex lock;
+
+ virCPUDefPtr host_cpu;
+};
+
+
+static virCPUDefPtr
+cpuParseString(virConnectPtr conn,
+ const char *cpu,
+ enum virCPUType mode)
+{
+ xmlDocPtr xml = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ virCPUDefPtr def = NULL;
+
+ xml = xmlParseMemory(cpu, strlen(cpu));
+
+ if (xml == NULL || (ctxt = xmlXPathNewContext(xml)) == NULL) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
+
+ ctxt->node = xmlDocGetRootElement(xml);
+ def = virCPUDefParseXML(conn, ctxt->node, ctxt, mode);
+
+cleanup:
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml);
+
+ return def;
+}
+
+
+static virCPUDefPtr
+cpuGetHostCPU(virConnectPtr conn)
+{
+ virCPUDefPtr cpu;
+ const char *xml;
+
+ if (conn->driver == NULL || conn->driver->getHostCPU == NULL) {
+ virCPUReportError(conn, VIR_ERR_NO_SUPPORT, "virConnectGetHostCPU");
+ goto error;
+ }
+
+ if ((xml = conn->driver->getHostCPU(conn)) == NULL)
+ goto error;
+
+ cpu = cpuParseString(conn, xml, VIR_CPU_TYPE_HOST);
+ VIR_FREE(xml);
+
+ if (cpu != NULL)
+ return cpu;
+
+error:
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot get host CPU"));
+ return NULL;
+}
+
+
+static void
+cpuDriverLock(struct cpu_driver *driver)
+{
+ virMutexLock(&driver->lock);
+}
+
+
+static void
+cpuDriverUnlock(struct cpu_driver *driver)
+{
+ virMutexUnlock(&driver->lock);
+}
+
+
+static virDrvOpenStatus
+cpuDriverOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED)
+{
+ struct cpu_driver *driver;
+
+ if (VIR_ALLOC(driver) < 0) {
+ virReportOOMError(conn);
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ conn->cpuPrivateData = driver;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+static int
+cpuDriverClose(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ struct cpu_driver *driver = conn->cpuPrivateData;
+
+ if (driver != NULL)
+ virCPUDefFree(driver->host_cpu);
+
+ conn->cpuPrivateData = NULL;
+
+ VIR_FREE(driver);
+
+ return 0;
+}
+
+
+static int
+cpuDriverCompare(virConnectPtr conn,
+ const char *xml)
+{
+ struct cpu_driver *driver = conn->cpuPrivateData;
+ virCPUDefPtr cpu = NULL;
+ int ret = VIR_CPU_COMPARE_ERROR;
+
+ VIR_DEBUG("conn=%p, xml=%s", conn, xml);
+
+ cpuDriverLock(driver);
+
+ if ((cpu = cpuParseString(conn, xml, VIR_CPU_TYPE_AUTO)) == NULL)
+ goto cleanup;
+
+ if (driver->host_cpu == NULL &&
+ (driver->host_cpu = cpuGetHostCPU(conn)) == NULL)
+ goto cleanup;
+
+ ret = cpuCompare(conn, driver->host_cpu, cpu);
+
+cleanup:
+ cpuDriverUnlock(driver);
+
+ virCPUDefFree(cpu);
+ return ret;
+}
+
+
+virCPUDriver driver = {
+ .name = "cpu",
+ .open = cpuDriverOpen,
+ .close = cpuDriverClose,
+
+ .compare = cpuDriverCompare
+};
+
+
+int cpuRegister(void)
+{
+ return virRegisterCPUDriver(&driver);
+}
diff --git a/src/cpu/cpu_driver.h b/src/cpu/cpu_driver.h
new file mode 100644
index 0000000..51b7314
--- /dev/null
+++ b/src/cpu/cpu_driver.h
@@ -0,0 +1,40 @@
+/*
+ * cpu_driver.c: Unified CPU driver; unified interface to architecture
+ * specific CPU drivers.
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Jiri Denemark <jdenemar(a)redhat.com>
+ */
+
+#ifndef __VIR_CPU_DRIVER_H__
+#define __VIR_CPU_DRIVER_H__
+
+#include "driver.h"
+#include "virterror_internal.h"
+#include "cpu_conf.h"
+
+
+#define virCPUReportError(conn, code, fmt...) \
+ virReportErrorHelper(conn, VIR_FROM_CPU, code, __FILE__, \
+ __FUNCTION__, __LINE__, fmt)
+
+
+int cpuRegister(void);
+
+#endif /* __VIR_CPU_DRIVER_H__ */
diff --git a/src/datatypes.h b/src/datatypes.h
index afb51dc..685aacc 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -141,6 +141,7 @@ struct _virConnect {
virStorageDriverPtr storageDriver;
virDeviceMonitorPtr deviceMonitor;
virSecretDriverPtr secretDriver;
+ virCPUDriverPtr cpuDriver;
/* Private data pointer which can be used by driver and
* network driver as they wish.
@@ -152,6 +153,7 @@ struct _virConnect {
void * storagePrivateData;
void * devMonPrivateData;
void * secretPrivateData;
+ void * cpuPrivateData;
/*
* The lock mutex must be acquired before accessing/changing
--
1.6.5.6