net: rock: Keep the ctl FD open (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 15 Dec 2017 20:08:10 +0000 (15:08 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 15 Dec 2017 20:08:10 +0000 (15:08 -0500)
Instead of reopening the ctl FD every time we want to use it, we can just
keep it open.

Notionally, all of the Rock's FDs (data, ctl, and listen) are part of the
same object.  The only downside is we have more open FDs, chans, and convs.

The motivator for this is fcntl operations on sockets - the application's
intent is to affect all of the FDs of the Rock, not just the data FD.

Note that you'll see more files in 'pip', and that the name of Qctl files
is usually 'listen' or clone.  For example, conversation 2's ctl file was
created by opening 1/listen:

FD: 08,  pathname: /net/tcp/1/listen
Dev: ip, Devinfo: Qctl, proto tcp, conv idx 2

The lesson is that the pathname is what was opened, not what the file is.
You need to look at the rest of the info for that.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept4.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/connect.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/shutdown.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/plan9_helpers.h

index 87ab301..67a57de 100644 (file)
@@ -70,10 +70,7 @@ int __libc_accept4(int fd, __SOCKADDR_ARG addr, socklen_t *alen, int a4_flags)
                                return -1;
                        /* at this point, we have a new conversation, and lcfd is its ctl
                         * fd.  nfd will be the FD for that conv's data file.  sock_data
-                        * will trade our lcfd for the data file fd.  even if it fails,
-                        * sock_data will close our lcfd for us.  when it succeeds, it'll
-                        * open the data file before closing lcfd, which will keep the
-                        * converstation alive.
+                        * will store our lcfd in the rock and return the data file fd.
                         *
                         * Note, we pass the listen socket's stype, but not it's sopts.  The
                         * sopts (e.g. SOCK_NONBLOCK) apply to the original socket, not to
index a642248..0170493 100644 (file)
@@ -28,7 +28,7 @@
 /* Give the socket FD the local address ADDR (which is LEN bytes long).  */
 int __bind(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
 {
-       int n, cfd;
+       int n;
        socklen_t len;
        Rock *r;
        char msg[128];
@@ -50,20 +50,14 @@ int __bind(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
        if (r->domain != PF_INET)
                return 0;
 
-       cfd = _sock_open_ctlfd(r);
-       if (cfd < 0) {
-               errno = EBADF;
-               return -1;
-       }
        lip = (struct sockaddr_in *)&r->addr;
        if (lip->sin_port > 0)
                snprintf(msg, sizeof msg, "bind %d", ntohs(lip->sin_port));
        else
                strcpy(msg, "bind *");
-       n = write(cfd, msg, strlen(msg));
+       n = write(r->ctl_fd, msg, strlen(msg));
        if (n < 0) {
                errno = EOPNOTSUPP;     /* Improve error reporting!!! */
-               close(cfd);
                return -1;
        }
        if (lip->sin_port <= 0)
@@ -73,13 +67,12 @@ int __bind(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
         * open the listen file or anything like that. */
        if ((r->domain == PF_INET) && (r->stype == SOCK_DGRAM)) {
                n = snprintf(msg, sizeof(msg), "announce *!%d", ntohs(lip->sin_port));
-               n = write(cfd, msg, n);
+               n = write(r->ctl_fd, msg, n);
                if (n < 0) {
                        perror("bind-announce failed");
                        return -1;
                }
        }
-       close(cfd);
        return 0;
 }
 weak_alias(__bind, bind)
index 205f00b..0d1d4ff 100644 (file)
@@ -31,7 +31,7 @@
 int __connect(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
 {
        Rock *r;
-       int n, cfd, nfd;
+       int n, nfd;
        char msg[8 + 256 + 1], file[8 + 256 + 1];
        struct sockaddr_in *lip, *rip;
        struct sockaddr_un *runix;
@@ -57,11 +57,6 @@ int __connect(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
                         * r->raddr, so we're already done here */
                        if (r->stype == SOCK_DGRAM)
                                return 0;
-                       /* set up a tcp or udp connection */
-                       cfd = _sock_open_ctlfd(r);
-                       if (cfd < 0) {
-                               return -1;
-                       }
                        /* whatever .. */
                        rip = (struct sockaddr_in *)addr.__sockaddr_in__;
                        lip = (struct sockaddr_in *)&r->addr;
@@ -73,12 +68,9 @@ int __connect(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
                                snprintf(msg, sizeof msg, "connect %s!%d%s",
                                                 inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
                                                 r->reserved ? "!r" : "");
-                       n = write(cfd, msg, strlen(msg));
-                       if (n < 0) {
-                               close(cfd);
+                       n = write(r->ctl_fd, msg, strlen(msg));
+                       if (n < 0)
                                return -1;
-                       }
-                       close(cfd);
                        return 0;
                case PF_UNIX:
                        /* null terminate the address */
index ccbd9af..9586eef 100644 (file)
@@ -31,7 +31,7 @@
 int __listen(int fd, int backlog)
 {
        Rock *r;
-       int n, cfd;
+       int n;
        char msg[128];
        struct sockaddr_in *lip;
        struct sockaddr_un *lunix;
@@ -44,28 +44,20 @@ int __listen(int fd, int backlog)
 
        switch (r->domain) {
                case PF_INET:
-                       cfd = _sock_open_ctlfd(r);
-                       if (cfd < 0) {
-                               errno = EBADF;
-                               return -1;
-                       }
                        lip = (struct sockaddr_in *)&r->addr;
                        if (lip->sin_port >= 0) {
-                               if (write(cfd, "bind 0", 6) < 0) {
+                               if (write(r->ctl_fd, "bind 0", 6) < 0) {
                                        errno = EINVAL; //EGREG;
-                                       close(cfd);
                                        return -1;
                                }
                                snprintf(msg, sizeof msg, "announce %d", ntohs(lip->sin_port));
                        } else
                                strcpy(msg, "announce *");
-                       n = write(cfd, msg, strlen(msg));
+                       n = write(r->ctl_fd, msg, strlen(msg));
                        if (n < 0) {
                                errno = EOPNOTSUPP;     /* Improve error reporting!!! */
-                               close(cfd);
                                return -1;
                        }
-                       close(cfd);
                        return 0;
                case PF_UNIX:
                        if (r->other < 0) {
index f50fd32..412618f 100644 (file)
 
 #include <sys/plan9_helpers.h>
 
-int _sock_open_ctlfd(Rock *r)
-{
-       int open_flags = O_RDWR;
-
-       open_flags |= (r->sopts & SOCK_CLOEXEC ? O_CLOEXEC : 0);
-       return open(r->ctl, open_flags);
-}
-
 void
 _sock_ingetaddr(Rock *r, struct sockaddr_in *ip, socklen_t *alen,
                 const char *a)
@@ -194,6 +186,7 @@ Rock *_sock_newrock(int fd)
        r->reserved = 0;
        memset(&r->raddr, 0, sizeof(r->raddr_stor));
        r->ctl[0] = '\0';
+       r->ctl_fd = -1;
        r->other = -1;
        r->has_listen_fd = FALSE;
        r->listen_fd = -1;
@@ -206,6 +199,8 @@ void _sock_fd_closed(int fd)
 
        if (!r)
                return;
+       if (r->ctl_fd >= 0)
+               close(r->ctl_fd);
        if (r->has_listen_fd) {
                close(r->listen_fd);
                /* This shouldn't matter - the rock is being closed anyways. */
@@ -214,7 +209,7 @@ void _sock_fd_closed(int fd)
 }
 
 /* For a ctlfd and a few other settings, it opens and returns the corresponding
- * datafd.  This will close cfd for you. */
+ * datafd.  This will close cfd on error, or store it in the rock o/w. */
 int _sock_data(int cfd, const char *net, int domain, int type, int protocol,
                Rock **rp)
 {
@@ -239,8 +234,8 @@ int _sock_data(int cfd, const char *net, int domain, int type, int protocol,
        open_flags |= (type & SOCK_NONBLOCK ? O_NONBLOCK : 0);
        open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
        fd = open(name, open_flags);
-       close(cfd);     /* close this no matter what */
        if (fd < 0) {
+               close(cfd);
                errno = ENOBUFS;
                return -1;
        }
@@ -249,8 +244,9 @@ int _sock_data(int cfd, const char *net, int domain, int type, int protocol,
        snprintf(name, sizeof(name), "/net/%s/%d/ctl", net, n);
        r = _sock_newrock(fd);
        if (r == 0) {
-               errno = ENOBUFS;
+               close(cfd);
                close(fd);
+               errno = ENOBUFS;
                return -1;
        }
        if (rp)
@@ -262,6 +258,7 @@ int _sock_data(int cfd, const char *net, int domain, int type, int protocol,
        r->sopts = _sock_get_opts(type);
        r->protocol = protocol;
        strcpy(r->ctl, name);
+       r->ctl_fd = cfd;
        return fd;
 }
 
index c27e348..8ea7548 100644 (file)
@@ -17,7 +17,7 @@
  * success, -1 for errors. */
 int shutdown(int fd, int how)
 {
-       int ret, ctlfd;
+       int ret;
        static const char rd_msg[] = "shutdown rd";
        static const char wr_msg[] = "shutdown wr";
        static const char rdwr_msg[] = "shutdown rdwr";
@@ -49,11 +49,7 @@ int shutdown(int fd, int how)
                werrstr("Rock lookup failed");
                return -1;
        }
-       ctlfd = _sock_open_ctlfd(r);
-       if (!ctlfd)
-               return -1;
-       ret = write(ctlfd, msg, msg_sz);
-       close(ctlfd);
+       ret = write(r->ctl_fd, msg, msg_sz);
        if (ret != msg_sz)
                return -1;
        return 0;
index daeb1e5..fa18861 100644 (file)
@@ -57,7 +57,8 @@ struct Rock {
                struct sockaddr raddr;  /* peer address */
                struct sockaddr_storage raddr_stor;
        };
-       char ctl[Ctlsize];                      /* name of control file (if any) */
+       char ctl[Ctlsize];                      /* Only used for relative path lookups now */
+       int ctl_fd;                                     /* fd of the ctl file */
        int other;                                      /* fd of the remote end for Unix domain */
        bool has_listen_fd;                     /* has set up a listen file, O_PATH */
        int listen_fd;                          /* fd of the listen file, if any */
@@ -75,7 +76,6 @@ extern void _sock_ingetaddr(Rock *, struct sockaddr_in *, socklen_t *,
 extern int _sock_strip_opts(int type);
 extern int _sock_get_opts(int type);
 extern int _sock_lookup_listen_fd(int sock_fd, bool can_open);
-extern int _sock_open_ctlfd(Rock *r);
 
 int get_sibling_fd(int fd, const char *sibling);
 int write_hex_to_fd(int fd, uint64_t num);