* src/lxc/lxc_driver.c, src/lxc/lxc_driver.c,
src/xen/xen_driver.c: Wire up virDomainOpenConsole
---
src/lxc/lxc_driver.c | 67 ++-
src/uml/uml_driver.c | 77 ++
src/xen/xen_driver.c | 59 +-
3 files changed, 195 insertions(+), 8 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 48a38d1..f0d16a7 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -51,6 +51,7 @@
#include "uuid.h"
#include "stats_linux.h"
#include "hooks.h"
+#include "fdstream.h"
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -2738,6 +2739,70 @@ cleanup:
return ret;
}
+static int
+lxcDomainOpenConsole(virDomainPtr dom,
+ const char *devname,
+ virStreamPtr st,
+ unsigned int flags)
+{
+lxc_driver_t *driver = dom->conn->privateData;
+virDomainObjPtr vm = NULL;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+int ret = -1;
+virDomainChrDefPtr chr = NULL;
+
+virCheckFlags(0, -1);
+
+lxcDriverLock(driver);
+virUUIDFormat(dom->uuid, uuidstr);
+vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+if (!vm) {
+lxcError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+goto cleanup;
+}
+
+if (!virDomainObjIsActive(vm)) {
+lxcError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+goto cleanup;
+}
+
+if (devname) {
+/* XXX support device aliases in future */
+lxcError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Named device aliases are not supported"));
+goto cleanup;
+} else {
+if (vm->def->console)
+chr = vm->def->console;
+else if (vm->def->nserials)
+chr = vm->def->serials[0];
+}
+
+if (!chr) {
+lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot find default console device"));
+goto cleanup;
+}
+
+if (chr->type != VIR_DOMAIN_CHR_TYPE_PTY) {
+lxcError(VIR_ERR_INTERNAL_ERROR,
+ _("character device %s is not using a PTY"), devname);
+goto cleanup;
+}
+
+if (virFDStreamOpenFile(st, chr->data.file.path, O_RDWR) < 0)
+goto cleanup;
+
+ret = 0;
+cleanup:
+if (vm)
+virDomainObjUnlock(vm);
+lxcDriverUnlock(driver);
+return ret;
+}
+
/* Function Tables */
static virDriver lxcDriver = {
@@ -2844,7 +2909,7 @@ static virDriver lxcDriver = {
NULL, /* qemuDomainMonitorCommand */
lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */
lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */
-NULL, /* domainOpenConsole */
+lxcDomainOpenConsole, /* domainOpenConsole */
};
static virStateDriver lxcStateDriver = {
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index e0bb4e5..e54db3d 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -59,6 +59,7 @@
#include "datatypes.h"
#include "logging.h"
#include "domain_nwfilter.h"
+#include "fdstream.h"
#define VIR_FROM_THIS VIR_FROM_UML
@@ -2025,11 +2026,11 @@ cleanup:
static int
-umlDomainBlockPeek (virDomainPtr dom,
- const char *path,
- unsigned long long offset, size_t size,
- void *buffer,
- unsigned int flags ATTRIBUTE_UNUSED)
+umlDomainBlockPeek(virDomainPtr dom,
+ const char *path,
+ unsigned long long offset, size_t size,
+ void *buffer,
+ unsigned int flags ATTRIBUTE_UNUSED)
{
struct uml_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
@@ -2095,6 +2096,70 @@ cleanup:
}
+static int
+umlDomainOpenConsole(virDomainPtr dom,
+ const char *devname,
+ virStreamPtr st,
+ unsigned int flags)
+{
+struct uml_driver *driver = dom->conn->privateData;
+virDomainObjPtr vm = NULL;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+int ret = -1;
+virDomainChrDefPtr chr = NULL;
+
+virCheckFlags(0, -1);
+
+umlDriverLock(driver);
+virUUIDFormat(dom->uuid, uuidstr);
+vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+if (!vm) {
+umlReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+goto cleanup;
+}
+
+if (!virDomainObjIsActive(vm)) {
+umlReportError(VIR_ERR_OPERATION_INVALID,
+"%s", _("domain is not running"));
+goto cleanup;
+}
+
+if (devname) {
+/* XXX support device aliases in future */
+umlReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Named device aliases are not supported"));
+goto cleanup;
+} else {
+if (vm->def->con