1 /* 2 * qemu_domainjob.h: helper functions for QEMU domain jobs 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library. If not, see 16 * <http://www.gnu.org/licenses/>. 17 */ 18 19 #pragma once 20 21 #include <glib-object.h> 22 #include "qemu_monitor.h" 23 24 #define JOB_MASK(job) (job == 0 ? 0 : 1 << (job - 1)) 25 #define QEMU_JOB_DEFAULT_MASK \ 26 (JOB_MASK(QEMU_JOB_QUERY) | \ 27 JOB_MASK(QEMU_JOB_DESTROY) | \ 28 JOB_MASK(QEMU_JOB_ABORT)) 29 30 /* Jobs which have to be tracked in domain state XML. */ 31 #define QEMU_DOMAIN_TRACK_JOBS \ 32 (JOB_MASK(QEMU_JOB_DESTROY) | \ 33 JOB_MASK(QEMU_JOB_ASYNC)) 34 35 /* Only 1 job is allowed at any time 36 * A job includes *all* monitor commands, even those just querying 37 * information, not merely actions */ 38 typedef enum { 39 QEMU_JOB_NONE = 0, /* Always set to 0 for easy if (jobActive) conditions */ 40 QEMU_JOB_QUERY, /* Doesn't change any state */ 41 QEMU_JOB_DESTROY, /* Destroys the domain (cannot be masked out) */ 42 QEMU_JOB_SUSPEND, /* Suspends (stops vCPUs) the domain */ 43 QEMU_JOB_MODIFY, /* May change state */ 44 QEMU_JOB_ABORT, /* Abort current async job */ 45 QEMU_JOB_MIGRATION_OP, /* Operation influencing outgoing migration */ 46 47 /* The following two items must always be the last items before JOB_LAST */ 48 QEMU_JOB_ASYNC, /* Asynchronous job */ 49 QEMU_JOB_ASYNC_NESTED, /* Normal job within an async job */ 50 51 QEMU_JOB_LAST 52 } qemuDomainJob; 53 VIR_ENUM_DECL(qemuDomainJob); 54 55 typedef enum { 56 QEMU_AGENT_JOB_NONE = 0, /* No agent job. */ 57 QEMU_AGENT_JOB_QUERY, /* Does not change state of domain */ 58 QEMU_AGENT_JOB_MODIFY, /* May change state of domain */ 59 60 QEMU_AGENT_JOB_LAST 61 } qemuDomainAgentJob; 62 VIR_ENUM_DECL(qemuDomainAgentJob); 63 64 /* Async job consists of a series of jobs that may change state. Independent 65 * jobs that do not change state (and possibly others if explicitly allowed by 66 * current async job) are allowed to be run even if async job is active. 67 */ 68 typedef enum { 69 QEMU_ASYNC_JOB_NONE = 0, 70 QEMU_ASYNC_JOB_MIGRATION_OUT, 71 QEMU_ASYNC_JOB_MIGRATION_IN, 72 QEMU_ASYNC_JOB_SAVE, 73 QEMU_ASYNC_JOB_DUMP, 74 QEMU_ASYNC_JOB_SNAPSHOT, 75 QEMU_ASYNC_JOB_START, 76 QEMU_ASYNC_JOB_BACKUP, 77 78 QEMU_ASYNC_JOB_LAST 79 } qemuDomainAsyncJob; 80 VIR_ENUM_DECL(qemuDomainAsyncJob); 81 82 typedef enum { 83 QEMU_DOMAIN_JOB_STATUS_NONE = 0, 84 QEMU_DOMAIN_JOB_STATUS_ACTIVE, 85 QEMU_DOMAIN_JOB_STATUS_MIGRATING, 86 QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED, 87 QEMU_DOMAIN_JOB_STATUS_PAUSED, 88 QEMU_DOMAIN_JOB_STATUS_POSTCOPY, 89 QEMU_DOMAIN_JOB_STATUS_COMPLETED, 90 QEMU_DOMAIN_JOB_STATUS_FAILED, 91 QEMU_DOMAIN_JOB_STATUS_CANCELED, 92 } qemuDomainJobStatus; 93 94 typedef enum { 95 QEMU_DOMAIN_JOB_STATS_TYPE_NONE = 0, 96 QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION, 97 QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP, 98 QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP, 99 QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP, 100 } qemuDomainJobStatsType; 101 102 103 typedef struct _qemuDomainMirrorStats qemuDomainMirrorStats; 104 struct _qemuDomainMirrorStats { 105 unsigned long long transferred; 106 unsigned long long total; 107 }; 108 109 typedef struct _qemuDomainBackupStats qemuDomainBackupStats; 110 struct _qemuDomainBackupStats { 111 unsigned long long transferred; 112 unsigned long long total; 113 unsigned long long tmp_used; 114 unsigned long long tmp_total; 115 }; 116 117 typedef struct _qemuDomainJobInfo qemuDomainJobInfo; 118 struct _qemuDomainJobInfo { 119 qemuDomainJobStatus status; 120 virDomainJobOperation operation; 121 unsigned long long started; /* When the async job started */ 122 unsigned long long stopped; /* When the domain's CPUs were stopped */ 123 unsigned long long sent; /* When the source sent status info to the 124 destination (only for migrations). */ 125 unsigned long long received; /* When the destination host received status 126 info from the source (migrations only). */ 127 /* Computed values */ 128 unsigned long long timeElapsed; 129 long long timeDelta; /* delta = received - sent, i.e., the difference 130 between the source and the destination time plus 131 the time between the end of Perform phase on the 132 source and the beginning of Finish phase on the 133 destination. */ 134 bool timeDeltaSet; 135 /* Raw values from QEMU */ 136 qemuDomainJobStatsType statsType; 137 union { 138 qemuMonitorMigrationStats mig; 139 qemuMonitorDumpStats dump; 140 qemuDomainBackupStats backup; 141 } stats; 142 qemuDomainMirrorStats mirrorStats; 143 144 char *errmsg; /* optional error message for failed completed jobs */ 145 }; 146 147 void 148 qemuDomainJobInfoFree(qemuDomainJobInfo *info); 149 150 G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree); 151 152 qemuDomainJobInfo * 153 qemuDomainJobInfoCopy(qemuDomainJobInfo *info); 154 155 typedef struct _qemuDomainJobObj qemuDomainJobObj; 156 157 typedef void *(*qemuDomainObjPrivateJobAlloc)(void); 158 typedef void (*qemuDomainObjPrivateJobFree)(void *); 159 typedef void (*qemuDomainObjPrivateJobReset)(void *); 160 typedef int (*qemuDomainObjPrivateJobFormat)(virBuffer *, 161 qemuDomainJobObj *, 162 virDomainObj *); 163 typedef int (*qemuDomainObjPrivateJobParse)(xmlXPathContextPtr, 164 qemuDomainJobObj *, 165 virDomainObj *); 166 167 typedef struct _qemuDomainObjPrivateJobCallbacks qemuDomainObjPrivateJobCallbacks; 168 struct _qemuDomainObjPrivateJobCallbacks { 169 qemuDomainObjPrivateJobAlloc allocJobPrivate; 170 qemuDomainObjPrivateJobFree freeJobPrivate; 171 qemuDomainObjPrivateJobReset resetJobPrivate; 172 qemuDomainObjPrivateJobFormat formatJob; 173 qemuDomainObjPrivateJobParse parseJob; 174 }; 175 176 struct _qemuDomainJobObj { 177 virCond cond; /* Use to coordinate jobs */ 178 179 /* The following members are for QEMU_JOB_* */ 180 qemuDomainJob active; /* Currently running job */ 181 unsigned long long owner; /* Thread id which set current job */ 182 char *ownerAPI; /* The API which owns the job */ 183 unsigned long long started; /* When the current job started */ 184 185 /* The following members are for QEMU_AGENT_JOB_* */ 186 qemuDomainAgentJob agentActive; /* Currently running agent job */ 187 unsigned long long agentOwner; /* Thread id which set current agent job */ 188 char *agentOwnerAPI; /* The API which owns the agent job */ 189 unsigned long long agentStarted; /* When the current agent job started */ 190 191 /* The following members are for QEMU_ASYNC_JOB_* */ 192 virCond asyncCond; /* Use to coordinate with async jobs */ 193 qemuDomainAsyncJob asyncJob; /* Currently active async job */ 194 unsigned long long asyncOwner; /* Thread which set current async job */ 195 char *asyncOwnerAPI; /* The API which owns the async job */ 196 unsigned long long asyncStarted; /* When the current async job started */ 197 int phase; /* Job phase (mainly for migrations) */ 198 unsigned long long mask; /* Jobs allowed during async job */ 199 qemuDomainJobInfo *current; /* async job progress data */ 200 qemuDomainJobInfo *completed; /* statistics data of a recently completed job */ 201 bool abortJob; /* abort of the job requested */ 202 char *error; /* job event completion error */ 203 unsigned long apiFlags; /* flags passed to the API which started the async job */ 204 205 void *privateData; /* job specific collection of data */ 206 qemuDomainObjPrivateJobCallbacks *cb; 207 }; 208 209 const char *qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job, 210 int phase); 211 int qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job, 212 const char *phase); 213 214 void qemuDomainEventEmitJobCompleted(virQEMUDriver *driver, 215 virDomainObj *vm); 216 217 int qemuDomainObjBeginJob(virQEMUDriver *driver, 218 virDomainObj *obj, 219 qemuDomainJob job) 220 G_GNUC_WARN_UNUSED_RESULT; 221 int qemuDomainObjBeginAgentJob(virQEMUDriver *driver, 222 virDomainObj *obj, 223 qemuDomainAgentJob agentJob) 224 G_GNUC_WARN_UNUSED_RESULT; 225 int qemuDomainObjBeginAsyncJob(virQEMUDriver *driver, 226 virDomainObj *obj, 227 qemuDomainAsyncJob asyncJob, 228 virDomainJobOperation operation, 229 unsigned long apiFlags) 230 G_GNUC_WARN_UNUSED_RESULT; 231 int qemuDomainObjBeginNestedJob(virQEMUDriver *driver, 232 virDomainObj *obj, 233 qemuDomainAsyncJob asyncJob) 234 G_GNUC_WARN_UNUSED_RESULT; 235 int qemuDomainObjBeginJobNowait(virQEMUDriver *driver, 236 virDomainObj *obj, 237 qemuDomainJob job) 238 G_GNUC_WARN_UNUSED_RESULT; 239 240 void qemuDomainObjEndJob(virQEMUDriver *driver, 241 virDomainObj *obj); 242 void qemuDomainObjEndAgentJob(virDomainObj *obj); 243 void qemuDomainObjEndAsyncJob(virQEMUDriver *driver, 244 virDomainObj *obj); 245 void qemuDomainObjAbortAsyncJob(virDomainObj *obj); 246 void qemuDomainObjSetJobPhase(virQEMUDriver *driver, 247 virDomainObj *obj, 248 int phase); 249 void qemuDomainObjSetAsyncJobMask(virDomainObj *obj, 250 unsigned long long allowedJobs); 251 int qemuDomainObjRestoreJob(virDomainObj *obj, 252 qemuDomainJobObj *job); 253 void qemuDomainObjDiscardAsyncJob(virQEMUDriver *driver, 254 virDomainObj *obj); 255 void qemuDomainObjReleaseAsyncJob(virDomainObj *obj); 256 257 int qemuDomainJobInfoUpdateTime(qemuDomainJobInfo *jobInfo) 258 ATTRIBUTE_NONNULL(1); 259 int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfo *jobInfo) 260 ATTRIBUTE_NONNULL(1); 261 int qemuDomainJobInfoToInfo(qemuDomainJobInfo *jobInfo, 262 virDomainJobInfoPtr info) 263 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); 264 int qemuDomainJobInfoToParams(qemuDomainJobInfo *jobInfo, 265 int *type, 266 virTypedParameterPtr *params, 267 int *nparams) 268 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) 269 ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); 270 271 bool qemuDomainTrackJob(qemuDomainJob job); 272 273 void qemuDomainObjClearJob(qemuDomainJobObj *job); 274 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(qemuDomainJobObj, qemuDomainObjClearJob); 275 276 int 277 qemuDomainObjInitJob(qemuDomainJobObj *job, 278 qemuDomainObjPrivateJobCallbacks *cb); 279 280 bool qemuDomainJobAllowed(qemuDomainJobObj *jobs, qemuDomainJob newJob); 281 282 int 283 qemuDomainObjPrivateXMLFormatJob(virBuffer *buf, 284 virDomainObj *vm); 285 286 int 287 qemuDomainObjPrivateXMLParseJob(virDomainObj *vm, 288 xmlXPathContextPtr ctxt); 289