4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2012, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lnet/selftest/conctl.c
34 * IOC handle in kernel
36 * Author: Liang Zhen <liangzhen@clusterfs.com>
39 #include <linux/libcfs/libcfs.h>
40 #include <linux/lnet/lib-lnet.h>
41 #include <uapi/linux/lnet/lnetst.h>
45 lst_session_new_ioctl(struct lstio_session_new_args *args)
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)
57 LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
61 if (copy_from_user(name, args->lstio_ses_namep,
62 args->lstio_ses_nmlen)) {
63 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
67 name[args->lstio_ses_nmlen] = 0;
69 rc = lstcon_session_new(name,
71 args->lstio_ses_feats,
72 args->lstio_ses_timeout,
73 args->lstio_ses_force,
76 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
81 lst_session_end_ioctl(struct lstio_session_end_args *args)
83 if (args->lstio_ses_key != console_session.ses_key)
86 return lstcon_session_end();
90 lst_session_info_ioctl(struct lstio_session_info_args *args)
92 /* no checking of key */
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)
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);
112 lst_debug_ioctl(struct lstio_debug_args *args)
118 if (args->lstio_dbg_key != console_session.ses_key)
121 if (!args->lstio_dbg_resultp)
124 if (args->lstio_dbg_namep && /* name of batch/group */
125 (args->lstio_dbg_nmlen <= 0 ||
126 args->lstio_dbg_nmlen > LST_NAME_SIZE))
129 if (args->lstio_dbg_namep) {
130 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
134 if (copy_from_user(name, args->lstio_dbg_namep,
135 args->lstio_dbg_nmlen)) {
136 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
141 name[args->lstio_dbg_nmlen] = 0;
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);
152 case LST_OPC_BATCHSRV:
154 case LST_OPC_BATCHCLI:
158 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
159 name, client, args->lstio_dbg_resultp);
166 rc = lstcon_group_debug(args->lstio_dbg_timeout,
167 name, args->lstio_dbg_resultp);
171 if (args->lstio_dbg_count <= 0 ||
172 !args->lstio_dbg_idsp)
175 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
176 args->lstio_dbg_count,
177 args->lstio_dbg_idsp,
178 args->lstio_dbg_resultp);
187 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
193 lst_group_add_ioctl(struct lstio_group_add_args *args)
198 if (args->lstio_grp_key != console_session.ses_key)
201 if (!args->lstio_grp_namep ||
202 args->lstio_grp_nmlen <= 0 ||
203 args->lstio_grp_nmlen > LST_NAME_SIZE)
206 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
210 if (copy_from_user(name, args->lstio_grp_namep,
211 args->lstio_grp_nmlen)) {
212 LIBCFS_FREE(name, args->lstio_grp_nmlen);
216 name[args->lstio_grp_nmlen] = 0;
218 rc = lstcon_group_add(name);
220 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
226 lst_group_del_ioctl(struct lstio_group_del_args *args)
231 if (args->lstio_grp_key != console_session.ses_key)
234 if (!args->lstio_grp_namep ||
235 args->lstio_grp_nmlen <= 0 ||
236 args->lstio_grp_nmlen > LST_NAME_SIZE)
239 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
243 if (copy_from_user(name, args->lstio_grp_namep,
244 args->lstio_grp_nmlen)) {
245 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
249 name[args->lstio_grp_nmlen] = 0;
251 rc = lstcon_group_del(name);
253 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
259 lst_group_update_ioctl(struct lstio_group_update_args *args)
264 if (args->lstio_grp_key != console_session.ses_key)
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)
273 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
277 if (copy_from_user(name, args->lstio_grp_namep,
278 args->lstio_grp_nmlen)) {
279 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
283 name[args->lstio_grp_nmlen] = 0;
285 switch (args->lstio_grp_opc) {
286 case LST_GROUP_CLEAN:
287 rc = lstcon_group_clean(name, args->lstio_grp_args);
290 case LST_GROUP_REFRESH:
291 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
295 if (args->lstio_grp_count <= 0 ||
296 !args->lstio_grp_idsp) {
300 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
301 args->lstio_grp_idsp,
302 args->lstio_grp_resultp);
310 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
316 lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
322 if (args->lstio_grp_key != console_session.ses_key)
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)
334 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
338 if (copy_from_user(name, args->lstio_grp_namep,
339 args->lstio_grp_nmlen)) {
340 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
345 name[args->lstio_grp_nmlen] = 0;
347 rc = lstcon_nodes_add(name, args->lstio_grp_count,
348 args->lstio_grp_idsp, &feats,
349 args->lstio_grp_resultp);
351 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
353 copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
361 lst_group_list_ioctl(struct lstio_group_list_args *args)
363 if (args->lstio_grp_key != console_session.ses_key)
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)
372 return lstcon_group_list(args->lstio_grp_idx,
373 args->lstio_grp_nmlen,
374 args->lstio_grp_namep);
378 lst_group_info_ioctl(struct lstio_group_info_args *args)
385 if (args->lstio_grp_key != console_session.ses_key)
388 if (!args->lstio_grp_namep ||
389 args->lstio_grp_nmlen <= 0 ||
390 args->lstio_grp_nmlen > LST_NAME_SIZE)
393 if (!args->lstio_grp_entp && /* output: group entry */
394 !args->lstio_grp_dentsp) /* output: node entry */
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 */
402 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
404 copy_from_user(&index, args->lstio_grp_idxp,
408 if (ndent <= 0 || index < 0)
412 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
416 if (copy_from_user(name, args->lstio_grp_namep,
417 args->lstio_grp_nmlen)) {
418 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
422 name[args->lstio_grp_nmlen] = 0;
424 rc = lstcon_group_info(name, args->lstio_grp_entp,
425 &index, &ndent, args->lstio_grp_dentsp);
427 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
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))))
441 lst_batch_add_ioctl(struct lstio_batch_add_args *args)
446 if (args->lstio_bat_key != console_session.ses_key)
449 if (!args->lstio_bat_namep ||
450 args->lstio_bat_nmlen <= 0 ||
451 args->lstio_bat_nmlen > LST_NAME_SIZE)
454 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
458 if (copy_from_user(name, args->lstio_bat_namep,
459 args->lstio_bat_nmlen)) {
460 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
464 name[args->lstio_bat_nmlen] = 0;
466 rc = lstcon_batch_add(name);
468 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
474 lst_batch_run_ioctl(struct lstio_batch_run_args *args)
479 if (args->lstio_bat_key != console_session.ses_key)
482 if (!args->lstio_bat_namep ||
483 args->lstio_bat_nmlen <= 0 ||
484 args->lstio_bat_nmlen > LST_NAME_SIZE)
487 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
491 if (copy_from_user(name, args->lstio_bat_namep,
492 args->lstio_bat_nmlen)) {
493 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
497 name[args->lstio_bat_nmlen] = 0;
499 rc = lstcon_batch_run(name, args->lstio_bat_timeout,
500 args->lstio_bat_resultp);
502 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
508 lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
513 if (args->lstio_bat_key != console_session.ses_key)
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)
522 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
526 if (copy_from_user(name, args->lstio_bat_namep,
527 args->lstio_bat_nmlen)) {
528 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
532 name[args->lstio_bat_nmlen] = 0;
534 rc = lstcon_batch_stop(name, args->lstio_bat_force,
535 args->lstio_bat_resultp);
537 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
543 lst_batch_query_ioctl(struct lstio_batch_query_args *args)
548 if (args->lstio_bat_key != console_session.ses_key)
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)
557 if (args->lstio_bat_testidx < 0)
560 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
564 if (copy_from_user(name, args->lstio_bat_namep,
565 args->lstio_bat_nmlen)) {
566 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
570 name[args->lstio_bat_nmlen] = 0;
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);
578 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
584 lst_batch_list_ioctl(struct lstio_batch_list_args *args)
586 if (args->lstio_bat_key != console_session.ses_key)
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)
595 return lstcon_batch_list(args->lstio_bat_idx,
596 args->lstio_bat_nmlen,
597 args->lstio_bat_namep);
601 lst_batch_info_ioctl(struct lstio_batch_info_args *args)
608 if (args->lstio_bat_key != console_session.ses_key)
611 if (!args->lstio_bat_namep || /* batch name */
612 args->lstio_bat_nmlen <= 0 ||
613 args->lstio_bat_nmlen > LST_NAME_SIZE)
616 if (!args->lstio_bat_entp && /* output: batch entry */
617 !args->lstio_bat_dentsp) /* output: node entry */
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 */
625 if (copy_from_user(&index, args->lstio_bat_idxp,
627 copy_from_user(&ndent, args->lstio_bat_ndentp,
631 if (ndent <= 0 || index < 0)
635 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
639 if (copy_from_user(name, args->lstio_bat_namep,
640 args->lstio_bat_nmlen)) {
641 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
645 name[args->lstio_bat_nmlen] = 0;
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);
651 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
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))))
665 lst_stat_query_ioctl(struct lstio_stat_args *args)
670 /* TODO: not finished */
671 if (args->lstio_sta_key != console_session.ses_key)
674 if (!args->lstio_sta_resultp)
677 if (args->lstio_sta_idsp) {
678 if (args->lstio_sta_count <= 0)
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)
690 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
694 rc = copy_from_user(name, args->lstio_sta_namep,
695 args->lstio_sta_nmlen);
697 rc = lstcon_group_stat(name, args->lstio_sta_timeout,
698 args->lstio_sta_resultp);
706 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
710 static int lst_test_add_ioctl(struct lstio_test_args *args)
713 char *src_name = NULL;
714 char *dst_name = NULL;
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)
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)
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)))
745 /* Enforce zero parameter length if there's no parameter */
746 if (!args->lstio_tes_param && args->lstio_tes_param_len)
749 LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
753 LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
757 LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
761 if (args->lstio_tes_param) {
762 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
765 if (copy_from_user(param, args->lstio_tes_param,
766 args->lstio_tes_param_len)) {
773 if (copy_from_user(batch_name, args->lstio_tes_bat_name,
774 args->lstio_tes_bat_nmlen) ||
775 copy_from_user(src_name, args->lstio_tes_sgrp_name,
776 args->lstio_tes_sgrp_nmlen) ||
777 copy_from_user(dst_name, args->lstio_tes_dgrp_name,
778 args->lstio_tes_dgrp_nmlen))
781 rc = lstcon_test_add(batch_name, args->lstio_tes_type,
782 args->lstio_tes_loop, 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);
789 rc = (copy_to_user(args->lstio_tes_retp, &ret,
790 sizeof(ret))) ? -EFAULT : 0;
793 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
796 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
799 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
802 LIBCFS_FREE(param, args->lstio_tes_param_len);
808 lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
811 struct libcfs_ioctl_data *data;
815 if (cmd != IOC_LIBCFS_LNETST)
818 data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
820 opc = data->ioc_u32[0];
822 if (data->ioc_plen1 > PAGE_SIZE)
825 LIBCFS_ALLOC(buf, data->ioc_plen1);
829 /* copy in parameter */
830 if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
831 LIBCFS_FREE(buf, data->ioc_plen1);
835 mutex_lock(&console_session.ses_mutex);
837 console_session.ses_laststamp = ktime_get_real_seconds();
839 if (console_session.ses_shutdown) {
844 if (console_session.ses_expired)
845 lstcon_session_end();
847 if (opc != LSTIO_SESSION_NEW &&
848 console_session.ses_state == LST_SESSION_NONE) {
849 CDEBUG(D_NET, "LST no active session\n");
854 memset(&console_session.ses_trans_stat, 0, sizeof(struct lstcon_trans_stat));
857 case LSTIO_SESSION_NEW:
858 rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
860 case LSTIO_SESSION_END:
861 rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
863 case LSTIO_SESSION_INFO:
864 rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
867 rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
869 case LSTIO_GROUP_ADD:
870 rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
872 case LSTIO_GROUP_DEL:
873 rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
875 case LSTIO_GROUP_UPDATE:
876 rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
878 case LSTIO_NODES_ADD:
879 rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
881 case LSTIO_GROUP_LIST:
882 rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
884 case LSTIO_GROUP_INFO:
885 rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
887 case LSTIO_BATCH_ADD:
888 rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
890 case LSTIO_BATCH_START:
891 rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
893 case LSTIO_BATCH_STOP:
894 rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
896 case LSTIO_BATCH_QUERY:
897 rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
899 case LSTIO_BATCH_LIST:
900 rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
902 case LSTIO_BATCH_INFO:
903 rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
906 rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
908 case LSTIO_STAT_QUERY:
909 rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
915 if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
916 sizeof(struct lstcon_trans_stat)))
919 mutex_unlock(&console_session.ses_mutex);
921 LIBCFS_FREE(buf, data->ioc_plen1);