From: Daniel P. Berrange Date: Fri, 22 Oct 2010 13:40:26 +0000 (+0100) Subject: Wire up virDomainOpenConsole for LXC, Xen and UML X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5fb9db272d0048f216047eb782ef76a455f0d024;p=libvirt.git Wire up virDomainOpenConsole for LXC, Xen and UML 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 --- diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 24450e526b..f5014cbd2c 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -52,6 +52,7 @@ #include "stats_linux.h" #include "hooks.h" #include "files.h" +#include "fdstream.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -2730,6 +2731,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 = { @@ -2836,7 +2901,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 d90db934ae..358889475e 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -60,6 +60,7 @@ #include "logging.h" #include "domain_nwfilter.h" #include "files.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 1c2e732a34..168b619f80 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,7 @@ #include "node_device_conf.h" #include "pci.h" #include "uuid.h" +#include "fdstream.h" #define VIR_FROM_THIS VIR_FROM_XEN @@ -1928,6 +1930,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. */ @@ -2035,7 +2091,7 @@ static virDriver xenUnifiedDriver = { NULL, /* qemuDomainMonitorCommand */ NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ - NULL, /* domainOpenConsole */ + xenUnifiedDomainOpenConsole, /* domainOpenConsole */ }; /**