[libvirt] [PATCHv2] build: use gnulib passfd for simpler SCM_RIGHTS code

Laine Stump laine at laine.org
Mon Apr 25 07:17:40 UTC 2011


On 04/21/2011 05:17 PM, Eric Blake wrote:
> * .gnulib: Update to latest for passfd fixes.
> * bootstrap.conf (gnulib_modules): Add passfd.
> * src/util/util.c (virFileOpenAs): Simplify.
> ---
>
> Now that the mingw side of passfd is fixed in gnulib, I can
> resubmit this patch.
>
> v2: update .gnulib, no other changes
>
>   .gnulib         |    2 +-
>   bootstrap.conf  |    1 +
>   src/util/util.c |   38 ++++++++------------------------------
>   3 files changed, 10 insertions(+), 31 deletions(-)
>
> diff --git a/.gnulib b/.gnulib
> index fb79969..5a9e46a 160000
> --- a/.gnulib
> +++ b/.gnulib
> @@ -1 +1 @@
> -Subproject commit fb799692f5bb43310424977e0ca15599fc68d776
> +Subproject commit 5a9e46ab46042f007426c1e06b836cf5608d8d4a
> diff --git a/bootstrap.conf b/bootstrap.conf
> index 293f86e..3b3a90f 100644
> --- a/bootstrap.conf
> +++ b/bootstrap.conf
> @@ -52,6 +52,7 @@ mkstemps
>   mktempd
>   netdb
>   nonblocking
> +passfd
>   perror
>   physmem
>   pipe-posix
> diff --git a/src/util/util.c b/src/util/util.c
> index d4d2610..de4e3b3 100644
> --- a/src/util/util.c
> +++ b/src/util/util.c
> @@ -78,6 +78,7 @@
>   #include "files.h"
>   #include "command.h"
>   #include "nonblocking.h"
> +#include "passfd.h"
>
>   #ifndef NSIG
>   # define NSIG 32
> @@ -1480,11 +1481,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
>       int waitret, status, ret = 0;
>       int fd = -1;
>       int pair[2] = { -1, -1 };
> -    struct msghdr msg;
> -    struct cmsghdr *cmsg;
> -    char buf[CMSG_SPACE(sizeof(fd))];
> -    char dummy = 0;
> -    struct iovec iov;
>       int forkRet;
>
>       if ((!(flags&  VIR_FILE_OPEN_AS_UID))
> @@ -1506,18 +1502,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
>           return ret;
>       }
>
> -    memset(&msg, 0, sizeof(msg));
> -    iov.iov_base =&dummy;
> -    iov.iov_len = 1;
> -    msg.msg_iov =&iov;
> -    msg.msg_iovlen = 1;
> -    msg.msg_control = buf;
> -    msg.msg_controllen = sizeof(buf);
> -    cmsg = CMSG_FIRSTHDR(&msg);
> -    cmsg->cmsg_level = SOL_SOCKET;
> -    cmsg->cmsg_type = SCM_RIGHTS;
> -    cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
> -
>       forkRet = virFork(&pid);
>
>       if (pid<  0) {
> @@ -1529,26 +1513,20 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
>           VIR_FORCE_CLOSE(pair[1]);
>
>           do {
> -            ret = recvmsg(pair[0],&msg, 0);
> +            ret = recvfd(pair[0], 0);
>           } while (ret<  0&&  errno == EINTR);
>
> -        if (ret<  0) {
> +        if (ret<  0&&  errno != EACCES) {
>               ret = -errno;
>               VIR_FORCE_CLOSE(pair[0]);
>               while ((waitret = waitpid(pid, NULL, 0) == -1)
>                      &&  (errno == EINTR));
>               goto parenterror;
> +        } else {
> +            fd = ret;
>           }

What if errno == EACCES? Will we be getting all the error recovery we 
need in the caller?


>           VIR_FORCE_CLOSE(pair[0]);
>
> -        /* See if fd was transferred.  */
> -        cmsg = CMSG_FIRSTHDR(&msg);
> -        if (cmsg&&  cmsg->cmsg_len == CMSG_LEN(sizeof(fd))&&
> -            cmsg->cmsg_level == SOL_SOCKET&&
> -            cmsg->cmsg_type == SCM_RIGHTS) {
> -            memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
> -        }
> -
>           /* wait for child to complete, and retrieve its exit code */
>           while ((waitret = waitpid(pid,&status, 0) == -1)
>                  &&  (errno == EINTR));
> @@ -1557,12 +1535,14 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
>               virReportSystemError(errno,
>                                    _("failed to wait for child creating '%s'"),
>                                    path);
> +            VIR_FORCE_CLOSE(fd);
>               goto parenterror;
>           }
>           if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
>               fd == -1) {
>               /* fall back to the simpler method, which works better in
>                * some cases */
> +            VIR_FORCE_CLOSE(fd);
>               return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
>           }
>           if (!ret)
> @@ -1627,10 +1607,9 @@ parenterror:
>                                path, mode);
>           goto childerror;
>       }
> -    memcpy(CMSG_DATA(cmsg),&fd, sizeof(fd));
>
>       do {
> -        ret = sendmsg(pair[1],&msg, 0);
> +        ret = sendfd(pair[1], fd);
>       } while (ret<  0&&  errno == EINTR);
>
>       if (ret<  0) {
> @@ -1638,7 +1617,6 @@ parenterror:
>           goto childerror;
>       }
>
> -    ret = 0;
>   childerror:
>       /* ret tracks -errno on failure, but exit value must be positive.
>        * If the child exits with EACCES, then the parent tries again.  */




More information about the libvir-list mailing list