[libvirt] [PATCH v2 0/2] Resolve issues seen with schedinfo
by John Ferlan
These patches resolve an issue seen using 'virsh schedinfo <domain>' on a
non running domain that have been present since 1.0.4 as a result of the
cgroup infrastructure changes:
https://www.redhat.com/archives/libvir-list/2013-April/msg00783.html
The exact commit id that caused the issue is listed in each of the commit
messages. I used git bisect to determine, although it was tricky because
the TPM changes were made around the same time and required commit '8b934a5c'
to be applied in order to actually see domains on my host.
Prior to the changes the "CFS Bandwidth" data was obtained since the driver
cgroup was mounted as opposed to the changes from the above set which mount
cgroups when the domain is running.
The result for 'virsh schedinfo <domain>' for a non running guest is to
return the configuration data for default, --config, and --current options.
The --live option reports a failure. For a running guest, default, --live,
and --current report values from cgroup, while --config reports only the
configuration values.
This issue also affects the libvirt-cim code in how it defines QEMU domains.
Fortunately it only looks for the "cpu_shares" value.
Difference to v1:
- In the [qemu|lxc]DomainGetSchedulerType() API's, rather than check for
priv->cgroup, check if the domain is running and return defaults if not
- In the [qemu|lxc]DomainGetSchedulerParametersFlags() API's, if we're
only returning configuration data, then don't gate the result returned
on the CFS bandwidth data cgroup availability.
qemu: Resolve issue with GetScheduler APIs for non running domain
lxc: Resolve issue with GetScheduler APIs for non running domain
src/lxc/lxc_driver.c | 11 ++++++++++-
src/qemu/qemu_driver.c | 11 ++++++++++-
2 files changed, 20 insertions(+), 2 deletions(-)
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH v4 0/7] Add qcow2 extensions support
by Ján Tomko
Since QEMU 1.1 qcow2 supports a features bitfield, allowing
to implement additional features without breaking compatibility
with older QEMU versions.
The version header on-disk is bumped to 3, however the format name
is still 'qcow2', not 'qcow3' (which is what I used in v2).
v4: rebased
v3: https://www.redhat.com/archives/libvir-list/2013-May/msg01179.html
v2: https://www.redhat.com/archives/libvir-list/2013-February/msg00212.html
qcow2 vs. qcow3 discussion:
https://www.redhat.com/archives/libvir-list/2013-March/msg00094.html
Ján Tomko (7):
storage: rework qemu-img command line generation
util: add support for qcow2v3 image detection
conf: add features to volume target XML
storage: add support for creating qcow2 images with extensions
conf: split out snapshot disk XML formatting
Add qcow2 features support to snapshots
qemu: add qcow2 extension support to inactive external snapshots
docs/formatsnapshot.html.in | 5 +
docs/formatstorage.html.in | 19 +++
docs/schemas/Makefile.am | 1 +
docs/schemas/domainsnapshot.rng | 7 +
docs/schemas/storagefilefeatures.rng | 24 ++++
docs/schemas/storagevol.rng | 7 +
libvirt.spec.in | 1 +
mingw-libvirt.spec.in | 2 +
src/conf/snapshot_conf.c | 127 ++++++++++++++----
src/conf/snapshot_conf.h | 2 +
src/conf/storage_conf.c | 74 ++++++++++
src/conf/storage_conf.h | 7 +-
src/libvirt_private.syms | 2 +
src/qemu/qemu_driver.c | 72 +++++++---
src/storage/storage_backend.c | 143 +++++++++++++-------
src/storage/storage_backend_fs.c | 10 ++
src/util/virstoragefile.c | 164 ++++++++++++++++++-----
src/util/virstoragefile.h | 12 ++
tests/domainsnapshotxml2xmlin/disk_snapshot.xml | 5 +
tests/domainsnapshotxml2xmlout/disk_snapshot.xml | 4 +
tests/storagevolxml2argvdata/qcow2-1.1.argv | 1 +
tests/storagevolxml2argvdata/qcow2-lazy.argv | 1 +
tests/storagevolxml2argvdata/vol-qcow2-1.1.xml | 32 +++++
tests/storagevolxml2argvdata/vol-qcow2-lazy.xml | 35 +++++
tests/storagevolxml2argvtest.c | 2 +
tests/storagevolxml2xmlin/vol-qcow2-1.1.xml | 32 +++++
tests/storagevolxml2xmlin/vol-qcow2-lazy.xml | 35 +++++
tests/storagevolxml2xmlout/vol-qcow2-1.1.xml | 33 +++++
tests/storagevolxml2xmlout/vol-qcow2-lazy.xml | 35 +++++
tests/storagevolxml2xmltest.c | 2 +
30 files changed, 766 insertions(+), 130 deletions(-)
create mode 100644 docs/schemas/storagefilefeatures.rng
create mode 100644 tests/storagevolxml2argvdata/qcow2-1.1.argv
create mode 100644 tests/storagevolxml2argvdata/qcow2-lazy.argv
create mode 100644 tests/storagevolxml2argvdata/vol-qcow2-1.1.xml
create mode 100644 tests/storagevolxml2argvdata/vol-qcow2-lazy.xml
create mode 100644 tests/storagevolxml2xmlin/vol-qcow2-1.1.xml
create mode 100644 tests/storagevolxml2xmlin/vol-qcow2-lazy.xml
create mode 100644 tests/storagevolxml2xmlout/vol-qcow2-1.1.xml
create mode 100644 tests/storagevolxml2xmlout/vol-qcow2-lazy.xml
--
1.8.1.5
11 years, 5 months
[libvirt] [PATCH] util: switch virBufferTrim to void
by Ján Tomko
We don't care whether the trim was succesful or not anywhere
except the tests.
Switch it to void and set the buffer error on wrong usage.
---
Patch that tried to shut Coverity up by checking the return values anyway:
https://www.redhat.com/archives/libvir-list/2013-June/msg00650.html
src/util/virbuffer.c | 19 ++++++++++---------
src/util/virbuffer.h | 2 +-
tests/virbuftest.c | 43 ++++++++++++++++---------------------------
tools/virsh.c | 9 +++------
4 files changed, 30 insertions(+), 43 deletions(-)
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index 693e4b2..4969497 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -660,27 +660,28 @@ virBufferStrcat(virBufferPtr buf, ...)
* further limits how much of the tail is trimmed. If @str is NULL, then
* @len must be non-negative.
*
- * Returns -1 if @buf has previously encountered an error or if @len is
- * invalid, 0 if there was nothing to trim (@buf was too short or @str
- * didn't match), and 1 if the trim was successful.
+ * Sets error to -1 (usage) if str is NULL and len is less than zero.
*/
-int
+void
virBufferTrim(virBufferPtr buf, const char *str, int len)
{
size_t len2 = 0;
- if (!buf || buf->error || (!str && len < 0))
- return -1;
+ if (!buf || buf->error)
+ return;
+ if (!str && len < 0) {
+ virBufferSetError(buf, -1);
+ return;
+ }
if (len > 0 && len > buf->use)
- return 0;
+ return;
if (str) {
len2 = strlen(str);
if (len2 > buf->use ||
memcmp(&buf->content[buf->use - len2], str, len2) != 0)
- return 0;
+ return;
}
buf->use -= len < 0 ? len2 : len;
buf->content[buf->use] = '\0';
- return 1;
}
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
index 7b69c0e..e0b77ab 100644
--- a/src/util/virbuffer.h
+++ b/src/util/virbuffer.h
@@ -77,6 +77,6 @@ void virBufferURIEncodeString(virBufferPtr buf, const char *str);
void virBufferAdjustIndent(virBufferPtr buf, int indent);
int virBufferGetIndent(const virBufferPtr buf, bool dynamic);
-int virBufferTrim(virBufferPtr buf, const char *trim, int len);
+void virBufferTrim(virBufferPtr buf, const char *trim, int len);
#endif /* __VIR_BUFFER_H__ */
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
index c7a504b..3938f0d 100644
--- a/tests/virbuftest.c
+++ b/tests/virbuftest.c
@@ -148,38 +148,21 @@ static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
char *result = NULL;
const char *expected = "a,b";
int ret = -1;
- int i = 1;
-
-#define ACT(str, len, result) \
- do { \
- if (virBufferTrim(buf, str, len) != result) { \
- TEST_ERROR("trim %d failed", i); \
- goto cleanup; \
- } \
- i++; \
- } while (0);
-
- if (virBufferTrim(buf, "", 0) != -1) {
- TEST_ERROR("Wrong failure detection 1");
- goto cleanup;
- }
+
+ virBufferTrim(buf, "", 0);
buf = &bufinit;
- if (virBufferTrim(buf, NULL, -1) != -1) {
- TEST_ERROR("Wrong failure detection 2");
- goto cleanup;
- }
virBufferAddLit(buf, "a;");
- ACT("", 0, 1);
- ACT("", -1, 1);
- ACT(NULL, 1, 1);
- ACT(NULL, 5, 0);
- ACT("a", 2, 0);
+ virBufferTrim(buf, "", 0);
+ virBufferTrim(buf, "", -1);
+ virBufferTrim(buf, NULL, 1);
+ virBufferTrim(buf, NULL, 5);
+ virBufferTrim(buf, "a", 2);
virBufferAddLit(buf, ",b,,");
- ACT("b", -1, 0);
- ACT("b,,", 1, 1);
- ACT(",", -1, 1);
+ virBufferTrim(buf, "b", -1);
+ virBufferTrim(buf, "b,,", 1);
+ virBufferTrim(buf, ",", -1);
result = virBufferContentAndReset(buf);
if (!result || STRNEQ(result, expected)) {
@@ -187,6 +170,12 @@ static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
goto cleanup;
}
+ virBufferTrim(buf, NULL, -1);
+ if (virBufferError(buf) != -1) {
+ TEST_ERROR("Usage error not flagged");
+ goto cleanup;
+ }
+
ret = 0;
cleanup:
diff --git a/tools/virsh.c b/tools/virsh.c
index 26d37c6..af2bb76 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -632,18 +632,15 @@ vshTreePrintInternal(vshControl *ctl,
false, indent) < 0)
goto cleanup;
}
- if (virBufferTrim(indent, " ", -1) < 0)
- goto cleanup;
+ virBufferTrim(indent, " ", -1);
/* If there was no child device, and we're the last in
* a list of devices, then print another blank line */
if (nextlastdev == -1 && devid == lastdev)
vshPrint(ctl, "%s\n", virBufferCurrentContent(indent));
- if (!root) {
- if (virBufferTrim(indent, NULL, 2) < 0)
- goto cleanup;
- }
+ if (!root)
+ virBufferTrim(indent, NULL, 2);
ret = 0;
cleanup:
return ret;
--
1.8.1.5
11 years, 5 months
[libvirt] [PATCH] qemu: set QEMU_CAPS_DEVICE_VIDEO_PRIMARY cap flag in QMP detection
by Guannan Ren
When qemu >= 1.20, it is safe to use -device for primary video
device as described in 4c993d8ab.
So, we are missing the cap flag in QMP capabilities detection, this
flag can be initialized safely in virQEMUCapsInitQMPBasic.
---
src/qemu/qemu_capabilities.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1091a07..406dca9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2418,6 +2418,7 @@ virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);
virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE);
virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY);
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
}
/* Capabilities that are architecture depending
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] check return values of virBufferTrim
by Ján Tomko
Just to silence Coverity:
Event check_return:
Calling function "virBufferTrim(virBufferPtr, char const *, int)"
without checking return value (as is done elsewhere 5 out of 6 times).
---
src/node_device/node_device_udev.c | 5 ++---
src/rpc/virnetsshsession.c | 3 +--
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index bb58415..a37989a 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -370,9 +370,8 @@ udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED,
const char *format = NULL;
virBufferAdd(&buf, fmt, -1);
- virBufferTrim(&buf, "\n", -1);
-
- format = virBufferContentAndReset(&buf);
+ if (virBufferTrim(&buf, "\n", -1) >= 0)
+ format = virBufferContentAndReset(&buf);
virLogVMessage(VIR_LOG_FROM_LIBRARY,
virLogPriorityFromSyslog(priority),
diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c
index b6aedc8..2299871 100644
--- a/src/rpc/virnetsshsession.c
+++ b/src/rpc/virnetsshsession.c
@@ -362,9 +362,8 @@ virNetSSHCheckHostKey(virNetSSHSessionPtr sess)
* we have to use a *MAGIC* constant. */
for (i = 0; i < 16; i++)
virBufferAsprintf(&buff, "%02hhX:", keyhash[i]);
- virBufferTrim(&buff, ":", 1);
- if (virBufferError(&buff) != 0) {
+ if (virBufferTrim(&buff, ":", 1) < 0) {
virReportOOMError();
return -1;
}
--
1.8.1.5
11 years, 5 months
[libvirt] Not able to open Xen Connection using libvirt
by varun bhatnagar
Hi,
I am trying to create virtual machine through libvirt using xen hypervisor.
I was able to install xen successfully but when I tried connecting to the
hypervisor it gave an error. And while installing libvirt (libvirt-1.0.1) I
installed it with xen support.
I am pasting the snapshot of the error below:
[image: Inline image 1]
Can anyone tell me why I am getting this error?
//
Varun
11 years, 5 months
[libvirt] [PATCH 0/2] Don't always fail migrations on I/O errors
by Peter Krempa
Recently I've added code that aborts migration in case of I/O error. This may
not be desirable as qemu does actually support such migration. This series adds
a flag that enables this option that will be now disabled by default.
Peter Krempa (2):
migration: Make erroring out on I/O error controllable by flag
migration: Don't propagate VIR_MIGRATE_ABORT_ON_ERROR
include/libvirt/libvirt.h.in | 1 +
src/libvirt.c | 17 +++++++++++------
src/qemu/qemu_driver.c | 4 ++--
src/qemu/qemu_migration.c | 39 ++++++++++++++++++++++++---------------
src/qemu/qemu_migration.h | 6 ++++--
tools/virsh-domain.c | 7 +++++++
tools/virsh.pod | 6 ++++--
7 files changed, 53 insertions(+), 27 deletions(-)
--
1.8.2.1
11 years, 5 months
[libvirt] [PATCH] qemu: Avoid leaking uri in qemuMigrationPrepareDirect
by Jiri Denemark
---
src/qemu/qemu_migration.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 48e0d44..68c9cc5 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2367,7 +2367,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
const char *p;
char *uri_str = NULL;
int ret = -1;
- virURIPtr uri;
+ virURIPtr uri = NULL;
VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
@@ -2472,6 +2472,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
cookieout, cookieoutlen, def,
NULL, this_port, flags);
cleanup:
+ virURIFree(uri);
VIR_FREE(hostname);
if (ret != 0)
VIR_FREE(*uri_out);
--
1.8.2.1
11 years, 5 months
[libvirt] [PATCH 1/2 v3] json: add stream parser
by Dmitry Guryanov
Add function virJSONValueFromStream, which reads data from
a stream and passes it to json parser. When end of the object
is reached, it returns this object.
To avoid reading from the stream by single bytes it reads to
a buffer (in a structure virJSONStreamParserState), which should
be passed to a consequent call of this function. So if the end
of one object and the beginning of the next object have been
read by a single system call - virJSONValueFromStream handle
it correctly.
example of usage:
virJSONValuePtr v;
virJSONStreamParserState state;
memset(&state, 0, sizeof(state));
while (1) {
v = virJSONValueFromStream(mon->fd, &state);
if (v == (void *)-1)
/* error */
break;
if (v == NULL)
/* file descriptor has been closed */
break;
/* handle object 'v' */
}
I need such function for the parallels driver. It caches info
about domains and needs some mechanism to update this cache.
There is a "prlsrvctl monitor" command which waits for events
forever and prints info about events to stdout in json format.
So parallels driver could start separate thread which will
read from prlsrvctl's stdout and update cache accordingly.
There is the same task in qemu_monitor_json, but each json object
is printed in a separate line there. It's not possible in my case,
because some fields could have line endings.
---
src/libvirt_private.syms | 1 +
src/util/virjson.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virjson.h | 8 +++
3 files changed, 119 insertions(+), 0 deletions(-)
* This patch left unchanged since v2
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b449293..0db2a0d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1391,6 +1391,7 @@ virJSONValueArrayGet;
virJSONValueArraySize;
virJSONValueFree;
virJSONValueFromString;
+virJSONValueFromStream;
virJSONValueGetBoolean;
virJSONValueGetNumberDouble;
virJSONValueGetNumberInt;
diff --git a/src/util/virjson.c b/src/util/virjson.c
index 3a6f520..9559a26 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1022,6 +1022,116 @@ cleanup:
return ret;
}
+/*
+ * Read single JSON object from the stream. Store data, which
+ * have already been read from the stream, but belongs to the
+ * next object to the virJSONStreamParserState structure. So that
+ * consequent call to this function will parse it and return that
+ * object.
+ *
+ * @fd: file descriptor, opened for reading
+ * @state: pointer to the structure with buffer for data, read from fd.
+ *
+ * Return (void *)-1 in case of error, NULL when eof reached,
+ * pointer to the virJSONValuePtr in case of success.
+ */
+
+virJSONValuePtr virJSONValueFromStream(int fd, virJSONStreamParserStatePtr state)
+{
+ yajl_handle hand;
+ virJSONParser parser = { NULL, NULL, 0 };
+ virJSONValuePtr value = (void *)-1;
+# ifndef WITH_YAJL2
+ yajl_parser_config cfg = { 1, 1 };
+# endif
+ ssize_t len;
+ int ret = 0;
+ bool done = false;
+
+# ifdef WITH_YAJL2
+ hand = yajl_alloc(&parserCallbacks, NULL, &parser);
+ if (hand) {
+ yajl_config(hand, yajl_allow_comments, 1);
+ yajl_config(hand, yajl_dont_validate_strings, 0);
+ yajl_config(hand, yajl_allow_trailing_garbage, 1);
+ }
+# else
+ hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
+# endif
+ if (!hand) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to create JSON parser"));
+ goto cleanup;
+ }
+
+ do {
+ if (strlen(&state->buf[state->pos]) == 0) {
+ state->pos = 0;
+ memset(state->buf, 0, sizeof(state->buf));
+ len = read(fd, state->buf, sizeof(state->buf) - 1);
+
+ if (len < 0) {
+ virReportSystemError(errno, _("cannot read from fd '%d'"), fd);
+ virJSONValueFree(parser.head);
+ goto cleanup;
+ }
+
+ if (len == 0) {
+ value = parser.head;
+ goto cleanup;
+ }
+ }
+
+ for (;state->pos < strlen(state->buf); state->pos++) {
+ unsigned char *buf = (unsigned char *)&state->buf[state->pos];
+ /*
+ * New yaml library has useful function yajl_get_bytes_consumed
+ * which allows parsing by larger chunks. But rhel-6 has 1.0.7
+ * version, which doesn't have it.
+ */
+ ret = yajl_parse(hand, buf, 1);
+# ifdef WITH_YAJL2
+ if (ret == 0 && yajl_get_bytes_consumed(hand) == 0) {
+ done = true;
+ /* state->pos points to the first symbol after current
+ * object */
+ break;
+ } else if (ret != 0) {
+# else
+ if (ret == 0) {
+ done = true;
+ /* state->pos points to the last symbol of the
+ * current object */
+ state->pos++;
+ break;
+ } else if (ret != yajl_status_insufficient_data) {
+# endif
+ unsigned char *errstr = yajl_get_error(hand, 1, buf, 1);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse json: %s"),
+ (const char*) errstr);
+ VIR_FREE(errstr);
+ virJSONValueFree(parser.head);
+ goto cleanup;
+ }
+ }
+ } while (!done);
+
+ value = parser.head;
+
+cleanup:
+ yajl_free(hand);
+
+ if (parser.nstate) {
+ int i;
+ for (i = 0 ; i < parser.nstate ; i++) {
+ VIR_FREE(parser.state[i].key);
+ }
+ }
+
+ VIR_DEBUG("result=%p", parser.head);
+ return value;
+}
static int virJSONValueToStringOne(virJSONValuePtr object,
yajl_gen g)
diff --git a/src/util/virjson.h b/src/util/virjson.h
index db11396..1f5ce38 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -48,6 +48,8 @@ typedef virJSONObjectPair *virJSONObjectPairPtr;
typedef struct _virJSONArray virJSONArray;
typedef virJSONArray *virJSONArrayPtr;
+typedef struct _virJSONStreamParserState virJSONStreamParserState;
+typedef virJSONStreamParserState *virJSONStreamParserStatePtr;
struct _virJSONObjectPair {
char *key;
@@ -77,6 +79,11 @@ struct _virJSONValue {
} data;
};
+struct _virJSONStreamParserState {
+ char buf[1024];
+ size_t pos;
+};
+
void virJSONValueFree(virJSONValuePtr value);
virJSONValuePtr virJSONValueNewString(const char *data);
@@ -138,5 +145,6 @@ int virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,
virJSONValuePtr virJSONValueFromString(const char *jsonstring);
char *virJSONValueToString(virJSONValuePtr object,
bool pretty);
+virJSONValuePtr virJSONValueFromStream(int fd, virJSONStreamParserStatePtr state);
#endif /* __VIR_JSON_H_ */
--
1.7.1
11 years, 5 months