virDomainDefFree(dom->def);
virDomainDefFree(dom->newDef);
- VIR_FREE(dom->monitorpath);
+ virDomainChrDefFree(dom->monitor_chr);
+
VIR_FREE(dom->vcpupids);
virMutexDestroy(&dom->lock);
xmlNodePtr config;
xmlNodePtr oldnode;
virDomainObjPtr obj;
+ char *monitorpath;
if (!(obj = virDomainObjNew(conn)))
return NULL;
}
obj->pid = (pid_t)val;
- if(!(obj->monitorpath =
- virXPathString(conn, "string(./monitor[1]/@path)", ctxt))) {
+ if (VIR_ALLOC(obj->monitor_chr) < 0) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ if (!(monitorpath =
+ virXPathString(conn, "string(./monitor[1]/@path)", ctxt))) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("no monitor path"));
goto error;
}
+ tmp = virXPathString(conn, "string(./monitor[1]/@type)", ctxt);
+ if (tmp)
+ obj->monitor_chr->type = virDomainChrTypeFromString(tmp);
+ else
+ obj->monitor_chr->type = VIR_DOMAIN_CHR_TYPE_PTY;
+ VIR_FREE(tmp);
+
+ switch (obj->monitor_chr->type) {
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ obj->monitor_chr->data.file.path = monitorpath;
+ break;
+ default:
+ VIR_FREE(monitorpath);
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unsupported monitor type '%s'"),
+ virDomainChrTypeToString(obj->monitor_chr->type));
+ break;
+ }
+
return obj;
error:
+ virDomainChrDefFree(obj->monitor_chr);
virDomainObjFree(obj);
return NULL;
}
{
char *config_xml = NULL, *xml = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ const char *monitorpath;
virBufferVSprintf(&buf, "<domstatus state='%s' pid='%d'>\n",
virDomainStateTypeToString(obj->state),
obj->pid);
- virBufferEscapeString(&buf, " <monitor path='%s'/>\n", obj->monitorpath);
+
+ switch (obj->monitor_chr->type) {
+ default:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ monitorpath = obj->monitor_chr->data.file.path;
+ break;
+ }
+
+ virBufferEscapeString(&buf, " <monitor path='%s'", monitorpath);
+ virBufferVSprintf(&buf, " type='%s'/>\n",
+ virDomainChrTypeToString(obj->monitor_chr->type));
if (!(config_xml = virDomainDefFormat(conn,
obj->def,
static int qemudOpenMonitor(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm,
- const char *monitor,
int reconnect);
{
int rc;
- if ((rc = qemudOpenMonitor(NULL, driver, obj, obj->monitorpath, 1)) != 0) {
+ if ((rc = qemudOpenMonitor(NULL, driver, obj, 1)) != 0) {
VIR_ERROR(_("Failed to reconnect monitor for %s: %d\n"),
obj->def->name, rc);
goto error;
}
static int
-qemudOpenMonitor(virConnectPtr conn,
- struct qemud_driver* driver,
- virDomainObjPtr vm,
- const char *monitor,
- int reconnect)
+qemudOpenMonitorCommon(virConnectPtr conn,
+ struct qemud_driver* driver,
+ virDomainObjPtr vm,
+ int monfd,
+ int reconnect)
{
- int monfd;
char buf[1024];
- int ret = -1;
+ int ret;
- if ((monfd = open(monitor, O_RDWR)) < 0) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Unable to open monitor path %s"), monitor);
- return -1;
- }
if (virSetCloseExec(monfd) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to set monitor close-on-exec flag"));
- goto error;
+ return -1;
}
if (virSetNonBlock(monfd) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to put monitor into non-blocking mode"));
- goto error;
+ return -1;
}
if (!reconnect) {
}
if (ret != 0)
- goto error;
+ return ret;
if ((vm->monitorWatch = virEventAddHandle(vm->monitor, 0,
qemudDispatchVMEvent,
driver, NULL)) < 0)
- goto error;
+ return -1;
+ return 0;
+}
- /* Keep monitor open upon success */
- if (ret == 0)
- return ret;
+static int
+qemudOpenMonitorPty(virConnectPtr conn,
+ struct qemud_driver* driver,
+ virDomainObjPtr vm,
+ const char *monitor,
+ int reconnect)
+{
+ int monfd;
- error:
+ if ((monfd = open(monitor, O_RDWR)) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Unable to open monitor path %s"), monitor);
+ return -1;
+ }
+
+ if (qemudOpenMonitorCommon(conn, driver, vm, monfd, reconnect) < 0)
+ goto error;
+
+ return 0;
+
+error:
close(monfd);
- return ret;
+ return -1;
+}
+
+static int
+qemudOpenMonitor(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ int reconnect)
+{
+ switch (vm->monitor_chr->type) {
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ return qemudOpenMonitorPty(conn, driver, vm,
+ vm->monitor_chr->data.file.path,
+ reconnect);
+ default:
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unable to handle monitor type: %s"),
+ virDomainChrTypeToString(vm->monitor_chr->type));
+ return -1;
+ }
}
/* Returns -1 for error, 0 success, 1 continue reading */
}
/* Got them all, so now open the monitor console */
- if ((ret = qemudOpenMonitor(conn, driver, vm, monitor, 0)) != 0)
- goto cleanup;
+ vm->monitor_chr->data.file.path = monitor;
+ monitor = NULL;
- vm->monitorpath = monitor;
+ if ((ret = qemudOpenMonitor(conn, driver, vm, 0)) != 0)
+ goto cleanup;
return 0;
if (qemuPrepareHostDevices(conn, vm->def) < 0)
goto cleanup;
+ if (VIR_ALLOC(vm->monitor_chr) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
+
+ vm->monitor_chr->type = VIR_DOMAIN_CHR_TYPE_PTY;
+
if ((ret = virFileDeletePid(driver->stateDir, vm->def->name)) != 0) {
virReportSystemError(conn, ret,
_("Cannot remove stale PID file for %s"),
}
vm->def->id = driver->nextvmid++;
- if (qemudBuildCommandLine(conn, driver, vm->def,
+ if (qemudBuildCommandLine(conn, driver, vm->def, vm->monitor_chr,
qemuCmdFlags, &argv, &progenv,
&tapfds, &ntapfds, migrateFrom) < 0)
goto cleanup;
unsigned int flags ATTRIBUTE_UNUSED) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def = NULL;
+ virDomainChrDef monitor_chr;
const char *emulator;
unsigned int qemuCmdFlags;
struct stat sb;
goto cleanup;
}
+ monitor_chr.type = VIR_DOMAIN_CHR_TYPE_PTY;
if (qemudBuildCommandLine(conn, driver, def,
- qemuCmdFlags,
+ &monitor_chr, qemuCmdFlags,
&retargv, &retenv,
NULL, NULL, /* Don't want it to create TAP devices */
NULL) < 0) {