From 30e02e12c123496f1d1461957eef120070f23ca5 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Fri, 27 Apr 2012 15:50:22 +0200 Subject: [PATCH] qemu: Make sure qemu can access its directory in hugetlbfs 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 | 1 + src/qemu/qemu_driver.c | 27 +++++++++++++++++---------- src/util/virfile.c | 37 +++++++++++++++++++++++++++++++++++++ src/util/virfile.h | 4 ++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8d29e75842..0ab3ae8f70 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1204,6 +1204,7 @@ virFileFclose; virFileFdopen; virFileRewrite; virFileTouch; +virFileUpdatePerm; # virkeycode.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5e686c3503..38aada6667 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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; } diff --git a/src/util/virfile.c b/src/util/virfile.c index 66160dc902..db3d737d96 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -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; +} diff --git a/src/util/virfile.h b/src/util/virfile.h index 184677c597..05f50480e6 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -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 */ -- GitLab