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.
38 #include <sys/socket.h>
39 #include <procbridge.h>
45 /* XXX CFS workaround, to give a chance to let nal thread wake up
46 * from waiting in select
48 static int procbridge_notifier_handler(void *arg)
51 procbridge p = (procbridge) arg;
53 syscall(SYS_read, p->notifier[1], buf, sizeof(buf));
57 void procbridge_wakeup_nal(procbridge p)
60 syscall(SYS_write, p->notifier[0], buf, sizeof(buf));
64 * Arguments: nal: a pointer to my top side nal structure
65 * ni: my network interface index
67 * cleanup nal state, reclaim the lower side thread and
68 * its state using PTL_FINI codepoint
70 static void procbridge_shutdown(nal_t *n)
72 lib_nal_t *nal = n->nal_data;
73 bridge b=(bridge)nal->libnal_data;
74 procbridge p=(procbridge)b->local;
76 p->nal_flags |= NAL_FLAG_STOPPING;
77 procbridge_wakeup_nal(p);
80 pthread_mutex_lock(&p->mutex);
81 if (p->nal_flags & NAL_FLAG_STOPPED) {
82 pthread_mutex_unlock(&p->mutex);
85 pthread_cond_wait(&p->cond, &p->mutex);
86 pthread_mutex_unlock(&p->mutex);
94 extern int procbridge_startup (nal_t *, ptl_pid_t,
95 ptl_ni_limits_t *, ptl_ni_limits_t *);
98 * the interface vector to allow the generic code to access
99 * this nal. this is seperate from the library side lib_nal.
100 * TODO: should be dyanmically allocated
102 nal_t procapi_nal = {
104 nal_ni_init: procbridge_startup,
105 nal_ni_fini: procbridge_shutdown,
108 ptl_nid_t tcpnal_mynid;
110 #ifdef ENABLE_SELECT_DISPATCH
111 procbridge __global_procbridge = NULL;
114 /* Function: procbridge_startup
116 * Arguments: pid: requested process id (port offset)
117 * PTL_ID_ANY not supported.
118 * desired: limits passed from the application
119 * and effectively ignored
120 * actual: limits actually allocated and returned
122 * Returns: portals rc
124 * initializes the tcp nal. we define unix_failure as an
125 * error wrapper to cut down clutter.
127 int procbridge_startup (nal_t *nal, ptl_pid_t requested_pid,
128 ptl_ni_limits_t *requested_limits,
129 ptl_ni_limits_t *actual_limits)
131 nal_init_args_t args;
135 /* XXX nal_type is purely private to tcpnal here */
136 int nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
138 LASSERT(nal == &procapi_nal);
142 b=(bridge)malloc(sizeof(struct bridge));
143 p=(procbridge)malloc(sizeof(struct procbridge));
146 args.nia_requested_pid = requested_pid;
147 args.nia_requested_limits = requested_limits;
148 args.nia_actual_limits = actual_limits;
149 args.nia_nal_type = nal_type;
151 args.nia_apinal = nal;
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");
164 if (!register_io_handler(p->notifier[1], READ_HANDLER,
165 procbridge_notifier_handler, p)) {
166 perror("fail to register notifier handler");
170 #ifdef ENABLE_SELECT_DISPATCH
171 __global_procbridge = p;
174 /* create nal thread */
175 if (pthread_create(&p->t, NULL, nal_thread, &args)) {
176 perror("nal_init: pthread_create");
181 pthread_mutex_lock(&p->mutex);
182 if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
183 pthread_mutex_unlock(&p->mutex);
186 pthread_cond_wait(&p->cond, &p->mutex);
187 pthread_mutex_unlock(&p->mutex);
190 if (p->nal_flags & NAL_FLAG_STOPPED)
193 b->lib_nal->libnal_ni.ni_pid.nid = tcpnal_mynid;