4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
34 * libcfs/libcfs/darwin/darwin-tcpip.c
36 * Darwin porting library
37 * Make things easy to port
39 * Author: Phil Schwan <phil@clusterfs.com>
42 #include <mach/mach_types.h>
44 #include <sys/mount.h>
46 #include <netinet/in.h>
47 #include <netinet/tcp.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/sockio.h>
51 #include <sys/protosw.h>
54 #define DEBUG_SUBSYSTEM S_LNET
56 #include <libcfs/libcfs.h>
58 static __inline__ struct sockaddr_in
61 struct sockaddr_in blank = { sizeof(struct sockaddr_in), AF_INET };
66 libcfs_ipif_free_enumeration (char **names, int n)
72 for (i = 0; i < n && names[i] != NULL; i++)
73 LIBCFS_FREE(names[i], IFNAMSIZ);
75 LIBCFS_FREE(names, n * sizeof(*names));
82 * No hack kernel structre, all using KPI.
86 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
94 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
97 CERROR ("Can't create socket: %d\n", rc);
101 nob = strnlen(name, IFNAMSIZ);
102 if (nob == IFNAMSIZ) {
103 CERROR("Interface name %s too long\n", name);
108 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
109 bzero(&ifr, sizeof(ifr));
110 strcpy(ifr.ifr_name, name);
111 rc = -sock_ioctl (so, SIOCGIFFLAGS, &ifr);
114 CERROR("Can't get flags for interface %s\n", name);
118 if ((ifr.ifr_flags & IFF_UP) == 0) {
119 CDEBUG(D_NET, "Interface %s down\n", name);
127 bzero(&ifr, sizeof(ifr));
128 strcpy(ifr.ifr_name, name);
129 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
130 rc = -sock_ioctl(so, SIOCGIFADDR, &ifr);
133 CERROR("Can't get IP address for interface %s\n", name);
137 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
140 bzero(&ifr, sizeof(ifr));
141 strcpy(ifr.ifr_name, name);
142 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
143 rc = -sock_ioctl(so, SIOCGIFNETMASK, &ifr);
146 CERROR("Can't get netmask for interface %s\n", name);
150 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
158 libcfs_ipif_enumerate (char ***namesp)
160 /* Allocate and fill in 'names', returning # interfaces/error */
172 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
175 CERROR ("Can't create socket: %d\n", rc);
179 nalloc = 16; /* first guess at max interfaces */
182 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
184 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
185 CWARN("Too many interfaces: only enumerating first %d\n",
189 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
191 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
196 ifc.ifc_buf = (char *)ifr;
197 ifc.ifc_len = nalloc * sizeof(*ifr);
202 * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in
203 * kernel space because it always try to copy result to userspace.
204 * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...).
205 * I've created a bug for Apple, let's wait...
208 for (i = 0; i < 16; i++) {
210 bzero(&en, sizeof(en));
211 snprintf(en.ifr_name, IFNAMSIZ, "en%d", i);
212 rc = -sock_ioctl (so, SIOCGIFFLAGS, &en);
215 strcpy(ifr[nfound++].ifr_name, en.ifr_name);
218 #else /* NOT in using now */
219 rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc);
222 CERROR ("Error %d enumerating interfaces\n", rc);
226 nfound = ifc.ifc_len/sizeof(*ifr);
227 LASSERT (nfound <= nalloc);
230 if (nfound < nalloc || toobig)
233 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
239 LIBCFS_ALLOC(names, nfound * sizeof(*names));
244 /* NULL out all names[i] */
245 memset (names, 0, nfound * sizeof(*names));
247 for (i = 0; i < nfound; i++) {
249 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
250 if (nob == IFNAMSIZ) {
251 /* no space for terminating NULL */
252 CERROR("interface name %.*s too long (%d max)\n",
253 nob, ifr[i].ifr_name, IFNAMSIZ);
258 LIBCFS_ALLOC(names[i], IFNAMSIZ);
259 if (names[i] == NULL) {
264 memcpy(names[i], ifr[i].ifr_name, nob);
273 libcfs_ipif_free_enumeration(names, nfound);
275 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
283 * Public entry of socket upcall.
285 * so_upcall can only be installed while create/accept of socket in
286 * Darwin 8.0, so we setup libcfs_sock_upcall() as upcall for all
287 * sockets in creat/accept, it will call upcall provided by user
288 * which can be setup after create/accept of socket.
290 static void libcfs_sock_upcall(socket_t so, void* arg, int waitf)
294 sock = (cfs_socket_t *)arg;
295 LASSERT(sock->s_magic == CFS_SOCK_MAGIC);
297 if ((sock->s_flags & CFS_SOCK_UPCALL) != 0 && sock->s_upcall != NULL)
298 sock->s_upcall(so, sock->s_upcallarg, waitf);
302 void libcfs_sock_set_cb(cfs_socket_t *sock, so_upcall callback, void *arg)
304 sock->s_upcall = callback;
305 sock->s_upcallarg = arg;
306 sock->s_flags |= CFS_SOCK_UPCALL;
310 void libcfs_sock_reset_cb(cfs_socket_t *sock)
312 sock->s_flags &= ~CFS_SOCK_UPCALL;
313 sock->s_upcall = NULL;
314 sock->s_upcallarg = NULL;
319 libcfs_sock_create (cfs_socket_t **sockp, int *fatal,
320 __u32 local_ip, int local_port)
322 struct sockaddr_in locaddr;
328 /* All errors are fatal except bind failure if the port is in use */
331 sock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
333 CERROR("Can't allocate cfs_socket.\n");
337 sock->s_magic = CFS_SOCK_MAGIC;
339 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
340 libcfs_sock_upcall, sock, &C2B_SOCK(sock));
344 optlen = sizeof(option);
345 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET,
346 SO_REUSEADDR, &option, optlen);
350 /* can't specify a local port without a local IP */
351 LASSERT (local_ip == 0 || local_port != 0);
353 if (local_ip != 0 || local_port != 0) {
354 bzero (&locaddr, sizeof (locaddr));
355 locaddr.sin_len = sizeof(struct sockaddr_in);
356 locaddr.sin_family = AF_INET;
357 locaddr.sin_port = htons (local_port);
358 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) : INADDR_ANY;
359 rc = -sock_bind(C2B_SOCK(sock), (struct sockaddr *)&locaddr);
360 if (rc == -EADDRINUSE) {
361 CDEBUG(D_NET, "Port %d already in use\n", local_port);
366 CERROR("Error trying to bind to port %d: %d\n",
373 if (C2B_SOCK(sock) != NULL)
374 sock_close(C2B_SOCK(sock));
380 libcfs_sock_listen (cfs_socket_t **sockp,
381 __u32 local_ip, int local_port, int backlog)
387 rc = libcfs_sock_create(&sock, &fatal, local_ip, local_port);
390 CERROR("Can't create socket: port %d already in use\n",
395 rc = -sock_listen(C2B_SOCK(sock), backlog);
401 if (C2B_SOCK(sock) != NULL)
402 sock_close(C2B_SOCK(sock));
408 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
410 cfs_socket_t *newsock;
413 newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
415 CERROR("Can't allocate cfs_socket.\n");
418 newsock->s_magic = CFS_SOCK_MAGIC;
420 * thread will sleep in sock_accept by calling of msleep(),
421 * it can be interrupted because msleep() use PCATCH as argument.
423 rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0,
424 libcfs_sock_upcall, newsock, &C2B_SOCK(newsock));
426 if (C2B_SOCK(newsock) != NULL)
427 sock_close(C2B_SOCK(newsock));
428 FREE(newsock, M_TEMP);
429 if ((sock->s_flags & CFS_SOCK_DOWN) != 0)
430 /* shutdown by libcfs_sock_abort_accept(), fake
431 * error number for lnet_acceptor() */
440 libcfs_sock_abort_accept (cfs_socket_t *sock)
445 * we want to wakeup thread blocked by sock_accept, but we don't
446 * know the address where thread is sleeping on, so we cannot
447 * wakeup it directly.
448 * The thread slept in sock_accept will be waken up while:
449 * 1. interrupt by signal
450 * 2. new connection is coming (sonewconn)
451 * 3. disconnecting of the socket (soisconnected)
453 * Cause we can't send signal to a thread directly(no KPI), so the
454 * only thing can be done here is disconnect the socket (by
455 * sock_shutdown() or sth else? ).
457 * Shutdown request of socket with SHUT_WR or SHUT_RDWR will
458 * be issured to the protocol.
459 * sock_shutdown()->tcp_usr_shutdown()->tcp_usrclosed()->
460 * tcp_close()->soisdisconnected(), it will wakeup thread by
461 * wakeup((caddr_t)&so->so_timeo);
463 sock->s_flags |= CFS_SOCK_DOWN;
464 sock_shutdown(C2B_SOCK(sock), SHUT_RDWR);
468 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
472 cfs_duration_t to = cfs_time_seconds(timeout);
483 struct msghdr msg = {
492 cfs_duration_usec(to, &tv);
493 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_RCVTIMEO,
496 CERROR("Can't set socket recv timeout "
498 (long)tv.tv_sec, (int)tv.tv_usec, rc);
502 then = cfs_time_current();
503 rc = -sock_receive(C2B_SOCK(sock), &msg, 0, &rcvlen);
504 to -= cfs_time_current() - then;
506 if (rc != 0 && rc != -EWOULDBLOCK)
514 buffer = ((char *)buffer) + rcvlen;
521 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
525 cfs_duration_t to = cfs_time_seconds(timeout);
536 struct msghdr msg = {
543 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0,
547 cfs_duration_usec(to, &tv);
548 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDTIMEO,
551 CERROR("Can't set socket send timeout "
553 (long)tv.tv_sec, (int)tv.tv_usec, rc);
558 then = cfs_time_current();
559 rc = -sock_send(C2B_SOCK(sock), &msg,
560 ((timeout == 0) ? MSG_DONTWAIT : 0), &sndlen);
561 to -= cfs_time_current() - then;
563 if (rc != 0 && rc != -EWOULDBLOCK)
570 buffer = ((char *)buffer) + sndlen;
578 libcfs_sock_getaddr (cfs_socket_t *sock, int remote, __u32 *ip, int *port)
580 struct sockaddr_in sin;
584 /* Get remote address */
585 rc = -sock_getpeername(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
587 /* Get local address */
588 rc = -sock_getsockname(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
590 CERROR ("Error %d getting sock %s IP/port\n",
591 rc, remote ? "peer" : "local");
596 *ip = ntohl (sin.sin_addr.s_addr);
599 *port = ntohs (sin.sin_port);
604 libcfs_sock_setbuf (cfs_socket_t *sock, int txbufsize, int rxbufsize)
609 if (txbufsize != 0) {
611 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
612 (char *)&option, sizeof (option));
614 CERROR ("Can't set send buffer %d: %d\n",
620 if (rxbufsize != 0) {
622 rc = -sock_setsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
623 (char *)&option, sizeof (option));
625 CERROR ("Can't set receive buffer %d: %d\n",
634 libcfs_sock_getbuf (cfs_socket_t *sock, int *txbufsize, int *rxbufsize)
640 if (txbufsize != NULL) {
641 optlen = sizeof(option);
642 rc = -sock_getsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
643 (char *)&option, &optlen);
645 CERROR ("Can't get send buffer size: %d\n", rc);
651 if (rxbufsize != NULL) {
652 optlen = sizeof(option);
653 rc = -sock_getsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
654 (char *)&option, &optlen);
656 CERROR ("Can't get receive buffer size: %d\n", rc);
665 libcfs_sock_release (cfs_socket_t *sock)
667 if (C2B_SOCK(sock) != NULL) {
668 sock_shutdown(C2B_SOCK(sock), 2);
669 sock_close(C2B_SOCK(sock));
675 libcfs_sock_connect (cfs_socket_t **sockp, int *fatal,
676 __u32 local_ip, int local_port,
677 __u32 peer_ip, int peer_port)
680 struct sockaddr_in srvaddr;
683 rc = libcfs_sock_create(&sock, fatal, local_ip, local_port);
687 bzero(&srvaddr, sizeof(srvaddr));
688 srvaddr.sin_len = sizeof(struct sockaddr_in);
689 srvaddr.sin_family = AF_INET;
690 srvaddr.sin_port = htons(peer_port);
691 srvaddr.sin_addr.s_addr = htonl(peer_ip);
693 rc = -sock_connect(C2B_SOCK(sock), (struct sockaddr *)&srvaddr, 0);
699 *fatal = !(rc == -EADDRNOTAVAIL || rc == -EADDRINUSE);
700 CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET,
701 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
702 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
704 libcfs_sock_release(sock);
708 #else /* !__DARWIN8__ */
711 * To use bigger buffer for socket:
712 * 1. Increase nmbclusters (Cannot increased by sysctl because it's ready only, so
713 * we must patch kernel).
714 * 2. Increase net.inet.tcp.reass.maxsegments
715 * 3. Increase net.inet.tcp.sendspace
716 * 4. Increase net.inet.tcp.recvspace
717 * 5. Increase kern.ipc.maxsockbuf
719 #define KSOCK_MAX_BUF (1152*1024)
722 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
729 CFS_DECL_FUNNEL_DATA;
732 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
735 CERROR ("Can't create socket: %d\n", rc);
738 nob = strnlen(name, IFNAMSIZ);
739 if (nob == IFNAMSIZ) {
740 CERROR("Interface name %s too long\n", name);
745 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
746 strcpy(ifr.ifr_name, name);
748 rc = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ifr, current_proc());
752 CERROR("Can't get flags for interface %s\n", name);
755 if ((ifr.ifr_flags & IFF_UP) == 0) {
756 CDEBUG(D_NET, "Interface %s down\n", name);
763 strcpy(ifr.ifr_name, name);
764 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
766 rc = ifioctl(so, SIOCGIFADDR, (caddr_t)&ifr, current_proc());
770 CERROR("Can't get IP address for interface %s\n", name);
774 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
777 strcpy(ifr.ifr_name, name);
778 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
780 rc = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ifr, current_proc());
784 CERROR("Can't get netmask for interface %s\n", name);
788 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
798 libcfs_ipif_enumerate (char ***namesp)
800 /* Allocate and fill in 'names', returning # interfaces/error */
811 CFS_DECL_FUNNEL_DATA;
814 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
817 CERROR ("Can't create socket: %d\n", rc);
821 nalloc = 16; /* first guess at max interfaces */
824 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
826 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
827 CWARN("Too many interfaces: only enumerating first %d\n",
831 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
833 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
838 ifc.ifc_buf = (char *)ifr;
839 ifc.ifc_len = nalloc * sizeof(*ifr);
842 rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc());
846 CERROR ("Error %d enumerating interfaces\n", rc);
850 nfound = ifc.ifc_len/sizeof(*ifr);
851 LASSERT (nfound <= nalloc);
853 if (nfound < nalloc || toobig)
856 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
862 LIBCFS_ALLOC(names, nfound * sizeof(*names));
867 /* NULL out all names[i] */
868 memset (names, 0, nfound * sizeof(*names));
870 for (i = 0; i < nfound; i++) {
872 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
873 if (nob == IFNAMSIZ) {
874 /* no space for terminating NULL */
875 CERROR("interface name %.*s too long (%d max)\n",
876 nob, ifr[i].ifr_name, IFNAMSIZ);
881 LIBCFS_ALLOC(names[i], IFNAMSIZ);
882 if (names[i] == NULL) {
887 memcpy(names[i], ifr[i].ifr_name, nob);
896 libcfs_ipif_free_enumeration(names, nfound);
898 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
907 libcfs_sock_create (struct socket **sockp, int *fatal,
908 __u32 local_ip, int local_port)
910 struct sockaddr_in locaddr;
915 CFS_DECL_FUNNEL_DATA;
919 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
922 CERROR ("Can't create socket: %d\n", rc);
926 bzero(&sopt, sizeof sopt);
928 sopt.sopt_level = SOL_SOCKET;
929 sopt.sopt_name = SO_REUSEADDR;
930 sopt.sopt_val = &option;
931 sopt.sopt_valsize = sizeof(option);
933 rc = sosetopt(so, &sopt);
936 CERROR ("Can't set sock reuse address: %d\n", rc);
939 /* can't specify a local port without a local IP */
940 LASSERT (local_ip == 0 || local_port != 0);
942 if (local_ip != 0 || local_port != 0) {
943 bzero (&locaddr, sizeof (locaddr));
944 locaddr.sin_len = sizeof(struct sockaddr_in);
945 locaddr.sin_family = AF_INET;
946 locaddr.sin_port = htons (local_port);
947 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) :
950 rc = sobind(so, (struct sockaddr *)&locaddr);
951 if (rc == EADDRINUSE) {
953 CDEBUG(D_NET, "Port %d already in use\n", local_port);
959 CERROR ("Can't bind to local IP Address %u.%u.%u.%u: %d\n",
960 HIPQUAD(local_ip), rc);
974 libcfs_sock_listen (struct socket **sockp,
975 __u32 local_ip, int local_port, int backlog)
979 CFS_DECL_FUNNEL_DATA;
981 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
984 CERROR("Can't create socket: port %d already in use\n",
989 rc = solisten(*sockp, backlog);
993 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
1001 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
1004 struct sockaddr *sa;
1006 CFS_DECL_FUNNEL_DATA;
1010 if ((sock->so_options & SO_ACCEPTCONN) == 0) {
1016 if ((sock->so_state & SS_NBIO) && sock->so_comp.tqh_first == NULL) {
1019 return (-EWOULDBLOCK);
1023 while (TAILQ_EMPTY(&sock->so_comp) && sock->so_error == 0) {
1024 if (sock->so_state & SS_CANTRCVMORE) {
1025 sock->so_error = ECONNABORTED;
1028 error = tsleep((caddr_t)&sock->so_timeo, PSOCK | PCATCH,
1036 if (sock->so_error) {
1037 error = sock->so_error;
1045 * At this point we know that there is at least one connection
1046 * ready to be accepted. Remove it from the queue prior to
1047 * allocating the file descriptor for it since falloc() may
1048 * block allowing another process to accept the connection
1051 so = TAILQ_FIRST(&sock->so_comp);
1052 TAILQ_REMOVE(&sock->so_comp, so, so_list);
1055 so->so_state &= ~SS_COMP;
1058 (void) soaccept(so, &sa);
1068 libcfs_sock_abort_accept (struct socket *sock)
1070 wakeup(&sock->so_timeo);
1074 * XXX Liang: timeout for write is not supported yet.
1077 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
1083 struct iovec iov = {
1092 .uio_segflg = UIO_SYSSPACE,
1093 .uio_rw = UIO_WRITE,
1098 rc = sosend(sock, NULL, &suio, (struct mbuf *)0, (struct mbuf *)0, 0);
1102 if ( suio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1107 rc = nob - suio.uio_resid;
1108 buffer = ((char *)buffer) + rc;
1109 nob = suio.uio_resid;
1118 * XXX Liang: timeout for read is not supported yet.
1121 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
1127 struct iovec iov = {
1136 .uio_segflg = UIO_SYSSPACE,
1142 rc = soreceive(sock, (struct sockaddr **)0, &ruio, (struct mbuf **)0, (struct mbuf **)0, (int *)0);
1146 if ( ruio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1151 rc = nob - ruio.uio_resid;
1152 buffer = ((char *)buffer) + rc;
1153 nob = ruio.uio_resid;
1162 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
1164 struct sockopt sopt;
1169 bzero(&sopt, sizeof sopt);
1170 sopt.sopt_dir = SOPT_SET;
1171 sopt.sopt_level = SOL_SOCKET;
1172 sopt.sopt_val = &option;
1173 sopt.sopt_valsize = sizeof(option);
1175 if (txbufsize != 0) {
1177 if (option > KSOCK_MAX_BUF)
1178 option = KSOCK_MAX_BUF;
1180 sopt.sopt_name = SO_SNDBUF;
1182 rc = sosetopt(sock, &sopt);
1185 CERROR ("Can't set send buffer %d: %d\n",
1192 if (rxbufsize != 0) {
1194 sopt.sopt_name = SO_RCVBUF;
1196 rc = sosetopt(sock, &sopt);
1199 CERROR ("Can't set receive buffer %d: %d\n",
1208 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
1210 struct sockaddr_in *sin;
1211 struct sockaddr *sa = NULL;
1217 rc = sock->so_proto->pr_usrreqs->pru_peeraddr(sock, &sa);
1221 if (sa) FREE(sa, M_SONAME);
1222 CERROR ("Error %d getting sock peer IP\n", rc);
1227 rc = sock->so_proto->pr_usrreqs->pru_sockaddr(sock, &sa);
1230 if (sa) FREE(sa, M_SONAME);
1231 CERROR ("Error %d getting sock local IP\n", rc);
1236 sin = (struct sockaddr_in *)sa;
1238 *ip = ntohl (sin->sin_addr.s_addr);
1240 *port = ntohs (sin->sin_port);
1248 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
1250 struct sockopt sopt;
1254 bzero(&sopt, sizeof sopt);
1255 sopt.sopt_dir = SOPT_GET;
1256 sopt.sopt_level = SOL_SOCKET;
1258 if (txbufsize != NULL) {
1259 sopt.sopt_val = txbufsize;
1260 sopt.sopt_valsize = sizeof(*txbufsize);
1261 sopt.sopt_name = SO_SNDBUF;
1263 rc = sogetopt(sock, &sopt);
1266 CERROR ("Can't get send buffer size: %d\n", rc);
1271 if (rxbufsize != NULL) {
1272 sopt.sopt_val = rxbufsize;
1273 sopt.sopt_valsize = sizeof(*rxbufsize);
1274 sopt.sopt_name = SO_RCVBUF;
1276 rc = sogetopt(sock, &sopt);
1279 CERROR ("Can't get receive buffer size: %d\n", rc);
1287 libcfs_sock_connect (struct socket **sockp, int *fatal,
1288 __u32 local_ip, int local_port,
1289 __u32 peer_ip, int peer_port)
1291 struct sockaddr_in srvaddr;
1295 CFS_DECL_FUNNEL_DATA;
1297 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
1301 bzero(&srvaddr, sizeof(srvaddr));
1302 srvaddr.sin_len = sizeof(struct sockaddr_in);
1303 srvaddr.sin_family = AF_INET;
1304 srvaddr.sin_port = htons (peer_port);
1305 srvaddr.sin_addr.s_addr = htonl (peer_ip);
1308 rc = soconnect(so, (struct sockaddr *)&srvaddr);
1311 if (rc != EADDRNOTAVAIL && rc != EADDRINUSE)
1312 CNETERR("Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1313 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1317 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
1318 CDEBUG(D_NET, "ksocknal sleep for waiting auto_connect.\n");
1319 (void) tsleep((caddr_t)&so->so_timeo, PSOCK, "ksocknal_conn", hz);
1321 if ((rc = so->so_error) != 0) {
1325 CNETERR("Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1326 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1329 LASSERT(so->so_state & SS_ISCONNECTED);
1344 libcfs_sock_release (struct socket *sock)
1346 CFS_DECL_FUNNEL_DATA;
1348 soshutdown(sock, 0);