1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002, Lawrence Livermore National Labs (LLNL)
5 * Author: Brian Behlendorf <behlendorf1@llnl.gov>
6 * Kedar Sovani (kedar@calsoftinc.com)
7 * Amey Inamdar (amey@calsoftinc.com)
9 * This file is part of Portals, http://www.sf.net/projects/lustre/
11 * Portals is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Portals is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Portals; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* This is a striped down version of pinger. It follows a single
27 * request-response protocol. Doesn't do Bulk data pinging. Also doesn't
28 * send multiple packets in a single ioctl.
32 #define DEBUG_SUBSYSTEM S_PINGER
34 #include <linux/kp30.h>
35 #include <portals/p30.h>
36 #include <linux/module.h>
37 #include <linux/proc_fs.h>
38 #include <linux/init.h>
39 #include <linux/poll.h>
41 /* int portal_debug = D_PING_CLI; */
44 #define STDSIZE (sizeof(int) + sizeof(int) + 4) /* The data is 4 bytes
47 /* This should be enclosed in a structure */
49 static struct pingcli_data *client = NULL;
54 pingcli_shutdown(int err)
58 /* Yes, we are intentionally allowing us to fall through each
59 * case in to the next. This allows us to pass an error
60 * code to just clean up the right stuff.
64 /* Unlink any memory descriptors we may have used */
65 if ((rc = PtlMDUnlink (client->md_out_head_h)))
66 PDEBUG ("PtlMDUnlink", rc);
68 /* Free the event queue */
69 if ((rc = PtlEQFree (client->eq)))
70 PDEBUG ("PtlEQFree", rc);
72 if ((rc = PtlMEUnlink (client->me)))
73 PDEBUG ("PtlMEUnlink", rc);
75 kportal_put_ni (client->args->ioc_nal);
78 /* Free our buffers */
79 if (client->outbuf != NULL)
80 PORTAL_FREE (client->outbuf, STDSIZE);
82 if (client->inbuf != NULL)
83 PORTAL_FREE (client->inbuf, STDSIZE);
88 sizeof(struct pingcli_data));
92 CDEBUG (D_OTHER, "ping client released resources\n");
93 } /* pingcli_shutdown() */
95 static int pingcli_callback(ptl_event_t *ev)
97 wake_up_process (client->tsk);
102 static struct pingcli_data *
103 pingcli_start(struct portal_ioctl_data *args)
105 const ptl_handle_ni_t *nip;
106 unsigned ping_head_magic = PING_HEADER_MAGIC;
107 char str[PTL_NALFMT_SIZE];
110 client->tsk = current;
113 CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64" (%s), \
114 nal %d, size %u, count: %u, timeout: %u\n",
116 portals_nid2str(args->ioc_nid, args->ioc_nal, str),
117 args->ioc_nal, args->ioc_size,
118 args->ioc_count, args->ioc_timeout);
121 PORTAL_ALLOC (client->outbuf, STDSIZE) ;
122 if (client->outbuf == NULL)
124 CERROR ("Unable to allocate out_buf ("LPSZ" bytes)\n", STDSIZE);
125 pingcli_shutdown (4);
129 PORTAL_ALLOC (client->inbuf, STDSIZE);
131 if (client->inbuf == NULL)
133 CERROR ("Unable to allocate out_buf ("LPSZ" bytes)\n", STDSIZE);
134 pingcli_shutdown (4);
138 /* Aquire and initialize the proper nal for portals. */
139 if ((nip = kportal_get_ni (args->ioc_nal)) == NULL)
141 CERROR ("NAL %d not loaded.\n", args->ioc_nal);
142 pingcli_shutdown (4);
146 /* Based on the initialization aquire our unique portal ID. */
147 if ((rc = PtlGetId (*nip, &client->myid)))
149 CERROR ("PtlGetId error %d\n", rc);
150 pingcli_shutdown (2);
154 /* Setup the local match entries */
155 client->id_local.nid = PTL_NID_ANY;
156 client->id_local.pid = PTL_PID_ANY;
158 /* Setup the remote match entries */
159 client->id_remote.nid = args->ioc_nid;
160 client->id_remote.pid = 0;
162 if ((rc = PtlMEAttach (*nip, PTL_PING_CLIENT,
163 client->id_local, 0, ~0, PTL_RETAIN,
164 PTL_INS_AFTER, &client->me)))
166 CERROR ("PtlMEAttach error %d\n", rc);
167 pingcli_shutdown (2);
171 /* Allocate the event queue for this network interface */
172 if ((rc = PtlEQAlloc (*nip, 64, pingcli_callback, &client->eq)))
174 CERROR ("PtlEQAlloc error %d\n", rc);
175 pingcli_shutdown (2);
180 client->md_in_head.start = client->inbuf;
181 client->md_in_head.length = STDSIZE;
182 client->md_in_head.threshold = 1;
183 client->md_in_head.options = PTL_MD_EVENT_START_DISABLE | PTL_MD_OP_PUT;
184 client->md_in_head.user_ptr = NULL;
185 client->md_in_head.eventq = client->eq;
186 memset (client->inbuf, 0, STDSIZE);
188 /* Attach the incoming buffer */
189 if ((rc = PtlMDAttach (client->me, client->md_in_head,
190 PTL_UNLINK, &client->md_in_head_h))) {
191 CERROR ("PtlMDAttach error %d\n", rc);
192 pingcli_shutdown (1);
196 /* Setup the outgoing ping header */
197 client->md_out_head.start = client->outbuf;
198 client->md_out_head.length = STDSIZE;
199 client->md_out_head.threshold = 1;
200 client->md_out_head.options = PTL_MD_EVENT_START_DISABLE | PTL_MD_OP_PUT;
201 client->md_out_head.user_ptr = NULL;
202 client->md_out_head.eventq = PTL_EQ_NONE;
204 memcpy (client->outbuf, &ping_head_magic, sizeof(ping_head_magic));
206 /* Bind the outgoing ping header */
207 if ((rc=PtlMDBind (*nip, client->md_out_head,
208 PTL_UNLINK, &client->md_out_head_h))) {
209 CERROR ("PtlMDBind error %d\n", rc);
210 pingcli_shutdown (1);
213 /* Put the ping packet */
214 if((rc = PtlPut (client->md_out_head_h, PTL_NOACK_REQ,
215 client->id_remote, PTL_PING_SERVER, 0, 0, 0, 0))) {
216 PDEBUG ("PtlPut (header)", rc);
217 pingcli_shutdown (1);
222 set_current_state (TASK_INTERRUPTIBLE);
223 rc = schedule_timeout (20 * args->ioc_timeout);
225 printk ("LustreError: Time out on the server\n");
226 pingcli_shutdown (2);
229 printk("Lustre: Received respose from the server \n");
232 pingcli_shutdown (2);
236 } /* pingcli_setup() */
240 /* called by the portals_ioctl for ping requests */
241 int kping_client(struct portal_ioctl_data *args)
244 PORTAL_ALLOC (client, sizeof(struct pingcli_data));
245 memset (client, 0, sizeof(struct pingcli_data));
248 CERROR ("Unable to allocate client structure\n");
251 pingcli_start (args);
254 } /* kping_client() */
257 static int __init pingcli_init(void)
259 PORTAL_SYMBOL_REGISTER(kping_client);
261 } /* pingcli_init() */
264 static void /*__exit*/ pingcli_cleanup(void)
266 PORTAL_SYMBOL_UNREGISTER (kping_client);
267 } /* pingcli_cleanup() */
270 MODULE_AUTHOR("Brian Behlendorf (LLNL)");
271 MODULE_DESCRIPTION("A simple kernel space ping client for portals testing");
272 MODULE_LICENSE("GPL");
274 module_init(pingcli_init);
275 module_exit(pingcli_cleanup);
277 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
278 EXPORT_SYMBOL (kping_client);