]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Make sure qemu can access its directory in hugetlbfs
authorJiri Denemark <jdenemar@redhat.com>
Fri, 27 Apr 2012 13:50:22 +0000 (15:50 +0200)
committerCole Robinson <crobinso@redhat.com>
Thu, 7 Jun 2012 22:04:38 +0000 (18:04 -0400)
When libvirtd is started, we create "libvirt/qemu" directories under
hugetlbfs mount point. Only the "qemu" subdirectory is chowned to qemu
user and "libvirt" remains owned by root. If umask was too restrictive
when libvirtd started, qemu user may lose access to "qemu"
subdirectory. Let's explicitly grant search permissions to "libvirt"
directory for all users.
(cherry picked from commit 9d2ac5453e4d50c6f12b2f8a5078691fec60020b)

src/libvirt_private.syms
src/qemu/qemu_driver.c
src/util/virfile.c
src/util/virfile.h

index 8d29e75842837690acbd6d37268cb90ac7b98207..0ab3ae8f70622fdc8ee0d50c3fbe1cfd91d7a150 100644 (file)
@@ -1204,6 +1204,7 @@ virFileFclose;
 virFileFdopen;
 virFileRewrite;
 virFileTouch;
+virFileUpdatePerm;
 
 
 # virkeycode.h
index 5e686c3503e3457e51f12b4a52750570b00bce20..38aada6667a0d1cc1f1d6b434e5058a9d4ffe2b8 100644 (file)
@@ -456,6 +456,8 @@ qemudStartup(int privileged) {
     int rc;
     virConnectPtr conn = NULL;
     char ebuf[1024];
+    char *membase = NULL;
+    char *mempath = NULL;
 
     if (VIR_ALLOC(qemu_driver) < 0)
         return -1;
@@ -660,23 +662,26 @@ qemudStartup(int privileged) {
      */
     if (qemu_driver->hugetlbfs_mount &&
         qemu_driver->hugetlbfs_mount[0] == '/') {
-        char *mempath = NULL;
-        if (virAsprintf(&mempath, "%s/libvirt/qemu", qemu_driver->hugetlbfs_mount) < 0)
+        if (virAsprintf(&membase, "%s/libvirt",
+                        qemu_driver->hugetlbfs_mount) < 0 ||
+            virAsprintf(&mempath, "%s/qemu", membase) < 0)
             goto out_of_memory;
 
         if (virFileMakePath(mempath) < 0) {
             virReportSystemError(errno,
                                  _("unable to create hugepage path %s"), mempath);
-            VIR_FREE(mempath);
             goto error;
         }
-        if (qemu_driver->privileged &&
-            chown(mempath, qemu_driver->user, qemu_driver->group) < 0) {
-            virReportSystemError(errno,
-                                 _("unable to set ownership on %s to %d:%d"),
-                                 mempath, qemu_driver->user, qemu_driver->group);
-            VIR_FREE(mempath);
-            goto error;
+        if (qemu_driver->privileged) {
+            if (virFileUpdatePerm(membase, 0, S_IXGRP | S_IXOTH) < 0)
+                goto error;
+            if (chown(mempath, qemu_driver->user, qemu_driver->group) < 0) {
+                virReportSystemError(errno,
+                                     _("unable to set ownership on %s to %d:%d"),
+                                     mempath, qemu_driver->user,
+                                     qemu_driver->group);
+                goto error;
+            }
         }
 
         qemu_driver->hugepage_path = mempath;
@@ -737,6 +742,8 @@ error:
         virConnectClose(conn);
     VIR_FREE(base);
     VIR_FREE(driverConf);
+    VIR_FREE(membase);
+    VIR_FREE(mempath);
     qemudShutdown();
     return -1;
 }
index 66160dc9026f41881131e2a476d7fa8f41554db7..db3d737d96d9b604ba696cac1c8e1cf49ee2e4ca 100644 (file)
@@ -437,3 +437,40 @@ int virFileTouch(const char *path, mode_t mode)
 
     return 0;
 }
+
+
+#define MODE_BITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+
+int virFileUpdatePerm(const char *path,
+                      mode_t mode_remove,
+                      mode_t mode_add)
+{
+    struct stat sb;
+    mode_t mode;
+
+    if (mode_remove & ~MODE_BITS || mode_add & ~MODE_BITS) {
+        virFileError(VIR_ERR_INVALID_ARG, "%s", _("invalid mode"));
+        return -1;
+    }
+
+    if (stat(path, &sb) < 0) {
+        virReportSystemError(errno, _("cannot stat '%s'"), path);
+        return -1;
+    }
+
+    mode = sb.st_mode & MODE_BITS;
+
+    if ((mode & mode_remove) == 0 && (mode & mode_add) == mode_add)
+        return 0;
+
+    mode &= MODE_BITS ^ mode_remove;
+    mode |= mode_add;
+
+    if (chmod(path, mode) < 0) {
+        virReportSystemError(errno, _("cannot change permission of '%s'"),
+                             path);
+        return -1;
+    }
+
+    return 0;
+}
index 184677c5974eb5ea02e266d9501d4cc5efa6eefa..05f50480e6ef7450f6498e9ecdaf1e7aecb149a5 100644 (file)
@@ -83,4 +83,8 @@ int virFileRewrite(const char *path,
 
 int virFileTouch(const char *path, mode_t mode);
 
+int virFileUpdatePerm(const char *path,
+                      mode_t mode_remove,
+                      mode_t mode_add);
+
 #endif /* __VIR_FILES_H */