1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * libcfs/libcfs/darwin/darwin-tcpip.c
38 * Darwin porting library
39 * Make things easy to port
41 * Author: Phil Schwan <phil@clusterfs.com>
44 #include <mach/mach_types.h>
46 #include <sys/mount.h>
48 #include <netinet/in.h>
49 #include <netinet/tcp.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sockio.h>
53 #include <sys/protosw.h>
56 #define DEBUG_SUBSYSTEM S_LNET
58 #include <libcfs/libcfs.h>
60 static __inline__ struct sockaddr_in
63 struct sockaddr_in blank = { sizeof(struct sockaddr_in), AF_INET };
68 libcfs_ipif_free_enumeration (char **names, int n)
74 for (i = 0; i < n && names[i] != NULL; i++)
75 LIBCFS_FREE(names[i], IFNAMSIZ);
77 LIBCFS_FREE(names, n * sizeof(*names));
84 * No hack kernel structre, all using KPI.
88 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
96 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
99 CERROR ("Can't create socket: %d\n", rc);
103 nob = strnlen(name, IFNAMSIZ);
104 if (nob == IFNAMSIZ) {
105 CERROR("Interface name %s too long\n", name);
110 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
111 bzero(&ifr, sizeof(ifr));
112 strcpy(ifr.ifr_name, name);
113 rc = -sock_ioctl (so, SIOCGIFFLAGS, &ifr);
116 CERROR("Can't get flags for interface %s\n", name);
120 if ((ifr.ifr_flags & IFF_UP) == 0) {
121 CDEBUG(D_NET, "Interface %s down\n", name);
129 bzero(&ifr, sizeof(ifr));
130 strcpy(ifr.ifr_name, name);
131 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
132 rc = -sock_ioctl(so, SIOCGIFADDR, &ifr);
135 CERROR("Can't get IP address for interface %s\n", name);
139 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
142 bzero(&ifr, sizeof(ifr));
143 strcpy(ifr.ifr_name, name);
144 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
145 rc = -sock_ioctl(so, SIOCGIFNETMASK, &ifr);
148 CERROR("Can't get netmask for interface %s\n", name);
152 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
160 libcfs_ipif_enumerate (char ***namesp)
162 /* Allocate and fill in 'names', returning # interfaces/error */
174 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
177 CERROR ("Can't create socket: %d\n", rc);
181 nalloc = 16; /* first guess at max interfaces */
184 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
186 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
187 CWARN("Too many interfaces: only enumerating first %d\n",
191 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
193 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
198 ifc.ifc_buf = (char *)ifr;
199 ifc.ifc_len = nalloc * sizeof(*ifr);
204 * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in
205 * kernel space because it always try to copy result to userspace.
206 * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...).
207 * I've created a bug for Apple, let's wait...
210 for (i = 0; i < 16; i++) {
212 bzero(&en, sizeof(en));
213 snprintf(en.ifr_name, IFNAMSIZ, "en%d", i);
214 rc = -sock_ioctl (so, SIOCGIFFLAGS, &en);
217 strcpy(ifr[nfound++].ifr_name, en.ifr_name);
220 #else /* NOT in using now */
221 rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc);
224 CERROR ("Error %d enumerating interfaces\n", rc);
228 nfound = ifc.ifc_len/sizeof(*ifr);
229 LASSERT (nfound <= nalloc);
232 if (nfound < nalloc || toobig)
235 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
241 LIBCFS_ALLOC(names, nfound * sizeof(*names));
246 /* NULL out all names[i] */
247 memset (names, 0, nfound * sizeof(*names));
249 for (i = 0; i < nfound; i++) {
251 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
252 if (nob == IFNAMSIZ) {
253 /* no space for terminating NULL */
254 CERROR("interface name %.*s too long (%d max)\n",
255 nob, ifr[i].ifr_name, IFNAMSIZ);
260 LIBCFS_ALLOC(names[i], IFNAMSIZ);
261 if (names[i] == NULL) {
266 memcpy(names[i], ifr[i].ifr_name, nob);
275 libcfs_ipif_free_enumeration(names, nfound);
277 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
285 * Public entry of socket upcall.
287 * so_upcall can only be installed while create/accept of socket in
288 * Darwin 8.0, so we setup libcfs_sock_upcall() as upcall for all
289 * sockets in creat/accept, it will call upcall provided by user
290 * which can be setup after create/accept of socket.
292 static void libcfs_sock_upcall(socket_t so, void* arg, int waitf)
296 sock = (cfs_socket_t *)arg;
297 LASSERT(sock->s_magic == CFS_SOCK_MAGIC);
299 if ((sock->s_flags & CFS_SOCK_UPCALL) != 0 && sock->s_upcall != NULL)
300 sock->s_upcall(so, sock->s_upcallarg, waitf);
304 void libcfs_sock_set_cb(cfs_socket_t *sock, so_upcall callback, void *arg)
306 sock->s_upcall = callback;
307 sock->s_upcallarg = arg;
308 sock->s_flags |= CFS_SOCK_UPCALL;
312 void libcfs_sock_reset_cb(cfs_socket_t *sock)
314 sock->s_flags &= ~CFS_SOCK_UPCALL;
315 sock->s_upcall = NULL;
316 sock->s_upcallarg = NULL;
321 libcfs_sock_create (cfs_socket_t **sockp, int *fatal,
322 __u32 local_ip, int local_port)
324 struct sockaddr_in locaddr;
330 /* All errors are fatal except bind failure if the port is in use */
333 sock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
335 CERROR("Can't allocate cfs_socket.\n");
339 sock->s_magic = CFS_SOCK_MAGIC;
341 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
342 libcfs_sock_upcall, sock, &C2B_SOCK(sock));
346 optlen = sizeof(option);
347 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET,
348 SO_REUSEADDR, &option, optlen);
352 /* can't specify a local port without a local IP */
353 LASSERT (local_ip == 0 || local_port != 0);
355 if (local_ip != 0 || local_port != 0) {
356 bzero (&locaddr, sizeof (locaddr));
357 locaddr.sin_len = sizeof(struct sockaddr_in);
358 locaddr.sin_family = AF_INET;
359 locaddr.sin_port = htons (local_port);
360 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) : INADDR_ANY;
361 rc = -sock_bind(C2B_SOCK(sock), (struct sockaddr *)&locaddr);
362 if (rc == -EADDRINUSE) {
363 CDEBUG(D_NET, "Port %d already in use\n", local_port);
368 CERROR("Error trying to bind to port %d: %d\n",
375 if (C2B_SOCK(sock) != NULL)
376 sock_close(C2B_SOCK(sock));
382 libcfs_sock_listen (cfs_socket_t **sockp,
383 __u32 local_ip, int local_port, int backlog)
389 rc = libcfs_sock_create(&sock, &fatal, local_ip, local_port);
392 CERROR("Can't create socket: port %d already in use\n",
397 rc = -sock_listen(C2B_SOCK(sock), backlog);
403 if (C2B_SOCK(sock) != NULL)
404 sock_close(C2B_SOCK(sock));
410 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
412 cfs_socket_t *newsock;
415 newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
417 CERROR("Can't allocate cfs_socket.\n");
420 newsock->s_magic = CFS_SOCK_MAGIC;
422 * thread will sleep in sock_accept by calling of msleep(),
423 * it can be interrupted because msleep() use PCATCH as argument.
425 rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0,
426 libcfs_sock_upcall, newsock, &C2B_SOCK(newsock));
428 if (C2B_SOCK(newsock) != NULL)
429 sock_close(C2B_SOCK(newsock));
430 FREE(newsock, M_TEMP);
431 if ((sock->s_flags & CFS_SOCK_DOWN) != 0)
432 /* shutdown by libcfs_sock_abort_accept(), fake
433 * error number for lnet_acceptor() */
442 libcfs_sock_abort_accept (cfs_socket_t *sock)
447 * we want to wakeup thread blocked by sock_accept, but we don't
448 * know the address where thread is sleeping on, so we cannot
449 * wakeup it directly.
450 * The thread slept in sock_accept will be waken up while:
451 * 1. interrupt by signal
452 * 2. new connection is coming (sonewconn)
453 * 3. disconnecting of the socket (soisconnected)
455 * Cause we can't send signal to a thread directly(no KPI), so the
456 * only thing can be done here is disconnect the socket (by
457 * sock_shutdown() or sth else? ).
459 * Shutdown request of socket with SHUT_WR or SHUT_RDWR will
460 * be issured to the protocol.
461 * sock_shutdown()->tcp_usr_shutdown()->tcp_usrclosed()->
462 * tcp_close()->soisdisconnected(), it will wakeup thread by
463 * wakeup((caddr_t)&so->so_timeo);
465 sock->s_flags |= CFS_SOCK_DOWN;
466 sock_shutdown(C2B_SOCK(sock), SHUT_RDWR);
470 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
474 cfs_duration_t to = cfs_time_seconds(timeout);
485 struct msghdr msg = {
494 cfs_duration_usec(to, &tv);
495 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_RCVTIMEO,
498 CERROR("Can't set socket recv timeout "
500 (long)tv.tv_sec, (int)tv.tv_usec, rc);
504 then = cfs_time_current();
505 rc = -sock_receive(C2B_SOCK(sock), &msg, 0, &rcvlen);
506 to -= cfs_time_current() - then;
508 if (rc != 0 && rc != -EWOULDBLOCK)
516 buffer = ((char *)buffer) + rcvlen;
523 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
527 cfs_duration_t to = cfs_time_seconds(timeout);
538 struct msghdr msg = {
545 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0,
549 cfs_duration_usec(to, &tv);
550 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDTIMEO,
553 CERROR("Can't set socket send timeout "
555 (long)tv.tv_sec, (int)tv.tv_usec, rc);
560 then = cfs_time_current();
561 rc = -sock_send(C2B_SOCK(sock), &msg,
562 ((timeout == 0) ? MSG_DONTWAIT : 0), &sndlen);
563 to -= cfs_time_current() - then;
565 if (rc != 0 && rc != -EWOULDBLOCK)
572 buffer = ((char *)buffer) + sndlen;
580 libcfs_sock_getaddr (cfs_socket_t *sock, int remote, __u32 *ip, int *port)
582 struct sockaddr_in sin;
586 /* Get remote address */
587 rc = -sock_getpeername(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
589 /* Get local address */
590 rc = -sock_getsockname(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
592 CERROR ("Error %d getting sock %s IP/port\n",
593 rc, remote ? "peer" : "local");
598 *ip = ntohl (sin.sin_addr.s_addr);
601 *port = ntohs (sin.sin_port);
606 libcfs_sock_setbuf (cfs_socket_t *sock, int txbufsize, int rxbufsize)
611 if (txbufsize != 0) {
613 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
614 (char *)&option, sizeof (option));
616 CERROR ("Can't set send buffer %d: %d\n",
622 if (rxbufsize != 0) {
624 rc = -sock_setsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
625 (char *)&option, sizeof (option));
627 CERROR ("Can't set receive buffer %d: %d\n",
636 libcfs_sock_getbuf (cfs_socket_t *sock, int *txbufsize, int *rxbufsize)
642 if (txbufsize != NULL) {
643 optlen = sizeof(option);
644 rc = -sock_getsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
645 (char *)&option, &optlen);
647 CERROR ("Can't get send buffer size: %d\n", rc);
653 if (rxbufsize != NULL) {
654 optlen = sizeof(option);
655 rc = -sock_getsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
656 (char *)&option, &optlen);
658 CERROR ("Can't get receive buffer size: %d\n", rc);
667 libcfs_sock_release (cfs_socket_t *sock)
669 if (C2B_SOCK(sock) != NULL) {
670 sock_shutdown(C2B_SOCK(sock), 2);
671 sock_close(C2B_SOCK(sock));
677 libcfs_sock_connect (cfs_socket_t **sockp, int *fatal,
678 __u32 local_ip, int local_port,
679 __u32 peer_ip, int peer_port)
682 struct sockaddr_in srvaddr;
685 rc = libcfs_sock_create(&sock, fatal, local_ip, local_port);
689 bzero(&srvaddr, sizeof(srvaddr));
690 srvaddr.sin_len = sizeof(struct sockaddr_in);
691 srvaddr.sin_family = AF_INET;
692 srvaddr.sin_port = htons(peer_port);
693 srvaddr.sin_addr.s_addr = htonl(peer_ip);
695 rc = -sock_connect(C2B_SOCK(sock), (struct sockaddr *)&srvaddr, 0);
701 *fatal = !(rc == -EADDRNOTAVAIL || rc == -EADDRINUSE);
702 CDEBUG(*fatal ? D_NETERROR : D_NET,
703 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
704 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
706 libcfs_sock_release(sock);
710 #else /* !__DARWIN8__ */
713 * To use bigger buffer for socket:
714 * 1. Increase nmbclusters (Cannot increased by sysctl because it's ready only, so
715 * we must patch kernel).
716 * 2. Increase net.inet.tcp.reass.maxsegments
717 * 3. Increase net.inet.tcp.sendspace
718 * 4. Increase net.inet.tcp.recvspace
719 * 5. Increase kern.ipc.maxsockbuf
721 #define KSOCK_MAX_BUF (1152*1024)
724 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
731 CFS_DECL_FUNNEL_DATA;
734 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
737 CERROR ("Can't create socket: %d\n", rc);
740 nob = strnlen(name, IFNAMSIZ);
741 if (nob == IFNAMSIZ) {
742 CERROR("Interface name %s too long\n", name);
747 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
748 strcpy(ifr.ifr_name, name);
750 rc = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ifr, current_proc());
754 CERROR("Can't get flags for interface %s\n", name);
757 if ((ifr.ifr_flags & IFF_UP) == 0) {
758 CDEBUG(D_NET, "Interface %s down\n", name);
765 strcpy(ifr.ifr_name, name);
766 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
768 rc = ifioctl(so, SIOCGIFADDR, (caddr_t)&ifr, current_proc());
772 CERROR("Can't get IP address for interface %s\n", name);
776 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
779 strcpy(ifr.ifr_name, name);
780 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
782 rc = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ifr, current_proc());
786 CERROR("Can't get netmask for interface %s\n", name);
790 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
800 libcfs_ipif_enumerate (char ***namesp)
802 /* Allocate and fill in 'names', returning # interfaces/error */
813 CFS_DECL_FUNNEL_DATA;
816 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
819 CERROR ("Can't create socket: %d\n", rc);
823 nalloc = 16; /* first guess at max interfaces */
826 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
828 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
829 CWARN("Too many interfaces: only enumerating first %d\n",
833 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
835 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
840 ifc.ifc_buf = (char *)ifr;
841 ifc.ifc_len = nalloc * sizeof(*ifr);
844 rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc());
848 CERROR ("Error %d enumerating interfaces\n", rc);
852 nfound = ifc.ifc_len/sizeof(*ifr);
853 LASSERT (nfound <= nalloc);
855 if (nfound < nalloc || toobig)
858 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
864 LIBCFS_ALLOC(names, nfound * sizeof(*names));
869 /* NULL out all names[i] */
870 memset (names, 0, nfound * sizeof(*names));
872 for (i = 0; i < nfound; i++) {
874 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
875 if (nob == IFNAMSIZ) {
876 /* no space for terminating NULL */
877 CERROR("interface name %.*s too long (%d max)\n",
878 nob, ifr[i].ifr_name, IFNAMSIZ);
883 LIBCFS_ALLOC(names[i], IFNAMSIZ);
884 if (names[i] == NULL) {
889 memcpy(names[i], ifr[i].ifr_name, nob);
898 libcfs_ipif_free_enumeration(names, nfound);
900 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
909 libcfs_sock_create (struct socket **sockp, int *fatal,
910 __u32 local_ip, int local_port)
912 struct sockaddr_in locaddr;
917 CFS_DECL_FUNNEL_DATA;
921 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
924 CERROR ("Can't create socket: %d\n", rc);
928 bzero(&sopt, sizeof sopt);
930 sopt.sopt_level = SOL_SOCKET;
931 sopt.sopt_name = SO_REUSEADDR;
932 sopt.sopt_val = &option;
933 sopt.sopt_valsize = sizeof(option);
935 rc = sosetopt(so, &sopt);
938 CERROR ("Can't set sock reuse address: %d\n", rc);
941 /* can't specify a local port without a local IP */
942 LASSERT (local_ip == 0 || local_port != 0);
944 if (local_ip != 0 || local_port != 0) {
945 bzero (&locaddr, sizeof (locaddr));
946 locaddr.sin_len = sizeof(struct sockaddr_in);
947 locaddr.sin_family = AF_INET;
948 locaddr.sin_port = htons (local_port);
949 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) :
952 rc = sobind(so, (struct sockaddr *)&locaddr);
953 if (rc == EADDRINUSE) {
955 CDEBUG(D_NET, "Port %d already in use\n", local_port);
961 CERROR ("Can't bind to local IP Address %u.%u.%u.%u: %d\n",
962 HIPQUAD(local_ip), rc);
976 libcfs_sock_listen (struct socket **sockp,
977 __u32 local_ip, int local_port, int backlog)
981 CFS_DECL_FUNNEL_DATA;
983 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
986 CERROR("Can't create socket: port %d already in use\n",
991 rc = solisten(*sockp, backlog);
995 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
1003 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
1006 struct sockaddr *sa;
1008 CFS_DECL_FUNNEL_DATA;
1012 if ((sock->so_options & SO_ACCEPTCONN) == 0) {
1018 if ((sock->so_state & SS_NBIO) && sock->so_comp.tqh_first == NULL) {
1021 return (-EWOULDBLOCK);
1025 while (TAILQ_EMPTY(&sock->so_comp) && sock->so_error == 0) {
1026 if (sock->so_state & SS_CANTRCVMORE) {
1027 sock->so_error = ECONNABORTED;
1030 error = tsleep((caddr_t)&sock->so_timeo, PSOCK | PCATCH,
1038 if (sock->so_error) {
1039 error = sock->so_error;
1047 * At this point we know that there is at least one connection
1048 * ready to be accepted. Remove it from the queue prior to
1049 * allocating the file descriptor for it since falloc() may
1050 * block allowing another process to accept the connection
1053 so = TAILQ_FIRST(&sock->so_comp);
1054 TAILQ_REMOVE(&sock->so_comp, so, so_list);
1057 so->so_state &= ~SS_COMP;
1060 (void) soaccept(so, &sa);
1070 libcfs_sock_abort_accept (struct socket *sock)
1072 wakeup(&sock->so_timeo);
1076 * XXX Liang: timeout for write is not supported yet.
1079 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
1085 struct iovec iov = {
1094 .uio_segflg = UIO_SYSSPACE,
1095 .uio_rw = UIO_WRITE,
1100 rc = sosend(sock, NULL, &suio, (struct mbuf *)0, (struct mbuf *)0, 0);
1104 if ( suio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1109 rc = nob - suio.uio_resid;
1110 buffer = ((char *)buffer) + rc;
1111 nob = suio.uio_resid;
1120 * XXX Liang: timeout for read is not supported yet.
1123 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
1129 struct iovec iov = {
1138 .uio_segflg = UIO_SYSSPACE,
1144 rc = soreceive(sock, (struct sockaddr **)0, &ruio, (struct mbuf **)0, (struct mbuf **)0, (int *)0);
1148 if ( ruio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1153 rc = nob - ruio.uio_resid;
1154 buffer = ((char *)buffer) + rc;
1155 nob = ruio.uio_resid;
1164 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
1166 struct sockopt sopt;
1171 bzero(&sopt, sizeof sopt);
1172 sopt.sopt_dir = SOPT_SET;
1173 sopt.sopt_level = SOL_SOCKET;
1174 sopt.sopt_val = &option;
1175 sopt.sopt_valsize = sizeof(option);
1177 if (txbufsize != 0) {
1179 if (option > KSOCK_MAX_BUF)
1180 option = KSOCK_MAX_BUF;
1182 sopt.sopt_name = SO_SNDBUF;
1184 rc = sosetopt(sock, &sopt);
1187 CERROR ("Can't set send buffer %d: %d\n",
1194 if (rxbufsize != 0) {
1196 sopt.sopt_name = SO_RCVBUF;
1198 rc = sosetopt(sock, &sopt);
1201 CERROR ("Can't set receive buffer %d: %d\n",
1210 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
1212 struct sockaddr_in *sin;
1213 struct sockaddr *sa = NULL;
1219 rc = sock->so_proto->pr_usrreqs->pru_peeraddr(sock, &sa);
1223 if (sa) FREE(sa, M_SONAME);
1224 CERROR ("Error %d getting sock peer IP\n", rc);
1229 rc = sock->so_proto->pr_usrreqs->pru_sockaddr(sock, &sa);
1232 if (sa) FREE(sa, M_SONAME);
1233 CERROR ("Error %d getting sock local IP\n", rc);
1238 sin = (struct sockaddr_in *)sa;
1240 *ip = ntohl (sin->sin_addr.s_addr);
1242 *port = ntohs (sin->sin_port);
1250 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
1252 struct sockopt sopt;
1256 bzero(&sopt, sizeof sopt);
1257 sopt.sopt_dir = SOPT_GET;
1258 sopt.sopt_level = SOL_SOCKET;
1260 if (txbufsize != NULL) {
1261 sopt.sopt_val = txbufsize;
1262 sopt.sopt_valsize = sizeof(*txbufsize);
1263 sopt.sopt_name = SO_SNDBUF;
1265 rc = sogetopt(sock, &sopt);
1268 CERROR ("Can't get send buffer size: %d\n", rc);
1273 if (rxbufsize != NULL) {
1274 sopt.sopt_val = rxbufsize;
1275 sopt.sopt_valsize = sizeof(*rxbufsize);
1276 sopt.sopt_name = SO_RCVBUF;
1278 rc = sogetopt(sock, &sopt);
1281 CERROR ("Can't get receive buffer size: %d\n", rc);
1289 libcfs_sock_connect (struct socket **sockp, int *fatal,
1290 __u32 local_ip, int local_port,
1291 __u32 peer_ip, int peer_port)
1293 struct sockaddr_in srvaddr;
1297 CFS_DECL_FUNNEL_DATA;
1299 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
1303 bzero(&srvaddr, sizeof(srvaddr));
1304 srvaddr.sin_len = sizeof(struct sockaddr_in);
1305 srvaddr.sin_family = AF_INET;
1306 srvaddr.sin_port = htons (peer_port);
1307 srvaddr.sin_addr.s_addr = htonl (peer_ip);
1310 rc = soconnect(so, (struct sockaddr *)&srvaddr);
1313 if (rc != EADDRNOTAVAIL && rc != EADDRINUSE)
1315 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1316 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1320 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
1321 CDEBUG(D_NET, "ksocknal sleep for waiting auto_connect.\n");
1322 (void) tsleep((caddr_t)&so->so_timeo, PSOCK, "ksocknal_conn", hz);
1324 if ((rc = so->so_error) != 0) {
1329 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1330 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1333 LASSERT(so->so_state & SS_ISCONNECTED);
1348 libcfs_sock_release (struct socket *sock)
1350 CFS_DECL_FUNNEL_DATA;
1352 soshutdown(sock, 0);