[libvirt] [PATCH 11/14] CPU driver implementation

Jiri Denemark jdenemar at redhat.com
Mon Dec 14 22:35:14 UTC 2009


Signed-off-by: Jiri Denemark <jdenemar at 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 at 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 at 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 at 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




More information about the libvir-list mailing list