mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Move QEMU-only fields from virDomainDiskDef into privateData
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
078717e151
commit
46a7a49535
@ -1290,11 +1290,6 @@ virDomainDiskDefNew(virDomainXMLOptionPtr xmlopt)
|
||||
!(ret->privateData = xmlopt->privateData.diskNew()))
|
||||
goto error;
|
||||
|
||||
if (virCondInit(&ret->blockJobSyncCond) < 0) {
|
||||
virReportSystemError(errno, "%s", _("Failed to initialize condition"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
@ -1319,7 +1314,6 @@ virDomainDiskDefFree(virDomainDiskDefPtr def)
|
||||
VIR_FREE(def->domain_name);
|
||||
virDomainDeviceInfoClear(&def->info);
|
||||
virObjectUnref(def->privateData);
|
||||
virCondDestroy(&def->blockJobSyncCond);
|
||||
|
||||
VIR_FREE(def);
|
||||
}
|
||||
|
@ -691,20 +691,10 @@ struct _virDomainDiskDef {
|
||||
int tray_status; /* enum virDomainDiskTray */
|
||||
int removable; /* enum virTristateSwitch */
|
||||
|
||||
/* ideally we want a smarter way to interlock block jobs on single qemu disk
|
||||
* in the future, but for now we just disallow any concurrent job on a
|
||||
* single disk */
|
||||
bool blockjob;
|
||||
virStorageSourcePtr mirror;
|
||||
int mirrorState; /* enum virDomainDiskMirrorState */
|
||||
int mirrorJob; /* virDomainBlockJobType */
|
||||
|
||||
/* for some synchronous block jobs, we need to notify the owner */
|
||||
virCond blockJobSyncCond;
|
||||
int blockJobType; /* type of the block job from the event */
|
||||
int blockJobStatus; /* status of the finished block job */
|
||||
bool blockJobSync; /* the block job needs synchronized termination */
|
||||
|
||||
struct {
|
||||
unsigned int cylinders;
|
||||
unsigned int heads;
|
||||
|
@ -65,6 +65,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||
virDomainDiskDefPtr persistDisk = NULL;
|
||||
bool save = false;
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
/* Have to generate two variants of the event for old vs. new
|
||||
* client callbacks */
|
||||
@ -127,7 +128,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
||||
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
|
||||
true, true));
|
||||
disk->blockjob = false;
|
||||
diskPriv->blockjob = false;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_BLOCK_JOB_READY:
|
||||
@ -143,7 +144,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
||||
VIR_DOMAIN_DISK_MIRROR_STATE_ABORT : VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||
save = true;
|
||||
disk->blockjob = false;
|
||||
diskPriv->blockjob = false;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_BLOCK_JOB_LAST:
|
||||
@ -185,11 +186,13 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
||||
void
|
||||
qemuBlockJobSyncBegin(virDomainDiskDefPtr disk)
|
||||
{
|
||||
if (disk->blockJobSync)
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (diskPriv->blockJobSync)
|
||||
VIR_WARN("Disk %s already has synchronous block job",
|
||||
disk->dst);
|
||||
|
||||
disk->blockJobSync = true;
|
||||
diskPriv->blockJobSync = true;
|
||||
}
|
||||
|
||||
|
||||
@ -211,15 +214,17 @@ qemuBlockJobSyncEnd(virQEMUDriverPtr driver,
|
||||
virDomainDiskDefPtr disk,
|
||||
virConnectDomainEventBlockJobStatus *ret_status)
|
||||
{
|
||||
if (disk->blockJobSync && disk->blockJobStatus != -1) {
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (diskPriv->blockJobSync && diskPriv->blockJobStatus != -1) {
|
||||
if (ret_status)
|
||||
*ret_status = disk->blockJobStatus;
|
||||
*ret_status = diskPriv->blockJobStatus;
|
||||
qemuBlockJobEventProcess(driver, vm, disk,
|
||||
disk->blockJobType,
|
||||
disk->blockJobStatus);
|
||||
disk->blockJobStatus = -1;
|
||||
diskPriv->blockJobType,
|
||||
diskPriv->blockJobStatus);
|
||||
diskPriv->blockJobStatus = -1;
|
||||
}
|
||||
disk->blockJobSync = false;
|
||||
diskPriv->blockJobSync = false;
|
||||
}
|
||||
|
||||
|
||||
@ -248,24 +253,26 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
|
||||
unsigned long long timeout,
|
||||
virConnectDomainEventBlockJobStatus *ret_status)
|
||||
{
|
||||
if (!disk->blockJobSync) {
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (!diskPriv->blockJobSync) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("No current synchronous block job"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (disk->blockJobSync && disk->blockJobStatus == -1) {
|
||||
while (diskPriv->blockJobSync && diskPriv->blockJobStatus == -1) {
|
||||
int r;
|
||||
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("guest unexpectedly quit"));
|
||||
disk->blockJobSync = false;
|
||||
diskPriv->blockJobSync = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout == (unsigned long long)-1) {
|
||||
r = virCondWait(&disk->blockJobSyncCond, &vm->parent.lock);
|
||||
r = virCondWait(&diskPriv->blockJobSyncCond, &vm->parent.lock);
|
||||
} else if (timeout) {
|
||||
unsigned long long now;
|
||||
if (virTimeMillisNow(&now) < 0) {
|
||||
@ -273,7 +280,8 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
|
||||
_("Unable to get current time"));
|
||||
return -1;
|
||||
}
|
||||
r = virCondWaitUntil(&disk->blockJobSyncCond, &vm->parent.lock,
|
||||
r = virCondWaitUntil(&diskPriv->blockJobSyncCond,
|
||||
&vm->parent.lock,
|
||||
now + timeout);
|
||||
if (r < 0 && errno == ETIMEDOUT)
|
||||
return 0;
|
||||
@ -283,7 +291,7 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
disk->blockJobSync = false;
|
||||
diskPriv->blockJobSync = false;
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Unable to wait on block job sync "
|
||||
"condition"));
|
||||
@ -292,11 +300,11 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
|
||||
}
|
||||
|
||||
if (ret_status)
|
||||
*ret_status = disk->blockJobStatus;
|
||||
*ret_status = diskPriv->blockJobStatus;
|
||||
qemuBlockJobEventProcess(driver, vm, disk,
|
||||
disk->blockJobType,
|
||||
disk->blockJobStatus);
|
||||
disk->blockJobStatus = -1;
|
||||
diskPriv->blockJobType,
|
||||
diskPriv->blockJobStatus);
|
||||
diskPriv->blockJobStatus = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -412,6 +412,53 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
|
||||
}
|
||||
|
||||
|
||||
static virClassPtr qemuDomainDiskPrivateClass;
|
||||
static void qemuDomainDiskPrivateDispose(void *obj);
|
||||
|
||||
static int
|
||||
qemuDomainDiskPrivateOnceInit(void)
|
||||
{
|
||||
qemuDomainDiskPrivateClass = virClassNew(virClassForObject(),
|
||||
"qemuDomainDiskPrivate",
|
||||
sizeof(qemuDomainDiskPrivate),
|
||||
qemuDomainDiskPrivateDispose);
|
||||
if (!qemuDomainDiskPrivateClass)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
VIR_ONCE_GLOBAL_INIT(qemuDomainDiskPrivate)
|
||||
|
||||
static virObjectPtr
|
||||
qemuDomainDiskPrivateNew(void)
|
||||
{
|
||||
qemuDomainDiskPrivatePtr priv;
|
||||
|
||||
if (qemuDomainDiskPrivateInitialize() < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(priv = virObjectNew(qemuDomainDiskPrivateClass)))
|
||||
return NULL;
|
||||
|
||||
if (virCondInit(&priv->blockJobSyncCond) < 0) {
|
||||
virReportSystemError(errno, "%s", _("Failed to initialize condition"));
|
||||
virObjectUnref(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (virObjectPtr) priv;
|
||||
}
|
||||
|
||||
static void
|
||||
qemuDomainDiskPrivateDispose(void *obj)
|
||||
{
|
||||
qemuDomainDiskPrivatePtr priv = obj;
|
||||
|
||||
virCondDestroy(&priv->blockJobSyncCond);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
qemuDomainObjPrivateAlloc(void)
|
||||
{
|
||||
@ -741,6 +788,7 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
|
||||
virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks = {
|
||||
.alloc = qemuDomainObjPrivateAlloc,
|
||||
.free = qemuDomainObjPrivateFree,
|
||||
.diskNew = qemuDomainDiskPrivateNew,
|
||||
.parse = qemuDomainObjPrivateXMLParse,
|
||||
.format = qemuDomainObjPrivateXMLFormat,
|
||||
};
|
||||
@ -2809,6 +2857,8 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
||||
bool
|
||||
qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
|
||||
{
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (disk->mirror) {
|
||||
virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
|
||||
_("disk '%s' already in active block job"),
|
||||
@ -2817,7 +2867,7 @@ qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (disk->blockjob) {
|
||||
if (diskPriv->blockjob) {
|
||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
||||
_("disk '%s' already in active block job"),
|
||||
disk->dst);
|
||||
@ -2843,12 +2893,13 @@ qemuDomainHasBlockjob(virDomainObjPtr vm,
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
if (!copy_only &&
|
||||
vm->def->disks[i]->blockjob)
|
||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (!copy_only && diskPriv->blockjob)
|
||||
return true;
|
||||
|
||||
if (vm->def->disks[i]->mirror &&
|
||||
vm->def->disks[i]->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
|
||||
if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
# include "qemu_conf.h"
|
||||
# include "qemu_capabilities.h"
|
||||
# include "virchrdev.h"
|
||||
# include "virobject.h"
|
||||
|
||||
# define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
|
||||
(VIR_DOMAIN_XML_SECURE | \
|
||||
@ -199,6 +200,26 @@ struct _qemuDomainObjPrivate {
|
||||
virBitmapPtr autoCpuset;
|
||||
};
|
||||
|
||||
# define QEMU_DOMAIN_DISK_PRIVATE(disk) \
|
||||
((qemuDomainDiskPrivatePtr) (disk)->privateData)
|
||||
|
||||
typedef struct _qemuDomainDiskPrivate qemuDomainDiskPrivate;
|
||||
typedef qemuDomainDiskPrivate *qemuDomainDiskPrivatePtr;
|
||||
struct _qemuDomainDiskPrivate {
|
||||
virObject parent;
|
||||
|
||||
/* ideally we want a smarter way to interlock block jobs on single qemu disk
|
||||
* in the future, but for now we just disallow any concurrent job on a
|
||||
* single disk */
|
||||
bool blockjob;
|
||||
|
||||
/* for some synchronous block jobs, we need to notify the owner */
|
||||
virCond blockJobSyncCond;
|
||||
int blockJobType; /* type of the block job from the event */
|
||||
int blockJobStatus; /* status of the finished block job */
|
||||
bool blockJobSync; /* the block job needs synchronized termination */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
QEMU_PROCESS_EVENT_WATCHDOG = 0,
|
||||
QEMU_PROCESS_EVENT_GUESTPANIC,
|
||||
|
@ -14317,9 +14317,10 @@ qemuDomainSnapshotPrepare(virConnectPtr conn,
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
virDomainSnapshotDiskDefPtr disk = &def->disks[i];
|
||||
virDomainDiskDefPtr dom_disk = vm->def->disks[i];
|
||||
qemuDomainDiskPrivatePtr dom_diskPriv = QEMU_DOMAIN_DISK_PRIVATE(dom_disk);
|
||||
|
||||
if (disk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_NONE &&
|
||||
dom_disk->blockjob) {
|
||||
dom_diskPriv->blockjob) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("disk '%s' has an active block job"),
|
||||
disk->name);
|
||||
@ -16639,7 +16640,7 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
|
||||
if (ret < 0)
|
||||
goto endjob;
|
||||
|
||||
disk->blockjob = true;
|
||||
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
|
||||
|
||||
endjob:
|
||||
qemuDomainObjEndJob(driver, vm);
|
||||
@ -16767,7 +16768,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
||||
}
|
||||
|
||||
endjob:
|
||||
if (disk && disk->blockJobSync)
|
||||
if (disk && QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync)
|
||||
qemuBlockJobSyncEnd(driver, vm, disk, NULL);
|
||||
qemuDomainObjEndJob(driver, vm);
|
||||
|
||||
@ -17100,7 +17101,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
|
||||
disk->mirror = mirror;
|
||||
mirror = NULL;
|
||||
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
|
||||
disk->blockjob = true;
|
||||
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
|
||||
|
||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
||||
VIR_WARN("Unable to save status on vm %s after state change",
|
||||
@ -17493,7 +17494,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
disk->blockjob = true;
|
||||
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
|
||||
|
||||
if (mirror) {
|
||||
if (ret == 0) {
|
||||
|
@ -1743,6 +1743,7 @@ qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver,
|
||||
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
/* skip shared, RO and source-less disks */
|
||||
if (disk->src->shared || disk->src->readonly ||
|
||||
@ -1750,7 +1751,7 @@ qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver,
|
||||
continue;
|
||||
|
||||
/* skip disks that didn't start mirroring */
|
||||
if (!disk->blockJobSync)
|
||||
if (!diskPriv->blockJobSync)
|
||||
continue;
|
||||
|
||||
/* process any pending event */
|
||||
@ -1871,6 +1872,7 @@ qemuMigrationCancelDriveMirror(virQEMUDriverPtr driver,
|
||||
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
/* skip shared, RO and source-less disks */
|
||||
if (disk->src->shared || disk->src->readonly ||
|
||||
@ -1878,7 +1880,7 @@ qemuMigrationCancelDriveMirror(virQEMUDriverPtr driver,
|
||||
continue;
|
||||
|
||||
/* skip disks that didn't start mirroring */
|
||||
if (!disk->blockJobSync)
|
||||
if (!diskPriv->blockJobSync)
|
||||
continue;
|
||||
|
||||
if (qemuMigrationCancelOneDriveMirror(driver, vm, disk) < 0)
|
||||
|
@ -1001,6 +1001,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
virQEMUDriverPtr driver = opaque;
|
||||
struct qemuProcessEvent *processEvent = NULL;
|
||||
virDomainDiskDefPtr disk;
|
||||
qemuDomainDiskPrivatePtr diskPriv;
|
||||
char *data = NULL;
|
||||
|
||||
virObjectLock(vm);
|
||||
@ -1010,12 +1011,13 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
|
||||
if (!(disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias)))
|
||||
goto error;
|
||||
diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
|
||||
if (disk->blockJobSync) {
|
||||
disk->blockJobType = type;
|
||||
disk->blockJobStatus = status;
|
||||
if (diskPriv->blockJobSync) {
|
||||
diskPriv->blockJobType = type;
|
||||
diskPriv->blockJobStatus = status;
|
||||
/* We have an SYNC API waiting for this event, dispatch it back */
|
||||
virCondSignal(&disk->blockJobSyncCond);
|
||||
virCondSignal(&diskPriv->blockJobSyncCond);
|
||||
} else {
|
||||
/* there is no waiting SYNC API, dispatch the update to a thread */
|
||||
if (VIR_ALLOC(processEvent) < 0)
|
||||
@ -5063,9 +5065,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
||||
|
||||
/* Wake up anything waiting on synchronous block jobs */
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||
if (disk->blockJobSync && disk->blockJobStatus == -1)
|
||||
virCondSignal(&disk->blockJobSyncCond);
|
||||
qemuDomainDiskPrivatePtr diskPriv =
|
||||
QEMU_DOMAIN_DISK_PRIVATE(vm->def->disks[i]);
|
||||
if (diskPriv->blockJobSync && diskPriv->blockJobStatus == -1)
|
||||
virCondSignal(&diskPriv->blockJobSyncCond);
|
||||
}
|
||||
|
||||
if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user