Right now it can be used to sent rtnl and kmsg descriptors. These functions will be used later to send journal directory descriptor in machined. --- src/nspawn/nspawn.c | 66 +++++++---------------------------------------------- src/shared/util.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ src/shared/util.h | 3 +++ 3 files changed, 67 insertions(+), 58 deletions(-)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4211a3d..bd7532c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1839,15 +1839,6 @@ static int setup_kmsg(const char *dest, int kmsg_socket) { const char *from, *to; _cleanup_umask_ mode_t u; int fd, k; - union { - struct cmsghdr cmsghdr; - uint8_t buf[CMSG_SPACE(sizeof(int))]; - } control = {}; - struct msghdr mh = { - .msg_control = &control, - .msg_controllen = sizeof(control), - }; - struct cmsghdr *cmsg; assert(kmsg_socket >= 0); @@ -1872,17 +1863,9 @@ static int setup_kmsg(const char *dest, int kmsg_socket) { if (fd < 0) return log_error_errno(errno, "Failed to open fifo: %m"); - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - mh.msg_controllen = cmsg->cmsg_len; - /* Store away the fd in the socket, so that it stays open as * long as we run the child */ - k = sendmsg(kmsg_socket, &mh, MSG_NOSIGNAL); + k = send_fd(kmsg_socket, fd); safe_close(fd); if (k < 0) @@ -1894,20 +1877,11 @@ static int setup_kmsg(const char *dest, int kmsg_socket) { return 0; } -static int send_rtnl(int send_fd) { - union { - struct cmsghdr cmsghdr; - uint8_t buf[CMSG_SPACE(sizeof(int))]; - } control = {}; - struct msghdr mh = { - .msg_control = &control, - .msg_controllen = sizeof(control), - }; - struct cmsghdr *cmsg; +static int send_rtnl(int sender_fd) { _cleanup_close_ int fd = -1; - ssize_t k; + int r; - assert(send_fd >= 0); + assert(sender_fd >= 0); if (!arg_expose_ports) return 0; @@ -1916,18 +1890,10 @@ static int send_rtnl(int send_fd) { if (fd < 0) return log_error_errno(errno, "Failed to allocate container netlink: %m"); - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - mh.msg_controllen = cmsg->cmsg_len; - /* Store away the fd in the socket, so that it stays open as * long as we run the child */ - k = sendmsg(send_fd, &mh, MSG_NOSIGNAL); - if (k < 0) + r = send_fd(sender_fd, fd); + if (r < 0) return log_error_errno(errno, "Failed to send netlink fd: %m"); return 0; @@ -2032,18 +1998,8 @@ static int on_address_change(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) } static int watch_rtnl(sd_event *event, int recv_fd, union in_addr_union *exposed, sd_rtnl **ret) { - union { - struct cmsghdr cmsghdr; - uint8_t buf[CMSG_SPACE(sizeof(int))]; - } control = {}; - struct msghdr mh = { - .msg_control = &control, - .msg_controllen = sizeof(control), - }; - struct cmsghdr *cmsg; _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; int fd, r; - ssize_t k; assert(event); assert(recv_fd >= 0); @@ -2052,16 +2008,10 @@ static int watch_rtnl(sd_event *event, int recv_fd, union in_addr_union *exposed if (!arg_expose_ports) return 0; - k = recvmsg(recv_fd, &mh, MSG_NOSIGNAL); - if (k < 0) + r = receive_fd(recv_fd, &fd); + if (r < 0) return log_error_errno(errno, "Failed to recv netlink fd: %m"); - cmsg = CMSG_FIRSTHDR(&mh); - assert(cmsg->cmsg_level == SOL_SOCKET); - assert(cmsg->cmsg_type == SCM_RIGHTS); - assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int))); - memcpy(&fd, CMSG_DATA(cmsg), sizeof(int)); - r = sd_rtnl_open_fd(&rtnl, fd, 1, RTNLGRP_IPV4_IFADDR); if (r < 0) { safe_close(fd); diff --git a/src/shared/util.c b/src/shared/util.c index 8a61079..395af7c 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6046,3 +6046,59 @@ int reset_uid_gid(void) { return 0; } + +int send_fd(int sender_fd, int fd) { + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; + } control = {}; + struct msghdr mh = { + .msg_control = &control, + .msg_controllen = sizeof(control), + }; + struct cmsghdr *cmsg; + ssize_t k; + + assert(sender_fd >= 0); + + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); + + mh.msg_controllen = cmsg->cmsg_len; + k = sendmsg(sender_fd, &mh, MSG_NOSIGNAL); + + if (k < 0) + return -1; + return 0; +} + +int receive_fd(int recv_fd, int *fd) { + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; + } control = {}; + struct msghdr mh = { + .msg_control = &control, + .msg_controllen = sizeof(control), + }; + struct cmsghdr *cmsg; + ssize_t k; + + assert(recv_fd >= 0); + assert(fd != NULL); + + k = recvmsg(recv_fd, &mh, MSG_NOSIGNAL); + if (k < 0) + return -1; + + cmsg = CMSG_FIRSTHDR(&mh); + assert(cmsg->cmsg_level == SOL_SOCKET); + assert(cmsg->cmsg_type == SCM_RIGHTS); + assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int))); + memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); + + return 0; +} diff --git a/src/shared/util.h b/src/shared/util.h index 467ae23..1cfb45f 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -901,3 +901,6 @@ int parse_mode(const char *s, mode_t *ret); int mount_move_root(const char *path); int reset_uid_gid(void); + +int send_fd(int sender_fd, int fd); +int receive_fd(int recv_fd, int *fd); -- 2.1.0 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel