Signed-off-by: Lin Ma <lma@xxxxxxxx> --- tools/virsh-completer-domain.c | 54 ++++++++++++++++++++++++++++++++++ tools/virsh-completer-domain.h | 4 +++ tools/virsh-domain.c | 1 + 3 files changed, 59 insertions(+) diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c index 6f67c91746..ab81a0dcfe 100644 --- a/tools/virsh-completer-domain.c +++ b/tools/virsh-completer-domain.c @@ -617,3 +617,57 @@ virshDomainVcpulistViaAgentCompleter(vshControl *ctl, virshDomainFree(dom); return ret; } + +char ** +virshDomainConsoleCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags) +{ + virshControlPtr priv = ctl->privData; + g_autoptr(xmlDoc) xmldoc = NULL; + g_autoptr(xmlXPathContext) ctxt = NULL; + int nserials, nparallels, offset = 0, head; + g_autofree xmlNodePtr *serials = NULL; + g_autofree xmlNodePtr *parallels = NULL; + size_t i; + VIR_AUTOSTRINGLIST tmp = NULL; + + virCheckFlags(0, NULL); + + if (!priv->conn || virConnectIsAlive(priv->conn) <= 0) + return NULL; + + if (virshDomainGetXML(ctl, cmd, 0, &xmldoc, &ctxt) < 0) + return NULL; + + nserials = virXPathNodeSet("./devices/serial", ctxt, &serials); + if (nserials < 0) + return NULL; + + nparallels = virXPathNodeSet("./devices/parallel", ctxt, ¶llels); + if (nparallels < 0) + return NULL; + + tmp = g_new0(char *, nserials + nparallels + 1); + + for (i = 0; i < nserials; i++) { + ctxt->node = serials[i]; + if (STRNEQ(virXPathString("string(./@type)", ctxt), "pty")) + offset += 1; + else + tmp[i - offset] = virXPathString("string(./alias/@name)", ctxt); + } + + head = i - offset; + offset = 0; + + for (i = 0; i < nparallels; i++) { + ctxt->node = parallels[i]; + if (STRNEQ(virXPathString("string(./@type)", ctxt), "pty")) + offset += 1; + else + tmp[head + i - offset] = virXPathString("string(./alias/@name)", ctxt); + } + + return g_steal_pointer(&tmp); +} diff --git a/tools/virsh-completer-domain.h b/tools/virsh-completer-domain.h index d5021f6aa6..02fea2fe94 100644 --- a/tools/virsh-completer-domain.h +++ b/tools/virsh-completer-domain.h @@ -94,3 +94,7 @@ char ** virshDomainCpulistCompleter(vshControl *ctl, char ** virshDomainVcpulistViaAgentCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); + +char ** virshDomainConsoleCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index c051b047ea..7189c8c826 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2960,6 +2960,7 @@ static const vshCmdOptDef opts_console[] = { VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name = "devname", /* sc_prohibit_devname */ .type = VSH_OT_STRING, + .completer = virshDomainConsoleCompleter, .help = N_("character device name") }, {.name = "force", -- 2.26.0