Whamcloud - gitweb
Land from b_hd_pid to HEAD
[fs/lustre-release.git] / lustre / liblustre / tests / echo_test.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #include <stdio.h>
5 #include <netinet/in.h>
6 #include <sys/socket.h>
7 #include <arpa/inet.h>
8
9 #include <portals/ptlctl.h>     /* needed for parse_dump */
10
11
12 #include <liblustre.h>
13 #include <linux/obd.h>
14 #include <linux/obd_class.h>
15 #include <procbridge.h>
16
17 #define LIBLUSTRE_TEST 1
18 #include "../utils/lctl.c"
19
20 struct ldlm_namespace;
21 struct ldlm_res_id;
22 struct obd_import;
23
24 unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL |
25                                             S_GMNAL | S_IBNAL);
26
27 void get_random_bytes(void *ptr, int size)
28 {
29         char *p = ptr;
30
31         if (size < 1)
32                 return;
33
34         while(size--)
35                 *p++ = rand();
36 }
37
38 void *inter_module_get(char *arg)
39 {
40         if (!strcmp(arg, "tcpnal_ni"))
41                 return &tcpnal_ni;
42         else if (!strcmp(arg, "ldlm_cli_cancel_unused"))
43                 return ldlm_cli_cancel_unused;
44         else if (!strcmp(arg, "ldlm_namespace_cleanup"))
45                 return ldlm_namespace_cleanup;
46         else if (!strcmp(arg, "ldlm_replay_locks"))
47                 return ldlm_replay_locks;
48         else
49                 return NULL;
50 }
51
52 /* XXX move to proper place */
53 char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
54 {
55         switch(nal){
56         case TCPNAL:
57                 /* userspace NAL */
58         case SOCKNAL:
59                 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u.%u.%u.%u",
60                          (__u32)(nid >> 32), HIPQUAD(nid));
61                 break;
62         case QSWNAL:
63         case GMNAL:
64         case IBNAL:
65                 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u",
66                          (__u32)(nid >> 32), (__u32)nid);
67                 break;
68         default:
69                 snprintf(str, PTL_NALFMT_SIZE - 1, "?%d? %llx",
70                          nal, (long long)nid);
71                 break;
72         }
73         return str;
74 }
75
76 ptl_handle_ni_t         tcpnal_ni;
77
78 struct pingcli_args {
79         ptl_nid_t mynid;
80         ptl_nid_t nid;
81         ptl_pid_t port;
82         int count;
83         int size;
84 };
85 /*      bug #4615       */
86 char *portals_id2str(int nal, ptl_process_id_t id, char *str)
87 {
88         switch(nal){
89         case TCPNAL:
90                 /* userspace NAL */
91         case SOCKNAL:
92                 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u.%u.%u.%u,%u",
93                          (__u32)(id.nid >> 32), HIPQUAD((id.nid)) , id.pid);
94                 break;
95         case QSWNAL:
96         case GMNAL:
97         case IBNAL:
98                 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u,%u",
99                          (__u32)(id.nid >> 32), (__u32)id.nid, id.pid);
100                 break;
101         default:
102                 snprintf(str, PTL_NALFMT_SIZE - 1, "?%d? %llx,%lx",
103                          nal, (long long)id.nid, (long)id.pid );
104                 break;
105         }
106         return str;
107 }
108
109 struct task_struct *current;
110
111 int
112 libcfs_nal_cmd(struct portals_cfg *pcfg)
113 {
114         CERROR("empty function!!!\n");
115         return 0;
116 }
117
118 int in_group_p(gid_t gid)
119 {
120         return 0;
121 }
122
123 int init_current(int argc, char **argv)
124
125         current = malloc(sizeof(*current));
126         strncpy(current->comm, argv[0], sizeof(current->comm));
127         current->pid = getpid();
128         return 0;
129 }
130
131 ptl_nid_t tcpnal_mynid;
132
133 int init_lib_portals()
134 {
135         int max_interfaces;
136         int rc;
137
138         rc = PtlInit(&max_interfaces);
139         if (rc != 0) {
140                 CERROR("ksocknal: PtlNIInit failed: error %d\n", rc);
141                 RETURN (rc);
142         }
143         return rc;
144 }
145
146 extern int class_handle_ioctl(unsigned int cmd, unsigned long arg);
147
148 int liblustre_ioctl(int dev_id, unsigned int opc, void *ptr)
149 {
150         int   rc = -EINVAL;
151         
152         switch (dev_id) {
153         default:
154                 fprintf(stderr, "Unexpected device id %d\n", dev_id);
155                 abort();
156                 break;
157                 
158         case OBD_DEV_ID:
159                 rc = class_handle_ioctl(opc, (unsigned long)ptr);
160                 break;
161         }
162
163         return rc;
164 }
165
166 static void generate_random_uuid(unsigned char uuid_out[16])
167 {
168         int *arr = (int*)uuid_out;
169         int i;
170
171         for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
172                 arr[i] = rand();
173 }
174
175 static char *echo_server_nid = NULL;
176 static char *echo_server_ostname = "obd1";
177 static char *osc_dev_name = "OSC_DEV_NAME";
178 static char *echo_dev_name = "ECHO_CLIENT_DEV_NAME";
179
180 static int connect_echo_client(void)
181 {
182         struct lustre_cfg lcfg;
183         ptl_nid_t nid;
184         char *peer = "ECHO_PEER_NID";
185         class_uuid_t osc_uuid, echo_uuid;
186         struct obd_uuid osc_uuid_str, echo_uuid_str;
187         int nal, err;
188         ENTRY;
189
190         generate_random_uuid(osc_uuid);
191         class_uuid_unparse(osc_uuid, &osc_uuid_str);
192         generate_random_uuid(echo_uuid);
193         class_uuid_unparse(echo_uuid, &echo_uuid_str);
194
195         if (ptl_parse_nid(&nid, echo_server_nid)) {
196                 CERROR("Can't parse NID %s\n", echo_server_nid);
197                 RETURN(-EINVAL);
198         }
199         nal = ptl_name2nal("tcp");
200         if (nal <= 0) {
201                 CERROR("Can't parse NAL tcp\n");
202                 RETURN(-EINVAL);
203         }
204
205         /* add uuid */
206         LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
207         lcfg.lcfg_nid = nid;
208         lcfg.lcfg_inllen1 = strlen(peer) + 1;
209         lcfg.lcfg_inlbuf1 = peer;
210         lcfg.lcfg_nal = nal;
211         err = class_process_config(&lcfg);
212         if (err < 0) {
213                 CERROR("failed add_uuid\n");
214                 RETURN(-EINVAL);
215         }
216
217         /* attach osc */
218         LCFG_INIT(lcfg, LCFG_ATTACH, osc_dev_name);
219         lcfg.lcfg_inlbuf1 = "osc";
220         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
221         lcfg.lcfg_inlbuf2 = osc_uuid_str.uuid;
222         lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
223         err = class_process_config(&lcfg);
224         if (err < 0) {
225                 CERROR("failed attach osc\n");
226                 RETURN(-EINVAL);
227         }
228
229         /* setup osc */
230         LCFG_INIT(lcfg, LCFG_SETUP, osc_dev_name);
231         lcfg.lcfg_inlbuf1 = echo_server_ostname;
232         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
233         lcfg.lcfg_inlbuf2 = peer;
234         lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
235         err = class_process_config(&lcfg);
236         if (err < 0) {
237                 CERROR("failed setup osc\n");
238                 RETURN(-EINVAL);
239         }
240
241         /* attach echo_client */
242         LCFG_INIT(lcfg, LCFG_ATTACH, echo_dev_name);
243         lcfg.lcfg_inlbuf1 = "echo_client";
244         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
245         lcfg.lcfg_inlbuf2 = echo_uuid_str.uuid;
246         lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
247         err = class_process_config(&lcfg);
248         if (err < 0) {
249                 CERROR("failed attach echo_client\n");
250                 RETURN(-EINVAL);
251         }
252
253         /* setup echo_client */
254         LCFG_INIT(lcfg, LCFG_SETUP, echo_dev_name);
255         lcfg.lcfg_inlbuf1 = osc_dev_name;
256         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
257         lcfg.lcfg_inlbuf2 = NULL;
258         lcfg.lcfg_inllen2 = 0;
259         err = class_process_config(&lcfg);
260         if (err < 0) {
261                 CERROR("failed setup echo_client\n");
262                 RETURN(-EINVAL);
263         }
264
265         RETURN(0);
266 }
267
268 static int disconnect_echo_client(void)
269 {
270         struct lustre_cfg lcfg;
271         int err;
272         ENTRY;
273
274         /* cleanup echo_client */
275         LCFG_INIT(lcfg, LCFG_CLEANUP, echo_dev_name);
276         err = class_process_config(&lcfg);
277         if (err < 0) {
278                 CERROR("failed cleanup echo_client\n");
279                 RETURN(-EINVAL);
280         }
281
282         /* detach echo_client */
283         LCFG_INIT(lcfg, LCFG_DETACH, echo_dev_name);
284         err = class_process_config(&lcfg);
285         if (err < 0) {
286                 CERROR("failed detach echo_client\n");
287                 RETURN(-EINVAL);
288         }
289
290         /* cleanup osc */
291         LCFG_INIT(lcfg, LCFG_CLEANUP, osc_dev_name);
292         err = class_process_config(&lcfg);
293         if (err < 0) {
294                 CERROR("failed cleanup osc device\n");
295                 RETURN(-EINVAL);
296         }
297
298         /* detach osc */
299         LCFG_INIT(lcfg, LCFG_DETACH, osc_dev_name);
300         err = class_process_config(&lcfg);
301         if (err < 0) {
302                 CERROR("failed detach osc device\n");
303                 RETURN(-EINVAL);
304         }
305
306         RETURN(0);
307 }
308
309 static void usage(const char *s)
310 {
311         printf("Usage: %s -s ost_host_name [-n ost_name]\n", s);
312         printf("    ost_host_name: the host name of echo server\n");
313         printf("    ost_name: ost name, default is \"obd1\"\n");
314 }
315
316 extern int time_ptlwait1;
317 extern int time_ptlwait2;
318 extern int time_ptlselect;
319
320 int main(int argc, char **argv) 
321 {
322         int c, rc;
323
324         while ((c = getopt(argc, argv, "s:n:")) != -1) {
325                 switch (c) {
326                 case 's':
327                         echo_server_nid = optarg;
328                         break;
329                 case 'n':
330                         echo_server_ostname = optarg;
331                         break;
332                 default:
333                         usage(argv[0]);
334                         return 1;
335                 }
336         }
337
338         if (optind != argc)
339                 usage(argv[0]);
340
341         if (!echo_server_nid) {
342                 usage(argv[0]);
343                 return 1;
344         }
345
346         srand(time(NULL));
347
348         tcpnal_mynid = rand();
349 #if 1
350         portal_debug = 0;
351         portal_subsystem_debug = 0;
352 #endif
353
354         if (init_current(argc, argv) ||
355             init_obdclass() || init_lib_portals() ||
356             ptlrpc_init() ||
357             mdc_init() ||
358             lov_init() ||
359             osc_init() ||
360             echo_client_init()) {
361                 printf("error\n");
362                 return 1;
363         }
364
365         rc = connect_echo_client();
366         if (rc)
367                 return rc;
368
369         set_ioc_handler(liblustre_ioctl);
370
371         rc = lctl_main(1, &argv[0]);
372
373         rc |= disconnect_echo_client();
374
375         return rc;
376 }