]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: cgroup: Allow ignoring EACCES in virCgroup(Allow|Deny)DevicePath
authorPeter Krempa <pkrempa@redhat.com>
Tue, 16 Feb 2016 13:43:41 +0000 (14:43 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 17 Feb 2016 09:54:05 +0000 (10:54 +0100)
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
src/lxc/lxc_driver.c
src/qemu/qemu_cgroup.c
src/util/vircgroup.c
src/util/vircgroup.h

index 60805af992b58675e84d7097863e94fa8561b03a..4afe7e229eeb5329c8e1cf7b1ca97cb0c183ee9e 100644 (file)
@@ -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:
index 41639acd52629bf9136f9ec73d24fb5e2fc95b82..3c6c839dd376098da79fa8570415f9cda430d21a 100644 (file)
@@ -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);
 
index 5a4cd555ddf363826b823c2ada6981eea8b98c10..2c0ac306116906b61a9f10675419424bb756c466 100644 (file)
@@ -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);
index a35bac73e103f450436e0f6cb74917f8df9a94b3..d032c604e39434fd538c1b732e5fb913e3594187 100644 (file)
@@ -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"));
index 0f687a5c43c92875173692a4569a1e0b704d6bbd..7914cbbdaa7a3c9a01f45625601066e9292fbb87 100644 (file)
@@ -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,