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