[systemd-devel] [PATCH 1/7] nspawn, shared: Factor out sending and receiving fd

Krzesimir Nowak krzesimir at endocode.com
Mon Jun 1 08:28:57 PDT 2015


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



More information about the systemd-devel mailing list