2015-04-16 09:24:19 +00:00
|
|
|
/*
|
|
|
|
* qemu_blockjob.h: helper functions for QEMU block jobs
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
|
|
|
* 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
|
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2018-12-13 14:53:50 +00:00
|
|
|
#ifndef LIBVIRT_QEMU_BLOCKJOB_H
|
|
|
|
# define LIBVIRT_QEMU_BLOCKJOB_H
|
2015-04-16 09:24:19 +00:00
|
|
|
|
qemuBlockJobSync*: introduce sync block job helpers
qemuBlockJobSyncBegin and qemuBlockJobSyncEnd delimit a region of code
where block job events are processed "synchronously".
qemuBlockJobSyncWait and qemuBlockJobSyncWaitWithTimeout wait for an
event generated by a block job.
The Wait* functions may be called multiple times while the synchronous
block job is active. Any pending block job event will be processed by
only when Wait* or End is called. disk->blockJobStatus is reset by
these functions, so if it is needed a pointer to a
virConnectDomainEventBlockJobStatus variable should be passed as the
last argument. It is safe to pass NULL if you do not care about the
block job status.
All functions assume the VM object is locked. The Wait* functions will
unlock the object for as long as they are waiting. They will return -1
and report an error if the domain exits before an event is received.
Typical use is as follows:
virQEMUDriverPtr driver;
virDomainObjPtr vm; /* locked */
virDomainDiskDefPtr disk;
virConnectDomainEventBlockJobStatus status;
qemuBlockJobSyncBegin(disk);
... start block job ...
if (qemuBlockJobSyncWait(driver, vm, disk, &status) < 0) {
/* domain died while waiting for event */
ret = -1;
goto error;
}
... possibly start other block jobs
or wait for further events ...
qemuBlockJobSyncEnd(driver, vm, disk, NULL);
To perform other tasks periodically while waiting for an event:
virQEMUDriverPtr driver;
virDomainObjPtr vm; /* locked */
virDomainDiskDefPtr disk;
virConnectDomainEventBlockJobStatus status;
unsigned long long timeout = 500 * 1000ull; /* milliseconds */
qemuBlockJobSyncBegin(disk);
... start block job ...
do {
... do other task ...
if (qemuBlockJobSyncWaitWithTimeout(driver, vm, disk,
timeout, &status) < 0) {
/* domain died while waiting for event */
ret = -1;
goto error;
}
} while (status == -1);
qemuBlockJobSyncEnd(driver, vm, disk, NULL);
Signed-off-by: Michael Chapman <mike@very.puzzling.org>
2015-04-16 09:24:20 +00:00
|
|
|
# include "internal.h"
|
2015-04-16 09:24:19 +00:00
|
|
|
# include "qemu_conf.h"
|
|
|
|
|
2019-01-17 15:34:11 +00:00
|
|
|
/**
|
|
|
|
* This enum has to map all known block job states from enum virDomainBlockJobType
|
|
|
|
* to the same values. All internal blockjobs can be mapped after and don't
|
|
|
|
* need to have stable values.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
2019-01-23 19:38:41 +00:00
|
|
|
/* Mapped to public enum */
|
2019-01-17 15:34:11 +00:00
|
|
|
QEMU_BLOCKJOB_STATE_COMPLETED = VIR_DOMAIN_BLOCK_JOB_COMPLETED,
|
|
|
|
QEMU_BLOCKJOB_STATE_FAILED = VIR_DOMAIN_BLOCK_JOB_FAILED,
|
|
|
|
QEMU_BLOCKJOB_STATE_CANCELLED = VIR_DOMAIN_BLOCK_JOB_CANCELED,
|
|
|
|
QEMU_BLOCKJOB_STATE_READY = VIR_DOMAIN_BLOCK_JOB_READY,
|
2019-01-23 19:38:41 +00:00
|
|
|
/* Additional enum values local to qemu */
|
|
|
|
QEMU_BLOCKJOB_STATE_NEW,
|
2019-01-17 15:34:11 +00:00
|
|
|
QEMU_BLOCKJOB_STATE_RUNNING,
|
|
|
|
QEMU_BLOCKJOB_STATE_LAST
|
|
|
|
} qemuBlockjobState;
|
|
|
|
verify((int)QEMU_BLOCKJOB_STATE_NEW == VIR_DOMAIN_BLOCK_JOB_LAST);
|
|
|
|
|
2018-11-23 11:45:32 +00:00
|
|
|
/**
|
|
|
|
* This enum has to map all known block job types from enum virDomainBlockJobType
|
|
|
|
* to the same values. All internal blockjobs can be mapped after and don't
|
|
|
|
* need to have stable values.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
2019-01-23 19:38:41 +00:00
|
|
|
/* Mapped to public enum */
|
2018-11-23 11:45:32 +00:00
|
|
|
QEMU_BLOCKJOB_TYPE_NONE = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN,
|
|
|
|
QEMU_BLOCKJOB_TYPE_PULL = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL,
|
|
|
|
QEMU_BLOCKJOB_TYPE_COPY = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY,
|
|
|
|
QEMU_BLOCKJOB_TYPE_COMMIT = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT,
|
|
|
|
QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT,
|
2019-01-23 19:38:41 +00:00
|
|
|
/* Additional enum values local to qemu */
|
2018-11-23 11:45:32 +00:00
|
|
|
QEMU_BLOCKJOB_TYPE_INTERNAL,
|
|
|
|
QEMU_BLOCKJOB_TYPE_LAST
|
|
|
|
} qemuBlockJobType;
|
|
|
|
verify((int)QEMU_BLOCKJOB_TYPE_INTERNAL == VIR_DOMAIN_BLOCK_JOB_TYPE_LAST);
|
2018-10-17 06:57:08 +00:00
|
|
|
|
|
|
|
typedef struct _qemuBlockJobData qemuBlockJobData;
|
|
|
|
typedef qemuBlockJobData *qemuBlockJobDataPtr;
|
|
|
|
|
|
|
|
struct _qemuBlockJobData {
|
2018-11-14 15:47:50 +00:00
|
|
|
virObject parent;
|
|
|
|
|
2019-01-17 16:01:55 +00:00
|
|
|
char *name;
|
|
|
|
|
2018-11-21 14:36:47 +00:00
|
|
|
virDomainDiskDefPtr disk; /* may be NULL, if blockjob does not correspond to any disk */
|
|
|
|
|
2018-10-17 06:57:08 +00:00
|
|
|
bool started;
|
2018-11-23 11:45:32 +00:00
|
|
|
int type; /* qemuBlockJobType */
|
2019-01-17 15:34:11 +00:00
|
|
|
int state; /* qemuBlockjobState */
|
2018-10-17 06:57:08 +00:00
|
|
|
char *errmsg;
|
|
|
|
bool synchronous; /* API call is waiting for this job */
|
2018-11-22 14:05:50 +00:00
|
|
|
|
|
|
|
int newstate; /* virConnectDomainEventBlockJobStatus - new state to be processed */
|
2018-10-17 06:57:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-11-19 15:48:09 +00:00
|
|
|
qemuBlockJobDataPtr
|
2018-11-23 11:45:32 +00:00
|
|
|
qemuBlockJobDiskNew(virDomainDiskDefPtr disk,
|
2019-01-17 16:01:55 +00:00
|
|
|
qemuBlockJobType type,
|
|
|
|
const char *jobname)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
|
2018-11-19 15:48:09 +00:00
|
|
|
|
|
|
|
qemuBlockJobDataPtr
|
|
|
|
qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk)
|
|
|
|
ATTRIBUTE_NONNULL(1);
|
|
|
|
|
|
|
|
void
|
|
|
|
qemuBlockJobStarted(qemuBlockJobDataPtr job)
|
|
|
|
ATTRIBUTE_NONNULL(1);
|
|
|
|
|
2019-01-17 15:34:11 +00:00
|
|
|
bool
|
|
|
|
qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
|
|
|
|
ATTRIBUTE_NONNULL(1);
|
|
|
|
|
2018-11-19 15:48:09 +00:00
|
|
|
void
|
|
|
|
qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job);
|
|
|
|
|
2018-11-27 12:55:28 +00:00
|
|
|
int qemuBlockJobUpdate(virDomainObjPtr vm,
|
|
|
|
qemuBlockJobDataPtr job,
|
|
|
|
int asyncJob);
|
2015-04-16 09:24:19 +00:00
|
|
|
|
2018-10-19 07:14:54 +00:00
|
|
|
void qemuBlockJobSyncBegin(qemuBlockJobDataPtr job);
|
2018-11-27 17:06:28 +00:00
|
|
|
void qemuBlockJobSyncEnd(virDomainObjPtr vm,
|
|
|
|
qemuBlockJobDataPtr job,
|
|
|
|
int asyncJob);
|
qemuBlockJobSync*: introduce sync block job helpers
qemuBlockJobSyncBegin and qemuBlockJobSyncEnd delimit a region of code
where block job events are processed "synchronously".
qemuBlockJobSyncWait and qemuBlockJobSyncWaitWithTimeout wait for an
event generated by a block job.
The Wait* functions may be called multiple times while the synchronous
block job is active. Any pending block job event will be processed by
only when Wait* or End is called. disk->blockJobStatus is reset by
these functions, so if it is needed a pointer to a
virConnectDomainEventBlockJobStatus variable should be passed as the
last argument. It is safe to pass NULL if you do not care about the
block job status.
All functions assume the VM object is locked. The Wait* functions will
unlock the object for as long as they are waiting. They will return -1
and report an error if the domain exits before an event is received.
Typical use is as follows:
virQEMUDriverPtr driver;
virDomainObjPtr vm; /* locked */
virDomainDiskDefPtr disk;
virConnectDomainEventBlockJobStatus status;
qemuBlockJobSyncBegin(disk);
... start block job ...
if (qemuBlockJobSyncWait(driver, vm, disk, &status) < 0) {
/* domain died while waiting for event */
ret = -1;
goto error;
}
... possibly start other block jobs
or wait for further events ...
qemuBlockJobSyncEnd(driver, vm, disk, NULL);
To perform other tasks periodically while waiting for an event:
virQEMUDriverPtr driver;
virDomainObjPtr vm; /* locked */
virDomainDiskDefPtr disk;
virConnectDomainEventBlockJobStatus status;
unsigned long long timeout = 500 * 1000ull; /* milliseconds */
qemuBlockJobSyncBegin(disk);
... start block job ...
do {
... do other task ...
if (qemuBlockJobSyncWaitWithTimeout(driver, vm, disk,
timeout, &status) < 0) {
/* domain died while waiting for event */
ret = -1;
goto error;
}
} while (status == -1);
qemuBlockJobSyncEnd(driver, vm, disk, NULL);
Signed-off-by: Michael Chapman <mike@very.puzzling.org>
2015-04-16 09:24:20 +00:00
|
|
|
|
2018-11-19 15:48:09 +00:00
|
|
|
qemuBlockJobDataPtr
|
|
|
|
qemuBlockJobGetByDisk(virDomainDiskDefPtr disk)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
|
|
|
|
2018-12-13 14:53:50 +00:00
|
|
|
#endif /* LIBVIRT_QEMU_BLOCKJOB_H */
|