mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
* src/domain_conf.h src/qemu_driver.c: use monitor fd for QEmu/KVM
domain shutdown and read saved vm status on libvirtd startup, last 2 patches from Guido Günther finishing up the surviving the libvirt daemon restart daniel
This commit is contained in:
parent
103ee5d4c2
commit
6d004d3f8a
@ -1,3 +1,10 @@
|
|||||||
|
Tue Jan 20 16:48:00 CET 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/domain_conf.h src/qemu_driver.c: use monitor fd for QEmu/KVM
|
||||||
|
domain shutdown and read saved vm status on libvirtd startup,
|
||||||
|
last 2 patches from Guido Günther finishing up the surviving the
|
||||||
|
libvirt daemon restart
|
||||||
|
|
||||||
Tue Jan 20 16:35:24 CET 2009 Daniel Veillard <veillard@redhat.com>
|
Tue Jan 20 16:35:24 CET 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* docs/apibuild.py: fix the parser with another Win32 keyword
|
* docs/apibuild.py: fix the parser with another Win32 keyword
|
||||||
|
@ -465,6 +465,7 @@ struct _virDomainObj {
|
|||||||
int stderr_fd;
|
int stderr_fd;
|
||||||
int stderr_watch;
|
int stderr_watch;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
int monitor_watch;
|
||||||
char *monitorpath;
|
char *monitorpath;
|
||||||
int monitorWatch;
|
int monitorWatch;
|
||||||
int logfile;
|
int logfile;
|
||||||
|
@ -181,6 +181,45 @@ qemudLogFD(virConnectPtr conn, const char* logDir, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemudLogReadFD(virConnectPtr conn, const char* logDir, const char* name, off_t pos)
|
||||||
|
{
|
||||||
|
char logfile[PATH_MAX];
|
||||||
|
mode_t logmode = O_RDONLY;
|
||||||
|
int ret, fd = -1;
|
||||||
|
|
||||||
|
if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
|
||||||
|
< 0 || ret >= sizeof(logfile)) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("failed to build logfile name %s/%s.log"),
|
||||||
|
logDir, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((fd = open(logfile, logmode)) < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("failed to create logfile %s: %s"),
|
||||||
|
logfile, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (qemudSetCloseExec(fd) < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to set VM logfile close-on-exec flag: %s"),
|
||||||
|
strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to seek to %lld in %s: %s"),
|
||||||
|
pos, logfile, strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemudAutostartConfigs(struct qemud_driver *driver) {
|
qemudAutostartConfigs(struct qemud_driver *driver) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -258,6 +297,84 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int qemudOpenMonitor(virConnectPtr conn,
|
||||||
|
struct qemud_driver* driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *monitor,
|
||||||
|
int reconnect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemudReconnectVMs
|
||||||
|
*
|
||||||
|
* Reconnect running vms to the daemon process
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qemudReconnectVMs(struct qemud_driver *driver)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < driver->domains.count ; i++) {
|
||||||
|
virDomainObjPtr vm = driver->domains.objs[i];
|
||||||
|
qemudDomainStatusPtr status = NULL;
|
||||||
|
char *config = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
virDomainObjLock(vm);
|
||||||
|
if ((rc = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) == 0)
|
||||||
|
DEBUG("Found pid %d for '%s'", vm->pid, vm->def->name);
|
||||||
|
else
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
if ((config = virDomainConfigFile(NULL,
|
||||||
|
driver->stateDir,
|
||||||
|
vm->def->name)) == NULL) {
|
||||||
|
qemudLog(QEMUD_ERR, _("Failed to read domain status for %s\n"),
|
||||||
|
vm->def->name);
|
||||||
|
goto next_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = qemudDomainStatusParseFile(NULL, driver->caps, config, 0);
|
||||||
|
if (status) {
|
||||||
|
vm->newDef = vm->def;
|
||||||
|
vm->def = status->def;
|
||||||
|
} else {
|
||||||
|
qemudLog(QEMUD_ERR, _("Failed to parse domain status for %s\n"),
|
||||||
|
vm->def->name);
|
||||||
|
goto next_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rc = qemudOpenMonitor(NULL, driver, vm, status->monitorpath, 1)) != 0) {
|
||||||
|
qemudLog(QEMUD_ERR, _("Failed to reconnect monitor for %s: %d\n"),
|
||||||
|
vm->def->name, rc);
|
||||||
|
goto next_error;
|
||||||
|
} else
|
||||||
|
vm->monitorpath = status->monitorpath;
|
||||||
|
|
||||||
|
if((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (vm->def->id >= driver->nextvmid)
|
||||||
|
driver->nextvmid = vm->def->id + 1;
|
||||||
|
|
||||||
|
vm->state = status->state;
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
next_error:
|
||||||
|
/* we failed to reconnect the vm so remove it's traces */
|
||||||
|
vm->def->id = -1;
|
||||||
|
qemudRemoveDomainStatus(NULL, driver, vm);
|
||||||
|
virDomainDefFree(vm->def);
|
||||||
|
vm->def = vm->newDef;
|
||||||
|
vm->newDef = NULL;
|
||||||
|
next:
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
VIR_FREE(status);
|
||||||
|
VIR_FREE(config);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemudStartup:
|
* qemudStartup:
|
||||||
*
|
*
|
||||||
@ -357,6 +474,7 @@ qemudStartup(void) {
|
|||||||
qemu_driver->autostartDir,
|
qemu_driver->autostartDir,
|
||||||
NULL, NULL) < 0)
|
NULL, NULL) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
qemudReconnectVMs(qemu_driver);
|
||||||
qemudAutostartConfigs(qemu_driver);
|
qemudAutostartConfigs(qemu_driver);
|
||||||
|
|
||||||
qemuDriverUnlock(qemu_driver);
|
qemuDriverUnlock(qemu_driver);
|
||||||
@ -449,7 +567,6 @@ qemudActive(void) {
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
qemudShutdown(void) {
|
qemudShutdown(void) {
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (!qemu_driver)
|
if (!qemu_driver)
|
||||||
return -1;
|
return -1;
|
||||||
@ -457,15 +574,6 @@ qemudShutdown(void) {
|
|||||||
qemuDriverLock(qemu_driver);
|
qemuDriverLock(qemu_driver);
|
||||||
virCapabilitiesFree(qemu_driver->caps);
|
virCapabilitiesFree(qemu_driver->caps);
|
||||||
|
|
||||||
/* shutdown active VMs */
|
|
||||||
for (i = 0 ; i < qemu_driver->domains.count ; i++) {
|
|
||||||
virDomainObjPtr dom = qemu_driver->domains.objs[i];
|
|
||||||
virDomainObjLock(dom);
|
|
||||||
if (virDomainIsActive(dom))
|
|
||||||
qemudShutdownVMDaemon(NULL, qemu_driver, dom);
|
|
||||||
virDomainObjUnlock(dom);
|
|
||||||
}
|
|
||||||
|
|
||||||
virDomainObjListFree(&qemu_driver->domains);
|
virDomainObjListFree(&qemu_driver->domains);
|
||||||
|
|
||||||
VIR_FREE(qemu_driver->logDir);
|
VIR_FREE(qemu_driver->logDir);
|
||||||
@ -516,11 +624,7 @@ qemudReadMonitorOutput(virConnectPtr conn,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = read(fd, buf+got, buflen-got-1);
|
ret = read(fd, buf+got, buflen-got-1);
|
||||||
if (ret == 0) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("QEMU quit during %s startup\n%s"), what, buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
@ -584,8 +688,10 @@ qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int qemudOpenMonitor(virConnectPtr conn,
|
static int qemudOpenMonitor(virConnectPtr conn,
|
||||||
|
struct qemud_driver* driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *monitor) {
|
const char *monitor,
|
||||||
|
int reconnect) {
|
||||||
int monfd;
|
int monfd;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -606,11 +712,19 @@ static int qemudOpenMonitor(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemudReadMonitorOutput(conn,
|
if (!reconnect) {
|
||||||
vm, monfd,
|
ret = qemudReadMonitorOutput(conn,
|
||||||
buf, sizeof(buf),
|
vm, monfd,
|
||||||
qemudCheckMonitorPrompt,
|
buf, sizeof(buf),
|
||||||
"monitor", 10000);
|
qemudCheckMonitorPrompt,
|
||||||
|
"monitor", 10000);
|
||||||
|
} else {
|
||||||
|
vm->monitor = monfd;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!(vm->monitorpath = strdup(monitor))) {
|
if (!(vm->monitorpath = strdup(monitor))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
||||||
@ -618,6 +732,12 @@ static int qemudOpenMonitor(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((vm->monitor_watch = virEventAddHandle(vm->monitor, 0,
|
||||||
|
qemudDispatchVMEvent,
|
||||||
|
driver, NULL)) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
/* Keep monitor open upon success */
|
/* Keep monitor open upon success */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -677,6 +797,7 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
|
|||||||
const char *output,
|
const char *output,
|
||||||
int fd ATTRIBUTE_UNUSED)
|
int fd ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
struct qemud_driver* driver = conn->privateData;
|
||||||
char *monitor = NULL;
|
char *monitor = NULL;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
@ -711,7 +832,7 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Got them all, so now open the monitor console */
|
/* Got them all, so now open the monitor console */
|
||||||
ret = qemudOpenMonitor(conn, vm, monitor);
|
ret = qemudOpenMonitor(conn, driver, vm, monitor, 0);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(monitor);
|
VIR_FREE(monitor);
|
||||||
@ -719,21 +840,23 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int qemudWaitForMonitor(virConnectPtr conn,
|
static int qemudWaitForMonitor(virConnectPtr conn,
|
||||||
virDomainObjPtr vm) {
|
struct qemud_driver* driver,
|
||||||
|
virDomainObjPtr vm, off_t pos)
|
||||||
|
{
|
||||||
char buf[1024]; /* Plenty of space to get startup greeting */
|
char buf[1024]; /* Plenty of space to get startup greeting */
|
||||||
int ret = qemudReadMonitorOutput(conn,
|
int logfd;
|
||||||
vm, vm->stderr_fd,
|
int ret;
|
||||||
buf, sizeof(buf),
|
|
||||||
qemudFindCharDevicePTYs,
|
|
||||||
"console", 3000);
|
|
||||||
|
|
||||||
buf[sizeof(buf)-1] = '\0';
|
if ((logfd = qemudLogReadFD(conn, driver->logDir, vm->def->name, pos))
|
||||||
|
< 0)
|
||||||
|
return logfd;
|
||||||
|
|
||||||
if (safewrite(vm->logfile, buf, strlen(buf)) < 0) {
|
ret = qemudReadMonitorOutput(conn, vm, logfd, buf, sizeof(buf),
|
||||||
/* Log, but ignore failures to write logfile for VM */
|
qemudFindCharDevicePTYs,
|
||||||
qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
|
"console", 3000);
|
||||||
|
if (close(logfd) < 0)
|
||||||
|
qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,6 +1065,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
fd_set keepfd;
|
fd_set keepfd;
|
||||||
const char *emulator;
|
const char *emulator;
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
int pos = -1;
|
||||||
|
|
||||||
FD_ZERO(&keepfd);
|
FD_ZERO(&keepfd);
|
||||||
|
|
||||||
@ -1034,14 +1158,15 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
|
||||||
vm->stdout_fd = -1;
|
if ((pos = lseek(vm->logfile, 0, SEEK_END)) < 0)
|
||||||
vm->stderr_fd = -1;
|
qemudLog(QEMUD_WARN, _("Unable to seek to end of logfile %d: %s\n"),
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
for (i = 0 ; i < ntapfds ; i++)
|
for (i = 0 ; i < ntapfds ; i++)
|
||||||
FD_SET(tapfds[i], &keepfd);
|
FD_SET(tapfds[i], &keepfd);
|
||||||
|
|
||||||
ret = virExec(conn, argv, progenv, &keepfd, &child,
|
ret = virExec(conn, argv, progenv, &keepfd, &child,
|
||||||
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
|
vm->stdin_fd, &vm->logfile, &vm->logfile,
|
||||||
VIR_EXEC_NONBLOCK | VIR_EXEC_DAEMON);
|
VIR_EXEC_NONBLOCK | VIR_EXEC_DAEMON);
|
||||||
|
|
||||||
/* wait for qemu process to to show up */
|
/* wait for qemu process to to show up */
|
||||||
@ -1078,19 +1203,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (((vm->stdout_watch = virEventAddHandle(vm->stdout_fd,
|
if ((qemudWaitForMonitor(conn, driver, vm, pos) < 0) ||
|
||||||
VIR_EVENT_HANDLE_READABLE |
|
|
||||||
VIR_EVENT_HANDLE_ERROR |
|
|
||||||
VIR_EVENT_HANDLE_HANGUP,
|
|
||||||
qemudDispatchVMEvent,
|
|
||||||
driver, NULL)) < 0) ||
|
|
||||||
((vm->stderr_watch = virEventAddHandle(vm->stderr_fd,
|
|
||||||
VIR_EVENT_HANDLE_READABLE |
|
|
||||||
VIR_EVENT_HANDLE_ERROR |
|
|
||||||
VIR_EVENT_HANDLE_HANGUP,
|
|
||||||
qemudDispatchVMEvent,
|
|
||||||
driver, NULL)) < 0) ||
|
|
||||||
(qemudWaitForMonitor(conn, vm) < 0) ||
|
|
||||||
(qemudDetectVcpuPIDs(conn, vm) < 0) ||
|
(qemudDetectVcpuPIDs(conn, vm) < 0) ||
|
||||||
(qemudInitCpus(conn, vm, migrateFrom) < 0)) {
|
(qemudInitCpus(conn, vm, migrateFrom) < 0)) {
|
||||||
qemudShutdownVMDaemon(conn, driver, vm);
|
qemudShutdownVMDaemon(conn, driver, vm);
|
||||||
@ -1102,32 +1215,6 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudVMData(struct qemud_driver *driver ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm, int fd) {
|
|
||||||
char buf[4096];
|
|
||||||
if (vm->pid < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
int ret = read(fd, buf, sizeof(buf)-1);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno == EAGAIN)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ret == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
buf[ret] = '\0';
|
|
||||||
|
|
||||||
if (safewrite(vm->logfile, buf, ret) < 0) {
|
|
||||||
/* Log, but ignore failures to write logfile for VM */
|
|
||||||
qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
struct qemud_driver *driver, virDomainObjPtr vm) {
|
struct qemud_driver *driver, virDomainObjPtr vm) {
|
||||||
@ -1141,22 +1228,14 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
qemudLog(QEMUD_ERROR, _("Failed to send SIGTERM to %s (%d): %s\n"),
|
qemudLog(QEMUD_ERROR, _("Failed to send SIGTERM to %s (%d): %s\n"),
|
||||||
vm->def->name, vm->pid, strerror(errno));
|
vm->def->name, vm->pid, strerror(errno));
|
||||||
|
|
||||||
qemudVMData(driver, vm, vm->stdout_fd);
|
virEventRemoveHandle(vm->monitor_watch);
|
||||||
qemudVMData(driver, vm, vm->stderr_fd);
|
|
||||||
|
|
||||||
virEventRemoveHandle(vm->stdout_watch);
|
|
||||||
virEventRemoveHandle(vm->stderr_watch);
|
|
||||||
|
|
||||||
if (close(vm->logfile) < 0)
|
if (close(vm->logfile) < 0)
|
||||||
qemudLog(QEMUD_WARN, _("Unable to close logfile %d: %s\n"),
|
qemudLog(QEMUD_WARN, _("Unable to close logfile %d: %s\n"),
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
close(vm->stdout_fd);
|
|
||||||
close(vm->stderr_fd);
|
|
||||||
if (vm->monitor != -1)
|
if (vm->monitor != -1)
|
||||||
close(vm->monitor);
|
close(vm->monitor);
|
||||||
vm->logfile = -1;
|
vm->logfile = -1;
|
||||||
vm->stdout_fd = -1;
|
|
||||||
vm->stderr_fd = -1;
|
|
||||||
vm->monitor = -1;
|
vm->monitor = -1;
|
||||||
|
|
||||||
/* shut it off for sure */
|
/* shut it off for sure */
|
||||||
@ -1191,8 +1270,7 @@ qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
|
|||||||
virDomainObjPtr tmpvm = driver->domains.objs[i];
|
virDomainObjPtr tmpvm = driver->domains.objs[i];
|
||||||
virDomainObjLock(tmpvm);
|
virDomainObjLock(tmpvm);
|
||||||
if (virDomainIsActive(tmpvm) &&
|
if (virDomainIsActive(tmpvm) &&
|
||||||
(tmpvm->stdout_watch == watch ||
|
tmpvm->monitor_watch == watch) {
|
||||||
tmpvm->stderr_watch == watch)) {
|
|
||||||
vm = tmpvm;
|
vm = tmpvm;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1202,15 +1280,15 @@ qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
|
|||||||
if (!vm)
|
if (!vm)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (vm->stdout_fd != fd &&
|
if (vm->monitor != fd) {
|
||||||
vm->stderr_fd != fd) {
|
|
||||||
failed = 1;
|
failed = 1;
|
||||||
} else {
|
} else {
|
||||||
if (events & VIR_EVENT_HANDLE_READABLE) {
|
if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
|
||||||
if (qemudVMData(driver, vm, fd) < 0)
|
|
||||||
failed = 1;
|
|
||||||
} else {
|
|
||||||
quit = 1;
|
quit = 1;
|
||||||
|
else {
|
||||||
|
qemudLog(QEMUD_ERROR, _("unhandled fd event %d for %s"),
|
||||||
|
events, vm->def->name);
|
||||||
|
failed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user