[libvirt] [PATCH 05/12] qemu: Manage disk's unpriv_sgio in domain lifecyle

Osier Yang jyang at redhat.com
Tue Dec 11 13:37:22 UTC 2012


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




More information about the libvir-list mailing list