Introduce implementations of the virDomainOpenConsole() API for LXC, Xen and UML drivers. * 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 | 58 +++++++++++++++++++++++++++++++++++++- 3 files changed, 194 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..cc96d1a 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,60 @@ 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: + virDomainDefFree(def); + return ret; +} /*----- Register with libvirt.c, and initialize Xen drivers. -----*/ /* The interface which we export upwards to libvirt.c. */ @@ -2087,7 +2143,7 @@ static virDriver xenUnifiedDriver = { NULL, /* qemuDomainMonitorCommand */ NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ - NULL, /* domainOpenConsole */ + xenUnifiedDomainOpenConsole, /* domainOpenConsole */ }; /** -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list