1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Darwin porting library
23 * Make things easy to port
26 #include <mach/mach_types.h>
28 #include <sys/mount.h>
30 #include <netinet/in.h>
31 #include <netinet/tcp.h>
32 #include <sys/socket.h>
33 #include <sys/socketvar.h>
34 #include <sys/sockio.h>
35 #include <sys/protosw.h>
38 #define DEBUG_SUBSYSTEM S_LNET
40 #include <libcfs/libcfs.h>
42 static __inline__ struct sockaddr_in
45 struct sockaddr_in blank = { sizeof(struct sockaddr_in), AF_INET };
50 libcfs_ipif_free_enumeration (char **names, int n)
56 for (i = 0; i < n && names[i] != NULL; i++)
57 LIBCFS_FREE(names[i], IFNAMSIZ);
59 LIBCFS_FREE(names, n * sizeof(*names));
66 * No hack kernel structre, all using KPI.
70 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
78 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
81 CERROR ("Can't create socket: %d\n", rc);
85 nob = strnlen(name, IFNAMSIZ);
86 if (nob == IFNAMSIZ) {
87 CERROR("Interface name %s too long\n", name);
92 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
93 bzero(&ifr, sizeof(ifr));
94 strcpy(ifr.ifr_name, name);
95 rc = -sock_ioctl (so, SIOCGIFFLAGS, &ifr);
98 CERROR("Can't get flags for interface %s\n", name);
102 if ((ifr.ifr_flags & IFF_UP) == 0) {
103 CDEBUG(D_NET, "Interface %s down\n", name);
111 bzero(&ifr, sizeof(ifr));
112 strcpy(ifr.ifr_name, name);
113 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
114 rc = -sock_ioctl(so, SIOCGIFADDR, &ifr);
117 CERROR("Can't get IP address for interface %s\n", name);
121 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
124 bzero(&ifr, sizeof(ifr));
125 strcpy(ifr.ifr_name, name);
126 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
127 rc = -sock_ioctl(so, SIOCGIFNETMASK, &ifr);
130 CERROR("Can't get netmask for interface %s\n", name);
134 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
142 libcfs_ipif_enumerate (char ***namesp)
144 /* Allocate and fill in 'names', returning # interfaces/error */
156 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
159 CERROR ("Can't create socket: %d\n", rc);
163 nalloc = 16; /* first guess at max interfaces */
166 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
168 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
169 CWARN("Too many interfaces: only enumerating first %d\n",
173 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
175 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
180 ifc.ifc_buf = (char *)ifr;
181 ifc.ifc_len = nalloc * sizeof(*ifr);
186 * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in
187 * kernel space because it always try to copy result to userspace.
188 * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...).
189 * I've created a bug for Apple, let's wait...
192 for (i = 0; i < 16; i++) {
194 bzero(&en, sizeof(en));
195 snprintf(en.ifr_name, IFNAMSIZ, "en%d", i);
196 rc = -sock_ioctl (so, SIOCGIFFLAGS, &en);
199 strcpy(ifr[nfound++].ifr_name, en.ifr_name);
202 #else /* NOT in using now */
203 rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc);
206 CERROR ("Error %d enumerating interfaces\n", rc);
210 nfound = ifc.ifc_len/sizeof(*ifr);
211 LASSERT (nfound <= nalloc);
214 if (nfound < nalloc || toobig)
217 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
223 LIBCFS_ALLOC(names, nfound * sizeof(*names));
228 /* NULL out all names[i] */
229 memset (names, 0, nfound * sizeof(*names));
231 for (i = 0; i < nfound; i++) {
233 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
234 if (nob == IFNAMSIZ) {
235 /* no space for terminating NULL */
236 CERROR("interface name %.*s too long (%d max)\n",
237 nob, ifr[i].ifr_name, IFNAMSIZ);
242 LIBCFS_ALLOC(names[i], IFNAMSIZ);
243 if (names[i] == NULL) {
248 memcpy(names[i], ifr[i].ifr_name, nob);
257 libcfs_ipif_free_enumeration(names, nfound);
259 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
267 * Public entry of socket upcall.
269 * so_upcall can only be installed while create/accept of socket in
270 * Darwin 8.0, so we setup libcfs_sock_upcall() as upcall for all
271 * sockets in creat/accept, it will call upcall provided by user
272 * which can be setup after create/accept of socket.
274 static void libcfs_sock_upcall(socket_t so, void* arg, int waitf)
278 sock = (cfs_socket_t *)arg;
279 LASSERT(sock->s_magic == CFS_SOCK_MAGIC);
281 if ((sock->s_flags & CFS_SOCK_UPCALL) != 0 && sock->s_upcall != NULL)
282 sock->s_upcall(so, sock->s_upcallarg, waitf);
286 void libcfs_sock_set_cb(cfs_socket_t *sock, so_upcall callback, void *arg)
288 sock->s_upcall = callback;
289 sock->s_upcallarg = arg;
290 sock->s_flags |= CFS_SOCK_UPCALL;
294 void libcfs_sock_reset_cb(cfs_socket_t *sock)
296 sock->s_flags &= ~CFS_SOCK_UPCALL;
297 sock->s_upcall = NULL;
298 sock->s_upcallarg = NULL;
303 libcfs_sock_create (cfs_socket_t **sockp, int *fatal,
304 __u32 local_ip, int local_port)
306 struct sockaddr_in locaddr;
312 /* All errors are fatal except bind failure if the port is in use */
315 sock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
317 CERROR("Can't allocate cfs_socket.\n");
321 sock->s_magic = CFS_SOCK_MAGIC;
323 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
324 libcfs_sock_upcall, sock, &C2B_SOCK(sock));
328 optlen = sizeof(option);
329 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET,
330 SO_REUSEADDR, &option, optlen);
334 /* can't specify a local port without a local IP */
335 LASSERT (local_ip == 0 || local_port != 0);
337 if (local_ip != 0 || local_port != 0) {
338 bzero (&locaddr, sizeof (locaddr));
339 locaddr.sin_len = sizeof(struct sockaddr_in);
340 locaddr.sin_family = AF_INET;
341 locaddr.sin_port = htons (local_port);
342 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) : INADDR_ANY;
343 rc = -sock_bind(C2B_SOCK(sock), (struct sockaddr *)&locaddr);
344 if (rc == -EADDRINUSE) {
345 CDEBUG(D_NET, "Port %d already in use\n", local_port);
350 CERROR("Error trying to bind to port %d: %d\n",
357 if (C2B_SOCK(sock) != NULL)
358 sock_close(C2B_SOCK(sock));
364 libcfs_sock_listen (cfs_socket_t **sockp,
365 __u32 local_ip, int local_port, int backlog)
371 rc = libcfs_sock_create(&sock, &fatal, local_ip, local_port);
374 CERROR("Can't create socket: port %d already in use\n",
379 rc = -sock_listen(C2B_SOCK(sock), backlog);
385 if (C2B_SOCK(sock) != NULL)
386 sock_close(C2B_SOCK(sock));
392 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
394 cfs_socket_t *newsock;
397 newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
399 CERROR("Can't allocate cfs_socket.\n");
402 newsock->s_magic = CFS_SOCK_MAGIC;
404 * thread will sleep in sock_accept by calling of msleep(),
405 * it can be interrupted because msleep() use PCATCH as argument.
407 rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0,
408 libcfs_sock_upcall, newsock, &C2B_SOCK(newsock));
410 if (C2B_SOCK(newsock) != NULL)
411 sock_close(C2B_SOCK(newsock));
412 FREE(newsock, M_TEMP);
413 if ((sock->s_flags & CFS_SOCK_DOWN) != 0)
414 /* shutdown by libcfs_sock_abort_accept(), fake
415 * error number for lnet_acceptor() */
424 libcfs_sock_abort_accept (cfs_socket_t *sock)
429 * we want to wakeup thread blocked by sock_accept, but we don't
430 * know the address where thread is sleeping on, so we cannot
431 * wakeup it directly.
432 * The thread slept in sock_accept will be waken up while:
433 * 1. interrupt by signal
434 * 2. new connection is coming (sonewconn)
435 * 3. disconnecting of the socket (soisconnected)
437 * Cause we can't send signal to a thread directly(no KPI), so the
438 * only thing can be done here is disconnect the socket (by
439 * sock_shutdown() or sth else? ).
441 * Shutdown request of socket with SHUT_WR or SHUT_RDWR will
442 * be issured to the protocol.
443 * sock_shutdown()->tcp_usr_shutdown()->tcp_usrclosed()->
444 * tcp_close()->soisdisconnected(), it will wakeup thread by
445 * wakeup((caddr_t)&so->so_timeo);
447 sock->s_flags |= CFS_SOCK_DOWN;
448 sock_shutdown(C2B_SOCK(sock), SHUT_RDWR);
452 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
456 cfs_duration_t to = cfs_time_seconds(timeout);
467 struct msghdr msg = {
476 cfs_duration_usec(to, &tv);
477 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_RCVTIMEO,
480 CERROR("Can't set socket recv timeout "
482 (long)tv.tv_sec, (int)tv.tv_usec, rc);
486 then = cfs_time_current();
487 rc = -sock_receive(C2B_SOCK(sock), &msg, 0, &rcvlen);
488 to -= cfs_time_current() - then;
490 if (rc != 0 && rc != -EWOULDBLOCK)
498 buffer = ((char *)buffer) + rcvlen;
505 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
509 cfs_duration_t to = cfs_time_seconds(timeout);
520 struct msghdr msg = {
527 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0,
531 cfs_duration_usec(to, &tv);
532 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDTIMEO,
535 CERROR("Can't set socket send timeout "
537 (long)tv.tv_sec, (int)tv.tv_usec, rc);
542 then = cfs_time_current();
543 rc = -sock_send(C2B_SOCK(sock), &msg,
544 ((timeout == 0) ? MSG_DONTWAIT : 0), &sndlen);
545 to -= cfs_time_current() - then;
547 if (rc != 0 && rc != -EWOULDBLOCK)
554 buffer = ((char *)buffer) + sndlen;
562 libcfs_sock_getaddr (cfs_socket_t *sock, int remote, __u32 *ip, int *port)
564 struct sockaddr_in sin;
568 /* Get remote address */
569 rc = -sock_getpeername(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
571 /* Get local address */
572 rc = -sock_getsockname(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
574 CERROR ("Error %d getting sock %s IP/port\n",
575 rc, remote ? "peer" : "local");
580 *ip = ntohl (sin.sin_addr.s_addr);
583 *port = ntohs (sin.sin_port);
588 libcfs_sock_setbuf (cfs_socket_t *sock, int txbufsize, int rxbufsize)
593 if (txbufsize != 0) {
595 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
596 (char *)&option, sizeof (option));
598 CERROR ("Can't set send buffer %d: %d\n",
604 if (rxbufsize != 0) {
606 rc = -sock_setsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
607 (char *)&option, sizeof (option));
609 CERROR ("Can't set receive buffer %d: %d\n",
618 libcfs_sock_getbuf (cfs_socket_t *sock, int *txbufsize, int *rxbufsize)
624 if (txbufsize != NULL) {
625 optlen = sizeof(option);
626 rc = -sock_getsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
627 (char *)&option, &optlen);
629 CERROR ("Can't get send buffer size: %d\n", rc);
635 if (rxbufsize != NULL) {
636 optlen = sizeof(option);
637 rc = -sock_getsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
638 (char *)&option, &optlen);
640 CERROR ("Can't get receive buffer size: %d\n", rc);
649 libcfs_sock_release (cfs_socket_t *sock)
651 if (C2B_SOCK(sock) != NULL) {
652 sock_shutdown(C2B_SOCK(sock), 2);
653 sock_close(C2B_SOCK(sock));
659 libcfs_sock_connect (cfs_socket_t **sockp, int *fatal,
660 __u32 local_ip, int local_port,
661 __u32 peer_ip, int peer_port)
664 struct sockaddr_in srvaddr;
667 rc = libcfs_sock_create(&sock, fatal, local_ip, local_port);
671 bzero(&srvaddr, sizeof(srvaddr));
672 srvaddr.sin_len = sizeof(struct sockaddr_in);
673 srvaddr.sin_family = AF_INET;
674 srvaddr.sin_port = htons(peer_port);
675 srvaddr.sin_addr.s_addr = htonl(peer_ip);
677 rc = -sock_connect(C2B_SOCK(sock), (struct sockaddr *)&srvaddr, 0);
683 *fatal = !(rc == -EADDRNOTAVAIL || rc == -EADDRINUSE);
684 CDEBUG(*fatal ? D_NETERROR : D_NET,
685 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
686 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
688 libcfs_sock_release(sock);
692 #else /* !__DARWIN8__ */
695 * To use bigger buffer for socket:
696 * 1. Increase nmbclusters (Cannot increased by sysctl because it's ready only, so
697 * we must patch kernel).
698 * 2. Increase net.inet.tcp.reass.maxsegments
699 * 3. Increase net.inet.tcp.sendspace
700 * 4. Increase net.inet.tcp.recvspace
701 * 5. Increase kern.ipc.maxsockbuf
703 #define KSOCK_MAX_BUF (1152*1024)
706 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
713 CFS_DECL_FUNNEL_DATA;
716 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
719 CERROR ("Can't create socket: %d\n", rc);
722 nob = strnlen(name, IFNAMSIZ);
723 if (nob == IFNAMSIZ) {
724 CERROR("Interface name %s too long\n", name);
729 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
730 strcpy(ifr.ifr_name, name);
732 rc = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ifr, current_proc());
736 CERROR("Can't get flags for interface %s\n", name);
739 if ((ifr.ifr_flags & IFF_UP) == 0) {
740 CDEBUG(D_NET, "Interface %s down\n", name);
747 strcpy(ifr.ifr_name, name);
748 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
750 rc = ifioctl(so, SIOCGIFADDR, (caddr_t)&ifr, current_proc());
754 CERROR("Can't get IP address for interface %s\n", name);
758 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
761 strcpy(ifr.ifr_name, name);
762 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
764 rc = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ifr, current_proc());
768 CERROR("Can't get netmask for interface %s\n", name);
772 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
782 libcfs_ipif_enumerate (char ***namesp)
784 /* Allocate and fill in 'names', returning # interfaces/error */
795 CFS_DECL_FUNNEL_DATA;
798 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
801 CERROR ("Can't create socket: %d\n", rc);
805 nalloc = 16; /* first guess at max interfaces */
808 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
810 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
811 CWARN("Too many interfaces: only enumerating first %d\n",
815 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
817 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
822 ifc.ifc_buf = (char *)ifr;
823 ifc.ifc_len = nalloc * sizeof(*ifr);
826 rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc());
830 CERROR ("Error %d enumerating interfaces\n", rc);
834 nfound = ifc.ifc_len/sizeof(*ifr);
835 LASSERT (nfound <= nalloc);
837 if (nfound < nalloc || toobig)
840 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
846 LIBCFS_ALLOC(names, nfound * sizeof(*names));
851 /* NULL out all names[i] */
852 memset (names, 0, nfound * sizeof(*names));
854 for (i = 0; i < nfound; i++) {
856 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
857 if (nob == IFNAMSIZ) {
858 /* no space for terminating NULL */
859 CERROR("interface name %.*s too long (%d max)\n",
860 nob, ifr[i].ifr_name, IFNAMSIZ);
865 LIBCFS_ALLOC(names[i], IFNAMSIZ);
866 if (names[i] == NULL) {
871 memcpy(names[i], ifr[i].ifr_name, nob);
880 libcfs_ipif_free_enumeration(names, nfound);
882 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
891 libcfs_sock_create (struct socket **sockp, int *fatal,
892 __u32 local_ip, int local_port)
894 struct sockaddr_in locaddr;
899 CFS_DECL_FUNNEL_DATA;
903 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
906 CERROR ("Can't create socket: %d\n", rc);
910 bzero(&sopt, sizeof sopt);
912 sopt.sopt_level = SOL_SOCKET;
913 sopt.sopt_name = SO_REUSEADDR;
914 sopt.sopt_val = &option;
915 sopt.sopt_valsize = sizeof(option);
917 rc = sosetopt(so, &sopt);
920 CERROR ("Can't set sock reuse address: %d\n", rc);
923 /* can't specify a local port without a local IP */
924 LASSERT (local_ip == 0 || local_port != 0);
926 if (local_ip != 0 || local_port != 0) {
927 bzero (&locaddr, sizeof (locaddr));
928 locaddr.sin_len = sizeof(struct sockaddr_in);
929 locaddr.sin_family = AF_INET;
930 locaddr.sin_port = htons (local_port);
931 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) :
934 rc = sobind(so, (struct sockaddr *)&locaddr);
935 if (rc == EADDRINUSE) {
937 CDEBUG(D_NET, "Port %d already in use\n", local_port);
943 CERROR ("Can't bind to local IP Address %u.%u.%u.%u: %d\n",
944 HIPQUAD(local_ip), rc);
958 libcfs_sock_listen (struct socket **sockp,
959 __u32 local_ip, int local_port, int backlog)
963 CFS_DECL_FUNNEL_DATA;
965 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
968 CERROR("Can't create socket: port %d already in use\n",
973 rc = solisten(*sockp, backlog);
977 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
985 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
990 CFS_DECL_FUNNEL_DATA;
994 if ((sock->so_options & SO_ACCEPTCONN) == 0) {
1000 if ((sock->so_state & SS_NBIO) && sock->so_comp.tqh_first == NULL) {
1003 return (-EWOULDBLOCK);
1007 while (TAILQ_EMPTY(&sock->so_comp) && sock->so_error == 0) {
1008 if (sock->so_state & SS_CANTRCVMORE) {
1009 sock->so_error = ECONNABORTED;
1012 error = tsleep((caddr_t)&sock->so_timeo, PSOCK | PCATCH,
1020 if (sock->so_error) {
1021 error = sock->so_error;
1029 * At this point we know that there is at least one connection
1030 * ready to be accepted. Remove it from the queue prior to
1031 * allocating the file descriptor for it since falloc() may
1032 * block allowing another process to accept the connection
1035 so = TAILQ_FIRST(&sock->so_comp);
1036 TAILQ_REMOVE(&sock->so_comp, so, so_list);
1039 so->so_state &= ~SS_COMP;
1042 (void) soaccept(so, &sa);
1052 libcfs_sock_abort_accept (struct socket *sock)
1054 wakeup(&sock->so_timeo);
1058 * XXX Liang: timeout for write is not supported yet.
1061 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
1067 struct iovec iov = {
1076 .uio_segflg = UIO_SYSSPACE,
1077 .uio_rw = UIO_WRITE,
1082 rc = sosend(sock, NULL, &suio, (struct mbuf *)0, (struct mbuf *)0, 0);
1086 if ( suio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1091 rc = nob - suio.uio_resid;
1092 buffer = ((char *)buffer) + rc;
1093 nob = suio.uio_resid;
1102 * XXX Liang: timeout for read is not supported yet.
1105 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
1111 struct iovec iov = {
1120 .uio_segflg = UIO_SYSSPACE,
1126 rc = soreceive(sock, (struct sockaddr **)0, &ruio, (struct mbuf **)0, (struct mbuf **)0, (int *)0);
1130 if ( ruio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1135 rc = nob - ruio.uio_resid;
1136 buffer = ((char *)buffer) + rc;
1137 nob = ruio.uio_resid;
1146 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
1148 struct sockopt sopt;
1153 bzero(&sopt, sizeof sopt);
1154 sopt.sopt_dir = SOPT_SET;
1155 sopt.sopt_level = SOL_SOCKET;
1156 sopt.sopt_val = &option;
1157 sopt.sopt_valsize = sizeof(option);
1159 if (txbufsize != 0) {
1161 if (option > KSOCK_MAX_BUF)
1162 option = KSOCK_MAX_BUF;
1164 sopt.sopt_name = SO_SNDBUF;
1166 rc = sosetopt(sock, &sopt);
1169 CERROR ("Can't set send buffer %d: %d\n",
1176 if (rxbufsize != 0) {
1178 sopt.sopt_name = SO_RCVBUF;
1180 rc = sosetopt(sock, &sopt);
1183 CERROR ("Can't set receive buffer %d: %d\n",
1192 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
1194 struct sockaddr_in *sin;
1195 struct sockaddr *sa = NULL;
1201 rc = sock->so_proto->pr_usrreqs->pru_peeraddr(sock, &sa);
1205 if (sa) FREE(sa, M_SONAME);
1206 CERROR ("Error %d getting sock peer IP\n", rc);
1211 rc = sock->so_proto->pr_usrreqs->pru_sockaddr(sock, &sa);
1214 if (sa) FREE(sa, M_SONAME);
1215 CERROR ("Error %d getting sock local IP\n", rc);
1220 sin = (struct sockaddr_in *)sa;
1222 *ip = ntohl (sin->sin_addr.s_addr);
1224 *port = ntohs (sin->sin_port);
1232 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
1234 struct sockopt sopt;
1238 bzero(&sopt, sizeof sopt);
1239 sopt.sopt_dir = SOPT_GET;
1240 sopt.sopt_level = SOL_SOCKET;
1242 if (txbufsize != NULL) {
1243 sopt.sopt_val = txbufsize;
1244 sopt.sopt_valsize = sizeof(*txbufsize);
1245 sopt.sopt_name = SO_SNDBUF;
1247 rc = sogetopt(sock, &sopt);
1250 CERROR ("Can't get send buffer size: %d\n", rc);
1255 if (rxbufsize != NULL) {
1256 sopt.sopt_val = rxbufsize;
1257 sopt.sopt_valsize = sizeof(*rxbufsize);
1258 sopt.sopt_name = SO_RCVBUF;
1260 rc = sogetopt(sock, &sopt);
1263 CERROR ("Can't get receive buffer size: %d\n", rc);
1271 libcfs_sock_connect (struct socket **sockp, int *fatal,
1272 __u32 local_ip, int local_port,
1273 __u32 peer_ip, int peer_port)
1275 struct sockaddr_in srvaddr;
1279 CFS_DECL_FUNNEL_DATA;
1281 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
1285 bzero(&srvaddr, sizeof(srvaddr));
1286 srvaddr.sin_len = sizeof(struct sockaddr_in);
1287 srvaddr.sin_family = AF_INET;
1288 srvaddr.sin_port = htons (peer_port);
1289 srvaddr.sin_addr.s_addr = htonl (peer_ip);
1292 rc = soconnect(so, (struct sockaddr *)&srvaddr);
1295 if (rc != EADDRNOTAVAIL && rc != EADDRINUSE)
1297 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1298 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1302 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
1303 CDEBUG(D_NET, "ksocknal sleep for waiting auto_connect.\n");
1304 (void) tsleep((caddr_t)&so->so_timeo, PSOCK, "ksocknal_conn", hz);
1306 if ((rc = so->so_error) != 0) {
1311 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1312 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1315 LASSERT(so->so_state & SS_ISCONNECTED);
1330 libcfs_sock_release (struct socket *sock)
1332 CFS_DECL_FUNNEL_DATA;
1334 soshutdown(sock, 0);