[libvirt] [PATCH 4/4] read saved vm status on libvirtd startup

connect back to running vms. changes: * don't use proc * don't bother about stdin * don't use global qemu_driver directly Cheer, -- Guido --- src/qemu_driver.c | 112 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 2dedca2..3b01fd4 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -297,6 +297,86 @@ 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; + + vm->stdout_fd = vm->stderr_fd = vm->logfile; + + 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: * @@ -396,6 +476,7 @@ qemudStartup(void) { qemu_driver->autostartDir, NULL, NULL) < 0) goto error; + qemudReconnectVMs(qemu_driver); qemudAutostartConfigs(qemu_driver); qemuDriverUnlock(qemu_driver); @@ -488,7 +569,6 @@ qemudActive(void) { */ static int qemudShutdown(void) { - unsigned int i; if (!qemu_driver) return -1; @@ -496,15 +576,6 @@ qemudShutdown(void) { qemuDriverLock(qemu_driver); 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); VIR_FREE(qemu_driver->logDir); @@ -621,7 +692,8 @@ qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED, static int qemudOpenMonitor(virConnectPtr conn, struct qemud_driver* driver, virDomainObjPtr vm, - const char *monitor) { + const char *monitor, + int reconnect) { int monfd; char buf[1024]; int ret = -1; @@ -642,11 +714,19 @@ static int qemudOpenMonitor(virConnectPtr conn, goto error; } - ret = qemudReadMonitorOutput(conn, - vm, monfd, - buf, sizeof(buf), - qemudCheckMonitorPrompt, - "monitor", 10000); + if (!reconnect) { + ret = qemudReadMonitorOutput(conn, + vm, monfd, + buf, sizeof(buf), + qemudCheckMonitorPrompt, + "monitor", 10000); + } else { + vm->monitor = monfd; + ret = 0; + } + + if (ret != 0) + goto error; if (!(vm->monitorpath = strdup(monitor))) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, -- 1.6.0.6

On Sun, Jan 18, 2009 at 08:28:59PM +0100, Guido G?nther wrote:
connect back to running vms.
changes: * don't use proc * don't bother about stdin * don't use global qemu_driver directly Cheer, -- Guido
+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; + + vm->stdout_fd = vm->stderr_fd = vm->logfile;
If nothing is actaully using the stdout/err FDs anymore we can just leave them at -1. Aside from that, ACK to this patch. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Tue, Jan 20, 2009 at 08:18:11AM +0100, Guido G?nther wrote:
On Mon, Jan 19, 2009 at 01:39:51PM +0000, Daniel P. Berrange wrote:
+ vm->stdout_fd = vm->stderr_fd = vm->logfile;
If nothing is actaully using the stdout/err FDs anymore we can just leave them at -1. Fixed in the attached patch.
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Tue, Jan 20, 2009 at 10:22:04AM +0000, Daniel P. Berrange wrote:
On Tue, Jan 20, 2009 at 08:18:11AM +0100, Guido G?nther wrote:
On Mon, Jan 19, 2009 at 01:39:51PM +0000, Daniel P. Berrange wrote:
+ vm->stdout_fd = vm->stderr_fd = vm->logfile;
If nothing is actaully using the stdout/err FDs anymore we can just leave them at -1. Fixed in the attached patch.
ACK
Okay, also commited, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
Guido Günther