[libvirt] [PATCH 08/10] qemu: Manage disk's cdbfilter in domain's lifecycle

Osier Yang jyang at redhat.com
Tue Dec 4 13:17:31 UTC 2012


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 6e65cfd..d7c9b6b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -627,6 +627,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 2a60741..b991a22 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(virQEMUDriverPtr 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.1




More information about the libvir-list mailing list