From: Osier Yang Date: Wed, 2 Jan 2013 14:37:10 +0000 (+0800) Subject: qemu: set unpriv_sgio when starting domain and attaching disk X-Git-Tag: v1.0.2-rc1~281 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=278f87c4b526dcf97d1824ce08722925428e17b4;p=thirdparty%2Flibvirt.git qemu: set unpriv_sgio when starting domain and attaching disk This ignores the default "filtered" if unpriv_sgio is not supported by kernel, but for explicit request "filtered", it error out for domain starting. --- diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 237e040b08..d9b7c1d865 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1284,6 +1284,7 @@ virGetDeviceUnprivSGIO; virGetGroupID; virGetGroupName; virGetHostname; +virGetUnprivSGIOSysfsPath; virGetUserCacheDirectory; virGetUserConfigDirectory; virGetUserDirectory; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index df728037d3..55a5f7b144 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 47c62d83f4..a74a92306d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3409,6 +3409,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, @@ -3758,6 +3786,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 c12df32128..52a298d503 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 275489ac70..47ab17f542 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 634dcaf0c1..5a08c8138b 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__ */