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