Here lifecyle only means starting and shutdown.
To record the original "unpriv_sgio" value for non-shared disk,
this introduces "orig_cdbfilter" for disk def. On domain starting,
the disk's "unpriv_sgio" is set with regards to the config in domain
XML. And on domain shutdown, it's restored to the original value
("orig_cdbfilter"). Later patch will prevent restoring if other
domain is still using the shared disk.
---
src/conf/domain_conf.h | 1 +
src/qemu/qemu_process.c | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9586f75..256bea2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -629,6 +629,7 @@ struct _virDomainDiskDef {
bool rawio_specified;
int rawio; /* no = 0, yes = 1 */
int cdbfilter;
+ int orig_cdbfilter;
size_t nseclabels;
virSecurityDeviceLabelDefPtr *seclabels;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 89152b8..859c5b0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3707,12 +3707,31 @@ int qemuProcessStart(virConnectPtr conn,
/* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
+ int val;
if (disk->rawio == 1)
virCommandAllowCap(cmd, CAP_SYS_RAWIO);
+ /* Set sysfs unpriv_sgio if cdbfilter is specified */
+ if (disk->cdbfilter) {
+ if (virGetDeviceUnprivSGIO(disk->src, &val) < 0)
+ goto cleanup;
+
+ if (val == 0)
+ disk->orig_cdbfilter = VIR_DOMAIN_DISK_CDB_FILTER_YES;
+ else
+ disk->orig_cdbfilter = VIR_DOMAIN_DISK_CDB_FILTER_NO;
+
+ if (virSetDeviceUnprivSGIO(disk->src,
+ (disk->cdbfilter ==
+ VIR_DOMAIN_DISK_CDB_FILTER_NO)
+ ? 1 : 0) < 0)
+ goto cleanup;
+ }
+
if (disk->shared) {
- if (qemuAddSharedDisk(driver->sharedDisks, disk->src, 0) < 0)
+ if (qemuAddSharedDisk(driver->sharedDisks, disk->src,
+ disk->orig_cdbfilter) < 0)
goto cleanup;
}
}
@@ -4113,6 +4132,19 @@ void qemuProcessStop(virQEMUDriverPtr driver,
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
+ int val;
+
+ /* Restore sysfs unpriv_sgio for the disk */
+ if (disk->cdbfilter) {
+ if (disk->orig_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);
+ }
if (disk->shared) {
ignore_value(qemuRemoveSharedDisk(driver->sharedDisks, disk->src));
--
1.7.7.6