[libvirt] [PATCH 06/10] qemu: Allow the scsi-generic device in cgroup

Osier Yang jyang at redhat.com
Fri Apr 26 20:15:30 UTC 2013


From: Han Cheng <hanc.fnst at cn.fujitsu.com>

This adds the scsi-generic device into the device controller's
whitelist, so that it's allowed to used by the qemu process.

Signed-off-by: Han Cheng <hanc.fnst at cn.fujitsu.com>

---
v2.5 - v3:
  * Only rebasing, and small changes on coding style
---
 src/qemu/qemu_cgroup.c | 72 +++++++++++++++++++++++++++++++++++++++++++-------
 src/qemu/qemu_cgroup.h |  3 +++
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 891984a..f631db1 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -214,6 +214,34 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
 }
 
 
+int
+qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
+                              const char *path,
+                              void *opaque)
+{
+    virDomainObjPtr vm = opaque;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int rc;
+
+    VIR_DEBUG("Process path '%s' for SCSI device", path);
+
+    rc = virCgroupAllowDevicePath(priv->cgroup, path,
+                                  virSCSIDeviceGetReadonly(dev) ?
+                                  VIR_CGROUP_DEVICE_READ :
+                                  VIR_CGROUP_DEVICE_RW);
+
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
+                             virSCSIDeviceGetReadonly(dev) ? "r" : "rw", rc);
+    if (rc < 0) {
+        virReportSystemError(-rc,
+                             _("Unable to allow device %s"),
+                             path);
+        return -1;
+    }
+
+    return 0;
+}
+
 int qemuInitCgroup(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
                    bool startup)
@@ -421,26 +449,50 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
 
         for (i = 0; i < vm->def->nhostdevs; i++) {
             virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-            virUSBDevicePtr usb;
+            virUSBDevicePtr usb = NULL;
+            virSCSIDevicePtr scsi = NULL;
 
             if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
                 continue;
-            if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+            if (hostdev->source.subsys.type !=
+                VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+                hostdev->source.subsys.type !=
+                VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
                 continue;
             if (hostdev->missing)
                 continue;
 
-            if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                                       hostdev->source.subsys.u.usb.device,
-                                       NULL)) == NULL)
-                goto cleanup;
+            if (hostdev->source.subsys.type ==
+                VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+                if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
+                                           hostdev->source.subsys.u.usb.device,
+                                           NULL)) == NULL)
+                    goto cleanup;
 
-            if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
-                                        vm) < 0) {
+                if (virUSBDeviceFileIterate(usb,
+                                            qemuSetupHostUsbDeviceCgroup,
+                                            vm) < 0) {
+                    virUSBDeviceFree(usb);
+                    goto cleanup;
+                }
                 virUSBDeviceFree(usb);
-                goto cleanup;
+            } else if (hostdev->source.subsys.type ==
+                       VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
+                if ((scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter,
+                                             hostdev->source.subsys.u.scsi.bus,
+                                             hostdev->source.subsys.u.scsi.target,
+                                             hostdev->source.subsys.u.scsi.unit,
+                                             hostdev->readonly)) == NULL)
+                    goto cleanup;
+
+                if (virSCSIDeviceFileIterate(scsi,
+                                             qemuSetupHostScsiDeviceCgroup,
+                                             vm) < 0) {
+                    virSCSIDeviceFree(scsi);
+                    goto cleanup;
+                }
+                virSCSIDeviceFree(scsi);
             }
-            virUSBDeviceFree(usb);
         }
     }
 
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index e63f443..14f0553 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -36,6 +36,9 @@ int qemuTeardownDiskCgroup(virDomainObjPtr vm,
 int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev,
                                  const char *path,
                                  void *opaque);
+int qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev,
+                                  const char *path,
+                                  void *opaque);
 int qemuInitCgroup(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
                    bool startup);
-- 
1.8.1.4




More information about the libvir-list mailing list