Here lifecyle only means staring and shutdown.
To record the original "unpriv_sgio" value, this introduces
"old_cdbfilter" for disk def. When the domain is starting,
the disk's "unpriv_sgio" is set with regards to the config
in domain XML. And when the domain is being destroyed, it's
restored to the original value ("old_cdbfilter").
---
src/conf/domain_conf.h | 1 +
src/qemu/qemu_process.c | 53 +++++++++++++++++++++++++++++++++++++++-------
2 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8d5aa34..47a16c8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -616,6 +616,7 @@ struct _virDomainDiskDef {
bool rawio_specified;
int rawio; /* no = 0, yes = 1 */
int cdbfilter;
+ int old_cdbfilter; /* Record the original state, internal only */
size_t nseclabels;
virSecurityDeviceLabelDefPtr *seclabels;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 962d6ea..13fce78 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3696,17 +3696,39 @@ int qemuProcessStart(virConnectPtr conn,
if (driver->clearEmulatorCapabilities)
virCommandClearCaps(cmd);
- /* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
for (i = 0; i < vm->def->ndisks; i++) {
- if (vm->def->disks[i]->rawio == 1)
+ virDomainDiskDefPtr disk = vm->def->disks[i];
+ int val;
+
+ /* Add CAP_SYS_RAWIO if the disk is desirous of it */
+ if (disk->rawio == 1)
virCommandAllowCap(cmd, CAP_SYS_RAWIO);
- if (vm->def->disks[i]->shared &&
+ /* Add to qemud_driver->sharedDisks list if the disk is shared */
+ if (disk->shared &&
(qemuSharedDiskListAdd(driver->sharedDisks,
- vm->def->disks[i]->src,
+ disk->src,
vm->def->name) < 0)) {
goto cleanup;
}
+
+ if (!disk->cdbfilter)
+ continue;
+
+ /* Set sysfs unpriv_sgio if cdbfilter is specified */
+ if (virGetDeviceUnprivSGIO(disk->src, &val) < 0)
+ goto cleanup;
+
+ if (val == 0)
+ disk->old_cdbfilter = VIR_DOMAIN_DISK_CDB_FILTER_YES;
+ else
+ disk->old_cdbfilter = VIR_DOMAIN_DISK_CDB_FILTER_NO;
+
+ if (virSetDeviceUnprivSGIO(disk->src,
+ (disk->cdbfilter ==
+ VIR_DOMAIN_DISK_CDB_FILTER_NO)
+ ? 1 : 0) < 0)
+ goto cleanup;
}
virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
@@ -4099,17 +4121,32 @@ void qemuProcessStop(struct qemud_driver *driver,
flags & VIR_QEMU_PROCESS_STOP_MIGRATED);
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
- /* Remove the shared disk entry from qemud_driver->sharedDisks */
for (i = 0; i < vm->def->ndisks; i++) {
- if (vm->def->disks[i]->shared &&
+ virDomainDiskDefPtr disk = vm->def->disks[i];
+ int val;
+
+ /* Remove the shared disk entry from qemud_driver->sharedDisks */
+ if (disk->shared &&
(qemuSharedDiskListDel(driver->sharedDisks,
- vm->def->disks[i]->src,
+ disk->src,
vm->def->name) < 0)) {
VIR_WARN("Unable to remove shared disk entry for "
"disk = '%s', domain = '%s'",
- vm->def->disks[i]->src,
+ disk->src,
vm->def->name);
}
+
+ if (!disk->cdbfilter)
+ continue;
+
+ /* Restore sysfs unpriv_sgio for the disk */
+ if (disk->old_cdbfilter == VIR_DOMAIN_DISK_CDB_FILTER_YES)
+ val = 0;
+ else
+ val = 1;
+
+ if (virSetDeviceUnprivSGIO(disk->src, val) < 0)
+ VIR_WARN("Unable to restore unpriv_sgio for disk '%s'",
disk->src);
}
/* Clear out dynamically assigned labels */
--
1.7.7.6