From: "Daniel P. Berrange" <berrange(a)redhat.com>
To allow virDomainOpenConsole to access non-primary consoles,
device aliases are required to be set. Until now only the QEMU
driver has done this. Update LXC & UML to set aliases for any
console devices
* src/lxc/lxc_driver.c, src/uml/uml_driver.c: Set aliases
for console devices
---
src/lxc/lxc_driver.c | 30 ++++++++++++++++++++++++------
src/uml/uml_driver.c | 41 +++++++++++++++++++++++++++++++++++------
2 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 8e02676..037d781 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1681,6 +1681,14 @@ static int lxcVmStart(virConnectPtr conn,
return -1;
}
+ /* Do this upfront, so any part of the startup process can add
+ * runtime state to vm->def that won't be persisted. This let's us
+ * report implicit runtime defaults in the XML, like vnc listen/socket
+ */
+ VIR_DEBUG("Setting current domain def as transient");
+ if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0)
+ goto cleanup;
+
/* Here we open all the PTYs we need on the host OS side.
* The LXC controller will open the guest OS side PTYs
* forward I/O between them.
@@ -1709,6 +1717,12 @@ static int lxcVmStart(virConnectPtr conn,
VIR_FREE(vm->def->consoles[i]->source.data.file.path);
vm->def->consoles[i]->source.data.file.path = ttyPath;
+
+ VIR_FREE(vm->def->consoles[i]->info.alias);
+ if (virAsprintf(&vm->def->consoles[i]->info.alias,
"console%zu", i) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
}
if (lxcSetupInterfaces(conn, vm->def, &nveths, &veths) != 0)
@@ -3020,6 +3034,7 @@ lxcDomainOpenConsole(virDomainPtr dom,
char uuidstr[VIR_UUID_STRING_BUFLEN];
int ret = -1;
virDomainChrDefPtr chr = NULL;
+ size_t i;
virCheckFlags(0, -1);
@@ -3039,10 +3054,12 @@ lxcDomainOpenConsole(virDomainPtr dom,
}
if (dev_name) {
- /* XXX support device aliases in future */
- lxcError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Named device aliases are not supported"));
- goto cleanup;
+ for (i = 0 ; i < vm->def->nconsoles ; i++) {
+ if (STREQ(vm->def->consoles[i]->info.alias, dev_name)) {
+ chr = vm->def->consoles[i];
+ break;
+ }
+ }
} else {
if (vm->def->nconsoles)
chr = vm->def->consoles[0];
@@ -3051,8 +3068,9 @@ lxcDomainOpenConsole(virDomainPtr dom,
}
if (!chr) {
- lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot find default console device"));
+ lxcError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find console device '%s'"),
+ dev_name ? dev_name : _("default"));
goto cleanup;
}
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 44529f0..c9fe0ac 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -987,11 +987,12 @@ static int umlStartVMDaemon(virConnectPtr conn,
struct uml_driver *driver,
virDomainObjPtr vm,
bool autoDestroy) {
- int ret;
+ int ret = -1;
char *logfile;
int logfd = -1;
umlDomainObjPrivatePtr priv = vm->privateData;
virCommandPtr cmd = NULL;
+ size_t i;
if (virDomainObjIsActive(vm)) {
umlReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -1045,6 +1046,16 @@ static int umlStartVMDaemon(virConnectPtr conn,
return -1;
}
+ /* Do this upfront, so any part of the startup process can add
+ * runtime state to vm->def that won't be persisted. This let's us
+ * report implicit runtime defaults in the XML, like vnc listen/socket
+ */
+ VIR_DEBUG("Setting current domain def as transient");
+ if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0) {
+ VIR_FORCE_CLOSE(logfd);
+ return -1;
+ }
+
if (!(cmd = umlBuildCommandLine(conn, driver, vm))) {
VIR_FORCE_CLOSE(logfd);
virDomainConfVMNWFilterTeardown(vm);
@@ -1052,6 +1063,14 @@ static int umlStartVMDaemon(virConnectPtr conn,
return -1;
}
+ for (i = 0 ; i < vm->def->nconsoles ; i++) {
+ VIR_FREE(vm->def->consoles[i]->info.alias);
+ if (virAsprintf(&vm->def->consoles[i]->info.alias,
"console%zu", i) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
virCommandWriteArgLog(cmd, logfd);
priv->monitor = -1;
@@ -1077,6 +1096,12 @@ cleanup:
if (ret < 0) {
virDomainConfVMNWFilterTeardown(vm);
umlCleanupTapDevices(vm);
+ if (vm->newDef) {
+ virDomainDefFree(vm->def);
+ vm->def = vm->newDef;
+ vm->def->id = -1;
+ vm->newDef = NULL;
+ }
}
/* NB we don't mark it running here - we do that async
@@ -2366,6 +2391,7 @@ umlDomainOpenConsole(virDomainPtr dom,
char uuidstr[VIR_UUID_STRING_BUFLEN];
int ret = -1;
virDomainChrDefPtr chr = NULL;
+ size_t i;
virCheckFlags(0, -1);
@@ -2385,10 +2411,12 @@ umlDomainOpenConsole(virDomainPtr dom,
}
if (dev_name) {
- /* XXX support device aliases in future */
- umlReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Named device aliases are not supported"));
- goto cleanup;
+ for (i = 0 ; i < vm->def->nconsoles ; i++) {
+ if (STREQ(vm->def->consoles[i]->info.alias, dev_name)) {
+ chr = vm->def->consoles[i];
+ break;
+ }
+ }
} else {
if (vm->def->nconsoles)
chr = vm->def->consoles[0];
@@ -2398,7 +2426,8 @@ umlDomainOpenConsole(virDomainPtr dom,
if (!chr) {
umlReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot find character device %s"), dev_name);
+ _("cannot find console device '%s'"),
+ dev_name ? dev_name : _("default"));
goto cleanup;
}
--
1.7.6.4