This patch adds support for the newly introduced VIR_DOMAIN_CONSOLE_FORCE and VIR_DOMAIN_CONSOLE_SAFE flags. The console command now has an optional parameter --force that specifies that the user wants to forcibly interrupt an ongoing console session and create a new one. Flag --safe requests that the console should be opened only if the hypervisor driver supports safe console handling. The behaviour to this point was that the daemon opened two streams to the console, that competed for data from the pipe, and the result was that both of the consoles ended up scrambled. This patch doesn't modify operation of other commands dealing with console connections (start, create) as those open connections to newly started domains making it virtualy impossible for another client to race for the console and steal it. * tools/console.c: - add support for flag passthrough * tools/console.h: - modify function prototypes to match impl. * tools/virsh.c: - add flag --force for the console command --- tools/console.c | 5 +++-- tools/console.h | 3 ++- tools/virsh.c | 24 +++++++++++++++++++----- tools/virsh.pod | 8 +++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/tools/console.c b/tools/console.c index 4a32522..ca226c3 100644 --- a/tools/console.c +++ b/tools/console.c @@ -299,7 +299,8 @@ vshGetEscapeChar(const char *s) int vshRunConsole(virDomainPtr dom, const char *dev_name, - const char *escape_seq) + const char *escape_seq, + unsigned int flags) { int ret = -1; struct termios ttyattr, rawattr; @@ -353,7 +354,7 @@ int vshRunConsole(virDomainPtr dom, if (!con->st) goto cleanup; - if (virDomainOpenConsole(dom, dev_name, con->st, 0) < 0) + if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0) goto cleanup; if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0) diff --git a/tools/console.h b/tools/console.h index 8cca08f..2b5440c 100644 --- a/tools/console.h +++ b/tools/console.h @@ -27,7 +27,8 @@ int vshRunConsole(virDomainPtr dom, const char *dev_name, - const char *escape_seq); + const char *escape_seq, + unsigned int flags); # endif /* !WIN32 */ diff --git a/tools/virsh.c b/tools/virsh.c index 1613d2e..c6d642f 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -819,11 +819,17 @@ static const vshCmdInfo info_console[] = { static const vshCmdOptDef opts_console[] = { {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"devname", VSH_OT_STRING, 0, N_("character device name")}, + {"force", VSH_OT_BOOL, 0, + N_("force console connection (disconnect already connected sessions)")}, + {"safe", VSH_OT_BOOL, 0, + N_("only connect if safe console handling is supported")}, {NULL, 0, 0, NULL} }; static bool -cmdRunConsole(vshControl *ctl, virDomainPtr dom, const char *name) +cmdRunConsole(vshControl *ctl, virDomainPtr dom, + const char *name, + unsigned int flags) { bool ret = false; int state; @@ -840,7 +846,7 @@ cmdRunConsole(vshControl *ctl, virDomainPtr dom, const char *name) vshPrintExtra(ctl, _("Connected to domain %s\n"), virDomainGetName(dom)); vshPrintExtra(ctl, _("Escape character is %s\n"), ctl->escapeChar); - if (vshRunConsole(dom, name, ctl->escapeChar) == 0) + if (vshRunConsole(dom, name, ctl->escapeChar, flags) == 0) ret = true; cleanup: @@ -853,6 +859,9 @@ cmdConsole(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom; bool ret = false; + bool force = vshCommandOptBool(cmd, "force"); + bool safe = vshCommandOptBool(cmd, "safe"); + unsigned int flags = 0; const char *name = NULL; if (!vshConnectionUsability(ctl, ctl->conn)) @@ -866,7 +875,12 @@ cmdConsole(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - ret = cmdRunConsole(ctl, dom, name); + if (force) + flags |= VIR_DOMAIN_CONSOLE_FORCE; + if (safe) + flags |= VIR_DOMAIN_CONSOLE_SAFE; + + ret = cmdRunConsole(ctl, dom, name, flags); cleanup: virDomainFree(dom); @@ -2477,7 +2491,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) virDomainGetName(dom), from); #ifndef WIN32 if (console) - cmdRunConsole(ctl, dom, NULL); + cmdRunConsole(ctl, dom, NULL, 0); #endif virDomainFree(dom); } else { @@ -2982,7 +2996,7 @@ started: vshPrint(ctl, _("Domain %s started\n"), virDomainGetName(dom)); #ifndef WIN32 - if (console && !cmdRunConsole(ctl, dom, NULL)) + if (console && !cmdRunConsole(ctl, dom, NULL, 0)) goto cleanup; #endif diff --git a/tools/virsh.pod b/tools/virsh.pod index a85da13..2e02c5a 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -405,13 +405,19 @@ Configure a domain to be automatically started at boot. The option I<--disable> disables autostarting. -=item B<console> I<domain-id> [I<devname>] +=item B<console> I<domain-id> [I<devname>] [I<--safe>] [I<--force>] Connect the virtual serial console for the guest. The optional I<devname> parameter refers to the device alias of an alternate console, serial or parallel device configured for the guest. If omitted, the primary console will be opened. +If the flag I<--safe> is specified, the connection is only attempted +if the driver supports safe console handling. This flag specifies that +the server has to ensure exclusive access to console devices. Optionally +the I<--force> flag may be specified, requesting to disconnect any existing +sessions, such as in a case of a broken connection. + =item B<create> I<FILE> [I<--console>] [I<--paused>] [I<--autodestroy>] Create a domain from an XML <file>. An easy way to create the XML -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list