2010-12-16 15:23:41 +00:00
|
|
|
/*
|
|
|
|
* qemu_domain.h: QEMU domain private state
|
|
|
|
*
|
2012-08-14 00:09:12 +00:00
|
|
|
* Copyright (C) 2006-2012 Red Hat, Inc.
|
2010-12-16 15:23:41 +00:00
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-12-16 15:23:41 +00:00
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __QEMU_DOMAIN_H__
|
|
|
|
# define __QEMU_DOMAIN_H__
|
|
|
|
|
|
|
|
# include "threads.h"
|
|
|
|
# include "domain_conf.h"
|
2012-08-14 00:09:12 +00:00
|
|
|
# include "snapshot_conf.h"
|
2010-12-16 15:23:41 +00:00
|
|
|
# include "qemu_monitor.h"
|
2011-10-05 17:31:54 +00:00
|
|
|
# include "qemu_agent.h"
|
2010-12-16 16:12:02 +00:00
|
|
|
# include "qemu_conf.h"
|
2012-08-20 16:44:14 +00:00
|
|
|
# include "qemu_capabilities.h"
|
2011-10-06 10:24:47 +00:00
|
|
|
# include "virconsole.h"
|
2010-12-16 15:23:41 +00:00
|
|
|
|
2011-07-11 17:29:09 +00:00
|
|
|
# define QEMU_EXPECTED_VIRT_TYPES \
|
|
|
|
((1 << VIR_DOMAIN_VIRT_QEMU) | \
|
|
|
|
(1 << VIR_DOMAIN_VIRT_KQEMU) | \
|
|
|
|
(1 << VIR_DOMAIN_VIRT_KVM) | \
|
|
|
|
(1 << VIR_DOMAIN_VIRT_XEN))
|
|
|
|
|
2012-10-08 09:58:05 +00:00
|
|
|
# define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
|
|
|
|
(VIR_DOMAIN_XML_SECURE | \
|
|
|
|
VIR_DOMAIN_XML_UPDATE_CPU)
|
|
|
|
|
2012-03-20 15:56:29 +00:00
|
|
|
# if ULONG_MAX == 4294967295
|
|
|
|
/* Qemu has a 64-bit limit, but we are limited by our historical choice of
|
|
|
|
* representing bandwidth in a long instead of a 64-bit int. */
|
2012-08-03 16:34:06 +00:00
|
|
|
# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX ULONG_MAX
|
2012-03-20 15:56:29 +00:00
|
|
|
# else
|
2012-08-03 16:34:06 +00:00
|
|
|
# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024))
|
2012-03-20 15:56:29 +00:00
|
|
|
# endif
|
2011-08-26 18:10:22 +00:00
|
|
|
|
2011-06-30 09:23:50 +00:00
|
|
|
# define JOB_MASK(job) (1 << (job - 1))
|
|
|
|
# define DEFAULT_JOB_MASK \
|
2011-07-19 00:27:39 +00:00
|
|
|
(JOB_MASK(QEMU_JOB_QUERY) | \
|
|
|
|
JOB_MASK(QEMU_JOB_DESTROY) | \
|
|
|
|
JOB_MASK(QEMU_JOB_ABORT))
|
2011-06-30 09:23:50 +00:00
|
|
|
|
2012-04-06 17:42:34 +00:00
|
|
|
/* Jobs which have to be tracked in domain state XML. */
|
|
|
|
# define QEMU_DOMAIN_TRACK_JOBS \
|
|
|
|
(JOB_MASK(QEMU_JOB_DESTROY) | \
|
|
|
|
JOB_MASK(QEMU_JOB_ASYNC))
|
|
|
|
|
2010-12-16 15:23:41 +00:00
|
|
|
/* Only 1 job is allowed at any time
|
|
|
|
* A job includes *all* monitor commands, even those just querying
|
|
|
|
* information, not merely actions */
|
|
|
|
enum qemuDomainJob {
|
|
|
|
QEMU_JOB_NONE = 0, /* Always set to 0 for easy if (jobActive) conditions */
|
2011-06-30 09:23:50 +00:00
|
|
|
QEMU_JOB_QUERY, /* Doesn't change any state */
|
|
|
|
QEMU_JOB_DESTROY, /* Destroys the domain (cannot be masked out) */
|
|
|
|
QEMU_JOB_SUSPEND, /* Suspends (stops vCPUs) the domain */
|
|
|
|
QEMU_JOB_MODIFY, /* May change state */
|
2011-07-19 00:27:39 +00:00
|
|
|
QEMU_JOB_ABORT, /* Abort current async job */
|
2011-07-19 00:27:36 +00:00
|
|
|
QEMU_JOB_MIGRATION_OP, /* Operation influencing outgoing migration */
|
2011-06-30 09:23:50 +00:00
|
|
|
|
2011-06-06 08:28:38 +00:00
|
|
|
/* The following two items must always be the last items before JOB_LAST */
|
2011-06-30 09:23:50 +00:00
|
|
|
QEMU_JOB_ASYNC, /* Asynchronous job */
|
|
|
|
QEMU_JOB_ASYNC_NESTED, /* Normal job within an async job */
|
2011-06-06 08:28:38 +00:00
|
|
|
|
|
|
|
QEMU_JOB_LAST
|
2011-06-30 09:23:50 +00:00
|
|
|
};
|
2012-03-16 06:56:19 +00:00
|
|
|
VIR_ENUM_DECL(qemuDomainJob)
|
2011-06-30 09:23:50 +00:00
|
|
|
|
|
|
|
/* Async job consists of a series of jobs that may change state. Independent
|
|
|
|
* jobs that do not change state (and possibly others if explicitly allowed by
|
|
|
|
* current async job) are allowed to be run even if async job is active.
|
|
|
|
*/
|
|
|
|
enum qemuDomainAsyncJob {
|
|
|
|
QEMU_ASYNC_JOB_NONE = 0,
|
|
|
|
QEMU_ASYNC_JOB_MIGRATION_OUT,
|
|
|
|
QEMU_ASYNC_JOB_MIGRATION_IN,
|
|
|
|
QEMU_ASYNC_JOB_SAVE,
|
|
|
|
QEMU_ASYNC_JOB_DUMP,
|
2012-10-08 14:34:19 +00:00
|
|
|
QEMU_ASYNC_JOB_SNAPSHOT,
|
2011-06-06 08:28:38 +00:00
|
|
|
|
|
|
|
QEMU_ASYNC_JOB_LAST
|
2010-12-16 15:23:41 +00:00
|
|
|
};
|
2012-03-16 06:56:19 +00:00
|
|
|
VIR_ENUM_DECL(qemuDomainAsyncJob)
|
2010-12-16 15:23:41 +00:00
|
|
|
|
2011-06-06 08:34:33 +00:00
|
|
|
struct qemuDomainJobObj {
|
2011-06-30 09:23:50 +00:00
|
|
|
virCond cond; /* Use to coordinate jobs */
|
|
|
|
enum qemuDomainJob active; /* Currently running job */
|
2012-04-06 16:55:46 +00:00
|
|
|
int owner; /* Thread which set current job */
|
2011-06-06 08:34:33 +00:00
|
|
|
|
2011-06-30 09:23:50 +00:00
|
|
|
virCond asyncCond; /* Use to coordinate with async jobs */
|
|
|
|
enum qemuDomainAsyncJob asyncJob; /* Currently active async job */
|
2012-04-06 16:55:46 +00:00
|
|
|
int asyncOwner; /* Thread which set current async job */
|
2011-06-06 08:30:54 +00:00
|
|
|
int phase; /* Job phase (mainly for migrations) */
|
2011-06-30 09:23:50 +00:00
|
|
|
unsigned long long mask; /* Jobs allowed during async job */
|
|
|
|
unsigned long long start; /* When the async job started */
|
2012-06-12 03:06:33 +00:00
|
|
|
bool dump_memory_only; /* use dump-guest-memory to do dump */
|
2011-06-30 09:23:50 +00:00
|
|
|
virDomainJobInfo info; /* Async job progress data */
|
2012-11-08 13:49:55 +00:00
|
|
|
bool asyncAbort; /* abort of async job requested */
|
2011-06-06 08:34:33 +00:00
|
|
|
};
|
|
|
|
|
2010-12-16 15:23:41 +00:00
|
|
|
typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
|
|
|
|
typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
|
2012-03-16 06:52:26 +00:00
|
|
|
virDomainObjPtr vm);
|
|
|
|
|
2010-12-16 15:23:41 +00:00
|
|
|
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
|
|
|
|
typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
|
|
|
|
struct _qemuDomainObjPrivate {
|
2011-06-06 08:34:33 +00:00
|
|
|
struct qemuDomainJobObj job;
|
2010-12-16 15:23:41 +00:00
|
|
|
|
|
|
|
qemuMonitorPtr mon;
|
2011-01-07 23:36:25 +00:00
|
|
|
virDomainChrSourceDefPtr monConfig;
|
2010-12-16 15:23:41 +00:00
|
|
|
int monJSON;
|
2011-05-31 16:34:20 +00:00
|
|
|
bool monError;
|
|
|
|
unsigned long long monStart;
|
2011-10-05 17:31:54 +00:00
|
|
|
|
|
|
|
qemuAgentPtr agent;
|
|
|
|
bool agentError;
|
|
|
|
unsigned long long agentStart;
|
|
|
|
|
2010-12-16 15:23:41 +00:00
|
|
|
bool gotShutdown;
|
2011-12-09 14:33:13 +00:00
|
|
|
bool beingDestroyed;
|
2011-06-17 13:43:54 +00:00
|
|
|
char *pidfile;
|
2010-12-16 15:23:41 +00:00
|
|
|
|
|
|
|
int nvcpupids;
|
|
|
|
int *vcpupids;
|
|
|
|
|
|
|
|
qemuDomainPCIAddressSetPtr pciaddrs;
|
|
|
|
int persistentAddrs;
|
2011-05-04 11:55:38 +00:00
|
|
|
|
2012-08-20 16:44:14 +00:00
|
|
|
qemuCapsPtr caps;
|
2010-10-26 14:04:46 +00:00
|
|
|
char *lockState;
|
2011-06-15 16:49:58 +00:00
|
|
|
|
|
|
|
bool fakeReboot;
|
2011-08-12 13:29:37 +00:00
|
|
|
|
|
|
|
int jobs_queued;
|
2011-08-26 18:10:22 +00:00
|
|
|
|
|
|
|
unsigned long migMaxBandwidth;
|
2011-10-04 07:11:35 +00:00
|
|
|
char *origname;
|
2011-10-06 10:24:47 +00:00
|
|
|
|
|
|
|
virConsolesPtr cons;
|
2012-03-16 06:52:26 +00:00
|
|
|
|
|
|
|
qemuDomainCleanupCallback *cleanupCallbacks;
|
|
|
|
size_t ncleanupCallbacks;
|
|
|
|
size_t ncleanupCallbacks_max;
|
2010-12-16 15:23:41 +00:00
|
|
|
};
|
|
|
|
|
2011-02-14 16:09:39 +00:00
|
|
|
struct qemuDomainWatchdogEvent
|
|
|
|
{
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int action;
|
|
|
|
};
|
|
|
|
|
2011-06-06 08:30:54 +00:00
|
|
|
const char *qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job,
|
|
|
|
int phase);
|
|
|
|
int qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
|
|
|
|
const char *phase);
|
|
|
|
|
2011-07-08 21:58:28 +00:00
|
|
|
void qemuDomainEventFlush(int timer, void *opaque);
|
2011-02-14 16:09:39 +00:00
|
|
|
|
|
|
|
/* driver must be locked before calling */
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainEventQueue(virQEMUDriverPtr driver,
|
2011-02-14 16:09:39 +00:00
|
|
|
virDomainEventPtr event);
|
2010-12-16 15:23:41 +00:00
|
|
|
|
|
|
|
void qemuDomainSetPrivateDataHooks(virCapsPtr caps);
|
|
|
|
void qemuDomainSetNamespaceHooks(virCapsPtr caps);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainObjBeginJob(virQEMUDriverPtr driver,
|
2011-06-06 08:28:38 +00:00
|
|
|
virDomainObjPtr obj,
|
2011-06-30 09:23:50 +00:00
|
|
|
enum qemuDomainJob job)
|
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
|
2011-06-06 08:28:38 +00:00
|
|
|
virDomainObjPtr obj,
|
2011-06-30 09:23:50 +00:00
|
|
|
enum qemuDomainAsyncJob asyncJob)
|
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainObjBeginJobWithDriver(virQEMUDriverPtr driver,
|
2011-06-30 09:23:50 +00:00
|
|
|
virDomainObjPtr obj,
|
|
|
|
enum qemuDomainJob job)
|
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainObjBeginAsyncJobWithDriver(virQEMUDriverPtr driver,
|
2011-06-30 09:23:50 +00:00
|
|
|
virDomainObjPtr obj,
|
|
|
|
enum qemuDomainAsyncJob asyncJob)
|
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
bool qemuDomainObjEndJob(virQEMUDriverPtr driver,
|
2012-07-11 13:35:46 +00:00
|
|
|
virDomainObjPtr obj)
|
2011-06-30 09:23:50 +00:00
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
2012-11-28 16:43:10 +00:00
|
|
|
bool qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver,
|
2012-07-11 13:35:46 +00:00
|
|
|
virDomainObjPtr obj)
|
2011-06-30 09:23:50 +00:00
|
|
|
ATTRIBUTE_RETURN_CHECK;
|
2012-11-08 13:49:55 +00:00
|
|
|
void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjSetJobPhase(virQEMUDriverPtr driver,
|
2011-06-06 08:30:54 +00:00
|
|
|
virDomainObjPtr obj,
|
|
|
|
int phase);
|
2011-06-30 09:23:50 +00:00
|
|
|
void qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj,
|
|
|
|
unsigned long long allowedJobs);
|
2011-07-04 21:33:39 +00:00
|
|
|
void qemuDomainObjRestoreJob(virDomainObjPtr obj,
|
|
|
|
struct qemuDomainJobObj *job);
|
2012-04-06 16:55:46 +00:00
|
|
|
void qemuDomainObjTransferJob(virDomainObjPtr obj);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjDiscardAsyncJob(virQEMUDriverPtr driver,
|
2011-06-06 08:28:38 +00:00
|
|
|
virDomainObjPtr obj);
|
2012-04-06 16:55:46 +00:00
|
|
|
void qemuDomainObjReleaseAsyncJob(virDomainObjPtr obj);
|
2011-06-06 08:34:33 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjEnterMonitorWithDriver(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj,
|
|
|
|
enum qemuDomainAsyncJob asyncJob)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjExitMonitorWithDriver(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2011-10-05 17:31:54 +00:00
|
|
|
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjEnterAgent(virQEMUDriverPtr driver,
|
2011-10-05 17:31:54 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjExitAgent(virQEMUDriverPtr driver,
|
2011-10-05 17:31:54 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjEnterAgentWithDriver(virQEMUDriverPtr driver,
|
2011-10-05 17:31:54 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjExitAgentWithDriver(virQEMUDriverPtr driver,
|
2011-10-05 17:31:54 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
|
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjEnterRemoteWithDriver(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjExitRemoteWithDriver(virQEMUDriverPtr driver,
|
qemu: fix crash when mixing sync and async monitor jobs
Currently, we attempt to run sync job and async job at the same time. It
means that the monitor commands for two jobs can be run in any order.
In the function qemuDomainObjEnterMonitorInternal():
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0)
We check whether the caller is an async job by priv->job.active and
priv->job.asynJob. But when an async job is running, and a sync job is
also running at the time of the check, then priv->job.active is not
QEMU_JOB_NONE. So we cannot check whether the caller is an async job
in the function qemuDomainObjEnterMonitorInternal(), and must instead
put the burden on the caller to tell us when an async command wants
to do a nested job.
Once the burden is on the caller, then only async monitor enters need
to worry about whether the VM is still running; for sync monitor enter,
the internal return is always 0, so lots of ignore_value can be dropped.
* src/qemu/THREADS.txt: Reflect new rules.
* src/qemu/qemu_domain.h (qemuDomainObjEnterMonitorAsync): New
prototype.
* src/qemu/qemu_process.h (qemuProcessStartCPUs)
(qemuProcessStopCPUs): Add parameter.
* src/qemu/qemu_migration.h (qemuMigrationToFile): Likewise.
(qemuMigrationWaitForCompletion): Make static.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal): Add
parameter.
(qemuDomainObjEnterMonitorAsync): New function.
(qemuDomainObjEnterMonitor, qemuDomainObjEnterMonitorWithDriver):
Update callers.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemudDomainCoreDump, doCoreDump, processWatchdogEvent)
(qemudDomainSuspend, qemudDomainResume, qemuDomainSaveImageStartVM)
(qemuDomainSnapshotCreateActive, qemuDomainRevertToSnapshot):
Likewise.
* src/qemu/qemu_process.c (qemuProcessStopCPUs)
(qemuProcessFakeReboot, qemuProcessRecoverMigration)
(qemuProcessRecoverJob, qemuProcessStart): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationToFile)
(qemuMigrationWaitForCompletion, qemuMigrationUpdateJobStatus)
(qemuMigrationJobStart, qemuDomainMigrateGraphicsRelocate)
(doNativeMigrate, doTunnelMigrate, qemuMigrationPerformJob)
(qemuMigrationPerformPhase, qemuMigrationFinish)
(qemuMigrationConfirm): Likewise.
* src/qemu/qemu_hotplug.c: Drop unneeded ignore_value.
2011-07-28 23:18:24 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2010-12-16 16:12:02 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
|
2012-05-04 19:00:13 +00:00
|
|
|
virDomainDefPtr vm,
|
|
|
|
unsigned int flags,
|
|
|
|
virBuffer *buf);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
char *qemuDomainDefFormatXML(virQEMUDriverPtr driver,
|
2011-05-27 10:30:26 +00:00
|
|
|
virDomainDefPtr vm,
|
2012-10-08 09:58:05 +00:00
|
|
|
unsigned int flags);
|
2011-05-27 10:30:26 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
char *qemuDomainFormatXML(virQEMUDriverPtr driver,
|
2011-01-31 10:47:03 +00:00
|
|
|
virDomainObjPtr vm,
|
2012-10-08 09:58:05 +00:00
|
|
|
unsigned int flags);
|
2011-01-31 10:47:03 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
char *qemuDomainDefFormatLive(virQEMUDriverPtr driver,
|
2012-03-09 15:42:46 +00:00
|
|
|
virDomainDefPtr def,
|
2012-05-04 19:23:17 +00:00
|
|
|
bool inactive,
|
|
|
|
bool compatible);
|
2012-03-09 15:42:46 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjTaint(virQEMUDriverPtr driver,
|
2011-05-04 10:59:20 +00:00
|
|
|
virDomainObjPtr obj,
|
2011-05-05 11:48:07 +00:00
|
|
|
enum virDomainTaintFlags taint,
|
|
|
|
int logFD);
|
2011-05-04 10:59:20 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjCheckTaint(virQEMUDriverPtr driver,
|
2011-05-05 11:48:07 +00:00
|
|
|
virDomainObjPtr obj,
|
|
|
|
int logFD);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjCheckDiskTaint(virQEMUDriverPtr driver,
|
2011-05-04 10:59:20 +00:00
|
|
|
virDomainObjPtr obj,
|
2011-05-05 11:48:07 +00:00
|
|
|
virDomainDiskDefPtr disk,
|
|
|
|
int logFD);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainObjCheckNetTaint(virQEMUDriverPtr driver,
|
2011-05-04 10:59:20 +00:00
|
|
|
virDomainObjPtr obj,
|
2011-05-05 11:48:07 +00:00
|
|
|
virDomainNetDefPtr net,
|
|
|
|
int logFD);
|
2011-05-04 10:59:20 +00:00
|
|
|
|
2011-05-05 11:38:04 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm, bool append);
|
|
|
|
int qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm, off_t pos);
|
|
|
|
int qemuDomainAppendLog(virQEMUDriverPtr driver,
|
2011-05-05 11:40:50 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
int logFD,
|
|
|
|
const char *fmt, ...) ATTRIBUTE_FMT_PRINTF(4, 5);
|
2011-05-05 11:38:04 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
const char *qemuFindQemuImgBinary(virQEMUDriverPtr driver);
|
2011-09-21 19:08:51 +00:00
|
|
|
|
|
|
|
int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
|
|
|
|
virDomainSnapshotObjPtr snapshot,
|
|
|
|
char *snapshotDir);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainSnapshotForEachQcow2(virQEMUDriverPtr driver,
|
2011-09-21 19:08:51 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainSnapshotObjPtr snap,
|
|
|
|
const char *op,
|
|
|
|
bool try_all);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
|
2011-09-21 19:08:51 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainSnapshotObjPtr snap,
|
|
|
|
bool update_current,
|
|
|
|
bool metadata_only);
|
|
|
|
|
2012-11-28 17:29:44 +00:00
|
|
|
typedef struct _virQEMUSnapRemove virQEMUSnapRemove;
|
|
|
|
typedef virQEMUSnapRemove *virQEMUSnapRemovePtr;
|
|
|
|
struct _virQEMUSnapRemove {
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver;
|
2011-09-21 19:08:51 +00:00
|
|
|
virDomainObjPtr vm;
|
|
|
|
int err;
|
|
|
|
bool metadata_only;
|
|
|
|
bool current;
|
|
|
|
};
|
|
|
|
|
|
|
|
void qemuDomainSnapshotDiscardAll(void *payload,
|
|
|
|
const void *name,
|
|
|
|
void *data);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
|
2011-09-21 19:08:51 +00:00
|
|
|
virDomainObjPtr vm);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainRemoveInactive(virQEMUDriverPtr driver,
|
2011-09-21 19:08:51 +00:00
|
|
|
virDomainObjPtr vm);
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainSetFakeReboot(virQEMUDriverPtr driver,
|
2011-09-28 10:10:13 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
bool value);
|
|
|
|
|
2011-09-29 13:14:13 +00:00
|
|
|
bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
|
|
|
|
enum qemuDomainJob job);
|
2011-10-18 08:51:06 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
|
2011-10-18 08:51:06 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
bool start_with_state);
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
storage: cache backing chain while qemu domain is live
Technically, we should not be re-probing any file that qemu might
be currently writing to. As such, we should cache the backing
file chain prior to starting qemu. This patch adds the cache,
but does not use it until the next patch.
Ultimately, we want to also store the chain in domain XML, so that
it is remembered across libvirtd restarts, and so that the only
kosher way to modify the backing chain of an offline domain will be
through libvirt API calls, but we aren't there yet. So for now, we
merely invalidate the cache any time we do a live operation that
alters the chain (block-pull, block-commit, external disk snapshot),
as well as tear down the cache when the domain is not running.
* src/conf/domain_conf.h (_virDomainDiskDef): New field.
* src/conf/domain_conf.c (virDomainDiskDefFree): Clean new field.
* src/qemu/qemu_domain.h (qemuDomainDetermineDiskChain): New
prototype.
* src/qemu/qemu_domain.c (qemuDomainDetermineDiskChain): New
function.
* src/qemu/qemu_driver.c (qemuDomainAttachDeviceDiskLive)
(qemuDomainChangeDiskMediaLive): Pre-populate chain.
(qemuDomainSnapshotCreateSingleDiskActive): Uncache chain before
snapshot.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Update
chain after block pull.
2012-10-09 22:08:14 +00:00
|
|
|
virDomainDiskDefPtr disk,
|
|
|
|
bool force);
|
2012-03-16 06:52:26 +00:00
|
|
|
|
|
|
|
int qemuDomainCleanupAdd(virDomainObjPtr vm,
|
|
|
|
qemuDomainCleanupCallback cb);
|
|
|
|
void qemuDomainCleanupRemove(virDomainObjPtr vm,
|
|
|
|
qemuDomainCleanupCallback cb);
|
2012-11-28 16:43:10 +00:00
|
|
|
void qemuDomainCleanupRun(virQEMUDriverPtr driver,
|
2012-03-16 06:52:26 +00:00
|
|
|
virDomainObjPtr vm);
|
|
|
|
|
2010-12-16 15:23:41 +00:00
|
|
|
#endif /* __QEMU_DOMAIN_H__ */
|