[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH v2.5 08/10] qemu: cgroup and selinux for scsi hostdev



As libvirt gives guest minimal cgroup, we need to add sg into guest cgroup
whitelist for scsi hostdev. And we should set and restore selinux label
correctly for scsi hostdev.

Signed-off-by: Han Cheng <hanc fnst cn fujitsu com>
---
 src/qemu/qemu_cgroup.c          |   71 ++++++++++++++++++++++++++++++--------
 src/qemu/qemu_cgroup.h          |    3 ++
 src/security/security_selinux.c |   56 ++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 5aa9416..4f75cee 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -180,6 +180,30 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
     return 0;
 }
 
+int qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev,
+                                  const char *path,
+                                  void *opaque)
+{
+    qemuCgroupData *data = opaque;
+    int rc;
+
+    VIR_DEBUG("Process path '%s' for SCSI device", path);
+    rc = virCgroupAllowDevicePath(data->cgroup, path,
+                                  virSCSIDeviceGetReadonly(dev) ? VIR_CGROUP_DEVICE_READ
+                                  : VIR_CGROUP_DEVICE_RW);
+    virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path,
+                             virSCSIDeviceGetReadonly(dev) ? "r" : "rw", rc);
+    if (rc < 0) {
+        virReportSystemError(-rc,
+                             _("Unable to allow device %s"),
+                             path);
+        return -1;
+    }
+
+    return 0;
+
+}
+
 int qemuSetupCgroup(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virBitmapPtr nodemask)
@@ -277,26 +301,43 @@ 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)
-                continue;
-            if (hostdev->missing)
-                continue;
+            switch (hostdev->source.subsys.type) {
+            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+                if (hostdev->missing)
+                    continue;
 
-            if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                                       hostdev->source.subsys.u.usb.device,
-                                       NULL)) == NULL)
-                goto cleanup;
+                if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
+                                           hostdev->source.subsys.u.usb.device,
+                                           NULL)) == NULL)
+                    goto cleanup;
 
-            if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
-                                        &data) < 0) {
+                if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
+                                            &data) < 0) {
+                    goto cleanup;
+                }
                 virUSBDeviceFree(usb);
-                goto cleanup;
+                break;
+            case 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,
+                                             &data) < 0) {
+                    virSCSIDeviceFree(scsi);
+                    goto cleanup;
+                }
+                virSCSIDeviceFree(scsi);
+                break;
             }
-            virUSBDeviceFree(usb);
         }
     }
 
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index a677d07..72ed66a 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -45,6 +45,9 @@ int qemuTeardownDiskCgroup(virDomainObjPtr vm,
 int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev,
                                  const char *path,
                                  void *opaque);
+int qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev,
+                                  const char *path,
+                                  void *opaque);
 int qemuSetupCgroup(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virBitmapPtr nodemask);
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 60596ad..8b5ddc9 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -39,6 +39,7 @@
 #include "virlog.h"
 #include "virpci.h"
 #include "virusb.h"
+#include "virscsi.h"
 #include "virstoragefile.h"
 #include "virfile.h"
 #include "virhash.h"
@@ -1200,6 +1201,18 @@ virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
                                        &cbdata);
 }
 
+static int
+virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
+                                       const char *file, void *opaque)
+{
+    virSecurityLabelDefPtr secdef;
+    virDomainDefPtr def = opaque;
+
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (secdef == NULL)
+        return -1;
+    return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
+}
 
 static int
 virSecuritySELinuxSetSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED,
@@ -1271,6 +1284,23 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
         break;
     }
 
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
+        virSCSIDevicePtr scsi =
+            virSCSIDeviceNew(dev->source.subsys.u.scsi.adapter,
+                             dev->source.subsys.u.scsi.bus,
+                             dev->source.subsys.u.scsi.target,
+                             dev->source.subsys.u.scsi.unit,
+                             dev->readonly);
+
+        if (!scsi)
+            goto done;
+
+        ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxSetSecuritySCSILabel, def);
+        virSCSIDeviceFree(scsi);
+
+        break;
+    }
+
     default:
         ret = 0;
         break;
@@ -1368,6 +1398,15 @@ virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN
     }
 }
 
+static int
+virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
+                                           const char *file,
+                                           void *opaque)
+{
+    virSecurityManagerPtr mgr = opaque;
+
+    return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file);
+}
 
 static int
 virSecuritySELinuxRestoreSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED,
@@ -1433,6 +1472,23 @@ virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr,
         break;
     }
 
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
+        virSCSIDevicePtr scsi =
+            virSCSIDeviceNew(dev->source.subsys.u.scsi.adapter,
+                             dev->source.subsys.u.scsi.bus,
+                             dev->source.subsys.u.scsi.target,
+                             dev->source.subsys.u.scsi.unit,
+                             dev->readonly);
+
+        if (!scsi)
+            goto done;
+
+        ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSecuritySCSILabel, mgr);
+        virSCSIDeviceFree(scsi);
+
+        break;
+    }
+
     default:
         ret = 0;
         break;
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]