Whamcloud - gitweb
LU-9859 libcfs: always range-check libcfs_debug_mb setting.
[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 <uapi/linux/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_timeout,
73                                 args->lstio_ses_force,
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                 /* fallthrough */
155         case LST_OPC_BATCHCLI:
156                 if (name == NULL)
157                         goto out;
158
159                 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
160                                         name, client, args->lstio_dbg_resultp);
161                 break;
162
163         case LST_OPC_GROUP:
164                 if (name == NULL)
165                         goto out;
166
167                 rc = lstcon_group_debug(args->lstio_dbg_timeout,
168                                         name, args->lstio_dbg_resultp);
169                 break;
170
171         case LST_OPC_NODES:
172                 if (args->lstio_dbg_count <= 0 ||
173                     args->lstio_dbg_idsp == NULL)
174                         goto out;
175
176                 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
177                                         args->lstio_dbg_count,
178                                         args->lstio_dbg_idsp,
179                                         args->lstio_dbg_resultp);
180                 break;
181
182         default:
183                 break;
184         }
185
186 out:
187         if (name != NULL)
188                 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
189
190         return rc;
191 }
192
193 static int
194 lst_group_add_ioctl(struct lstio_group_add_args *args)
195 {
196         char *name;
197         int rc;
198
199         if (args->lstio_grp_key != console_session.ses_key)
200                 return -EACCES;
201
202         if (args->lstio_grp_namep == NULL ||
203             args->lstio_grp_nmlen <= 0 ||
204             args->lstio_grp_nmlen > LST_NAME_SIZE)
205                 return -EINVAL;
206
207         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
208         if (name == NULL)
209                 return -ENOMEM;
210
211         if (copy_from_user(name, args->lstio_grp_namep,
212                            args->lstio_grp_nmlen)) {
213                 LIBCFS_FREE(name, args->lstio_grp_nmlen);
214                 return -EFAULT;
215         }
216
217         name[args->lstio_grp_nmlen] = 0;
218
219         rc = lstcon_group_add(name);
220
221         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
222
223         return rc;
224 }
225
226 static int
227 lst_group_del_ioctl(struct lstio_group_del_args *args)
228 {
229         int rc;
230         char *name;
231
232         if (args->lstio_grp_key != console_session.ses_key)
233                 return -EACCES;
234
235         if (args->lstio_grp_namep == NULL ||
236             args->lstio_grp_nmlen <= 0 ||
237             args->lstio_grp_nmlen > LST_NAME_SIZE)
238                 return -EINVAL;
239
240         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
241         if (name == NULL)
242                 return -ENOMEM;
243
244         if (copy_from_user(name, args->lstio_grp_namep,
245                            args->lstio_grp_nmlen)) {
246                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
247                 return -EFAULT;
248         }
249
250         name[args->lstio_grp_nmlen] = 0;
251
252         rc = lstcon_group_del(name);
253
254         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
255
256         return rc;
257 }
258
259 static int
260 lst_group_update_ioctl(struct lstio_group_update_args *args)
261 {
262         int rc;
263         char *name;
264
265         if (args->lstio_grp_key != console_session.ses_key)
266                 return -EACCES;
267
268         if (args->lstio_grp_resultp == NULL ||
269             args->lstio_grp_namep == NULL ||
270             args->lstio_grp_nmlen <= 0 ||
271             args->lstio_grp_nmlen > LST_NAME_SIZE)
272                 return -EINVAL;
273
274         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
275         if (name == NULL)
276                 return -ENOMEM;
277
278         if (copy_from_user(name, args->lstio_grp_namep,
279                            args->lstio_grp_nmlen)) {
280                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
281                 return -EFAULT;
282         }
283
284         name[args->lstio_grp_nmlen] = 0;
285
286         switch (args->lstio_grp_opc) {
287         case LST_GROUP_CLEAN:
288                 rc = lstcon_group_clean(name, args->lstio_grp_args);
289                 break;
290
291         case LST_GROUP_REFRESH:
292                 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
293                 break;
294
295         case LST_GROUP_RMND:
296                 if (args->lstio_grp_count <= 0 ||
297                     args->lstio_grp_idsp == NULL) {
298                         rc = -EINVAL;
299                         break;
300                 }
301                 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
302                                          args->lstio_grp_idsp,
303                                          args->lstio_grp_resultp);
304                 break;
305
306         default:
307                 rc = -EINVAL;
308                 break;
309         }
310
311         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
312
313         return rc;
314 }
315
316 static int
317 lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
318 {
319         unsigned int feats;
320         int rc;
321         char *name;
322
323         if (args->lstio_grp_key != console_session.ses_key)
324                 return -EACCES;
325
326         if (args->lstio_grp_idsp == NULL || /* array of ids */
327             args->lstio_grp_count <= 0 ||
328             args->lstio_grp_resultp == NULL ||
329             args->lstio_grp_featp == NULL ||
330             args->lstio_grp_namep == NULL ||
331             args->lstio_grp_nmlen <= 0 ||
332             args->lstio_grp_nmlen > LST_NAME_SIZE)
333                 return -EINVAL;
334
335         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
336         if (name == NULL)
337                 return -ENOMEM;
338
339         if (copy_from_user(name, args->lstio_grp_namep,
340                            args->lstio_grp_nmlen)) {
341                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
342
343                 return -EFAULT;
344         }
345
346         name[args->lstio_grp_nmlen] = 0;
347
348         rc = lstcon_nodes_add(name, args->lstio_grp_count,
349                               args->lstio_grp_idsp, &feats,
350                               args->lstio_grp_resultp);
351
352         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
353         if (rc == 0 &&
354             copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
355                 return -EINVAL;
356         }
357
358         return rc;
359 }
360
361 static int
362 lst_group_list_ioctl(struct lstio_group_list_args *args)
363 {
364         if (args->lstio_grp_key != console_session.ses_key)
365                 return -EACCES;
366
367         if (args->lstio_grp_idx   < 0 ||
368             args->lstio_grp_namep == NULL ||
369             args->lstio_grp_nmlen <= 0 ||
370             args->lstio_grp_nmlen > LST_NAME_SIZE)
371                 return -EINVAL;
372
373         return lstcon_group_list(args->lstio_grp_idx,
374                                  args->lstio_grp_nmlen,
375                                  args->lstio_grp_namep);
376 }
377
378 static int
379 lst_group_info_ioctl(struct lstio_group_info_args *args)
380 {
381         char *name;
382         int ndent;
383         int index;
384         int rc;
385
386         if (args->lstio_grp_key != console_session.ses_key)
387                 return -EACCES;
388
389         if (args->lstio_grp_namep == NULL ||
390             args->lstio_grp_nmlen <= 0 ||
391             args->lstio_grp_nmlen > LST_NAME_SIZE)
392                 return -EINVAL;
393
394         if (args->lstio_grp_entp == NULL && /* output: group entry */
395             args->lstio_grp_dentsp == NULL)  /* output: node entry */
396                 return -EINVAL;
397
398         if (args->lstio_grp_dentsp != NULL) { /* have node entry */
399                 if (args->lstio_grp_idxp == NULL || /* node index */
400                     args->lstio_grp_ndentp == NULL) /* # of node entry */
401                         return -EINVAL;
402
403                 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
404                                    sizeof(ndent)) ||
405                     copy_from_user(&index, args->lstio_grp_idxp,
406                                    sizeof(index)))
407                         return -EFAULT;
408
409                 if (ndent <= 0 || index < 0)
410                         return -EINVAL;
411         }
412
413         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
414         if (name == NULL)
415                 return -ENOMEM;
416
417         if (copy_from_user(name, args->lstio_grp_namep,
418                            args->lstio_grp_nmlen)) {
419                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
420                 return -EFAULT;
421         }
422
423         name[args->lstio_grp_nmlen] = 0;
424
425         rc = lstcon_group_info(name, args->lstio_grp_entp,
426                                &index, &ndent, args->lstio_grp_dentsp);
427
428         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
429
430         if (rc != 0)
431                 return rc;
432
433         if (args->lstio_grp_dentsp != NULL &&
434             (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
435              copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
436                 return -EFAULT;
437
438         return 0;
439 }
440
441 static int
442 lst_batch_add_ioctl(struct lstio_batch_add_args *args)
443 {
444         int rc;
445         char *name;
446
447         if (args->lstio_bat_key != console_session.ses_key)
448                 return -EACCES;
449
450         if (args->lstio_bat_namep == NULL ||
451             args->lstio_bat_nmlen <= 0 ||
452             args->lstio_bat_nmlen > LST_NAME_SIZE)
453                 return -EINVAL;
454
455         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
456         if (name == NULL)
457                 return -ENOMEM;
458
459         if (copy_from_user(name, args->lstio_bat_namep,
460                            args->lstio_bat_nmlen)) {
461                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
462                 return -EFAULT;
463         }
464
465         name[args->lstio_bat_nmlen] = 0;
466
467         rc = lstcon_batch_add(name);
468
469         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
470
471         return rc;
472 }
473
474 static int
475 lst_batch_run_ioctl(struct lstio_batch_run_args *args)
476 {
477         int rc;
478         char *name;
479
480         if (args->lstio_bat_key != console_session.ses_key)
481                 return -EACCES;
482
483         if (args->lstio_bat_namep == NULL ||
484             args->lstio_bat_nmlen <= 0 ||
485             args->lstio_bat_nmlen > LST_NAME_SIZE)
486                 return -EINVAL;
487
488         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
489         if (name == NULL)
490                 return -ENOMEM;
491
492         if (copy_from_user(name, args->lstio_bat_namep,
493                            args->lstio_bat_nmlen)) {
494                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
495                 return -EFAULT;
496         }
497
498         name[args->lstio_bat_nmlen] = 0;
499
500         rc = lstcon_batch_run(name, args->lstio_bat_timeout,
501                               args->lstio_bat_resultp);
502
503         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
504
505         return rc;
506 }
507
508 static int
509 lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
510 {
511         int rc;
512         char *name;
513
514         if (args->lstio_bat_key != console_session.ses_key)
515                 return -EACCES;
516
517         if (args->lstio_bat_resultp == NULL ||
518             args->lstio_bat_namep == NULL ||
519             args->lstio_bat_nmlen <= 0 ||
520             args->lstio_bat_nmlen > LST_NAME_SIZE)
521                 return -EINVAL;
522
523         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
524         if (name == NULL)
525                 return -ENOMEM;
526
527         if (copy_from_user(name, args->lstio_bat_namep,
528                            args->lstio_bat_nmlen)) {
529                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
530                 return -EFAULT;
531         }
532
533         name[args->lstio_bat_nmlen] = 0;
534
535         rc = lstcon_batch_stop(name, args->lstio_bat_force,
536                                args->lstio_bat_resultp);
537
538         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
539
540         return rc;
541 }
542
543 static int
544 lst_batch_query_ioctl(struct lstio_batch_query_args *args)
545 {
546         char *name;
547         int rc;
548
549         if (args->lstio_bat_key != console_session.ses_key)
550                 return -EACCES;
551
552         if (args->lstio_bat_resultp == NULL ||
553             args->lstio_bat_namep == NULL ||
554             args->lstio_bat_nmlen <= 0 ||
555             args->lstio_bat_nmlen > LST_NAME_SIZE)
556                 return -EINVAL;
557
558         if (args->lstio_bat_testidx < 0)
559                 return -EINVAL;
560
561         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
562         if (name == NULL)
563                 return -ENOMEM;
564
565         if (copy_from_user(name, args->lstio_bat_namep,
566                            args->lstio_bat_nmlen)) {
567                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
568                 return -EFAULT;
569         }
570
571         name[args->lstio_bat_nmlen] = 0;
572
573         rc = lstcon_test_batch_query(name,
574                                      args->lstio_bat_testidx,
575                                      args->lstio_bat_client,
576                                      args->lstio_bat_timeout,
577                                      args->lstio_bat_resultp);
578
579         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
580
581         return rc;
582 }
583
584 static int
585 lst_batch_list_ioctl(struct lstio_batch_list_args *args)
586 {
587         if (args->lstio_bat_key != console_session.ses_key)
588                 return -EACCES;
589
590         if (args->lstio_bat_idx < 0 ||
591             args->lstio_bat_namep == NULL ||
592             args->lstio_bat_nmlen <= 0 ||
593             args->lstio_bat_nmlen > LST_NAME_SIZE)
594                 return -EINVAL;
595
596         return lstcon_batch_list(args->lstio_bat_idx,
597                                  args->lstio_bat_nmlen,
598                                  args->lstio_bat_namep);
599 }
600
601 static int
602 lst_batch_info_ioctl(struct lstio_batch_info_args *args)
603 {
604         char *name;
605         int rc;
606         int index;
607         int ndent;
608
609         if (args->lstio_bat_key != console_session.ses_key)
610                 return -EACCES;
611
612         if (args->lstio_bat_namep == NULL || /* batch name */
613             args->lstio_bat_nmlen <= 0 ||
614             args->lstio_bat_nmlen > LST_NAME_SIZE)
615                 return -EINVAL;
616
617         if (args->lstio_bat_entp == NULL && /* output: batch entry */
618             args->lstio_bat_dentsp == NULL) /* output: node entry */
619                 return -EINVAL;
620
621         if (args->lstio_bat_dentsp != NULL) { /* have node entry */
622                 if (args->lstio_bat_idxp == NULL || /* node index */
623                     args->lstio_bat_ndentp == NULL) /* # of node entry */
624                         return -EINVAL;
625
626                 if (copy_from_user(&index, args->lstio_bat_idxp,
627                                    sizeof(index)) ||
628                     copy_from_user(&ndent, args->lstio_bat_ndentp,
629                                    sizeof(ndent)))
630                         return -EFAULT;
631
632                 if (ndent <= 0 || index < 0)
633                         return -EINVAL;
634         }
635
636         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
637         if (name == NULL)
638                 return -ENOMEM;
639
640         if (copy_from_user(name, args->lstio_bat_namep,
641                            args->lstio_bat_nmlen)) {
642                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
643                 return -EFAULT;
644         }
645
646         name[args->lstio_bat_nmlen] = 0;
647
648         rc = lstcon_batch_info(name,
649                                args->lstio_bat_entp, args->lstio_bat_server,
650                                args->lstio_bat_testidx, &index, &ndent,
651                                args->lstio_bat_dentsp);
652
653         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
654
655         if (rc != 0)
656                 return rc;
657
658         if (args->lstio_bat_dentsp != NULL &&
659             (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
660              copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
661                 rc = -EFAULT;
662
663         return rc;
664 }
665
666 static int
667 lst_stat_query_ioctl(struct lstio_stat_args *args)
668 {
669         int rc;
670         char *name = NULL;
671
672         /* TODO: not finished */
673         if (args->lstio_sta_key != console_session.ses_key)
674                 return -EACCES;
675
676         if (args->lstio_sta_resultp == NULL)
677                 return -EINVAL;
678
679         if (args->lstio_sta_idsp != NULL) {
680                 if (args->lstio_sta_count <= 0)
681                         return -EINVAL;
682
683                 rc = lstcon_nodes_stat(args->lstio_sta_count,
684                                        args->lstio_sta_idsp,
685                                        args->lstio_sta_timeout,
686                                        args->lstio_sta_resultp);
687         } else if (args->lstio_sta_namep != NULL) {
688                 if (args->lstio_sta_nmlen <= 0 ||
689                     args->lstio_sta_nmlen > LST_NAME_SIZE)
690                         return -EINVAL;
691
692                 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
693                 if (name == NULL)
694                         return -ENOMEM;
695
696                 rc = copy_from_user(name, args->lstio_sta_namep,
697                                     args->lstio_sta_nmlen);
698                 if (rc == 0)
699                         rc = lstcon_group_stat(name, args->lstio_sta_timeout,
700                                                args->lstio_sta_resultp);
701                 else
702                         rc = -EFAULT;
703
704         } else {
705                 rc = -EINVAL;
706         }
707
708         if (name != NULL)
709                 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
710         return rc;
711 }
712
713 static int lst_test_add_ioctl(struct lstio_test_args *args)
714 {
715         char *batch_name;
716         char *src_name = NULL;
717         char *dst_name = NULL;
718         void *param = NULL;
719         int ret = 0;
720         int rc = -ENOMEM;
721
722         if (args->lstio_tes_resultp == NULL ||
723             args->lstio_tes_retp == NULL ||
724             args->lstio_tes_bat_name == NULL || /* no specified batch */
725             args->lstio_tes_bat_nmlen <= 0 ||
726             args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
727             args->lstio_tes_sgrp_name == NULL || /* no source group */
728             args->lstio_tes_sgrp_nmlen <= 0 ||
729             args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
730             args->lstio_tes_dgrp_name == NULL || /* no target group */
731             args->lstio_tes_dgrp_nmlen <= 0 ||
732             args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
733                 return -EINVAL;
734
735         if (args->lstio_tes_loop == 0 || /* negative is infinite */
736             args->lstio_tes_concur <= 0 ||
737             args->lstio_tes_dist <= 0 ||
738             args->lstio_tes_span <= 0)
739                 return -EINVAL;
740
741         /* have parameter, check if parameter length is valid */
742         if (args->lstio_tes_param != NULL &&
743             (args->lstio_tes_param_len <= 0 ||
744              args->lstio_tes_param_len >
745              PAGE_SIZE - sizeof(struct lstcon_test)))
746                 return -EINVAL;
747
748         LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
749         if (batch_name == NULL)
750                 return rc;
751
752         LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
753         if (src_name == NULL)
754                 goto out;
755
756         LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
757         if (dst_name == NULL)
758                 goto out;
759
760         if (args->lstio_tes_param != NULL) {
761                 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
762                 if (param == NULL)
763                         goto out;
764                 if (copy_from_user(param, args->lstio_tes_param,
765                                    args->lstio_tes_param_len)) {
766                         rc = -EFAULT;
767                         goto out;
768                 }
769         }
770
771         rc = -EFAULT;
772         if (copy_from_user(batch_name, args->lstio_tes_bat_name,
773                            args->lstio_tes_bat_nmlen) ||
774             copy_from_user(src_name, args->lstio_tes_sgrp_name,
775                            args->lstio_tes_sgrp_nmlen) ||
776             copy_from_user(dst_name, args->lstio_tes_dgrp_name,
777                            args->lstio_tes_dgrp_nmlen))
778                 goto out;
779
780         rc = lstcon_test_add(batch_name,
781                              args->lstio_tes_type,
782                              args->lstio_tes_loop,
783                              args->lstio_tes_concur,
784                              args->lstio_tes_dist, args->lstio_tes_span,
785                              src_name, dst_name, param,
786                              args->lstio_tes_param_len,
787                              &ret, args->lstio_tes_resultp);
788
789         if (ret != 0)
790                 rc = (copy_to_user(args->lstio_tes_retp, &ret,
791                                    sizeof(ret))) ? -EFAULT : 0;
792 out:
793         if (batch_name != NULL)
794                 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
795
796         if (src_name != NULL)
797                 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
798
799         if (dst_name != NULL)
800                 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
801
802         if (param != NULL)
803                 LIBCFS_FREE(param, args->lstio_tes_param_len);
804
805         return rc;
806 }
807
808 int
809 lstcon_ioctl_entry(struct notifier_block *nb,
810                    unsigned long cmd, void *vdata)
811 {
812         struct libcfs_ioctl_hdr *hdr = vdata;
813         struct libcfs_ioctl_data *data;
814         char *buf = NULL;
815         int rc = -EINVAL;
816         int opc;
817
818         if (cmd != IOC_LIBCFS_LNETST)
819                 goto err;
820
821         data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
822
823         opc = data->ioc_u32[0];
824
825         if (data->ioc_plen1 > PAGE_SIZE)
826                 goto err;
827
828         LIBCFS_ALLOC(buf, data->ioc_plen1);
829         if (buf == NULL) {
830                 rc = -ENOMEM;
831                 goto err;
832         }
833
834         /* copy in parameter */
835         if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
836                 rc = -EFAULT;
837                 goto out_free_buf;
838         }
839
840         mutex_lock(&console_session.ses_mutex);
841
842         console_session.ses_laststamp = ktime_get_real_seconds();
843
844         if (console_session.ses_shutdown) {
845                 rc = -ESHUTDOWN;
846                 goto out;
847         }
848
849         if (console_session.ses_expired)
850                 lstcon_session_end();
851
852         if (opc != LSTIO_SESSION_NEW &&
853             console_session.ses_state == LST_SESSION_NONE) {
854                 CDEBUG(D_NET, "LST no active session\n");
855                 rc = -ESRCH;
856                 goto out;
857         }
858
859         memset(&console_session.ses_trans_stat, 0,
860                sizeof(struct lstcon_trans_stat));
861
862         switch (opc) {
863         case LSTIO_SESSION_NEW:
864                 rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
865                 break;
866         case LSTIO_SESSION_END:
867                 rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
868                 break;
869         case LSTIO_SESSION_INFO:
870                 rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
871                 break;
872         case LSTIO_DEBUG:
873                 rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
874                 break;
875         case LSTIO_GROUP_ADD:
876                 rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
877                 break;
878         case LSTIO_GROUP_DEL:
879                 rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
880                 break;
881         case LSTIO_GROUP_UPDATE:
882                 rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
883                 break;
884         case LSTIO_NODES_ADD:
885                 rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
886                 break;
887         case LSTIO_GROUP_LIST:
888                 rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
889                 break;
890         case LSTIO_GROUP_INFO:
891                 rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
892                 break;
893         case LSTIO_BATCH_ADD:
894                 rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
895                 break;
896         case LSTIO_BATCH_START:
897                 rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
898                 break;
899         case LSTIO_BATCH_STOP:
900                 rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
901                 break;
902         case LSTIO_BATCH_QUERY:
903                 rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
904                 break;
905         case LSTIO_BATCH_LIST:
906                 rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
907                 break;
908         case LSTIO_BATCH_INFO:
909                 rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
910                 break;
911         case LSTIO_TEST_ADD:
912                 rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
913                 break;
914         case LSTIO_STAT_QUERY:
915                 rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
916                 break;
917         default:
918                 rc = -EINVAL;
919                 goto out;
920         }
921
922         if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
923                          sizeof(struct lstcon_trans_stat)))
924                 rc = -EFAULT;
925 out:
926         mutex_unlock(&console_session.ses_mutex);
927 out_free_buf:
928         LIBCFS_FREE(buf, data->ioc_plen1);
929 err:
930         return notifier_from_ioctl_errno(rc);
931 }