]> 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)
committerJiri Denemark <jdenemar@redhat.com>
Mon, 30 Apr 2012 06:17:40 +0000 (08:17 +0200)
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.

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

index 025816ab1ba44286fc52fd874861c9c3f41e79ca..d4038b21f2ae387ff430d2a16d50b5233a15617a 100644 (file)
@@ -1209,6 +1209,7 @@ virFileFclose;
 virFileFdopen;
 virFileRewrite;
 virFileTouch;
+virFileUpdatePerm;
 
 
 # virkeycode.h
index 349274b2518b4839ea4ed50d4c62fc03003e8998..78899a4734ebeb889a519ffea22dc0401c903699 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 */