Linux-libre 4.9.86-gnu
[librecmc/linux-libre.git] / drivers / staging / lustre / 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, 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 "../../include/linux/libcfs/libcfs.h"
40 #include "../../include/linux/lnet/lib-lnet.h"
41 #include "../../include/linux/lnet/lnetst.h"
42 #include "console.h"
43
44 static int
45 lst_session_new_ioctl(lstio_session_new_args_t *args)
46 {
47         char *name;
48         int rc;
49
50         if (!args->lstio_ses_idp ||     /* address for output sid */
51             !args->lstio_ses_key ||     /* no key is specified */
52             !args->lstio_ses_namep ||   /* 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)
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(lstio_session_end_args_t *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(lstio_session_info_args_t *args)
91 {
92         /* no checking of key */
93
94         if (!args->lstio_ses_idp ||     /* address for output sid */
95             !args->lstio_ses_keyp ||    /* address for output key */
96             !args->lstio_ses_featp ||   /* address for output features */
97             !args->lstio_ses_ndinfo ||  /* address for output ndinfo */
98             !args->lstio_ses_namep ||   /* address for output 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(lstio_debug_args_t *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)
122                 return -EINVAL;
123
124         if (args->lstio_dbg_namep &&    /* 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) {
130                 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
131                 if (!name)
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)
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)
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)
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)
187                 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
188
189         return rc;
190 }
191
192 static int
193 lst_group_add_ioctl(lstio_group_add_args_t *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 ||
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)
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(lstio_group_del_args_t *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 ||
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)
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(lstio_group_update_args_t *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 ||
268             !args->lstio_grp_namep ||
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)
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) {
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(lstio_group_nodes_args_t *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 ||    /* array of ids */
326             args->lstio_grp_count <= 0 ||
327             !args->lstio_grp_resultp ||
328             !args->lstio_grp_featp ||
329             !args->lstio_grp_namep ||
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)
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 &&
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(lstio_group_list_args_t *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 ||
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(lstio_group_info_args_t *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 ||
389             args->lstio_grp_nmlen <= 0 ||
390             args->lstio_grp_nmlen > LST_NAME_SIZE)
391                 return -EINVAL;
392
393         if (!args->lstio_grp_entp &&    /* output: group entry */
394             !args->lstio_grp_dentsp)    /* output: node entry */
395                 return -EINVAL;
396
397         if (args->lstio_grp_dentsp) {           /* have node entry */
398                 if (!args->lstio_grp_idxp ||    /* node index */
399                     !args->lstio_grp_ndentp)    /* # 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)
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)
430                 return rc;
431
432         if (args->lstio_grp_dentsp &&
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(lstio_batch_add_args_t *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 ||
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)
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(lstio_batch_run_args_t *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 ||
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)
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(lstio_batch_stop_args_t *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 ||
517             !args->lstio_bat_namep ||
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)
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(lstio_batch_query_args_t *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 ||
552             !args->lstio_bat_namep ||
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)
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(lstio_batch_list_args_t *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 ||
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(lstio_batch_info_args_t *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 ||   /* 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 &&    /* output: batch entry */
617             !args->lstio_bat_dentsp)    /* output: node entry */
618                 return -EINVAL;
619
620         if (args->lstio_bat_dentsp) {           /* have node entry */
621                 if (!args->lstio_bat_idxp ||    /* node index */
622                     !args->lstio_bat_ndentp)    /* # 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)
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, args->lstio_bat_entp,
648                                args->lstio_bat_server, args->lstio_bat_testidx,
649                                &index, &ndent, args->lstio_bat_dentsp);
650
651         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
652
653         if (rc)
654                 return rc;
655
656         if (args->lstio_bat_dentsp &&
657             (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
658              copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
659                 rc = -EFAULT;
660
661         return rc;
662 }
663
664 static int
665 lst_stat_query_ioctl(lstio_stat_args_t *args)
666 {
667         int rc;
668         char *name = NULL;
669
670         /* TODO: not finished */
671         if (args->lstio_sta_key != console_session.ses_key)
672                 return -EACCES;
673
674         if (!args->lstio_sta_resultp)
675                 return -EINVAL;
676
677         if (args->lstio_sta_idsp) {
678                 if (args->lstio_sta_count <= 0)
679                         return -EINVAL;
680
681                 rc = lstcon_nodes_stat(args->lstio_sta_count,
682                                        args->lstio_sta_idsp,
683                                        args->lstio_sta_timeout,
684                                        args->lstio_sta_resultp);
685         } else if (args->lstio_sta_namep) {
686                 if (args->lstio_sta_nmlen <= 0 ||
687                     args->lstio_sta_nmlen > LST_NAME_SIZE)
688                         return -EINVAL;
689
690                 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
691                 if (!name)
692                         return -ENOMEM;
693
694                 rc = copy_from_user(name, args->lstio_sta_namep,
695                                     args->lstio_sta_nmlen);
696                 if (!rc)
697                         rc = lstcon_group_stat(name, args->lstio_sta_timeout,
698                                                args->lstio_sta_resultp);
699                 else
700                         rc = -EFAULT;
701         } else {
702                 rc = -EINVAL;
703         }
704
705         if (name)
706                 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
707         return rc;
708 }
709
710 static int lst_test_add_ioctl(lstio_test_args_t *args)
711 {
712         char *batch_name;
713         char *src_name = NULL;
714         char *dst_name = NULL;
715         void *param = NULL;
716         int ret = 0;
717         int rc = -ENOMEM;
718
719         if (!args->lstio_tes_resultp ||
720             !args->lstio_tes_retp ||
721             !args->lstio_tes_bat_name ||        /* no specified batch */
722             args->lstio_tes_bat_nmlen <= 0 ||
723             args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
724             !args->lstio_tes_sgrp_name ||       /* no source group */
725             args->lstio_tes_sgrp_nmlen <= 0 ||
726             args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
727             !args->lstio_tes_dgrp_name ||       /* no target group */
728             args->lstio_tes_dgrp_nmlen <= 0 ||
729             args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
730                 return -EINVAL;
731
732         if (!args->lstio_tes_loop ||            /* negative is infinite */
733             args->lstio_tes_concur <= 0 ||
734             args->lstio_tes_dist <= 0 ||
735             args->lstio_tes_span <= 0)
736                 return -EINVAL;
737
738         /* have parameter, check if parameter length is valid */
739         if (args->lstio_tes_param &&
740             (args->lstio_tes_param_len <= 0 ||
741              args->lstio_tes_param_len >
742              PAGE_SIZE - sizeof(struct lstcon_test)))
743                 return -EINVAL;
744
745         LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
746         if (!batch_name)
747                 return rc;
748
749         LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
750         if (!src_name)
751                 goto out;
752
753         LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
754         if (!dst_name)
755                 goto out;
756
757         if (args->lstio_tes_param) {
758                 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
759                 if (!param)
760                         goto out;
761                 if (copy_from_user(param, args->lstio_tes_param,
762                                    args->lstio_tes_param_len)) {
763                         rc = -EFAULT;
764                         goto out;
765                 }
766         }
767
768         rc = -EFAULT;
769         if (copy_from_user(batch_name, args->lstio_tes_bat_name,
770                            args->lstio_tes_bat_nmlen) ||
771             copy_from_user(src_name, args->lstio_tes_sgrp_name,
772                            args->lstio_tes_sgrp_nmlen) ||
773             copy_from_user(dst_name, args->lstio_tes_dgrp_name,
774                            args->lstio_tes_dgrp_nmlen))
775                 goto out;
776
777         rc = lstcon_test_add(batch_name, args->lstio_tes_type,
778                              args->lstio_tes_loop, args->lstio_tes_concur,
779                              args->lstio_tes_dist, args->lstio_tes_span,
780                              src_name, dst_name, param,
781                              args->lstio_tes_param_len,
782                              &ret, args->lstio_tes_resultp);
783
784         if (ret)
785                 rc = (copy_to_user(args->lstio_tes_retp, &ret,
786                                    sizeof(ret))) ? -EFAULT : 0;
787 out:
788         if (batch_name)
789                 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
790
791         if (src_name)
792                 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
793
794         if (dst_name)
795                 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
796
797         if (param)
798                 LIBCFS_FREE(param, args->lstio_tes_param_len);
799
800         return rc;
801 }
802
803 int
804 lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
805 {
806         char *buf;
807         struct libcfs_ioctl_data *data;
808         int opc;
809         int rc;
810
811         if (cmd != IOC_LIBCFS_LNETST)
812                 return -EINVAL;
813
814         data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
815
816         opc = data->ioc_u32[0];
817
818         if (data->ioc_plen1 > PAGE_SIZE)
819                 return -EINVAL;
820
821         LIBCFS_ALLOC(buf, data->ioc_plen1);
822         if (!buf)
823                 return -ENOMEM;
824
825         /* copy in parameter */
826         if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
827                 LIBCFS_FREE(buf, data->ioc_plen1);
828                 return -EFAULT;
829         }
830
831         mutex_lock(&console_session.ses_mutex);
832
833         console_session.ses_laststamp = ktime_get_real_seconds();
834
835         if (console_session.ses_shutdown) {
836                 rc = -ESHUTDOWN;
837                 goto out;
838         }
839
840         if (console_session.ses_expired)
841                 lstcon_session_end();
842
843         if (opc != LSTIO_SESSION_NEW &&
844             console_session.ses_state == LST_SESSION_NONE) {
845                 CDEBUG(D_NET, "LST no active session\n");
846                 rc = -ESRCH;
847                 goto out;
848         }
849
850         memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t));
851
852         switch (opc) {
853         case LSTIO_SESSION_NEW:
854                 rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf);
855                 break;
856         case LSTIO_SESSION_END:
857                 rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf);
858                 break;
859         case LSTIO_SESSION_INFO:
860                 rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf);
861                 break;
862         case LSTIO_DEBUG:
863                 rc = lst_debug_ioctl((lstio_debug_args_t *)buf);
864                 break;
865         case LSTIO_GROUP_ADD:
866                 rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf);
867                 break;
868         case LSTIO_GROUP_DEL:
869                 rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf);
870                 break;
871         case LSTIO_GROUP_UPDATE:
872                 rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf);
873                 break;
874         case LSTIO_NODES_ADD:
875                 rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf);
876                 break;
877         case LSTIO_GROUP_LIST:
878                 rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf);
879                 break;
880         case LSTIO_GROUP_INFO:
881                 rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf);
882                 break;
883         case LSTIO_BATCH_ADD:
884                 rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf);
885                 break;
886         case LSTIO_BATCH_START:
887                 rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf);
888                 break;
889         case LSTIO_BATCH_STOP:
890                 rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf);
891                 break;
892         case LSTIO_BATCH_QUERY:
893                 rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf);
894                 break;
895         case LSTIO_BATCH_LIST:
896                 rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf);
897                 break;
898         case LSTIO_BATCH_INFO:
899                 rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf);
900                 break;
901         case LSTIO_TEST_ADD:
902                 rc = lst_test_add_ioctl((lstio_test_args_t *)buf);
903                 break;
904         case LSTIO_STAT_QUERY:
905                 rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf);
906                 break;
907         default:
908                 rc = -EINVAL;
909         }
910
911         if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
912                          sizeof(lstcon_trans_stat_t)))
913                 rc = -EFAULT;
914 out:
915         mutex_unlock(&console_session.ses_mutex);
916
917         LIBCFS_FREE(buf, data->ioc_plen1);
918
919         return rc;
920 }