This ignores the default "filtered" if unpriv_sgio is not supported
by kernel, but for explicit request "filtered", it error out for
domain starting.
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 15 +++++++++------
src/qemu/qemu_process.c | 31 +++++++++++++++++++++++++++++++
src/qemu/qemu_process.h | 1 +
src/util/virutil.c | 2 +-
src/util/virutil.h | 2 ++
6 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6fba1d9..7472254 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1283,6 +1283,7 @@ virGetDeviceUnprivSGIO;
virGetGroupID;
virGetGroupName;
virGetHostname;
+virGetUnprivSGIOSysfsPath;
virGetUserCacheDirectory;
virGetUserConfigDirectory;
virGetUserDirectory;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index bdaabdf..9ea484c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5865,12 +5865,15 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
NULLSTR(disk->src));
}
- if (ret == 0 &&
- disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
- disk->shared) {
- if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0)
- VIR_WARN("Failed to add disk '%s' to shared disk table",
- disk->src);
+ if (ret == 0) {
+ if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && disk->shared) {
+ if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0)
+ VIR_WARN("Failed to add disk '%s' to shared disk
table",
+ disk->src);
+ }
+
+ if (qemuSetUnprivSGIO(disk) < 0)
+ VIR_WARN("Failed to set unpriv_sgio of disk '%s'",
disk->src);
}
end:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2a1b6b7..47dae1a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3384,6 +3384,34 @@ qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr
driver)
virHashForEach(driver->domains.objs, qemuProcessReconnectHelper, &data);
}
+int
+qemuSetUnprivSGIO(virDomainDiskDefPtr disk)
+{
+ int val = -1;
+
+ if (disk->sgio)
+ val = (disk->sgio == VIR_DOMAIN_DISK_SGIO_UNFILTERED);
+
+ /* Ignore the setting if unpriv_sgio is not supported by the
+ * kernel, otherwise defaults to filter the SG_IO commands,
+ * I.E. Set unpriv_sgio to 0.
+ */
+ if (disk->sgio == VIR_DOMAIN_DISK_SGIO_DEFAULT &&
+ disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+ char *sysfs_path = NULL;
+
+ if ((sysfs_path = virGetUnprivSGIOSysfsPath(disk->src, NULL)) &&
+ virFileExists(sysfs_path))
+ val = 0;
+ VIR_FREE(sysfs_path);
+ }
+
+ if (val >= 0 && virSetDeviceUnprivSGIO(disk->src, NULL, val) < 0)
+ return -1;
+
+ return 0;
+}
+
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -3733,6 +3761,9 @@ int qemuProcessStart(virConnectPtr conn,
if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0)
goto cleanup;
}
+
+ if (qemuSetUnprivSGIO(disk) < 0)
+ goto cleanup;
}
virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index c12df32..52a298d 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -98,5 +98,6 @@ bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
virDomainObjPtr vm);
virBitmapPtr qemuPrepareCpumap(virQEMUDriverPtr driver,
virBitmapPtr nodemask);
+int qemuSetUnprivSGIO(virDomainDiskDefPtr disk);
#endif /* __QEMU_PROCESS_H__ */
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 275489a..47ab17f 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -3171,7 +3171,7 @@ virGetDeviceID(const char *path ATRRIBUTE_UNUSED,
#define SYSFS_DEV_BLOCK_PATH "/sys/dev/block"
-static char *
+char *
virGetUnprivSGIOSysfsPath(const char *path,
const char *sysfs_dir)
{
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 634dcaf..5a08c81 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -291,5 +291,7 @@ int virSetDeviceUnprivSGIO(const char *path,
int virGetDeviceUnprivSGIO(const char *path,
const char *sysfs_dir,
int *unpriv_sgio);
+char * virGetUnprivSGIOSysfsPath(const char *path,
+ const char *sysfs_dir);
#endif /* __VIR_UTIL_H__ */
--
1.7.7.6