[libvirt] [PATCH 8/8] Implement code to attach to external QEMU instances.
Matthias Bolte
matthias.bolte at googlemail.com
Tue Jul 5 13:09:23 UTC 2011
2011/7/4 Daniel P. Berrange <berrange at redhat.com>:
> Given a PID, the QEMU driver reads /proc/$PID/cmdline and
> /proc/$PID/environ to get the configuration. This is fed
> into the ARGV->XML convertor to build an XML configuration
> for the process.
>
> /proc/$PID/exe is resolved to identify the full command
> binary path
>
> After checking for name/uuid uniqueness, an attempt is
> made to connect to the monitor socket. If successful
> then 'info status' and 'info kvm' are issued to determine
> whether the CPUs are running and if KVM is enabled.
>
> * src/qemu/qemu_driver.c: Implement virDomainQemuAttach
> * src/qemu/qemu_process.h, src/qemu/qemu_process.c: Add
> qemuProcessAttach to connect to the monitor of an
> existing QEMU process
> ---
> src/conf/domain_conf.c | 3 +-
> src/conf/domain_conf.h | 1 +
> src/qemu/qemu_command.c | 2 +
> src/qemu/qemu_driver.c | 91 +++++++++++++++++++-
> src/qemu/qemu_process.c | 218 ++++++++++++++++++++++++++++++++++++++++++++---
> src/qemu/qemu_process.h | 8 ++
> 6 files changed, 308 insertions(+), 15 deletions(-)
> static int
> qemuDomainOpenConsole(virDomainPtr dom,
> const char *devname,
> @@ -8539,6 +8625,7 @@ static virDriver qemuDriver = {
> .domainRevertToSnapshot = qemuDomainRevertToSnapshot, /* 0.8.0 */
> .domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */
> .qemuDomainMonitorCommand = qemuDomainMonitorCommand, /* 0.8.3 */
> + .qemuDomainAttach = qemuDomainAttach, /* 0.9.3 */
s/0.9.3/0.9.4/
> +int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
> + struct qemud_driver *driver,
> + virDomainObjPtr vm,
> + int pid,
> + const char *pidfile,
> + virDomainChrSourceDefPtr monConfig,
> + bool monJSON)
> +{
> + char ebuf[1024];
> + int logfile = -1;
> + char *timestamp;
> + qemuDomainObjPrivatePtr priv = vm->privateData;
> + bool running = true;
> + virSecurityLabelPtr seclabel = NULL;
> +
> + VIR_DEBUG("Beginning VM attach process");
> +
> + if (virDomainObjIsActive(vm)) {
> + qemuReportError(VIR_ERR_OPERATION_INVALID,
> + "%s", _("VM is already active"));
> + return -1;
> + }
> +
> + /* Do this upfront, so any part of the startup process can add
> + * runtime state to vm->def that won't be persisted. This let's us
> + * report implicit runtime defaults in the XML, like vnc listen/socket
> + */
> + VIR_DEBUG("Setting current domain def as transient");
> + if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0)
> + goto cleanup;
> +
> + vm->def->id = driver->nextvmid++;
> +
> + if (virFileMakePath(driver->logDir) != 0) {
> + virReportSystemError(errno,
> + _("cannot create log directory %s"),
> + driver->logDir);
> + goto cleanup;
> + }
This doesn't work as virFileMakePath doesn't set errno for all errors,
but returns an errno value. Needs to be something like this
int err;
if ((err = virFileMakePath(driver->logDir)) != 0) {
virReportSystemError(err,
_("cannot create log directory %s"),
driver->logDir);
goto cleanup;
}
Also grep'ing for virFileMakePath shows that there are many instances
that use virFileMakePath in the wrong way.
> + VIR_FREE(priv->pidfile);
> + if (pidfile &&
> + !(priv->pidfile = strdup(pidfile)))
> + goto no_memory;
> +
> + VIR_DEBUG("Detect security driver config");
> + vm->def->seclabel.type = VIR_DOMAIN_SECLABEL_STATIC;
> + if (VIR_ALLOC(seclabel) < 0)
> + goto no_memory;
> + if (virSecurityManagerGetProcessLabel(driver->securityManager,
> + vm, seclabel) < 0)
> + goto cleanup;
> + if (!(vm->def->seclabel.model = strdup(driver->caps->host.secModel.model)))
> + goto no_memory;
> + if (!(vm->def->seclabel.label = strdup(seclabel->label)))
> + goto no_memory;
> +
> + VIR_DEBUG("Creating domain log file");
> + if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
> + goto cleanup;
> +
> + VIR_DEBUG("Determining emulator version");
> + qemuCapsFree(priv->qemuCaps);
> + priv->qemuCaps = NULL;
> + if (qemuCapsExtractVersionInfo(vm->def->emulator,
> + vm->def->os.arch,
> + NULL,
> + &priv->qemuCaps) < 0)
> + goto cleanup;
> +
> + if (VIR_ALLOC(priv->monConfig) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + VIR_DEBUG("Preparing monitor state");
> + priv->monConfig = monConfig;
Allocating and overwriting priv->monConfig leaks memory here.
ACK, with those problems fixed.
--
Matthias Bolte
http://photron.blogspot.com
More information about the libvir-list
mailing list