[libvirt] [PATCH] drvbhyve: Automatically tear down guest domains on shutdown
by Conrad Meyer
Reboot requires more sophistication and is left as a future work item --
but at least part of the plumbing is in place.
---
Looking for feedback. I'm pretty unfamiliar with libvirt; maybe this isn't
quite the right way to do this. Sorry. If you want me to rework it in some way,
just let me know.
I tried to model this off of DrvQEMU, which I knew to support this behavior.
Reboot should probably be processed on a threadpool thread outside of the event
loop, so I omitted it for now.
P.S., the 'read-non-seekable' check test seems to just hang forever on FreeBSD.
I haven't dug into it, but POSIX FIFO behavior is pretty weird.
---
src/Makefile.am | 2 +
src/bhyve/bhyve_monitor.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++
src/bhyve/bhyve_monitor.h | 36 +++++++++
src/bhyve/bhyve_process.c | 14 +++-
4 files changed, 233 insertions(+), 3 deletions(-)
create mode 100644 src/bhyve/bhyve_monitor.c
create mode 100644 src/bhyve/bhyve_monitor.h
diff --git a/src/Makefile.am b/src/Makefile.am
index d8fe624..b6c1701 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -833,6 +833,8 @@ BHYVE_DRIVER_SOURCES = \
bhyve/bhyve_domain.h \
bhyve/bhyve_driver.h \
bhyve/bhyve_driver.c \
+ bhyve/bhyve_monitor.c \
+ bhyve/bhyve_monitor.h \
bhyve/bhyve_process.c \
bhyve/bhyve_process.h \
bhyve/bhyve_utils.h \
diff --git a/src/bhyve/bhyve_monitor.c b/src/bhyve/bhyve_monitor.c
new file mode 100644
index 0000000..cd3cf6e
--- /dev/null
+++ b/src/bhyve/bhyve_monitor.c
@@ -0,0 +1,184 @@
+/*
+ * bhyve_monitor.c: Tear-down or reboot bhyve domains on guest shutdown
+ *
+ * Copyright (C) 2014 Conrad Meyer
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Conrad Meyer <cse.cem(a)gmail.com>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include "bhyve_monitor.h"
+#include "bhyve_process.h"
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virlog.h"
+
+#define VIR_FROM_THIS VIR_FROM_BHYVE
+
+VIR_LOG_INIT("bhyve.bhyve_monitor");
+
+struct _bhyveMonitor {
+ int kq;
+ int watch;
+ virDomainObjPtr vm;
+ bhyveConnPtr driver;
+};
+
+static void
+bhyveMonitorIO(int watch, int kq, int events ATTRIBUTE_UNUSED, void *opaque)
+{
+ const struct timespec zerowait = {};
+ bhyveMonitorPtr mon = opaque;
+ struct kevent kev;
+ int rc, status;
+
+ if (watch != mon->watch || kq != mon->kq) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("event from unexpected fd %d!=%d / watch %d!=%d"),
+ mon->kq, kq, mon->watch, watch);
+ return;
+ }
+
+ rc = kevent(kq, NULL, 0, &kev, 1, &zerowait);
+ if (rc < 0) {
+ virReportSystemError(errno, "%s", _("Unable to query kqueue"));
+ return;
+ }
+
+ if (rc == 0)
+ return;
+
+ if ((kev.flags & EV_ERROR) != 0) {
+ virReportSystemError(kev.data, "%s", _("Unable to query kqueue"));
+ return;
+ }
+
+ if (kev.filter == EVFILT_PROC && (kev.fflags & NOTE_EXIT) != 0) {
+ if ((pid_t)kev.ident != mon->vm->pid) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("event from unexpected proc %ju!=%ju"),
+ (uintmax_t)mon->vm->pid, (uintmax_t)kev.ident);
+ return;
+ }
+
+ status = kev.data;
+ if (WIFSIGNALED(status) && WCOREDUMP(status)) {
+ VIR_ERROR("Guest %s got signal %d and crashed", mon->vm->def->name,
+ WTERMSIG(status));
+ virBhyveProcessStop(mon->driver, mon->vm,
+ VIR_DOMAIN_SHUTOFF_CRASHED);
+ } else if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) == 0) {
+ /* 0 - reboot */
+ /* TODO: Implementing reboot is a little more complicated. */
+ VIR_INFO("Guest %s rebooted; destroying domain.",
+ mon->vm->def->name);
+ virBhyveProcessStop(mon->driver, mon->vm,
+ VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+ } else if (WEXITSTATUS(status) < 3) {
+ /* 1 - shutdown, 2 - halt, 3 - triple fault. others - error */
+ VIR_INFO("Guest %s shut itself down; destroying domain.",
+ mon->vm->def->name);
+ virBhyveProcessStop(mon->driver, mon->vm,
+ VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+ } else {
+ VIR_INFO("Guest %s had an error and exited with status %d; destroying domain.",
+ mon->vm->def->name, WEXITSTATUS(status));
+ virBhyveProcessStop(mon->driver, mon->vm,
+ VIR_DOMAIN_SHUTOFF_UNKNOWN);
+ }
+ }
+ }
+}
+
+static void
+bhyveMonitorRelease(void *opaque)
+{
+ bhyveMonitorPtr mon = opaque;
+
+ VIR_FORCE_CLOSE(mon->kq);
+ virObjectUnref(mon->vm);
+ VIR_FREE(mon);
+}
+
+bhyveMonitorPtr
+bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver)
+{
+ bhyveMonitorPtr mon;
+ struct kevent kev;
+ int rc;
+
+ if (VIR_ALLOC(mon) < 0)
+ return NULL;
+
+ mon->vm = virObjectRef(vm);
+ mon->driver = driver;
+
+ mon->kq = kqueue();
+ if (mon->kq < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("Unable to create kqueue"));
+ goto cleanup;
+ }
+
+ EV_SET(&kev, vm->pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, mon);
+ rc = kevent(mon->kq, &kev, 1, NULL, 0, NULL);
+ if (rc < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("Unable to register process kevent"));
+ goto cleanup;
+ }
+
+ mon->watch = virEventAddHandle(mon->kq,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ bhyveMonitorIO,
+ mon,
+ bhyveMonitorRelease);
+ if (mon->watch < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unable to register monitor events"));
+ goto cleanup;
+ }
+
+ return mon;
+
+ cleanup:
+ bhyveMonitorRelease(mon);
+ return NULL;
+}
+
+void
+bhyveMonitorClose(bhyveMonitorPtr mon)
+{
+
+ if (mon == NULL)
+ return;
+
+ if (mon->watch > 0)
+ virEventRemoveHandle(mon->watch);
+ else
+ bhyveMonitorRelease(mon);
+}
diff --git a/src/bhyve/bhyve_monitor.h b/src/bhyve/bhyve_monitor.h
new file mode 100644
index 0000000..226d878
--- /dev/null
+++ b/src/bhyve/bhyve_monitor.h
@@ -0,0 +1,36 @@
+/*
+ * bhyve_monitor.h: Tear-down or reboot bhyve domains on guest shutdown
+ *
+ * Copyright (C) 2014 Conrad Meyer
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Conrad Meyer <cse.cem(a)gmail.com>
+ */
+
+#ifndef BHYVE_MONITOR_H
+# define BHYVE_MONITOR_H
+
+# include "internal.h"
+# include "domain_conf.h"
+# include "bhyve_utils.h"
+
+typedef struct _bhyveMonitor bhyveMonitor;
+typedef bhyveMonitor *bhyveMonitorPtr;
+
+bhyveMonitorPtr bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver);
+void bhyveMonitorClose(bhyveMonitorPtr mon);
+
+#endif /* BHYVE_MONITOR_H */
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index a30e36a..284641a 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -32,8 +32,9 @@
#include <net/if_tap.h>
#include "bhyve_device.h"
-#include "bhyve_process.h"
#include "bhyve_command.h"
+#include "bhyve_monitor.h"
+#include "bhyve_process.h"
#include "datatypes.h"
#include "virerror.h"
#include "virlog.h"
@@ -209,6 +210,7 @@ virBhyveProcessStart(virConnectPtr conn,
vm->def->id = vm->pid;
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
+ vm->privateData = bhyveMonitorOpen(vm, driver);
if (virDomainSaveStatus(driver->xmlopt,
BHYVE_STATE_DIR,
@@ -268,6 +270,9 @@ virBhyveProcessStop(bhyveConnPtr driver,
return -1;
}
+ if (vm->privateData != NULL)
+ bhyveMonitorClose((bhyveMonitorPtr)vm->privateData);
+
/* First, try to kill 'bhyve' process */
if (virProcessKillPainfully(vm->pid, true) != 0)
VIR_WARN("Failed to gracefully stop bhyve VM '%s' (pid: %d)",
@@ -371,9 +376,12 @@ virBhyveProcessReconnect(virDomainObjPtr vm,
goto cleanup;
proc_argv = kvm_getargv(data->kd, kp, 0);
- if (proc_argv && proc_argv[0])
- if (STREQ(expected_proctitle, proc_argv[0]))
+ if (proc_argv && proc_argv[0]) {
+ if (STREQ(expected_proctitle, proc_argv[0])) {
ret = 0;
+ vm->privateData = bhyveMonitorOpen(vm, data->driver);
+ }
+ }
cleanup:
if (ret < 0) {
--
1.9.3
9 years, 11 months
[libvirt] [PATCH 0/3] qemu: support update graphic device persistently
by Wang Rui
We can change vnc password by using virDomainUpdateDeviceFlags API with
live flag. But it can't be changed with config flag.
1/3: improve the error number when update graphics failed
2/3: refactor the function qemuDomainFindGraphics for the future patch
3/3: support updating vnc/spice auth arguments persistently
Wang Rui (3):
qemu: report properer error number when change graphics failed
qemu: revise qemuDomainFindGraphics to be reused in the future patch
qemu: make persistent update of graphics device supported
src/conf/domain_conf.c | 3 ++-
src/qemu/qemu_driver.c | 38 +++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_hotplug.c | 23 +++++++++++------------
src/qemu/qemu_hotplug.h | 3 +++
4 files changed, 53 insertions(+), 14 deletions(-)
--
1.7.12.4
9 years, 11 months
[libvirt] [PATCH] docs: Create html documentation even if XHTML1 DTD is not available to validate
by Ian Campbell
On a Debian system lacking the w3c-dtd-xhtml package the build fails
with:
$ make -C docs/ formatcaps.html
make: Entering directory '/local/scratch/ianc/devel/libvirt.git/docs'
Generating formatcaps.html.tmp
I/O error : Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
formatcaps.html.in:2: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
^
I/O error : Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
../docs/sitemap.html.in:2: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
^
missing XHTML1 DTD
rm formatcaps.html.tmp
make: Leaving directory '/local/scratch/ianc/devel/libvirt.git/docs'
$ ls docs/formatcaps*
docs/formatcaps.html.in
https://www.redhat.com/archives/libvir-list/2009-November/msg00413.html
suggests that the XHTML1 DTD should not be a hard requirement and the
docs should be generated but not validated if it is not available.
Therefore when the DTD is not available arrange for the .html.tmp file
to be propagated to the .html output.
Signed-off-by: Ian Campbell <ian.campbell(a)citrix.com>
Cc: Daniel Veillard <veillard(a)redhat.com>
---
docs/Makefile.am | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 5485ee9..c5ba688 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -232,7 +232,7 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
$(XMLLINT) --catalogs --nonet --format --valid $< > $(srcdir)/$@ \
|| { rm $(srcdir)/$@ && exit 1; }; \
- else echo "missing XHTML1 DTD" ; fi ; fi
+ else echo "missing XHTML1 DTD"; cat $< > $(srcdir)/$@ ; fi ; fi
%.php.tmp: %.php.in site.xsl page.xsl sitemap.html.in
@if [ -x $(XSLTPROC) ] ; then \
@@ -258,7 +258,7 @@ html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
> /dev/null ; then \
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
$(XMLLINT) --catalogs --nonet --valid --noout $(srcdir)/html/*.html ; \
- else echo "missing XHTML1 DTD" ; fi ; fi
+ else echo "missing XHTML1 DTD"; cat $< > $(srcdir)/$@ ; fi ; fi
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
--
2.1.1
9 years, 11 months
[libvirt] [PATCH] network: don't allow multiple dhcp sections
by Kyle DeFrancia
This resolves: https://bugzilla.redhat.com/show_bug.cgi?id=907779
A <dhcp> element can exist in only one IPv4 address and one IPv6
address per network. This patch enforces that in virNetworkUpdate.
---
src/conf/network_conf.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 067334e..a914962 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -3472,6 +3472,31 @@ virNetworkIpDefByIndex(virNetworkDefPtr def, int
parentIndex) }
static int
+virNetworkDefUpdateCheckMultiDHCP(virNetworkDefPtr def,
+ virNetworkIpDefPtr ipdef)
+{
+ int family = VIR_SOCKET_ADDR_FAMILY(&ipdef->address);
+ size_t i;
+ virNetworkIpDefPtr ip;
+
+ for (i = 0;
+ (ip = virNetworkDefGetIpByIndex(def, family, i));
+ i++) {
+ if (ip != ipdef) {
+ if (ip->nranges || ip->nhosts) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("dhcp is supported only for a "
+ "single %s address on each network"),
+ (family == AF_INET) ? "IPv4" : "IPv6");
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
unsigned int command,
int parentIndex,
@@ -3536,6 +3561,9 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr
def, } else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
+ if (virNetworkDefUpdateCheckMultiDHCP(def, ipdef) < 0)
+ goto cleanup;
+
/* log error if an entry with same name/address/ip already
exists */ for (i = 0; i < ipdef->nhosts; i++) {
if ((host.mac &&
@@ -3643,6 +3671,9 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr
def, if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
+ if (virNetworkDefUpdateCheckMultiDHCP(def, ipdef) < 0)
+ goto cleanup;
+
if (i < ipdef->nranges) {
char *startip = virSocketAddrFormat(&range.start);
char *endip = virSocketAddrFormat(&range.end);
--
2.1.0
9 years, 11 months
[libvirt] [PATCH] cpu-driver: Fix the cross driver function call
by Daniel Hansel
For Intel and PowerPC the implementation is calling a cpu driver
function across driver layers (i.e. from qemu driver directly to cpu
driver).
The correct behavior is to use libvirt API functionality to perform such
a inter-driver call.
This patch introduces a new cpu driver API function getModels() to
retrieve the cpu models. The currect implementation to process the
cpu_map XML content is transferred to the INTEL and PowerPC cpu driver
specific API functions.
Additionally processing the cpu_map XML file is not safe due to the fact
that the cpu map does not exist for all architectures. Therefore it is
better to encapsulate the processing in the architecture specific cpu
drivers.
Signed-off-by: Daniel Hansel <daniel.hansel(a)linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy(a)linux.vnet.ibm.com>
Reviewed-by: Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
---
src/cpu/cpu.c | 68 +++++++++------------------------------------------
src/cpu/cpu.h | 4 +++
src/cpu/cpu_powerpc.c | 37 ++++++++++++++++++++++++++++
src/cpu/cpu_x86.c | 33 +++++++++++++++++++++++++
4 files changed, 86 insertions(+), 56 deletions(-)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 08bec5e..788f688 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -724,43 +724,6 @@ cpuModelIsAllowed(const char *model,
return false;
}
-struct cpuGetModelsData
-{
- char **data;
- size_t len; /* It includes the last element of DATA, which is NULL. */
-};
-
-static int
-cpuGetArchModelsCb(cpuMapElement element,
- xmlXPathContextPtr ctxt,
- void *cbdata)
-{
- char *name;
- struct cpuGetModelsData *data = cbdata;
- if (element != CPU_MAP_ELEMENT_MODEL)
- return 0;
-
- name = virXPathString("string(@name)", ctxt);
- if (name == NULL)
- return -1;
-
- if (!data->data) {
- VIR_FREE(name);
- data->len++;
- return 0;
- }
-
- return VIR_INSERT_ELEMENT(data->data, data->len - 1, data->len, name);
-}
-
-
-static int
-cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
-{
- return cpuMapLoad(arch, cpuGetArchModelsCb, data);
-}
-
-
/**
* cpuGetModels:
*
@@ -774,18 +737,17 @@ cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
int
cpuGetModels(const char *archName, char ***models)
{
- struct cpuGetModelsData data;
- virArch arch;
struct cpuArchDriver *driver;
- data.data = NULL;
- data.len = 1;
+ virArch arch;
+
+ VIR_DEBUG("arch=%s", archName);
arch = virArchFromString(archName);
if (arch == VIR_ARCH_NONE) {
virReportError(VIR_ERR_INVALID_ARG,
_("cannot find architecture %s"),
archName);
- goto error;
+ return -1;
}
driver = cpuGetSubDriver(arch);
@@ -793,21 +755,15 @@ cpuGetModels(const char *archName, char ***models)
virReportError(VIR_ERR_INVALID_ARG,
_("cannot find a driver for the architecture %s"),
archName);
- goto error;
+ return -1;
}
- if (models && VIR_ALLOC_N(data.data, data.len) < 0)
- goto error;
-
- if (cpuGetArchModels(driver->name, &data) < 0)
- goto error;
-
- if (models)
- *models = data.data;
-
- return data.len - 1;
+ if (!driver->getModels) {
+ virReportError(VIR_ERR_NO_SUPPORT,
+ _("CPU driver for %s has no CPU model support"),
+ virArchToString(arch));
+ return -1;
+ }
- error:
- virStringFreeList(data.data);
- return -1;
+ return driver->getModels(models);
}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 339964c..09e9538 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -100,6 +100,9 @@ typedef char *
typedef virCPUDataPtr
(*cpuArchDataParse) (const char *xmlStr);
+typedef int
+(*cpuArchGetModels) (char ***models);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -115,6 +118,7 @@ struct cpuArchDriver {
cpuArchHasFeature hasFeature;
cpuArchDataFormat dataFormat;
cpuArchDataParse dataParse;
+ cpuArchGetModels getModels;
};
diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
index 67cb9ff..155d93e 100644
--- a/src/cpu/cpu_powerpc.c
+++ b/src/cpu/cpu_powerpc.c
@@ -649,6 +649,42 @@ ppcBaseline(virCPUDefPtr *cpus,
goto cleanup;
}
+static int
+ppcGetModels(char ***models)
+{
+ struct ppc_map *map;
+ struct ppc_model *model;
+ char *name;
+ size_t nmodels = 0;
+
+ if (!(map = ppcLoadMap()))
+ goto error;
+
+ if (models && VIR_ALLOC_N(*models, 0) < 0)
+ goto error;
+
+ model = map->models;
+ while (model != NULL) {
+ if (VIR_STRDUP(name, model->name) < 0)
+ goto error;
+
+ if (VIR_INSERT_ELEMENT(*models, 0, nmodels, name) < 0)
+ goto error;
+
+ model = model->next;
+ }
+
+ cleanup:
+ ppcMapFree(map);
+
+ return nmodels;
+
+ error:
+ virStringFreeList(*models);
+ nmodels = -1;
+ goto cleanup;
+}
+
struct cpuArchDriver cpuDriverPowerPC = {
.name = "ppc64",
.arch = archs,
@@ -662,4 +698,5 @@ struct cpuArchDriver cpuDriverPowerPC = {
.baseline = ppcBaseline,
.update = ppcUpdate,
.hasFeature = NULL,
+ .getModels = ppcGetModels,
};
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 026b54e..f6dcba4 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2160,6 +2160,38 @@ x86HasFeature(const virCPUData *data,
return ret;
}
+static int
+x86GetModels(char ***models)
+{
+ const struct x86_map *map;
+ struct x86_model *model;
+ char *name;
+ size_t nmodels = 0;
+
+ if (!(map = virCPUx86GetMap()))
+ return -1;
+
+ if (models && VIR_ALLOC_N(*models, 0) < 0)
+ goto error;
+
+ model = map->models;
+ while (model != NULL) {
+ if (VIR_STRDUP(name, model->name) < 0)
+ goto error;
+
+ if (VIR_INSERT_ELEMENT(*models, 0, nmodels, name) < 0)
+ goto error;
+
+ model = model->next;
+ }
+
+ return nmodels;
+
+ error:
+ virStringFreeList(*models);
+ return -1;
+}
+
struct cpuArchDriver cpuDriverX86 = {
.name = "x86",
@@ -2180,4 +2212,5 @@ struct cpuArchDriver cpuDriverX86 = {
.hasFeature = x86HasFeature,
.dataFormat = x86CPUDataFormat,
.dataParse = x86CPUDataParse,
+ .getModels = x86GetModels,
};
--
1.8.5.5
9 years, 11 months
[libvirt] [PATCH] qemu: output error when try to hotplug unsupport console
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1164627
When try to use attach-device to hotplug a qemu
unsupport sonsole, command will return success,
and add a console in vm's xml.But this doesn't work
in qemu, qemu doesn't support these console.Add
a error output when try to hotplug a unsupport console
in qemuBuildConsoleChrDeviceStr.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/qemu/qemu_command.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1399ce4..2bf4a83 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10069,13 +10069,17 @@ qemuBuildConsoleChrDeviceStr(char **deviceStr,
break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
+ break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST:
- break;
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported console target type %s"),
+ NULLSTR(virDomainChrConsoleTargetTypeToString(chr->targetType)));
+ return ret;
}
ret = 0;
--
1.8.3.1
9 years, 11 months
[libvirt] [PATCH] network: Let domains be restricted to local DNS
by Josh Stone
This adds a new "localOnly" attribute on the domain element of the
network xml. With this set to "yes", DNS requests under that domain
will only be resolved by libvirt's dnsmasq, never forwarded upstream.
This was how it worked before commit f69a6b987d616, and I found that
functionality useful. For example, I have my host's NetworkManager
dnsmasq configured to forward that domain to libvirt's dnsmasq, so I can
easily resolve guest names from outside. But if libvirt's dnsmasq
doesn't know a name and forwards it to the host, I'd get an endless
forwarding loop. Now I can set localOnly="yes" to prevent the loop.
Signed-off-by: Josh Stone <jistone(a)redhat.com>
Cc: Laine Stump <laine(a)laine.org>
---
docs/formatnetwork.html.in | 12 +++++++++++-
docs/schemas/network.rng | 3 +++
src/conf/network_conf.c | 5 +++++
src/conf/network_conf.h | 1 +
src/network/bridge_driver.c | 5 +++++
.../networkxml2confdata/nat-network-dns-local-domain.conf | 14 ++++++++++++++
tests/networkxml2confdata/nat-network-dns-local-domain.xml | 9 +++++++++
tests/networkxml2conftest.c | 1 +
8 files changed, 49 insertions(+), 1 deletion(-)
create mode 100644 tests/networkxml2confdata/nat-network-dns-local-domain.conf
create mode 100644 tests/networkxml2confdata/nat-network-dns-local-domain.xml
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index dc438aee8622..defcdba00930 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -82,7 +82,7 @@
<pre>
...
<bridge name="virbr0" stp="on" delay="5"/>
- <domain name="example.com"/>
+ <domain name="example.com" localOnly="no"/>
<forward mode="nat" dev="eth0"/>
...</pre>
@@ -113,6 +113,16 @@
a <code><forward></code> mode of "nat" or "route" (or an
isolated network with no <code><forward></code>
element). <span class="since">Since 0.4.5</span>
+
+ <p>
+ If the optional <code>localOnly</code> attribute on the
+ <code>domain</code> element is "yes", then DNS requests under
+ this domain will only be resolved by the virtual network's own
+ DNS server - they will not be forwarded to the host's upstream
+ DNS server. If <code>localOnly</code> is "no", and by
+ default, unresolved requests <b>will</b> be forwarded.
+ <span class="since">Since 1.2.11</span>
+ </p>
</dd>
<dt><code>forward</code></dt>
<dd>Inclusion of the <code>forward</code> element indicates that
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 4546f8037580..a1da28092375 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -225,6 +225,9 @@
<optional>
<element name="domain">
<attribute name="name"><ref name="dnsName"/></attribute>
+ <optional>
+ <attribute name="localOnly"><ref name="virYesNo"/></attribute>
+ </optional>
</element>
</optional>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 067334e87cb0..61451c39805f 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2083,6 +2083,11 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
/* Parse network domain information */
def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
+ tmp = virXPathString("string(./domain[1]/@localOnly)", ctxt);
+ if (tmp) {
+ def->domain_local = STRCASEEQ(tmp, "yes");
+ VIR_FREE(tmp);
+ }
if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL &&
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode, -1)) == NULL)
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 660cd2d10cd1..6308a7dcfbf7 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -232,6 +232,7 @@ struct _virNetworkDef {
char *bridge; /* Name of bridge device */
char *domain;
+ bool domain_local; /* Choose not to forward dns for this domain */
unsigned long delay; /* Bridge forward delay (ms) */
bool stp; /* Spanning tree protocol */
virMacAddr mac; /* mac address of bridge device */
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 6cb421c52850..dfa375d3aa72 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -912,6 +912,11 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
}
if (network->def->domain) {
+ if (network->def->domain_local) {
+ virBufferAsprintf(&configbuf,
+ "local=/%s/\n",
+ network->def->domain);
+ }
virBufferAsprintf(&configbuf,
"domain=%s\n"
"expand-hosts\n",
diff --git a/tests/networkxml2confdata/nat-network-dns-local-domain.conf b/tests/networkxml2confdata/nat-network-dns-local-domain.conf
new file mode 100644
index 000000000000..5f41b9186cbc
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-local-domain.conf
@@ -0,0 +1,14 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+local=/example.com/
+domain=example.com
+expand-hosts
+except-interface=lo
+bind-dynamic
+interface=virbr0
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2confdata/nat-network-dns-local-domain.xml b/tests/networkxml2confdata/nat-network-dns-local-domain.xml
new file mode 100644
index 000000000000..a92d71f1f2f6
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-local-domain.xml
@@ -0,0 +1,9 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
+ <forward dev='eth0' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <domain name='example.com' localOnly='yes'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ </ip>
+</network>
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 4f1d9345ffe4..d2aa8c62cfcd 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -146,6 +146,7 @@ mymain(void)
DO_TEST("nat-network-dns-hosts", full);
DO_TEST("nat-network-dns-forward-plain", full);
DO_TEST("nat-network-dns-forwarders", full);
+ DO_TEST("nat-network-dns-local-domain", full);
DO_TEST("dhcp6-network", dhcpv6);
DO_TEST("dhcp6-nat-network", dhcpv6);
DO_TEST("dhcp6host-routed-network", dhcpv6);
--
2.1.0
9 years, 11 months
[libvirt] [PATCHv5 0/3] leaseshelper: Couple of improvements
by Peter Krempa
Nehal J Wani (1):
leaseshelper: improvements to support all events
Peter Krempa (2):
leaseshelper: Refactor control flow
network: dnsmasq: Don't format lease file path
src/network/bridge_driver.c | 16 +-
src/network/bridge_driver.h | 3 -
src/network/leaseshelper.c | 246 +++++++++++++++------
tests/networkxml2confdata/dhcp6-nat-network.conf | 1 -
tests/networkxml2confdata/dhcp6-network.conf | 1 -
tests/networkxml2confdata/isolated-network.conf | 1 -
.../nat-network-dns-srv-record-minimal.conf | 1 -
.../nat-network-dns-srv-record.conf | 1 -
.../nat-network-dns-txt-record.conf | 1 -
tests/networkxml2confdata/nat-network.conf | 1 -
tests/networkxml2confdata/netboot-network.conf | 1 -
.../networkxml2confdata/netboot-proxy-network.conf | 1 -
tests/networkxml2conftest.c | 12 -
13 files changed, 181 insertions(+), 105 deletions(-)
--
2.1.0
9 years, 11 months
[libvirt] ANNOUNCE: virt-manager 1.1.0 released
by Cole Robinson
I'm happy to announce the release of virt-manager 1.1.0!
virt-manager is a desktop application for managing KVM, Xen, and LXC
virtualization via libvirt.
The release can be downloaded from:
http://virt-manager.org/download/
The direct download links are:
http://virt-manager.org/download/sources/virt-manager/virt-manager-1.1.0....
This release includes:
- Switch to libosinfo as OS metadata database (Giuseppe Scrivano)
- Use libosinfo for OS detection from CDROM media labels (Giuseppe
Scrivano)
- Use libosinfo for improved OS defaults, like recommended disk size
(Giuseppe Scrivano)
- virt-image tool has been removed, as previously announced
- Enable Hyper-V enlightenments for Windows VMs
- Revert virtio-console default, back to plain serial console
- Experimental q35 option in new VM 'customize' dialog
- UI for virtual network QoS settings (Giuseppe Scrivano)
- virt-install: --disk discard= support (Jim Minter)
- addhardware: Add spiceport UI (Marc-André Lureau)
- virt-install: --events on_poweroff etc. support (Chen Hanxiao)
- cli --network portgroup= support and UI support
- cli --boot initargs= and UI support
- addhardware: allow setting controller model (Chen Hanxiao)
- virt-install: support setting hugepage options (Chen Hanxiao)
Thanks to everyone who has contributed to this release through testing,
bug reporting, submitting patches, and otherwise sending in feedback!
Thanks,
Cole
9 years, 11 months
[libvirt] [PATCH] qemu: update disk chain in vm->newDef when block job compeleted
by weiwei li
A bug will be hitted with libvirt+qemu+kvm when doing follow steps:
1.initial status :vm = base+z(z is a snapshot)
2. call snapshotCreateXML( ): vm = base+z +z'
3. call blockRebase( ): vm = base+z''(z rebase to z')
4.(after rebasing work done) vm shutdown and then start
an error occured like this:
"unable to set user and group to '0:0' on '
/path/to/disk': No such file or directory
A second start may sucess.
The error message reported by virSecurityDACSetSecurityDiskLabel
when the disk chain is misused(that is base+z +z', after rebase,
but z' was deleted yet).virSecurityDACSetSecurityDiskLabel used
an old disk chain after rebasing.
In qemuProcessHandleBlockJob when rebase complete, the disk chain
in vm->def is updated but vm->newDef is not(when vm->newDef is not
null). In shutdown( actrully in qemuProcessStop ), if vm->newDef
is not null , vm->def will be replaced by vm->newDef, which
contains a wrong disk chain!!! Then the next start will failed with
above message.
To fix it, update disk chain in vm->newDef in qemuProcessHandleBlockJob.
Signed-off-by: Weiwei Li <nuonuoli(a)tencent.com>
---
src/qemu/qemu_process.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 24e5f0f..0491249 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1033,6 +1033,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
virDomainDiskDefPtr disk;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virDomainDiskDefPtr persistDisk = NULL;
+ virDomainDiskDefPtr newDisk = NULL;
bool save = false;
virObjectLock(vm);
@@ -1101,6 +1102,32 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
true, true));
+ /* Chang vm->newDef disk chain */
+ if (!persistDisk && vm->newDef){
+ int indx = virDomainDiskIndexByName(vm->newDef,
+ disk->dst,
+ false);
+ virStorageSourcePtr copy = NULL;
+
+ if (indx >=0){
+ newDisk = vm->newDef->disks[indx];
+ copy = virStorageSourceCopy(disk->src, false);
+ if (virStorageSourceInitChainElement(copy,
+ newDisk->src,
+ false) < 0) {
+ VIR_WARN("Unable to update newDef definition "
+ "on vm %s after block job",
+ vm->def->name);
+ virStorageSourceFree(copy);
+ copy = NULL;
+ newDisk = NULL;
+ }
+ }
+ if (copy){
+ virStorageSourceFree(newDisk->src);
+ newDisk->src = copy;
+ }
+ }
} else if (disk->mirror &&
(type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY ||
type == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)) {
--
1.7.1
9 years, 11 months