On Wed, Mar 09, 2011 at 06:45:45PM -0700, Eric Blake wrote:
Currently, the hook function in virFileOperation is extremely
limited:
it must be async-signal-safe, and cannot modify any memory in the
parent process. It is much handier to return a valid fd and operate
on it in the parent than to deal with hook restrictions.
* src/util/util.h (VIR_FILE_OP_RETURN_FD): New flag.
* src/util/util.c (virFileOperationNoFork, virFileOperation):
Honor new flag.
---
src/util/util.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++------
src/util/util.h | 4 +-
2 files changed, 126 insertions(+), 17 deletions(-)
ACK,
+ 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));
+ }
....
+ if (flags & VIR_FILE_OP_RETURN_FD) {
+ VIR_FORCE_CLOSE(pair[1]);
+
+ do {
+ ret = recvmsg(pair[0], &msg, 0);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ ret = -errno;
+ VIR_FORCE_CLOSE(pair[0]);
+ while ((waitret = waitpid(pid, NULL, 0) == -1)
+ && (errno == EINTR));
+ goto parenterror;
+ }
+ 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));
+ }
Also might be nice to create two helper methods for this
int virFileHandleSendToSocket(int unixfd, int sendfd);
int virFileHandleRecvFromSocket(int unixfd);
which we can also use in the monitor code that does the
same thing
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|