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