[libvirt] [PATCH 3/4 V4] send-key: Expose the new API in virsh

Daniel P. Berrange berrange at redhat.com
Tue Jul 19 15:05:46 UTC 2011


On Thu, Jul 14, 2011 at 11:32:17AM +0800, Lai Jiangshan wrote:
> Also support string names for the linux keycode(auto detect).
> 
> Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
> Acked-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  tools/virsh.c   |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/virsh.pod |    4 ++
>  2 files changed, 98 insertions(+), 0 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index cd17f42..741e726 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -58,6 +58,7 @@
>  #include "threads.h"
>  #include "command.h"
>  #include "count-one-bits.h"
> +#include "virtkey.h"
>  
>  static char *progname;
>  
> @@ -3350,6 +3351,98 @@ 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> KEY_RIGHTCTRL KEY_C\n"
> +                "        virsh # send-key <domain> --codeset xt 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 > 0xffff || 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 = NULL;
> +    int keycode;
> +    unsigned int keycodes[VIR_DOMAIN_SEND_KEY_MAX_KEYS];
> +
> +    if (!vshConnectionUsability(ctl, ctl->conn))
> +        return false;
> +
> +    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
> +        return false;
> +
> +    if (vshCommandOptString(cmd, "codeset", &codeset_option) <= 0)
> +        codeset_option = "linux";
> +
> +    if (vshCommandOptInt(cmd, "holdtime", &holdtime) <= 0)
> +        holdtime = 0;
> +
> +    codeset = virKeycodeSetTypeFromString(codeset_option);
> +    if ((int)codeset < 0) {
> +        vshError(ctl, _("unknown codeset: '%s'"), codeset_option);
> +        goto cleanup;
> +    }
> +
> +    while ((opt = vshCommandOptArgv(cmd, opt))) {
> +        if (count == VIR_DOMAIN_SEND_KEY_MAX_KEYS) {
> +            vshError(ctl, _("too many keycodes"));
> +            goto cleanup;
> +        }
> +
> +        if ((keycode = get_integer_keycode(opt->data)) <= 0) {
> +            if ((keycode = virParseKeyName(codeset, opt->data)) <= 0) {
> +                vshError(ctl, _("invalid keycode: '%s'"), opt->data);
> +                goto cleanup;
> +            }
> +        }
> +
> +        keycodes[count] = keycode;
> +        count++;
> +    }
> +
> +    if (!(virDomainSendKey(dom, codeset, holdtime, keycodes, count, 0) < 0))
> +        ret = true;
> +
> +cleanup:
> +    virDomainFree(dom);
> +    return ret;
> +}
> +
> +/*
>   * "setmemory" command
>   */
>  static const vshCmdInfo info_setmem[] = {
> @@ -11684,6 +11777,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 52f1549..d8d0a18 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -309,6 +309,10 @@ running B<virsh suspend>.  When in a paused state the domain will still
>  consume allocated resources like memory, but will not be eligible for
>  scheduling by the hypervisor.
>  
> +=item B<send-key> I<domain-id> optional I<--codeset> B<codeset> optional I<--holdtime> B<holdtime> B<keycode>...
> +
> +Send keys to the guest
> +
>  =item B<shutdown>
>  
>  The domain is in the process of shutting down, i.e. the guest operating system

ACK when updated to deal with recommended changes to previous patch

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