[libvirt] [PATCH 00/20] Prepare QEMU capabilities for detection via QMP

As of QEMU 1.2 libvirt is supposed to stop parsing -help and instead use various QMP commands to detect capabilities. Before we can do this, the current QEMU capabilities code needs a serious cleanup and some refactoring. This series does that major preparation work. Currently we consider "capabilities" to just refer to flags we detect from -help. This series expands to cover all the things we detect from QEMU, specifically including machine types, CPU definitions and architecture. It introduces a single object to track all this data and a centralized caching mechanism so we never re-query data we already have somewhere.

From: "Daniel P. Berrange" <berrange@redhat.com> Add an API allowing flags from one virBitmapPtr to be copied into another instance. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/libvirt_private.syms | 1 + src/util/bitmap.c | 19 +++++++++++++++++++ src/util/bitmap.h | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0494e1f..8dfb4ce 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -8,6 +8,7 @@ # bitmap.h virBitmapAlloc; virBitmapClearBit; +virBitmapCopy; virBitmapFree; virBitmapGetBit; virBitmapSetBit; diff --git a/src/util/bitmap.c b/src/util/bitmap.c index 53a8a38..cd52802 100644 --- a/src/util/bitmap.c +++ b/src/util/bitmap.c @@ -93,6 +93,25 @@ void virBitmapFree(virBitmapPtr bitmap) } } + +int virBitmapCopy(virBitmapPtr dst, virBitmapPtr src) +{ + size_t sz; + + if (dst->size != src->size) { + errno = EINVAL; + return -1; + } + + sz = (src->size + VIR_BITMAP_BITS_PER_UNIT - 1) / + VIR_BITMAP_BITS_PER_UNIT; + + memcpy(dst->map, src->map, sz * sizeof(src->map[0])); + + return 0; +} + + /** * virBitmapSetBit: * @bitmap: Pointer to bitmap diff --git a/src/util/bitmap.h b/src/util/bitmap.h index c3e6222..1d8750e 100644 --- a/src/util/bitmap.h +++ b/src/util/bitmap.h @@ -42,6 +42,12 @@ virBitmapPtr virBitmapAlloc(size_t size) ATTRIBUTE_RETURN_CHECK; void virBitmapFree(virBitmapPtr bitmap); /* + * Copy all bits from @src to @dst. The bitmap sizes + * must be the same + */ +int virBitmapCopy(virBitmapPtr dst, virBitmapPtr src); + +/* * Set bit position @b in @bitmap */ int virBitmapSetBit(virBitmapPtr bitmap, size_t b) -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Add an API allowing flags from one virBitmapPtr to be copied into another instance.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/libvirt_private.syms | 1 + src/util/bitmap.c | 19 +++++++++++++++++++ src/util/bitmap.h | 6 ++++++ 3 files changed, 26 insertions(+)
This conflicts with a patch proposed by Hu Tao (https://www.redhat.com/archives/libvir-list/2012-September/msg00317.html).
+ +int virBitmapCopy(virBitmapPtr dst, virBitmapPtr src)
This requires you to pre-create the copy, so a better name might be virBitmapCopyInto(), and then rebase Hu's patch, so that his function signature: +/** + * virBitmapCopy: + * @src: the source bitmap. + * + * Makes a copy of bitmap @src. + * + * returns the copied bitmap on success, or NULL otherwise. Caller + * should call virBitmapFree to free the returned bitmap. + */ +virBitmapPtr virBitmapCopy(virBitmapPtr src) would then call into your virBitmapCopyInto for fewer lines of implementation. That is, I like Hu's semantics better of creating the copy, but I still think your function is useful, if given the correct name. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Sep 11, 2012 at 03:35:45PM -0600, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Add an API allowing flags from one virBitmapPtr to be copied into another instance.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/libvirt_private.syms | 1 + src/util/bitmap.c | 19 +++++++++++++++++++ src/util/bitmap.h | 6 ++++++ 3 files changed, 26 insertions(+)
This conflicts with a patch proposed by Hu Tao (https://www.redhat.com/archives/libvir-list/2012-September/msg00317.html).
+ +int virBitmapCopy(virBitmapPtr dst, virBitmapPtr src)
This requires you to pre-create the copy, so a better name might be virBitmapCopyInto(), and then rebase Hu's patch, so that his function signature:
+/** + * virBitmapCopy: + * @src: the source bitmap. + * + * Makes a copy of bitmap @src. + * + * returns the copied bitmap on success, or NULL otherwise. Caller + * should call virBitmapFree to free the returned bitmap. + */ +virBitmapPtr virBitmapCopy(virBitmapPtr src)
would then call into your virBitmapCopyInto for fewer lines of implementation.
That is, I like Hu's semantics better of creating the copy, but I still think your function is useful, if given the correct name.
Actually I think my function has the right name already. Functions which create new instances should have 'New' in their name, eg virBitmapPtr virBitmapNewCopy(virBitmapPtr src) Unless you object to this suggestion, I'll push my patch and let Hu rebase against it. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 09/12/2012 10:22 AM, Daniel P. Berrange wrote:
This requires you to pre-create the copy, so a better name might be virBitmapCopyInto(), and then rebase Hu's patch, so that his function signature:
Actually I think my function has the right name already. Functions which create new instances should have 'New' in their name, eg
virBitmapPtr virBitmapNewCopy(virBitmapPtr src)
Unless you object to this suggestion, I'll push my patch and let Hu rebase against it.
Yes, your alternate proposal of how to do the new naming makes sense, so ACK to your patch going in as-is. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> Technically speaking we should wait until we receive the QMP greeting message before attempting to send any QMP monitor commands. Mostly we've got away with this, but there is a race in some QEMU which cause it to SEGV if you sent it data too soon after startup. Waiting for the QMP greeting avoids the race Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 290f150..fb67b9a 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -79,6 +79,7 @@ struct _qemuMonitor { unsigned json: 1; unsigned json_hmp: 1; + unsigned wait_greeting: 1; }; static virClassPtr qemuMonitorClass; @@ -365,6 +366,9 @@ qemuMonitorIOProcess(qemuMonitorPtr mon) if (len < 0) return -1; + if (len && mon->wait_greeting) + mon->wait_greeting = 0; + if (len < mon->bufferOffset) { memmove(mon->buffer, mon->buffer + len, mon->bufferOffset - len); mon->bufferOffset -= len; @@ -538,7 +542,8 @@ static void qemuMonitorUpdateWatch(qemuMonitorPtr mon) if (mon->lastError.code == VIR_ERR_OK) { events |= VIR_EVENT_HANDLE_READABLE; - if (mon->msg && mon->msg->txOffset < mon->msg->txLength) + if ((mon->msg && mon->msg->txOffset < mon->msg->txLength) && + !mon->wait_greeting) events |= VIR_EVENT_HANDLE_WRITABLE; } @@ -716,6 +721,8 @@ qemuMonitorOpen(virDomainObjPtr vm, mon->fd = -1; mon->vm = vm; mon->json = json; + if (json) + mon->wait_greeting = 1; mon->cb = cb; qemuMonitorLock(mon); -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Technically speaking we should wait until we receive the QMP greeting message before attempting to send any QMP monitor commands. Mostly we've got away with this, but there is a race in some QEMU which cause it to SEGV if you sent it data too soon after startup. Waiting for the QMP greeting avoids the race
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
ACK.
@@ -716,6 +721,8 @@ qemuMonitorOpen(virDomainObjPtr vm, mon->fd = -1; mon->vm = vm; mon->json = json; + if (json) + mon->wait_greeting = 1;
Could collapse 3 lines to 1 with: mon->json = mon->wait_greeting = json; but that comes at the expense of readability, so keep your version. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 09/11/2012 05:26 PM, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Technically speaking we should wait until we receive the QMP greeting message before attempting to send any QMP monitor commands. Mostly we've got away with this, but there is a race in some QEMU which cause it to SEGV if you sent it data too soon after startup. Waiting for the QMP greeting avoids the race
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
ACK.
Spoke too soon. This makes the testsuite hang in qemumonitorjsontest, as the fake json monitor never manages to trigger the wait_greeting reset to 0. I'm not sure how best to fix the infloop, but that is needed before this patch can go in. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 09/11/2012 05:34 PM, Eric Blake wrote:
soon after startup. Waiting for the QMP greeting avoids the race
Spoke too soon. This makes the testsuite hang in qemumonitorjsontest, as the fake json monitor never manages to trigger the wait_greeting reset to 0. I'm not sure how best to fix the infloop, but that is needed before this patch can go in.
My down-and-dirty hack: diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c index fb67b9a..157d58f 100644 --- i/src/qemu/qemu_monitor.c +++ w/src/qemu/qemu_monitor.c @@ -720,8 +720,8 @@ qemuMonitorOpen(virDomainObjPtr vm, } mon->fd = -1; mon->vm = vm; - mon->json = json; - if (json) + mon->json = !!json; + if (json == 1) mon->wait_greeting = 1; mon->cb = cb; qemuMonitorLock(mon); diff --git i/tests/qemumonitortestutils.c w/tests/qemumonitortestutils.c index 76b11e6..3e7285f 100644 --- i/tests/qemumonitortestutils.c +++ w/tests/qemumonitortestutils.c @@ -458,7 +458,7 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps) if (!(test->mon = qemuMonitorOpen(test->vm, &src, - true, + 2, &qemuCallbacks))) goto error; qemuMonitorLock(test->mon); -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Sep 11, 2012 at 05:34:55PM -0600, Eric Blake wrote:
On 09/11/2012 05:26 PM, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Technically speaking we should wait until we receive the QMP greeting message before attempting to send any QMP monitor commands. Mostly we've got away with this, but there is a race in some QEMU which cause it to SEGV if you sent it data too soon after startup. Waiting for the QMP greeting avoids the race
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
ACK.
Spoke too soon. This makes the testsuite hang in qemumonitorjsontest, as the fake json monitor never manages to trigger the wait_greeting reset to 0. I'm not sure how best to fix the infloop, but that is needed before this patch can go in.
Oh, the fix is to actually send the expected greeting, as a normal QEMU would :-) The following patch prevents a hang in the test suite for me. Can you confirm: diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 76b11e6..77e9a47 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -418,6 +418,9 @@ static qemuMonitorCallbacks qemuCallbacks = { .errorNotify = qemuMonitorTestErrorNotify, }; +#define QEMU_JSON_GREETING "{\"QMP\": {\"version\": {\"qemu\": {\"micro\": 1, \"minor\": 0, \"major\": 1}, \"package\": \" (qemu-kvm-1.0.1)\"}, \"capabilities\ +#define QEMU_TEXT_GREETING "QEMU 1.0,1 monitor - type 'help' for more information" + qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps) { qemuMonitorTestPtr test; @@ -468,8 +471,13 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps) if (!test->client) goto error; + if (qemuMonitorTestAddReponse(test, json ? + QEMU_JSON_GREETING : + QEMU_TEXT_GREETING) < 0) + goto error; + if (virNetSocketAddIOCallback(test->client, - VIR_EVENT_HANDLE_READABLE, + VIR_EVENT_HANDLE_WRITABLE, qemuMonitorTestIO, test, NULL) < 0) Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 09/12/2012 10:37 AM, Daniel P. Berrange wrote:
Spoke too soon. This makes the testsuite hang in qemumonitorjsontest, as the fake json monitor never manages to trigger the wait_greeting reset to 0. I'm not sure how best to fix the infloop, but that is needed before this patch can go in.
Oh, the fix is to actually send the expected greeting, as a normal QEMU would :-)
Yep, much nicer than my hack. (Although my hack points out that tests/qemumonitortestutils.c is passing 'true' to an 'int' parameter of qemuMonitorOpen(), so that's still worth tweaking, by either making qemuMonitorOpen() take a bool, or by fixing the test to pass 1...) Except that it failed to compile: CC libqemumonitortestutils_la-qemumonitortestutils.lo qemumonitortestutils.c:422:82: error: missing terminating " character [-Werror] qemumonitortestutils.c: In function 'qemuMonitorTestNew': qemumonitortestutils.c:475:35: error: expected ':' before 'QEMU' qemumonitortestutils.c:475:35: error: multi-character character constant [-Werror=multichar] qemumonitortestutils.c:475:35: error: missing terminating " character
The following patch prevents a hang in the test suite for me. Can you confirm:
Confirmed. ACK to the original patch + your changes + this squashed in: diff --git i/tests/qemumonitortestutils.c w/tests/qemumonitortestutils.c index 854fb7a..57adbaf 100644 --- i/tests/qemumonitortestutils.c +++ w/tests/qemumonitortestutils.c @@ -418,8 +418,11 @@ static qemuMonitorCallbacks qemuCallbacks = { .errorNotify = qemuMonitorTestErrorNotify, }; -#define QEMU_JSON_GREETING "{\"QMP\": {\"version\": {\"qemu\": {\"micro\": 1, \"minor\": 0, \"major\": 1}, \"package\": \" (qemu-kvm-1.0.1)\"}, \"capabilities\ -#define QEMU_TEXT_GREETING "QEMU 1.0,1 monitor - type 'help' for more information" +#define QEMU_JSON_GREETING "{\"QMP\": {\"version\": {\"qemu\": " \ + "{\"micro\": 1, \"minor\": 0, \"major\": 1}, " \ + "\"package\": \" (qemu-kvm-1.0.1)\"}, \"capabilities\": []}}" +#define QEMU_TEXT_GREETING \ + "QEMU 1.0,1 monitor - type 'help' for more information" qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps) { @@ -461,7 +464,7 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps) if (!(test->mon = qemuMonitorOpen(test->vm, &src, - true, + 1, &qemuCallbacks))) goto error; qemuMonitorLock(test->mon); -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> Currently qemuMonitorOpen() requires an address of the QEMU monitor. When doing QMP based capabilities detection it is easier if a pre-opened FD can be provided, since then the monitor can be run on the STDIO console. Add a new API qemuMonitorOpenFD() for such usage Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 81 ++++++++++++++++++++++++++++++++++--------------- src/qemu/qemu_monitor.h | 5 +++ 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index fb67b9a..543b6cd 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -680,11 +680,12 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { } -qemuMonitorPtr -qemuMonitorOpen(virDomainObjPtr vm, - virDomainChrSourceDefPtr config, - int json, - qemuMonitorCallbacksPtr cb) +static qemuMonitorPtr +qemuMonitorOpenInternal(virDomainObjPtr vm, + int fd, + bool hasSendFD, + int json, + qemuMonitorCallbacksPtr cb) { qemuMonitorPtr mon; @@ -718,7 +719,8 @@ qemuMonitorOpen(virDomainObjPtr vm, VIR_FREE(mon); return NULL; } - mon->fd = -1; + mon->fd = fd; + mon->hasSendFD = hasSendFD; mon->vm = vm; mon->json = json; if (json) @@ -726,25 +728,6 @@ qemuMonitorOpen(virDomainObjPtr vm, mon->cb = cb; qemuMonitorLock(mon); - switch (config->type) { - case VIR_DOMAIN_CHR_TYPE_UNIX: - mon->hasSendFD = 1; - mon->fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid); - break; - - case VIR_DOMAIN_CHR_TYPE_PTY: - mon->fd = qemuMonitorOpenPty(config->data.file.path); - break; - - default: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unable to handle monitor type: %s"), - virDomainChrTypeToString(config->type)); - goto cleanup; - } - - if (mon->fd == -1) goto cleanup; - if (virSetCloseExec(mon->fd) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to set monitor close-on-exec flag")); @@ -785,10 +768,58 @@ cleanup: */ mon->cb = NULL; qemuMonitorUnlock(mon); + /* The caller owns 'fd' on failure */ + mon->fd = -1; + if (mon->watch) + virEventRemoveHandle(mon->watch); qemuMonitorClose(mon); return NULL; } +qemuMonitorPtr +qemuMonitorOpen(virDomainObjPtr vm, + virDomainChrSourceDefPtr config, + int json, + qemuMonitorCallbacksPtr cb) +{ + int fd; + bool hasSendFD = false; + qemuMonitorPtr ret; + + switch (config->type) { + case VIR_DOMAIN_CHR_TYPE_UNIX: + hasSendFD = true; + if ((fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid)) < 0) + return NULL; + break; + + case VIR_DOMAIN_CHR_TYPE_PTY: + if ((fd = qemuMonitorOpenPty(config->data.file.path)) < 0) + return NULL; + break; + + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unable to handle monitor type: %s"), + virDomainChrTypeToString(config->type)); + return NULL; + } + + ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb); + if (!ret) + VIR_FORCE_CLOSE(fd); + return ret; +} + + +qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, + int sockfd, + int json, + qemuMonitorCallbacksPtr cb) +{ + return qemuMonitorOpenInternal(vm, sockfd, true, json, cb); +} + void qemuMonitorClose(qemuMonitorPtr mon) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 2033473..0f7ca2d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -147,6 +147,11 @@ qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, int json, qemuMonitorCallbacksPtr cb) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4); +qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, + int sockfd, + int json, + qemuMonitorCallbacksPtr cb) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); void qemuMonitorClose(qemuMonitorPtr mon); -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Currently qemuMonitorOpen() requires an address of the QEMU monitor. When doing QMP based capabilities detection it is easier if a pre-opened FD can be provided, since then the monitor can be run on the STDIO console. Add a new API qemuMonitorOpenFD() for such usage
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 81 ++++++++++++++++++++++++++++++++++--------------- src/qemu/qemu_monitor.h | 5 +++ 2 files changed, 61 insertions(+), 25 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> Don't bother checking for the existance of the HMP passthrough command. Just try to execute it, and propagate the failure. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 20 +--------------- src/qemu/qemu_monitor_json.c | 56 +++++++++++++++----------------------------- src/qemu/qemu_monitor_json.h | 3 +-- 3 files changed, 21 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 543b6cd..e04af72 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -78,7 +78,6 @@ struct _qemuMonitor { int nextSerial; unsigned json: 1; - unsigned json_hmp: 1; unsigned wait_greeting: 1; }; @@ -1131,7 +1130,6 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon, virBitmapPtr qemuCaps) { int ret; - int json_hmp; VIR_DEBUG("mon=%p", mon); if (!mon) { @@ -1145,10 +1143,9 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon, if (ret < 0) goto cleanup; - ret = qemuMonitorJSONCheckCommands(mon, qemuCaps, &json_hmp); + ret = qemuMonitorJSONCheckCommands(mon, qemuCaps); if (ret < 0) goto cleanup; - mon->json_hmp = json_hmp > 0; ret = qemuMonitorJSONCheckEvents(mon, qemuCaps); if (ret < 0) @@ -1163,21 +1160,6 @@ cleanup: int -qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd) -{ - if (!mon->json || mon->json_hmp) - return 1; - - if (cmd) { - VIR_DEBUG("HMP passthrough not supported by qemu process;" - " not trying HMP for command %s", cmd); - } - - return 0; -} - - -int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn) { diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index bab6ca2..10a68c6 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -909,6 +909,13 @@ qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, scm_fd, &reply) < 0) goto cleanup; + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Human monitor command is not available to run %s"), + cmd_str); + goto cleanup; + } + if (qemuMonitorJSONCheckError(cmd, reply)) goto cleanup; @@ -967,8 +974,7 @@ qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon) */ int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - virBitmapPtr qemuCaps, - int *json_hmp) + virBitmapPtr qemuCaps) { int ret = -1; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-commands", NULL); @@ -996,9 +1002,7 @@ qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, !(name = virJSONValueObjectGetString(entry, "name"))) goto cleanup; - if (STREQ(name, "human-monitor-command")) - *json_hmp = 1; - else if (STREQ(name, "system_wakeup")) + if (STREQ(name, "system_wakeup")) qemuCapsSet(qemuCaps, QEMU_CAPS_WAKEUP); else if (STREQ(name, "transaction")) qemuCapsSet(qemuCaps, QEMU_CAPS_TRANSACTION); @@ -2183,8 +2187,7 @@ int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "cpu_set")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("cpu_set command not found, trying HMP"); ret = qemuMonitorTextSetCPU(mon, cpu, online); goto cleanup; @@ -3078,8 +3081,7 @@ int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply) < 0)) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "drive_add")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("drive_add command not found, trying HMP"); ret = qemuMonitorTextAddDrive(mon, drivestr); goto cleanup; @@ -3112,14 +3114,8 @@ int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, goto cleanup; if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { - if (qemuMonitorCheckHMP(mon, "drive_del")) { - VIR_DEBUG("drive_del command not found, trying HMP"); - ret = qemuMonitorTextDriveDel(mon, drivestr); - } else { - VIR_ERROR(_("deleting disk is not supported. " - "This may leak data if disk is reassigned")); - ret = 1; - } + VIR_DEBUG("drive_del command not found, trying HMP"); + ret = qemuMonitorTextDriveDel(mon, drivestr); } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) { /* NB: device not found errors mean the drive was * auto-deleted and we ignore the error */ @@ -3181,8 +3177,7 @@ int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "savevm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("savevm command not found, trying HMP"); ret = qemuMonitorTextCreateSnapshot(mon, name); goto cleanup; @@ -3211,8 +3206,7 @@ int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "loadvm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("loadvm command not found, trying HMP"); ret = qemuMonitorTextLoadSnapshot(mon, name); goto cleanup; @@ -3241,8 +3235,7 @@ int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "delvm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("delvm command not found, trying HMP"); ret = qemuMonitorTextDeleteSnapshot(mon, name); goto cleanup; @@ -3287,8 +3280,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "snapshot_blkdev")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("blockdev-snapshot-sync command not found, trying HMP"); ret = qemuMonitorTextDiskSnapshot(mon, device, file); goto cleanup; @@ -3341,12 +3333,6 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, int ret = -1; if (hmp) { - if (!qemuMonitorCheckHMP(mon, NULL)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("HMP passthrough is not supported by qemu" - " process; only QMP commands can be used")); - return -1; - } return qemuMonitorJSONHumanCommandWithFd(mon, cmd_str, -1, reply_str); } else { if (!(cmd = virJSONValueFromString(cmd_str))) @@ -3381,8 +3367,7 @@ int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "inject-nmi")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("inject-nmi command not found, trying HMP"); ret = qemuMonitorTextInjectNMI(mon); } else { @@ -3404,10 +3389,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon, * FIXME: qmp sendkey has not been implemented yet, * and qmp API of it cannot be anticipated, so we use hmp temporary. */ - if (qemuMonitorCheckHMP(mon, "sendkey")) { - return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes); - } else - return -1; + return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes); } int qemuMonitorJSONScreendump(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 3255007..f6e34f4 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -43,8 +43,7 @@ int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, int qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon); int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - virBitmapPtr qemuCaps, - int *json_hmp); + virBitmapPtr qemuCaps); int qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, virBitmapPtr qemuCaps); -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Don't bother checking for the existance of the HMP passthrough command. Just try to execute it, and propagate the failure.
And these days, there's very few remaining HMP passthrough commands to worry about (meanwhile, there's some libvirt patches to write to pick up commands that no longer require HMP passthrough, such as send-key).
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 20 +--------------- src/qemu/qemu_monitor_json.c | 56 +++++++++++++++----------------------------- src/qemu/qemu_monitor_json.h | 3 +-- 3 files changed, 21 insertions(+), 58 deletions(-)
Much simpler. However,
int -qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd) -{ - if (!mon->json || mon->json_hmp) - return 1; - - if (cmd) { - VIR_DEBUG("HMP passthrough not supported by qemu process;" - " not trying HMP for command %s", cmd);
The old code used VIR_DEBUG,
+++ b/src/qemu/qemu_monitor_json.c @@ -909,6 +909,13 @@ qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, scm_fd, &reply) < 0) goto cleanup;
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Human monitor command is not available to run %s"), + cmd_str);
and the new code turns it into a hard error. I think that's a correct conversion, but the wrong choice of error code (see below [1]).
@@ -3112,14 +3114,8 @@ int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, goto cleanup;
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { - if (qemuMonitorCheckHMP(mon, "drive_del")) { - VIR_DEBUG("drive_del command not found, trying HMP"); - ret = qemuMonitorTextDriveDel(mon, drivestr); - } else { - VIR_ERROR(_("deleting disk is not supported. " - "This may leak data if disk is reassigned")); - ret = 1; - } + VIR_DEBUG("drive_del command not found, trying HMP"); + ret = qemuMonitorTextDriveDel(mon, drivestr);
Another subtle case of semantic changes. The old code did a fallback (by setting ret = 1), the new code now flat-out fails, and skips attempting the fallback. This time, I'm not so sure the change in semantics is correct.
@@ -3341,12 +3333,6 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, int ret = -1;
if (hmp) { - if (!qemuMonitorCheckHMP(mon, NULL)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("HMP passthrough is not supported by qemu" - " process; only QMP commands can be used")); - return -1; - }
[1] here, we are going from a nice VIR_ERR_CONFIG_UNSUPPORTED to a not-so-nice VIR_ERR_INTERNAL_ERROR. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Sep 11, 2012 at 05:59:06PM -0600, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Don't bother checking for the existance of the HMP passthrough command. Just try to execute it, and propagate the failure.
And these days, there's very few remaining HMP passthrough commands to worry about (meanwhile, there's some libvirt patches to write to pick up commands that no longer require HMP passthrough, such as send-key).
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 20 +--------------- src/qemu/qemu_monitor_json.c | 56 +++++++++++++++----------------------------- src/qemu/qemu_monitor_json.h | 3 +-- 3 files changed, 21 insertions(+), 58 deletions(-)
Much simpler. However,
int -qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd) -{ - if (!mon->json || mon->json_hmp) - return 1; - - if (cmd) { - VIR_DEBUG("HMP passthrough not supported by qemu process;" - " not trying HMP for command %s", cmd);
The old code used VIR_DEBUG,
+++ b/src/qemu/qemu_monitor_json.c @@ -909,6 +909,13 @@ qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, scm_fd, &reply) < 0) goto cleanup;
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Human monitor command is not available to run %s"), + cmd_str);
and the new code turns it into a hard error. I think that's a correct conversion, but the wrong choice of error code (see below [1]).
There's no actual change in semantics in general since although qemuMonitorCheckHMP() would VIR_DEBUG, the callers would then raise an actual error.
@@ -3112,14 +3114,8 @@ int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, goto cleanup;
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { - if (qemuMonitorCheckHMP(mon, "drive_del")) { - VIR_DEBUG("drive_del command not found, trying HMP"); - ret = qemuMonitorTextDriveDel(mon, drivestr); - } else { - VIR_ERROR(_("deleting disk is not supported. " - "This may leak data if disk is reassigned")); - ret = 1; - } + VIR_DEBUG("drive_del command not found, trying HMP"); + ret = qemuMonitorTextDriveDel(mon, drivestr);
Another subtle case of semantic changes. The old code did a fallback (by setting ret = 1), the new code now flat-out fails, and skips attempting the fallback. This time, I'm not so sure the change in semantics is correct.
This is a genuine bug - I'll fix this. We can make qemuMonitorJSONHumanCommandWithFd return -2 on CommandNotFound, and propagate this all the way back to the callers.
@@ -3341,12 +3333,6 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, int ret = -1;
if (hmp) { - if (!qemuMonitorCheckHMP(mon, NULL)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("HMP passthrough is not supported by qemu" - " process; only QMP commands can be used")); - return -1; - }
[1] here, we are going from a nice VIR_ERR_CONFIG_UNSUPPORTED to a not-so-nice VIR_ERR_INTERNAL_ERROR.
Arguably that error code is wrong already - CONFIG_UNSUPPORTED is for things you specify in the XML which are not supported. It isn't for API calls really. I should change it to OPERATION_UNSUPPORTED instad of INTERNAL_ERROR though. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Don't bother checking for the existance of the HMP passthrough command. Just try to execute it, and propagate the failure. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 20 +------------- src/qemu/qemu_monitor_json.c | 63 +++++++++++++++++++------------------------- src/qemu/qemu_monitor_json.h | 3 +-- 3 files changed, 29 insertions(+), 57 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index b43b15e..f8d717f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -78,7 +78,6 @@ struct _qemuMonitor { int nextSerial; unsigned json: 1; - unsigned json_hmp: 1; unsigned wait_greeting: 1; }; @@ -1131,7 +1130,6 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon, qemuCapsPtr caps) { int ret; - int json_hmp; VIR_DEBUG("mon=%p", mon); if (!mon) { @@ -1145,10 +1143,9 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon, if (ret < 0) goto cleanup; - ret = qemuMonitorJSONCheckCommands(mon, caps, &json_hmp); + ret = qemuMonitorJSONCheckCommands(mon, caps); if (ret < 0) goto cleanup; - mon->json_hmp = json_hmp > 0; ret = qemuMonitorJSONCheckEvents(mon, caps); if (ret < 0) @@ -1163,21 +1160,6 @@ cleanup: int -qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd) -{ - if (!mon->json || mon->json_hmp) - return 1; - - if (cmd) { - VIR_DEBUG("HMP passthrough not supported by qemu process;" - " not trying HMP for command %s", cmd); - } - - return 0; -} - - -int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn) { diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 8842817..ed18a64 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -909,6 +909,13 @@ qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, scm_fd, &reply) < 0) goto cleanup; + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("Human monitor command is not available to run %s"), + cmd_str); + goto cleanup; + } + if (qemuMonitorJSONCheckError(cmd, reply)) goto cleanup; @@ -967,8 +974,7 @@ qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon) */ int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - qemuCapsPtr caps, - int *json_hmp) + qemuCapsPtr caps) { int ret = -1; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-commands", NULL); @@ -996,9 +1002,7 @@ qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, !(name = virJSONValueObjectGetString(entry, "name"))) goto cleanup; - if (STREQ(name, "human-monitor-command")) - *json_hmp = 1; - else if (STREQ(name, "system_wakeup")) + if (STREQ(name, "system_wakeup")) qemuCapsSet(caps, QEMU_CAPS_WAKEUP); else if (STREQ(name, "transaction")) qemuCapsSet(caps, QEMU_CAPS_TRANSACTION); @@ -2183,8 +2187,7 @@ int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "cpu_set")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("cpu_set command not found, trying HMP"); ret = qemuMonitorTextSetCPU(mon, cpu, online); goto cleanup; @@ -3078,8 +3081,7 @@ int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply) < 0)) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "drive_add")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("drive_add command not found, trying HMP"); ret = qemuMonitorTextAddDrive(mon, drivestr); goto cleanup; @@ -3112,13 +3114,16 @@ int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, goto cleanup; if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { - if (qemuMonitorCheckHMP(mon, "drive_del")) { - VIR_DEBUG("drive_del command not found, trying HMP"); - ret = qemuMonitorTextDriveDel(mon, drivestr); - } else { - VIR_ERROR(_("deleting disk is not supported. " - "This may leak data if disk is reassigned")); - ret = 1; + VIR_DEBUG("drive_del command not found, trying HMP"); + if ((ret = qemuMonitorTextDriveDel(mon, drivestr)) < 0) { + virErrorPtr err = virGetLastError(); + if (err && err->code == VIR_ERR_OPERATION_UNSUPPORTED) { + VIR_ERROR("%s", + _("deleting disk is not supported. " + "This may leak data if disk is reassigned")); + ret = 1; + virResetLastError();; + } } } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) { /* NB: device not found errors mean the drive was @@ -3181,8 +3186,7 @@ int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "savevm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("savevm command not found, trying HMP"); ret = qemuMonitorTextCreateSnapshot(mon, name); goto cleanup; @@ -3211,8 +3215,7 @@ int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "loadvm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("loadvm command not found, trying HMP"); ret = qemuMonitorTextLoadSnapshot(mon, name); goto cleanup; @@ -3241,8 +3244,7 @@ int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "delvm")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("delvm command not found, trying HMP"); ret = qemuMonitorTextDeleteSnapshot(mon, name); goto cleanup; @@ -3287,8 +3289,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions, if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "snapshot_blkdev")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("blockdev-snapshot-sync command not found, trying HMP"); ret = qemuMonitorTextDiskSnapshot(mon, device, file); goto cleanup; @@ -3341,12 +3342,6 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, int ret = -1; if (hmp) { - if (!qemuMonitorCheckHMP(mon, NULL)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("HMP passthrough is not supported by qemu" - " process; only QMP commands can be used")); - return -1; - } return qemuMonitorJSONHumanCommandWithFd(mon, cmd_str, -1, reply_str); } else { if (!(cmd = virJSONValueFromString(cmd_str))) @@ -3381,8 +3376,7 @@ int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon) if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) goto cleanup; - if (qemuMonitorJSONHasError(reply, "CommandNotFound") && - qemuMonitorCheckHMP(mon, "inject-nmi")) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { VIR_DEBUG("inject-nmi command not found, trying HMP"); ret = qemuMonitorTextInjectNMI(mon); } else { @@ -3404,10 +3398,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon, * FIXME: qmp sendkey has not been implemented yet, * and qmp API of it cannot be anticipated, so we use hmp temporary. */ - if (qemuMonitorCheckHMP(mon, "sendkey")) { - return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes); - } else - return -1; + return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes); } int qemuMonitorJSONScreendump(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index f5d515f..d092b88 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -43,8 +43,7 @@ int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, int qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon); int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - qemuCapsPtr caps, - int *json_hmp); + qemuCapsPtr caps); int qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, qemuCapsPtr caps); -- 1.7.11.4

On 09/13/2012 07:29 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Don't bother checking for the existance of the HMP passthrough command. Just try to execute it, and propagate the failure.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_monitor.c | 20 +------------- src/qemu/qemu_monitor_json.c | 63 +++++++++++++++++++------------------------- src/qemu/qemu_monitor_json.h | 3 +-- 3 files changed, 29 insertions(+), 57 deletions(-)
Better. ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> If no private data needs to be maintained, it can be useful to create virDomainObjPtr instances without having a virCapsPtr instance around. Adapt the virDomainObjNew() function to allow for a NULL caps Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8952b69..ef368f7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1716,12 +1716,14 @@ virDomainObjPtr virDomainObjNew(virCapsPtr caps) return NULL; } - if (caps->privateDataAllocFunc && - !(domain->privateData = (caps->privateDataAllocFunc)())) { - virReportOOMError(); - goto error; + if (caps && + caps->privateDataAllocFunc) { + if (!(domain->privateData = (caps->privateDataAllocFunc)())) { + virReportOOMError(); + goto error; + } + domain->privateDataFreeFunc = caps->privateDataFreeFunc; } - domain->privateDataFreeFunc = caps->privateDataFreeFunc; if (!(domain->snapshots = virDomainSnapshotObjListNew())) goto error; -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
If no private data needs to be maintained, it can be useful to create virDomainObjPtr instances without having a virCapsPtr instance around. Adapt the virDomainObjNew() function to allow for a NULL caps
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> The current qemu capabilities are stored in a virBitmapPtr object, whose type is exposed to callers. We want to store more data besides just the flags, so we need to move to a struct type. This object will also need to be reference counted, since we'll be maintaining a cache of data per binary. This change introduces a 'qemuCapsPtr' virObject class. Most of the change is just renaming types and variables in all the callers Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 376 ++++++++++++++++------------ src/qemu/qemu_capabilities.h | 29 ++- src/qemu/qemu_command.c | 580 +++++++++++++++++++++---------------------- src/qemu/qemu_command.h | 53 ++-- src/qemu/qemu_domain.c | 16 +- src/qemu/qemu_domain.h | 4 +- src/qemu/qemu_driver.c | 40 +-- src/qemu/qemu_hotplug.c | 138 +++++----- src/qemu/qemu_migration.c | 16 +- src/qemu/qemu_monitor.c | 6 +- src/qemu/qemu_monitor.h | 3 +- src/qemu/qemu_monitor_json.c | 16 +- src/qemu/qemu_monitor_json.h | 4 +- src/qemu/qemu_process.c | 62 ++--- tests/qemuhelptest.c | 16 +- tests/qemuxml2argvtest.c | 6 +- tests/qemuxmlnstest.c | 6 +- 17 files changed, 712 insertions(+), 659 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ed85b6f..b8c1f36 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -178,6 +178,28 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "disable-s4", /* 105 */ ); +struct _qemuCaps { + virObject object; + + virBitmapPtr flags; +}; + + +static virClassPtr qemuCapsClass; +static void qemuCapsDispose(void *obj); + +static int qemuCapsOnceInit(void) +{ + if (!(qemuCapsClass = virClassNew("qemuCaps", + sizeof(qemuCaps), + qemuCapsDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(qemuCaps) + struct qemu_feature_flags { const char *name; const int default_on; @@ -304,7 +326,7 @@ qemuCapsParseMachineTypesStr(const char *output, int qemuCapsProbeMachineTypes(const char *binary, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virCapsGuestMachinePtr **machines, int *nmachines) { @@ -322,7 +344,7 @@ qemuCapsProbeMachineTypes(const char *binary, return -1; } - cmd = qemuCapsProbeCommand(binary, qemuCaps); + cmd = qemuCapsProbeCommand(binary, caps); virCommandAddArgList(cmd, "-M", "?", NULL); virCommandSetOutputBuffer(cmd, &output); @@ -590,7 +612,7 @@ cleanup: int qemuCapsProbeCPUModels(const char *qemu, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, const char *arch, unsigned int *count, const char ***cpus) @@ -614,7 +636,7 @@ qemuCapsProbeCPUModels(const char *qemu, return 0; } - cmd = qemuCapsProbeCommand(qemu, qemuCaps); + cmd = qemuCapsProbeCommand(qemu, caps); virCommandAddArgList(cmd, "-cpu", "?", NULL); virCommandSetOutputBuffer(cmd, &output); @@ -652,8 +674,8 @@ qemuCapsInitGuest(virCapsPtr caps, int nmachines = 0; struct stat st; unsigned int ncpus; - virBitmapPtr qemuCaps = NULL; - virBitmapPtr kvmCaps = NULL; + qemuCapsPtr qemubinCaps = NULL; + qemuCapsPtr kvmbinCaps = NULL; int ret = -1; /* Check for existance of base emulator, or alternate base @@ -669,7 +691,7 @@ qemuCapsInitGuest(virCapsPtr caps, /* Ignore binary if extracting version info fails */ if (binary && qemuCapsExtractVersionInfo(binary, info->arch, - false, NULL, &qemuCaps) < 0) + false, NULL, &qemubinCaps) < 0) VIR_FREE(binary); /* qemu-kvm/kvm binaries can only be used if @@ -692,16 +714,16 @@ qemuCapsInitGuest(virCapsPtr caps, if (qemuCapsExtractVersionInfo(kvmbin, info->arch, false, NULL, - &kvmCaps) < 0) { + &kvmbinCaps) < 0) { VIR_FREE(kvmbin); continue; } if (!binary) { binary = kvmbin; - qemuCaps = kvmCaps; + qemubinCaps = kvmbinCaps; kvmbin = NULL; - kvmCaps = NULL; + kvmbinCaps = NULL; } break; } @@ -711,13 +733,13 @@ qemuCapsInitGuest(virCapsPtr caps, return 0; if (access("/dev/kvm", F_OK) == 0 && - (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM) || - qemuCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM) || + (qemuCapsGet(qemubinCaps, QEMU_CAPS_KVM) || + qemuCapsGet(qemubinCaps, QEMU_CAPS_ENABLE_KVM) || kvmbin)) haskvm = 1; if (access("/dev/kqemu", F_OK) == 0 && - qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) + qemuCapsGet(qemubinCaps, QEMU_CAPS_KQEMU)) haskqemu = 1; if (stat(binary, &st) == 0) { @@ -757,7 +779,7 @@ qemuCapsInitGuest(virCapsPtr caps, info->wordsize, binary, binary_mtime, old_caps, &machines, &nmachines); if (probe && - qemuCapsProbeMachineTypes(binary, qemuCaps, + qemuCapsProbeMachineTypes(binary, qemubinCaps, &machines, &nmachines) < 0) goto error; } @@ -785,7 +807,7 @@ qemuCapsInitGuest(virCapsPtr caps, !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0)) goto error; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) && + if (qemuCapsGet(qemubinCaps, QEMU_CAPS_BOOTINDEX) && !virCapabilitiesAddGuestFeature(guest, "deviceboot", 1, 0)) goto error; @@ -828,7 +850,7 @@ qemuCapsInitGuest(virCapsPtr caps, binary_mtime, old_caps, &machines, &nmachines); if (probe && - qemuCapsProbeMachineTypes(kvmbin, qemuCaps, + qemuCapsProbeMachineTypes(kvmbin, kvmbinCaps, &machines, &nmachines) < 0) goto error; } @@ -872,8 +894,8 @@ qemuCapsInitGuest(virCapsPtr caps, cleanup: VIR_FREE(binary); VIR_FREE(kvmbin); - qemuCapsFree(qemuCaps); - qemuCapsFree(kvmCaps); + virObjectUnref(qemubinCaps); + virObjectUnref(kvmbinCaps); return ret; @@ -1023,122 +1045,122 @@ qemuCapsComputeCmdFlags(const char *help, unsigned int version, unsigned int is_kvm, unsigned int kvm_version, - virBitmapPtr flags, + qemuCapsPtr caps, bool check_yajl ATTRIBUTE_UNUSED) { const char *p; const char *fsdev, *netdev; if (strstr(help, "-no-kqemu")) - qemuCapsSet(flags, QEMU_CAPS_KQEMU); + qemuCapsSet(caps, QEMU_CAPS_KQEMU); if (strstr(help, "-enable-kqemu")) - qemuCapsSet(flags, QEMU_CAPS_ENABLE_KQEMU); + qemuCapsSet(caps, QEMU_CAPS_ENABLE_KQEMU); if (strstr(help, "-no-kvm")) - qemuCapsSet(flags, QEMU_CAPS_KVM); + qemuCapsSet(caps, QEMU_CAPS_KVM); if (strstr(help, "-enable-kvm")) - qemuCapsSet(flags, QEMU_CAPS_ENABLE_KVM); + qemuCapsSet(caps, QEMU_CAPS_ENABLE_KVM); if (strstr(help, "-no-reboot")) - qemuCapsSet(flags, QEMU_CAPS_NO_REBOOT); + qemuCapsSet(caps, QEMU_CAPS_NO_REBOOT); if (strstr(help, "-name")) { - qemuCapsSet(flags, QEMU_CAPS_NAME); + qemuCapsSet(caps, QEMU_CAPS_NAME); if (strstr(help, ",process=")) - qemuCapsSet(flags, QEMU_CAPS_NAME_PROCESS); + qemuCapsSet(caps, QEMU_CAPS_NAME_PROCESS); } if (strstr(help, "-uuid")) - qemuCapsSet(flags, QEMU_CAPS_UUID); + qemuCapsSet(caps, QEMU_CAPS_UUID); if (strstr(help, "-xen-domid")) - qemuCapsSet(flags, QEMU_CAPS_XEN_DOMID); + qemuCapsSet(caps, QEMU_CAPS_XEN_DOMID); else if (strstr(help, "-domid")) - qemuCapsSet(flags, QEMU_CAPS_DOMID); + qemuCapsSet(caps, QEMU_CAPS_DOMID); if (strstr(help, "-drive")) { const char *cache = strstr(help, "cache="); - qemuCapsSet(flags, QEMU_CAPS_DRIVE); + qemuCapsSet(caps, QEMU_CAPS_DRIVE); if (cache && (p = strchr(cache, ']'))) { if (memmem(cache, p - cache, "on|off", sizeof("on|off") - 1) == NULL) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_CACHE_V2); if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1)) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC); if (memmem(cache, p - cache, "unsafe", sizeof("unsafe") - 1)) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_UNSAFE); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_CACHE_UNSAFE); } if (strstr(help, "format=")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_FORMAT); if (strstr(help, "readonly=")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_READONLY); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_READONLY); if (strstr(help, "aio=threads|native")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_AIO); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_AIO); if (strstr(help, "copy-on-read=on|off")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_COPY_ON_READ); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_COPY_ON_READ); if (strstr(help, "bps=")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_IOTUNE); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_IOTUNE); } if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) { const char *nl = strstr(p, "\n"); - qemuCapsSet(flags, QEMU_CAPS_VGA); + qemuCapsSet(caps, QEMU_CAPS_VGA); if (strstr(p, "|qxl")) - qemuCapsSet(flags, QEMU_CAPS_VGA_QXL); + qemuCapsSet(caps, QEMU_CAPS_VGA_QXL); if ((p = strstr(p, "|none")) && p < nl) - qemuCapsSet(flags, QEMU_CAPS_VGA_NONE); + qemuCapsSet(caps, QEMU_CAPS_VGA_NONE); } if (strstr(help, "-spice")) - qemuCapsSet(flags, QEMU_CAPS_SPICE); + qemuCapsSet(caps, QEMU_CAPS_SPICE); if (strstr(help, "boot=on")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_BOOT); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_BOOT); if (strstr(help, "serial=s")) - qemuCapsSet(flags, QEMU_CAPS_DRIVE_SERIAL); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_SERIAL); if (strstr(help, "-pcidevice")) - qemuCapsSet(flags, QEMU_CAPS_PCIDEVICE); + qemuCapsSet(caps, QEMU_CAPS_PCIDEVICE); if (strstr(help, "-mem-path")) - qemuCapsSet(flags, QEMU_CAPS_MEM_PATH); + qemuCapsSet(caps, QEMU_CAPS_MEM_PATH); if (strstr(help, "-chardev")) { - qemuCapsSet(flags, QEMU_CAPS_CHARDEV); + qemuCapsSet(caps, QEMU_CAPS_CHARDEV); if (strstr(help, "-chardev spicevmc")) - qemuCapsSet(flags, QEMU_CAPS_CHARDEV_SPICEVMC); + qemuCapsSet(caps, QEMU_CAPS_CHARDEV_SPICEVMC); } if (strstr(help, "-balloon")) - qemuCapsSet(flags, QEMU_CAPS_BALLOON); + qemuCapsSet(caps, QEMU_CAPS_BALLOON); if (strstr(help, "-device")) { - qemuCapsSet(flags, QEMU_CAPS_DEVICE); + qemuCapsSet(caps, QEMU_CAPS_DEVICE); /* * When -device was introduced, qemu already supported drive's * readonly option but didn't advertise that. */ - qemuCapsSet(flags, QEMU_CAPS_DRIVE_READONLY); + qemuCapsSet(caps, QEMU_CAPS_DRIVE_READONLY); } if (strstr(help, "-nodefconfig")) - qemuCapsSet(flags, QEMU_CAPS_NODEFCONFIG); + qemuCapsSet(caps, QEMU_CAPS_NODEFCONFIG); if (strstr(help, "-no-user-config")) - qemuCapsSet(flags, QEMU_CAPS_NO_USER_CONFIG); + qemuCapsSet(caps, QEMU_CAPS_NO_USER_CONFIG); /* The trailing ' ' is important to avoid a bogus match */ if (strstr(help, "-rtc ")) - qemuCapsSet(flags, QEMU_CAPS_RTC); + qemuCapsSet(caps, QEMU_CAPS_RTC); /* to wit */ if (strstr(help, "-rtc-td-hack")) - qemuCapsSet(flags, QEMU_CAPS_RTC_TD_HACK); + qemuCapsSet(caps, QEMU_CAPS_RTC_TD_HACK); if (strstr(help, "-no-hpet")) - qemuCapsSet(flags, QEMU_CAPS_NO_HPET); + qemuCapsSet(caps, QEMU_CAPS_NO_HPET); if (strstr(help, "-no-acpi")) - qemuCapsSet(flags, QEMU_CAPS_NO_ACPI); + qemuCapsSet(caps, QEMU_CAPS_NO_ACPI); if (strstr(help, "-no-kvm-pit-reinjection")) - qemuCapsSet(flags, QEMU_CAPS_NO_KVM_PIT); + qemuCapsSet(caps, QEMU_CAPS_NO_KVM_PIT); if (strstr(help, "-tdf")) - qemuCapsSet(flags, QEMU_CAPS_TDF); + qemuCapsSet(caps, QEMU_CAPS_TDF); if (strstr(help, "-enable-nesting")) - qemuCapsSet(flags, QEMU_CAPS_NESTING); + qemuCapsSet(caps, QEMU_CAPS_NESTING); if (strstr(help, ",menu=on")) - qemuCapsSet(flags, QEMU_CAPS_BOOT_MENU); + qemuCapsSet(caps, QEMU_CAPS_BOOT_MENU); if ((fsdev = strstr(help, "-fsdev"))) { - qemuCapsSet(flags, QEMU_CAPS_FSDEV); + qemuCapsSet(caps, QEMU_CAPS_FSDEV); if (strstr(fsdev, "readonly")) - qemuCapsSet(flags, QEMU_CAPS_FSDEV_READONLY); + qemuCapsSet(caps, QEMU_CAPS_FSDEV_READONLY); if (strstr(fsdev, "writeout")) - qemuCapsSet(flags, QEMU_CAPS_FSDEV_WRITEOUT); + qemuCapsSet(caps, QEMU_CAPS_FSDEV_WRITEOUT); } if (strstr(help, "-smbios type")) - qemuCapsSet(flags, QEMU_CAPS_SMBIOS_TYPE); + qemuCapsSet(caps, QEMU_CAPS_SMBIOS_TYPE); if ((netdev = strstr(help, "-netdev"))) { /* Disable -netdev on 0.12 since although it exists, @@ -1147,26 +1169,26 @@ qemuCapsComputeCmdFlags(const char *help, * But see below about RHEL build. */ if (version >= 13000) { if (strstr(netdev, "bridge")) - qemuCapsSet(flags, QEMU_CAPS_NETDEV_BRIDGE); - qemuCapsSet(flags, QEMU_CAPS_NETDEV); + qemuCapsSet(caps, QEMU_CAPS_NETDEV_BRIDGE); + qemuCapsSet(caps, QEMU_CAPS_NETDEV); } } if (strstr(help, "-sdl")) - qemuCapsSet(flags, QEMU_CAPS_SDL); + qemuCapsSet(caps, QEMU_CAPS_SDL); if (strstr(help, "cores=") && strstr(help, "threads=") && strstr(help, "sockets=")) - qemuCapsSet(flags, QEMU_CAPS_SMP_TOPOLOGY); + qemuCapsSet(caps, QEMU_CAPS_SMP_TOPOLOGY); if (version >= 9000) - qemuCapsSet(flags, QEMU_CAPS_VNC_COLON); + qemuCapsSet(caps, QEMU_CAPS_VNC_COLON); if (is_kvm && (version >= 10000 || kvm_version >= 74)) - qemuCapsSet(flags, QEMU_CAPS_VNET_HDR); + qemuCapsSet(caps, QEMU_CAPS_VNET_HDR); if (strstr(help, ",vhost=")) { - qemuCapsSet(flags, QEMU_CAPS_VHOST_NET); + qemuCapsSet(caps, QEMU_CAPS_VHOST_NET); } /* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling @@ -1174,7 +1196,7 @@ qemuCapsComputeCmdFlags(const char *help, * 0.14.* and 0.15.0) */ if (strstr(help, "-no-shutdown") && (version < 14000 || version > 15000)) - qemuCapsSet(flags, QEMU_CAPS_NO_SHUTDOWN); + qemuCapsSet(caps, QEMU_CAPS_NO_SHUTDOWN); /* * Handling of -incoming arg with varying features @@ -1189,25 +1211,25 @@ qemuCapsComputeCmdFlags(const char *help, * while waiting for data, so pretend it doesn't exist */ if (version >= 10000) { - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_TCP); - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_EXEC); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_TCP); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_EXEC); if (version >= 12000) { - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_UNIX); - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_FD); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_UNIX); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_FD); } } else if (kvm_version >= 79) { - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_TCP); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_TCP); if (kvm_version >= 80) - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_QEMU_EXEC); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_EXEC); } else if (kvm_version > 0) { - qemuCapsSet(flags, QEMU_CAPS_MIGRATE_KVM_STDIO); + qemuCapsSet(caps, QEMU_CAPS_MIGRATE_KVM_STDIO); } if (version >= 10000) - qemuCapsSet(flags, QEMU_CAPS_0_10); + qemuCapsSet(caps, QEMU_CAPS_0_10); if (version >= 11000) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_BLK_SG_IO); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_BLK_SG_IO); /* While JSON mode was available in 0.12.0, it was too * incomplete to contemplate using. The 0.13.0 release @@ -1220,11 +1242,11 @@ qemuCapsComputeCmdFlags(const char *help, */ #if HAVE_YAJL if (version >= 13000) { - qemuCapsSet(flags, QEMU_CAPS_MONITOR_JSON); + qemuCapsSet(caps, QEMU_CAPS_MONITOR_JSON); } else if (version >= 12000 && strstr(help, "libvirt")) { - qemuCapsSet(flags, QEMU_CAPS_MONITOR_JSON); - qemuCapsSet(flags, QEMU_CAPS_NETDEV); + qemuCapsSet(caps, QEMU_CAPS_MONITOR_JSON); + qemuCapsSet(caps, QEMU_CAPS_NETDEV); } #else /* Starting with qemu 0.15 and newer, upstream qemu no longer @@ -1243,12 +1265,12 @@ qemuCapsComputeCmdFlags(const char *help, "compiled with yajl")); return -1; } - qemuCapsSet(flags, QEMU_CAPS_NETDEV); + qemuCapsSet(caps, QEMU_CAPS_NETDEV); } #endif if (version >= 13000) - qemuCapsSet(flags, QEMU_CAPS_PCI_MULTIFUNCTION); + qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIFUNCTION); /* Although very new versions of qemu advertise the presence of * the rombar option in the output of "qemu -device pci-assign,?", @@ -1261,10 +1283,10 @@ qemuCapsComputeCmdFlags(const char *help, * log and refuse to start, so it would be immediately obvious). */ if (version >= 12000) - qemuCapsSet(flags, QEMU_CAPS_PCI_ROMBAR); + qemuCapsSet(caps, QEMU_CAPS_PCI_ROMBAR); if (version >= 11000) - qemuCapsSet(flags, QEMU_CAPS_CPU_HOST); + qemuCapsSet(caps, QEMU_CAPS_CPU_HOST); return 0; } @@ -1294,7 +1316,7 @@ qemuCapsComputeCmdFlags(const char *help, int qemuCapsParseHelpStr(const char *qemu, const char *help, - virBitmapPtr flags, + qemuCapsPtr caps, unsigned int *version, unsigned int *is_kvm, unsigned int *kvm_version, @@ -1355,10 +1377,10 @@ int qemuCapsParseHelpStr(const char *qemu, *version = (major * 1000 * 1000) + (minor * 1000) + micro; if (qemuCapsComputeCmdFlags(help, *version, *is_kvm, *kvm_version, - flags, check_yajl) < 0) + caps, check_yajl) < 0) goto cleanup; - strflags = virBitmapString(flags); + strflags = virBitmapString(caps->flags); VIR_DEBUG("Version %u.%u.%u, cooked version %u, flags %s", major, minor, micro, *version, NULLSTR(strflags)); VIR_FREE(strflags); @@ -1385,7 +1407,7 @@ cleanup: static int qemuCapsExtractDeviceStr(const char *qemu, - virBitmapPtr flags) + qemuCapsPtr caps) { char *output = NULL; virCommandPtr cmd; @@ -1399,7 +1421,7 @@ qemuCapsExtractDeviceStr(const char *qemu, * understand '-device name,?', and always exits with status 1 for * the simpler '-device ?', so this function is really only useful * if -help includes "device driver,?". */ - cmd = qemuCapsProbeCommand(qemu, flags); + cmd = qemuCapsProbeCommand(qemu, caps); virCommandAddArgList(cmd, "-device", "?", "-device", "pci-assign,?", @@ -1414,7 +1436,7 @@ qemuCapsExtractDeviceStr(const char *qemu, if (virCommandRun(cmd, NULL) < 0) goto cleanup; - ret = qemuCapsParseDeviceStr(output, flags); + ret = qemuCapsParseDeviceStr(output, caps); cleanup: VIR_FREE(output); @@ -1424,85 +1446,85 @@ cleanup: int -qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) +qemuCapsParseDeviceStr(const char *str, qemuCapsPtr caps) { /* Which devices exist. */ if (strstr(str, "name \"hda-duplex\"")) - qemuCapsSet(flags, QEMU_CAPS_HDA_DUPLEX); + qemuCapsSet(caps, QEMU_CAPS_HDA_DUPLEX); if (strstr(str, "name \"hda-micro\"")) - qemuCapsSet(flags, QEMU_CAPS_HDA_MICRO); + qemuCapsSet(caps, QEMU_CAPS_HDA_MICRO); if (strstr(str, "name \"ccid-card-emulated\"")) - qemuCapsSet(flags, QEMU_CAPS_CCID_EMULATED); + qemuCapsSet(caps, QEMU_CAPS_CCID_EMULATED); if (strstr(str, "name \"ccid-card-passthru\"")) - qemuCapsSet(flags, QEMU_CAPS_CCID_PASSTHRU); + qemuCapsSet(caps, QEMU_CAPS_CCID_PASSTHRU); if (strstr(str, "name \"piix3-usb-uhci\"")) - qemuCapsSet(flags, QEMU_CAPS_PIIX3_USB_UHCI); + qemuCapsSet(caps, QEMU_CAPS_PIIX3_USB_UHCI); if (strstr(str, "name \"piix4-usb-uhci\"")) - qemuCapsSet(flags, QEMU_CAPS_PIIX4_USB_UHCI); + qemuCapsSet(caps, QEMU_CAPS_PIIX4_USB_UHCI); if (strstr(str, "name \"usb-ehci\"")) - qemuCapsSet(flags, QEMU_CAPS_USB_EHCI); + qemuCapsSet(caps, QEMU_CAPS_USB_EHCI); if (strstr(str, "name \"ich9-usb-ehci1\"")) - qemuCapsSet(flags, QEMU_CAPS_ICH9_USB_EHCI1); + qemuCapsSet(caps, QEMU_CAPS_ICH9_USB_EHCI1); if (strstr(str, "name \"vt82c686b-usb-uhci\"")) - qemuCapsSet(flags, QEMU_CAPS_VT82C686B_USB_UHCI); + qemuCapsSet(caps, QEMU_CAPS_VT82C686B_USB_UHCI); if (strstr(str, "name \"pci-ohci\"")) - qemuCapsSet(flags, QEMU_CAPS_PCI_OHCI); + qemuCapsSet(caps, QEMU_CAPS_PCI_OHCI); if (strstr(str, "name \"nec-usb-xhci\"")) - qemuCapsSet(flags, QEMU_CAPS_NEC_USB_XHCI); + qemuCapsSet(caps, QEMU_CAPS_NEC_USB_XHCI); if (strstr(str, "name \"usb-redir\"")) - qemuCapsSet(flags, QEMU_CAPS_USB_REDIR); + qemuCapsSet(caps, QEMU_CAPS_USB_REDIR); if (strstr(str, "name \"usb-hub\"")) - qemuCapsSet(flags, QEMU_CAPS_USB_HUB); + qemuCapsSet(caps, QEMU_CAPS_USB_HUB); if (strstr(str, "name \"ich9-ahci\"")) - qemuCapsSet(flags, QEMU_CAPS_ICH9_AHCI); + qemuCapsSet(caps, QEMU_CAPS_ICH9_AHCI); if (strstr(str, "name \"virtio-blk-s390\"") || strstr(str, "name \"virtio-net-s390\"") || strstr(str, "name \"virtio-serial-s390\"")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_S390); if (strstr(str, "name \"lsi53c895a\"")) - qemuCapsSet(flags, QEMU_CAPS_SCSI_LSI); + qemuCapsSet(caps, QEMU_CAPS_SCSI_LSI); if (strstr(str, "name \"virtio-scsi-pci\"")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_SCSI_PCI); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_SCSI_PCI); /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */ - if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) && + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV_SPICEVMC) && strstr(str, "name \"spicevmc\"")) - qemuCapsSet(flags, QEMU_CAPS_DEVICE_SPICEVMC); + qemuCapsSet(caps, QEMU_CAPS_DEVICE_SPICEVMC); /* Features of given devices. */ if (strstr(str, "pci-assign.configfd")) - qemuCapsSet(flags, QEMU_CAPS_PCI_CONFIGFD); + qemuCapsSet(caps, QEMU_CAPS_PCI_CONFIGFD); if (strstr(str, "virtio-blk-pci.multifunction")) - qemuCapsSet(flags, QEMU_CAPS_PCI_MULTIFUNCTION); + qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIFUNCTION); if (strstr(str, "virtio-blk-pci.bootindex")) { - qemuCapsSet(flags, QEMU_CAPS_BOOTINDEX); + qemuCapsSet(caps, QEMU_CAPS_BOOTINDEX); if (strstr(str, "pci-assign.bootindex")) - qemuCapsSet(flags, QEMU_CAPS_PCI_BOOTINDEX); + qemuCapsSet(caps, QEMU_CAPS_PCI_BOOTINDEX); } if (strstr(str, "virtio-net-pci.tx=")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_TX_ALG); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_TX_ALG); if (strstr(str, "name \"qxl-vga\"")) - qemuCapsSet(flags, QEMU_CAPS_DEVICE_QXL_VGA); + qemuCapsSet(caps, QEMU_CAPS_DEVICE_QXL_VGA); if (strstr(str, "virtio-blk-pci.ioeventfd")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_IOEVENTFD); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_IOEVENTFD); if (strstr(str, "name \"sga\"")) - qemuCapsSet(flags, QEMU_CAPS_SGA); + qemuCapsSet(caps, QEMU_CAPS_SGA); if (strstr(str, "virtio-blk-pci.event_idx")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX); if (strstr(str, "virtio-net-pci.event_idx")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_NET_EVENT_IDX); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX); if (strstr(str, "virtio-blk-pci.scsi")) - qemuCapsSet(flags, QEMU_CAPS_VIRTIO_BLK_SCSI); + qemuCapsSet(caps, QEMU_CAPS_VIRTIO_BLK_SCSI); if (strstr(str, "scsi-disk.channel")) - qemuCapsSet(flags, QEMU_CAPS_SCSI_DISK_CHANNEL); + qemuCapsSet(caps, QEMU_CAPS_SCSI_DISK_CHANNEL); if (strstr(str, "scsi-block")) - qemuCapsSet(flags, QEMU_CAPS_SCSI_BLOCK); + qemuCapsSet(caps, QEMU_CAPS_SCSI_BLOCK); if (strstr(str, "scsi-cd")) - qemuCapsSet(flags, QEMU_CAPS_SCSI_CD); + qemuCapsSet(caps, QEMU_CAPS_SCSI_CD); if (strstr(str, "ide-cd")) - qemuCapsSet(flags, QEMU_CAPS_IDE_CD); + qemuCapsSet(caps, QEMU_CAPS_IDE_CD); /* * the iolimit detection is not really straight forward: * in qemu this is a capability of the block layer, if @@ -1512,11 +1534,11 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) */ if (strstr(str, ".logical_block_size") && strstr(str, ".physical_block_size")) - qemuCapsSet(flags, QEMU_CAPS_BLOCKIO); + qemuCapsSet(caps, QEMU_CAPS_BLOCKIO); if (strstr(str, "PIIX4_PM.disable_s3=")) - qemuCapsSet(flags, QEMU_CAPS_DISABLE_S3); + qemuCapsSet(caps, QEMU_CAPS_DISABLE_S3); if (strstr(str, "PIIX4_PM.disable_s4=")) - qemuCapsSet(flags, QEMU_CAPS_DISABLE_S4); + qemuCapsSet(caps, QEMU_CAPS_DISABLE_S4); return 0; } @@ -1525,16 +1547,16 @@ int qemuCapsExtractVersionInfo(const char *qemu, const char *arch, bool check_yajl, unsigned int *retversion, - virBitmapPtr *retflags) + qemuCapsPtr *retcaps) { int ret = -1; unsigned int version, is_kvm, kvm_version; - virBitmapPtr flags = NULL; + qemuCapsPtr caps = NULL; char *help = NULL; virCommandPtr cmd; - if (retflags) - *retflags = NULL; + if (retcaps) + *retcaps = NULL; if (retversion) *retversion = 0; @@ -1554,8 +1576,8 @@ int qemuCapsExtractVersionInfo(const char *qemu, if (virCommandRun(cmd, NULL) < 0) goto cleanup; - if (!(flags = qemuCapsNew()) || - qemuCapsParseHelpStr(qemu, help, flags, + if (!(caps = qemuCapsNew()) || + qemuCapsParseHelpStr(qemu, help, caps, &version, &is_kvm, &kvm_version, check_yajl) == -1) goto cleanup; @@ -1563,26 +1585,26 @@ int qemuCapsExtractVersionInfo(const char *qemu, /* Currently only x86_64 and i686 support PCI-multibus. */ if (STREQLEN(arch, "x86_64", 6) || STREQLEN(arch, "i686", 4)) { - qemuCapsSet(flags, QEMU_CAPS_PCI_MULTIBUS); + qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS); } /* S390 and probably other archs do not support no-acpi - maybe the qemu option parsing should be re-thought. */ if (STRPREFIX(arch, "s390")) - qemuCapsClear(flags, QEMU_CAPS_NO_ACPI); + qemuCapsClear(caps, QEMU_CAPS_NO_ACPI); - /* qemuCapsExtractDeviceStr will only set additional flags if qemu + /* qemuCapsExtractDeviceStr will only set additional caps if qemu * understands the 0.13.0+ notion of "-device driver,". */ - if (qemuCapsGet(flags, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE) && strstr(help, "-device driver,?") && - qemuCapsExtractDeviceStr(qemu, flags) < 0) + qemuCapsExtractDeviceStr(qemu, caps) < 0) goto cleanup; if (retversion) *retversion = version; - if (retflags) { - *retflags = flags; - flags = NULL; + if (retcaps) { + *retcaps = caps; + caps = NULL; } ret = 0; @@ -1590,7 +1612,7 @@ int qemuCapsExtractVersionInfo(const char *qemu, cleanup: VIR_FREE(help); virCommandFree(cmd); - qemuCapsFree(flags); + virObjectUnref(caps); return ret; } @@ -1644,54 +1666,80 @@ int qemuCapsExtractVersion(virCapsPtr caps, } -virBitmapPtr + + +qemuCapsPtr qemuCapsNew(void) { - virBitmapPtr caps; + qemuCapsPtr caps; - if (!(caps = virBitmapAlloc(QEMU_CAPS_LAST))) - virReportOOMError(); + if (qemuCapsInitialize() < 0) + return NULL; + + if (!(caps = virObjectNew(qemuCapsClass))) + return NULL; + + if (!(caps->flags = virBitmapAlloc(QEMU_CAPS_LAST))) + goto no_memory; return caps; + +no_memory: + virReportOOMError(); + virObjectUnref(caps); + return NULL; } +void qemuCapsDispose(void *obj) +{ + qemuCapsPtr caps = obj; + + virBitmapFree(caps->flags); +} + void -qemuCapsSet(virBitmapPtr caps, +qemuCapsSet(qemuCapsPtr caps, enum qemuCapsFlags flag) { - ignore_value(virBitmapSetBit(caps, flag)); + ignore_value(virBitmapSetBit(caps->flags, flag)); } void -qemuCapsSetList(virBitmapPtr caps, ...) +qemuCapsSetList(qemuCapsPtr caps, ...) { va_list list; int flag; va_start(list, caps); while ((flag = va_arg(list, int)) < QEMU_CAPS_LAST) - ignore_value(virBitmapSetBit(caps, flag)); + ignore_value(virBitmapSetBit(caps->flags, flag)); va_end(list); } void -qemuCapsClear(virBitmapPtr caps, +qemuCapsClear(qemuCapsPtr caps, enum qemuCapsFlags flag) { - ignore_value(virBitmapClearBit(caps, flag)); + ignore_value(virBitmapClearBit(caps->flags, flag)); +} + + +char *qemuCapsFlagsString(qemuCapsPtr caps) +{ + return virBitmapString(caps->flags); } bool -qemuCapsGet(virBitmapPtr caps, +qemuCapsGet(qemuCapsPtr caps, enum qemuCapsFlags flag) { bool b; - if (!caps || virBitmapGetBit(caps, flag, &b) < 0) + if (!caps || virBitmapGetBit(caps->flags, flag, &b) < 0) return false; else return b; @@ -1700,14 +1748,14 @@ qemuCapsGet(virBitmapPtr caps, virCommandPtr qemuCapsProbeCommand(const char *qemu, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virCommandPtr cmd = virCommandNew(qemu); - if (qemuCaps) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG)) + if (caps) { + if (qemuCapsGet(caps, QEMU_CAPS_NO_USER_CONFIG)) virCommandAddArg(cmd, "-no-user-config"); - else if (qemuCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG)) + else if (qemuCapsGet(caps, QEMU_CAPS_NODEFCONFIG)) virCommandAddArg(cmd, "-nodefconfig"); } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 49d64e5..1e817c6 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -24,7 +24,7 @@ #ifndef __QEMU_CAPABILITIES_H__ # define __QEMU_CAPABILITIES_H__ -# include "bitmap.h" +# include "virobject.h" # include "capabilities.h" # include "command.h" @@ -145,30 +145,33 @@ enum qemuCapsFlags { QEMU_CAPS_LAST, /* this must always be the last item */ }; -virBitmapPtr qemuCapsNew(void); +typedef struct _qemuCaps qemuCaps; +typedef qemuCaps *qemuCapsPtr; -# define qemuCapsFree(caps) virBitmapFree(caps) +qemuCapsPtr qemuCapsNew(void); -void qemuCapsSet(virBitmapPtr caps, +void qemuCapsSet(qemuCapsPtr caps, enum qemuCapsFlags flag) ATTRIBUTE_NONNULL(1); -void qemuCapsSetList(virBitmapPtr caps, ...) ATTRIBUTE_NONNULL(1); +void qemuCapsSetList(qemuCapsPtr caps, ...) ATTRIBUTE_NONNULL(1); -void qemuCapsClear(virBitmapPtr caps, +void qemuCapsClear(qemuCapsPtr caps, enum qemuCapsFlags flag) ATTRIBUTE_NONNULL(1); -bool qemuCapsGet(virBitmapPtr caps, +bool qemuCapsGet(qemuCapsPtr caps, enum qemuCapsFlags flag); +char *qemuCapsFlagsString(qemuCapsPtr caps); + virCapsPtr qemuCapsInit(virCapsPtr old_caps); int qemuCapsProbeMachineTypes(const char *binary, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virCapsGuestMachinePtr **machines, int *nmachines); int qemuCapsProbeCPUModels(const char *qemu, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, const char *arch, unsigned int *count, const char ***cpus); @@ -179,20 +182,20 @@ int qemuCapsExtractVersionInfo(const char *qemu, const char *arch, bool check_yajl, unsigned int *version, - virBitmapPtr *qemuCaps); + qemuCapsPtr *retcaps); int qemuCapsParseHelpStr(const char *qemu, const char *str, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, unsigned int *version, unsigned int *is_kvm, unsigned int *kvm_version, bool check_yajl); int qemuCapsParseDeviceStr(const char *str, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); virCommandPtr qemuCapsProbeCommand(const char *qemu, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); VIR_ENUM_DECL(qemuCaps); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a83d6de..5b4aeda 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -149,14 +149,14 @@ int qemuPhysIfaceConnect(virDomainDefPtr def, struct qemud_driver *driver, virDomainNetDefPtr net, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, enum virNetDevVPortProfileOp vmop) { int rc; char *res_ifname = NULL; int vnet_hdr = 0; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR) && + if (qemuCapsGet(caps, QEMU_CAPS_VNET_HDR) && net->model && STREQ(net->model, "virtio")) vnet_hdr = 1; @@ -184,7 +184,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { char *brname = NULL; int err; @@ -250,7 +250,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, template_ifname = true; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR) && + if (qemuCapsGet(caps, QEMU_CAPS_VNET_HDR) && net->model && STREQ(net->model, "virtio")) { tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR; } @@ -302,7 +302,7 @@ cleanup: int qemuOpenVhostNet(virDomainDefPtr def, virDomainNetDefPtr net, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, int *vhostfd) { *vhostfd = -1; /* assume we won't use vhost */ @@ -315,9 +315,9 @@ qemuOpenVhostNet(virDomainDefPtr def, /* If qemu doesn't support vhost-net mode (including the -netdev command * option), don't try to open the device. */ - if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) && - qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) { + if (!(qemuCapsGet(caps, QEMU_CAPS_VHOST_NET) && + qemuCapsGet(caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE))) { if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("vhost-net is not supported with " @@ -400,11 +400,11 @@ static int qemuAssignDeviceDiskAliasLegacy(virDomainDiskDefPtr disk) char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { char *ret; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (virAsprintf(&ret, "%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias) < 0) { virReportOOMError(); return NULL; @@ -474,13 +474,13 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk) static int qemuSetScsiControllerModel(virDomainDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, int *model) { if (*model > 0) { switch (*model) { case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SCSI_LSI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This QEMU doesn't support " "lsi scsi controller")); @@ -488,7 +488,7 @@ qemuSetScsiControllerModel(virDomainDefPtr def, } break; case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI_PCI)) { + if (!qemuCapsGet(caps, QEMU_CAPS_VIRTIO_SCSI_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This QEMU doesn't support " "virtio scsi controller")); @@ -508,7 +508,7 @@ qemuSetScsiControllerModel(virDomainDefPtr def, if (STREQ(def->os.arch, "ppc64") && STREQ(def->os.machine, "pseries")) { *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI; - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_SCSI_LSI)) { *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -524,7 +524,7 @@ qemuSetScsiControllerModel(virDomainDefPtr def, static int qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { const char *prefix = virDomainDiskBusTypeToString(disk->bus); int controllerModel = -1; @@ -535,7 +535,7 @@ qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, virDomainDiskFindControllerModel(def, disk, VIR_DOMAIN_CONTROLLER_TYPE_SCSI); - if ((qemuSetScsiControllerModel(def, qemuCaps, &controllerModel)) < 0) + if ((qemuSetScsiControllerModel(def, caps, &controllerModel)) < 0) return -1; } @@ -571,11 +571,11 @@ no_memory: int qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef, virDomainDiskDefPtr def, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) - return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps); + if (qemuCapsGet(caps, QEMU_CAPS_DRIVE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) + return qemuAssignDeviceDiskAliasCustom(vmdef, def, caps); else return qemuAssignDeviceDiskAliasFixed(def); } else { @@ -686,16 +686,16 @@ qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller) int -qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps) +qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps) { int i; for (i = 0; i < def->ndisks ; i++) { - if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(def, def->disks[i], caps) < 0) return -1; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NET_NAME) || - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_NET_NAME) || + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { for (i = 0; i < def->nnets ; i++) { /* type='hostdev' interfaces are also on the hostdevs list, * and will have their alias assigned with other hostdevs. @@ -707,7 +707,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps) } } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) return 0; for (i = 0; i < def->nfss ; i++) { @@ -811,21 +811,21 @@ qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, } static int -qemuDomainAssignS390Addresses(virDomainDefPtr def, virBitmapPtr qemuCaps) +qemuDomainAssignS390Addresses(virDomainDefPtr def, qemuCapsPtr caps) { int ret = -1; - virBitmapPtr localCaps = NULL; + qemuCapsPtr localCaps = NULL; - if (!qemuCaps) { + if (!caps) { /* need to get information from real environment */ if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, false, NULL, &localCaps) < 0) goto cleanup; - qemuCaps = localCaps; + caps = localCaps; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) { + if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390)) { /* deal with legacy virtio-s390 */ qemuDomainPrimeS390VirtioDevices( def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390); @@ -834,7 +834,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def, virBitmapPtr qemuCaps) ret = 0; cleanup: - qemuCapsFree(localCaps); + virObjectUnref(localCaps); return ret; } @@ -893,21 +893,21 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, } int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { int i, rc = -1; int model; - virBitmapPtr localCaps = NULL; + qemuCapsPtr localCaps = NULL; /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */ - if (!qemuCaps) { + if (!caps) { /* need to get information from real environment */ if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, false, NULL, &localCaps) < 0) goto cleanup; - qemuCaps = localCaps; + caps = localCaps; } for (i = 0 ; i < def->nnets; i++) { @@ -923,7 +923,7 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, for (i = 0 ; i < def->ncontrollers; i++) { model = def->controllers[i]->model; if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { - rc = qemuSetScsiControllerModel(def, qemuCaps, &model); + rc = qemuSetScsiControllerModel(def, caps, &model); if (rc) goto cleanup; } @@ -954,7 +954,7 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, rc = 0; cleanup: - qemuCapsFree(localCaps); + virObjectUnref(localCaps); return rc; } @@ -1065,25 +1065,25 @@ cleanup: int qemuDomainAssignPCIAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virDomainObjPtr obj) { int ret = -1; - virBitmapPtr localCaps = NULL; + qemuCapsPtr localCaps = NULL; qemuDomainPCIAddressSetPtr addrs = NULL; qemuDomainObjPrivatePtr priv = NULL; - if (!qemuCaps) { + if (!caps) { /* need to get information from real environment */ if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, false, NULL, &localCaps) < 0) goto cleanup; - qemuCaps = localCaps; + caps = localCaps; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (!(addrs = qemuDomainPCIAddressSetCreate(def))) goto cleanup; @@ -1107,27 +1107,27 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, ret = 0; cleanup: - qemuCapsFree(localCaps); + virObjectUnref(localCaps); qemuDomainPCIAddressSetFree(addrs); return ret; } int qemuDomainAssignAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virDomainObjPtr obj) { int rc; - rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps); + rc = qemuDomainAssignSpaprVIOAddresses(def, caps); if (rc) return rc; - rc = qemuDomainAssignS390Addresses(def, qemuCaps); + rc = qemuDomainAssignS390Addresses(def, caps); if (rc) return rc; - return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); + return qemuDomainAssignPCIAddresses(def, caps, obj); } static void @@ -1756,7 +1756,7 @@ qemuUsbId(virBufferPtr buf, int idx) static int qemuBuildDeviceAddressStr(virBufferPtr buf, virDomainDeviceInfoPtr info, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { if (info->addr.pci.domain != 0) { @@ -1769,7 +1769,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, _("Only PCI device addresses with bus=0 are supported")); return -1; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) { + if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIFUNCTION)) { if (info->addr.pci.function > 7) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("The function of PCI device addresses must " @@ -1797,7 +1797,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, * When QEMU grows support for > 1 PCI domain, then pci.0 change * to pciNN.0 where NN is the domain number */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS)) + if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) virBufferAsprintf(buf, ",bus=pci.0"); else virBufferAsprintf(buf, ",bus=pci"); @@ -1823,7 +1823,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, static int qemuBuildRomStr(virBufferPtr buf, virDomainDeviceInfoPtr info, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { if (info->rombar || info->romfile) { if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { @@ -1831,7 +1831,7 @@ qemuBuildRomStr(virBufferPtr buf, "%s", _("rombar and romfile are supported only for PCI devices")); return -1; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) { + if (!qemuCapsGet(caps, QEMU_CAPS_PCI_ROMBAR)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("rombar and romfile not supported in this QEMU binary")); return -1; @@ -1856,9 +1856,9 @@ qemuBuildRomStr(virBufferPtr buf, static int qemuBuildIoEventFdStr(virBufferPtr buf, enum virDomainIoEventFd use, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { - if (use && qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD)) + if (use && qemuCapsGet(caps, QEMU_CAPS_VIRTIO_IOEVENTFD)) virBufferAsprintf(buf, ",ioeventfd=%s", virDomainIoEventFdTypeToString(use)); return 0; @@ -2073,7 +2073,7 @@ char * qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk, bool bootable, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer opt = VIR_BUFFER_INITIALIZER; const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); @@ -2152,7 +2152,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, break; case VIR_DOMAIN_DISK_BUS_VIRTIO: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && + if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390) && (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)) { /* Paranoia - leave in here for now */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -2233,24 +2233,24 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, virBufferEscape(&opt, ',', ",", "file=%s,", disk->src); } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) virBufferAddLit(&opt, "if=none"); else virBufferAsprintf(&opt, "if=%s", bus); if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { if ((disk->bus == VIR_DOMAIN_DISK_BUS_SCSI)) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) + if (!qemuCapsGet(caps, QEMU_CAPS_SCSI_CD)) virBufferAddLit(&opt, ",media=cdrom"); } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) + if (!qemuCapsGet(caps, QEMU_CAPS_IDE_CD)) virBufferAddLit(&opt, ",media=cdrom"); } else { virBufferAddLit(&opt, ",media=cdrom"); } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virBufferAsprintf(&opt, ",id=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias); } else { if (busid == -1 && unitid == -1) { @@ -2264,13 +2264,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } } if (bootable && - qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) && + qemuCapsGet(caps, QEMU_CAPS_DRIVE_BOOT) && (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK || disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) && disk->bus != VIR_DOMAIN_DISK_BUS_IDE) virBufferAddLit(&opt, ",boot=on"); if (disk->readonly && - qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) + qemuCapsGet(caps, QEMU_CAPS_DRIVE_READONLY)) virBufferAddLit(&opt, ",readonly=on"); if (disk->transient) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -2279,7 +2279,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } if (disk->driverType && *disk->driverType != '\0' && disk->type != VIR_DOMAIN_DISK_TYPE_DIR && - qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) + qemuCapsGet(caps, QEMU_CAPS_DRIVE_FORMAT)) virBufferAsprintf(&opt, ",format=%s", disk->driverType); /* generate geometry command string */ @@ -2297,7 +2297,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } if (disk->serial && - qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL)) { + qemuCapsGet(caps, QEMU_CAPS_DRIVE_SERIAL)) { if (qemuSafeSerialParamValue(disk->serial) < 0) goto error; virBufferAsprintf(&opt, ",serial=%s", disk->serial); @@ -2306,17 +2306,17 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, if (disk->cachemode) { const char *mode = NULL; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2)) { + if (qemuCapsGet(caps, QEMU_CAPS_DRIVE_CACHE_V2)) { mode = qemuDiskCacheV2TypeToString(disk->cachemode); if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC && - !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) { + !qemuCapsGet(caps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("disk cache mode 'directsync' is not " "supported by this QEMU")); goto error; } else if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_UNSAFE && - !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) { + !qemuCapsGet(caps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("disk cache mode 'unsafe' is not " "supported by this QEMU")); @@ -2332,7 +2332,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } if (disk->copy_on_read) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) { + if (qemuCapsGet(caps, QEMU_CAPS_DRIVE_COPY_ON_READ)) { virBufferAsprintf(&opt, ",copy-on-read=%s", virDomainDiskCopyOnReadTypeToString(disk->copy_on_read)); } else { @@ -2342,7 +2342,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) { + if (qemuCapsGet(caps, QEMU_CAPS_MONITOR_JSON)) { const char *wpolicy = NULL, *rpolicy = NULL; if (disk->error_policy) @@ -2368,7 +2368,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } if (disk->iomode) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_AIO)) { + if (qemuCapsGet(caps, QEMU_CAPS_DRIVE_AIO)) { virBufferAsprintf(&opt, ",aio=%s", virDomainDiskIoTypeToString(disk->iomode)); } else { @@ -2386,7 +2386,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, disk->blkdeviotune.total_iops_sec || disk->blkdeviotune.read_iops_sec || disk->blkdeviotune.write_iops_sec) && - !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) { + !qemuCapsGet(caps, QEMU_CAPS_DRIVE_IOTUNE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("block I/O throttling not supported with this " "QEMU binary")); @@ -2439,7 +2439,7 @@ char * qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskDefPtr disk, int bootindex, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer opt = VIR_BUFFER_INITIALIZER; const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); @@ -2469,7 +2469,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskTypeToString(disk->type)); goto error; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) { + if (!qemuCapsGet(caps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("disk device='lun' is not supported by this QEMU")); goto error; @@ -2484,7 +2484,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) { + if (qemuCapsGet(caps, QEMU_CAPS_IDE_CD)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, "ide-cd"); else @@ -2499,7 +2499,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, break; case VIR_DOMAIN_DISK_BUS_SCSI: if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SCSI_BLOCK)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This QEMU doesn't support scsi-block for " "lun passthrough")); @@ -2510,7 +2510,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, controllerModel = virDomainDiskFindControllerModel(def, disk, VIR_DOMAIN_CONTROLLER_TYPE_SCSI); - if ((qemuSetScsiControllerModel(def, qemuCaps, &controllerModel)) < 0) + if ((qemuSetScsiControllerModel(def, caps, &controllerModel)) < 0) goto error; if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { @@ -2524,7 +2524,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { virBufferAddLit(&opt, "scsi-block"); } else { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { + if (qemuCapsGet(caps, QEMU_CAPS_SCSI_CD)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, "scsi-cd"); else @@ -2539,7 +2539,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, disk->info.addr.drive.bus, disk->info.addr.drive.unit); } else { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { if (disk->info.addr.drive.target > 7) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This QEMU doesn't support target " @@ -2557,7 +2557,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, } if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { + if (qemuCapsGet(caps, QEMU_CAPS_SCSI_CD)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, "scsi-cd"); else @@ -2588,7 +2588,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) { + if (qemuCapsGet(caps, QEMU_CAPS_IDE_CD)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, "ide-cd"); else @@ -2608,13 +2608,13 @@ qemuBuildDriveDevStr(virDomainDefPtr def, } else { virBufferAddLit(&opt, "virtio-blk-pci"); } - qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps); + qemuBuildIoEventFdStr(&opt, disk->ioeventfd, caps); if (disk->event_idx && - qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) { + qemuCapsGet(caps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) { virBufferAsprintf(&opt, ",event_idx=%s", virDomainVirtioEventIdxTypeToString(disk->event_idx)); } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) { + if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_BLK_SCSI)) { /* if sg_io is true but the scsi option isn't supported, * that means it's just always on in this version of qemu. */ @@ -2622,7 +2622,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) ? "on" : "off"); } - if (qemuBuildDeviceAddressStr(&opt, &disk->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&opt, &disk->info, caps) < 0) goto error; break; case VIR_DOMAIN_DISK_BUS_USB: @@ -2635,9 +2635,9 @@ qemuBuildDriveDevStr(virDomainDefPtr def, } virBufferAsprintf(&opt, ",drive=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias); virBufferAsprintf(&opt, ",id=%s", disk->info.alias); - if (bootindex && qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) + if (bootindex && qemuCapsGet(caps, QEMU_CAPS_BOOTINDEX)) virBufferAsprintf(&opt, ",bootindex=%d", bootindex); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) { + if (qemuCapsGet(caps, QEMU_CAPS_BLOCKIO)) { if (disk->blockio.logical_block_size > 0) virBufferAsprintf(&opt, ",logical_block_size=%u", disk->blockio.logical_block_size); @@ -2660,7 +2660,7 @@ error: char *qemuBuildFSStr(virDomainFSDefPtr fs, - virBitmapPtr qemuCaps ATTRIBUTE_UNUSED) + qemuCapsPtr caps ATTRIBUTE_UNUSED) { virBuffer opt = VIR_BUFFER_INITIALIZER; const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver); @@ -2699,7 +2699,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, } if (fs->wrpolicy) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT)) { + if (qemuCapsGet(caps, QEMU_CAPS_FSDEV_WRITEOUT)) { virBufferAsprintf(&opt, ",writeout=%s", wrpolicy); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -2712,7 +2712,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, virBufferAsprintf(&opt, ",path=%s", fs->src); if (fs->readonly) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) { + if (qemuCapsGet(caps, QEMU_CAPS_FSDEV_READONLY)) { virBufferAddLit(&opt, ",readonly"); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -2737,7 +2737,7 @@ error: char * qemuBuildFSDevStr(virDomainFSDefPtr fs, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer opt = VIR_BUFFER_INITIALIZER; @@ -2752,7 +2752,7 @@ qemuBuildFSDevStr(virDomainFSDefPtr fs, virBufferAsprintf(&opt, ",fsdev=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); virBufferAsprintf(&opt, ",mount_tag=%s", fs->dst); - if (qemuBuildDeviceAddressStr(&opt, &fs->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&opt, &fs->info, caps) < 0) goto error; if (virBufferError(&opt)) { @@ -2798,11 +2798,11 @@ qemuControllerModelUSBToCaps(int model) static int qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef, virDomainControllerDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virBuffer *buf) { const char *smodel; - int model, caps; + int model, flags; model = def->model; @@ -2814,9 +2814,9 @@ qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef, } smodel = qemuControllerModelUSBTypeToString(model); - caps = qemuControllerModelUSBToCaps(model); + flags = qemuControllerModelUSBToCaps(model); - if (caps == -1 || !qemuCapsGet(qemuCaps, caps)) { + if (flags == -1 || !qemuCapsGet(caps, flags)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("%s not supported in this QEMU binary"), smodel); return -1; @@ -2839,7 +2839,7 @@ qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef, char * qemuBuildControllerDevStr(virDomainDefPtr domainDef, virDomainControllerDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, int *nusbcontroller) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -2848,7 +2848,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, switch (def->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: model = def->model; - if ((qemuSetScsiControllerModel(domainDef, qemuCaps, &model)) < 0) + if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0) return NULL; switch (model) { @@ -2899,7 +2899,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, break; case VIR_DOMAIN_CONTROLLER_TYPE_USB: - if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1) + if (qemuBuildUSBControllerDevStr(domainDef, def, caps, &buf) == -1) goto error; if (nusbcontroller) @@ -2916,7 +2916,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, goto error; } - if (qemuBuildDeviceAddressStr(&buf, &def->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -2961,7 +2961,7 @@ char * qemuBuildNicDevStr(virDomainNetDefPtr net, int vlan, int bootindex, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *nic; @@ -2983,7 +2983,7 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, virBufferAdd(&buf, nic, strlen(nic)); if (usingVirtio && net->driver.virtio.txmode) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) { + if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_TX_ALG)) { virBufferAddLit(&buf, ",tx="); switch (net->driver.virtio.txmode) { case VIR_DOMAIN_NET_VIRTIO_TX_MODE_IOTHREAD: @@ -3008,9 +3008,9 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, } } if (usingVirtio) { - qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps); + qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, caps); if (net->driver.virtio.event_idx && - qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) { + qemuCapsGet(caps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) { virBufferAsprintf(&buf, ",event_idx=%s", virDomainVirtioEventIdxTypeToString(net->driver.virtio.event_idx)); } @@ -3024,11 +3024,11 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, net->mac.addr[0], net->mac.addr[1], net->mac.addr[2], net->mac.addr[3], net->mac.addr[4], net->mac.addr[5]); - if (qemuBuildDeviceAddressStr(&buf, &net->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &net->info, caps) < 0) goto error; - if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0) + if (qemuBuildRomStr(&buf, &net->info, caps) < 0) goto error; - if (bootindex && qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) + if (bootindex && qemuCapsGet(caps, QEMU_CAPS_BOOTINDEX)) virBufferAsprintf(&buf, ",bootindex=%d", bootindex); if (virBufferError(&buf)) { @@ -3047,7 +3047,7 @@ error: char * qemuBuildHostNetStr(virDomainNetDefPtr net, struct qemud_driver *driver, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, char type_sep, int vlan, const char *tapfd, @@ -3073,7 +3073,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, */ case VIR_DOMAIN_NET_TYPE_BRIDGE: if (!driver->privileged && - qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE)) { + qemuCapsGet(caps, QEMU_CAPS_NETDEV_BRIDGE)) { brname = virDomainNetGetActualBridgeName(net); virBufferAsprintf(&buf, "bridge%cbr=%s", type_sep, brname); type_sep = ','; @@ -3160,7 +3160,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3172,7 +3172,7 @@ qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev, } virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3190,13 +3190,13 @@ error: char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; virBufferAddLit(&buf, "virtio-balloon-pci"); virBufferAsprintf(&buf, ",id=%s", dev->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3214,7 +3214,7 @@ error: char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3222,7 +3222,7 @@ qemuBuildUSBInputDevStr(virDomainInputDefPtr dev, dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "usb-mouse" : "usb-tablet", dev->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3240,7 +3240,7 @@ error: char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *model = virDomainSoundModelTypeToString(sound->model); @@ -3260,7 +3260,7 @@ qemuBuildSoundDevStr(virDomainSoundDefPtr sound, model = "intel-hda"; virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &sound->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &sound->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3293,17 +3293,17 @@ qemuSoundCodecTypeToCaps(int type) static char * qemuBuildSoundCodecStr(virDomainSoundDefPtr sound, virDomainSoundCodecDefPtr codec, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *stype; - int type, caps; + int type, flags; type = codec->type; stype = qemuSoundCodecTypeToString(type); - caps = qemuSoundCodecTypeToCaps(type); + flags = qemuSoundCodecTypeToCaps(type); - if (caps == -1 || !qemuCapsGet(qemuCaps, caps)) { + if (flags == -1 || !qemuCapsGet(caps, flags)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("%s not supported in this QEMU binary"), stype); goto error; @@ -3321,7 +3321,7 @@ error: static char * qemuBuildVideoDevStr(virDomainVideoDefPtr video, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *model = qemuVideoTypeToString(video->type); @@ -3346,7 +3346,7 @@ qemuBuildVideoDevStr(virDomainVideoDefPtr video, virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); } - if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &video->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3389,7 +3389,7 @@ qemuOpenPCIConfig(virDomainHostdevDefPtr dev) char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3403,9 +3403,9 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, virBufferAsprintf(&buf, ",configfd=%s", configfd); if (dev->info->bootIndex) virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex); - if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, dev->info, caps) < 0) goto error; - if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0) + if (qemuBuildRomStr(&buf, dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3438,7 +3438,7 @@ qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev) char * qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3449,7 +3449,7 @@ qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, goto error; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR)) { + if (!qemuCapsGet(caps, QEMU_CAPS_USB_REDIR)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("USB redirection is not supported " "by this version of QEMU")); @@ -3460,7 +3460,7 @@ qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, dev->info.alias, dev->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3477,7 +3477,7 @@ error: char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3493,7 +3493,7 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, dev->source.subsys.u.usb.device, dev->info->alias); - if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3511,7 +3511,7 @@ error: char * qemuBuildHubDevStr(virDomainHubDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -3522,7 +3522,7 @@ qemuBuildHubDevStr(virDomainHubDefPtr dev, goto error; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) { + if (!qemuCapsGet(caps, QEMU_CAPS_USB_HUB)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("usb-hub not supported by QEMU binary")); goto error; @@ -3530,7 +3530,7 @@ qemuBuildHubDevStr(virDomainHubDefPtr dev, virBufferAddLit(&buf, "usb-hub"); virBufferAsprintf(&buf, ",id=%s", dev->info.alias); - if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) goto error; if (virBufferError(&buf)) { @@ -3572,7 +3572,7 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev) * host side of the character device */ static char * qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; bool telnet; @@ -3651,7 +3651,7 @@ qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias, break; case VIR_DOMAIN_CHR_TYPE_SPICEVMC: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV_SPICEVMC)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("spicevmc not supported in this QEMU binary")); goto error; @@ -3772,7 +3772,7 @@ error: static char * qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; switch (dev->deviceType) { @@ -3782,7 +3782,7 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev, case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: /* Legacy syntax '-device spicevmc' */ if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC)) { + qemuCapsGet(caps, QEMU_CAPS_DEVICE_SPICEVMC)) { virBufferAddLit(&buf, "spicevmc"); } else { virBufferAddLit(&buf, "virtserialport"); @@ -3825,7 +3825,7 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev, if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) { + qemuCapsGet(caps, QEMU_CAPS_DEVICE_SPICEVMC))) { virBufferAsprintf(&buf, ",chardev=char%s,id=%s", dev->info.alias, dev->info.alias); if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) { @@ -4031,7 +4031,7 @@ static int qemuBuildCpuArgStr(const struct qemud_driver *driver, const virDomainDefPtr def, const char *emulator, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, const struct utsname *ut, char **opt, bool *hasHwVirt, @@ -4064,7 +4064,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, int hasSVM; if (host && - qemuCapsProbeCPUModels(emulator, qemuCaps, host->arch, + qemuCapsProbeCPUModels(emulator, caps, host->arch, &ncpus, &cpus) < 0) goto cleanup; @@ -4111,7 +4111,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) { const char *mode = virCPUModeTypeToString(cpu->mode); - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CPU_HOST)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("CPU mode '%s' is not supported by QEMU" " binary"), mode); @@ -4221,13 +4221,13 @@ no_memory: static char * qemuBuildSmpArgStr(const virDomainDefPtr def, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; virBufferAsprintf(&buf, "%u", def->vcpus); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_SMP_TOPOLOGY)) { + if (qemuCapsGet(caps, QEMU_CAPS_SMP_TOPOLOGY)) { if (def->vcpus != def->maxvcpus) virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus); /* sockets, cores, and threads are either all zero @@ -4335,7 +4335,7 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, bool monitor_json, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, const char *migrateFrom, int migrateFd, virDomainSnapshotObjPtr snapshot, @@ -4367,25 +4367,25 @@ qemuBuildCommandLine(virConnectPtr conn, * do not use boot=on for drives when not using KVM since this * is not supported at all in upstream QEmu. */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM) && + if (qemuCapsGet(caps, QEMU_CAPS_KVM) && (def->virtType == VIR_DOMAIN_VIRT_QEMU)) - qemuCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT); + qemuCapsClear(caps, QEMU_CAPS_DRIVE_BOOT); switch (def->virtType) { case VIR_DOMAIN_VIRT_QEMU: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) + if (qemuCapsGet(caps, QEMU_CAPS_KQEMU)) disableKQEMU = 1; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM)) + if (qemuCapsGet(caps, QEMU_CAPS_KVM)) disableKVM = 1; break; case VIR_DOMAIN_VIRT_KQEMU: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM)) + if (qemuCapsGet(caps, QEMU_CAPS_KVM)) disableKVM = 1; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KQEMU)) { + if (qemuCapsGet(caps, QEMU_CAPS_ENABLE_KQEMU)) { enableKQEMU = 1; - } else if (!qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) { + } else if (!qemuCapsGet(caps, QEMU_CAPS_KQEMU)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("the QEMU binary %s does not support kqemu"), emulator); @@ -4393,12 +4393,12 @@ qemuBuildCommandLine(virConnectPtr conn, break; case VIR_DOMAIN_VIRT_KVM: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) + if (qemuCapsGet(caps, QEMU_CAPS_KQEMU)) disableKQEMU = 1; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) { + if (qemuCapsGet(caps, QEMU_CAPS_ENABLE_KVM)) { enableKVM = 1; - } else if (!qemuCapsGet(qemuCaps, QEMU_CAPS_KVM)) { + } else if (!qemuCapsGet(caps, QEMU_CAPS_KVM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("the QEMU binary %s does not support kvm"), emulator); @@ -4420,10 +4420,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddEnvPassCommon(cmd); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NAME)) { + if (qemuCapsGet(caps, QEMU_CAPS_NAME)) { virCommandAddArg(cmd, "-name"); if (driver->setProcessName && - qemuCapsGet(qemuCaps, QEMU_CAPS_NAME_PROCESS)) { + qemuCapsGet(caps, QEMU_CAPS_NAME_PROCESS)) { virCommandAddArgFormat(cmd, "%s,process=qemu:%s", def->name, def->name); } else { @@ -4439,7 +4439,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (def->os.machine) virCommandAddArgList(cmd, "-M", def->os.machine, NULL); - if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps, + if (qemuBuildCpuArgStr(driver, def, emulator, caps, &ut, &cpu, &hasHwVirt, !!migrateFrom) < 0) goto error; @@ -4447,7 +4447,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgList(cmd, "-cpu", cpu, NULL); VIR_FREE(cpu); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NESTING) && + if (qemuCapsGet(caps, QEMU_CAPS_NESTING) && hasHwVirt) virCommandAddArg(cmd, "-enable-nesting"); } @@ -4485,7 +4485,7 @@ qemuBuildCommandLine(virConnectPtr conn, "%s", _("hugepages are disabled by administrator config")); goto error; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { + if (!qemuCapsGet(caps, QEMU_CAPS_MEM_PATH)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("hugepage backing not supported by '%s'"), def->emulator); @@ -4496,7 +4496,7 @@ qemuBuildCommandLine(virConnectPtr conn, } virCommandAddArg(cmd, "-smp"); - if (!(smp = qemuBuildSmpArgStr(def, qemuCaps))) + if (!(smp = qemuBuildSmpArgStr(def, caps))) goto error; virCommandAddArg(cmd, smp); VIR_FREE(smp); @@ -4505,15 +4505,15 @@ qemuBuildCommandLine(virConnectPtr conn, if (qemuBuildNumaArgStr(def, cmd) < 0) goto error; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_UUID)) + if (qemuCapsGet(caps, QEMU_CAPS_UUID)) virCommandAddArgList(cmd, "-uuid", uuid, NULL); if (def->virtType == VIR_DOMAIN_VIRT_XEN || STREQ(def->os.type, "xen") || STREQ(def->os.type, "linux")) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DOMID)) { + if (qemuCapsGet(caps, QEMU_CAPS_DOMID)) { virCommandAddArg(cmd, "-domid"); virCommandAddArgFormat(cmd, "%d", def->id); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_XEN_DOMID)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_XEN_DOMID)) { virCommandAddArg(cmd, "-xen-attach"); virCommandAddArg(cmd, "-xen-domid"); virCommandAddArgFormat(cmd, "%d", def->id); @@ -4530,7 +4530,7 @@ qemuBuildCommandLine(virConnectPtr conn, virSysinfoDefPtr source = NULL; bool skip_uuid = false; - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SMBIOS_TYPE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("the QEMU binary %s does not support smbios settings"), emulator); @@ -4583,23 +4583,23 @@ qemuBuildCommandLine(virConnectPtr conn, if (!def->graphics) virCommandAddArg(cmd, "-nographic"); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { /* Disable global config files and default devices */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG)) + if (qemuCapsGet(caps, QEMU_CAPS_NO_USER_CONFIG)) virCommandAddArg(cmd, "-no-user-config"); - else if (qemuCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG)) + else if (qemuCapsGet(caps, QEMU_CAPS_NODEFCONFIG)) virCommandAddArg(cmd, "-nodefconfig"); virCommandAddArg(cmd, "-nodefaults"); } /* Serial graphics adapter */ if (def->os.bios.useserial == VIR_DOMAIN_BIOS_USESERIAL_YES) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("qemu does not support -device")); goto error; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SGA)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SGA)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("qemu does not support SGA")); goto error; @@ -4615,11 +4615,11 @@ qemuBuildCommandLine(virConnectPtr conn, if (monitor_chr) { char *chrdev; /* Use -chardev if it's available */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) { + if (qemuCapsGet(caps, QEMU_CAPS_CHARDEV)) { virCommandAddArg(cmd, "-chardev"); if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor", - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, chrdev); VIR_FREE(chrdev); @@ -4641,7 +4641,7 @@ qemuBuildCommandLine(virConnectPtr conn, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_RTC)) { + if (qemuCapsGet(caps, QEMU_CAPS_RTC)) { const char *rtcopt; virCommandAddArg(cmd, "-rtc"); if (!(rtcopt = qemuBuildClockArgStr(&def->clock))) @@ -4689,7 +4689,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* This has already been taken care of (in qemuBuildClockArgStr) if QEMU_CAPS_RTC is set (mutually exclusive with QEMUD_FLAG_RTC_TD_HACK) */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_RTC_TD_HACK)) { + if (qemuCapsGet(caps, QEMU_CAPS_RTC_TD_HACK)) { switch (def->clock.timers[i]->tickpolicy) { case -1: case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY: @@ -4705,7 +4705,7 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy)); goto error; } - } else if (!qemuCapsGet(qemuCaps, QEMU_CAPS_RTC) + } else if (!qemuCapsGet(caps, QEMU_CAPS_RTC) && (def->clock.timers[i]->tickpolicy != VIR_DOMAIN_TIMER_TICKPOLICY_DELAY) && (def->clock.timers[i]->tickpolicy != -1)) { @@ -4724,13 +4724,13 @@ qemuBuildCommandLine(virConnectPtr conn, case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY: /* delay is the default if we don't have kernel (-no-kvm-pit), otherwise, the default is catchup. */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) + if (qemuCapsGet(caps, QEMU_CAPS_NO_KVM_PIT)) virCommandAddArg(cmd, "-no-kvm-pit-reinjection"); break; case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) { + if (qemuCapsGet(caps, QEMU_CAPS_NO_KVM_PIT)) { /* do nothing - this is default for kvm-pit */ - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_TDF)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_TDF)) { /* -tdf switches to 'catchup' with userspace pit. */ virCommandAddArg(cmd, "-tdf"); } else { @@ -4759,7 +4759,7 @@ qemuBuildCommandLine(virConnectPtr conn, * and when -no-hpet doesn't exist is "no". "confusing"? * "yes"! */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) { + if (qemuCapsGet(caps, QEMU_CAPS_NO_HPET)) { if (def->clock.timers[i]->present == 0) virCommandAddArg(cmd, "-no-hpet"); } else { @@ -4774,7 +4774,7 @@ qemuBuildCommandLine(virConnectPtr conn, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_REBOOT) && + if (qemuCapsGet(caps, QEMU_CAPS_NO_REBOOT) && def->onReboot != VIR_DOMAIN_LIFECYCLE_RESTART) virCommandAddArg(cmd, "-no-reboot"); @@ -4782,16 +4782,16 @@ qemuBuildCommandLine(virConnectPtr conn, * when QEMU stops. If we use no-shutdown, then we can * watch for this event and do a soft/warm reboot. */ - if (monitor_json && qemuCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) + if (monitor_json && qemuCapsGet(caps, QEMU_CAPS_NO_SHUTDOWN)) virCommandAddArg(cmd, "-no-shutdown"); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) { + if (qemuCapsGet(caps, QEMU_CAPS_NO_ACPI)) { if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI))) virCommandAddArg(cmd, "-no-acpi"); } if (def->pm.s3) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S3)) { + if (!qemuCapsGet(caps, QEMU_CAPS_DISABLE_S3)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("setting ACPI S3 not supported")); goto error; @@ -4802,7 +4802,7 @@ qemuBuildCommandLine(virConnectPtr conn, } if (def->pm.s4) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S4)) { + if (!qemuCapsGet(caps, QEMU_CAPS_DISABLE_S4)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("setting ACPI S4 not supported")); goto error; @@ -4822,15 +4822,15 @@ qemuBuildCommandLine(virConnectPtr conn, /* def->os.nBootDevs is guaranteed to be > 0 unless per-device boot * configuration is used */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) { + if (!qemuCapsGet(caps, QEMU_CAPS_BOOTINDEX)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("hypervisor lacks deviceboot feature")); goto error; } emitBootindex = true; - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) && + } else if (qemuCapsGet(caps, QEMU_CAPS_BOOTINDEX) && (def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_ENABLED || - !qemuCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) { + !qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU))) { emitBootindex = true; } @@ -4861,7 +4861,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-boot"); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU) && + if (qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU) && def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) { if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED) virBufferAsprintf(&boot_buf, "order=%s,menu=on", boot); @@ -4896,7 +4896,7 @@ qemuBuildCommandLine(virConnectPtr conn, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { for (i = 0 ; i < def->ncontrollers ; i++) { virDomainControllerDefPtr cont = def->controllers[i]; @@ -4916,7 +4916,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* Only recent QEMU implements a SATA (AHCI) controller */ if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) { + if (!qemuCapsGet(caps, QEMU_CAPS_ICH9_AHCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("SATA is not supported with this " "QEMU binary")); @@ -4926,7 +4926,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-device"); if (!(devstr = qemuBuildControllerDevStr(def, cont, - qemuCaps, NULL))) + caps, NULL))) goto error; virCommandAddArg(cmd, devstr); @@ -4934,7 +4934,7 @@ qemuBuildCommandLine(virConnectPtr conn, } } else if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && cont->model == -1 && - !qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) { + !qemuCapsGet(caps, QEMU_CAPS_PIIX3_USB_UHCI)) { if (usblegacy) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Multiple legacy USB controllers are " @@ -4946,7 +4946,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-device"); char *devstr; - if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps, + if (!(devstr = qemuBuildControllerDevStr(def, cont, caps, &usbcontroller))) goto error; @@ -4957,10 +4957,10 @@ qemuBuildCommandLine(virConnectPtr conn, } /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DRIVE)) { int bootCD = 0, bootFloppy = 0, bootDisk = 0; - if ((qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) { + if ((qemuCapsGet(caps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) { /* bootDevs will get translated into either bootindex=N or boot=on * depending on what qemu supports */ for (i = 0 ; i < def->os.nBootDevs ; i++) { @@ -4988,7 +4988,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* Unless we have -device, then USB disks need special handling */ if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) && - !qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + !qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { virCommandAddArg(cmd, "-usbdevice"); virCommandAddArgFormat(cmd, "disk:%s", disk->src); @@ -5024,19 +5024,19 @@ qemuBuildCommandLine(virConnectPtr conn, devices. Fortunately, those don't need static PCI addresses, so we don't really care that we can't use -device */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN) { withDeviceArg = 1; } else { - qemuCapsClear(qemuCaps, QEMU_CAPS_DEVICE); + qemuCapsClear(caps, QEMU_CAPS_DEVICE); deviceFlagMasked = true; } } optstr = qemuBuildDriveStr(conn, disk, emitBootindex ? false : !!bootindex, - qemuCaps); + caps); if (deviceFlagMasked) - qemuCapsSet(qemuCaps, QEMU_CAPS_DEVICE); + qemuCapsSet(caps, QEMU_CAPS_DEVICE); if (!optstr) goto error; virCommandAddArg(cmd, optstr); @@ -5066,7 +5066,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-device"); if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); @@ -5198,19 +5198,19 @@ qemuBuildCommandLine(virConnectPtr conn, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) { + if (qemuCapsGet(caps, QEMU_CAPS_FSDEV)) { for (i = 0 ; i < def->nfss ; i++) { char *optstr; virDomainFSDefPtr fs = def->fss[i]; virCommandAddArg(cmd, "-fsdev"); - if (!(optstr = qemuBuildFSStr(fs, qemuCaps))) + if (!(optstr = qemuBuildFSStr(fs, caps))) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); virCommandAddArg(cmd, "-device"); - if (!(optstr = qemuBuildFSDevStr(fs, qemuCaps))) + if (!(optstr = qemuBuildFSDevStr(fs, caps))) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); @@ -5225,7 +5225,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (!def->nnets) { /* If we have -device, then we set -nodefault already */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) virCommandAddArgList(cmd, "-net", "none", NULL); } else { int bootNet = 0; @@ -5256,8 +5256,8 @@ qemuBuildCommandLine(virConnectPtr conn, bootindex = net->info.bootIndex; /* VLANs are not used with -netdev, so don't record them */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (qemuCapsGet(caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) vlan = -1; else vlan = i; @@ -5318,9 +5318,9 @@ qemuBuildCommandLine(virConnectPtr conn, */ if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || driver->privileged || - (!qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) { + (!qemuCapsGet(caps, QEMU_CAPS_NETDEV_BRIDGE))) { int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net, - qemuCaps); + caps); if (tapfd < 0) goto error; @@ -5333,7 +5333,7 @@ qemuBuildCommandLine(virConnectPtr conn, } } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { int tapfd = qemuPhysIfaceConnect(def, driver, net, - qemuCaps, vmop); + caps, vmop); if (tapfd < 0) goto error; @@ -5352,7 +5352,7 @@ qemuBuildCommandLine(virConnectPtr conn, network device */ int vhostfd; - if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(def, net, caps, &vhostfd) < 0) goto error; if (vhostfd >= 0) { virCommandTransferFD(cmd, vhostfd); @@ -5370,19 +5370,19 @@ qemuBuildCommandLine(virConnectPtr conn, * * NB, no support for -netdev without use of -device */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-netdev"); - if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps, + if (!(host = qemuBuildHostNetStr(net, driver, caps, ',', vlan, tapfd_name, vhostfd_name))) goto error; virCommandAddArg(cmd, host); VIR_FREE(host); } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-device"); - nic = qemuBuildNicDevStr(net, vlan, bootindex, qemuCaps); + nic = qemuBuildNicDevStr(net, vlan, bootindex, caps); if (!nic) goto error; virCommandAddArg(cmd, nic); @@ -5394,10 +5394,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, nic); VIR_FREE(nic); } - if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) { + if (!(qemuCapsGet(caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE))) { virCommandAddArg(cmd, "-net"); - if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps, + if (!(host = qemuBuildHostNetStr(net, driver, caps, ',', vlan, tapfd_name, vhostfd_name))) goto error; @@ -5429,8 +5429,8 @@ qemuBuildCommandLine(virConnectPtr conn, switch (smartcard->type) { case VIR_DOMAIN_SMARTCARD_TYPE_HOST: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || - !qemuCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV) || + !qemuCapsGet(caps, QEMU_CAPS_CCID_EMULATED)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("this QEMU binary lacks smartcard host " "mode support")); @@ -5441,8 +5441,8 @@ qemuBuildCommandLine(virConnectPtr conn, break; case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || - !qemuCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV) || + !qemuCapsGet(caps, QEMU_CAPS_CCID_EMULATED)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("this QEMU binary lacks smartcard host " "mode support")); @@ -5477,8 +5477,8 @@ qemuBuildCommandLine(virConnectPtr conn, break; case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || - !qemuCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV) || + !qemuCapsGet(caps, QEMU_CAPS_CCID_PASSTHRU)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("this QEMU binary lacks smartcard " "passthrough mode support")); @@ -5488,7 +5488,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru, smartcard->info.alias, - qemuCaps))) { + caps))) { virBufferFreeAndReset(&opt); goto error; } @@ -5513,7 +5513,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (!def->nserials) { /* If we have -device, then we set -nodefault already */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) virCommandAddArgList(cmd, "-serial", "none", NULL); } else { for (i = 0 ; i < def->nserials ; i++) { @@ -5521,18 +5521,18 @@ qemuBuildCommandLine(virConnectPtr conn, char *devstr; /* Use -chardev with -device if they are available */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_CHARDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&serial->source, serial->info.alias, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps, + if (!(devstr = qemuBuildChrDeviceStr(serial, caps, def->os.arch, def->os.machine))) goto error; @@ -5550,7 +5550,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (!def->nparallels) { /* If we have -device, then we set -nodefault already */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) virCommandAddArgList(cmd, "-parallel", "none", NULL); } else { for (i = 0 ; i < def->nparallels ; i++) { @@ -5558,12 +5558,12 @@ qemuBuildCommandLine(virConnectPtr conn, char *devstr; /* Use -chardev with -device if they are available */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_CHARDEV) && + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(¶llel->source, parallel->info.alias, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -5590,8 +5590,8 @@ qemuBuildCommandLine(virConnectPtr conn, switch(channel->targetType) { case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || - !qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV) || + !qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("guestfwd requires QEMU to support -chardev & -device")); goto error; @@ -5600,7 +5600,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&channel->source, channel->info.alias, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -5619,13 +5619,13 @@ qemuBuildCommandLine(virConnectPtr conn, break; case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtio channel requires QEMU to support -device")); goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC) && + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE_SPICEVMC) && channel->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) { /* spicevmc was originally introduced via a -device * with a backend internal to qemu; although we prefer @@ -5635,7 +5635,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&channel->source, channel->info.alias, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -5643,7 +5643,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-device"); if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -5658,7 +5658,7 @@ qemuBuildCommandLine(virConnectPtr conn, switch(console->targetType) { case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO: - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtio channel requires QEMU to support -device")); goto error; @@ -5667,14 +5667,14 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&console->source, console->info.alias, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); virCommandAddArg(cmd, "-device"); if (!(devstr = qemuBuildVirtioSerialPortDevStr(console, - qemuCaps))) + caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -5699,7 +5699,7 @@ qemuBuildCommandLine(virConnectPtr conn, char *optstr; virCommandAddArg(cmd, "-device"); - if (!(optstr = qemuBuildHubDevStr(hub, qemuCaps))) + if (!(optstr = qemuBuildHubDevStr(hub, caps))) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); @@ -5709,10 +5709,10 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainInputDefPtr input = def->inputs[i]; if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { char *optstr; virCommandAddArg(cmd, "-device"); - if (!(optstr = qemuBuildUSBInputDevStr(input, qemuCaps))) + if (!(optstr = qemuBuildUSBInputDevStr(input, caps))) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); @@ -5746,7 +5746,7 @@ qemuBuildCommandLine(virConnectPtr conn, virBufferAsprintf(&opt, "unix:%s", def->graphics[0]->data.vnc.socket); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_VNC_COLON)) { const char *listenNetwork; const char *listenAddr = NULL; char *netAddr = NULL; @@ -5801,7 +5801,7 @@ qemuBuildCommandLine(virConnectPtr conn, def->graphics[0]->data.vnc.port - 5900); } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) { + if (qemuCapsGet(caps, QEMU_CAPS_VNC_COLON)) { if (def->graphics[0]->data.vnc.auth.passwd || driver->vncPassword) virBufferAddLit(&opt, ",password"); @@ -5846,8 +5846,8 @@ qemuBuildCommandLine(virConnectPtr conn, } } else if ((def->ngraphics == 1) && def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_0_10) && - !qemuCapsGet(qemuCaps, QEMU_CAPS_SDL)) { + if (qemuCapsGet(caps, QEMU_CAPS_0_10) && + !qemuCapsGet(caps, QEMU_CAPS_SDL)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("sdl not supported by '%s'"), def->emulator); @@ -5873,7 +5873,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* New QEMU has this flag to let us explicitly ask for * SDL graphics. This is better than relying on the * default, since the default changes :-( */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_SDL)) + if (qemuCapsGet(caps, QEMU_CAPS_SDL)) virCommandAddArg(cmd, "-sdl"); } else if ((def->ngraphics == 1) && @@ -5885,7 +5885,7 @@ qemuBuildCommandLine(virConnectPtr conn, int ret; int defaultMode = def->graphics[0]->data.spice.defaultMode; - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SPICE)) { + if (!qemuCapsGet(caps, QEMU_CAPS_SPICE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("spice graphics are not supported with this QEMU")); goto error; @@ -6033,12 +6033,12 @@ qemuBuildCommandLine(virConnectPtr conn, } if (def->nvideos > 0) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_VGA)) { + if (qemuCapsGet(caps, QEMU_CAPS_VGA)) { if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) { /* nothing - vga has no effect on Xen pvfb */ } else { if ((def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) && - !qemuCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) { + !qemuCapsGet(caps, QEMU_CAPS_VGA_QXL)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This QEMU does not support QXL graphics adapters")); goto error; @@ -6056,7 +6056,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) { if (def->videos[0]->vram && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (def->videos[0]->vram > (UINT_MAX / 1024)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("value for 'vram' must be less than '%u'"), @@ -6066,7 +6066,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-global"); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)) + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE_QXL_VGA)) virCommandAddArgFormat(cmd, "qxl-vga.vram_size=%u", def->videos[0]->vram * 1024); else @@ -6100,7 +6100,7 @@ qemuBuildCommandLine(virConnectPtr conn, } if (def->nvideos > 1) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { for (i = 1 ; i < def->nvideos ; i++) { char *str; if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { @@ -6112,7 +6112,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-device"); - if (!(str = qemuBuildVideoDevStr(def->videos[i], qemuCaps))) + if (!(str = qemuBuildVideoDevStr(def->videos[i], caps))) goto error; virCommandAddArg(cmd, str); @@ -6127,15 +6127,15 @@ qemuBuildCommandLine(virConnectPtr conn, } else { /* If we have -device, then we set -nodefault already */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && - qemuCapsGet(qemuCaps, QEMU_CAPS_VGA) && - qemuCapsGet(qemuCaps, QEMU_CAPS_VGA_NONE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE) && + qemuCapsGet(caps, QEMU_CAPS_VGA) && + qemuCapsGet(caps, QEMU_CAPS_VGA_NONE)) virCommandAddArgList(cmd, "-vga", "none", NULL); } /* Add sound hardware */ if (def->nsounds) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { for (i = 0 ; i < def->nsounds ; i++) { virDomainSoundDefPtr sound = def->sounds[i]; char *str = NULL; @@ -6147,7 +6147,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL); } else { virCommandAddArg(cmd, "-device"); - if (!(str = qemuBuildSoundDevStr(sound, qemuCaps))) + if (!(str = qemuBuildSoundDevStr(sound, caps))) goto error; virCommandAddArg(cmd, str); @@ -6158,7 +6158,7 @@ qemuBuildCommandLine(virConnectPtr conn, for (ii = 0 ; ii < sound->ncodecs ; ii++) { virCommandAddArg(cmd, "-device"); - if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[ii], qemuCaps))) { + if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[ii], caps))) { goto error; } @@ -6171,7 +6171,7 @@ qemuBuildCommandLine(virConnectPtr conn, 0 }; virCommandAddArg(cmd, "-device"); - if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, qemuCaps))) { + if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, caps))) { goto error; } @@ -6221,10 +6221,10 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainWatchdogDefPtr watchdog = def->watchdog; char *optstr; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-device"); - optstr = qemuBuildWatchdogDevStr(watchdog, qemuCaps); + optstr = qemuBuildWatchdogDevStr(watchdog, caps); if (!optstr) goto error; } else { @@ -6263,18 +6263,18 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-chardev"); if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr, redirdev->info.alias, - qemuCaps))) { + caps))) { goto error; } virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) goto error; virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildRedirdevDevStr(redirdev, qemuCaps))) + if (!(devstr = qemuBuildRedirdevDevStr(redirdev, caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -6293,7 +6293,7 @@ qemuBuildCommandLine(virConnectPtr conn, _("booting from assigned devices is only" " supported for PCI devices")); goto error; - } else if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) { + } else if (!qemuCapsGet(caps, QEMU_CAPS_PCI_BOOTINDEX)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("booting from assigned PCI devices is not" " supported with this version of qemu")); @@ -6305,9 +6305,9 @@ qemuBuildCommandLine(virConnectPtr conn, if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, qemuCaps))) + if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, caps))) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); @@ -6323,9 +6323,9 @@ qemuBuildCommandLine(virConnectPtr conn, /* PCI */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { char *configfd_name = NULL; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { + if (qemuCapsGet(caps, QEMU_CAPS_PCI_CONFIGFD)) { int configfd = qemuOpenPCIConfig(hostdev); if (configfd >= 0) { @@ -6338,13 +6338,13 @@ qemuBuildCommandLine(virConnectPtr conn, } } virCommandAddArg(cmd, "-device"); - devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name, qemuCaps); + devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name, caps); VIR_FREE(configfd_name); if (!devstr) goto error; virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_PCIDEVICE)) { virCommandAddArg(cmd, "-pcidevice"); if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev))) goto error; @@ -6364,7 +6364,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (migrateFrom) { virCommandAddArg(cmd, "-incoming"); if (STRPREFIX(migrateFrom, "tcp")) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_TCP)) { + if (!qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_TCP)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("TCP migration is not supported with " "this QEMU binary")); @@ -6372,13 +6372,13 @@ qemuBuildCommandLine(virConnectPtr conn, } virCommandAddArg(cmd, migrateFrom); } else if (STREQ(migrateFrom, "stdio")) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) { + if (qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_FD)) { virCommandAddArgFormat(cmd, "fd:%d", migrateFd); virCommandPreserveFD(cmd, migrateFd); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { virCommandAddArg(cmd, "exec:cat"); virCommandSetInputFD(cmd, migrateFd); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_KVM_STDIO)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_MIGRATE_KVM_STDIO)) { virCommandAddArg(cmd, migrateFrom); virCommandSetInputFD(cmd, migrateFd); } else { @@ -6388,7 +6388,7 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } } else if (STRPREFIX(migrateFrom, "exec")) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { + if (!qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("EXEC migration is not supported " "with this QEMU binary")); @@ -6396,7 +6396,7 @@ qemuBuildCommandLine(virConnectPtr conn, } virCommandAddArg(cmd, migrateFrom); } else if (STRPREFIX(migrateFrom, "fd")) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) { + if (!qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_FD)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("FD migration is not supported " "with this QEMU binary")); @@ -6405,7 +6405,7 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, migrateFrom); virCommandPreserveFD(cmd, migrateFd); } else if (STRPREFIX(migrateFrom, "unix")) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { + if (!qemuCapsGet(caps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("UNIX migration is not supported " "with this QEMU binary")); @@ -6433,16 +6433,16 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainMemballoonModelTypeToString(def->memballoon->model)); goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { char *optstr; virCommandAddArg(cmd, "-device"); - optstr = qemuBuildMemballoonDevStr(def->memballoon, qemuCaps); + optstr = qemuBuildMemballoonDevStr(def->memballoon, caps); if (!optstr) goto error; virCommandAddArg(cmd, optstr); VIR_FREE(optstr); - } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_BALLOON)) { + } else if (qemuCapsGet(caps, QEMU_CAPS_BALLOON)) { virCommandAddArgList(cmd, "-balloon", "virtio", NULL); } } @@ -6479,7 +6479,7 @@ qemuBuildCommandLine(virConnectPtr conn, */ char * qemuBuildChrDeviceStr(virDomainChrDefPtr serial, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, char *os_arch, char *machine) { @@ -6491,7 +6491,7 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial, serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) { virBufferAsprintf(&cmd, "spapr-vty,chardev=char%s", serial->info.alias); - if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0) + if (qemuBuildDeviceAddressStr(&cmd, &serial->info, caps) < 0) goto error; } } else diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 7c5e8dd..e155583 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -29,6 +29,7 @@ # include "capabilities.h" # include "qemu_conf.h" # include "qemu_domain.h" +# include "qemu_capabilities.h" /* Config type for XML import/export conversions */ # define QEMU_CONFIG_FORMAT_ARGV "qemu-argv" @@ -53,7 +54,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, bool monitor_json, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, const char *migrateFrom, int migrateFd, virDomainSnapshotObjPtr current_snapshot, @@ -63,14 +64,14 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, /* Generate string for arch-specific '-device' parameter */ char * qemuBuildChrDeviceStr (virDomainChrDefPtr serial, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, char *os_arch, char *machine); /* With vlan == -1, use netdev syntax, else old hostnet */ char * qemuBuildHostNetStr(virDomainNetDefPtr net, struct qemud_driver *driver, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, char type_sep, int vlan, const char *tapfd, @@ -85,50 +86,50 @@ char * qemuBuildNicStr(virDomainNetDefPtr net, char * qemuBuildNicDevStr(virDomainNetDefPtr net, int vlan, int bootindex, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); /* Both legacy & current support */ char *qemuBuildDriveStr(virConnectPtr conn, virDomainDiskDefPtr disk, bool bootable, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char *qemuBuildFSStr(virDomainFSDefPtr fs, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); /* Current, best practice */ char * qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskDefPtr disk, int bootindex, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char * qemuBuildFSDevStr(virDomainFSDefPtr fs, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); /* Current, best practice */ char * qemuBuildControllerDevStr(virDomainDefPtr domainDef, virDomainControllerDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, int *nusbcontroller); char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); /* Legacy, pre device support */ char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev); /* Current, best practice */ char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); @@ -136,28 +137,28 @@ int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev); /* Current, best practice */ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); -char * qemuBuildHubDevStr(virDomainHubDefPtr dev, virBitmapPtr qemuCaps); -char * qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, virBitmapPtr qemuCaps); +char * qemuBuildHubDevStr(virDomainHubDefPtr dev, qemuCapsPtr caps); +char * qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, qemuCapsPtr caps); int qemuNetworkIfaceConnect(virDomainDefPtr def, virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) ATTRIBUTE_NONNULL(2); int qemuPhysIfaceConnect(virDomainDefPtr def, struct qemud_driver *driver, virDomainNetDefPtr net, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, enum virNetDevVPortProfileOp vmop); int qemuOpenVhostNet(virDomainDefPtr def, virDomainNetDefPtr net, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, int *vhostfd); int qemudCanonicalizeMachine(struct qemud_driver *driver, @@ -185,13 +186,13 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, bool *monJSON); int qemuDomainAssignAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virDomainObjPtr); int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuDomainAssignPCIAddresses(virDomainDefPtr def, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virDomainObjPtr obj); qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def); int qemuDomainPCIAddressReserveFunction(qemuDomainPCIAddressSetPtr addrs, @@ -213,12 +214,12 @@ int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot); void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs); int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs); -int qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps); +int qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps); int qemuDomainNetVLAN(virDomainNetDefPtr def); int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx); int qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef, virDomainDiskDefPtr def, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx); int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller); int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, int idx); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0ae30b7..44124f4 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -230,7 +230,7 @@ static void qemuDomainObjPrivateFree(void *data) { qemuDomainObjPrivatePtr priv = data; - qemuCapsFree(priv->qemuCaps); + virObjectUnref(priv->caps); qemuDomainPCIAddressSetFree(priv->pciaddrs); virDomainChrSourceDefFree(priv->monConfig); @@ -290,11 +290,11 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) virBufferAddLit(buf, " </vcpus>\n"); } - if (priv->qemuCaps) { + if (priv->caps) { int i; virBufferAddLit(buf, " <qemuCaps>\n"); for (i = 0 ; i < QEMU_CAPS_LAST ; i++) { - if (qemuCapsGet(priv->qemuCaps, i)) { + if (qemuCapsGet(priv->caps, i)) { virBufferAsprintf(buf, " <flag name='%s'/>\n", qemuCapsTypeToString(i)); } @@ -335,7 +335,7 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) char *tmp; int n, i; xmlNodePtr *nodes = NULL; - virBitmapPtr qemuCaps = NULL; + qemuCapsPtr caps = NULL; if (VIR_ALLOC(priv->monConfig) < 0) { virReportOOMError(); @@ -407,7 +407,7 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) goto error; } if (n > 0) { - if (!(qemuCaps = qemuCapsNew())) + if (!(caps = qemuCapsNew())) goto error; for (i = 0 ; i < n ; i++) { @@ -421,11 +421,11 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) goto error; } VIR_FREE(str); - qemuCapsSet(qemuCaps, flag); + qemuCapsSet(caps, flag); } } - priv->qemuCaps = qemuCaps; + priv->caps = caps; } VIR_FREE(nodes); @@ -476,7 +476,7 @@ error: virDomainChrSourceDefFree(priv->monConfig); priv->monConfig = NULL; VIR_FREE(nodes); - qemuCapsFree(qemuCaps); + virObjectUnref(caps); return -1; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index dff53cf..8ee2541 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -30,7 +30,7 @@ # include "qemu_monitor.h" # include "qemu_agent.h" # include "qemu_conf.h" -# include "bitmap.h" +# include "qemu_capabilities.h" # include "virconsole.h" # define QEMU_EXPECTED_VIRT_TYPES \ @@ -139,7 +139,7 @@ struct _qemuDomainObjPrivate { qemuDomainPCIAddressSetPtr pciaddrs; int persistentAddrs; - virBitmapPtr qemuCaps; + qemuCapsPtr caps; char *lockState; bool fakeReboot; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8e8e00c..affb226 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1805,8 +1805,8 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) } } else { #if HAVE_YAJL - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) { - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_MONITOR_JSON)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_NO_SHUTDOWN)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Reboot is not supported with this QEMU binary")); goto cleanup; @@ -2328,7 +2328,7 @@ static int qemudDomainGetInfo(virDomainPtr dom, if ((vm->def->memballoon != NULL) && (vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) { info->memory = vm->def->mem.max_balloon; - } else if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT)) { + } else if (qemuCapsGet(priv->caps, QEMU_CAPS_BALLOON_EVENT)) { info->memory = vm->def->mem.cur_balloon; } else if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) { if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) @@ -3116,7 +3116,7 @@ static int qemuDumpToFd(struct qemud_driver *driver, virDomainObjPtr vm, qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DUMP_GUEST_MEMORY)) { virReportError(VIR_ERR_NO_SUPPORT, "%s", _("dump-guest-memory is not supported")); return -1; @@ -5047,7 +5047,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, /* Refresh current memory based on balloon info if supported */ if ((vm->def->memballoon != NULL) && (vm->def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) && - !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT) && + !qemuCapsGet(priv->caps, QEMU_CAPS_BALLOON_EVENT) && (virDomainObjIsActive(vm))) { /* Don't delay if someone's using the monitor, just use * existing most recent data instead */ @@ -5133,7 +5133,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, struct qemud_driver *driver = conn->privateData; virDomainDefPtr def = NULL; virDomainChrSourceDef monConfig; - virBitmapPtr qemuCaps = NULL; + qemuCapsPtr caps = NULL; bool monitor_json = false; virCommandPtr cmd = NULL; char *ret = NULL; @@ -5225,19 +5225,19 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, false, NULL, - &qemuCaps) < 0) + &caps) < 0) goto cleanup; - monitor_json = qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON); + monitor_json = qemuCapsGet(caps, QEMU_CAPS_MONITOR_JSON); if (qemuProcessPrepareMonitorChr(driver, &monConfig, def->name) < 0) goto cleanup; - if (qemuAssignDeviceAliases(def, qemuCaps) < 0) + if (qemuAssignDeviceAliases(def, caps) < 0) goto cleanup; if (!(cmd = qemuBuildCommandLine(conn, driver, def, - &monConfig, monitor_json, qemuCaps, + &monConfig, monitor_json, caps, NULL, -1, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) goto cleanup; @@ -5246,7 +5246,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, cleanup: qemuDriverUnlock(driver); - qemuCapsFree(qemuCaps); + virObjectUnref(caps); virCommandFree(cmd); virDomainDefFree(def); return ret; @@ -10580,7 +10580,7 @@ qemuDomainSnapshotDiskPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def, int external = 0; qemuDomainObjPrivatePtr priv = vm->privateData; - if (allow_reuse && !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) { + if (allow_reuse && !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("reuse is not supported with this QEMU binary")); goto cleanup; @@ -10661,7 +10661,7 @@ qemuDomainSnapshotDiskPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def, } if (active) { if (external == 1 || - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) { + qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) { *flags |= VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC; } else if (atomic && external > 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -10934,7 +10934,7 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn, goto cleanup; } } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) { actions = virJSONValueNewArray(); if (!actions) { virReportOOMError(); @@ -11034,7 +11034,7 @@ cleanup: } if (vm && (ret == 0 || - !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION))) { + !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION))) { if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0 || (persist && virDomainSaveConfig(driver->configDir, vm->newDef) < 0)) @@ -12616,9 +12616,9 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, } priv = vm->privateData; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_BLOCKJOB_ASYNC)) { async = true; - } else if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_SYNC)) { + } else if (!qemuCapsGet(priv->caps, QEMU_CAPS_BLOCKJOB_SYNC)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("block jobs not supported with this QEMU binary")); goto cleanup; @@ -12880,7 +12880,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, goto cleanup; } priv = vm->privateData; - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_IOTUNE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("block I/O throttling not supported with this " "QEMU binary")); @@ -13733,7 +13733,7 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom, goto cleanup; } - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_WAKEUP) && + if (!qemuCapsGet(priv->caps, QEMU_CAPS_WAKEUP) && (target == VIR_NODE_SUSPEND_TARGET_MEM || target == VIR_NODE_SUSPEND_TARGET_HYBRID)) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", @@ -13829,7 +13829,7 @@ qemuDomainPMWakeup(virDomainPtr dom, priv = vm->privateData; - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_WAKEUP)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_WAKEUP)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Unable to wake up domain due to " "missing system_wakeup monitor command")); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index a8a904c..a792456 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -98,7 +98,7 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver, return -1; } - if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps))) + if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->caps))) goto error; qemuDomainObjEnterMonitorWithDriver(driver, vm); @@ -227,17 +227,17 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, return -1; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0) goto error; releaseaddr = true; - if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->caps) < 0) goto error; - if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->caps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->caps))) goto error; } @@ -247,7 +247,7 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -287,7 +287,7 @@ error: VIR_FREE(devstr); VIR_FREE(drivestr); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, @@ -322,7 +322,7 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, return -1; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0) goto cleanup; releaseaddr = true; @@ -331,13 +331,13 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && controller->model == -1 && - !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) { + !qemuCapsGet(priv->caps, QEMU_CAPS_PIIX3_USB_UHCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("USB controller hotplug unsupported in this QEMU binary")); goto cleanup; } - if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL))) { + if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->caps, NULL))) { goto cleanup; } } @@ -348,7 +348,7 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDevice(priv->mon, devstr); } else { ret = qemuMonitorAttachPCIDiskController(priv->mon, @@ -364,7 +364,7 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, cleanup: if ((ret != 0) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, @@ -461,14 +461,14 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn, goto error; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->caps) < 0) goto error; - if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->caps))) goto error; } - if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->caps))) goto error; for (i = 0 ; i <= disk->info.addr.drive.controller ; i++) { @@ -494,7 +494,7 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -583,12 +583,12 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, goto error; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->caps) < 0) goto error; - if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->caps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->caps))) goto error; } @@ -598,7 +598,7 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -688,7 +688,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_HOST_NET_ADD)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("installed qemu version does not support host_net_add")); goto cleanup; @@ -703,38 +703,38 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, */ if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || driver->privileged || - (!qemuCapsGet (priv->qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) { + (!qemuCapsGet (priv->caps, QEMU_CAPS_NETDEV_BRIDGE))) { if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net, - priv->qemuCaps)) < 0) + priv->caps)) < 0) goto cleanup; iface_connected = true; - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->caps, &vhostfd) < 0) goto cleanup; } } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net, - priv->qemuCaps, + priv->caps, VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0) goto cleanup; iface_connected = true; - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->caps, &vhostfd) < 0) goto cleanup; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) || - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NET_NAME) || + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0) goto cleanup; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0) goto cleanup; releaseaddr = true; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { vlan = -1; } else { vlan = qemuDomainNetVLAN(net); @@ -756,22 +756,22 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto no_memory; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps, + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { + if (!(netstr = qemuBuildHostNetStr(net, driver, priv->caps, ',', -1, tapfd_name, vhostfd_name))) goto cleanup; } else { - if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps, + if (!(netstr = qemuBuildHostNetStr(net, driver, priv->caps, ' ', vlan, tapfd_name, vhostfd_name))) goto cleanup; } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name, vhostfd, vhostfd_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); @@ -797,8 +797,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (!(nicstr = qemuBuildNicDevStr(net, vlan, 0, priv->qemuCaps))) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { + if (!(nicstr = qemuBuildNicDevStr(net, vlan, 0, priv->caps))) goto try_remove; } else { if (!(nicstr = qemuBuildNicStr(net, NULL, vlan))) @@ -806,7 +806,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditNet(vm, NULL, net, "attach", false); @@ -833,7 +833,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } else { qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV)) { if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditNet(vm, NULL, net, "attach", false); @@ -857,7 +857,7 @@ cleanup: if (!ret) { vm->def->nets[vm->def->nnets++] = net; } else { - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, @@ -890,8 +890,8 @@ try_remove: goto cleanup; if (vlan < 0) { - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { char *netdev_name; if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0) goto no_memory; @@ -943,13 +943,13 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, &hostdev, 1) < 0) return -1; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) goto error; if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0) goto error; releaseaddr = true; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_PCI_CONFIGFD)) { configfd = qemuOpenPCIConfig(hostdev); if (configfd >= 0) { if (virAsprintf(&configfd_name, "fd-%s", @@ -967,7 +967,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, } if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name, - priv->qemuCaps))) + priv->caps))) goto error; qemuDomainObjEnterMonitorWithDriver(driver, vm); @@ -999,7 +999,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, return 0; error: - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, @@ -1024,10 +1024,10 @@ int qemuDomainAttachRedirdevDevice(struct qemud_driver *driver, qemuDomainObjPrivatePtr priv = vm->privateData; char *devstr = NULL; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceRedirdevAlias(vm->def, redirdev, -1) < 0) goto error; - if (!(devstr = qemuBuildRedirdevDevStr(redirdev, priv->qemuCaps))) + if (!(devstr = qemuBuildRedirdevDevStr(redirdev, priv->caps))) goto error; } @@ -1037,7 +1037,7 @@ int qemuDomainAttachRedirdevDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) ret = qemuMonitorAddDevice(priv->mon, devstr); else goto error; @@ -1067,10 +1067,10 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, qemuDomainObjPrivatePtr priv = vm->privateData; char *devstr = NULL; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) goto error; - if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->qemuCaps))) + if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->caps))) goto error; } @@ -1102,7 +1102,7 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) ret = qemuMonitorAddDevice(priv->mon, devstr); else ret = qemuMonitorAddUSBDeviceExact(priv->mon, @@ -1696,7 +1696,7 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditDisk(vm, detach->src, NULL, "detach", false); @@ -1718,7 +1718,7 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, virDomainAuditDisk(vm, detach->src, NULL, "detach", true); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, detach->info.addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src); @@ -1766,7 +1766,7 @@ int qemuDomainDetachDiskDevice(struct qemud_driver *driver, goto cleanup; } - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_OPERATION_FAILED, _("Underlying qemu does not support %s disk removal"), virDomainDiskBusTypeToString(dev->data.disk->bus)); @@ -1921,13 +1921,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, goto cleanup; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceControllerAlias(detach) < 0) goto cleanup; } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; @@ -1944,7 +1944,7 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, virDomainControllerRemove(vm->def, idx); virDomainControllerDefFree(detach); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, detach->info.addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on controller"); @@ -1982,7 +1982,7 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); } else { ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci); @@ -2017,7 +2017,7 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, ret = -1; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, detach->info->addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on host device"); @@ -2041,7 +2041,7 @@ qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, return -1; } - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached with this QEMU version")); return -1; @@ -2232,7 +2232,7 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditNet(vm, detach, NULL, "detach", false); @@ -2247,8 +2247,8 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, } } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); virDomainAuditNet(vm, detach, NULL, "detach", false); @@ -2265,7 +2265,7 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainAuditNet(vm, detach, NULL, "detach", true); - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, detach->info.addr.pci.slot) < 0) VIR_WARN("Unable to release PCI address on NIC"); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 1b21ef6..99fc8ce 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1905,7 +1905,7 @@ qemuMigrationRun(struct qemud_driver *driver, break; case MIGRATION_DEST_UNIX: - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { ret = qemuMonitorMigrateToUnix(priv->mon, migrate_flags, spec->dest.unix_socket.file); } else { @@ -2058,7 +2058,7 @@ static int doNativeMigrate(struct qemud_driver *driver, if (!uribits) return -1; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) + if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD)) spec.destType = MIGRATION_DEST_CONNECT_HOST; else spec.destType = MIGRATION_DEST_HOST; @@ -2099,9 +2099,9 @@ static int doTunnelMigrate(struct qemud_driver *driver, driver, vm, st, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, resource); - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && - !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX) && - !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) && + !qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_UNIX) && + !qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Source qemu is too old to support tunnelled migration")); return -1; @@ -2110,7 +2110,7 @@ static int doTunnelMigrate(struct qemud_driver *driver, spec.fwdType = MIGRATION_FWD_STREAM; spec.fwd.stream = st; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD)) { int fds[2]; spec.destType = MIGRATION_DEST_FD; @@ -3192,7 +3192,7 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, qemuDomainObjExitMonitorWithDriver(driver, vm); } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) && (!compressor || pipe(pipeFD) == 0)) { /* All right! We can use fd migration, which means that qemu * doesn't have to open() the file, so while we still have to @@ -3243,7 +3243,7 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, if (!compressor) { const char *args[] = { "cat", NULL }; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + if (qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_FD) && priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { rc = qemuMonitorMigrateToFd(priv->mon, QEMU_MONITOR_MIGRATE_BACKGROUND, diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index e04af72..f8d717f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1127,7 +1127,7 @@ int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, int qemuMonitorSetCapabilities(qemuMonitorPtr mon, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { int ret; VIR_DEBUG("mon=%p", mon); @@ -1143,11 +1143,11 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon, if (ret < 0) goto cleanup; - ret = qemuMonitorJSONCheckCommands(mon, qemuCaps); + ret = qemuMonitorJSONCheckCommands(mon, caps); if (ret < 0) goto cleanup; - ret = qemuMonitorJSONCheckEvents(mon, qemuCaps); + ret = qemuMonitorJSONCheckEvents(mon, caps); if (ret < 0) goto cleanup; } else { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 0f7ca2d..f206d49 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -27,6 +27,7 @@ # include "internal.h" +# include "qemu_capabilities.h" # include "domain_conf.h" # include "qemu_conf.h" # include "bitmap.h" @@ -156,7 +157,7 @@ qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, void qemuMonitorClose(qemuMonitorPtr mon); int qemuMonitorSetCapabilities(qemuMonitorPtr mon, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 10a68c6..11b85d9 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -974,7 +974,7 @@ qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon) */ int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { int ret = -1; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-commands", NULL); @@ -1003,15 +1003,15 @@ qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, goto cleanup; if (STREQ(name, "system_wakeup")) - qemuCapsSet(qemuCaps, QEMU_CAPS_WAKEUP); + qemuCapsSet(caps, QEMU_CAPS_WAKEUP); else if (STREQ(name, "transaction")) - qemuCapsSet(qemuCaps, QEMU_CAPS_TRANSACTION); + qemuCapsSet(caps, QEMU_CAPS_TRANSACTION); else if (STREQ(name, "block_job_cancel")) - qemuCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_SYNC); + qemuCapsSet(caps, QEMU_CAPS_BLOCKJOB_SYNC); else if (STREQ(name, "block-job-cancel")) - qemuCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC); + qemuCapsSet(caps, QEMU_CAPS_BLOCKJOB_ASYNC); else if (STREQ(name, "dump-guest-memory")) - qemuCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY); + qemuCapsSet(caps, QEMU_CAPS_DUMP_GUEST_MEMORY); } ret = 0; @@ -1025,7 +1025,7 @@ cleanup: int qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, - virBitmapPtr qemuCaps) + qemuCapsPtr caps) { int ret = -1; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-events", NULL); @@ -1061,7 +1061,7 @@ qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, goto cleanup; if (STREQ(name, "BALLOON_CHANGE")) - qemuCapsSet(qemuCaps, QEMU_CAPS_BALLOON_EVENT); + qemuCapsSet(caps, QEMU_CAPS_BALLOON_EVENT); } ret = 0; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index f6e34f4..d092b88 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -43,9 +43,9 @@ int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, int qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon); int qemuMonitorJSONCheckCommands(qemuMonitorPtr mon, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, - virBitmapPtr qemuCaps); + qemuCapsPtr caps); int qemuMonitorJSONStartCPUs(qemuMonitorPtr mon, virConnectPtr conn); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 77d679a..5ac1d2b 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1262,7 +1262,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm) qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorSetCapabilities(priv->mon, priv->qemuCaps); + ret = qemuMonitorSetCapabilities(priv->mon, priv->caps); qemuDomainObjExitMonitorWithDriver(driver, vm); error: @@ -1472,10 +1472,10 @@ qemuProcessLookupPTYs(virDomainChrDefPtr *devices, static int qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, virHashTablePtr paths) { - bool chardevfmt = qemuCapsGet(qemuCaps, QEMU_CAPS_CHARDEV); + bool chardevfmt = qemuCapsGet(caps, QEMU_CAPS_CHARDEV); if (qemuProcessLookupPTYs(vm->def->serials, vm->def->nserials, paths, chardevfmt) < 0) @@ -1584,7 +1584,7 @@ qemuProcessReadLogFD(int logfd, char *buf, int maxlen, int off) static int qemuProcessWaitForMonitor(struct qemud_driver* driver, virDomainObjPtr vm, - virBitmapPtr qemuCaps, + qemuCapsPtr caps, off_t pos) { char *buf = NULL; @@ -1629,7 +1629,7 @@ qemuProcessWaitForMonitor(struct qemud_driver* driver, VIR_DEBUG("qemuMonitorGetPtyPaths returned %i", ret); if (ret == 0) - ret = qemuProcessFindCharDevicePTYsMonitor(vm, qemuCaps, paths); + ret = qemuProcessFindCharDevicePTYsMonitor(vm, caps, paths); cleanup: virHashFree(paths); @@ -1930,7 +1930,7 @@ qemuProcessSetLinkStates(virDomainObjPtr vm) if (def->nets[i]->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) { VIR_DEBUG("Setting link state: %s", def->nets[i]->info.alias); - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV)) { virReportError(VIR_ERR_NO_SUPPORT, "%s", _("Setting of link state is not supported by this qemu")); return -1; @@ -2091,7 +2091,7 @@ qemuProcessInitPasswords(virConnectPtr conn, if (ret < 0) goto cleanup; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { int i; for (i = 0 ; i < vm->def->ndisks ; i++) { @@ -3163,11 +3163,11 @@ qemuProcessReconnect(void *opaque) /* If upgrading from old libvirtd we won't have found any * caps in the domain status, so re-query them */ - if (!priv->qemuCaps && + if (!priv->caps && qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch, false, NULL, - &priv->qemuCaps) < 0) + &priv->caps) < 0) goto error; /* In case the domain shutdown while we were not running, @@ -3183,8 +3183,8 @@ qemuProcessReconnect(void *opaque) goto endjob; } - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) - if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj)) < 0) + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) + if ((qemuDomainAssignAddresses(obj->def, priv->caps, obj)) < 0) goto error; if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0) @@ -3256,7 +3256,7 @@ error: * to remove danger of it ending up running twice if * user tries to start it again later */ - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_NO_SHUTDOWN)) { /* If we couldn't get the monitor and qemu supports * no-shutdown, we can safely say that the domain * crashed ... */ @@ -3563,15 +3563,15 @@ int qemuProcessStart(virConnectPtr conn, } VIR_DEBUG("Determining emulator version"); - qemuCapsFree(priv->qemuCaps); - priv->qemuCaps = NULL; + virObjectUnref(priv->caps); + priv->caps = NULL; if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, true, NULL, - &priv->qemuCaps) < 0) + &priv->caps) < 0) goto cleanup; - if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0) + if (qemuAssignDeviceAliases(vm->def, priv->caps) < 0) goto cleanup; VIR_DEBUG("Checking for CDROM and floppy presence"); @@ -3616,7 +3616,7 @@ int qemuProcessStart(virConnectPtr conn, if (qemuProcessPrepareMonitorChr(driver, priv->monConfig, vm->def->name) < 0) goto cleanup; - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) + if (qemuCapsGet(priv->caps, QEMU_CAPS_MONITOR_JSON)) priv->monJSON = 1; else priv->monJSON = 0; @@ -3647,15 +3647,15 @@ int qemuProcessStart(virConnectPtr conn, * we also need to populate the PCi address set cache for later * use in hotplug */ - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Assigning domain PCI addresses"); - if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm)) < 0) + if ((qemuDomainAssignAddresses(vm->def, priv->caps, vm)) < 0) goto cleanup; } VIR_DEBUG("Building emulator command line"); if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig, - priv->monJSON != 0, priv->qemuCaps, + priv->monJSON != 0, priv->caps, migrateFrom, stdin_fd, snapshot, vmop))) goto cleanup; @@ -3800,7 +3800,7 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; VIR_DEBUG("Waiting for monitor to show up"); - if (qemuProcessWaitForMonitor(driver, vm, priv->qemuCaps, pos) < 0) + if (qemuProcessWaitForMonitor(driver, vm, priv->caps, pos) < 0) goto cleanup; /* Failure to connect to agent shouldn't be fatal */ @@ -3837,7 +3837,7 @@ int qemuProcessStart(virConnectPtr conn, /* If we have -device, then addresses are assigned explicitly. * If not, then we have to detect dynamic ones here */ - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Determining domain device PCI addresses"); if (qemuProcessInitPCIAddresses(driver, vm) < 0) goto cleanup; @@ -4222,8 +4222,8 @@ retry: virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); VIR_FREE(priv->vcpupids); priv->nvcpupids = 0; - qemuCapsFree(priv->qemuCaps); - priv->qemuCaps = NULL; + virObjectUnref(priv->caps); + priv->caps = NULL; VIR_FREE(priv->pidfile); /* The "release" hook cleans up additional resources */ @@ -4333,13 +4333,13 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, goto cleanup; VIR_DEBUG("Determining emulator version"); - qemuCapsFree(priv->qemuCaps); - priv->qemuCaps = NULL; + virObjectUnref(priv->caps); + priv->caps = NULL; if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, false, NULL, - &priv->qemuCaps) < 0) + &priv->caps) < 0) goto cleanup; VIR_DEBUG("Preparing monitor state"); @@ -4356,9 +4356,9 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, * we also need to populate the PCi address set cache for later * use in hotplug */ - if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Assigning domain PCI addresses"); - if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm)) < 0) + if ((qemuDomainAssignAddresses(vm->def, priv->caps, vm)) < 0) goto cleanup; } @@ -4380,7 +4380,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, vm->pid = pid; VIR_DEBUG("Waiting for monitor to show up"); - if (qemuProcessWaitForMonitor(driver, vm, priv->qemuCaps, -1) < 0) + if (qemuProcessWaitForMonitor(driver, vm, priv->caps, -1) < 0) goto cleanup; /* Failure to connect to agent shouldn't be fatal */ @@ -4397,7 +4397,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, /* If we have -device, then addresses are assigned explicitly. * If not, then we have to detect dynamic ones here */ - if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { VIR_DEBUG("Determining domain device PCI addresses"); if (qemuProcessInitPCIAddresses(driver, vm) < 0) goto cleanup; diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 0d884f4..748c43f 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -11,14 +11,14 @@ struct testInfo { const char *name; - virBitmapPtr flags; + qemuCapsPtr flags; unsigned int version; unsigned int is_kvm; unsigned int kvm_version; }; -static void printMismatchedFlags(virBitmapPtr got, - virBitmapPtr expect) +static void printMismatchedFlags(qemuCapsPtr got, + qemuCapsPtr expect) { int i; @@ -38,7 +38,7 @@ static int testHelpStrParsing(const void *data) char *path = NULL; char *help = NULL; unsigned int version, is_kvm, kvm_version; - virBitmapPtr flags = NULL; + qemuCapsPtr flags = NULL; int ret = -1; char *got = NULL; char *expected = NULL; @@ -75,8 +75,8 @@ static int testHelpStrParsing(const void *data) goto cleanup; } - got = virBitmapString(flags); - expected = virBitmapString(info->flags); + got = qemuCapsFlagsString(flags); + expected = qemuCapsFlagsString(info->flags); if (!got || !expected) goto cleanup; @@ -116,7 +116,7 @@ static int testHelpStrParsing(const void *data) cleanup: VIR_FREE(path); VIR_FREE(help); - qemuCapsFree(flags); + virObjectUnref(flags); VIR_FREE(got); VIR_FREE(expected); return ret; @@ -138,7 +138,7 @@ mymain(void) if (virtTestRun("QEMU Help String Parsing " name, \ 1, testHelpStrParsing, &info) < 0) \ ret = -1; \ - qemuCapsFree(info.flags); \ + virObjectUnref(info.flags); \ } while (0) DO_TEST("qemu-0.9.1", 9001, 0, 0, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 47c3f6c..11b9aab 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -78,7 +78,7 @@ typedef enum { static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, - virBitmapPtr extraFlags, + qemuCapsPtr extraFlags, const char *migrateFrom, int migrateFd, virQemuXML2ArgvTestFlags flags) @@ -235,7 +235,7 @@ out: struct testInfo { const char *name; - virBitmapPtr extraFlags; + qemuCapsPtr extraFlags; const char *migrateFrom; int migrateFd; unsigned int flags; @@ -311,7 +311,7 @@ mymain(void) if (virtTestRun("QEMU XML-2-ARGV " name, \ 1, testCompareXMLToArgvHelper, &info) < 0) \ ret = -1; \ - qemuCapsFree(info.extraFlags); \ + virObjectUnref(info.extraFlags); \ } while (0) # define DO_TEST(name, ...) \ diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c index 253c89e..43b5fe6 100644 --- a/tests/qemuxmlnstest.c +++ b/tests/qemuxmlnstest.c @@ -25,7 +25,7 @@ static struct qemud_driver driver; static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, - virBitmapPtr extraFlags, + qemuCapsPtr extraFlags, const char *migrateFrom, int migrateFd, bool json, @@ -164,7 +164,7 @@ static int testCompareXMLToArgvFiles(const char *xml, struct testInfo { const char *name; - virBitmapPtr extraFlags; + qemuCapsPtr extraFlags; const char *migrateFrom; int migrateFd; bool json; @@ -238,7 +238,7 @@ mymain(void) if (virtTestRun("QEMU XML-2-ARGV " name, \ 1, testCompareXMLToArgvHelper, &info) < 0) \ ret = -1; \ - qemuCapsFree(info.extraFlags); \ + virObjectUnref(info.extraFlags); \ } while (0) # define DO_TEST(name, expectError, ...) \ -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
The current qemu capabilities are stored in a virBitmapPtr object, whose type is exposed to callers. We want to store more data besides just the flags, so we need to move to a struct type. This object will also need to be reference counted, since we'll be maintaining a cache of data per binary. This change introduces a 'qemuCapsPtr' virObject class. Most of the change is just renaming types and variables in all the callers
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 376 ++++++++++++++++------------ src/qemu/qemu_capabilities.h | 29 ++- src/qemu/qemu_command.c | 580 +++++++++++++++++++++---------------------- src/qemu/qemu_command.h | 53 ++-- src/qemu/qemu_domain.c | 16 +- src/qemu/qemu_domain.h | 4 +- src/qemu/qemu_driver.c | 40 +-- src/qemu/qemu_hotplug.c | 138 +++++----- src/qemu/qemu_migration.c | 16 +- src/qemu/qemu_monitor.c | 6 +- src/qemu/qemu_monitor.h | 3 +- src/qemu/qemu_monitor_json.c | 16 +- src/qemu/qemu_monitor_json.h | 4 +- src/qemu/qemu_process.c | 62 ++--- tests/qemuhelptest.c | 16 +- tests/qemuxml2argvtest.c | 6 +- tests/qemuxmlnstest.c | 6 +- 17 files changed, 712 insertions(+), 659 deletions(-)
Slightly more additions than removals; I'm hoping it's due to the new struct, and maybe a few places where the renaming let you split long lines.
@@ -1644,54 +1666,80 @@ int qemuCapsExtractVersion(virCapsPtr caps, }
-virBitmapPtr + + +qemuCapsPtr
A lot of blank lines here. ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> The qemuCapsProbeCommand API is only used by the capabilities code, so can be static Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 40 ++++++++++++++++++++-------------------- src/qemu/qemu_capabilities.h | 3 --- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index b8c1f36..b6193d9 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -253,6 +253,26 @@ static const struct qemu_arch_info const arch_info_xen[] = { }; +static virCommandPtr +qemuCapsProbeCommand(const char *qemu, + qemuCapsPtr caps) +{ + virCommandPtr cmd = virCommandNew(qemu); + + if (caps) { + if (qemuCapsGet(caps, QEMU_CAPS_NO_USER_CONFIG)) + virCommandAddArg(cmd, "-no-user-config"); + else if (qemuCapsGet(caps, QEMU_CAPS_NODEFCONFIG)) + virCommandAddArg(cmd, "-nodefconfig"); + } + + virCommandAddEnvPassCommon(cmd); + virCommandClearCaps(cmd); + + return cmd; +} + + /* Format is: * <machine> <desc> [(default)|(alias of <canonical>)] */ @@ -1744,23 +1764,3 @@ qemuCapsGet(qemuCapsPtr caps, else return b; } - - -virCommandPtr -qemuCapsProbeCommand(const char *qemu, - qemuCapsPtr caps) -{ - virCommandPtr cmd = virCommandNew(qemu); - - if (caps) { - if (qemuCapsGet(caps, QEMU_CAPS_NO_USER_CONFIG)) - virCommandAddArg(cmd, "-no-user-config"); - else if (qemuCapsGet(caps, QEMU_CAPS_NODEFCONFIG)) - virCommandAddArg(cmd, "-nodefconfig"); - } - - virCommandAddEnvPassCommon(cmd); - virCommandClearCaps(cmd); - - return cmd; -} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 1e817c6..830b283 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -194,9 +194,6 @@ int qemuCapsParseHelpStr(const char *qemu, int qemuCapsParseDeviceStr(const char *str, qemuCapsPtr caps); -virCommandPtr qemuCapsProbeCommand(const char *qemu, - qemuCapsPtr caps); - VIR_ENUM_DECL(qemuCaps); #endif /* __QEMU_CAPABILITIES_H__*/ -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
The qemuCapsProbeCommand API is only used by the capabilities code, so can be static
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 40 ++++++++++++++++++++-------------------- src/qemu/qemu_capabilities.h | 3 --- 2 files changed, 20 insertions(+), 23 deletions(-)
ACK. The diff is big only because you also did code motion for topological sorting. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> Add struct fields and APIs to allow the qemu capabilities object to store version, arch, machines & cpu names, etc Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 10 ++++++ 2 files changed, 88 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index b6193d9..1e36e4b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -182,6 +182,18 @@ struct _qemuCaps { virObject object; virBitmapPtr flags; + + unsigned int version; + unsigned int kvmVersion; + + char *arch; + + size_t ncpuDefinitions; + char **cpuDefinitions; + + size_t nmachineTypes; + char **machineTypes; + char **machineAliases; }; @@ -1714,6 +1726,21 @@ no_memory: void qemuCapsDispose(void *obj) { qemuCapsPtr caps = obj; + size_t i; + + VIR_FREE(caps->arch); + + for (i = 0 ; i < caps->nmachineTypes ; i++) { + VIR_FREE(caps->machineTypes[i]); + VIR_FREE(caps->machineAliases[i]); + } + VIR_FREE(caps->machineTypes); + VIR_FREE(caps->machineAliases); + + for (i = 0 ; i < caps->ncpuDefinitions ; i++) { + VIR_FREE(caps->cpuDefinitions[i]); + } + VIR_FREE(caps->cpuDefinitions); virBitmapFree(caps->flags); } @@ -1764,3 +1791,54 @@ qemuCapsGet(qemuCapsPtr caps, else return b; } + + +const char *qemuCapsGetArch(qemuCapsPtr caps) +{ + return caps->arch; +} + + +unsigned int qemuCapsGetVersion(qemuCapsPtr caps) +{ + return caps->version; +} + + +unsigned int qemuCapsGetKVMVersion(qemuCapsPtr caps) +{ + return caps->kvmVersion; +} + + +size_t qemuCapsGetCPUDefinitions(qemuCapsPtr caps, + char ***names) +{ + *names = caps->cpuDefinitions; + return caps->ncpuDefinitions; +} + + +size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, + char ***names) +{ + *names = caps->machineTypes; + return caps->nmachineTypes; +} + + +const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, + const char *name) + +{ + size_t i; + + for (i = 0 ; i < caps->nmachineTypes ; i++) { + if (!caps->machineAliases[i]) + continue; + if (STREQ(caps->machineAliases[i], name)) + return caps->machineTypes[i]; + } + + return name; +} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 830b283..c6e3756 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -163,6 +163,16 @@ bool qemuCapsGet(qemuCapsPtr caps, char *qemuCapsFlagsString(qemuCapsPtr caps); +const char *qemuCapsGetArch(qemuCapsPtr caps); +unsigned int qemuCapsGetVersion(qemuCapsPtr caps); +unsigned int qemuCapsGetKVMVersion(qemuCapsPtr caps); +size_t qemuCapsGetCPUDefinitions(qemuCapsPtr caps, + char ***names); +size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, + char ***names); +const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, + const char *name); + virCapsPtr qemuCapsInit(virCapsPtr old_caps); int qemuCapsProbeMachineTypes(const char *binary, -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Add struct fields and APIs to allow the qemu capabilities object to store version, arch, machines & cpu names, etc
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 10 ++++++ 2 files changed, 88 insertions(+)
ACK.
+size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, + char ***names) +{ + *names = caps->machineTypes; + return caps->nmachineTypes;
I guess we're pretty safe assuming the caller won't go modifying the contents of the returned array behind the qemuCaps' back. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> To allow each VM instance to record additional capabilities without affecting other VMs, there needs to be a way to do a deep copy of the qemuCapsPtr object --- src/qemu/qemu_capabilities.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 48 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 1e36e4b..bc45c52 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1723,6 +1723,53 @@ no_memory: } +qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps) +{ + qemuCapsPtr ret = qemuCapsNew(); + size_t i; + + if (!ret) + return NULL; + + virBitmapCopy(ret->flags, caps->flags); + + ret->version = caps->version; + ret->kvmVersion = caps->kvmVersion; + + if (caps->arch && + !(ret->arch = strdup(caps->arch))) + goto no_memory; + + if (VIR_ALLOC_N(ret->cpuDefinitions, caps->ncpuDefinitions) < 0) + goto no_memory; + ret->ncpuDefinitions = caps->ncpuDefinitions; + for (i = 0 ; i < caps->ncpuDefinitions ; i++) { + if (!(ret->cpuDefinitions[i] = strdup(caps->cpuDefinitions[i]))) + goto no_memory; + } + + if (VIR_ALLOC_N(ret->machineTypes, caps->nmachineTypes) < 0) + goto no_memory; + if (VIR_ALLOC_N(ret->machineAliases, caps->nmachineTypes) < 0) + goto no_memory; + ret->nmachineTypes = caps->nmachineTypes; + for (i = 0 ; i < caps->nmachineTypes ; i++) { + if (!(ret->machineTypes[i] = strdup(caps->machineTypes[i]))) + goto no_memory; + if (caps->machineAliases[i] && + !(ret->machineAliases[i] = strdup(caps->machineAliases[i]))) + goto no_memory; + } + + return ret; + +no_memory: + virReportOOMError(); + virObjectUnref(ret); + return NULL; +} + + void qemuCapsDispose(void *obj) { qemuCapsPtr caps = obj; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index c6e3756..cd104c0 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -149,6 +149,7 @@ typedef struct _qemuCaps qemuCaps; typedef qemuCaps *qemuCapsPtr; qemuCapsPtr qemuCapsNew(void); +qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps); void qemuCapsSet(qemuCapsPtr caps, enum qemuCapsFlags flag) ATTRIBUTE_NONNULL(1); -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
To allow each VM instance to record additional capabilities without affecting other VMs, there needs to be a way to do a deep copy of the qemuCapsPtr object --- src/qemu/qemu_capabilities.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 48 insertions(+)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> The QEMU capabilities APIs used a misc of 'int' and 'unsigned int' for variables relating to array sizes. Change all these to use 'size_t' Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 22 +++++++++++----------- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index bc45c52..97aeac7 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -291,7 +291,7 @@ qemuCapsProbeCommand(const char *qemu, static int qemuCapsParseMachineTypesStr(const char *output, virCapsGuestMachinePtr **machines, - int *nmachines) + size_t *nmachines) { const char *p = output; const char *next; @@ -360,7 +360,7 @@ int qemuCapsProbeMachineTypes(const char *binary, qemuCapsPtr caps, virCapsGuestMachinePtr **machines, - int *nmachines) + size_t *nmachines) { char *output; int ret = -1; @@ -401,7 +401,7 @@ qemuCapsGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info, const char *emulator, time_t emulator_mtime, virCapsGuestMachinePtr **machines, - int *nmachines) + size_t *nmachines) { virCapsGuestMachinePtr *list; int i; @@ -456,7 +456,7 @@ qemuCapsGetOldMachines(const char *ostype, time_t emulator_mtime, virCapsPtr old_caps, virCapsGuestMachinePtr **machines, - int *nmachines) + size_t *nmachines) { int i; @@ -490,8 +490,8 @@ qemuCapsGetOldMachines(const char *ostype, typedef int (*qemuCapsParseCPUModels)(const char *output, - unsigned int *retcount, - const char ***retcpus); + size_t *retcount, + const char ***retcpus); /* Format: * <arch> <model> @@ -500,7 +500,7 @@ typedef int */ static int qemuCapsParseX86Models(const char *output, - unsigned int *retcount, + size_t *retcount, const char ***retcpus) { const char *p = output; @@ -576,7 +576,7 @@ error: */ static int qemuCapsParsePPCModels(const char *output, - unsigned int *retcount, + size_t *retcount, const char ***retcpus) { const char *p = output; @@ -646,7 +646,7 @@ int qemuCapsProbeCPUModels(const char *qemu, qemuCapsPtr caps, const char *arch, - unsigned int *count, + size_t *count, const char ***cpus) { char *output = NULL; @@ -703,9 +703,9 @@ qemuCapsInitGuest(virCapsPtr caps, char *binary = NULL; time_t binary_mtime; virCapsGuestMachinePtr *machines = NULL; - int nmachines = 0; + size_t nmachines = 0; struct stat st; - unsigned int ncpus; + size_t ncpus; qemuCapsPtr qemubinCaps = NULL; qemuCapsPtr kvmbinCaps = NULL; int ret = -1; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index cd104c0..9d31094 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -179,12 +179,12 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps); int qemuCapsProbeMachineTypes(const char *binary, qemuCapsPtr caps, virCapsGuestMachinePtr **machines, - int *nmachines); + size_t *nmachines); int qemuCapsProbeCPUModels(const char *qemu, qemuCapsPtr caps, const char *arch, - unsigned int *count, + size_t *count, const char ***cpus); int qemuCapsExtractVersion(virCapsPtr caps, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5b4aeda..ea0b275 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4040,7 +4040,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, const virCPUDefPtr host = driver->caps->host.cpu; virCPUDefPtr guest = NULL; virCPUDefPtr cpu = NULL; - unsigned int ncpus = 0; + size_t ncpus = 0; const char **cpus = NULL; const char *default_model; union cpuData *data = NULL; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index affb226..2bc9101 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5440,7 +5440,7 @@ static int qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical) { virCapsGuestMachinePtr *machines = NULL; - int i, nmachines = 0; + size_t i, nmachines = 0; /* XXX we should be checking emulator capabilities and pass them instead * of NULL so that -nodefconfig or -no-user-config is properly added when -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
The QEMU capabilities APIs used a misc of 'int' and 'unsigned int' for variables relating to array sizes. Change all these to use 'size_t'
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 22 +++++++++++----------- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-)
Fairly mechanical. ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 09/12/2012 10:14 PM, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
The QEMU capabilities APIs used a misc of 'int' and 'unsigned int' for variables relating to array sizes. Change all these to use 'size_t'
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 22 +++++++++++----------- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-)
Fairly mechanical. ACK.
Spoke too soon; I'm getting a test coredump: TEST: qemuxml2argvtest .../bin/sh: line 5: 19492 Segmentation fault abs_top_builddir=`cd '..'; pwd` abs_top_srcdir=`cd '..'; pwd` abs_builddir=`pwd` abs_srcdir=`cd '.'; pwd` CONFIG_HEADER="`cd '..'; pwd`/config.h" PATH="`cd '..'; pwd`/daemon:`cd '..'; pwd`/tools:`cd '..'; pwd`/tests:$PATH" SHELL="/bin/sh" LIBVIRT_DRIVER_DIR="/home/remote/eblake/libvirt/src/.libs" LIBVIRT_AUTOSTART=0 LC_ALL=C ${dir}$tst FAIL: qemuxml2argvtest but haven't yet takent the time to pin it down. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Thu, Sep 13, 2012 at 06:12:47AM -0600, Eric Blake wrote:
On 09/12/2012 10:14 PM, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
The QEMU capabilities APIs used a misc of 'int' and 'unsigned int' for variables relating to array sizes. Change all these to use 'size_t'
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 22 +++++++++++----------- src/qemu/qemu_capabilities.h | 4 ++-- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-)
Fairly mechanical. ACK.
Spoke too soon; I'm getting a test coredump: TEST: qemuxml2argvtest .../bin/sh: line 5: 19492 Segmentation fault abs_top_builddir=`cd '..'; pwd` abs_top_srcdir=`cd '..'; pwd` abs_builddir=`pwd` abs_srcdir=`cd '.'; pwd` CONFIG_HEADER="`cd '..'; pwd`/config.h" PATH="`cd '..'; pwd`/daemon:`cd '..'; pwd`/tools:`cd '..'; pwd`/tests:$PATH" SHELL="/bin/sh" LIBVIRT_DRIVER_DIR="/home/remote/eblake/libvirt/src/.libs" LIBVIRT_AUTOSTART=0 LC_ALL=C ${dir}$tst FAIL: qemuxml2argvtest
but haven't yet takent the time to pin it down.
Hmm, I already pushed this patch & others you ACKd. I ran 'make check' first and didn't see this crash though. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 09/13/2012 06:17 AM, Daniel P. Berrange wrote:
Spoke too soon; I'm getting a test coredump: TEST: qemuxml2argvtest .../bin/sh: line 5: 19492 Segmentation fault abs_top_builddir=`cd '..'; pwd` abs_top_srcdir=`cd '..'; pwd` abs_builddir=`pwd` abs_srcdir=`cd '.'; pwd` CONFIG_HEADER="`cd '..'; pwd`/config.h" PATH="`cd '..'; pwd`/daemon:`cd '..'; pwd`/tools:`cd '..'; pwd`/tests:$PATH" SHELL="/bin/sh" LIBVIRT_DRIVER_DIR="/home/remote/eblake/libvirt/src/.libs" LIBVIRT_AUTOSTART=0 LC_ALL=C ${dir}$tst FAIL: qemuxml2argvtest
but haven't yet takent the time to pin it down.
Hmm, I already pushed this patch & others you ACKd. I ran 'make check' first and didn't see this crash though.
Weird - I saw it on the tree where I was hand-applying your patches, but not on a fresh checkout. Wonder what I did wrong to my tree? At any rate, I think we're safe, after all. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce a qemuCapsNewForBinary() API which creates a new QEMU capabilities object, populated with data relating to a specific QEMU binary. The qemuCaps object is also given a timestamp, which makes it possible to detect when the cached capabilities for a binary are out of date Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 142 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 2 files changed, 145 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 97aeac7..e8b5797 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -181,6 +181,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, struct _qemuCaps { virObject object; + char *binary; + time_t mtime; + virBitmapPtr flags; unsigned int version; @@ -1790,6 +1793,8 @@ void qemuCapsDispose(void *obj) VIR_FREE(caps->cpuDefinitions); virBitmapFree(caps->flags); + + VIR_FREE(caps->binary); } void @@ -1889,3 +1894,140 @@ const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, return name; } + + +#define QEMU_SYSTEM_PREFIX "qemu-system-" + +qemuCapsPtr qemuCapsNewForBinary(const char *binary) +{ + qemuCapsPtr caps = qemuCapsNew(); + const char *tmp; + struct utsname ut; + unsigned int is_kvm; + char *help = NULL; + virCommandPtr cmd = NULL; + virCapsGuestMachinePtr *machines = NULL; + size_t nmachines; + size_t i; + struct stat sb; + + if (!(caps->binary = strdup(binary))) + goto no_memory; + + tmp = strstr(binary, QEMU_SYSTEM_PREFIX); + if (tmp) { + tmp += strlen(QEMU_SYSTEM_PREFIX); + } else { + uname_normalize(&ut); + tmp = ut.machine; + } + if (!(caps->arch = strdup(tmp))) + goto no_memory; + + /* We would also want to check faccessat if we cared about ACLs, + * but we don't. */ + if (stat(binary, &sb) < 0) { + virReportSystemError(errno, _("Cannot check QEMU binary %s"), + binary); + goto error; + } + if (!(S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0)) { + errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES; + virReportSystemError(errno, _("QEMU binary %s is not executable"), + binary); + goto error; + } + caps->mtime = sb.st_mtime; + + /* Make sure the binary we are about to try exec'ing exists. + * Technically we could catch the exec() failure, but that's + * in a sub-process so it's hard to feed back a useful error. + */ + if (!virFileIsExecutable(binary)) { + goto error; + } + + cmd = qemuCapsProbeCommand(binary, NULL); + virCommandAddArgList(cmd, "-help", NULL); + virCommandSetOutputBuffer(cmd, &help); + + if (virCommandRun(cmd, NULL) < 0) + goto error; + + if (qemuCapsParseHelpStr(binary, help, caps, + &caps->version, + &is_kvm, + &caps->kvmVersion, + false) < 0) + goto error; + + /* Currently only x86_64 and i686 support PCI-multibus. */ + if (STREQLEN(caps->arch, "x86_64", 6) || + STREQLEN(caps->arch, "i686", 4)) { + qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS); + } + + /* S390 and probably other archs do not support no-acpi - + maybe the qemu option parsing should be re-thought. */ + if (STRPREFIX(caps->arch, "s390")) + qemuCapsClear(caps, QEMU_CAPS_NO_ACPI); + + /* qemuCapsExtractDeviceStr will only set additional caps if qemu + * understands the 0.13.0+ notion of "-device driver,". */ + if (qemuCapsGet(caps, QEMU_CAPS_DEVICE) && + strstr(help, "-device driver,?") && + qemuCapsExtractDeviceStr(binary, caps) < 0) + goto error; + + if (qemuCapsProbeCPUModels(binary, caps, caps->arch, + &caps->ncpuDefinitions, + (const char ***)&caps->cpuDefinitions) < 0) + goto error; + + if (qemuCapsProbeMachineTypes(binary, caps, + &machines, &nmachines) < 0) + goto error; + + if (VIR_ALLOC_N(caps->machineTypes, nmachines) < 0) + goto no_memory; + if (VIR_ALLOC_N(caps->machineAliases, nmachines) < 0) + goto no_memory; + caps->nmachineTypes = nmachines; + + for (i = 0 ; i < caps->nmachineTypes ; i++) { + if (machines[i]->canonical) { + caps->machineTypes[i] = machines[i]->canonical; + caps->machineAliases[i] = machines[i]->name; + } else { + caps->machineTypes[i] = machines[i]->name; + } + } + VIR_FREE(machines); + +cleanup: + VIR_FREE(help); + virCommandFree(cmd); + return caps; + +no_memory: + virReportOOMError(); +error: + virCapabilitiesFreeMachines(machines, nmachines); + virObjectUnref(caps); + caps = NULL; + goto cleanup; +} + + +bool qemuCapsIsValid(qemuCapsPtr caps) +{ + struct stat sb; + + if (!caps->binary) + return true; + + if (stat(caps->binary, &sb) < 0) + return false; + + return sb.st_mtime == caps->mtime; +} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 9d31094..68d71a9 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -150,6 +150,7 @@ typedef qemuCaps *qemuCapsPtr; qemuCapsPtr qemuCapsNew(void); qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps); +qemuCapsPtr qemuCapsNewForBinary(const char *binary); void qemuCapsSet(qemuCapsPtr caps, enum qemuCapsFlags flag) ATTRIBUTE_NONNULL(1); @@ -174,6 +175,8 @@ size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, const char *name); +bool qemuCapsIsValid(qemuCapsPtr caps); + virCapsPtr qemuCapsInit(virCapsPtr old_caps); int qemuCapsProbeMachineTypes(const char *binary, -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce a qemuCapsNewForBinary() API which creates a new QEMU capabilities object, populated with data relating to a specific QEMU binary. The qemuCaps object is also given a timestamp, which makes it possible to detect when the cached capabilities for a binary are out of date
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 142 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 2 files changed, 145 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 97aeac7..e8b5797 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -181,6 +181,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, struct _qemuCaps { virObject object;
+ char *binary; + time_t mtime;
Do we care about subsecond resolution (that is, should this be struct timespec instead of time_t)? We already have gnulib functions imported that guarantee we can extract timespec from any stat() call, even on systems limited to second resolution. mtime can be faked; do we want to use ctime instead?
+qemuCapsPtr qemuCapsNewForBinary(const char *binary) +{
+ /* We would also want to check faccessat if we cared about ACLs, + * but we don't. */ + if (stat(binary, &sb) < 0) { + virReportSystemError(errno, _("Cannot check QEMU binary %s"), + binary); + goto error; + } + if (!(S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0)) {
Poor-man's access(binary, X_OK), but I can live with it (not to mention it is copied from somewhere else, and this is more of a refactoring). On the other hand...
+ errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES; + virReportSystemError(errno, _("QEMU binary %s is not executable"), + binary); + goto error; + } + caps->mtime = sb.st_mtime;
Here, if you include "stat-time.h" and use my struct-timespec hint, this would be caps->mtime = get_stat_mtime(&st). And again, should we be favoring ctime instead?
+ + /* Make sure the binary we are about to try exec'ing exists. + * Technically we could catch the exec() failure, but that's + * in a sub-process so it's hard to feed back a useful error. + */ + if (!virFileIsExecutable(binary)) { + goto error; + }
...Isn't this just repeating the open-coded st.st_mode&0111 and S_ISDIR checks done earlier? Can we simplify the code by doing this check alone, and dropping the open-coding?
+ + /* S390 and probably other archs do not support no-acpi -
Code copying, but s/archs/arches/ while you are here.
+ +bool qemuCapsIsValid(qemuCapsPtr caps) +{ + struct stat sb; + + if (!caps->binary) + return true; + + if (stat(caps->binary, &sb) < 0) + return false; + + return sb.st_mtime == caps->mtime;
with my earlier comments, this would be: return get_stat_[mc]time(&sb) == caps->[mc]time This is mostly copying existing code in preparation for deleting the original sites in favor of this code in later patches, so it's up to you whether to tweak push as-is with a later cleanup commit, or to post a v2 that fixes my comments in one commit. Weak ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Thu, Sep 13, 2012 at 10:31:09AM -0600, Eric Blake wrote:
On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce a qemuCapsNewForBinary() API which creates a new QEMU capabilities object, populated with data relating to a specific QEMU binary. The qemuCaps object is also given a timestamp, which makes it possible to detect when the cached capabilities for a binary are out of date
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 142 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 2 files changed, 145 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 97aeac7..e8b5797 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -181,6 +181,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, struct _qemuCaps { virObject object;
+ char *binary; + time_t mtime;
Do we care about subsecond resolution (that is, should this be struct timespec instead of time_t)? We already have gnulib functions imported that guarantee we can extract timespec from any stat() call, even on systems limited to second resolution.
mtime can be faked; do we want to use ctime instead?
+qemuCapsPtr qemuCapsNewForBinary(const char *binary) +{
+ /* We would also want to check faccessat if we cared about ACLs, + * but we don't. */ + if (stat(binary, &sb) < 0) { + virReportSystemError(errno, _("Cannot check QEMU binary %s"), + binary); + goto error; + } + if (!(S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0)) {
Poor-man's access(binary, X_OK), but I can live with it (not to mention it is copied from somewhere else, and this is more of a refactoring). On the other hand...
+ errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES; + virReportSystemError(errno, _("QEMU binary %s is not executable"), + binary); + goto error; + } + caps->mtime = sb.st_mtime;
Here, if you include "stat-time.h" and use my struct-timespec hint, this would be caps->mtime = get_stat_mtime(&st). And again, should we be favoring ctime instead?
+ + /* Make sure the binary we are about to try exec'ing exists. + * Technically we could catch the exec() failure, but that's + * in a sub-process so it's hard to feed back a useful error. + */ + if (!virFileIsExecutable(binary)) { + goto error; + }
...Isn't this just repeating the open-coded st.st_mode&0111 and S_ISDIR checks done earlier? Can we simplify the code by doing this check alone, and dropping the open-coding?
Sigh, I don't know what I was thinking. The original idea of open coding it was that I needed to stat() the binary to get the modification time. Calling virFileIsExecutable() would then repeat the stat() again. I was trying to avoid that duplicated call. For unknown reasons I then left the virFileIsExecutable() call in there. To be honest this was all just premature optimization, so I'll remove the open coded check and just live with the duplicated stat() call, as this isn't performance critical.
+ + /* S390 and probably other archs do not support no-acpi -
Code copying, but s/archs/arches/ while you are here.
+ +bool qemuCapsIsValid(qemuCapsPtr caps) +{ + struct stat sb; + + if (!caps->binary) + return true; + + if (stat(caps->binary, &sb) < 0) + return false; + + return sb.st_mtime == caps->mtime;
with my earlier comments, this would be: return get_stat_[mc]time(&sb) == caps->[mc]time
This is mostly copying existing code in preparation for deleting the original sites in favor of this code in later patches, so it's up to you whether to tweak push as-is with a later cleanup commit, or to post a v2 that fixes my comments in one commit. Weak ACK.
I'll delete the open coded calls. I don't think we need sub-second time resolution though. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce a qemuCapsCachePtr object to provide a global cache of capabilities for QEMU binaries. The cache auto-populates on first request for capabilities about a binary, and will auto-refresh if the binary has changed since a previous cache was populated Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 9 ++++ 2 files changed, 108 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e8b5797..4581e60 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -199,6 +199,11 @@ struct _qemuCaps { char **machineAliases; }; +struct _qemuCapsCache { + virMutex lock; + virHashTablePtr binaries; +}; + static virClassPtr qemuCapsClass; static void qemuCapsDispose(void *obj); @@ -1917,6 +1922,10 @@ qemuCapsPtr qemuCapsNewForBinary(const char *binary) tmp = strstr(binary, QEMU_SYSTEM_PREFIX); if (tmp) { tmp += strlen(QEMU_SYSTEM_PREFIX); + + /* For historical compat we uses 'itanium' as arch name */ + if (STREQ(tmp, "ia64")) + tmp = "itanium"; } else { uname_normalize(&ut); tmp = ut.machine; @@ -2031,3 +2040,93 @@ bool qemuCapsIsValid(qemuCapsPtr caps) return sb.st_mtime == caps->mtime; } + + +static void +qemuCapsHashDataFree(void *payload, const void *key ATTRIBUTE_UNUSED) +{ + virObjectUnref(payload); +} + +qemuCapsCachePtr qemuCapsCacheNew(void) +{ + qemuCapsCachePtr cache; + + if (VIR_ALLOC(cache) < 0) { + virReportOOMError(); + return NULL; + } + + if (virMutexInit(&cache->lock) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to initialize mutex")); + VIR_FREE(cache); + return NULL; + } + + if (!(cache->binaries = virHashCreate(10, qemuCapsHashDataFree))) + goto error; + + return cache; + +error: + qemuCapsCacheFree(cache); + return NULL; +} + + +qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary) +{ + qemuCapsPtr ret = NULL; + virMutexLock(&cache->lock); + ret = virHashLookup(cache->binaries, binary); + if (ret && + !qemuCapsIsValid(ret)) { + VIR_DEBUG("Cached capabilities %p no longer valid for %s", + ret, binary); + virHashRemoveEntry(cache->binaries, binary); + ret = NULL; + } + if (!ret) { + VIR_DEBUG("Creating capabilities for %s", + binary); + ret = qemuCapsNewForBinary(binary); + if (ret) { + VIR_DEBUG("Caching capabilities %p for %s", + ret, binary); + if (virHashAddEntry(cache->binaries, binary, ret) < 0) { + virObjectUnref(ret); + ret = NULL; + } + } + } + VIR_DEBUG("Returning caps %p for %s", ret, binary); + virObjectRef(ret); + virMutexUnlock(&cache->lock); + return ret; +} + + +qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary) +{ + qemuCapsPtr caps = qemuCapsCacheLookup(cache, binary); + qemuCapsPtr ret; + + if (!caps) + return NULL; + + ret = qemuCapsNewCopy(caps); + virObjectUnref(caps); + return ret; +} + + +void qemuCapsCacheFree(qemuCapsCachePtr cache) +{ + if (!cache) + return; + + virHashFree(cache->binaries); + virMutexDestroy(&cache->lock); + VIR_FREE(cache); +} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 68d71a9..f9105bb 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -148,6 +148,9 @@ enum qemuCapsFlags { typedef struct _qemuCaps qemuCaps; typedef qemuCaps *qemuCapsPtr; +typedef struct _qemuCapsCache qemuCapsCache; +typedef qemuCapsCache *qemuCapsCachePtr; + qemuCapsPtr qemuCapsNew(void); qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps); qemuCapsPtr qemuCapsNewForBinary(const char *binary); @@ -177,6 +180,12 @@ const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, bool qemuCapsIsValid(qemuCapsPtr caps); + +qemuCapsCachePtr qemuCapsCacheNew(void); +qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary); +qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary); +void qemuCapsCacheFree(qemuCapsCachePtr cache); + virCapsPtr qemuCapsInit(virCapsPtr old_caps); int qemuCapsProbeMachineTypes(const char *binary, -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> When building up a virCapsPtr instance, the QEMU driver was copying the list of machine types across from the previous virCapsPtr instance, if the QEMU binary had not changed. Replace this ad-hoc caching of data with use of the new qemuCapsCache global cache. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/capabilities.h | 1 - src/qemu/qemu_capabilities.c | 228 +++++++++++++------------------------------ src/qemu/qemu_capabilities.h | 7 +- src/qemu/qemu_conf.h | 2 + src/qemu/qemu_driver.c | 15 +-- 5 files changed, 84 insertions(+), 169 deletions(-) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index e43f404..a8694f8 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -53,7 +53,6 @@ struct _virCapsGuestDomainInfo { char *loader; int nmachines; virCapsGuestMachinePtr *machines; - time_t emulator_mtime; /* do @machines need refreshing? */ }; typedef struct _virCapsGuestDomain virCapsGuestDomain; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 4581e60..1e0f46f 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -404,97 +404,6 @@ cleanup: return ret; } -static int -qemuCapsGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info, - const char *emulator, - time_t emulator_mtime, - virCapsGuestMachinePtr **machines, - size_t *nmachines) -{ - virCapsGuestMachinePtr *list; - int i; - - if (!info->nmachines) - return 0; - - if (!info->emulator || !STREQ(emulator, info->emulator)) - return 0; - - if (emulator_mtime != info->emulator_mtime) { - VIR_DEBUG("mtime on %s has changed, refreshing machine types", - info->emulator); - return 0; - } - - if (VIR_ALLOC_N(list, info->nmachines) < 0) { - virReportOOMError(); - return 0; - } - - for (i = 0; i < info->nmachines; i++) { - if (VIR_ALLOC(list[i]) < 0) { - goto no_memory; - } - if (info->machines[i]->name && - !(list[i]->name = strdup(info->machines[i]->name))) { - goto no_memory; - } - if (info->machines[i]->canonical && - !(list[i]->canonical = strdup(info->machines[i]->canonical))) { - goto no_memory; - } - } - - *machines = list; - *nmachines = info->nmachines; - - return 1; - - no_memory: - virReportOOMError(); - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; -} - -static int -qemuCapsGetOldMachines(const char *ostype, - const char *arch, - int wordsize, - const char *emulator, - time_t emulator_mtime, - virCapsPtr old_caps, - virCapsGuestMachinePtr **machines, - size_t *nmachines) -{ - int i; - - for (i = 0; i < old_caps->nguests; i++) { - virCapsGuestPtr guest = old_caps->guests[i]; - int j; - - if (!STREQ(ostype, guest->ostype) || - !STREQ(arch, guest->arch.name) || - wordsize != guest->arch.wordsize) - continue; - - for (j = 0; j < guest->arch.ndomains; j++) { - virCapsGuestDomainPtr dom = guest->arch.domains[j]; - - if (qemuCapsGetOldMachinesFromInfo(&dom->info, - emulator, emulator_mtime, - machines, nmachines)) - return 1; - } - - if (qemuCapsGetOldMachinesFromInfo(&guest->arch.defaultInfo, - emulator, emulator_mtime, - machines, nmachines)) - return 1; - } - - return 0; -} - typedef int (*qemuCapsParseCPUModels)(const char *output, @@ -698,7 +607,7 @@ cleanup: static int qemuCapsInitGuest(virCapsPtr caps, - virCapsPtr old_caps, + qemuCapsCachePtr cache, const char *hostmachine, const struct qemu_arch_info *info, int hvm) @@ -709,11 +618,8 @@ qemuCapsInitGuest(virCapsPtr caps, int haskqemu = 0; char *kvmbin = NULL; char *binary = NULL; - time_t binary_mtime; virCapsGuestMachinePtr *machines = NULL; size_t nmachines = 0; - struct stat st; - size_t ncpus; qemuCapsPtr qemubinCaps = NULL; qemuCapsPtr kvmbinCaps = NULL; int ret = -1; @@ -729,10 +635,12 @@ qemuCapsInitGuest(virCapsPtr caps, } /* Ignore binary if extracting version info fails */ - if (binary && - qemuCapsExtractVersionInfo(binary, info->arch, - false, NULL, &qemubinCaps) < 0) - VIR_FREE(binary); + if (binary) { + if (!(qemubinCaps = qemuCapsCacheLookup(cache, binary))) { + virResetLastError(); + VIR_FREE(binary); + } + } /* qemu-kvm/kvm binaries can only be used if * - host & guest arches match @@ -752,9 +660,8 @@ qemuCapsInitGuest(virCapsPtr caps, if (!kvmbin) continue; - if (qemuCapsExtractVersionInfo(kvmbin, info->arch, - false, NULL, - &kvmbinCaps) < 0) { + if (!(kvmbinCaps = qemuCapsCacheLookup(cache, kvmbin))) { + virResetLastError(); VIR_FREE(kvmbin); continue; } @@ -782,15 +689,6 @@ qemuCapsInitGuest(virCapsPtr caps, qemuCapsGet(qemubinCaps, QEMU_CAPS_KQEMU)) haskqemu = 1; - if (stat(binary, &st) == 0) { - binary_mtime = st.st_mtime; - } else { - char ebuf[1024]; - VIR_WARN("Failed to stat %s, most peculiar : %s", - binary, virStrerror(errno, ebuf, sizeof(ebuf))); - binary_mtime = 0; - } - if (info->machine) { virCapsGuestMachinePtr machine; @@ -813,14 +711,7 @@ qemuCapsInitGuest(virCapsPtr caps, machines[0] = machine; } else { - int probe = 1; - if (old_caps && binary_mtime) - probe = !qemuCapsGetOldMachines(hvm ? "hvm" : "xen", info->arch, - info->wordsize, binary, binary_mtime, - old_caps, &machines, &nmachines); - if (probe && - qemuCapsProbeMachineTypes(binary, qemubinCaps, - &machines, &nmachines) < 0) + if (qemuCapsGetMachineTypesCaps(qemubinCaps, &nmachines, &machines) < 0) goto error; } @@ -839,11 +730,8 @@ qemuCapsInitGuest(virCapsPtr caps, machines = NULL; nmachines = 0; - guest->arch.defaultInfo.emulator_mtime = binary_mtime; - if (caps->host.cpu && - qemuCapsProbeCPUModels(binary, NULL, info->arch, &ncpus, NULL) == 0 && - ncpus > 0 && + qemuCapsGetCPUDefinitions(qemubinCaps, NULL) > 0 && !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0)) goto error; @@ -872,28 +760,9 @@ qemuCapsInitGuest(virCapsPtr caps, if (haskvm) { virCapsGuestDomainPtr dom; - if (kvmbin) { - int probe = 1; - - if (stat(kvmbin, &st) == 0) { - binary_mtime = st.st_mtime; - } else { - char ebuf[1024]; - VIR_WARN("Failed to stat %s, most peculiar : %s", - binary, virStrerror(errno, ebuf, sizeof(ebuf))); - binary_mtime = 0; - } - - if (old_caps && binary_mtime) - probe = !qemuCapsGetOldMachines("hvm", info->arch, - info->wordsize, kvmbin, - binary_mtime, old_caps, - &machines, &nmachines); - if (probe && - qemuCapsProbeMachineTypes(kvmbin, kvmbinCaps, - &machines, &nmachines) < 0) - goto error; - } + if (kvmbin && + qemuCapsGetMachineTypesCaps(kvmbinCaps, &nmachines, &machines) < 0) + goto error; if ((dom = virCapabilitiesAddGuestDomain(guest, "kvm", @@ -907,7 +776,6 @@ qemuCapsInitGuest(virCapsPtr caps, machines = NULL; nmachines = 0; - dom->info.emulator_mtime = binary_mtime; } } else { if (virCapabilitiesAddGuestDomain(guest, @@ -951,7 +819,7 @@ error: static int qemuCapsInitCPU(virCapsPtr caps, - const char *arch) + const char *arch) { virCPUDefPtr cpu = NULL; union cpuData *data = NULL; @@ -997,7 +865,7 @@ static int qemuDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED) } -virCapsPtr qemuCapsInit(virCapsPtr old_caps) +virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) { struct utsname utsname; virCapsPtr caps; @@ -1023,14 +891,8 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps) VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities"); } - if (old_caps == NULL || old_caps->host.cpu == NULL) { - if (qemuCapsInitCPU(caps, utsname.machine) < 0) - VIR_WARN("Failed to get host CPU"); - } - else { - caps->host.cpu = old_caps->host.cpu; - old_caps->host.cpu = NULL; - } + if (qemuCapsInitCPU(caps, utsname.machine) < 0) + VIR_WARN("Failed to get host CPU"); /* Add the power management features of the host */ @@ -1042,7 +904,7 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps) /* First the pure HVM guests */ for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++) - if (qemuCapsInitGuest(caps, old_caps, + if (qemuCapsInitGuest(caps, cache, utsname.machine, &arch_info_hvm[i], 1) < 0) goto no_memory; @@ -1057,7 +919,7 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps) if (STREQ(arch_info_xen[i].arch, utsname.machine) || (STREQ(utsname.machine, "x86_64") && STREQ(arch_info_xen[i].arch, "i686"))) { - if (qemuCapsInitGuest(caps, old_caps, + if (qemuCapsInitGuest(caps, cache, utsname.machine, &arch_info_xen[i], 0) < 0) goto no_memory; @@ -1850,6 +1712,11 @@ qemuCapsGet(qemuCapsPtr caps, } +const char *qemuCapsGetBinary(qemuCapsPtr caps) +{ + return caps->binary; +} + const char *qemuCapsGetArch(qemuCapsPtr caps) { return caps->arch; @@ -1871,7 +1738,8 @@ unsigned int qemuCapsGetKVMVersion(qemuCapsPtr caps) size_t qemuCapsGetCPUDefinitions(qemuCapsPtr caps, char ***names) { - *names = caps->cpuDefinitions; + if (names) + *names = caps->cpuDefinitions; return caps->ncpuDefinitions; } @@ -1879,10 +1747,50 @@ size_t qemuCapsGetCPUDefinitions(qemuCapsPtr caps, size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, char ***names) { - *names = caps->machineTypes; + if (names) + *names = caps->machineTypes; return caps->nmachineTypes; } +int qemuCapsGetMachineTypesCaps(qemuCapsPtr caps, + size_t *nmachines, + virCapsGuestMachinePtr **machines) +{ + size_t i; + + *nmachines = 0; + *machines = NULL; + if (VIR_ALLOC_N(*machines, caps->nmachineTypes) < 0) + goto no_memory; + *nmachines = caps->nmachineTypes; + + for (i = 0 ; i < caps->nmachineTypes ; i++) { + virCapsGuestMachinePtr mach; + if (VIR_ALLOC(mach) < 0) + goto no_memory; + if (caps->machineAliases[i]) { + if (!(mach->name = strdup(caps->machineAliases[i]))) + goto no_memory; + if (!(mach->canonical = strdup(caps->machineTypes[i]))) + goto no_memory; + } else { + if (!(mach->name = strdup(caps->machineTypes[i]))) + goto no_memory; + } + (*machines)[i] = mach; + } + + return 0; + +no_memory: + virCapabilitiesFreeMachines(*machines, *nmachines); + *nmachines = 0; + *machines = NULL; + return -1; +} + + + const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, const char *name) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f9105bb..1efde48 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -168,6 +168,7 @@ bool qemuCapsGet(qemuCapsPtr caps, char *qemuCapsFlagsString(qemuCapsPtr caps); +const char *qemuCapsGetBinary(qemuCapsPtr caps); const char *qemuCapsGetArch(qemuCapsPtr caps); unsigned int qemuCapsGetVersion(qemuCapsPtr caps); unsigned int qemuCapsGetKVMVersion(qemuCapsPtr caps); @@ -178,6 +179,10 @@ size_t qemuCapsGetMachineTypes(qemuCapsPtr caps, const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps, const char *name); +int qemuCapsGetMachineTypesCaps(qemuCapsPtr caps, + size_t *nmachines, + virCapsGuestMachinePtr **machines); + bool qemuCapsIsValid(qemuCapsPtr caps); @@ -186,7 +191,7 @@ qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary); qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary); void qemuCapsCacheFree(qemuCapsCachePtr cache); -virCapsPtr qemuCapsInit(virCapsPtr old_caps); +virCapsPtr qemuCapsInit(qemuCapsCachePtr cache); int qemuCapsProbeMachineTypes(const char *binary, qemuCapsPtr caps, diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index ac285f6..c737e91 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -43,6 +43,7 @@ # include "command.h" # include "threadpool.h" # include "locking/lock_manager.h" +# include "qemu_capabilities.h" # define QEMUD_CPUMASK_LEN CPU_SETSIZE @@ -115,6 +116,7 @@ struct qemud_driver { int max_queued; virCapsPtr caps; + qemuCapsCachePtr capsCache; virDomainEventStatePtr domainEventState; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2bc9101..709b80a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -320,8 +320,7 @@ error: static virCapsPtr -qemuCreateCapabilities(virCapsPtr oldcaps, - struct qemud_driver *driver) +qemuCreateCapabilities(struct qemud_driver *driver) { size_t i; virCapsPtr caps; @@ -330,7 +329,7 @@ qemuCreateCapabilities(virCapsPtr oldcaps, const char *doi, *model; /* Basic host arch / guest machine capabilities */ - if (!(caps = qemuCapsInit(oldcaps))) { + if (!(caps = qemuCapsInit(driver->capsCache))) { virReportOOMError(); return NULL; } @@ -710,8 +709,10 @@ qemudStartup(int privileged) { if (qemuSecurityInit(qemu_driver) < 0) goto error; - if ((qemu_driver->caps = qemuCreateCapabilities(NULL, - qemu_driver)) == NULL) + if ((qemu_driver->capsCache = qemuCapsCacheNew()) == NULL) + goto error; + + if ((qemu_driver->caps = qemuCreateCapabilities(qemu_driver)) == NULL) goto error; if ((qemu_driver->activePciHostdevs = pciDeviceListNew()) == NULL) @@ -927,6 +928,7 @@ qemudShutdown(void) { pciDeviceListFree(qemu_driver->inactivePciHostdevs); usbDeviceListFree(qemu_driver->activeUsbHostdevs); virCapabilitiesFree(qemu_driver->caps); + qemuCapsCacheFree(qemu_driver->capsCache); virDomainObjListDeinit(&qemu_driver->domains); virBitmapFree(qemu_driver->reservedRemotePorts); @@ -1166,8 +1168,7 @@ static char *qemudGetCapabilities(virConnectPtr conn) { qemuDriverLock(driver); - if ((caps = qemuCreateCapabilities(qemu_driver->caps, - qemu_driver)) == NULL) { + if ((caps = qemuCreateCapabilities(qemu_driver)) == NULL) { virCapabilitiesFree(caps); goto cleanup; } -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> Remove all use of the existing APIs for querying QEMU capability flags. Instead obtain a qemuCapsPtr object from the global cache. This avoids the execution of 'qemu -help' (and related commands) when launching new guests. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 92 ++++---------------------------------------- src/qemu/qemu_capabilities.h | 11 ++---- src/qemu/qemu_command.c | 85 +++++++++------------------------------- src/qemu/qemu_command.h | 3 +- src/qemu/qemu_driver.c | 63 +++++++++++++++++++++--------- src/qemu/qemu_process.c | 21 +++------- tests/qemuxml2argvtest.c | 4 -- tests/qemuxmlnstest.c | 4 -- 8 files changed, 81 insertions(+), 202 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 1e0f46f..f9a1dd5 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1445,79 +1445,6 @@ qemuCapsParseDeviceStr(const char *str, qemuCapsPtr caps) return 0; } -int qemuCapsExtractVersionInfo(const char *qemu, - const char *arch, - bool check_yajl, - unsigned int *retversion, - qemuCapsPtr *retcaps) -{ - int ret = -1; - unsigned int version, is_kvm, kvm_version; - qemuCapsPtr caps = NULL; - char *help = NULL; - virCommandPtr cmd; - - if (retcaps) - *retcaps = NULL; - if (retversion) - *retversion = 0; - - /* Make sure the binary we are about to try exec'ing exists. - * Technically we could catch the exec() failure, but that's - * in a sub-process so it's hard to feed back a useful error. - */ - if (!virFileIsExecutable(qemu)) { - virReportSystemError(errno, _("Cannot find QEMU binary %s"), qemu); - return -1; - } - - cmd = qemuCapsProbeCommand(qemu, NULL); - virCommandAddArgList(cmd, "-help", NULL); - virCommandSetOutputBuffer(cmd, &help); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - if (!(caps = qemuCapsNew()) || - qemuCapsParseHelpStr(qemu, help, caps, - &version, &is_kvm, &kvm_version, - check_yajl) == -1) - goto cleanup; - - /* Currently only x86_64 and i686 support PCI-multibus. */ - if (STREQLEN(arch, "x86_64", 6) || - STREQLEN(arch, "i686", 4)) { - qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS); - } - - /* S390 and probably other archs do not support no-acpi - - maybe the qemu option parsing should be re-thought. */ - if (STRPREFIX(arch, "s390")) - qemuCapsClear(caps, QEMU_CAPS_NO_ACPI); - - /* qemuCapsExtractDeviceStr will only set additional caps if qemu - * understands the 0.13.0+ notion of "-device driver,". */ - if (qemuCapsGet(caps, QEMU_CAPS_DEVICE) && - strstr(help, "-device driver,?") && - qemuCapsExtractDeviceStr(qemu, caps) < 0) - goto cleanup; - - if (retversion) - *retversion = version; - if (retcaps) { - *retcaps = caps; - caps = NULL; - } - - ret = 0; - -cleanup: - VIR_FREE(help); - virCommandFree(cmd); - virObjectUnref(caps); - - return ret; -} static void uname_normalize (struct utsname *ut) @@ -1533,12 +1460,13 @@ uname_normalize (struct utsname *ut) ut->machine[1] = '6'; } -int qemuCapsExtractVersion(virCapsPtr caps, - unsigned int *version) +int qemuCapsGetDefaultVersion(virCapsPtr caps, + qemuCapsCachePtr capsCache, + unsigned int *version) { const char *binary; - struct stat sb; struct utsname ut; + qemuCapsPtr qemucaps; if (*version > 0) return 0; @@ -1553,17 +1481,11 @@ int qemuCapsExtractVersion(virCapsPtr caps, return -1; } - if (stat(binary, &sb) < 0) { - virReportSystemError(errno, - _("Cannot find QEMU binary %s"), binary); - return -1; - } - - if (qemuCapsExtractVersionInfo(binary, ut.machine, false, - version, NULL) < 0) { + if (!(qemucaps = qemuCapsCacheLookup(capsCache, binary))) return -1; - } + *version = qemuCapsGetVersion(qemucaps); + virObjectUnref(qemucaps); return 0; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 1efde48..9d36726 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -27,6 +27,7 @@ # include "virobject.h" # include "capabilities.h" # include "command.h" +# include "virobject.h" /* Internal flags to keep track of qemu command line capabilities */ enum qemuCapsFlags { @@ -204,13 +205,9 @@ int qemuCapsProbeCPUModels(const char *qemu, size_t *count, const char ***cpus); -int qemuCapsExtractVersion(virCapsPtr caps, - unsigned int *version); -int qemuCapsExtractVersionInfo(const char *qemu, - const char *arch, - bool check_yajl, - unsigned int *version, - qemuCapsPtr *retcaps); +int qemuCapsGetDefaultVersion(virCapsPtr caps, + qemuCapsCachePtr capsCache, + unsigned int *version); int qemuCapsParseHelpStr(const char *qemu, const char *str, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ea0b275..2be6aa8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -810,33 +810,13 @@ qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, } -static int +static void qemuDomainAssignS390Addresses(virDomainDefPtr def, qemuCapsPtr caps) { - int ret = -1; - qemuCapsPtr localCaps = NULL; - - if (!caps) { - /* need to get information from real environment */ - if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, - false, NULL, - &localCaps) < 0) - goto cleanup; - caps = localCaps; - } - - if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390)) { - /* deal with legacy virtio-s390 */ + /* deal with legacy virtio-s390 */ + if (qemuCapsGet(caps, QEMU_CAPS_VIRTIO_S390)) qemuDomainPrimeS390VirtioDevices( def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390); - } - - ret = 0; - -cleanup: - virObjectUnref(localCaps); - - return ret; } static int @@ -863,7 +843,7 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, unsigned long long default_reg) { bool user_reg; - int rc; + int ret; if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) return 0; @@ -875,8 +855,8 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, info->addr.spaprvio.has_reg = true; } - rc = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info); - while (rc != 0) { + ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info); + while (ret != 0) { if (user_reg) { virReportError(VIR_ERR_XML_ERROR, _("spapr-vio address %#llx already in use"), @@ -886,7 +866,7 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, /* We assigned the reg, so try a new value */ info->addr.spaprvio.reg += 0x1000; - rc = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info); + ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info); } return 0; @@ -895,45 +875,32 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, qemuCapsPtr caps) { - int i, rc = -1; + int i, ret = -1; int model; - qemuCapsPtr localCaps = NULL; /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */ - if (!caps) { - /* need to get information from real environment */ - if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, - false, NULL, - &localCaps) < 0) - goto cleanup; - caps = localCaps; - } - for (i = 0 ; i < def->nnets; i++) { if (def->nets[i]->model && STREQ(def->nets[i]->model, "spapr-vlan")) def->nets[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; - rc = qemuAssignSpaprVIOAddress(def, &def->nets[i]->info, - 0x1000ul); - if (rc) + if (qemuAssignSpaprVIOAddress(def, &def->nets[i]->info, + 0x1000ul) < 0) goto cleanup; } for (i = 0 ; i < def->ncontrollers; i++) { model = def->controllers[i]->model; if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { - rc = qemuSetScsiControllerModel(def, caps, &model); - if (rc) + if (qemuSetScsiControllerModel(def, caps, &model) < 0) goto cleanup; } if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI && def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; - rc = qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info, - 0x2000ul); - if (rc) + if (qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info, + 0x2000ul) < 0) goto cleanup; } @@ -943,19 +910,17 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, STREQ(def->os.arch, "ppc64") && STREQ(def->os.machine, "pseries")) def->serials[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; - rc = qemuAssignSpaprVIOAddress(def, &def->serials[i]->info, - 0x30000000ul); - if (rc) + if (qemuAssignSpaprVIOAddress(def, &def->serials[i]->info, + 0x30000000ul) < 0) goto cleanup; } /* No other devices are currently supported on spapr-vio */ - rc = 0; + ret = 0; cleanup: - virObjectUnref(localCaps); - return rc; + return ret; } #define QEMU_PCI_ADDRESS_LAST_SLOT 31 @@ -1069,20 +1034,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, virDomainObjPtr obj) { int ret = -1; - qemuCapsPtr localCaps = NULL; qemuDomainPCIAddressSetPtr addrs = NULL; qemuDomainObjPrivatePtr priv = NULL; - if (!caps) { - /* need to get information from real environment */ - if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, - false, - NULL, - &localCaps) < 0) - goto cleanup; - caps = localCaps; - } - if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) { if (!(addrs = qemuDomainPCIAddressSetCreate(def))) goto cleanup; @@ -1107,7 +1061,6 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, ret = 0; cleanup: - virObjectUnref(localCaps); qemuDomainPCIAddressSetFree(addrs); return ret; @@ -1123,9 +1076,7 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, if (rc) return rc; - rc = qemuDomainAssignS390Addresses(def, caps); - if (rc) - return rc; + qemuDomainAssignS390Addresses(def, caps); return qemuDomainAssignPCIAddresses(def, caps, obj); } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index e155583..97c87a8 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -187,7 +187,8 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, int qemuDomainAssignAddresses(virDomainDefPtr def, qemuCapsPtr caps, - virDomainObjPtr); + virDomainObjPtr obj) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, qemuCapsPtr caps); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 709b80a..3f2fab3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1417,7 +1417,9 @@ static int qemudGetVersion(virConnectPtr conn, unsigned long *version) { int ret = -1; qemuDriverLock(driver); - if (qemuCapsExtractVersion(driver->caps, &driver->qemuVersion) < 0) + if (qemuCapsGetDefaultVersion(driver->caps, + driver->capsCache, + &driver->qemuVersion) < 0) goto cleanup; *version = driver->qemuVersion; @@ -1459,6 +1461,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, virDomainEventPtr event = NULL; virDomainEventPtr event2 = NULL; unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD; + qemuCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_START_PAUSED | VIR_DOMAIN_START_AUTODESTROY, NULL); @@ -1480,10 +1483,13 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; + if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) + goto cleanup; + if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(def, caps, NULL) < 0) goto cleanup; if (!(vm = virDomainAssignDef(driver->caps, @@ -1537,6 +1543,7 @@ cleanup: if (event2) qemuDomainEventQueue(driver, event2); } + virObjectUnref(caps); qemuDriverUnlock(driver); return dom; } @@ -5155,6 +5162,9 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, if (!def) goto cleanup; + if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) + goto cleanup; + /* Since we're just exporting args, we can't do bridge/network/direct * setups, since libvirt will normally create TAP/macvtap devices * directly. We convert those configs into generic 'ethernet' @@ -5223,12 +5233,6 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, net->info.bootIndex = bootIndex; } - if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, - false, - NULL, - &caps) < 0) - goto cleanup; - monitor_json = qemuCapsGet(caps, QEMU_CAPS_MONITOR_JSON); if (qemuProcessPrepareMonitorChr(driver, &monConfig, def->name) < 0) @@ -5522,6 +5526,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; virDomainEventPtr event = NULL; + qemuCapsPtr caps = NULL; int dupVM; qemuDriverLock(driver); @@ -5536,10 +5541,13 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0) goto cleanup; + if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) + goto cleanup; + if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(def, caps, NULL) < 0) goto cleanup; /* We need to differentiate two cases: @@ -5602,6 +5610,7 @@ cleanup: virDomainObjUnlock(vm); if (event) qemuDomainEventQueue(driver, event); + virObjectUnref(caps); qemuDriverUnlock(driver); return dom; } @@ -6020,7 +6029,8 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm, } static int -qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, +qemuDomainAttachDeviceConfig(qemuCapsPtr caps, + virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk; @@ -6046,7 +6056,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) if (virDomainDefAddImplicitControllers(vmdef) < 0) return -1; - if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(vmdef, caps, NULL) < 0) return -1; break; @@ -6065,7 +6075,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, return -1; } dev->data.net = NULL; - if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(vmdef, caps, NULL) < 0) return -1; break; @@ -6081,7 +6091,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, return -1; } dev->data.hostdev = NULL; - if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(vmdef, caps, NULL) < 0) return -1; break; @@ -6113,7 +6123,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, return -1; dev->data.controller = NULL; - if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(vmdef, caps, NULL) < 0) return -1; break; @@ -6206,7 +6216,8 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, } static int -qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, +qemuDomainUpdateDeviceConfig(qemuCapsPtr caps, + virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr orig, disk; @@ -6266,7 +6277,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, vmdef->nets[pos] = net; dev->data.net = NULL; - if (qemuDomainAssignAddresses(vmdef, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(vmdef, caps, NULL) < 0) return -1; break; @@ -6297,6 +6308,8 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0; int ret = -1; unsigned int affect; + qemuCapsPtr caps = NULL; + qemuDomainObjPrivatePtr priv; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -6314,6 +6327,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } + priv = vm->privateData; if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -6355,6 +6369,11 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, goto endjob; } + if (priv->caps) + caps = virObjectRef(priv->caps); + else if (!(caps = qemuCapsCacheLookup(driver->capsCache, vm->def->emulator))) + goto cleanup; + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { if (virDomainDefCompatibleDevice(vm->def, dev) < 0) goto endjob; @@ -6365,13 +6384,13 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, goto endjob; switch (action) { case QEMU_DEVICE_ATTACH: - ret = qemuDomainAttachDeviceConfig(vmdef, dev); + ret = qemuDomainAttachDeviceConfig(caps, vmdef, dev); break; case QEMU_DEVICE_DETACH: ret = qemuDomainDetachDeviceConfig(vmdef, dev); break; case QEMU_DEVICE_UPDATE: - ret = qemuDomainUpdateDeviceConfig(vmdef, dev); + ret = qemuDomainUpdateDeviceConfig(caps, vmdef, dev); break; default: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -6431,6 +6450,7 @@ endjob: vm = NULL; cleanup: + virObjectUnref(caps); virDomainDefFree(vmdef); if (dev != dev_copy) virDomainDeviceDefFree(dev_copy); @@ -12388,6 +12408,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, bool monJSON = false; pid_t pid = pid_value; char *pidfile = NULL; + qemuCapsPtr caps = NULL; virCheckFlags(0, NULL); @@ -12417,13 +12438,16 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, goto cleanup; } + if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) + goto cleanup; + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; - if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) + if (qemuDomainAssignAddresses(def, caps, NULL) < 0) goto cleanup; if (!(vm = virDomainAssignDef(driver->caps, @@ -12455,6 +12479,7 @@ endjob: cleanup: virDomainDefFree(def); + virObjectUnref(caps); virDomainChrSourceDefFree(monConfig); if (vm) virDomainObjUnlock(vm); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 5ac1d2b..bb56611 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3164,10 +3164,8 @@ qemuProcessReconnect(void *opaque) * caps in the domain status, so re-query them */ if (!priv->caps && - qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch, - false, - NULL, - &priv->caps) < 0) + !(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache, + obj->def->emulator))) goto error; /* In case the domain shutdown while we were not running, @@ -3564,11 +3562,8 @@ int qemuProcessStart(virConnectPtr conn, VIR_DEBUG("Determining emulator version"); virObjectUnref(priv->caps); - priv->caps = NULL; - if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, - true, - NULL, - &priv->caps) < 0) + if (!(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache, + vm->def->emulator))) goto cleanup; if (qemuAssignDeviceAliases(vm->def, priv->caps) < 0) @@ -4334,12 +4329,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_DEBUG("Determining emulator version"); virObjectUnref(priv->caps); - priv->caps = NULL; - if (qemuCapsExtractVersionInfo(vm->def->emulator, - vm->def->os.arch, - false, - NULL, - &priv->caps) < 0) + if (!(priv->caps = qemuCapsCacheLookupCopy(driver->capsCache, + vm->def->emulator))) goto cleanup; VIR_DEBUG("Preparing monitor state"); diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 11b9aab..51676a4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -157,10 +157,6 @@ static int testCompareXMLToArgvFiles(const char *xml, VIR_FREE(log); virResetLastError(); - /* We do not call qemuCapsExtractVersionInfo() before calling - * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for - * x86_64 and i686 architectures here. - */ if (STREQLEN(vmdef->os.arch, "x86_64", 6) || STREQLEN(vmdef->os.arch, "i686", 4)) { qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c index 43b5fe6..dd56091 100644 --- a/tests/qemuxmlnstest.c +++ b/tests/qemuxmlnstest.c @@ -102,10 +102,6 @@ static int testCompareXMLToArgvFiles(const char *xml, VIR_FREE(log); virResetLastError(); - /* We do not call qemuCapsExtractVersionInfo() before calling - * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for - * x86_64 and i686 architectures here. - */ if (STREQLEN(vmdef->os.arch, "x86_64", 6) || STREQLEN(vmdef->os.arch, "i686", 4)) { qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> If reporting case of a binary not supporting KVM or kQEMU, libvirt forgot to jump to the error branch for cleanup --- src/qemu/qemu_command.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 2be6aa8..3290de0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4340,6 +4340,7 @@ qemuBuildCommandLine(virConnectPtr conn, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("the QEMU binary %s does not support kqemu"), emulator); + goto error; } break; @@ -4353,6 +4354,7 @@ qemuBuildCommandLine(virConnectPtr conn, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("the QEMU binary %s does not support kvm"), emulator); + goto error; } break; -- 1.7.11.4

On 09/11/2012 08:11 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
If reporting case of a binary not supporting KVM or kQEMU, libvirt forgot to jump to the error branch for cleanup --- src/qemu/qemu_command.c | 2 ++ 1 file changed, 2 insertions(+)
ACK; practically trivial. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> When XML for a new guest is received, the machine type is immediately canonicalized into the version specific name. This involves probing QEMU for supported machine types. Replace this probing with a lookup of the machine types in the (hopefully cached) qemuCapsPtr object Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_command.h | 3 -- src/qemu/qemu_driver.c | 133 ++++++++--------------------------------------- tests/qemuxml2argvtest.c | 12 ++++- tests/qemuxmlnstest.c | 3 -- 4 files changed, 33 insertions(+), 118 deletions(-) diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 97c87a8..253f65a 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -161,9 +161,6 @@ int qemuOpenVhostNet(virDomainDefPtr def, qemuCapsPtr caps, int *vhostfd); -int qemudCanonicalizeMachine(struct qemud_driver *driver, - virDomainDefPtr def); - /* * NB: def->name can be NULL upon return and the caller * *must* decide how to fill in a name in this case diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3f2fab3..10af8ed 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1452,6 +1452,26 @@ static int qemudNumDomains(virConnectPtr conn) { return n; } + +static int +qemuCanonicalizeMachine(virDomainDefPtr def, qemuCapsPtr caps) +{ + const char *canon = qemuCapsGetCanonicalMachine(caps, def->os.machine); + + if (canon != def->os.machine) { + char *tmp; + if (!(tmp = strdup(canon))) { + virReportOOMError(); + return -1; + } + VIR_FREE(def->os.machine); + def->os.machine = tmp; + } + + return 0; +} + + static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, unsigned int flags) { struct qemud_driver *driver = conn->privateData; @@ -1486,7 +1506,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) goto cleanup; - if (qemudCanonicalizeMachine(driver, def) < 0) + if (qemuCanonicalizeMachine(def, caps) < 0) goto cleanup; if (qemuDomainAssignAddresses(def, caps, NULL) < 0) @@ -5412,113 +5432,6 @@ qemuDomainStart(virDomainPtr dom) return qemuDomainStartWithFlags(dom, 0); } -static int -qemudCanonicalizeMachineFromInfo(virDomainDefPtr def, - virCapsGuestDomainInfoPtr info, - char **canonical) -{ - int i; - - *canonical = NULL; - - for (i = 0; i < info->nmachines; i++) { - virCapsGuestMachinePtr machine = info->machines[i]; - - if (!machine->canonical) - continue; - - if (def->os.machine && STRNEQ(def->os.machine, machine->name)) - continue; - - if (!(*canonical = strdup(machine->canonical))) { - virReportOOMError(); - return -1; - } - - break; - } - - return 0; -} - -static int -qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical) -{ - virCapsGuestMachinePtr *machines = NULL; - size_t i, nmachines = 0; - - /* XXX we should be checking emulator capabilities and pass them instead - * of NULL so that -nodefconfig or -no-user-config is properly added when - * probing machine types. Luckily, qemu does not support specifying new - * machine types in its configuration files yet, which means passing this - * additional parameter makes no difference now. - */ - if (qemuCapsProbeMachineTypes(def->emulator, NULL, - &machines, &nmachines) < 0) - return -1; - - for (i = 0; i < nmachines; i++) { - if (!machines[i]->canonical) - continue; - - if (def->os.machine && STRNEQ(def->os.machine, machines[i]->name)) - continue; - - *canonical = machines[i]->canonical; - machines[i]->canonical = NULL; - break; - } - - virCapabilitiesFreeMachines(machines, nmachines); - - return 0; -} - -int -qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def) -{ - char *canonical = NULL; - int i; - - for (i = 0; i < driver->caps->nguests; i++) { - virCapsGuestPtr guest = driver->caps->guests[i]; - virCapsGuestDomainInfoPtr info; - int j; - - for (j = 0; j < guest->arch.ndomains; j++) { - info = &guest->arch.domains[j]->info; - - if (!info->emulator || !STREQ(info->emulator, def->emulator)) - continue; - - if (!info->nmachines) - info = &guest->arch.defaultInfo; - - if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0) - return -1; - goto out; - } - - info = &guest->arch.defaultInfo; - - if (info->emulator && STREQ(info->emulator, def->emulator)) { - if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0) - return -1; - goto out; - } - } - - if (qemudCanonicalizeMachineDirect(def, &canonical) < 0) - return -1; - -out: - if (canonical) { - VIR_FREE(def->os.machine); - def->os.machine = canonical; - } - return 0; -} - static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { struct qemud_driver *driver = conn->privateData; virDomainDefPtr def; @@ -5544,7 +5457,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator))) goto cleanup; - if (qemudCanonicalizeMachine(driver, def) < 0) + if (qemuCanonicalizeMachine(def, caps) < 0) goto cleanup; if (qemuDomainAssignAddresses(def, caps, NULL) < 0) @@ -12444,7 +12357,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; - if (qemudCanonicalizeMachine(driver, def) < 0) + if (qemuCanonicalizeMachine(def, caps) < 0) goto cleanup; if (qemuDomainAssignAddresses(def, caps, NULL) < 0) diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 51676a4..0f61fd5 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -142,8 +142,12 @@ static int testCompareXMLToArgvFiles(const char *xml, QEMU_CAPS_NO_ACPI, QEMU_CAPS_LAST); - if (qemudCanonicalizeMachine(&driver, vmdef) < 0) - goto out; + if (STREQ(vmdef->os.machine, "pc") && + STREQ(vmdef->emulator, "/usr/bin/qemu-system-x86_64")) { + VIR_FREE(vmdef->os.machine); + if (!(vmdef->os.machine = strdup("pc-0.11"))) + goto out; + } if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) { if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) { @@ -157,6 +161,10 @@ static int testCompareXMLToArgvFiles(const char *xml, VIR_FREE(log); virResetLastError(); + /* We do not call qemuCapsExtractVersionInfo() before calling + * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for + * x86_64 and i686 architectures here. + */ if (STREQLEN(vmdef->os.arch, "x86_64", 6) || STREQLEN(vmdef->os.arch, "i686", 4)) { qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c index dd56091..3b06539 100644 --- a/tests/qemuxmlnstest.c +++ b/tests/qemuxmlnstest.c @@ -92,9 +92,6 @@ static int testCompareXMLToArgvFiles(const char *xml, QEMU_CAPS_NO_ACPI, QEMU_CAPS_LAST); - if (qemudCanonicalizeMachine(&driver, vmdef) < 0) - goto fail; - if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) qemuDomainAssignAddresses(vmdef, extraFlags, NULL); -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> When launching a QEMU guest the binary is probed to discover the list of supported CPU names. Remove this probing with a simple lookup of CPU models in the qemuCapsPtr object. This avoids another invocation of the QEMU binary during the startup path. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_command.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3290de0..6d14156 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3992,7 +3992,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, virCPUDefPtr guest = NULL; virCPUDefPtr cpu = NULL; size_t ncpus = 0; - const char **cpus = NULL; + char **cpus = NULL; const char *default_model; union cpuData *data = NULL; bool have_cpu = false; @@ -4014,12 +4014,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, const char *preferred; int hasSVM; - if (host && - qemuCapsProbeCPUModels(emulator, caps, host->arch, - &ncpus, &cpus) < 0) - goto cleanup; - - if (!ncpus || !host) { + if (!host || + (ncpus = qemuCapsGetCPUDefinitions(caps, &cpus)) == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("CPU specification not supported by hypervisor")); goto cleanup; @@ -4088,7 +4084,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, guest->type = VIR_CPU_TYPE_GUEST; guest->fallback = cpu->fallback; - if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0) + if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0) goto cleanup; virBufferAdd(&buf, guest->model, -1); @@ -4157,12 +4153,6 @@ cleanup: virCPUDefFree(guest); virCPUDefFree(cpu); - if (cpus) { - for (i = 0; i < ncpus; i++) - VIR_FREE(cpus[i]); - VIR_FREE(cpus); - } - return ret; no_memory: -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> The qemuCapsProbeMachineTypes & qemuCapsProbeCPUModels methods do not need to be invoked directly anymore. Make them static and refactor them to directly populate the qemuCapsPtr object Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 238 ++++++++++++++++--------------------------- src/qemu/qemu_capabilities.h | 13 +-- 2 files changed, 90 insertions(+), 161 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f9a1dd5..a5c25cb 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -298,17 +298,16 @@ qemuCapsProbeCommand(const char *qemu, */ static int qemuCapsParseMachineTypesStr(const char *output, - virCapsGuestMachinePtr **machines, - size_t *nmachines) + qemuCapsPtr caps) { const char *p = output; const char *next; - virCapsGuestMachinePtr *list = NULL; - int nitems = 0; + size_t defIdx = 0; do { const char *t; - virCapsGuestMachinePtr machine; + char *name; + char *canonical = NULL; if ((next = strchr(p, '\n'))) ++next; @@ -319,56 +318,61 @@ qemuCapsParseMachineTypesStr(const char *output, if (!(t = strchr(p, ' ')) || (next && t >= next)) continue; - if (VIR_ALLOC(machine) < 0) + if (!(name = strndup(p, t - p))) goto no_memory; - if (!(machine->name = strndup(p, t - p))) { - VIR_FREE(machine); - goto no_memory; - } - - if (VIR_REALLOC_N(list, nitems + 1) < 0) { - VIR_FREE(machine->name); - VIR_FREE(machine); - goto no_memory; - } - - p = t; - if (!(t = strstr(p, "(default)")) || (next && t >= next)) { - list[nitems++] = machine; - } else { - /* put the default first in the list */ - memmove(list + 1, list, sizeof(*list) * nitems); - list[0] = machine; - nitems++; - } + if (strstr(p, "(default)")) + defIdx = caps->nmachineTypes; if ((t = strstr(p, "(alias of ")) && (!next || t < next)) { p = t + strlen("(alias of "); if (!(t = strchr(p, ')')) || (next && t >= next)) continue; - if (!(machine->canonical = strndup(p, t - p))) + if (!(canonical = strndup(p, t - p))) { + VIR_FREE(name); goto no_memory; + } + } + + if (VIR_REALLOC_N(caps->machineTypes, caps->nmachineTypes + 1) < 0 || + VIR_REALLOC_N(caps->machineAliases, caps->nmachineTypes + 1) < 0) { + VIR_FREE(name); + VIR_FREE(canonical); + goto no_memory; + } + caps->nmachineTypes++; + if (canonical) { + caps->machineTypes[caps->nmachineTypes-1] = canonical; + caps->machineAliases[caps->nmachineTypes-1] = name; + } else { + caps->machineTypes[caps->nmachineTypes-1] = name; } } while ((p = next)); - *machines = list; - *nmachines = nitems; + + if (defIdx != 0) { + char *name = caps->machineTypes[defIdx]; + char *alias = caps->machineAliases[defIdx]; + memmove(caps->machineTypes + 1, + caps->machineTypes, + sizeof(caps->machineTypes[0]) * defIdx); + memmove(caps->machineAliases + 1, + caps->machineAliases, + sizeof(caps->machineAliases[0]) * defIdx); + caps->machineTypes[0] = name; + caps->machineAliases[0] = alias; + } return 0; no_memory: virReportOOMError(); - virCapabilitiesFreeMachines(list, nitems); return -1; } -int -qemuCapsProbeMachineTypes(const char *binary, - qemuCapsPtr caps, - virCapsGuestMachinePtr **machines, - size_t *nmachines) +static int +qemuCapsProbeMachineTypes(qemuCapsPtr caps) { char *output; int ret = -1; @@ -379,12 +383,13 @@ qemuCapsProbeMachineTypes(const char *binary, * Technically we could catch the exec() failure, but that's * in a sub-process so it's hard to feed back a useful error. */ - if (!virFileIsExecutable(binary)) { - virReportSystemError(errno, _("Cannot find QEMU binary %s"), binary); + if (!virFileIsExecutable(caps->binary)) { + virReportSystemError(errno, _("Cannot find QEMU binary %s"), + caps->binary); return -1; } - cmd = qemuCapsProbeCommand(binary, caps); + cmd = qemuCapsProbeCommand(caps->binary, caps); virCommandAddArgList(cmd, "-M", "?", NULL); virCommandSetOutputBuffer(cmd, &output); @@ -392,7 +397,7 @@ qemuCapsProbeMachineTypes(const char *binary, if (virCommandRun(cmd, &status) < 0) goto cleanup; - if (qemuCapsParseMachineTypesStr(output, machines, nmachines) < 0) + if (qemuCapsParseMachineTypesStr(output, caps) < 0) goto cleanup; ret = 0; @@ -407,8 +412,7 @@ cleanup: typedef int (*qemuCapsParseCPUModels)(const char *output, - size_t *retcount, - const char ***retcpus); + qemuCapsPtr caps); /* Format: * <arch> <model> @@ -417,17 +421,15 @@ typedef int */ static int qemuCapsParseX86Models(const char *output, - size_t *retcount, - const char ***retcpus) + qemuCapsPtr caps) { const char *p = output; const char *next; - unsigned int count = 0; - const char **cpus = NULL; - int i; + int ret = -1; do { const char *t; + size_t len; if ((next = strchr(p, '\n'))) next++; @@ -445,47 +447,31 @@ qemuCapsParseX86Models(const char *output, if (*p == '\0' || *p == '\n') continue; - if (retcpus) { - unsigned int len; - - if (VIR_REALLOC_N(cpus, count + 1) < 0) { - virReportOOMError(); - goto error; - } + if (VIR_EXPAND_N(caps->cpuDefinitions, caps->ncpuDefinitions, 1) < 0) { + virReportOOMError(); + goto cleanup; + } - if (next) - len = next - p - 1; - else - len = strlen(p); + if (next) + len = next - p - 1; + else + len = strlen(p); - if (len > 2 && *p == '[' && p[len - 1] == ']') { - p++; - len -= 2; - } + if (len > 2 && *p == '[' && p[len - 1] == ']') { + p++; + len -= 2; + } - if (!(cpus[count] = strndup(p, len))) { - virReportOOMError(); - goto error; - } + if (!(caps->cpuDefinitions[caps->ncpuDefinitions - 1] = strndup(p, len))) { + virReportOOMError(); + goto cleanup; } - count++; } while ((p = next)); - if (retcount) - *retcount = count; - if (retcpus) - *retcpus = cpus; - - return 0; - -error: - if (cpus) { - for (i = 0; i < count; i++) - VIR_FREE(cpus[i]); - } - VIR_FREE(cpus); + ret = 0; - return -1; +cleanup: + return ret; } /* ppc64 parser. @@ -493,17 +479,15 @@ error: */ static int qemuCapsParsePPCModels(const char *output, - size_t *retcount, - const char ***retcpus) + qemuCapsPtr caps) { const char *p = output; const char *next; - unsigned int count = 0; - const char **cpus = NULL; - int i, ret = -1; + int ret = -1; do { const char *t; + size_t len; if ((next = strchr(p, '\n'))) next++; @@ -524,75 +508,52 @@ qemuCapsParsePPCModels(const char *output, if (*p == '\n') continue; - if (retcpus) { - unsigned int len; - - if (VIR_REALLOC_N(cpus, count + 1) < 0) { - virReportOOMError(); - goto cleanup; - } + if (VIR_EXPAND_N(caps->cpuDefinitions, caps->ncpuDefinitions, 1) < 0) { + virReportOOMError(); + goto cleanup; + } - len = t - p - 1; + len = t - p - 1; - if (!(cpus[count] = strndup(p, len))) { - virReportOOMError(); - goto cleanup; - } + if (!(caps->cpuDefinitions[caps->ncpuDefinitions - 1] = strndup(p, len))) { + virReportOOMError(); + goto cleanup; } - count++; } while ((p = next)); - if (retcount) - *retcount = count; - if (retcpus) { - *retcpus = cpus; - cpus = NULL; - } ret = 0; cleanup: - if (cpus) { - for (i = 0; i < count; i++) - VIR_FREE(cpus[i]); - VIR_FREE(cpus); - } return ret; } -int -qemuCapsProbeCPUModels(const char *qemu, - qemuCapsPtr caps, - const char *arch, - size_t *count, - const char ***cpus) +static int +qemuCapsProbeCPUModels(qemuCapsPtr caps) { char *output = NULL; int ret = -1; qemuCapsParseCPUModels parse; virCommandPtr cmd; - if (count) - *count = 0; - if (cpus) - *cpus = NULL; - - if (STREQ(arch, "i686") || STREQ(arch, "x86_64")) + if (STREQ(caps->arch, "i686") || + STREQ(caps->arch, "x86_64")) parse = qemuCapsParseX86Models; - else if (STREQ(arch, "ppc64")) + else if (STREQ(caps->arch, "ppc64")) parse = qemuCapsParsePPCModels; else { - VIR_DEBUG("don't know how to parse %s CPU models", arch); + VIR_DEBUG("don't know how to parse %s CPU models", + caps->arch); return 0; } - cmd = qemuCapsProbeCommand(qemu, caps); + cmd = qemuCapsProbeCommand(caps->binary, caps); virCommandAddArgList(cmd, "-cpu", "?", NULL); virCommandSetOutputBuffer(cmd, &output); if (virCommandRun(cmd, NULL) < 0) goto cleanup; - if (parse(output, count, cpus) < 0) + if (parse(output, caps) < 0) goto cleanup; ret = 0; @@ -1741,9 +1702,6 @@ qemuCapsPtr qemuCapsNewForBinary(const char *binary) unsigned int is_kvm; char *help = NULL; virCommandPtr cmd = NULL; - virCapsGuestMachinePtr *machines = NULL; - size_t nmachines; - size_t i; struct stat sb; if (!(caps->binary = strdup(binary))) @@ -1818,31 +1776,12 @@ qemuCapsPtr qemuCapsNewForBinary(const char *binary) qemuCapsExtractDeviceStr(binary, caps) < 0) goto error; - if (qemuCapsProbeCPUModels(binary, caps, caps->arch, - &caps->ncpuDefinitions, - (const char ***)&caps->cpuDefinitions) < 0) + if (qemuCapsProbeCPUModels(caps) < 0) goto error; - if (qemuCapsProbeMachineTypes(binary, caps, - &machines, &nmachines) < 0) + if (qemuCapsProbeMachineTypes(caps) < 0) goto error; - if (VIR_ALLOC_N(caps->machineTypes, nmachines) < 0) - goto no_memory; - if (VIR_ALLOC_N(caps->machineAliases, nmachines) < 0) - goto no_memory; - caps->nmachineTypes = nmachines; - - for (i = 0 ; i < caps->nmachineTypes ; i++) { - if (machines[i]->canonical) { - caps->machineTypes[i] = machines[i]->canonical; - caps->machineAliases[i] = machines[i]->name; - } else { - caps->machineTypes[i] = machines[i]->name; - } - } - VIR_FREE(machines); - cleanup: VIR_FREE(help); virCommandFree(cmd); @@ -1851,7 +1790,6 @@ cleanup: no_memory: virReportOOMError(); error: - virCapabilitiesFreeMachines(machines, nmachines); virObjectUnref(caps); caps = NULL; goto cleanup; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 9d36726..2847879 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -194,21 +194,11 @@ void qemuCapsCacheFree(qemuCapsCachePtr cache); virCapsPtr qemuCapsInit(qemuCapsCachePtr cache); -int qemuCapsProbeMachineTypes(const char *binary, - qemuCapsPtr caps, - virCapsGuestMachinePtr **machines, - size_t *nmachines); - -int qemuCapsProbeCPUModels(const char *qemu, - qemuCapsPtr caps, - const char *arch, - size_t *count, - const char ***cpus); - int qemuCapsGetDefaultVersion(virCapsPtr caps, qemuCapsCachePtr capsCache, unsigned int *version); +/* Only for use by test suite */ int qemuCapsParseHelpStr(const char *qemu, const char *str, qemuCapsPtr caps, @@ -216,6 +206,7 @@ int qemuCapsParseHelpStr(const char *qemu, unsigned int *is_kvm, unsigned int *kvm_version, bool check_yajl); +/* Only for use by test suite */ int qemuCapsParseDeviceStr(const char *str, qemuCapsPtr caps); -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 158 +++++++++++++------------------------------ 1 file changed, 47 insertions(+), 111 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a5c25cb..0422a15 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -229,7 +229,6 @@ struct qemu_feature_flags { struct qemu_arch_info { const char *arch; int wordsize; - const char *machine; const char *binary; const char *altbinary; const struct qemu_feature_flags *flags; @@ -251,25 +250,20 @@ static const struct qemu_feature_flags const arch_info_x86_64_flags [] = { /* The archicture tables for supported QEMU archs */ static const struct qemu_arch_info const arch_info_hvm[] = { - { "i686", 32, NULL, "qemu", + { "i686", 32, "qemu", "qemu-system-x86_64", arch_info_i686_flags, 4 }, - { "x86_64", 64, NULL, "qemu-system-x86_64", + { "x86_64", 64, "qemu-system-x86_64", NULL, arch_info_x86_64_flags, 2 }, - { "arm", 32, NULL, "qemu-system-arm", NULL, NULL, 0 }, - { "microblaze", 32, NULL, "qemu-system-microblaze", NULL, NULL, 0 }, - { "microblazeel", 32, NULL, "qemu-system-microblazeel", NULL, NULL, 0 }, - { "mips", 32, NULL, "qemu-system-mips", NULL, NULL, 0 }, - { "mipsel", 32, NULL, "qemu-system-mipsel", NULL, NULL, 0 }, - { "sparc", 32, NULL, "qemu-system-sparc", NULL, NULL, 0 }, - { "ppc", 32, NULL, "qemu-system-ppc", NULL, NULL, 0 }, - { "ppc64", 64, NULL, "qemu-system-ppc64", NULL, NULL, 0 }, - { "itanium", 64, NULL, "qemu-system-ia64", NULL, NULL, 0 }, - { "s390x", 64, NULL, "qemu-system-s390x", NULL, NULL, 0 }, -}; - -static const struct qemu_arch_info const arch_info_xen[] = { - { "i686", 32, "xenner", "xenner", NULL, arch_info_i686_flags, 4 }, - { "x86_64", 64, "xenner", "xenner", NULL, arch_info_x86_64_flags, 2 }, + { "arm", 32, "qemu-system-arm", NULL, NULL, 0 }, + { "microblaze", 32, "qemu-system-microblaze", NULL, NULL, 0 }, + { "microblazeel", 32, "qemu-system-microblazeel", NULL, NULL, 0 }, + { "mips", 32, "qemu-system-mips", NULL, NULL, 0 }, + { "mipsel", 32, "qemu-system-mipsel", NULL, NULL, 0 }, + { "sparc", 32, "qemu-system-sparc", NULL, NULL, 0 }, + { "ppc", 32, "qemu-system-ppc", NULL, NULL, 0 }, + { "ppc64", 64, "qemu-system-ppc64", NULL, NULL, 0 }, + { "itanium", 64, "qemu-system-ia64", NULL, NULL, 0 }, + { "s390x", 64, "qemu-system-s390x", NULL, NULL, 0 }, }; @@ -570,8 +564,7 @@ static int qemuCapsInitGuest(virCapsPtr caps, qemuCapsCachePtr cache, const char *hostmachine, - const struct qemu_arch_info *info, - int hvm) + const struct qemu_arch_info *info) { virCapsGuestPtr guest; int i; @@ -650,36 +643,13 @@ qemuCapsInitGuest(virCapsPtr caps, qemuCapsGet(qemubinCaps, QEMU_CAPS_KQEMU)) haskqemu = 1; - if (info->machine) { - virCapsGuestMachinePtr machine; - - if (VIR_ALLOC(machine) < 0) { - goto no_memory; - } - - if (!(machine->name = strdup(info->machine))) { - VIR_FREE(machine); - goto no_memory; - } - - nmachines = 1; - - if (VIR_ALLOC_N(machines, nmachines) < 0) { - VIR_FREE(machine->name); - VIR_FREE(machine); - goto no_memory; - } - - machines[0] = machine; - } else { - if (qemuCapsGetMachineTypesCaps(qemubinCaps, &nmachines, &machines) < 0) - goto error; - } + if (qemuCapsGetMachineTypesCaps(qemubinCaps, &nmachines, &machines) < 0) + goto error; /* We register kvm as the base emulator too, since we can * just give -no-kvm to disable acceleration if required */ if ((guest = virCapabilitiesAddGuest(caps, - hvm ? "hvm" : "xen", + "hvm", info->arch, info->wordsize, binary, @@ -700,52 +670,42 @@ qemuCapsInitGuest(virCapsPtr caps, !virCapabilitiesAddGuestFeature(guest, "deviceboot", 1, 0)) goto error; - if (hvm) { - if (virCapabilitiesAddGuestDomain(guest, - "qemu", - NULL, - NULL, - 0, - NULL) == NULL) - goto error; + if (virCapabilitiesAddGuestDomain(guest, + "qemu", + NULL, + NULL, + 0, + NULL) == NULL) + goto error; - if (haskqemu && - virCapabilitiesAddGuestDomain(guest, - "kqemu", - NULL, - NULL, - 0, - NULL) == NULL) - goto error; + if (haskqemu && + virCapabilitiesAddGuestDomain(guest, + "kqemu", + NULL, + NULL, + 0, + NULL) == NULL) + goto error; - if (haskvm) { - virCapsGuestDomainPtr dom; + if (haskvm) { + virCapsGuestDomainPtr dom; - if (kvmbin && - qemuCapsGetMachineTypesCaps(kvmbinCaps, &nmachines, &machines) < 0) - goto error; + if (kvmbin && + qemuCapsGetMachineTypesCaps(kvmbinCaps, &nmachines, &machines) < 0) + goto error; - if ((dom = virCapabilitiesAddGuestDomain(guest, - "kvm", - kvmbin ? kvmbin : binary, - NULL, - nmachines, - machines)) == NULL) { - goto error; - } + if ((dom = virCapabilitiesAddGuestDomain(guest, + "kvm", + kvmbin ? kvmbin : binary, + NULL, + nmachines, + machines)) == NULL) { + goto error; + } - machines = NULL; - nmachines = 0; + machines = NULL; + nmachines = 0; - } - } else { - if (virCapabilitiesAddGuestDomain(guest, - "kvm", - NULL, - NULL, - 0, - NULL) == NULL) - goto error; } if (info->nflags) { @@ -768,9 +728,6 @@ cleanup: return ret; -no_memory: - virReportOOMError(); - error: virCapabilitiesFreeMachines(machines, nmachines); @@ -831,7 +788,6 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) struct utsname utsname; virCapsPtr caps; int i; - char *xenner = NULL; /* Really, this never fails - look at the man-page. */ uname (&utsname); @@ -867,28 +823,9 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++) if (qemuCapsInitGuest(caps, cache, utsname.machine, - &arch_info_hvm[i], 1) < 0) + &arch_info_hvm[i]) < 0) goto no_memory; - /* Then possibly the Xen paravirt guests (ie Xenner */ - xenner = virFindFileInPath("xenner"); - - if (xenner != NULL && virFileIsExecutable(xenner) == 0 && - access("/dev/kvm", F_OK) == 0) { - for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_xen) ; i++) - /* Allow Xen 32-on-32, 32-on-64 and 64-on-64 */ - if (STREQ(arch_info_xen[i].arch, utsname.machine) || - (STREQ(utsname.machine, "x86_64") && - STREQ(arch_info_xen[i].arch, "i686"))) { - if (qemuCapsInitGuest(caps, cache, - utsname.machine, - &arch_info_xen[i], 0) < 0) - goto no_memory; - } - } - - VIR_FREE(xenner); - /* QEMU Requires an emulator in the XML */ virCapabilitiesSetEmulatorRequired(caps); @@ -897,7 +834,6 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) return caps; no_memory: - VIR_FREE(xenner); virCapabilitiesFree(caps); return NULL; } -- 1.7.11.4

From: "Daniel P. Berrange" <berrange@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 161 +++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 74 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 0422a15..2e308db 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -220,53 +220,6 @@ static int qemuCapsOnceInit(void) VIR_ONCE_GLOBAL_INIT(qemuCaps) -struct qemu_feature_flags { - const char *name; - const int default_on; - const int toggle; -}; - -struct qemu_arch_info { - const char *arch; - int wordsize; - const char *binary; - const char *altbinary; - const struct qemu_feature_flags *flags; - int nflags; -}; - -/* Feature flags for the architecture info */ -static const struct qemu_feature_flags const arch_info_i686_flags [] = { - { "pae", 1, 0 }, - { "nonpae", 1, 0 }, - { "acpi", 1, 1 }, - { "apic", 1, 0 }, -}; - -static const struct qemu_feature_flags const arch_info_x86_64_flags [] = { - { "acpi", 1, 1 }, - { "apic", 1, 0 }, -}; - -/* The archicture tables for supported QEMU archs */ -static const struct qemu_arch_info const arch_info_hvm[] = { - { "i686", 32, "qemu", - "qemu-system-x86_64", arch_info_i686_flags, 4 }, - { "x86_64", 64, "qemu-system-x86_64", - NULL, arch_info_x86_64_flags, 2 }, - { "arm", 32, "qemu-system-arm", NULL, NULL, 0 }, - { "microblaze", 32, "qemu-system-microblaze", NULL, NULL, 0 }, - { "microblazeel", 32, "qemu-system-microblazeel", NULL, NULL, 0 }, - { "mips", 32, "qemu-system-mips", NULL, NULL, 0 }, - { "mipsel", 32, "qemu-system-mipsel", NULL, NULL, 0 }, - { "sparc", 32, "qemu-system-sparc", NULL, NULL, 0 }, - { "ppc", 32, "qemu-system-ppc", NULL, NULL, 0 }, - { "ppc64", 64, "qemu-system-ppc64", NULL, NULL, 0 }, - { "itanium", 64, "qemu-system-ia64", NULL, NULL, 0 }, - { "s390x", 64, "qemu-system-s390x", NULL, NULL, 0 }, -}; - - static virCommandPtr qemuCapsProbeCommand(const char *qemu, qemuCapsPtr caps) @@ -341,6 +294,7 @@ qemuCapsParseMachineTypesStr(const char *output, caps->machineAliases[caps->nmachineTypes-1] = name; } else { caps->machineTypes[caps->nmachineTypes-1] = name; + caps->machineAliases[caps->nmachineTypes-1] = NULL; } } while ((p = next)); @@ -360,7 +314,7 @@ qemuCapsParseMachineTypesStr(const char *output, return 0; - no_memory: +no_memory: virReportOOMError(); return -1; } @@ -560,11 +514,68 @@ cleanup: } +static char * +qemuCapsFindBinaryForArch(const char *arch) +{ + char *ret; + + if (STREQ(arch, "i686")) { + ret = virFindFileInPath("qemu-system-i386"); + if (ret && !virFileIsExecutable(ret)) + VIR_FREE(ret); + + if (!ret) + ret = virFindFileInPath("qemu-system-x86_64"); + if (ret && !virFileIsExecutable(ret)) + VIR_FREE(ret); + + if (!ret) + ret = virFindFileInPath("qemu"); + } else if (STREQ(arch, "itanium")) { + ret = virFindFileInPath("qemu-system-ia64"); + } else { + char *bin; + if (virAsprintf(&bin, "qemu-system-%s", arch) < 0) { + virReportOOMError(); + return NULL; + } + ret = virFindFileInPath(bin); + VIR_FREE(bin); + } + if (ret && !virFileIsExecutable(ret)) + VIR_FREE(ret); + return ret; +} + +static int +qemuCapsGetArchWordSize(const char *arch) +{ + if (STREQ(arch, "i686") || + STREQ(arch, "ppc") || + STREQ(arch, "sparc") || + STREQ(arch, "mips") || + STREQ(arch, "mipsel")) + return 32; + return 64; +} + +static bool +qemuCapsIsValidForKVM(const char *hostarch, + const char *guestarch) +{ + if (STREQ(hostarch, guestarch)) + return true; + if (STREQ(hostarch, "x86_64") && + STREQ(guestarch, "i686")) + return true; + return false; +} + static int qemuCapsInitGuest(virCapsPtr caps, qemuCapsCachePtr cache, - const char *hostmachine, - const struct qemu_arch_info *info) + const char *hostarch, + const char *guestarch) { virCapsGuestPtr guest; int i; @@ -581,12 +592,7 @@ qemuCapsInitGuest(virCapsPtr caps, /* Check for existance of base emulator, or alternate base * which can be used with magic cpu choice */ - binary = virFindFileInPath(info->binary); - - if (binary == NULL || !virFileIsExecutable(binary)) { - VIR_FREE(binary); - binary = virFindFileInPath(info->altbinary); - } + binary = qemuCapsFindBinaryForArch(guestarch); /* Ignore binary if extracting version info fails */ if (binary) { @@ -602,8 +608,7 @@ qemuCapsInitGuest(virCapsPtr caps, * - hostarch is x86_64 and guest arch is i686 * The latter simply needs "-cpu qemu32" */ - if (STREQ(info->arch, hostmachine) || - (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) { + if (qemuCapsIsValidForKVM(hostarch, guestarch)) { const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */ "qemu-kvm", /* Fedora */ "kvm" }; /* Upstream .spec */ @@ -650,8 +655,8 @@ qemuCapsInitGuest(virCapsPtr caps, * just give -no-kvm to disable acceleration if required */ if ((guest = virCapabilitiesAddGuest(caps, "hvm", - info->arch, - info->wordsize, + guestarch, + qemuCapsGetArchWordSize(guestarch), binary, NULL, nmachines, @@ -708,15 +713,16 @@ qemuCapsInitGuest(virCapsPtr caps, } - if (info->nflags) { - for (i = 0 ; i < info->nflags ; i++) { - if (virCapabilitiesAddGuestFeature(guest, - info->flags[i].name, - info->flags[i].default_on, - info->flags[i].toggle) == NULL) - goto error; - } - } + if ((STREQ(guestarch, "i686") || + STREQ(guestarch, "x86_64")) && + (virCapabilitiesAddGuestFeature(guest, "acpi", 1, 1) == NULL || + virCapabilitiesAddGuestFeature(guest, "apic", 1, 0) == NULL)) + goto error; + + if (STREQ(guestarch, "i686") && + (virCapabilitiesAddGuestFeature(guest, "pae", 1, 0) == NULL || + virCapabilitiesAddGuestFeature(guest, "nonpae", 1, 0) == NULL)) + goto error; ret = 0; @@ -788,13 +794,20 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) struct utsname utsname; virCapsPtr caps; int i; + const char *const arches[] = { + "i686", "x86_64", "arm", + "microblaze", "microblazeel", + "mips", "mipsel", "sparc", + "ppc", "ppc64", "itanium", + "s390x" + }; /* Really, this never fails - look at the man-page. */ uname (&utsname); if ((caps = virCapabilitiesNew(utsname.machine, 1, 1)) == NULL) - goto no_memory; + goto error; /* Using KVM's mac prefix for QEMU too */ virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 }); @@ -820,11 +833,11 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) "tcp"); /* First the pure HVM guests */ - for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++) + for (i = 0 ; i < ARRAY_CARDINALITY(arches) ; i++) if (qemuCapsInitGuest(caps, cache, utsname.machine, - &arch_info_hvm[i]) < 0) - goto no_memory; + arches[i]) < 0) + goto error; /* QEMU Requires an emulator in the XML */ virCapabilitiesSetEmulatorRequired(caps); @@ -833,7 +846,7 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache) return caps; - no_memory: +error: virCapabilitiesFree(caps); return NULL; } -- 1.7.11.4
participants (2)
-
Daniel P. Berrange
-
Eric Blake