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.
35 #include <procbridge.h>
42 * Arguments: nal_t *nal: pointer to my top-side nal structure
43 * id: the command to pass to the lower layer
44 * args, args_len:pointer to and length of the request
45 * ret, ret_len: pointer to and size of the result
46 * Returns: a portals status code
48 * forwards a packaged api call from the 'api' side to the 'library'
49 * side, and collects the result
51 static int procbridge_forward(nal_t *n, int id, void *args, size_t args_len,
52 void *ret, ptl_size_t ret_len)
54 bridge b = (bridge) n->nal_data;
63 lib_dispatch(b->nal_cb, NULL, id, args, ret);
70 * Arguments: nal: a pointer to my top side nal structure
71 * ni: my network interface index
73 * cleanup nal state, reclaim the lower side thread and
74 * its state using PTL_FINI codepoint
76 static int procbridge_shutdown(nal_t *n, int ni)
78 bridge b=(bridge)n->nal_data;
79 procbridge p=(procbridge)b->local;
81 p->nal_flags |= NAL_FLAG_STOPPING;
84 pthread_mutex_lock(&p->mutex);
85 if (p->nal_flags & NAL_FLAG_STOPPED) {
86 pthread_mutex_unlock(&p->mutex);
89 pthread_cond_wait(&p->cond, &p->mutex);
90 pthread_mutex_unlock(&p->mutex);
101 static int procbridge_validate(nal_t *nal, void *base, size_t extent)
110 * this function was originally intended to allow the
111 * lower half thread to be scheduled to allow progress. we
112 * overload it to explicitly block until signalled by the
115 static void procbridge_yield(nal_t *n)
117 bridge b=(bridge)n->nal_data;
118 procbridge p=(procbridge)b->local;
120 pthread_mutex_lock(&p->mutex);
121 pthread_cond_wait(&p->cond,&p->mutex);
122 pthread_mutex_unlock(&p->mutex);
126 static void procbridge_lock(nal_t * nal, unsigned long *flags){}
127 static void procbridge_unlock(nal_t * nal, unsigned long *flags){}
129 * the interface vector to allow the generic code to access
130 * this nal. this is seperate from the library side nal_cb.
131 * TODO: should be dyanmically allocated
133 static nal_t api_nal = {
136 forward: procbridge_forward,
137 shutdown: procbridge_shutdown,
138 validate: procbridge_validate,
139 yield: procbridge_yield,
140 lock: procbridge_lock,
141 unlock: procbridge_unlock
144 ptl_nid_t tcpnal_mynid;
146 /* Function: procbridge_interface
148 * Arguments: pid: requested process id (port offset)
149 * PTL_ID_ANY not supported.
150 * desired: limits passed from the application
151 * and effectively ignored
152 * actual: limits actually allocated and returned
154 * Returns: a pointer to my statically allocated top side NAL
157 * initializes the tcp nal. we define unix_failure as an
158 * error wrapper to cut down clutter.
160 nal_t *procbridge_interface(int num_interface,
161 ptl_pt_index_t ptl_size,
162 ptl_ac_index_t acl_size,
163 ptl_pid_t requested_pid)
165 nal_init_args_t args;
168 static int initialized=0;
169 ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
170 int nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
172 if(initialized) return (&api_nal);
176 b=(bridge)malloc(sizeof(struct bridge));
177 p=(procbridge)malloc(sizeof(struct procbridge));
182 limits.max_ptable_index = ptl_size;
184 limits.max_atable_index = acl_size;
186 args.nia_requested_pid = requested_pid;
187 args.nia_limits = &limits;
188 args.nia_nal_type = nal_type;
191 /* init procbridge */
192 pthread_mutex_init(&p->mutex,0);
193 pthread_cond_init(&p->cond, 0);
195 pthread_mutex_init(&p->nal_cb_lock, 0);
197 if (pthread_create(&p->t, NULL, nal_thread, &args)) {
198 perror("nal_init: pthread_create");
203 pthread_mutex_lock(&p->mutex);
204 if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
205 pthread_mutex_unlock(&p->mutex);
208 pthread_cond_wait(&p->cond, &p->mutex);
209 pthread_mutex_unlock(&p->mutex);
212 if (p->nal_flags & NAL_FLAG_STOPPED)
215 b->nal_cb->ni.nid = tcpnal_mynid;