Whamcloud - gitweb
LU-4423 lnet: use 64-bit time for selftest
[fs/lustre-release.git] / lnet / selftest / conctl.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2014, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lnet/selftest/conctl.c
33  *
34  * IOC handle in kernel
35  *
36  * Author: Liang Zhen <liangzhen@clusterfs.com>
37  */
38
39 #include <libcfs/libcfs.h>
40 #include <lnet/lib-lnet.h>
41 #include <lnet/lnetst.h>
42 #include "console.h"
43
44 static int
45 lst_session_new_ioctl(struct lstio_session_new_args *args)
46 {
47         char      *name;
48         int        rc;
49
50         if (args->lstio_ses_idp   == NULL || /* address for output sid */
51             args->lstio_ses_key   == 0 || /* no key is specified */
52             args->lstio_ses_namep == NULL || /* session name */
53             args->lstio_ses_nmlen <= 0 ||
54             args->lstio_ses_nmlen > LST_NAME_SIZE)
55                 return -EINVAL;
56
57         LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
58         if (name == NULL)
59                 return -ENOMEM;
60
61         if (copy_from_user(name, args->lstio_ses_namep,
62                            args->lstio_ses_nmlen)) {
63                 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
64                 return -EFAULT;
65         }
66
67         name[args->lstio_ses_nmlen] = 0;
68
69         rc = lstcon_session_new(name,
70                                 args->lstio_ses_key,
71                                 args->lstio_ses_feats,
72                                 args->lstio_ses_force,
73                                 args->lstio_ses_timeout,
74                                 args->lstio_ses_idp);
75
76         LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
77         return rc;
78 }
79
80 static int
81 lst_session_end_ioctl(struct lstio_session_end_args *args)
82 {
83         if (args->lstio_ses_key != console_session.ses_key)
84                 return -EACCES;
85
86         return lstcon_session_end();
87 }
88
89 static int
90 lst_session_info_ioctl(struct lstio_session_info_args *args)
91 {
92         /* no checking of key */
93
94         if (args->lstio_ses_idp   == NULL || /* address for ouput sid */
95             args->lstio_ses_keyp  == NULL || /* address for ouput key */
96             args->lstio_ses_featp  == NULL || /* address for ouput features */
97             args->lstio_ses_ndinfo == NULL || /* address for output ndinfo */
98             args->lstio_ses_namep == NULL || /* address for ouput name */
99             args->lstio_ses_nmlen <= 0 ||
100             args->lstio_ses_nmlen > LST_NAME_SIZE)
101                 return -EINVAL;
102
103         return lstcon_session_info(args->lstio_ses_idp,
104                                    args->lstio_ses_keyp,
105                                    args->lstio_ses_featp,
106                                    args->lstio_ses_ndinfo,
107                                    args->lstio_ses_namep,
108                                    args->lstio_ses_nmlen);
109 }
110
111 static int
112 lst_debug_ioctl(struct lstio_debug_args *args)
113 {
114         char   *name   = NULL;
115         int     client = 1;
116         int     rc;
117
118         if (args->lstio_dbg_key != console_session.ses_key)
119                 return -EACCES;
120
121         if (args->lstio_dbg_resultp == NULL)
122                 return -EINVAL;
123
124         if (args->lstio_dbg_namep != NULL && /* name of batch/group */
125             (args->lstio_dbg_nmlen <= 0 ||
126              args->lstio_dbg_nmlen > LST_NAME_SIZE))
127                 return -EINVAL;
128
129         if (args->lstio_dbg_namep != NULL) {
130                 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
131                 if (name == NULL)
132                         return -ENOMEM;
133
134                 if (copy_from_user(name, args->lstio_dbg_namep,
135                                        args->lstio_dbg_nmlen)) {
136                         LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
137
138                         return -EFAULT;
139                 }
140
141                 name[args->lstio_dbg_nmlen] = 0;
142         }
143
144         rc = -EINVAL;
145
146         switch (args->lstio_dbg_type) {
147         case LST_OPC_SESSION:
148                 rc = lstcon_session_debug(args->lstio_dbg_timeout,
149                                           args->lstio_dbg_resultp);
150                 break;
151
152         case LST_OPC_BATCHSRV:
153                 client = 0;
154         case LST_OPC_BATCHCLI:
155                 if (name == NULL)
156                         goto out;
157
158                 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
159                                         name, client, args->lstio_dbg_resultp);
160                 break;
161
162         case LST_OPC_GROUP:
163                 if (name == NULL)
164                         goto out;
165
166                 rc = lstcon_group_debug(args->lstio_dbg_timeout,
167                                         name, args->lstio_dbg_resultp);
168                 break;
169
170         case LST_OPC_NODES:
171                 if (args->lstio_dbg_count <= 0 ||
172                     args->lstio_dbg_idsp == NULL)
173                         goto out;
174
175                 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
176                                         args->lstio_dbg_count,
177                                         args->lstio_dbg_idsp,
178                                         args->lstio_dbg_resultp);
179                 break;
180
181         default:
182                 break;
183         }
184
185 out:
186         if (name != NULL)
187                 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
188
189         return rc;
190 }
191
192 static int
193 lst_group_add_ioctl(struct lstio_group_add_args *args)
194 {
195         char           *name;
196         int             rc;
197
198         if (args->lstio_grp_key != console_session.ses_key)
199                 return -EACCES;
200
201         if (args->lstio_grp_namep == NULL||
202             args->lstio_grp_nmlen <= 0 ||
203             args->lstio_grp_nmlen > LST_NAME_SIZE)
204                 return -EINVAL;
205
206         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
207         if (name == NULL)
208                 return -ENOMEM;
209
210         if (copy_from_user(name, args->lstio_grp_namep,
211                            args->lstio_grp_nmlen)) {
212                 LIBCFS_FREE(name, args->lstio_grp_nmlen);
213                 return -EFAULT;
214         }
215
216         name[args->lstio_grp_nmlen] = 0;
217
218         rc = lstcon_group_add(name);
219
220         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
221
222         return rc;
223 }
224
225 static int
226 lst_group_del_ioctl(struct lstio_group_del_args *args)
227 {
228         int     rc;
229         char   *name;
230
231         if (args->lstio_grp_key != console_session.ses_key)
232                 return -EACCES;
233
234         if (args->lstio_grp_namep == NULL ||
235             args->lstio_grp_nmlen <= 0 ||
236             args->lstio_grp_nmlen > LST_NAME_SIZE)
237                 return -EINVAL;
238
239         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
240         if (name == NULL)
241                 return -ENOMEM;
242
243         if (copy_from_user(name, args->lstio_grp_namep,
244                            args->lstio_grp_nmlen)) {
245                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
246                 return -EFAULT;
247         }
248
249         name[args->lstio_grp_nmlen] = 0;
250
251         rc = lstcon_group_del(name);
252
253         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
254
255         return rc;
256 }
257
258 static int
259 lst_group_update_ioctl(struct lstio_group_update_args *args)
260 {
261         int     rc;
262         char   *name;
263
264         if (args->lstio_grp_key != console_session.ses_key)
265                 return -EACCES;
266
267         if (args->lstio_grp_resultp == NULL ||
268             args->lstio_grp_namep == NULL ||
269             args->lstio_grp_nmlen <= 0 ||
270             args->lstio_grp_nmlen > LST_NAME_SIZE)
271                 return -EINVAL;
272
273         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
274         if (name == NULL)
275                 return -ENOMEM;
276
277         if (copy_from_user(name, args->lstio_grp_namep,
278                            args->lstio_grp_nmlen)) {
279                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
280                 return -EFAULT;
281         }
282
283         name[args->lstio_grp_nmlen] = 0;
284
285         switch (args->lstio_grp_opc) {
286         case LST_GROUP_CLEAN:
287                 rc = lstcon_group_clean(name, args->lstio_grp_args);
288                 break;
289
290         case LST_GROUP_REFRESH:
291                 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
292                 break;
293
294         case LST_GROUP_RMND:
295                 if (args->lstio_grp_count  <= 0 ||
296                     args->lstio_grp_idsp == NULL) {
297                         rc = -EINVAL;
298                         break;
299                 }
300                 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
301                                          args->lstio_grp_idsp,
302                                          args->lstio_grp_resultp);
303                 break;
304
305         default:
306                 rc = -EINVAL;
307                 break;
308         }
309
310         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
311
312         return rc;
313 }
314
315 static int
316 lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
317 {
318         unsigned feats;
319         int     rc;
320         char   *name;
321
322         if (args->lstio_grp_key != console_session.ses_key)
323                 return -EACCES;
324
325         if (args->lstio_grp_idsp == NULL || /* array of ids */
326             args->lstio_grp_count <= 0 ||
327             args->lstio_grp_resultp == NULL ||
328             args->lstio_grp_featp == NULL ||
329             args->lstio_grp_namep == NULL ||
330             args->lstio_grp_nmlen <= 0 ||
331             args->lstio_grp_nmlen > LST_NAME_SIZE)
332                 return -EINVAL;
333
334         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
335         if (name == NULL)
336                 return -ENOMEM;
337
338         if (copy_from_user(name, args->lstio_grp_namep,
339                                args->lstio_grp_nmlen)) {
340                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
341
342                 return -EFAULT;
343         }
344
345         name[args->lstio_grp_nmlen] = 0;
346
347         rc = lstcon_nodes_add(name, args->lstio_grp_count,
348                               args->lstio_grp_idsp, &feats,
349                               args->lstio_grp_resultp);
350
351         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
352         if (rc == 0 &&
353             copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
354                 return -EINVAL;
355         }
356
357         return rc;
358 }
359
360 static int
361 lst_group_list_ioctl(struct lstio_group_list_args *args)
362 {
363         if (args->lstio_grp_key != console_session.ses_key)
364                 return -EACCES;
365
366         if (args->lstio_grp_idx   < 0 ||
367             args->lstio_grp_namep == NULL ||
368             args->lstio_grp_nmlen <= 0 ||
369             args->lstio_grp_nmlen > LST_NAME_SIZE)
370                 return -EINVAL;
371
372         return lstcon_group_list(args->lstio_grp_idx,
373                               args->lstio_grp_nmlen,
374                               args->lstio_grp_namep);
375 }
376
377 static int
378 lst_group_info_ioctl(struct lstio_group_info_args *args)
379 {
380         char           *name;
381         int             ndent;
382         int             index;
383         int             rc;
384
385         if (args->lstio_grp_key != console_session.ses_key)
386                 return -EACCES;
387
388         if (args->lstio_grp_namep == NULL ||
389             args->lstio_grp_nmlen <= 0 ||
390             args->lstio_grp_nmlen > LST_NAME_SIZE)
391                 return -EINVAL;
392
393         if (args->lstio_grp_entp  == NULL && /* output: group entry */
394             args->lstio_grp_dentsp == NULL)  /* output: node entry */
395                 return -EINVAL;
396
397         if (args->lstio_grp_dentsp != NULL) { /* have node entry */
398                 if (args->lstio_grp_idxp == NULL || /* node index */
399                     args->lstio_grp_ndentp == NULL) /* # of node entry */
400                         return -EINVAL;
401
402                 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
403                                    sizeof(ndent)) ||
404                     copy_from_user(&index, args->lstio_grp_idxp,
405                                    sizeof(index)))
406                         return -EFAULT;
407
408                 if (ndent <= 0 || index < 0)
409                         return -EINVAL;
410         }
411
412         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
413         if (name == NULL)
414                 return -ENOMEM;
415
416         if (copy_from_user(name, args->lstio_grp_namep,
417                            args->lstio_grp_nmlen)) {
418                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
419                 return -EFAULT;
420         }
421
422         name[args->lstio_grp_nmlen] = 0;
423
424         rc = lstcon_group_info(name, args->lstio_grp_entp,
425                                &index, &ndent, args->lstio_grp_dentsp);
426
427         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
428
429         if (rc != 0)
430                 return rc;
431
432         if (args->lstio_grp_dentsp != NULL &&
433             (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
434              copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
435                 return -EFAULT;
436
437         return 0;
438 }
439
440 static int
441 lst_batch_add_ioctl(struct lstio_batch_add_args *args)
442 {
443         int             rc;
444         char           *name;
445
446         if (args->lstio_bat_key != console_session.ses_key)
447                 return -EACCES;
448
449         if (args->lstio_bat_namep == NULL ||
450             args->lstio_bat_nmlen <= 0 ||
451             args->lstio_bat_nmlen > LST_NAME_SIZE)
452                 return -EINVAL;
453
454         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
455         if (name == NULL)
456                 return -ENOMEM;
457
458         if (copy_from_user(name, args->lstio_bat_namep,
459                            args->lstio_bat_nmlen)) {
460                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
461                 return -EFAULT;
462         }
463
464         name[args->lstio_bat_nmlen] = 0;
465
466         rc = lstcon_batch_add(name);
467
468         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
469
470         return rc;
471 }
472
473 static int
474 lst_batch_run_ioctl(struct lstio_batch_run_args *args)
475 {
476         int             rc;
477         char           *name;
478
479         if (args->lstio_bat_key != console_session.ses_key)
480                 return -EACCES;
481
482         if (args->lstio_bat_namep == NULL ||
483             args->lstio_bat_nmlen <= 0 ||
484             args->lstio_bat_nmlen > LST_NAME_SIZE)
485                 return -EINVAL;
486
487         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
488         if (name == NULL)
489                 return -ENOMEM;
490
491         if (copy_from_user(name, args->lstio_bat_namep,
492                            args->lstio_bat_nmlen)) {
493                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
494                 return -EFAULT;
495         }
496
497         name[args->lstio_bat_nmlen] = 0;
498
499         rc = lstcon_batch_run(name, args->lstio_bat_timeout,
500                               args->lstio_bat_resultp);
501
502         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
503
504         return rc;
505 }
506
507 static int
508 lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
509 {
510         int             rc;
511         char           *name;
512
513         if (args->lstio_bat_key != console_session.ses_key)
514                 return -EACCES;
515
516         if (args->lstio_bat_resultp == NULL ||
517             args->lstio_bat_namep == NULL ||
518             args->lstio_bat_nmlen <= 0 ||
519             args->lstio_bat_nmlen > LST_NAME_SIZE)
520                 return -EINVAL;
521
522         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
523         if (name == NULL)
524                 return -ENOMEM;
525
526         if (copy_from_user(name, args->lstio_bat_namep,
527                            args->lstio_bat_nmlen)) {
528                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
529                 return -EFAULT;
530         }
531
532         name[args->lstio_bat_nmlen] = 0;
533
534         rc = lstcon_batch_stop(name, args->lstio_bat_force,
535                                args->lstio_bat_resultp);
536
537         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
538
539         return rc;
540 }
541
542 static int
543 lst_batch_query_ioctl(struct lstio_batch_query_args *args)
544 {
545         char   *name;
546         int     rc;
547
548         if (args->lstio_bat_key != console_session.ses_key)
549                 return -EACCES;
550
551         if (args->lstio_bat_resultp == NULL ||
552             args->lstio_bat_namep == NULL ||
553             args->lstio_bat_nmlen <= 0 ||
554             args->lstio_bat_nmlen > LST_NAME_SIZE)
555                 return -EINVAL;
556
557         if (args->lstio_bat_testidx < 0)
558                 return -EINVAL;
559
560         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
561         if (name == NULL)
562                 return -ENOMEM;
563
564         if (copy_from_user(name, args->lstio_bat_namep,
565                            args->lstio_bat_nmlen)) {
566                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
567                 return -EFAULT;
568         }
569
570         name[args->lstio_bat_nmlen] = 0;
571
572         rc = lstcon_test_batch_query(name,
573                                      args->lstio_bat_testidx,
574                                      args->lstio_bat_client,
575                                      args->lstio_bat_timeout,
576                                      args->lstio_bat_resultp);
577
578         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
579
580         return rc;
581 }
582
583 static int
584 lst_batch_list_ioctl(struct lstio_batch_list_args *args)
585 {
586         if (args->lstio_bat_key != console_session.ses_key)
587                 return -EACCES;
588
589         if (args->lstio_bat_idx   < 0 ||
590             args->lstio_bat_namep == NULL ||
591             args->lstio_bat_nmlen <= 0 ||
592             args->lstio_bat_nmlen > LST_NAME_SIZE)
593                 return -EINVAL;
594
595         return lstcon_batch_list(args->lstio_bat_idx,
596                               args->lstio_bat_nmlen,
597                               args->lstio_bat_namep);
598 }
599
600 static int
601 lst_batch_info_ioctl(struct lstio_batch_info_args *args)
602 {
603         char           *name;
604         int             rc;
605         int             index;
606         int             ndent;
607
608         if (args->lstio_bat_key != console_session.ses_key)
609                 return -EACCES;
610
611         if (args->lstio_bat_namep == NULL || /* batch name */
612             args->lstio_bat_nmlen <= 0 ||
613             args->lstio_bat_nmlen > LST_NAME_SIZE)
614                 return -EINVAL;
615
616         if (args->lstio_bat_entp == NULL && /* output: batch entry */
617             args->lstio_bat_dentsp == NULL) /* output: node entry */
618                 return -EINVAL;
619
620         if (args->lstio_bat_dentsp != NULL) { /* have node entry */
621                 if (args->lstio_bat_idxp == NULL || /* node index */
622                     args->lstio_bat_ndentp == NULL) /* # of node entry */
623                         return -EINVAL;
624
625                 if (copy_from_user(&index, args->lstio_bat_idxp,
626                                        sizeof(index)) ||
627                     copy_from_user(&ndent, args->lstio_bat_ndentp,
628                                        sizeof(ndent)))
629                         return -EFAULT;
630
631                 if (ndent <= 0 || index < 0)
632                         return -EINVAL;
633         }
634
635         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
636         if (name == NULL)
637                 return -ENOMEM;
638
639         if (copy_from_user(name, args->lstio_bat_namep,
640                            args->lstio_bat_nmlen)) {
641                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
642                 return -EFAULT;
643         }
644
645         name[args->lstio_bat_nmlen] = 0;
646
647         rc = lstcon_batch_info(name,
648                             args->lstio_bat_entp, args->lstio_bat_server,
649                             args->lstio_bat_testidx, &index, &ndent,
650                             args->lstio_bat_dentsp);
651
652         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
653
654         if (rc != 0)
655                 return rc;
656
657         if (args->lstio_bat_dentsp != NULL &&
658             (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
659              copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
660                 rc = -EFAULT;
661
662         return rc;
663 }
664
665 static int
666 lst_stat_query_ioctl(struct lstio_stat_args *args)
667 {
668         int             rc;
669         char           *name = NULL;
670
671         /* TODO: not finished */
672         if (args->lstio_sta_key != console_session.ses_key)
673                 return -EACCES;
674
675         if (args->lstio_sta_resultp == NULL)
676                 return -EINVAL;
677
678         if (args->lstio_sta_idsp != NULL) {
679                 if (args->lstio_sta_count <= 0)
680                         return -EINVAL;
681
682                 rc = lstcon_nodes_stat(args->lstio_sta_count,
683                                        args->lstio_sta_idsp,
684                                        args->lstio_sta_timeout,
685                                        args->lstio_sta_resultp);
686         } else if (args->lstio_sta_namep != NULL) {
687                 if (args->lstio_sta_nmlen <= 0 ||
688                     args->lstio_sta_nmlen > LST_NAME_SIZE)
689                         return -EINVAL;
690
691                 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
692                 if (name == NULL)
693                         return -ENOMEM;
694
695                 rc = copy_from_user(name, args->lstio_sta_namep,
696                                     args->lstio_sta_nmlen);
697                 if (rc == 0)
698                         rc = lstcon_group_stat(name, args->lstio_sta_timeout,
699                                                args->lstio_sta_resultp);
700                 else
701                         rc = -EFAULT;
702
703         } else {
704                 rc = -EINVAL;
705         }
706
707         if (name != NULL)
708                 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
709         return rc;
710 }
711
712 static int lst_test_add_ioctl(struct lstio_test_args *args)
713 {
714         char            *batch_name;
715         char            *src_name = NULL;
716         char            *dst_name = NULL;
717         void            *param = NULL;
718         int             ret = 0;
719         int             rc = -ENOMEM;
720
721         if (args->lstio_tes_resultp == NULL ||
722             args->lstio_tes_retp == NULL ||
723             args->lstio_tes_bat_name == NULL || /* no specified batch */
724             args->lstio_tes_bat_nmlen <= 0 ||
725             args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
726             args->lstio_tes_sgrp_name == NULL || /* no source group */
727             args->lstio_tes_sgrp_nmlen <= 0 ||
728             args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
729             args->lstio_tes_dgrp_name == NULL || /* no target group */
730             args->lstio_tes_dgrp_nmlen <= 0 ||
731             args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
732                 return -EINVAL;
733
734         if (args->lstio_tes_loop == 0 || /* negative is infinite */
735             args->lstio_tes_concur <= 0 ||
736             args->lstio_tes_dist <= 0 ||
737             args->lstio_tes_span <= 0)
738                 return -EINVAL;
739
740         /* have parameter, check if parameter length is valid */
741         if (args->lstio_tes_param != NULL &&
742             (args->lstio_tes_param_len <= 0 ||
743              args->lstio_tes_param_len >
744              PAGE_SIZE - sizeof(lstcon_test_t)))
745                 return -EINVAL;
746
747         LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
748         if (batch_name == NULL)
749                 return rc;
750
751         LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
752         if (src_name == NULL)
753                 goto out;
754
755         LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
756         if (dst_name == NULL)
757                 goto out;
758
759         if (args->lstio_tes_param != NULL) {
760                 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
761                 if (param == NULL)
762                         goto out;
763                 if (copy_from_user(param, args->lstio_tes_param,
764                                    args->lstio_tes_param_len)) {
765                         rc = -EFAULT;
766                         goto out;
767                 }
768         }
769
770         rc = -EFAULT;
771         if (copy_from_user(batch_name, args->lstio_tes_bat_name,
772                            args->lstio_tes_bat_nmlen) ||
773             copy_from_user(src_name, args->lstio_tes_sgrp_name,
774                            args->lstio_tes_sgrp_nmlen) ||
775             copy_from_user(dst_name, args->lstio_tes_dgrp_name,
776                            args->lstio_tes_dgrp_nmlen))
777                 goto out;
778
779         rc = lstcon_test_add(batch_name,
780                             args->lstio_tes_type,
781                             args->lstio_tes_loop,
782                             args->lstio_tes_concur,
783                             args->lstio_tes_dist, args->lstio_tes_span,
784                             src_name, dst_name, param,
785                             args->lstio_tes_param_len,
786                             &ret, args->lstio_tes_resultp);
787
788         if (ret != 0)
789                 rc = (copy_to_user(args->lstio_tes_retp, &ret,
790                                        sizeof(ret))) ? -EFAULT : 0;
791 out:
792         if (batch_name != NULL)
793                 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
794
795         if (src_name != NULL)
796                 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
797
798         if (dst_name != NULL)
799                 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
800
801         if (param != NULL)
802                 LIBCFS_FREE(param, args->lstio_tes_param_len);
803
804         return rc;
805 }
806
807 int
808 lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
809 {
810         char   *buf;
811         struct libcfs_ioctl_data *data;
812         int     opc;
813         int     rc;
814
815         if (cmd != IOC_LIBCFS_LNETST)
816                 return -EINVAL;
817
818         data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
819
820         opc = data->ioc_u32[0];
821
822         if (data->ioc_plen1 > PAGE_SIZE)
823                 return -EINVAL;
824
825         LIBCFS_ALLOC(buf, data->ioc_plen1);
826         if (buf == NULL)
827                 return -ENOMEM;
828
829         /* copy in parameter */
830         if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
831                 LIBCFS_FREE(buf, data->ioc_plen1);
832                 return -EFAULT;
833         }
834
835         mutex_lock(&console_session.ses_mutex);
836
837         console_session.ses_laststamp = ktime_get_real_seconds();
838
839         if (console_session.ses_shutdown) {
840                 rc = -ESHUTDOWN;
841                 goto out;
842         }
843
844         if (console_session.ses_expired)
845                 lstcon_session_end();
846
847         if (opc != LSTIO_SESSION_NEW &&
848             console_session.ses_state == LST_SESSION_NONE) {
849                 CDEBUG(D_NET, "LST no active session\n");
850                 rc = -ESRCH;
851                 goto out;
852         }
853
854         memset(&console_session.ses_trans_stat, 0, sizeof(struct lstcon_trans_stat));
855
856         switch (opc) {
857         case LSTIO_SESSION_NEW:
858                 rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
859                 break;
860         case LSTIO_SESSION_END:
861                 rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
862                 break;
863         case LSTIO_SESSION_INFO:
864                 rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
865                 break;
866         case LSTIO_DEBUG:
867                 rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
868                 break;
869         case LSTIO_GROUP_ADD:
870                 rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
871                 break;
872         case LSTIO_GROUP_DEL:
873                 rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
874                 break;
875         case LSTIO_GROUP_UPDATE:
876                 rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
877                 break;
878         case LSTIO_NODES_ADD:
879                 rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
880                 break;
881         case LSTIO_GROUP_LIST:
882                 rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
883                 break;
884         case LSTIO_GROUP_INFO:
885                 rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
886                 break;
887         case LSTIO_BATCH_ADD:
888                 rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
889                 break;
890         case LSTIO_BATCH_START:
891                 rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
892                 break;
893         case LSTIO_BATCH_STOP:
894                 rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
895                 break;
896         case LSTIO_BATCH_QUERY:
897                 rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
898                 break;
899         case LSTIO_BATCH_LIST:
900                 rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
901                 break;
902         case LSTIO_BATCH_INFO:
903                 rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
904                 break;
905         case LSTIO_TEST_ADD:
906                 rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
907                 break;
908         case LSTIO_STAT_QUERY:
909                 rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
910                 break;
911         default:
912                 rc = -EINVAL;
913         }
914
915         if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
916                          sizeof(struct lstcon_trans_stat)))
917                 rc = -EFAULT;
918 out:
919         mutex_unlock(&console_session.ses_mutex);
920
921         LIBCFS_FREE(buf, data->ioc_plen1);
922
923         return rc;
924 }