[libvirt] [PATCH 05/10] util: cgroup: Allow ignoring EACCES in virCgroup(Allow|Deny)DevicePath

Peter Krempa pkrempa at redhat.com
Tue Feb 16 15:29:47 UTC 2016


When adding disk images to ACL we may call those functions on NFS
shares. In that case we might get an EACCES, which isn't really relevant
since NFS would not hold a block device. This patch adds a flag that
allows to stop reporting an error on EACCES to avoid spaming logs.

Currently there's no functional change.
---
 src/lxc/lxc_cgroup.c   | 12 ++++++------
 src/lxc/lxc_driver.c   |  9 ++++++---
 src/qemu/qemu_cgroup.c | 20 ++++++++++----------
 src/util/vircgroup.c   | 38 +++++++++++++++++++++++++++++++++-----
 src/util/vircgroup.h   |  6 ++++--
 5 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 60805af..4afe7e2 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -331,7 +331,7 @@ virLXCSetupHostUSBDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,

     VIR_DEBUG("Process path '%s' for USB device", path);
     if (virCgroupAllowDevicePath(cgroup, path,
-                                 VIR_CGROUP_DEVICE_RWM) < 0)
+                                 VIR_CGROUP_DEVICE_RWM, false) < 0)
         return -1;

     return 0;
@@ -347,7 +347,7 @@ virLXCTeardownHostUSBDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,

     VIR_DEBUG("Process path '%s' for USB device", path);
     if (virCgroupDenyDevicePath(cgroup, path,
-                                VIR_CGROUP_DEVICE_RWM) < 0)
+                                VIR_CGROUP_DEVICE_RWM, false) < 0)
         return -1;

     return 0;
@@ -401,7 +401,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
                                      (def->disks[i]->src->readonly ?
                                       VIR_CGROUP_DEVICE_READ :
                                       VIR_CGROUP_DEVICE_RW) |
-                                     VIR_CGROUP_DEVICE_MKNOD) < 0)
+                                     VIR_CGROUP_DEVICE_MKNOD, false) < 0)
             goto cleanup;
     }

@@ -414,7 +414,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
                                      def->fss[i]->src,
                                      def->fss[i]->readonly ?
                                      VIR_CGROUP_DEVICE_READ :
-                                     VIR_CGROUP_DEVICE_RW) < 0)
+                                     VIR_CGROUP_DEVICE_RW, false) < 0)
             goto cleanup;
     }

@@ -448,14 +448,14 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
                 if (virCgroupAllowDevicePath(cgroup,
                                              hostdev->source.caps.u.storage.block,
                                              VIR_CGROUP_DEVICE_RW |
-                                             VIR_CGROUP_DEVICE_MKNOD) < 0)
+                                             VIR_CGROUP_DEVICE_MKNOD, false) < 0)
                     goto cleanup;
                 break;
             case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
                 if (virCgroupAllowDevicePath(cgroup,
                                              hostdev->source.caps.u.misc.chardev,
                                              VIR_CGROUP_DEVICE_RW |
-                                             VIR_CGROUP_DEVICE_MKNOD) < 0)
+                                             VIR_CGROUP_DEVICE_MKNOD, false) < 0)
                     goto cleanup;
                 break;
             default:
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 41639ac..3c6c839 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -4646,7 +4646,8 @@ lxcDomainDetachDeviceDiskLive(virDomainObjPtr vm,
     }
     virDomainAuditDisk(vm, def->src, NULL, "detach", true);

-    if (virCgroupDenyDevicePath(priv->cgroup, src, VIR_CGROUP_DEVICE_RWM) != 0)
+    if (virCgroupDenyDevicePath(priv->cgroup, src,
+                                VIR_CGROUP_DEVICE_RWM, false) != 0)
         VIR_WARN("cannot deny device %s for domain %s",
                  src, vm->def->name);

@@ -4822,7 +4823,8 @@ lxcDomainDetachDeviceHostdevStorageLive(virDomainObjPtr vm,
     }
     virDomainAuditHostdev(vm, def, "detach", true);

-    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.storage.block, VIR_CGROUP_DEVICE_RWM) != 0)
+    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.storage.block,
+                                VIR_CGROUP_DEVICE_RWM, false) != 0)
         VIR_WARN("cannot deny device %s for domain %s",
                  def->source.caps.u.storage.block, vm->def->name);

@@ -4871,7 +4873,8 @@ lxcDomainDetachDeviceHostdevMiscLive(virDomainObjPtr vm,
     }
     virDomainAuditHostdev(vm, def, "detach", true);

-    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.misc.chardev, VIR_CGROUP_DEVICE_RWM) != 0)
+    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.misc.chardev,
+                                VIR_CGROUP_DEVICE_RWM, false) != 0)
         VIR_WARN("cannot deny device %s for domain %s",
                  def->source.caps.u.misc.chardev, vm->def->name);

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 5a4cd55..2c0ac30 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -77,7 +77,7 @@ qemuSetImageCgroupInternal(virDomainObjPtr vm,

         VIR_DEBUG("Deny path %s", src->path);

-        ret = virCgroupDenyDevicePath(priv->cgroup, src->path, perms);
+        ret = virCgroupDenyDevicePath(priv->cgroup, src->path, perms, false);
     } else {
         if (!src->readonly && !forceReadonly)
             perms |= VIR_CGROUP_DEVICE_WRITE;
@@ -85,7 +85,7 @@ qemuSetImageCgroupInternal(virDomainObjPtr vm,
         VIR_DEBUG("Allow path %s, perms: %s",
                   src->path, virCgroupGetDevicePermsString(perms));

-        ret = virCgroupAllowDevicePath(priv->cgroup, src->path, perms);
+        ret = virCgroupAllowDevicePath(priv->cgroup, src->path, perms, false);
     }

     virDomainAuditCgroupPath(vm, priv->cgroup,
@@ -162,7 +162,7 @@ qemuSetupChrSourceCgroup(virDomainObjPtr vm,
     VIR_DEBUG("Process path '%s' for device", source->data.file.path);

     ret = virCgroupAllowDevicePath(priv->cgroup, source->data.file.path,
-                                   VIR_CGROUP_DEVICE_RW);
+                                   VIR_CGROUP_DEVICE_RW, false);
     virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
                              source->data.file.path, "rw", ret == 0);

@@ -209,7 +209,7 @@ qemuSetupInputCgroup(virDomainObjPtr vm,
     case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
         VIR_DEBUG("Process path '%s' for input device", dev->source.evdev);
         ret = virCgroupAllowDevicePath(priv->cgroup, dev->source.evdev,
-                                       VIR_CGROUP_DEVICE_RW);
+                                       VIR_CGROUP_DEVICE_RW, false);
         virDomainAuditCgroupPath(vm, priv->cgroup, "allow", dev->source.evdev, "rw", ret == 0);
         break;
     }
@@ -229,7 +229,7 @@ qemuSetupHostUSBDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,

     VIR_DEBUG("Process path '%s' for USB device", path);
     ret = virCgroupAllowDevicePath(priv->cgroup, path,
-                                   VIR_CGROUP_DEVICE_RW);
+                                   VIR_CGROUP_DEVICE_RW, false);
     virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", ret == 0);

     return ret;
@@ -249,7 +249,7 @@ qemuSetupHostSCSIDeviceCgroup(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
     ret = virCgroupAllowDevicePath(priv->cgroup, path,
                                    virSCSIDeviceGetReadonly(dev) ?
                                    VIR_CGROUP_DEVICE_READ :
-                                   VIR_CGROUP_DEVICE_RW);
+                                   VIR_CGROUP_DEVICE_RW, false);

     virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
                              virSCSIDeviceGetReadonly(dev) ? "r" : "rw", ret == 0);
@@ -298,7 +298,7 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,

                 VIR_DEBUG("Cgroup allow %s for PCI device assignment", path);
                 rv = virCgroupAllowDevicePath(priv->cgroup, path,
-                                              VIR_CGROUP_DEVICE_RW);
+                                              VIR_CGROUP_DEVICE_RW, false);
                 virDomainAuditCgroupPath(vm, priv->cgroup,
                                          "allow", path, "rw", rv == 0);
                 if (rv < 0)
@@ -407,7 +407,7 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,

                 VIR_DEBUG("Cgroup deny %s for PCI device assignment", path);
                 rv = virCgroupDenyDevicePath(priv->cgroup, path,
-                                             VIR_CGROUP_DEVICE_RWM);
+                                             VIR_CGROUP_DEVICE_RWM, false);
                 virDomainAuditCgroupPath(vm, priv->cgroup,
                                          "deny", path, "rwm", rv == 0);
                 if (rv < 0)
@@ -591,7 +591,7 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
         }

         rv = virCgroupAllowDevicePath(priv->cgroup, deviceACL[i],
-                                      VIR_CGROUP_DEVICE_RW);
+                                      VIR_CGROUP_DEVICE_RW, false);
         virDomainAuditCgroupPath(vm, priv->cgroup, "allow", deviceACL[i], "rw", rv == 0);
         if (rv < 0 &&
             !virLastErrorIsSystemErrno(ENOENT))
@@ -622,7 +622,7 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
             VIR_DEBUG("Setting Cgroup ACL for RNG device");
             rv = virCgroupAllowDevicePath(priv->cgroup,
                                           vm->def->rngs[i]->source.file,
-                                          VIR_CGROUP_DEVICE_RW);
+                                          VIR_CGROUP_DEVICE_RW, false);
             virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
                                      vm->def->rngs[i]->source.file,
                                      "rw", rv == 0);
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index a35bac7..d032c60 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -2986,19 +2986,26 @@ virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor,
  * @group: The cgroup to allow the device for
  * @path: the device to allow
  * @perms: Bitwise or of VIR_CGROUP_DEVICE permission bits to allow
+ * @ignoreEacces: Ignore lack of permission (mostly for NFS mounts)
  *
  * Queries the type of device and its major/minor number, and
  * adds that to the cgroup ACL
  *
- * Returns: 0 on success, 1 if path exists but is not a device, or
- * -1 on error
+ * Returns: 0 on success, 1 if path exists but is not a device or is not
+ * accesible, or * -1 on error
  */
 int
-virCgroupAllowDevicePath(virCgroupPtr group, const char *path, int perms)
+virCgroupAllowDevicePath(virCgroupPtr group,
+                         const char *path,
+                         int perms,
+                         bool ignoreEacces)
 {
     struct stat sb;

     if (stat(path, &sb) < 0) {
+        if (errno == EACCES && ignoreEacces)
+            return 1;
+
         virReportSystemError(errno,
                              _("Path '%s' is not accessible"),
                              path);
@@ -3064,12 +3071,32 @@ virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor,
 }


+/**
+ * virCgroupDenyDevicePath:
+ *
+ * @group: The cgroup to deny the device for
+ * @path: the device to deny
+ * @perms: Bitwise or of VIR_CGROUP_DEVICE permission bits to allow
+ * @ignoreEacces: Ignore lack of permission (mostly for NFS mounts)
+ *
+ * Queries the type of device and its major/minor number, and
+ * removes it from the cgroup ACL
+ *
+ * Returns: 0 on success, 1 if path exists but is not a device or is not
+ * accessible, or -1 on error.
+ */
 int
-virCgroupDenyDevicePath(virCgroupPtr group, const char *path, int perms)
+virCgroupDenyDevicePath(virCgroupPtr group,
+                        const char *path,
+                        int perms,
+                        bool ignoreEacces)
 {
     struct stat sb;

     if (stat(path, &sb) < 0) {
+        if (errno == EACCES && ignoreEacces)
+            return 1;
+
         virReportSystemError(errno,
                              _("Path '%s' is not accessible"),
                              path);
@@ -4637,7 +4664,8 @@ virCgroupAllowDevice(virCgroupPtr group ATTRIBUTE_UNUSED,
 int
 virCgroupAllowDevicePath(virCgroupPtr group ATTRIBUTE_UNUSED,
                          const char *path ATTRIBUTE_UNUSED,
-                         int perms ATTRIBUTE_UNUSED)
+                         int perms ATTRIBUTE_UNUSED,
+                         bool ignoreEaccess ATTRIBUTE_UNUSED)
 {
     virReportSystemError(ENOSYS, "%s",
                          _("Control groups not supported on this platform"));
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index 0f687a5..7914cbb 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -222,7 +222,8 @@ int virCgroupAllowDevice(virCgroupPtr group,
                          int perms);
 int virCgroupAllowDevicePath(virCgroupPtr group,
                              const char *path,
-                             int perms);
+                             int perms,
+                             bool ignoreEacces);

 int virCgroupDenyDevice(virCgroupPtr group,
                         char type,
@@ -231,7 +232,8 @@ int virCgroupDenyDevice(virCgroupPtr group,
                         int perms);
 int virCgroupDenyDevicePath(virCgroupPtr group,
                             const char *path,
-                            int perms);
+                            int perms,
+                            bool ignoreEacces);

 int
 virCgroupGetPercpuStats(virCgroupPtr group,
-- 
2.6.2




More information about the libvir-list mailing list