#include "qemu_domain.h"
#include "qemu_command.h"
+#include "qemu_capabilities.h"
#include "memory.h"
#include "logging.h"
#include "virterror_internal.h"
{
qemuDomainObjPrivatePtr priv = data;
+ qemuCapsFree(priv->qemuCaps);
+
qemuDomainPCIAddressSetFree(priv->pciaddrs);
virDomainChrSourceDefFree(priv->monConfig);
VIR_FREE(priv->vcpupids);
virBufferAddLit(buf, " </vcpus>\n");
}
+ if (priv->qemuCaps) {
+ int i;
+ virBufferAddLit(buf, " <qemuCaps>\n");
+ for (i = 0 ; i < QEMU_CAPS_LAST ; i++) {
+ if (qemuCapsGet(priv->qemuCaps, i)) {
+ virBufferVSprintf(buf, " <flag name='%s'/>\n",
+ qemuCapsTypeToString(i));
+ }
+ }
+ virBufferAddLit(buf, " </qemuCaps>\n");
+ }
+
return 0;
}
char *tmp;
int n, i;
xmlNodePtr *nodes = NULL;
+ virBitmapPtr qemuCaps = NULL;
if (VIR_ALLOC(priv->monConfig) < 0) {
virReportOOMError();
VIR_FREE(nodes);
}
+ if ((n = virXPathNodeSet("./qemuCaps/flag", ctxt, &nodes)) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("failed to parse qemu capabilities flags"));
+ goto error;
+ }
+ if (n > 0) {
+ if (!(qemuCaps = qemuCapsNew()))
+ goto error;
+
+ for (i = 0 ; i < n ; i++) {
+ char *str = virXMLPropString(nodes[i], "name");
+ if (str) {
+ int flag = qemuCapsTypeFromString(str);
+ VIR_FREE(str);
+ if (flag < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown qemu capabilities flag %s"), str);
+ goto error;
+ }
+ qemuCapsSet(qemuCaps, flag);
+ }
+ }
+
+ priv->qemuCaps = qemuCaps;
+ }
+ VIR_FREE(nodes);
+
+
return 0;
error:
virDomainChrSourceDefFree(priv->monConfig);
priv->monConfig = NULL;
VIR_FREE(nodes);
+ qemuCapsFree(qemuCaps);
return -1;
}
static int
qemuProcessInitPasswords(virConnectPtr conn,
struct qemud_driver *driver,
- virDomainObjPtr vm,
- virBitmapPtr qemuCaps)
+ virDomainObjPtr vm)
{
int ret = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
if (ret < 0)
goto cleanup;
- if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
int i;
for (i = 0 ; i < vm->def->ndisks ; i++) {
struct qemuProcessReconnectData *data = opaque;
struct qemud_driver *driver = data->driver;
qemuDomainObjPrivatePtr priv;
- virBitmapPtr qemuCaps = NULL;
virConnectPtr conn = data->conn;
virDomainObjLock(obj);
goto error;
}
- /* XXX we should be persisting the original flags in the XML
- * not re-detecting them, since the binary may have changed
- * since launch time */
- if (qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch,
+ /* If upgrading from old libvirtd we won't have found any
+ * caps in the domain status, so re-query them
+ */
+ if (!priv->qemuCaps &&
+ qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch,
NULL,
- &qemuCaps) >= 0 &&
- qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ &priv->qemuCaps) < 0)
+ goto error;
+
+ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
priv->persistentAddrs = 1;
if (!(priv->pciaddrs = qemuDomainPCIAddressSetCreate(obj->def)) ||
if (virDomainObjUnref(obj) > 0)
virDomainObjUnlock(obj);
- qemuCapsFree(qemuCaps);
return;
error:
- qemuCapsFree(qemuCaps);
if (!virDomainObjIsActive(obj)) {
if (virDomainObjUnref(obj) > 0)
virDomainObjUnlock(obj);
enum virVMOperationType vmop)
{
int ret;
- virBitmapPtr qemuCaps = NULL;
off_t pos = -1;
char ebuf[1024];
char *pidfile = NULL;
goto cleanup;
VIR_DEBUG0("Determining emulator version");
+ qemuCapsFree(priv->qemuCaps);
+ priv->qemuCaps = NULL;
if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch,
NULL,
- &qemuCaps) < 0)
+ &priv->qemuCaps) < 0)
goto cleanup;
VIR_DEBUG0("Setting up domain cgroup (if required)");
goto cleanup;
#if HAVE_YAJL
- if (qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON))
+ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON))
priv->monJSON = 1;
else
#endif
* we also need to populate the PCi address set cache for later
* use in hotplug
*/
- if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
VIR_DEBUG0("Assigning domain PCI addresses");
/* Populate cache with current addresses */
if (priv->pciaddrs) {
VIR_DEBUG0("Building emulator command line");
if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig,
- priv->monJSON != 0, qemuCaps,
+ priv->monJSON != 0, priv->qemuCaps,
migrateFrom, stdin_fd,
vm->current_snapshot, vmop)))
goto cleanup;
goto cleanup;
VIR_DEBUG0("Setting any required VM passwords");
- if (qemuProcessInitPasswords(conn, driver, vm, qemuCaps) < 0)
+ if (qemuProcessInitPasswords(conn, driver, vm) < 0)
goto cleanup;
/* If we have -device, then addresses are assigned explicitly.
* If not, then we have to detect dynamic ones here */
- if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
VIR_DEBUG0("Determining domain device PCI addresses");
if (qemuProcessInitPCIAddresses(driver, vm) < 0)
goto cleanup;
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
goto cleanup;
- qemuCapsFree(qemuCaps);
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
/* We jump here if we failed to start the VM for any reason, or
* if we failed to initialize the now running VM. kill it off and
* pretend we never started it */
- qemuCapsFree(qemuCaps);
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
qemuProcessStop(driver, vm, 0);
vm->state = VIR_DOMAIN_SHUTOFF;
VIR_FREE(priv->vcpupids);
priv->nvcpupids = 0;
+ qemuCapsFree(priv->qemuCaps);
+ priv->qemuCaps = NULL;
/* The "release" hook cleans up additional resources */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {