[libvirt] [libvirt-designer] Fix 'be find' typo in error message
by Christophe Fergeau
---
Pushed under the trivial rule.
Christophe
examples/virtxml.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/virtxml.c b/examples/virtxml.c
index 49a7b4e..20aa621 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -547,7 +547,7 @@ main(int argc, char *argv[])
}
if (!os) {
- print_error("Operating system could not be find or guessed");
+ print_error("Operating system could not be found or guessed");
goto cleanup;
}
--
1.8.1.4
11 years, 7 months
[libvirt] [RFC] Usage about 'virsh vol-wipe vol_name'
by harryxiyou
Hi all,
I am not very clear about the usage of ‘virsh vol-wipe vol_name’. I think
if 'virsh vol-wipe vol_name' can just wipe all the datas in this volume and
it is similar as we format a volume which the datas would be wiped, right?
After this wipe, we can use this volume like a new one.
However, if users just want to wipe portions data of this volume, which
command(interface) of libvirt could finish?
--
Thanks
Harry Wei
11 years, 7 months
Re: [libvirt] fail to convert qemu xml to args with libvirt-1.0.4: An error occurred, but the cause is unknown
by Yin Olivia-R63875
Hi Daniel,
I also tried libvirt-1.0.4 on my X86 machine.
user@x86:~ $ uname -a
Linux 2.6.32-33-server #70-Ubuntu SMP Thu Jul 7 22:28:30 UTC 2011 x86_64 GNU/Linux
user@x86:~ $ which virsh
/usr/local/bin/virsh
user@x86:~ $ /usr/local/bin/virsh --version
1.0.4
user@x86:~ $ cd libvirt-1.0.4/tests/qemuxml2argvdata
user@x86:~/libvirt-1.0.4/tests/qemuxml2argvdata $ virsh domxml-to-native qemu-argv qemuxml2argv-disk-virtio.xml >1.dom
error:An error occurred, but the cause is unknown
Best Regards,
Olivia
> -----Original Message-----
> From: Yin Olivia-R63875
> Sent: Thursday, April 11, 2013 10:18 AM
> To: 'Daniel P. Berrange'
> Cc: 'libvirt-users(a)redhat.com'; 'libvir-list(a)redhat.com'
> Subject: RE: fail to convert qemu xml to args with libvirt-1.0.4: An error
> occurred, but the cause is unknown
>
> Hi Daniel,
>
> Just Ping.
> Did you ever successfully convert QEMU xml file to argv on other platforms?
>
> Best Regards,
> Olivia
>
> > -----Original Message-----
> > From: Yin Olivia-R63875
> > Sent: Tuesday, April 09, 2013 1:22 PM
> > To: 'libvir-list(a)redhat.com'
> > Cc: 'libvirt-users(a)redhat.com'
> > Subject: fail to convert qemu xml to args with libvirt-1.0.4: An error
> > occurred, but the cause is unknown
> >
> > Hi,
> >
> > I used to convert qemu XML to args with libvirt-1.0.3.
> > But it failed to convert with libvirt-1.0.4.
> >
> > # virsh domxml-to-native qemu-argv test.xml >test.sh
> > error: An error occurred, but the cause is unknown
> >
> >
> > Comparing the debug file as below:
> > 1) lbvirt-1.0.3
> > <cut>
> > 2013-04-09 03:23:47.296+0000: 2669: debug :
> > virEventPollInterruptLocked:716 : Interrupting
> > 2013-04-09 03:23:47.296+0000: 2669: debug : virNetClientIO:1807 : All
> > done with our call head=(nil) call=0x100871c0 rv=0
> > 2013-04-09 03:23:47.297+0000: 2670: debug : virEventPollRunOnce:640 :
> > Poll got 1 event(s)
> > 2013-04-09 03:23:47.297+0000: 2670: debug :
> > virEventPollDispatchTimeouts:425 : Dispatch 0
> > 2013-04-09 03:23:47.297+0000: 2669: debug : virNetMessageFree:73 :
> > msg=0x10087500 nfds=0 cb=(nil)
> > 2013-04-09 03:23:47.297+0000: 2670: debug :
> > virEventPollDispatchHandles:470 : Dispatch 1
> > 2013-04-09 03:23:47.297+0000: 2670: debug :
> > virEventPollDispatchHandles:484 : i=0 w=1
> > 2013-04-09 03:23:47.297+0000: 2669: debug : virConnectClose:1483 :
> > conn=0x100878b8 <cut>
> >
> > 2) libvirt-1.0.4
> > <cut>
> > 2013-04-09 03:07:58.012+0000: 2834: debug :
> > virEventPollInterruptLocked:716 : Interrupting
> > 2013-04-09 03:07:58.012+0000: 2834: debug : virNetClientIO:1810 : All
> > done with our call head=(nil) call=0x10089db8 rv=0
> > 2013-04-09 03:07:58.012+0000: 2835: debug : virEventPollRunOnce:640 :
> > Poll got 1 event(s)
> > 2013-04-09 03:07:58.012+0000: 2835: debug :
> > virEventPollDispatchTimeouts:425 : Dispatch 0
> > 2013-04-09 03:07:58.012+0000: 2834: error :
> > virNetClientProgramDispatchError:175 : An error occurred, but the
> > cause is unknown
> > 2013-04-09 03:07:58.012+0000: 2835: debug :
> > virEventPollDispatchHandles:470 : Dispatch 1
> > 2013-04-09 03:07:58.012+0000: 2834: debug : virNetMessageFree:73 :
> > msg=0x1008a0f8 nfds=0 cb=(nil)
> > 2013-04-09 03:07:58.012+0000: 2835: debug :
> > virEventPollDispatchHandles:484 : i=0 w=1
> > 2013-04-09 03:07:58.012+0000: 2835: debug :
> > virEventPollDispatchHandles:498 : EVENT_POLL_DISPATCH_HANDLE: watch=1
> > events=1
> > 2013-04-09 03:07:58.012+0000: 2835: debug :
> > virEventPollCleanupTimeouts:516 : Cleanup 0
> > 2013-04-09 03:07:58.013+0000: 2835: debug :
> > virEventPollCleanupTimeouts:552 : Found 0 out of 0 timeout slots used,
> > releasing 0
> > 2013-04-09 03:07:58.013+0000: 2835: debug :
> virEventPollCleanupHandles:564 :
> > Cleanup 2
> > 2013-04-09 03:07:58.013+0000: 2834: debug : virConnectClose:1483 :
> > conn=0x1008a4b0 <cut>
> >
> >
> > How can I debug this cause unknown error?
> >
> > Best Regards,
> > Olivia
11 years, 7 months
[libvirt] [RFC] virCommandRun return error number
by harryxiyou
Hi all,
I copy portions of libvirt/src/storage/storage_backend_sheepdog.c
[...]
125 ret = virCommandRun(cmd, NULL);
126 if (ret == 0)
127 ret = virStorageBackendSheepdogParseNodeInfo(pool->def, output);
[...]
I found virCommandRun may return '-1', which hinds something error happens.
However, Sheepdog hasn't check here. Maybe i have come up with this bug.
I cannot remember clearly. Could anyone please give me some suggestions?
If ture, i will give a patch for this bug ;-).
--
Thanks
Harry Wei
11 years, 7 months
[libvirt] [PATCH v2 0/2] Add error handling to optional arguments in cmdCPUStats
by John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=907732
Also added informational message when count value is larger than number
of CPUs present. Original code commit '31047e2b' quietly changes it and
continues on.
Prior to patch 2/2, no errors were seen for following sequences
virsh cpu-stats guest xyz
virsh cpu-stats guest --start xyz
virsh cpu-stats guest --count xyz
virsh cpu-stats guest --count 99999999999
With patch 2/2, the following errors are displayed for the above sequence
error: Unable to parse integer parameter for start
error: Unable to parse integer parameter for start
error: Unable to parse integer parameter for CPUs to show
error: Unable to parse integer parameter for CPUs to show
Additionally, the following will be displayed on negative value input:
virsh cpu-stats guest --start -1
error: Invalid value for start CPU
virsh cpu-stats guest --count -1
error: Invalid value for number of CPUs to show
Using a --count parameter value larger than the number of vCPUs on the
system will display the following:
virsh cpu-stats guest --count 8
Only 4 CPUs available to show
CPU0:
cpu_time 10.770466061 seconds
vcpu_time 8.327848192 seconds
...
Diff to v1
- Split into 2 patches (one for struct defs, one for argument processing)
- Adjust argument processessing to delineate between bad argument and
invalid value (eg, negative CPU start number or count)
- Only display the > # cpus message when too large a value is supplied
John Ferlan (2):
Remove extraneous comma in info_cpu_stats and opts_cpu_stats
Add error handling to optional arguments in cmdCPUStats
tools/virsh-domain.c | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] qemu: Do not report unsafe migration for local files
by Jiri Denemark
When migrating a domain with disk images stored locally (and using
storage migration), we should not complain about unsafe migration no
matter what cache policy is used for that disk.
---
src/qemu/qemu_migration.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index a263668..a31bd02 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1477,13 +1477,17 @@ qemuMigrationIsSafe(virDomainDefPtr def)
!disk->shared &&
!disk->readonly &&
disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) {
- int cfs;
+ int rc;
if (disk->type == VIR_DOMAIN_DISK_TYPE_FILE) {
- if ((cfs = virStorageFileIsClusterFS(disk->src)) == 1)
+ if ((rc = virStorageFileIsSharedFS(disk->src)) < 0)
+ return false;
+ else if (rc == 0)
continue;
- else if (cfs < 0)
+ if ((rc = virStorageFileIsClusterFS(disk->src)) < 0)
return false;
+ else if (rc == 1)
+ continue;
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
continue;
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] virsh: Document that using incomplete XML files may have unexpected results
by Peter Krempa
Explicitly state that using incomplete XML definition snippets for hot-management
commands may have unexpected results due to autogenerating values for some of
the fields if they aren't specified explicitly.
---
tools/virsh.pod | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 1510d0d..11984bc 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1824,6 +1824,10 @@ within an existing device; consider using B<update-device> for this
usage. For passthrough host devices, see also B<nodedev-detach>,
needed if the device does not use managed mode.
+B<Note>: using of partial device definition XML files may lead to unexpected
+results as some fields may be autogenerated and thus match devices other than
+expected.
+
=item B<attach-disk> I<domain> I<source> I<target>
[I<--driver driver>] [I<--subdriver subdriver>] [I<--cache cache>]
[I<--type type>] [I<--mode mode>] [I<--config>] [I<--sourcetype soucetype>]
@@ -1893,6 +1897,10 @@ as command B<attach-device>.
For passthrough host devices, see also B<nodedev-reattach>, needed if
the device does not use managed mode.
+B<Note>: using of partial device definition XML files may lead to unexpected
+results as some fields may be autogenerated and thus match devices other than
+expected.
+
If I<--live> is specified, affect a running domain.
If I<--config> is specified, affect the next startup of a persistent domain.
If I<--current> is specified, affect the current domain state.
@@ -1969,6 +1977,10 @@ an offline domain, and like I<--live> I<--config> for a running domain.
Note that older versions of virsh used I<--config> as an alias for
I<--persistent>.
+B<Note>: using of partial device definition XML files may lead to unexpected
+results as some fields may be autogenerated and thus match devices other than
+expected.
+
=item B<change-media> I<domain> I<path> [I<--eject>] [I<--insert>]
[I<--update>] [I<source>] [I<--force>] [[I<--live>] [I<--config>] | [I<--current>]]
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCHv2] qemu: Try to use QMP for send-key if supported
by Peter Krempa
Instead of always using HMP use the QMP send-key command introduced in qemu 1.3.
---
Notes:
Version 2:
- always try QMP instead of adding capability bit
src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 64 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1bf8baf..759198b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3372,11 +3372,70 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
unsigned int *keycodes,
unsigned int nkeycodes)
{
- /*
- * FIXME: qmp sendkey has not been implemented yet,
- * and qmp API of it cannot be anticipated, so we use hmp temporary.
- */
- return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr keys = NULL;
+ virJSONValuePtr key = NULL;
+ unsigned int i;
+
+ /* create the key data array */
+ if (!(keys = virJSONValueNewArray()))
+ goto no_memory;
+
+ for (i = 0; i < nkeycodes; i++) {
+ if (keycodes[i] > 0xffff) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("keycode %d is invalid: 0x%X"), i, keycodes[i]);
+ goto cleanup;
+ }
+
+ /* create single key object */
+ if (!(key = virJSONValueNewObject()))
+ goto no_memory;
+
+ /* Union KeyValue has two, types, use the generic one */
+ if (virJSONValueObjectAppendString(key, "type", "number") < 0)
+ goto no_memory;
+
+ /* with the keycode */
+ if (virJSONValueObjectAppendNumberInt(key, "data", keycodes[i]) < 0)
+ goto no_memory;
+
+ if (virJSONValueArrayAppend(keys, key) < 0)
+ goto no_memory;
+
+ key = NULL;
+
+ }
+
+ cmd = qemuMonitorJSONMakeCommand("send-key",
+ "a:keys", keys,
+ holdtime ? "U:hold-time" : NULL, holdtime,
+ NULL);
+ if (!cmd)
+ goto cleanup;
+
+ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ goto cleanup;
+
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ VIR_DEBUG("send-key command not found, trying HMP");
+ ret = qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ } else {
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ virJSONValueFree(keys);
+ virJSONValueFree(key);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
}
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] Fix error return value for VirCommandNewArgList
by harryxiyou@gmail.com
From: Harry Wei <harryxiyou(a)gmail.com>
virCommandNewArgList may return NULL so we need not
do following stuffs and just return '-1'.
Signed-off-by: Harry Wei <harryxiyou(a)gmail.com>
CC: Osier Yang <jyang(a)redhat.com>
CC: Michal Privoznik <mprivozn(a)redhat.com>
---
src/storage/storage_backend_sheepdog.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c
index 35a3a04..3452eaa 100644
--- a/src/storage/storage_backend_sheepdog.c
+++ b/src/storage/storage_backend_sheepdog.c
@@ -120,6 +120,8 @@ virStorageBackendSheepdogRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virCommandPtr cmd;
cmd = virCommandNewArgList(COLLIE, "node", "info", "-r", NULL);
+ if (cmd == NULL)
+ return -1;
virStorageBackendSheepdogAddHostArg(cmd, pool);
virCommandSetOutputBuffer(cmd, &output);
ret = virCommandRun(cmd, NULL);
@@ -142,6 +144,8 @@ virStorageBackendSheepdogDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
virCheckFlags(0, -1);
virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "delete", vol->name, NULL);
+ if (cmd == NULL)
+ return -1;
virStorageBackendSheepdogAddHostArg(cmd, pool);
int ret = virCommandRun(cmd, NULL);
@@ -165,6 +169,8 @@ virStorageBackendSheepdogCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED,
}
virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "create", vol->name, NULL);
+ if (cmd == NULL)
+ return -1;
virCommandAddArgFormat(cmd, "%llu", vol->capacity);
virStorageBackendSheepdogAddHostArg(cmd, pool);
if (virCommandRun(cmd, NULL) < 0)
@@ -251,6 +257,8 @@ virStorageBackendSheepdogRefreshVol(virConnectPtr conn ATTRIBUTE_UNUSED,
char *output = NULL;
virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "list", vol->name, "-r", NULL);
+ if (cmd == NULL)
+ return -1;
virStorageBackendSheepdogAddHostArg(cmd, pool);
virCommandSetOutputBuffer(cmd, &output);
ret = virCommandRun(cmd, NULL);
@@ -293,6 +301,8 @@ virStorageBackendSheepdogResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED,
virCheckFlags(0, -1);
virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "resize", vol->name, NULL);
+ if (cmd == NULL)
+ return -1;
virCommandAddArgFormat(cmd, "%llu", capacity);
virStorageBackendSheepdogAddHostArg(cmd, pool);
int ret = virCommandRun(cmd, NULL);
--
1.7.9.5
11 years, 7 months
[libvirt] [PATCH] qemu: Use QMP for send-key if supported
by Peter Krempa
Instead of always using HMP use the QMP send-key command introduced in qemu 1.3.
---
src/qemu/qemu_capabilities.c | 3 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_driver.c | 25 +++++++++++------
src/qemu/qemu_monitor.c | 5 ++--
src/qemu/qemu_monitor.h | 3 ++-
src/qemu/qemu_monitor_json.c | 64 ++++++++++++++++++++++++++++++++++++++++----
6 files changed, 85 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 50712b0..051285c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -216,6 +216,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"ipv6-migration", /* 135 */
"machine-opt",
+ "send-key",
);
struct _virQEMUCaps {
@@ -1954,6 +1955,8 @@ virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
virQEMUCapsSet(qemuCaps, QEMU_CAPS_ADD_FD);
else if (STREQ(name, "nbd-server-start"))
virQEMUCapsSet(qemuCaps, QEMU_CAPS_NBD_SERVER);
+ else if (STREQ(name, "send-key"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_SEND_KEY);
VIR_FREE(name);
}
VIR_FREE(commands);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index b2dc588..bcd4daf 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -176,6 +176,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_SCSI_MEGASAS = 134, /* -device megasas */
QEMU_CAPS_IPV6_MIGRATION = 135, /* -incoming [::] */
QEMU_CAPS_MACHINE_OPT = 136, /* -machine xxxx*/
+ QEMU_CAPS_SEND_KEY = 137, /* send-key QMP command */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2c0d7d1..cfb6fc9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2227,14 +2227,16 @@ cleanup:
return ret;
}
-static int qemuDomainSendKey(virDomainPtr domain,
- unsigned int codeset,
- unsigned int holdtime,
- unsigned int *keycodes,
- int nkeycodes,
- unsigned int flags)
+static int
+qemuDomainSendKey(virDomainPtr domain,
+ unsigned int codeset,
+ unsigned int holdtime,
+ unsigned int *keycodes,
+ int nkeycodes,
+ unsigned int flags)
{
virQEMUDriverPtr driver = domain->conn->privateData;
+ virQEMUCapsPtr qemuCaps = NULL;
virDomainObjPtr vm = NULL;
int ret = -1;
qemuDomainObjPrivatePtr priv;
@@ -2251,7 +2253,8 @@ static int qemuDomainSendKey(virDomainPtr domain,
keycodes[i]);
if (keycode < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot translate keycode %u of %s codeset to rfb keycode"),
+ _("cannot translate keycode %u of %s codeset to "
+ "rfb keycode"),
keycodes[i],
virKeycodeSetTypeToString(codeset));
return -1;
@@ -2263,6 +2266,10 @@ static int qemuDomainSendKey(virDomainPtr domain,
if (!(vm = qemuDomObjFromDomain(domain)))
goto cleanup;
+ if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+ vm->def->emulator)))
+ goto cleanup;
+
priv = vm->privateData;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
@@ -2275,7 +2282,8 @@ static int qemuDomainSendKey(virDomainPtr domain,
}
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorSendKey(priv->mon, holdtime, keycodes, nkeycodes);
+ ret = qemuMonitorSendKey(priv->mon, holdtime, keycodes, nkeycodes,
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEND_KEY));
qemuDomainObjExitMonitor(driver, vm);
endjob:
@@ -2285,6 +2293,7 @@ endjob:
cleanup:
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(qemuCaps);
return ret;
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index d1c6690..d9b5c23 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3008,14 +3008,15 @@ int qemuMonitorInjectNMI(qemuMonitorPtr mon)
int qemuMonitorSendKey(qemuMonitorPtr mon,
unsigned int holdtime,
unsigned int *keycodes,
- unsigned int nkeycodes)
+ unsigned int nkeycodes,
+ bool useQMP)
{
int ret;
VIR_DEBUG("mon=%p, holdtime=%u, nkeycodes=%u",
mon, holdtime, nkeycodes);
- if (mon->json)
+ if (mon->json && useQMP)
ret = qemuMonitorJSONSendKey(mon, holdtime, keycodes, nkeycodes);
else
ret = qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b3808a8..fadad08 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -601,7 +601,8 @@ int qemuMonitorScreendump(qemuMonitorPtr mon,
int qemuMonitorSendKey(qemuMonitorPtr mon,
unsigned int holdtime,
unsigned int *keycodes,
- unsigned int nkeycodes);
+ unsigned int nkeycodes,
+ bool useQMP);
typedef enum {
BLOCK_JOB_ABORT,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1bf8baf..43057fb 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3372,11 +3372,65 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
unsigned int *keycodes,
unsigned int nkeycodes)
{
- /*
- * FIXME: qmp sendkey has not been implemented yet,
- * and qmp API of it cannot be anticipated, so we use hmp temporary.
- */
- return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr keys = NULL;
+ virJSONValuePtr key = NULL;
+ unsigned int i;
+
+ /* create the key data array */
+ if (!(keys = virJSONValueNewArray()))
+ goto no_memory;
+
+ for (i = 0; i < nkeycodes; i++) {
+ if (keycodes[i] > 0xffff) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("keycode %d is invalid: 0x%X"), i, keycodes[i]);
+ goto cleanup;
+ }
+
+ /* create single key object */
+ if (!(key = virJSONValueNewObject()))
+ goto no_memory;
+
+ /* Union KeyValue has two, types, use the generic one */
+ if (virJSONValueObjectAppendString(key, "type", "number") < 0)
+ goto no_memory;
+
+ /* with the keycode */
+ if (virJSONValueObjectAppendNumberInt(key, "data", keycodes[i]) < 0)
+ goto no_memory;
+
+ if (virJSONValueArrayAppend(keys, key) < 0)
+ goto no_memory;
+
+ key = NULL;
+
+ }
+
+ cmd = qemuMonitorJSONMakeCommand("send-key",
+ "a:keys", keys,
+ holdtime ? "U:hold-time" : NULL, holdtime,
+ NULL);
+ if (!cmd)
+ goto cleanup;
+
+ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ goto cleanup;
+
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ virJSONValueFree(keys);
+ virJSONValueFree(key);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
}
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
--
1.8.1.5
11 years, 7 months