[libvirt] [PATCH 09/10 V2] send-key: Expose the new API in virsh
Daniel P. Berrange
berrange at redhat.com
Mon Jun 13 23:01:13 UTC 2011
On Tue, Jun 07, 2011 at 05:11:16PM +0800, Lai Jiangshan wrote:
> Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
> ---
> tools/virsh.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> tools/virsh.pod | 4 ++
> 2 files changed, 106 insertions(+), 0 deletions(-)
>
> diff --git a/tools/virsh.c b/tools/virsh.c
> index d13c12b..7b5847f 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -33,6 +33,8 @@
> #include <signal.h>
> #include <poll.h>
>
> +#include <libvirt/virtkeys.h>
> +
> #include <libxml/parser.h>
> #include <libxml/tree.h>
> #include <libxml/xpath.h>
> @@ -3182,6 +3184,105 @@ cmdInjectNMI(vshControl *ctl, const vshCmd *cmd)
> }
>
> /*
> + * "send-key" command
> + */
> +static const vshCmdInfo info_send_key[] = {
> + {"help", N_("Send keycodes to the guest")},
> + {"desc", N_("Send keycodes to the guest, the keycodes must be integers\n"
> + " Examples:\n\n"
> + " virsh # send-key <domain> 37 18 21\n"
> + " virsh # send-key <domain> --holdtime 1000 0x15 18 0xf\n"
> + )},
> + {NULL, NULL}
> +};
> +
> +static const vshCmdOptDef opts_send_key[] = {
> + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
> + {"codeset", VSH_OT_STRING, VSH_OFLAG_REQ_OPT, N_("the codeset of keycodes, default:linux")},
> + {"holdtime", VSH_OT_INT, VSH_OFLAG_REQ_OPT,
> + N_("the time (in millsecond) how long the keys will be held")},
> + {"keycode", VSH_OT_ARGV, VSH_OFLAG_REQ, N_("the key code")},
> + {NULL, 0, 0, NULL}
> +};
> +
> +static int get_integer_keycode(const char *key_name)
> +{
> + long val;
> + char *endptr;
> +
> + val = strtol(key_name, &endptr, 0);
> + if (*endptr != '\0' || val > 255 || val <= 0)
> + return -1;
> +
> + return val;
> +}
> +
> +static bool
> +cmdSendKey(vshControl *ctl, const vshCmd *cmd)
> +{
> + virDomainPtr dom;
> + int ret = false;
> + const char *codeset_option;
> + int codeset;
> + int holdtime;
> + int count = 0;
> + const vshCmdOpt *opt;
> + int keycode;
> + unsigned int keycodes[MAX_SEND_KEY];
> +
> + if (!vshConnectionUsability(ctl, ctl->conn))
> + return false;
> +
> + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
> + return false;
> +
> + if (vshCommandOptString(cmd, "codeset", &codeset_option) <= 0)
> + codeset_option = "default";
> +
> + if (vshCommandOptInt(cmd, "holdtime", &holdtime) <= 0)
> + holdtime = 0;
> +
> + if (STREQ(codeset_option, "default") || STREQ(codeset_option, "linux")) {
> + codeset = LIBVIRT_KEYCODE_LINUX;
> + } else if (STREQ(codeset_option, "xt")) {
> + codeset = LIBVIRT_KEYCODE_XT;
> + } else if (STREQ(codeset_option, "atset1")) {
> + codeset = LIBVIRT_KEYCODE_ATSET1;
> + } else if (STREQ(codeset_option, "atset2")) {
> + codeset = LIBVIRT_KEYCODE_ATSET2;
> + } else if (STREQ(codeset_option, "atset3")) {
> + codeset = LIBVIRT_KEYCODE_ATSET3;
> + } else {
> + vshError(ctl, _("unknown codeset: '%s'"), codeset_option);
> + goto free_domain;
> + }
> +
> + for_each_variable_arg(cmd, opt) {
> + if (count == MAX_SEND_KEY) {
> + vshError(ctl, _("too many keycode"));
> + goto free_domain;
> + }
> +
> + if ((keycode = get_integer_keycode(opt->data)) > 0)
> + goto get_keycode;
> +
> + vshError(ctl, _("invalid keycode: '%s'"), opt->data);
> + goto free_domain;
> +
> +get_keycode:
> + keycodes[count] = keycode;
> + count++;
This control flow is a little odd to me - the extra label
and goto seems overkill. Why not just do
if ((keycode = get_integer_keycode(opt->data)) <= 0)
vshError(ctl, _("invalid keycode: '%s'"), opt->data);
goto free_domain;
}
keycodes[count] = keycode;
count++;
> + }
> +
> + if (!(virDomainSendKey(dom, codeset, holdtime, keycodes, count, 0) < 0))
> + ret = true;
Minor whitespace bug there.
> +
> +free_domain:
Normal naming convention for this label would be 'cleanup'
> + virDomainFree(dom);
> + return ret;
> +}
> +
> +/*
> * "setmemory" command
> */
> static const vshCmdInfo info_setmem[] = {
> @@ -11095,6 +11196,7 @@ static const vshCmdDef domManagementCmds[] = {
> {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0},
> {"edit", cmdEdit, opts_edit, info_edit, 0},
> {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0},
> + {"send-key", cmdSendKey, opts_send_key, info_send_key},
> {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave, 0},
> {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove,
> info_managedsaveremove, 0},
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 7ed3003..03b1418 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -296,6 +296,10 @@ scheduling by the hypervisor.
>
> Inject NMI to the guest
>
> +=item B<send-key> I<domain-id> I<--codeset> B<codeset> I<--holdtime> B<holdtime> B<keycode>...
> +
> +Send keys to the guest
> +
It would be nice to list the values that are allowed for codeset here
at least
> =item B<shutdown>
>
> The domain is in the process of shutting down, i.e. the guest operating system
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 :|
More information about the libvir-list
mailing list