Whamcloud - gitweb
LU-1187 tests: add create remote directory to racer
[fs/lustre-release.git] / libcfs / libcfs / user-tcpip.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #if !defined(__KERNEL__) || !defined(REDSTORM)
36
37 #include <libcfs/libcfs.h>
38
39 #include <sys/socket.h>
40 #ifdef  HAVE_NETINET_IN_H
41 #include <netinet/in.h>
42 #endif
43 #include <netinet/tcp.h>
44 #include <sys/ioctl.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <poll.h>
49 #include <net/if.h>
50 #include <arpa/inet.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #if defined(__sun__) || defined(__sun)
54 #include <sys/sockio.h>
55 #endif
56 #ifndef __CYGWIN__
57 #include <sys/syscall.h>
58 #endif
59
60 /*
61  * Functions to get network interfaces info
62  */
63
64 int
65 libcfs_sock_ioctl(int cmd, unsigned long arg)
66 {
67         int fd, rc;
68
69         fd = socket(AF_INET, SOCK_STREAM, 0);
70
71         if (fd < 0) {
72                 rc = -errno;
73                 CERROR("socket() failed: errno==%d\n", errno);
74                 return rc;
75         }
76
77         rc = ioctl(fd, cmd, arg);
78
79         close(fd);
80         return rc;
81 }
82
83 int
84 libcfs_ipif_query (char *name, int *up, __u32 *ip)
85 {
86         struct ifreq   ifr;
87         int            nob;
88         int            rc;
89         __u32          val;
90
91         nob = strlen(name);
92         if (nob >= IFNAMSIZ) {
93                 CERROR("Interface name %s too long\n", name);
94                 return -EINVAL;
95         }
96
97         CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
98
99         strcpy(ifr.ifr_name, name);
100         rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
101
102         if (rc != 0) {
103                 CERROR("Can't get flags for interface %s\n", name);
104                 return rc;
105         }
106
107         if ((ifr.ifr_flags & IFF_UP) == 0) {
108                 CDEBUG(D_NET, "Interface %s down\n", name);
109                 *up = 0;
110                 *ip = 0;
111                 return 0;
112         }
113
114         *up = 1;
115
116         strcpy(ifr.ifr_name, name);
117         ifr.ifr_addr.sa_family = AF_INET;
118         rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
119
120         if (rc != 0) {
121                 CERROR("Can't get IP address for interface %s\n", name);
122                 return rc;
123         }
124
125         val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
126         *ip = ntohl(val);
127
128         return 0;
129 }
130
131 void
132 libcfs_ipif_free_enumeration (char **names, int n)
133 {
134         int      i;
135
136         LASSERT (n > 0);
137
138         for (i = 0; i < n && names[i] != NULL; i++)
139                 LIBCFS_FREE(names[i], IFNAMSIZ);
140
141         LIBCFS_FREE(names, n * sizeof(*names));
142 }
143
144 int
145 libcfs_ipif_enumerate (char ***namesp)
146 {
147         /* Allocate and fill in 'names', returning # interfaces/error */
148         char          **names;
149         int             nalloc;
150         int             nfound;
151         struct ifreq   *ifr;
152         struct ifconf   ifc;
153         int             rc;
154         int             nob;
155         int             i;
156
157
158         nalloc = 16;        /* first guess at max interfaces */
159         for (;;) {
160                 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
161                 if (ifr == NULL) {
162                         CERROR ("ENOMEM enumerating up to %d interfaces\n",
163                                 nalloc);
164                         rc = -ENOMEM;
165                         goto out0;
166                 }
167
168                 ifc.ifc_buf = (char *)ifr;
169                 ifc.ifc_len = nalloc * sizeof(*ifr);
170
171                 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
172
173                 if (rc < 0) {
174                         CERROR ("Error %d enumerating interfaces\n", rc);
175                         goto out1;
176                 }
177
178                 LASSERT (rc == 0);
179
180                 nfound = ifc.ifc_len/sizeof(*ifr);
181                 LASSERT (nfound <= nalloc);
182
183                 if (nfound < nalloc)
184                         break;
185
186                 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
187                 nalloc *= 2;
188         }
189
190         if (nfound == 0)
191                 goto out1;
192
193         LIBCFS_ALLOC(names, nfound * sizeof(*names));
194         if (names == NULL) {
195                 rc = -ENOMEM;
196                 goto out1;
197         }
198         /* NULL out all names[i] */
199         memset (names, 0, nfound * sizeof(*names));
200
201         for (i = 0; i < nfound; i++) {
202
203                 nob = strlen (ifr[i].ifr_name);
204                 if (nob >= IFNAMSIZ) {
205                         /* no space for terminating NULL */
206                         CERROR("interface name %.*s too long (%d max)\n",
207                                nob, ifr[i].ifr_name, IFNAMSIZ);
208                         rc = -ENAMETOOLONG;
209                         goto out2;
210                 }
211
212                 LIBCFS_ALLOC(names[i], IFNAMSIZ);
213                 if (names[i] == NULL) {
214                         rc = -ENOMEM;
215                         goto out2;
216                 }
217
218                 memcpy(names[i], ifr[i].ifr_name, nob);
219                 names[i][nob] = 0;
220         }
221
222         *namesp = names;
223         rc = nfound;
224
225  out2:
226         if (rc < 0)
227                 libcfs_ipif_free_enumeration(names, nfound);
228  out1:
229         LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
230  out0:
231         return rc;
232 }
233
234 /*
235  * Network functions used by user-land lnet acceptor
236  */
237
238 int
239 libcfs_sock_listen (cfs_socket_t **sockp,
240                     __u32 local_ip, int local_port, int backlog)
241 {
242         int rc;
243         int fatal;
244
245         rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
246         if (rc != 0)
247                 return rc;
248
249         if ( listen((*sockp)->s_fd, backlog) ) {
250                 rc = -errno;
251                 CERROR("listen() with backlog==%d failed: errno==%d\n",
252                        backlog, errno);
253                 goto failed;
254         }
255
256         return 0;
257
258   failed:
259         libcfs_sock_release(*sockp);
260         return rc;
261 }
262
263 void
264 libcfs_sock_release (cfs_socket_t *sock)
265 {
266         close(sock->s_fd);
267         LIBCFS_FREE(sock, sizeof(cfs_socket_t));
268 }
269
270 int
271 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
272 {
273         struct sockaddr_in accaddr;
274         socklen_t          accaddr_len = sizeof(struct sockaddr_in);
275
276         LIBCFS_ALLOC(*newsockp, sizeof(cfs_socket_t));
277         if (*newsockp == NULL) {
278                 CERROR ("Can't alloc memory for cfs_socket_t\n");
279                 return -ENOMEM;
280         }
281
282         (*newsockp)->s_fd = accept(sock->s_fd,
283                                    (struct sockaddr *)&accaddr, &accaddr_len);
284
285         if ( (*newsockp)->s_fd < 0 ) {
286                 int rc = -errno;
287                 CERROR("accept() failed: errno==%d\n", -rc);
288                 LIBCFS_FREE(*newsockp, sizeof(cfs_socket_t));
289                 return rc;
290         }
291
292         return 0;
293 }
294
295 int
296 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
297 {
298         int           rc;
299         struct pollfd pfd;
300         cfs_time_t    start_time = cfs_time_current();
301
302         pfd.fd = sock->s_fd;
303         pfd.events = POLLIN;
304         pfd.revents = 0;
305
306         /* poll(2) measures timeout in msec */
307         timeout *= 1000;
308
309         while (nob != 0 && timeout > 0) {
310                 cfs_time_t current_time;
311
312                 rc = poll(&pfd, 1, timeout);
313                 if (rc < 0)
314                         return -errno;
315                 if (rc == 0)
316                         return -ETIMEDOUT;
317                 if ((pfd.revents & POLLIN) == 0)
318                         return -EIO;
319
320                 rc = read(sock->s_fd, buffer, nob);
321                 if (rc < 0)
322                         return -errno;
323                 if (rc == 0)
324                         return -EIO;
325
326                 buffer = ((char *)buffer) + rc;
327                 nob -= rc;
328
329                 current_time = cfs_time_current();
330                 timeout -= 1000 *
331                         cfs_duration_sec(cfs_time_sub(current_time,
332                                                       start_time));
333                 start_time = current_time;
334         }
335
336         if (nob == 0)
337                 return 0;
338         else
339                 return -ETIMEDOUT;
340 }
341
342 int
343 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
344 {
345         int           rc;
346         struct pollfd pfd;
347         cfs_time_t    start_time = cfs_time_current();
348
349         pfd.fd = sock->s_fd;
350         pfd.events = POLLOUT;
351         pfd.revents = 0;
352
353         /* poll(2) measures timeout in msec */
354         timeout *= 1000;
355
356         while (nob != 0 && timeout > 0) {
357                 cfs_time_t current_time;
358
359                 rc = poll(&pfd, 1, timeout);
360                 if (rc < 0)
361                         return -errno;
362                 if (rc == 0)
363                         return -ETIMEDOUT;
364                 if ((pfd.revents & POLLOUT) == 0)
365                         return -EIO;
366
367                 rc = write(sock->s_fd, buffer, nob);
368                 if (rc < 0)
369                         return -errno;
370                 if (rc == 0)
371                         return -EIO;
372
373                 buffer = ((char *)buffer) + rc;
374                 nob -= rc;
375
376                 current_time = cfs_time_current();
377                 timeout -= 1000 *
378                         cfs_duration_sec(cfs_time_sub(current_time,
379                                                       start_time));
380                 start_time = current_time;
381         }
382
383         if (nob == 0)
384                 return 0;
385         else
386                 return -ETIMEDOUT;
387 }
388
389 /* Just try to connect to localhost to wake up entity that are
390  * sleeping in accept() */
391 void
392 libcfs_sock_abort_accept(cfs_socket_t *sock)
393 {
394         int                fd, rc;
395         struct sockaddr_in remaddr;
396         struct sockaddr_in locaddr;
397         socklen_t          alen = sizeof(struct sockaddr_in);
398
399         rc = getsockname(sock->s_fd, (struct sockaddr *)&remaddr, &alen);
400         if ( rc != 0 ) {
401                 CERROR("getsockname() failed: errno==%d\n", errno);
402                 return;
403         }
404
405         memset(&locaddr, 0, sizeof(locaddr));
406         locaddr.sin_family = AF_INET;
407         locaddr.sin_port = remaddr.sin_port;
408         locaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
409
410         fd = socket(AF_INET, SOCK_STREAM, 0);
411         if ( fd < 0 ) {
412                 CERROR("socket() failed: errno==%d\n", errno);
413                 return;
414         }
415
416         rc = connect(fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
417         if ( rc != 0 ) {
418                 if ( errno != ECONNREFUSED )
419                         CERROR("connect() failed: errno==%d\n", errno);
420                 else
421                         CDEBUG(D_NET, "Nobody to wake up at %d\n",
422                                ntohs(remaddr.sin_port));
423         }
424
425         close(fd);
426 }
427
428 int
429 libcfs_sock_getaddr(cfs_socket_t *sock, int remote, __u32 *ip, int *port)
430 {
431         int                rc;
432         struct sockaddr_in peer_addr;
433         socklen_t          peer_addr_len = sizeof(peer_addr);
434
435         LASSERT(remote == 1);
436
437         rc = getpeername(sock->s_fd,
438                          (struct sockaddr *)&peer_addr, &peer_addr_len);
439         if (rc != 0)
440                 return -errno;
441
442         if (ip != NULL)
443                 *ip = ntohl(peer_addr.sin_addr.s_addr);
444         if (port != NULL)
445                 *port = ntohs(peer_addr.sin_port);
446
447         return rc;
448 }
449
450 /*
451  * Network functions of common use
452  */
453
454 int
455 libcfs_socketpair(cfs_socket_t **sockp)
456 {
457         int rc, i, fdp[2];
458
459         LIBCFS_ALLOC(sockp[0], sizeof(cfs_socket_t));
460         if (sockp[0] == NULL) {
461                 CERROR ("Can't alloc memory for cfs_socket_t (1)\n");
462                 return -ENOMEM;
463         }
464
465         LIBCFS_ALLOC(sockp[1], sizeof(cfs_socket_t));
466         if (sockp[1] == NULL) {
467                 CERROR ("Can't alloc memory for cfs_socket_t (2)\n");
468                 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
469                 return -ENOMEM;
470         }
471
472         rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fdp);
473         if (rc != 0) {
474                 rc = -errno;
475                 CERROR ("Cannot create socket pair\n");
476                 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
477                 LIBCFS_FREE(sockp[1], sizeof(cfs_socket_t));
478                 return rc;
479         }
480
481         sockp[0]->s_fd = fdp[0];
482         sockp[1]->s_fd = fdp[1];
483
484         for (i = 0; i < 2; i++) {
485                 rc = libcfs_fcntl_nonblock(sockp[i]);
486                 if (rc) {
487                         libcfs_sock_release(sockp[0]);
488                         libcfs_sock_release(sockp[1]);
489                         return rc;
490                 }
491         }
492
493         return 0;
494 }
495
496 int
497 libcfs_fcntl_nonblock(cfs_socket_t *sock)
498 {
499         int rc, flags;
500
501         flags = fcntl(sock->s_fd, F_GETFL, 0);
502         if (flags == -1) {
503                 rc = -errno;
504                 CERROR ("Cannot get socket flags\n");
505                 return rc;
506         }
507
508         rc = fcntl(sock->s_fd, F_SETFL, flags | O_NONBLOCK);
509         if (rc != 0) {
510                 rc = -errno;
511                 CERROR ("Cannot set socket flags\n");
512                 return rc;
513         }
514
515         return 0;
516 }
517
518 int
519 libcfs_sock_set_nagle(cfs_socket_t *sock, int nagle)
520 {
521         int rc;
522         int option = nagle ? 0 : 1;
523
524 #if defined(__sun__) || defined(__sun)
525         rc = setsockopt(sock->s_fd,
526                         IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option));
527 #else
528         rc = setsockopt(sock->s_fd,
529                         SOL_TCP, TCP_NODELAY, &option, sizeof(option));
530 #endif
531
532         if (rc != 0) {
533                 rc = -errno;
534                 CERROR ("Cannot set NODELAY socket option\n");
535                 return rc;
536         }
537
538         return 0;
539 }
540
541 int
542 libcfs_sock_set_bufsiz(cfs_socket_t *sock, int bufsiz)
543 {
544         int rc, option;
545
546         LASSERT (bufsiz != 0);
547
548         option = bufsiz;
549         rc = setsockopt(sock->s_fd,
550                         SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
551         if (rc != 0) {
552                 rc = -errno;
553                 CERROR ("Cannot set SNDBUF socket option\n");
554                 return rc;
555         }
556
557         option = bufsiz;
558         rc = setsockopt(sock->s_fd,
559                         SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
560         if (rc != 0) {
561                 rc = -errno;
562                 CERROR ("Cannot set RCVBUF socket option\n");
563                 return rc;
564         }
565
566         return 0;
567 }
568
569 int
570 libcfs_sock_bind(cfs_socket_t *sock, __u32 ip, __u16 port)
571 {
572         int                rc;
573         struct sockaddr_in locaddr;
574
575         if (ip == 0 && port == 0)
576                 return 0;
577
578         memset(&locaddr, 0, sizeof(locaddr));
579         locaddr.sin_family = AF_INET;
580         locaddr.sin_addr.s_addr = (ip == 0) ? INADDR_ANY : htonl(ip);
581         locaddr.sin_port = htons(port);
582
583         rc = bind(sock->s_fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
584         if (rc != 0) {
585                 rc = -errno;
586                 CERROR("Cannot bind to %d.%d.%d.%d %d: %d\n",
587                        HIPQUAD(ip), port, rc);
588                 return rc;
589         }
590
591         return 0;
592 }
593
594 int
595 libcfs_sock_create(cfs_socket_t **sockp, int *fatal,
596                    __u32 local_ip, int local_port)
597 {
598         int rc, fd, option;
599
600         *fatal = 1;
601
602         LIBCFS_ALLOC(*sockp, sizeof(cfs_socket_t));
603         if (*sockp == NULL) {
604                 CERROR("Can't alloc memory for cfs_socket_t\n");
605                 return -ENOMEM;
606         }
607
608         fd = socket(AF_INET, SOCK_STREAM, 0);
609         if (fd < 0) {
610                 rc = -errno;
611                 CERROR("Cannot create socket: %d\n", rc);
612                 LIBCFS_FREE(*sockp, sizeof(cfs_socket_t));
613                 return rc;
614         }
615
616         (*sockp)->s_fd = fd;
617
618         option = 1;
619         rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
620                         &option, sizeof(option));
621         if (rc != 0) {
622                 rc = -errno;
623                 CERROR("Cannot set SO_REUSEADDR for socket: %d\n", rc);
624                 libcfs_sock_release(*sockp);
625                 return rc;
626         }
627
628         rc = libcfs_sock_bind(*sockp, local_ip, local_port);
629         if (rc != 0) {
630                 *fatal = 0;
631                 libcfs_sock_release(*sockp);
632         }
633
634         return rc;
635 }
636
637 int
638 libcfs_sock_connect(cfs_socket_t *sock, __u32 ip, __u16 port)
639 {
640         int                rc;
641         struct sockaddr_in addr;
642
643         memset(&addr, 0, sizeof(addr));
644         addr.sin_family      = AF_INET;
645         addr.sin_addr.s_addr = htonl(ip);
646         addr.sin_port        = htons(port);
647
648         rc = connect(sock->s_fd, (struct sockaddr *)&addr,
649                      sizeof(struct sockaddr_in));
650
651         if(rc != 0 && errno != EINPROGRESS) {
652                 rc = -errno;
653                 if (rc != -EADDRINUSE && rc != -EADDRNOTAVAIL)
654                         CERROR ("Cannot connect to %u.%u.%u.%u:%d (err=%d)\n",
655                                 HIPQUAD(ip), port, errno);
656                 return rc;
657         }
658
659         return 0;
660 }
661
662 /* NB: EPIPE and ECONNRESET are considered as non-fatal
663  * because:
664  * 1) it still makes sense to continue reading &&
665  * 2) anyway, poll() will set up POLLHUP|POLLERR flags */
666 int
667 libcfs_sock_writev(cfs_socket_t *sock, const struct iovec *vector, int count)
668 {
669         int rc;
670
671         rc = syscall(SYS_writev, sock->s_fd, vector, count);
672
673         if (rc == 0) /* write nothing */
674                 return 0;
675
676         if (rc < 0) {
677                 if (errno == EAGAIN ||   /* write nothing   */
678                     errno == EPIPE ||    /* non-fatal error */
679                     errno == ECONNRESET) /* non-fatal error */
680                         return 0;
681                 else
682                         return -errno;
683         }
684
685         return rc;
686 }
687
688 int
689 libcfs_sock_readv(cfs_socket_t *sock, const struct iovec *vector, int count)
690 {
691         int rc;
692
693         rc = syscall(SYS_readv, sock->s_fd, vector, count);
694
695         if (rc == 0) /* EOF */
696                 return -EIO;
697
698         if (rc < 0) {
699                 if (errno == EAGAIN) /* read nothing */
700                         return 0;
701                 else
702                         return -errno;
703         }
704
705         return rc;
706 }
707
708 #endif /* !__KERNEL__ || !defined(REDSTORM) */