* 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->console)
+ chr = vm->def->console;
+ else if (vm->def->nserials)
+ chr = vm->def->serials[0];
+ }
+
+ if (!chr) {
+ umlReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find character device %s"), devname);
+ goto cleanup;
+ }
+
+ if (chr->type != VIR_DOMAIN_CHR_TYPE_PTY) {
+ umlReportError(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);
+ umlDriverUnlock(driver);
+ return ret;
+}
+
static virDriver umlDriver = {
VIR_DRV_UML,
@@ -2200,7 +2265,7 @@ static virDriver umlDriver = {
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainSetMemoryParamters */
NULL, /* domainGetMemoryParamters */
- NULL, /* domainOpenConsole */
+ umlDomainOpenConsole, /* domainOpenConsole */
};
static int
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 9cc46ae..008a4c9 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <sys/types.h>
+#include <fcntl.h>
#include <xen/dom0_ops.h>
#include <libxml/uri.h>
@@ -46,6 +47,7 @@
#include "node_device_conf.h"
#include "pci.h"
#include "uuid.h"
+#include "fdstream.h"
#define VIR_FROM_THIS VIR_FROM_XEN
@@ -1980,6 +1982,61 @@ out:
}
+static int
+xenUnifiedDomainOpenConsole(virDomainPtr dom,
+ const char *devname,
+ virStreamPtr st,
+ unsigned int flags)
+{
+ virDomainDefPtr def = NULL;
+ int ret = -1;
+ virDomainChrDefPtr chr = NULL;
+
+ virCheckFlags(0, -1);
+
+ if (dom->id == -1) {
+ xenUnifiedError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ if (devname) {
+ /* XXX support device aliases in future */
+ xenUnifiedError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Named device aliases are not supported"));
+ goto cleanup;
+ }
+
+ def = xenDaemonDomainFetch(dom->conn, dom->id, dom->name, NULL);
+ if (!def)
+ goto cleanup;
+
+ if (def->console)
+ chr = def->console;
+ else if (def->nserials)
+ chr = def->serials[0];
+
+ if (!chr) {
+ xenUnifiedError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot find default console device"));
+ goto cleanup;
+ }
+
+ if (chr->type != VIR_DOMAIN_CHR_TYPE_PTY) {
+ xenUnifiedError(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 (def)
+ virDomainDefFree(def);
+ return ret;
+}
/*----- Register with libvirt.c, and initialize Xen drivers. -----*/
/* The interface which we export upwards to libvirt.c. */
@@ -2087,7 +2144,7 @@ static virDriver xenUnifiedDriver = {
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainSetMemoryParameters */
NULL, /* domainGetMemoryParameters */
- NULL, /* domainOpenConsole */
+ xenUnifiedDomainOpenConsole, /* domainOpenConsole */
};
/**
--
1.7.2.3