1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cray Inc.
5 * Copyright (c) 2003 Cluster File Systems, Inc.
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.
24 * This file provides the 'api' side for the process-based nals.
25 * it is responsible for creating the 'library' side thread,
26 * and passing wrapped portals transactions to it.
28 * Along with initialization, shutdown, and transport to the library
29 * side, this file contains some stubs to satisfy the nal definition.
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <procbridge.h>
45 #ifdef HAVE_GETHOSTBYNAME
46 # include <sys/utsname.h>
50 # error "This LND requires a multi-threaded runtime"
53 /* XXX CFS workaround, to give a chance to let nal thread wake up
54 * from waiting in select
56 static int procbridge_notifier_handler(void *arg)
59 procbridge p = (procbridge) arg;
61 syscall(SYS_read, p->notifier[1], buf, sizeof(buf));
65 void procbridge_wakeup_nal(procbridge p)
68 syscall(SYS_write, p->notifier[0], buf, sizeof(buf));
73 .lnd_startup = procbridge_startup,
74 .lnd_shutdown = procbridge_shutdown,
75 .lnd_send = tcpnal_send,
76 .lnd_recv = tcpnal_recv,
77 .lnd_notify = tcpnal_notify,
82 * Arguments: ni: the instance of me
84 * cleanup nal state, reclaim the lower side thread and
85 * its state using PTL_FINI codepoint
88 procbridge_shutdown(lnet_ni_t *ni)
90 bridge b=(bridge)ni->ni_data;
91 procbridge p=(procbridge)b->local;
93 p->nal_flags |= NAL_FLAG_STOPPING;
94 procbridge_wakeup_nal(p);
97 pthread_mutex_lock(&p->mutex);
98 if (p->nal_flags & NAL_FLAG_STOPPED) {
99 pthread_mutex_unlock(&p->mutex);
102 pthread_cond_wait(&p->cond, &p->mutex);
103 pthread_mutex_unlock(&p->mutex);
110 #ifdef ENABLE_SELECT_DISPATCH
111 procbridge __global_procbridge = NULL;
114 /* Function: procbridge_startup
116 * Arguments: ni: the instance of me
117 * interfaces: ignored
119 * Returns: portals rc
121 * initializes the tcp nal. we define unix_failure as an
122 * error wrapper to cut down clutter.
125 procbridge_startup (lnet_ni_t *ni)
131 /* NB The local NID is not assigned. We only ever connect to the socknal,
132 * which assigns the src nid/pid on incoming non-privileged connections
133 * (i.e. us), and we don't accept connections. */
135 LASSERT (ni->ni_lnd == &the_tcplnd);
136 LASSERT (!tcpnal_running); /* only single instance supported */
137 LASSERT (ni->ni_interfaces[0] == NULL); /* explicit interface(s) not supported */
139 /* The credit settings here are pretty irrelevent. Userspace tcplnd has no
140 * tx descriptor pool to exhaust and does a blocking send; that's the real
141 * limit on send concurrency. */
142 ni->ni_maxtxcredits = 1000;
143 ni->ni_peertxcredits = 1000;
147 b=(bridge)malloc(sizeof(struct bridge));
148 p=(procbridge)malloc(sizeof(struct procbridge));
153 /* init procbridge */
154 pthread_mutex_init(&p->mutex,0);
155 pthread_cond_init(&p->cond, 0);
158 /* initialize notifier */
159 if (socketpair(AF_UNIX, SOCK_STREAM, 0, p->notifier)) {
160 perror("socketpair failed");
165 if (!register_io_handler(p->notifier[1], READ_HANDLER,
166 procbridge_notifier_handler, p)) {
167 perror("fail to register notifier handler");
171 #ifdef ENABLE_SELECT_DISPATCH
172 __global_procbridge = p;
175 /* create nal thread */
176 rc = pthread_create(&p->t, NULL, nal_thread, b);
178 perror("nal_init: pthread_create");
183 pthread_mutex_lock(&p->mutex);
184 if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
185 pthread_mutex_unlock(&p->mutex);
188 pthread_cond_wait(&p->cond, &p->mutex);
189 pthread_mutex_unlock(&p->mutex);
192 if (p->nal_flags & NAL_FLAG_STOPPED)