Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- 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@xxxxxxxxxx> + */ + +#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@xxxxxxxxxx> + */ + +#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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list