[libvirt] [PATCH] qemuDomainObjStart: Warn on corrupted image
by Michal Privoznik
If the managedsave image is corrupted, e.g. the XML part is, we fail to
parse it and throw an error, e.g.:
error: Failed to start domain jms8
error: XML error: missing security model when using multiple labels
This is okay, as we can't really start the machine and avoid undefined
qemu behaviour. On the other hand, the error message doesn't give a
clue to users what should they do. The consensus here would be to thrown
a warning to logs saying "Hey, you've got a corrupted file".
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9c3daad..08be24b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6041,8 +6041,11 @@ qemuDomainObjStart(virConnectPtr conn,
if (ret > 0)
VIR_WARN("Ignoring incomplete managed state %s", managed_save);
- else
+ else {
+ VIR_WARN("Unable to restore from managed state %s. "
+ "Maybe the file is corrupted?", managed_save);
goto cleanup;
+ }
}
}
--
1.8.3.2
11 years, 1 month
[libvirt] [PATCH 1/2] qemu: USB keyboard device support
by Vitor de Lima
Some guests (like the "pseries" guests) do not implicitly have
a virtual keyboard. This patch introduces the proper mechanisms
to create an USB keyboard using the existing "input" XML tag.
---
src/conf/domain_conf.c | 3 ++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 42 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ffdbe95..4938740 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -504,7 +504,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse",
- "tablet")
+ "tablet",
+ "keyboard")
VIR_ENUM_IMPL(virDomainInputBus, VIR_DOMAIN_INPUT_BUS_LAST,
"ps2",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 05c2a84..c659fd0 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1222,6 +1222,7 @@ struct _virDomainTPMDef {
enum virDomainInputType {
VIR_DOMAIN_INPUT_TYPE_MOUSE,
VIR_DOMAIN_INPUT_TYPE_TABLET,
+ VIR_DOMAIN_INPUT_TYPE_KEYBOARD,
VIR_DOMAIN_INPUT_TYPE_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1d693e1..36ca455 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5276,9 +5276,24 @@ qemuBuildUSBInputDevStr(virDomainDefPtr def,
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ const char * model = NULL;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_INPUT_TYPE_MOUSE:
+ model = "usb-mouse";
+ break;
+ case VIR_DOMAIN_INPUT_TYPE_TABLET:
+ model = "usb-tablet";
+ break;
+ case VIR_DOMAIN_INPUT_TYPE_KEYBOARD:
+ model = "usb-kbd";
+ break;
+ }
+
virBufferAsprintf(&buf, "%s,id=%s",
- dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
- "usb-mouse" : "usb-tablet", dev->info.alias);
+ model, dev->info.alias);
+
+
if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
goto error;
@@ -8959,9 +8974,22 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, optstr);
VIR_FREE(optstr);
} else {
+ const char *usbdev = NULL;
+
+ switch (input->type) {
+ case VIR_DOMAIN_INPUT_TYPE_MOUSE:
+ usbdev = "mouse";
+ break;
+ case VIR_DOMAIN_INPUT_TYPE_TABLET:
+ usbdev = "tablet";
+ break;
+ case VIR_DOMAIN_INPUT_TYPE_KEYBOARD:
+ usbdev = "keyboard";
+ break;
+ }
+
virCommandAddArgList(cmd, "-usbdevice",
- input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE
- ? "mouse" : "tablet", NULL);
+ usbdev, NULL);
}
}
}
@@ -11614,15 +11642,19 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
} else if (STREQ(arg, "-usbdevice")) {
WANT_VALUE();
if (STREQ(val, "tablet") ||
- STREQ(val, "mouse")) {
+ STREQ(val, "mouse") ||
+ STREQ(val, "keyboard")) {
virDomainInputDefPtr input;
if (VIR_ALLOC(input) < 0)
goto error;
input->bus = VIR_DOMAIN_INPUT_BUS_USB;
if (STREQ(val, "tablet"))
input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
+ else if (STREQ(val, "keyboard"))
+ input->type = VIR_DOMAIN_INPUT_TYPE_KEYBOARD;
else
input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
+
if (VIR_REALLOC_N(def->inputs, def->ninputs+1) < 0) {
virDomainInputDefFree(input);
goto error;
--
1.8.1.4
11 years, 1 month
[libvirt] [PATCH] virSecurityLabelDefParseXML: Don't parse label on model='none'
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1027096
If there's the following snippet in the domain XML, the domain will be
lost upon the daemon restart (if the domain is started prior restart):
<seclabel type='dynamic' relabel='yes'/>
The problem is, the 'label', 'imagelabel' and 'baselabel' are parsed
whenever the VIR_DOMAIN_XML_INACTIVE is *not* present or the label is
static. The latter is not our case, obviously. So, when libvirtd starts
up, it finds domain state xml and parse it. During parsing, many XML
flags are enabled but VIR_DOMAIN_XML_INACTIVE. Hence, our parser tries
to extract 'label', 'imagelabel' and 'baselabel' from the XML which
fails for model='none'. Err, this model - even though not specified in
XML - can be taken from qemu wide config file: /etc/libvirtd/qemu.conf.
However, in order to know we are dealing with model='none' the code in
question must be moved forward a bit. Then a new check must be
introduced. This is what the first two chunks are doing.
But this alone is not sufficient. The domain state XML won't contain the
model attribute without slight modification. The model should be
inserted into the XML even if equal to 'none' and the state XML is being
generated - what if the origin (the @security_driver variable in
qemu.conf) changes during libvirtd restarts?
At the end, a test to catch this scenario is introduced.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/domain_conf.c | 26 +++++++++++++-------
.../qemuxml2argv-seclabel-dynamic-relabel.args | 6 +++++
.../qemuxml2argv-seclabel-dynamic-relabel.xml | 28 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmltest.c | 1 +
5 files changed, 54 insertions(+), 8 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c1e0ea7..ffdbe95 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4370,6 +4370,17 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
def->norelabel = false;
}
+ /* Always parse model */
+ p = virXPathStringLimit("string(./@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ def->model = p;
+
+ /* For the model 'none' none of the following labels is going to be
+ * present. Hence, return now. */
+
+ if (STREQ_NULLABLE(def->model, "none"))
+ return def;
+
/* Only parse label, if using static labels, or
* if the 'live' VM XML is requested
*/
@@ -4408,11 +4419,6 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
def->baselabel = p;
}
- /* Always parse model */
- p = virXPathStringLimit("string(./@model)",
- VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
- def->model = p;
-
return def;
error:
@@ -14177,7 +14183,9 @@ virDomainEventActionDefFormat(virBufferPtr buf,
static void
-virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
+virSecurityLabelDefFormat(virBufferPtr buf,
+ virSecurityLabelDefPtr def,
+ unsigned flags)
{
const char *sectype = virDomainSeclabelTypeToString(def->type);
@@ -14196,7 +14204,9 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
virBufferAsprintf(buf, "<seclabel type='%s'",
sectype);
- if (def->model && STRNEQ(def->model, "none"))
+ /* When generating state XML do include the model */
+ if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS ||
+ STRNEQ_NULLABLE(def->model, "none"))
virBufferEscapeString(buf, " model='%s'", def->model);
if (def->type == VIR_DOMAIN_SECLABEL_NONE) {
@@ -17107,7 +17117,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAdjustIndent(buf, 2);
for (n = 0; n < def->nseclabels; n++)
- virSecurityLabelDefFormat(buf, def->seclabels[n]);
+ virSecurityLabelDefFormat(buf, def->seclabels[n], flags);
virBufferAdjustIndent(buf, -2);
if (def->namespaceData && def->ns.format) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.args b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.args
new file mode 100644
index 0000000..8bef546
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.args
@@ -0,0 +1,6 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
+-hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.xml
new file mode 100644
index 0000000..cb74239
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-relabel.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <seclabel type='dynamic' relabel='yes'/>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 0629e31..7ff74aa 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -963,6 +963,7 @@ mymain(void)
DO_TEST("seclabel-dynamic-baselabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-dynamic-override", QEMU_CAPS_NAME);
DO_TEST("seclabel-dynamic-labelskip", QEMU_CAPS_NAME);
+ DO_TEST("seclabel-dynamic-relabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-static", QEMU_CAPS_NAME);
DO_TEST("seclabel-static-relabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-static-labelskip", QEMU_CAPS_NAME);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ffff3b5..ceaaf6a 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -263,6 +263,7 @@ mymain(void)
DO_TEST_FULL("seclabel-dynamic-baselabel", false, WHEN_INACTIVE);
DO_TEST_FULL("seclabel-dynamic-override", false, WHEN_INACTIVE);
DO_TEST_FULL("seclabel-dynamic-labelskip", true, WHEN_INACTIVE);
+ DO_TEST_FULL("seclabel-dynamic-relabel", false, WHEN_INACTIVE);
DO_TEST("seclabel-static");
DO_TEST_FULL("seclabel-static-labelskip", false, WHEN_ACTIVE);
DO_TEST("seclabel-none");
--
1.8.3.2
11 years, 1 month
[libvirt] [PATCH]docs: fix typos in libvirt.h.in
by Chen Hanxiao
From: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
s/repersents/represents
Signed-off-by: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
---
include/libvirt/libvirt.h.in | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 2802a46..f3751e5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2503,7 +2503,7 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
/**
* VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC:
*
- * Macro for the BlockIoTune tunable weight: it repersents the read
+ * Macro for the BlockIoTune tunable weight: it represents the read
* bytes per second permitted through a block device, as a ullong.
*/
#define VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC "read_bytes_sec"
@@ -2511,7 +2511,7 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
/**
* VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC:
*
- * Macro for the BlockIoTune tunable weight: it repersents the write
+ * Macro for the BlockIoTune tunable weight: it represents the write
* bytes per second permitted through a block device, as a ullong.
*/
#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC "write_bytes_sec"
@@ -2519,7 +2519,7 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
/**
* VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC:
*
- * Macro for the BlockIoTune tunable weight: it repersents the total
+ * Macro for the BlockIoTune tunable weight: it represents the total
* I/O operations per second permitted through a block device, as a ullong.
*/
#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC "total_iops_sec"
@@ -2527,14 +2527,14 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
/**
* VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC:
*
- * Macro for the BlockIoTune tunable weight: it repersents the read
+ * Macro for the BlockIoTune tunable weight: it represents the read
* I/O operations per second permitted through a block device, as a ullong.
*/
#define VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC "read_iops_sec"
/**
* VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC:
- * Macro for the BlockIoTune tunable weight: it repersents the write
+ * Macro for the BlockIoTune tunable weight: it represents the write
* I/O operations per second permitted through a block device, as a ullong.
*/
#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC "write_iops_sec"
--
1.8.2.1
11 years, 1 month
[libvirt] [PATCH] Don't expose 'none' machine type to capabilities
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The 'none' machine type is something only intended for use
by libvirt probing capabilities. It isn't something that
is useful for running real VM instances. As such it should
not be exposed to users in the capabilities.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/qemu/qemu_capabilities.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2712a4d..548b988 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2137,6 +2137,8 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
goto cleanup;
for (i = 0; i < nmachines; i++) {
+ if (STREQ(machines[i]->name, "none"))
+ continue;
qemuCaps->nmachineTypes++;
if (VIR_STRDUP(qemuCaps->machineAliases[qemuCaps->nmachineTypes -1],
machines[i]->alias) < 0 ||
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] Fix busy wait loop in LXC container I/O handling
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If the host side of an LXC container console disconnected
and the guest side continued to write data, until the PTY
buffer filled up, the LXC controller would busy wait. It
would repeatedly see POLLHUP from poll() and not disable
the watch.
This was due to some bogus logic detecting blocking
conditions. Upon seeing a POLLHUP we must disable all
reading & writing from the PTY, and setup the epoll to
wake us up again when the connection comes back.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_controller.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index c8f68c0..c76e8d4 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -77,13 +77,11 @@ struct _virLXCControllerConsole {
int hostFd; /* PTY FD in the host OS */
bool hostClosed;
int hostEpoll;
- bool hostBlocking;
int contWatch;
int contFd; /* PTY FD in the container */
bool contClosed;
int contEpoll;
- bool contBlocking;
int epollWatch;
int epollFd; /* epoll FD for dealing with EOF */
@@ -814,12 +812,15 @@ static void virLXCControllerSignalChildIO(virNetServerPtr server,
int status;
ret = waitpid(-1, &status, WNOHANG);
+ VIR_DEBUG("Got sig child %d vs %lld", ret, (unsigned long long)ctrl->initpid);
if (ret == ctrl->initpid) {
virNetServerQuit(server);
virMutexLock(&lock);
if (WIFSIGNALED(status) &&
- WTERMSIG(status) == SIGHUP)
+ WTERMSIG(status) == SIGHUP) {
+ VIR_DEBUG("Status indicates reboot");
wantReboot = true;
+ }
virMutexUnlock(&lock);
}
}
@@ -830,28 +831,32 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
int hostEvents = 0;
int contEvents = 0;
- if (!console->hostClosed || (!console->hostBlocking && console->fromContLen)) {
+ /* If host console is open, then we can look to read/write */
+ if (!console->hostClosed) {
if (console->fromHostLen < sizeof(console->fromHostBuf))
hostEvents |= VIR_EVENT_HANDLE_READABLE;
if (console->fromContLen)
hostEvents |= VIR_EVENT_HANDLE_WRITABLE;
}
- if (!console->contClosed || (!console->contBlocking && console->fromHostLen)) {
+
+ /* If cont console is open, then we can look to read/write */
+ if (!console->contClosed) {
if (console->fromContLen < sizeof(console->fromContBuf))
contEvents |= VIR_EVENT_HANDLE_READABLE;
if (console->fromHostLen)
contEvents |= VIR_EVENT_HANDLE_WRITABLE;
}
- VIR_DEBUG("Container watch %d=%d host watch %d=%d",
- console->contWatch, contEvents,
- console->hostWatch, hostEvents);
+ VIR_DEBUG("Container watch=%d, events=%d closed=%d; host watch=%d events=%d closed=%d",
+ console->contWatch, contEvents, console->contClosed,
+ console->hostWatch, hostEvents, console->hostClosed);
virEventUpdateHandle(console->contWatch, contEvents);
virEventUpdateHandle(console->hostWatch, hostEvents);
if (console->hostClosed) {
+ /* Must setup an epoll to detect when host becomes accessible again */
int events = EPOLLIN | EPOLLET;
- if (console->hostBlocking)
+ if (console->fromContLen)
events |= EPOLLOUT;
if (events != console->hostEpoll) {
@@ -887,8 +892,9 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
}
if (console->contClosed) {
+ /* Must setup an epoll to detect when guest becomes accessible again */
int events = EPOLLIN | EPOLLET;
- if (console->contBlocking)
+ if (console->fromHostLen)
events |= EPOLLOUT;
if (events != console->contEpoll) {
@@ -959,7 +965,7 @@ static void virLXCControllerConsoleEPoll(int watch, int fd, int events, void *op
/* If we get HUP+dead PID, we just re-enable the main loop
* which will see the PID has died and exit */
- if ((event.events & EPOLLIN)) {
+ if ((event.events & (EPOLLIN|EPOLLOUT))) {
if (event.data.fd == console->hostFd) {
console->hostClosed = false;
} else {
@@ -1039,10 +1045,6 @@ static void virLXCControllerConsoleIO(int watch, int fd, int events, void *opaqu
*len -= done;
} else {
VIR_DEBUG("Write fd %d done %d errno %d", fd, (int)done, errno);
- if (watch == console->hostWatch)
- console->hostBlocking = true;
- else
- console->contBlocking = true;
}
}
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] Fix mem leak in virQEMUCapsProbeQMPMachineTypes on OOM
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The virQEMUCapsProbeQMPMachineTypes method iterates over machine
types copying them into the qemuCapsPtr object. It only updates
the qemuCaps->nmachinetypes value at the end though. So if OOM
occurs in the middle, the destructor of qemuCapsPtr will not
free the partially initialized machine types.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/qemu/qemu_capabilities.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 71a913b..2712a4d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2137,14 +2137,17 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
goto cleanup;
for (i = 0; i < nmachines; i++) {
- if (VIR_STRDUP(qemuCaps->machineAliases[i], machines[i]->alias) < 0 ||
- VIR_STRDUP(qemuCaps->machineTypes[i], machines[i]->name) < 0)
+ qemuCaps->nmachineTypes++;
+ if (VIR_STRDUP(qemuCaps->machineAliases[qemuCaps->nmachineTypes -1],
+ machines[i]->alias) < 0 ||
+ VIR_STRDUP(qemuCaps->machineTypes[qemuCaps->nmachineTypes - 1],
+ machines[i]->name) < 0)
goto cleanup;
if (machines[i]->isDefault)
defIdx = i;
- qemuCaps->machineMaxCpus[i] = machines[i]->maxCpus;
+ qemuCaps->machineMaxCpus[qemuCaps->nmachineTypes - 1] =
+ machines[i]->maxCpus;
}
- qemuCaps->nmachineTypes = nmachines;
if (defIdx)
virQEMUCapsSetDefaultMachine(qemuCaps, defIdx);
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH 0/2] Make vir*Free to set ptr to NULL
by Michal Privoznik
This is just a start to see if upstream likes it or not. If it turns out we
want this I can supply more patches - there are plenty of vir.*Free() functions
which doesn't set ptr to NULL.
My aim is to make it more visible where are we using stale pointer. Because if
the pointer is not set to NULL it may happen that the page isn't unmapped, so
on write access we are overwriting something else (perhaps glibc internal
structs). We may get SIGSEGV later on, but it will not show the root cause but
some random location instead. So you often have to run it under valgrind to get
to the real root cause. And I don't need to say how tricky is that, do I?
Of course, it won't catch every stale pointer bug we have, but my aim is to
catch a few at least.
Michal Privoznik (2):
virObjectUnref: Set pointer to NULL on dispose
virCommandFree: Set pointer to NULL
src/fdstream.c | 1 -
src/libvirt_private.syms | 4 ++--
src/qemu/qemu_driver.c | 1 -
src/storage/storage_backend_logical.c | 3 ---
src/util/vircommand.c | 11 ++++++++---
src/util/vircommand.h | 4 +++-
src/util/viridentity.c | 2 +-
src/util/virnetdevveth.c | 1 -
src/util/virobject.c | 13 ++++++++-----
src/util/virobject.h | 5 ++++-
10 files changed, 26 insertions(+), 19 deletions(-)
--
1.8.1.5
11 years, 1 month
[libvirt] [PATCH] virsh-domain: Mark --live and --config mutually exclusive in vcpucount
by Peter Krempa
The 'vcpucount' command is a getter command for the vCPUu count. When
one or more of the filtering flags are specified the command returns the
value only for the selected combination. In this case the --live and
--config combination isn't valid. This however didn't cause errors as
the combination of flags was rejected by the libvirt API but then the
fallback code kicked in and requested the count in a way where the clash
of the flags didn't matter.
Mark the flag combination mutually exclusive so that user's aren't
confused.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1024245
---
tools/virsh-domain.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 59e3d8d..60abd3d 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -5331,6 +5331,7 @@ cmdVcpucount(vshControl *ctl, const vshCmd *cmd)
if (!maximum && !active && current)
current = false;
+ VSH_EXCLUSIVE_OPTIONS_VAR(live, config)
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
VSH_EXCLUSIVE_OPTIONS_VAR(active, maximum);
--
1.8.4.2
11 years, 1 month
[libvirt] [PATCH] Only determine GuestCPU features if required
by Guido Günther
There's no need to probe CPU features if we don't need them later.
Debian Wheezy's QEMU 1.1.2 lacks the feature-word option so this
unbreaks starting domains that got broken by
d94b7817719b064849818b9ba6c37e403b7c003c like
error: internal error: unable to execute QEMU command 'qom-get': Property '.feature-words' not found
---
This might not be ideal since we might to want to use
qemuMonitorGetGuestCPU somewhere else later so I'm happy
to improve on this.
Cheers,
-- Guido
src/qemu/qemu_process.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fcceedd..be09ea0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3477,14 +3477,14 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
switch (arch) {
case VIR_ARCH_I686:
case VIR_ARCH_X86_64:
- qemuDomainObjEnterMonitor(driver, vm);
- guestcpu = qemuMonitorGetGuestCPU(priv->mon, arch);
- qemuDomainObjExitMonitor(driver, vm);
+ if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON) {
+ qemuDomainObjEnterMonitor(driver, vm);
+ guestcpu = qemuMonitorGetGuestCPU(priv->mon, arch);
+ qemuDomainObjExitMonitor(driver, vm);
- if (!(guestcpu))
- goto cleanup;
+ if (!(guestcpu))
+ goto cleanup;
- if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON) {
if (!cpuHasFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("host doesn't support paravirtual spinlocks"));
--
1.8.4.2
11 years, 1 month