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.
37 #define DEBUG_SUBSYSTEM S_LNET
38 #include <lnet/lib-lnet.h>
41 static char *accept = "secure";
42 CFS_MODULE_PARM(accept, "s", charp, 0444,
43 "Accept connections (secure|all|none)");
45 static int accept_port = 988;
46 CFS_MODULE_PARM(accept_port, "i", int, 0444,
47 "Acceptor's port (same on all nodes)");
49 static int accept_backlog = 127;
50 CFS_MODULE_PARM(accept_backlog, "i", int, 0444,
51 "Acceptor's listen backlog");
53 static int accept_timeout = 5;
54 CFS_MODULE_PARM(accept_timeout, "i", int, 0644,
55 "Acceptor's timeout (seconds)");
59 cfs_socket_t *pta_sock;
60 struct semaphore pta_signal;
61 } lnet_acceptor_state;
64 lnet_acceptor_timeout(void)
66 return accept_timeout;
68 EXPORT_SYMBOL(lnet_acceptor_timeout);
71 lnet_acceptor_port(void)
75 EXPORT_SYMBOL(lnet_acceptor_port);
78 lnet_connect_console_error (int rc, lnet_nid_t peer_nid,
79 __u32 peer_ip, int peer_port)
84 CNETERR("Connection to %s at host %u.%u.%u.%u on port %d was "
85 "refused: check that Lustre is running on that node.\n",
86 libcfs_nid2str(peer_nid),
87 HIPQUAD(peer_ip), peer_port);
91 CNETERR("Connection to %s at host %u.%u.%u.%u "
92 "was unreachable: the network or that node may "
93 "be down, or Lustre may be misconfigured.\n",
94 libcfs_nid2str(peer_nid), HIPQUAD(peer_ip));
97 CNETERR("Connection to %s at host %u.%u.%u.%u on "
98 "port %d took too long: that node may be hung "
99 "or experiencing high load.\n",
100 libcfs_nid2str(peer_nid),
101 HIPQUAD(peer_ip), peer_port);
104 LCONSOLE_ERROR_MSG(0x11b, "Connection to %s at host %u.%u.%u.%u"
105 " on port %d was reset: "
106 "is it running a compatible version of "
107 "Lustre and is %s one of its NIDs?\n",
108 libcfs_nid2str(peer_nid),
109 HIPQUAD(peer_ip), peer_port,
110 libcfs_nid2str(peer_nid));
113 LCONSOLE_ERROR_MSG(0x11c, "Protocol error connecting to %s at "
114 "host %u.%u.%u.%u on port %d: is it running "
115 "a compatible version of Lustre?\n",
116 libcfs_nid2str(peer_nid),
117 HIPQUAD(peer_ip), peer_port);
120 LCONSOLE_ERROR_MSG(0x11d, "No privileged ports available to "
121 "connect to %s at host %u.%u.%u.%u on port "
122 "%d\n", libcfs_nid2str(peer_nid),
123 HIPQUAD(peer_ip), peer_port);
126 LCONSOLE_ERROR_MSG(0x11e, "Unexpected error %d connecting to %s"
127 " at host %u.%u.%u.%u on port %d\n", rc,
128 libcfs_nid2str(peer_nid),
129 HIPQUAD(peer_ip), peer_port);
133 EXPORT_SYMBOL(lnet_connect_console_error);
136 lnet_connect(cfs_socket_t **sockp, lnet_nid_t peer_nid,
137 __u32 local_ip, __u32 peer_ip, int peer_port)
139 lnet_acceptor_connreq_t cr;
145 CLASSERT (sizeof(cr) <= 16); /* not too big to be on the stack */
147 for (port = LNET_ACCEPTOR_MAX_RESERVED_PORT;
148 port >= LNET_ACCEPTOR_MIN_RESERVED_PORT;
150 /* Iterate through reserved ports. */
152 rc = libcfs_sock_connect(&sock, &fatal,
161 CLASSERT (LNET_PROTO_ACCEPTOR_VERSION == 1);
163 if (the_lnet.ln_ptlcompat != 2) {
164 /* When portals compatibility is "strong", simply
165 * connect (i.e. send no acceptor connection request).
166 * Othewise send an acceptor connection request. I can
167 * have no portals peers so everyone else should
168 * understand my protocol. */
169 cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
170 cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
171 cr.acr_nid = peer_nid;
173 if (the_lnet.ln_testprotocompat != 0) {
174 /* single-shot proto check */
176 if ((the_lnet.ln_testprotocompat & 4) != 0) {
178 the_lnet.ln_testprotocompat &= ~4;
180 if ((the_lnet.ln_testprotocompat & 8) != 0) {
181 cr.acr_magic = LNET_PROTO_MAGIC;
182 the_lnet.ln_testprotocompat &= ~8;
187 rc = libcfs_sock_write(sock, &cr, sizeof(cr),
201 libcfs_sock_release(sock);
203 lnet_connect_console_error(rc, peer_nid, peer_ip, peer_port);
206 EXPORT_SYMBOL(lnet_connect);
209 lnet_accept_magic(__u32 magic, __u32 constant)
211 return (magic == constant ||
212 magic == __swab32(constant));
216 lnet_accept(lnet_ni_t *blind_ni, cfs_socket_t *sock, __u32 magic)
218 lnet_acceptor_connreq_t cr;
226 /* CAVEAT EMPTOR: I may be called by an LND in any thread's context if
227 * I passed the new socket "blindly" to the single NI that needed an
228 * acceptor. If so, blind_ni != NULL... */
230 LASSERT (sizeof(cr) <= 16); /* not too big for the stack */
232 rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port);
233 LASSERT (rc == 0); /* we succeeded before */
235 if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) {
237 if (lnet_accept_magic(magic, LNET_PROTO_MAGIC)) {
238 /* future version compatibility!
239 * When LNET unifies protocols over all LNDs, the first
240 * thing sent will be a version query. I send back
241 * LNET_PROTO_ACCEPTOR_MAGIC to tell her I'm "old" */
243 memset (&cr, 0, sizeof(cr));
244 cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
245 cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
246 rc = libcfs_sock_write(sock, &cr, sizeof(cr),
250 CERROR("Error sending magic+version in response"
251 "to LNET magic from %u.%u.%u.%u: %d\n",
252 HIPQUAD(peer_ip), rc);
256 if (magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC))
257 str = "'old' socknal/tcpnal";
258 else if (lnet_accept_magic(magic, LNET_PROTO_RA_MAGIC))
260 else if (lnet_accept_magic(magic, LNET_PROTO_OPENIB_MAGIC))
261 str = "'old' openibnal";
263 str = "unrecognised";
265 LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %u.%u.%u.%u"
266 " magic %08x: %s acceptor protocol\n",
267 HIPQUAD(peer_ip), magic, str);
271 flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC);
273 rc = libcfs_sock_read(sock, &cr.acr_version,
274 sizeof(cr.acr_version),
277 CERROR("Error %d reading connection request version from "
278 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
283 __swab32s(&cr.acr_version);
285 if (cr.acr_version != LNET_PROTO_ACCEPTOR_VERSION) {
286 /* future version compatibility!
287 * An acceptor-specific protocol rev will first send a version
288 * query. I send back my current version to tell her I'm
290 int peer_version = cr.acr_version;
292 memset (&cr, 0, sizeof(cr));
293 cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
294 cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
296 rc = libcfs_sock_write(sock, &cr, sizeof(cr),
300 CERROR("Error sending magic+version in response"
301 "to version %d from %u.%u.%u.%u: %d\n",
302 peer_version, HIPQUAD(peer_ip), rc);
306 rc = libcfs_sock_read(sock, &cr.acr_nid,
308 offsetof(lnet_acceptor_connreq_t, acr_nid),
311 CERROR("Error %d reading connection request from "
312 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
317 __swab64s(&cr.acr_nid);
319 ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid));
320 if (ni == NULL || /* no matching net */
321 ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */
324 LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %u.%u.%u.%u"
325 " for %s: No matching NI\n",
326 HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
330 if (ni->ni_lnd->lnd_accept == NULL) {
331 /* This catches a request for the loopback LND */
333 LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %u.%u.%u.%u"
334 " for %s: NI doesn not accept IP connections\n",
335 HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
339 CDEBUG(D_NET, "Accept %s from %u.%u.%u.%u%s\n",
340 libcfs_nid2str(cr.acr_nid), HIPQUAD(peer_ip),
341 blind_ni == NULL ? "" : " (blind)");
343 if (blind_ni == NULL) {
344 /* called by the acceptor: call into the requested NI... */
345 rc = ni->ni_lnd->lnd_accept(ni, sock);
347 /* portals_compatible set and the (only) NI called me to verify
348 * and skip the connection request... */
349 LASSERT (the_lnet.ln_ptlcompat != 0);
350 LASSERT (ni == blind_ni);
357 EXPORT_SYMBOL(lnet_accept);
360 lnet_acceptor(void *arg)
363 cfs_socket_t *newsock;
369 lnet_ni_t *blind_ni = NULL;
370 int secure = (int)((unsigned long)arg);
372 LASSERT (lnet_acceptor_state.pta_sock == NULL);
374 if (the_lnet.ln_ptlcompat != 0) {
375 /* When portals_compatibility is enabled, peers may connect
376 * without sending an acceptor connection request. There is no
377 * ambiguity about which network the peer wants to connect to
378 * since there can only be 1 network, so I pass connections
379 * "blindly" to it. */
380 n_acceptor_nis = lnet_count_acceptor_nis(&blind_ni);
381 LASSERT (n_acceptor_nis == 1);
382 LASSERT (blind_ni != NULL);
385 snprintf(name, sizeof(name), "acceptor_%03d", accept_port);
389 rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock,
390 0, accept_port, accept_backlog);
392 if (rc == -EADDRINUSE)
393 LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port"
394 " %d: port already in use\n",
397 LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port "
398 "%d: unexpected error %d\n",
401 lnet_acceptor_state.pta_sock = NULL;
403 LCONSOLE(0, "Accept %s, port %d%s\n",
405 blind_ni == NULL ? "" : " (proto compatible)");
408 /* set init status and unblock parent */
409 lnet_acceptor_state.pta_shutdown = rc;
410 mutex_up(&lnet_acceptor_state.pta_signal);
415 while (!lnet_acceptor_state.pta_shutdown) {
417 rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock);
420 CWARN("Accept error %d: pausing...\n", rc);
421 cfs_pause(cfs_time_seconds(1));
426 rc = libcfs_sock_getaddr(newsock, 1, &peer_ip, &peer_port);
428 CERROR("Can't determine new connection's address\n");
432 if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
433 CERROR("Refusing connection from %u.%u.%u.%u: "
434 "insecure port %d\n",
435 HIPQUAD(peer_ip), peer_port);
439 if (blind_ni != NULL) {
440 rc = blind_ni->ni_lnd->lnd_accept(blind_ni, newsock);
442 CERROR("NI %s refused 'blind' connection from "
444 libcfs_nid2str(blind_ni->ni_nid),
451 rc = libcfs_sock_read(newsock, &magic, sizeof(magic),
454 CERROR("Error %d reading connection request from "
455 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
459 rc = lnet_accept(NULL, newsock, magic);
466 libcfs_sock_release(newsock);
469 libcfs_sock_release(lnet_acceptor_state.pta_sock);
470 lnet_acceptor_state.pta_sock = NULL;
472 if (blind_ni != NULL)
473 lnet_ni_decref(blind_ni);
475 LCONSOLE(0,"Acceptor stopping\n");
477 /* unblock lnet_acceptor_stop() */
478 mutex_up(&lnet_acceptor_state.pta_signal);
483 lnet_acceptor_start(void)
488 LASSERT (lnet_acceptor_state.pta_sock == NULL);
489 init_mutex_locked(&lnet_acceptor_state.pta_signal);
491 if (!strcmp(accept, "secure")) {
493 } else if (!strcmp(accept, "all")) {
495 } else if (!strcmp(accept, "none")) {
498 LCONSOLE_ERROR_MSG(0x124, "Can't parse 'accept=\"%s\"'\n",
503 if (lnet_count_acceptor_nis(NULL) == 0) /* not required */
506 pid = cfs_kernel_thread(lnet_acceptor, (void *)secure, 0);
508 CERROR("Can't start acceptor thread: %ld\n", pid);
512 mutex_down(&lnet_acceptor_state.pta_signal); /* wait for acceptor to startup */
514 if (!lnet_acceptor_state.pta_shutdown) {
516 LASSERT (lnet_acceptor_state.pta_sock != NULL);
520 LASSERT (lnet_acceptor_state.pta_sock == NULL);
525 lnet_acceptor_stop(void)
527 if (lnet_acceptor_state.pta_sock == NULL) /* not running */
530 lnet_acceptor_state.pta_shutdown = 1;
531 libcfs_sock_abort_accept(lnet_acceptor_state.pta_sock);
533 /* block until acceptor signals exit */
534 mutex_down(&lnet_acceptor_state.pta_signal);
537 #else /* __KERNEL__ */
538 #ifdef HAVE_LIBPTHREAD
540 static char *accept_type;
541 static int accept_port = 988;
542 static int accept_backlog;
543 static int accept_timeout;
548 struct cfs_completion pta_completion;
549 } lnet_acceptor_state;
552 lnet_acceptor_port(void)
558 lnet_parse_int_tunable(int *value, char *name, int dflt)
560 char *env = getenv(name);
568 *value = strtoull(env, &end, 0);
572 CERROR("Can't parse tunable %s=%s\n", name, env);
577 lnet_parse_string_tunable(char **value, char *name, char *dflt)
579 char *env = getenv(name);
590 lnet_acceptor_get_tunables()
593 rc = lnet_parse_string_tunable(&accept_type, "LNET_ACCEPT", "secure");
598 rc = lnet_parse_int_tunable(&accept_port, "LNET_ACCEPT_PORT", 988);
603 rc = lnet_parse_int_tunable(&accept_backlog, "LNET_ACCEPT_BACKLOG", 127);
608 rc = lnet_parse_int_tunable(&accept_timeout, "LNET_ACCEPT_TIMEOUT", 5);
613 CDEBUG(D_NET, "accept_type = %s\n", accept_type);
614 CDEBUG(D_NET, "accept_port = %d\n", accept_port);
615 CDEBUG(D_NET, "accept_backlog = %d\n", accept_backlog);
616 CDEBUG(D_NET, "accept_timeout = %d\n", accept_timeout);
621 lnet_accept_magic(__u32 magic, __u32 constant)
623 return (magic == constant ||
624 magic == __swab32(constant));
627 /* user-land lnet_accept() isn't used by any LND's directly. So, we don't
628 * do it visible outside acceptor.c and we can change its prototype
631 lnet_accept(int sock, __u32 magic, __u32 peer_ip, int peer_port)
634 lnet_acceptor_connreq_t cr;
637 if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) {
638 LCONSOLE_ERROR("Refusing connection from %u.%u.%u.%u magic %08x: "
639 "unsupported acceptor protocol\n",
640 HIPQUAD(peer_ip), magic);
644 flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC);
646 rc = libcfs_sock_read(sock, &cr.acr_version,
647 sizeof(cr.acr_version),
650 CERROR("Error %d reading connection request version from "
651 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
656 __swab32s(&cr.acr_version);
658 if (cr.acr_version != LNET_PROTO_ACCEPTOR_VERSION)
661 rc = libcfs_sock_read(sock, &cr.acr_nid,
663 offsetof(lnet_acceptor_connreq_t, acr_nid),
666 CERROR("Error %d reading connection request from "
667 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
672 __swab64s(&cr.acr_nid);
674 ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid));
676 if (ni == NULL || /* no matching net */
677 ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */
680 LCONSOLE_ERROR("Refusing connection from %u.%u.%u.%u for %s: "
682 HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
686 if (ni->ni_lnd->lnd_accept == NULL) {
688 LCONSOLE_ERROR("Refusing connection from %u.%u.%u.%u for %s: "
689 " NI doesn not accept IP connections\n",
690 HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
694 CDEBUG(D_NET, "Accept %s from %u.%u.%u.%u\n",
695 libcfs_nid2str(cr.acr_nid), HIPQUAD(peer_ip));
697 rc = ni->ni_lnd->lnd_accept(ni, sock);
704 lnet_acceptor(void *arg)
707 int secure = (int)((unsigned long)arg);
714 snprintf(name, sizeof(name), "acceptor_%03d", accept_port);
718 rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock,
719 0, accept_port, accept_backlog);
721 if (rc == -EADDRINUSE)
722 LCONSOLE_ERROR("Can't start acceptor on port %d: "
723 "port already in use\n",
726 LCONSOLE_ERROR("Can't start acceptor on port %d: "
727 "unexpected error %d\n",
731 LCONSOLE(0, "Accept %s, port %d\n", accept_type, accept_port);
734 /* set init status and unblock parent */
735 lnet_acceptor_state.pta_shutdown = rc;
736 cfs_complete(&lnet_acceptor_state.pta_completion);
741 while (!lnet_acceptor_state.pta_shutdown) {
743 rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock,
744 &peer_ip, &peer_port);
748 /* maybe we're waken up with libcfs_sock_abort_accept() */
749 if (lnet_acceptor_state.pta_shutdown) {
754 if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
755 CERROR("Refusing connection from %u.%u.%u.%u: "
756 "insecure port %d\n",
757 HIPQUAD(peer_ip), peer_port);
761 rc = libcfs_sock_read(newsock, &magic, sizeof(magic),
764 CERROR("Error %d reading connection request from "
765 "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
769 rc = lnet_accept(newsock, magic, peer_ip, peer_port);
779 close(lnet_acceptor_state.pta_sock);
780 LCONSOLE(0,"Acceptor stopping\n");
782 /* unblock lnet_acceptor_stop() */
783 cfs_complete(&lnet_acceptor_state.pta_completion);
788 static int skip_waiting_for_completion;
791 lnet_acceptor_start(void)
796 rc = lnet_acceptor_get_tunables();
800 /* Do nothing if we're liblustre clients */
801 if ((the_lnet.ln_pid & LNET_PID_USERFLAG) != 0)
804 cfs_init_completion(&lnet_acceptor_state.pta_completion);
806 if (!strcmp(accept_type, "secure")) {
808 } else if (!strcmp(accept_type, "all")) {
810 } else if (!strcmp(accept_type, "none")) {
811 skip_waiting_for_completion = 1;
814 LCONSOLE_ERROR ("Can't parse 'accept_type=\"%s\"'\n", accept_type);
815 cfs_fini_completion(&lnet_acceptor_state.pta_completion);
819 if (lnet_count_acceptor_nis(NULL) == 0) { /* not required */
820 skip_waiting_for_completion = 1;
824 rc = cfs_create_thread(lnet_acceptor, (void *)secure);
826 CERROR("Can't start acceptor thread: %d\n", rc);
827 cfs_fini_completion(&lnet_acceptor_state.pta_completion);
831 /* wait for acceptor to startup */
832 cfs_wait_for_completion(&lnet_acceptor_state.pta_completion);
834 if (!lnet_acceptor_state.pta_shutdown)
837 cfs_fini_completion(&lnet_acceptor_state.pta_completion);
842 lnet_acceptor_stop(void)
844 /* Do nothing if we're liblustre clients */
845 if ((the_lnet.ln_pid & LNET_PID_USERFLAG) != 0)
848 if (!skip_waiting_for_completion) {
849 lnet_acceptor_state.pta_shutdown = 1;
850 libcfs_sock_abort_accept(accept_port);
852 /* block until acceptor signals exit */
853 cfs_wait_for_completion(&lnet_acceptor_state.pta_completion);
856 cfs_fini_completion(&lnet_acceptor_state.pta_completion);
860 lnet_acceptor_start(void)
866 lnet_acceptor_stop(void)
869 #endif /* !HAVE_LIBPTHREAD */
870 #endif /* !__KERNEL__ */