[libvirt] [PATCH] qemu: Make sure qemu can access its directory in hugetlbfs

Osier Yang jyang at redhat.com
Sat Apr 28 07:27:12 UTC 2012


On 2012年04月27日 22:45, Jiri Denemark wrote:
> 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/qemu/qemu_driver.c |   27 +++++++++++++++++----------
>   src/util/virfile.c     |   37 +++++++++++++++++++++++++++++++++++++
>   src/util/virfile.h     |    4 ++++
>   3 files changed, 58 insertions(+), 10 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index ce31e09..29bab3c 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 66160dc..db3d737 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 184677c..05f5048 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 */

src/libvirt_private.syms is not updated. Others look pretty clean for
me, ACK with the symbol added.

Regards,
Osier




More information about the libvir-list mailing list