mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 19:45:21 +00:00
build: use gnulib passfd for simpler SCM_RIGHTS code
* .gnulib: Update to latest for passfd fixes. * bootstrap.conf (gnulib_modules): Add passfd. * src/util/util.c (virFileOpenAs): Simplify.
This commit is contained in:
parent
1c84237852
commit
59a5981dd3
2
.gnulib
2
.gnulib
@ -1 +1 @@
|
|||||||
Subproject commit fb799692f5bb43310424977e0ca15599fc68d776
|
Subproject commit 7d06b32684363a39fae65c616b84bc7589768106
|
@ -52,6 +52,7 @@ mkstemps
|
|||||||
mktempd
|
mktempd
|
||||||
netdb
|
netdb
|
||||||
nonblocking
|
nonblocking
|
||||||
|
passfd
|
||||||
perror
|
perror
|
||||||
physmem
|
physmem
|
||||||
pipe-posix
|
pipe-posix
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "nonblocking.h"
|
#include "nonblocking.h"
|
||||||
|
#include "passfd.h"
|
||||||
|
|
||||||
#ifndef NSIG
|
#ifndef NSIG
|
||||||
# define NSIG 32
|
# define NSIG 32
|
||||||
@ -1480,11 +1481,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
|
|||||||
int waitret, status, ret = 0;
|
int waitret, status, ret = 0;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int pair[2] = { -1, -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;
|
int forkRet;
|
||||||
|
|
||||||
if ((!(flags & VIR_FILE_OPEN_AS_UID))
|
if ((!(flags & VIR_FILE_OPEN_AS_UID))
|
||||||
@ -1506,18 +1502,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
|
|||||||
return ret;
|
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);
|
forkRet = virFork(&pid);
|
||||||
|
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
@ -1529,26 +1513,20 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
|
|||||||
VIR_FORCE_CLOSE(pair[1]);
|
VIR_FORCE_CLOSE(pair[1]);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = recvmsg(pair[0], &msg, 0);
|
ret = recvfd(pair[0], 0);
|
||||||
} while (ret < 0 && errno == EINTR);
|
} while (ret < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0 && errno != EACCES) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
VIR_FORCE_CLOSE(pair[0]);
|
VIR_FORCE_CLOSE(pair[0]);
|
||||||
while ((waitret = waitpid(pid, NULL, 0) == -1)
|
while ((waitret = waitpid(pid, NULL, 0) == -1)
|
||||||
&& (errno == EINTR));
|
&& (errno == EINTR));
|
||||||
goto parenterror;
|
goto parenterror;
|
||||||
|
} else {
|
||||||
|
fd = ret;
|
||||||
}
|
}
|
||||||
VIR_FORCE_CLOSE(pair[0]);
|
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 */
|
/* wait for child to complete, and retrieve its exit code */
|
||||||
while ((waitret = waitpid(pid, &status, 0) == -1)
|
while ((waitret = waitpid(pid, &status, 0) == -1)
|
||||||
&& (errno == EINTR));
|
&& (errno == EINTR));
|
||||||
@ -1557,12 +1535,14 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
|
|||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("failed to wait for child creating '%s'"),
|
_("failed to wait for child creating '%s'"),
|
||||||
path);
|
path);
|
||||||
|
VIR_FORCE_CLOSE(fd);
|
||||||
goto parenterror;
|
goto parenterror;
|
||||||
}
|
}
|
||||||
if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
|
if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
|
||||||
fd == -1) {
|
fd == -1) {
|
||||||
/* fall back to the simpler method, which works better in
|
/* fall back to the simpler method, which works better in
|
||||||
* some cases */
|
* some cases */
|
||||||
|
VIR_FORCE_CLOSE(fd);
|
||||||
return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
|
return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
|
||||||
}
|
}
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -1627,10 +1607,9 @@ parenterror:
|
|||||||
path, mode);
|
path, mode);
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = sendmsg(pair[1], &msg, 0);
|
ret = sendfd(pair[1], fd);
|
||||||
} while (ret < 0 && errno == EINTR);
|
} while (ret < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1638,7 +1617,6 @@ parenterror:
|
|||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
childerror:
|
childerror:
|
||||||
/* ret tracks -errno on failure, but exit value must be positive.
|
/* ret tracks -errno on failure, but exit value must be positive.
|
||||||
* If the child exits with EACCES, then the parent tries again. */
|
* If the child exits with EACCES, then the parent tries again. */
|
||||||
|
Loading…
Reference in New Issue
Block a user