[Adding Jim as there was past discussion about serials/consoles]
On 08/03/2016 02:29 AM, Bob Liu wrote:
Add support for multi serial devices, after this patch virsh can be
used to
connect different serial devices of running domains. E.g.
vish # console <xxx> --devname serial<xxx>
Signed-off-by: Bob Liu <bob.liu(a)oracle.com>
---
Through some internal review it slipped that serial list is only supported from
Xen
= 4.5 (see below). Also for folks seeing this patch, it should be
noted that this
depends on a bug fix to have libxl_console_get_tty(...) correctly
returning the tty
path (as opposed to always returning the first one).
[0]
https://lists.xen.org/archives/html/xen-devel/2016-08/msg00438.html
src/libxl/libxl_conf.c | 25 ++++++++++++++++++-------
src/libxl/libxl_domain.c | 23 +++++++++++++++++++++++
src/libxl/libxl_driver.c | 17 +++++++++--------
3 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 146e08a..685a5ad 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -431,14 +431,25 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
}
if (def->nserials) {
- if (def->nserials > 1) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s",
- _("Only one serial device is supported by
libxl"));
- return -1;
+ if (def->nserials == 1) {
+ if (libxlMakeChrdevStr(def->serials[0], &b_info->u.hvm.serial)
<
+ 0)
+ return -1;
+ } else {
+ if (VIR_ALLOC_N(b_info->u.hvm.serial_list, def->nserials + 1)
<
+ 0)
+ return -1;
+
+ for (i = 0; i < def->nserials; i++) {
+ if (libxlMakeChrdevStr(def->serials[i],
+ &b_info->u.hvm.serial_list[i]) <
0)
+ {
+ libxl_string_list_dispose(&b_info->u.hvm.serial_list);
+ return -1;
+ }
+ }
+ b_info->u.hvm.serial_list[i] = NULL;
This particular chunk
needs to be surrounded with LIBXL_HAVE_BUILDINFO_SERIAL_LIST
(otherwise it would break compilation) and then warn the user that it's not supported
for Xen 4.4. Something like:
#ifdef LIBXL_HAVE_BUILDINFO_SERIAL_LIST
if (VIR_ALLOC_N(b_info->u.hvm.serial_list, def->nserials + 1) <
0)
return -1;
for (i = 0; i < def->nserials; i++) {
if (libxlMakeChrdevStr(def->serials[i],
&b_info->u.hvm.serial_list[i]) < 0)
{
libxl_string_list_dispose(&b_info->u.hvm.serial_list);
return -1;
}
}
b_info->u.hvm.serial_list[i] = NULL;
#else
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s",
_("Only one serial device is supported by
libxl"));
return -1;
#endif
}
- if (libxlMakeChrdevStr(def->serials[0], &b_info->u.hvm.serial)
< 0)
- return -1;
}
if (def->nparallels) {
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 0e26b91..82fe9e8 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -989,6 +989,29 @@ libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void
*for_callback)
VIR_FREE(console);
}
}
+ for (i = 0; i < vm->def->nserials; i++) {
+ virDomainChrDefPtr chr = vm->def->serials[i];
+ char *console = NULL;
+ int ret;
+
+ if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
+ ignore_value(virAsprintf(&chr->info.alias, "serial%zd",
i));
It's probably worth setting alias before this if, since it's general to
all serial types.
+ if (chr->source.data.file.path)
+ continue;
+ ret = libxl_console_get_tty(ctx, ev->domid,
+ chr->target.port,
+ LIBXL_CONSOLE_TYPE_SERIAL,
+ &console);
+ if (!ret) {
+ VIR_FREE(chr->source.data.file.path);
+ if (console && console[0] != '\0') {
+ ignore_value(VIR_STRDUP(chr->source.data.file.path,
+ console));
+ }
+ }
+ VIR_FREE(console);
+ }
+ }
virObjectUnlock(vm);
libxl_event_free(ctx, ev);
}
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index f153f69..a34eb02 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -4450,13 +4450,6 @@ libxlDomainOpenConsole(virDomainPtr dom,
virCheckFlags(VIR_DOMAIN_CONSOLE_FORCE, -1);
- if (dev_name) {
- /* XXX support device aliases in future */
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Named device aliases are not supported"));
- goto cleanup;
- }
-
if (!(vm = libxlDomObjFromDomain(dom)))
goto cleanup;
@@ -4472,8 +4465,16 @@ libxlDomainOpenConsole(virDomainPtr dom,
}
priv = vm->privateData;
+ if (dev_name) {
+ size_t i;
- if (vm->def->nconsoles) {
+ for (i = 0; !chr && i < vm->def->nserials; i++) {
+ if (STREQ(dev_name, vm->def->serials[i]->info.alias)) {
+ chr = vm->def->serials[i];
+ break;
+ }
+ }
+ } else if (vm->def->nconsoles) {
chr = vm->def->consoles[0];
if (chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
chr = vm->def->serials[0];