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, 2014, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lnet/selftest/conctl.c
33 * IOC handle in kernel
35 * Author: Liang Zhen <liangzhen@clusterfs.com>
38 #include <libcfs/linux/linux-net.h>
39 #include <libcfs/libcfs.h>
40 #include <lnet/lib-lnet.h>
44 lst_debug_ioctl(struct lstio_debug_args *args)
50 if (args->lstio_dbg_key != console_session.ses_key)
53 if (args->lstio_dbg_resultp == NULL)
56 if (args->lstio_dbg_namep != NULL && /* name of batch/group */
57 (args->lstio_dbg_nmlen <= 0 ||
58 args->lstio_dbg_nmlen > LST_NAME_SIZE))
61 if (args->lstio_dbg_namep != NULL) {
62 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
66 if (copy_from_user(name, args->lstio_dbg_namep,
67 args->lstio_dbg_nmlen)) {
68 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
73 name[args->lstio_dbg_nmlen] = 0;
78 switch (args->lstio_dbg_type) {
80 rc = lstcon_session_debug(args->lstio_dbg_timeout,
81 args->lstio_dbg_resultp);
84 case LST_OPC_BATCHSRV:
87 case LST_OPC_BATCHCLI:
91 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
92 name, client, args->lstio_dbg_resultp);
99 rc = lstcon_group_debug(args->lstio_dbg_timeout,
100 name, args->lstio_dbg_resultp);
104 if (args->lstio_dbg_count <= 0 ||
105 args->lstio_dbg_idsp == NULL)
108 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
109 args->lstio_dbg_count,
110 args->lstio_dbg_idsp,
111 args->lstio_dbg_resultp);
120 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
126 lst_group_add_ioctl(struct lstio_group_add_args *args)
131 if (args->lstio_grp_key != console_session.ses_key)
134 if (args->lstio_grp_namep == NULL ||
135 args->lstio_grp_nmlen <= 0 ||
136 args->lstio_grp_nmlen > LST_NAME_SIZE)
139 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
143 if (copy_from_user(name, args->lstio_grp_namep,
144 args->lstio_grp_nmlen)) {
145 LIBCFS_FREE(name, args->lstio_grp_nmlen);
149 name[args->lstio_grp_nmlen] = 0;
151 rc = lstcon_group_add(name);
153 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
159 lst_group_del_ioctl(struct lstio_group_del_args *args)
164 if (args->lstio_grp_key != console_session.ses_key)
167 if (args->lstio_grp_namep == NULL ||
168 args->lstio_grp_nmlen <= 0 ||
169 args->lstio_grp_nmlen > LST_NAME_SIZE)
172 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
176 if (copy_from_user(name, args->lstio_grp_namep,
177 args->lstio_grp_nmlen)) {
178 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
182 name[args->lstio_grp_nmlen] = 0;
184 rc = lstcon_group_del(name);
186 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
192 lst_group_update_ioctl(struct lstio_group_update_args *args)
197 if (args->lstio_grp_key != console_session.ses_key)
200 if (args->lstio_grp_resultp == NULL ||
201 args->lstio_grp_namep == NULL ||
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 + 1);
216 name[args->lstio_grp_nmlen] = 0;
218 switch (args->lstio_grp_opc) {
219 case LST_GROUP_CLEAN:
220 rc = lstcon_group_clean(name, args->lstio_grp_args);
223 case LST_GROUP_REFRESH:
224 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
228 if (args->lstio_grp_count <= 0 ||
229 args->lstio_grp_idsp == NULL) {
233 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
234 args->lstio_grp_idsp,
235 args->lstio_grp_resultp);
243 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
249 lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
255 if (args->lstio_grp_key != console_session.ses_key)
258 if (args->lstio_grp_idsp == NULL || /* array of ids */
259 args->lstio_grp_count <= 0 ||
260 args->lstio_grp_resultp == NULL ||
261 args->lstio_grp_featp == NULL ||
262 args->lstio_grp_namep == NULL ||
263 args->lstio_grp_nmlen <= 0 ||
264 args->lstio_grp_nmlen > LST_NAME_SIZE)
267 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
271 if (copy_from_user(name, args->lstio_grp_namep,
272 args->lstio_grp_nmlen)) {
273 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
278 name[args->lstio_grp_nmlen] = 0;
280 rc = lstcon_nodes_add(name, args->lstio_grp_count,
281 args->lstio_grp_idsp, &feats,
282 args->lstio_grp_resultp);
284 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
286 copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
294 lst_group_list_ioctl(struct lstio_group_list_args *args)
296 if (args->lstio_grp_key != console_session.ses_key)
299 if (args->lstio_grp_idx < 0 ||
300 args->lstio_grp_namep == NULL ||
301 args->lstio_grp_nmlen <= 0 ||
302 args->lstio_grp_nmlen > LST_NAME_SIZE)
305 return lstcon_group_list(args->lstio_grp_idx,
306 args->lstio_grp_nmlen,
307 args->lstio_grp_namep);
311 lst_group_info_ioctl(struct lstio_group_info_args *args)
318 if (args->lstio_grp_key != console_session.ses_key)
321 if (args->lstio_grp_namep == NULL ||
322 args->lstio_grp_nmlen <= 0 ||
323 args->lstio_grp_nmlen > LST_NAME_SIZE)
326 if (args->lstio_grp_entp == NULL && /* output: group entry */
327 args->lstio_grp_dentsp == NULL) /* output: node entry */
330 if (args->lstio_grp_dentsp != NULL) { /* have node entry */
331 if (args->lstio_grp_idxp == NULL || /* node index */
332 args->lstio_grp_ndentp == NULL) /* # of node entry */
335 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
337 copy_from_user(&index, args->lstio_grp_idxp,
341 if (ndent <= 0 || index < 0)
345 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
349 if (copy_from_user(name, args->lstio_grp_namep,
350 args->lstio_grp_nmlen)) {
351 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
355 name[args->lstio_grp_nmlen] = 0;
357 rc = lstcon_group_info(name, args->lstio_grp_entp,
358 &index, &ndent, args->lstio_grp_dentsp);
360 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
365 if (args->lstio_grp_dentsp != NULL &&
366 (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
367 copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
374 lst_batch_add_ioctl(struct lstio_batch_add_args *args)
379 if (args->lstio_bat_key != console_session.ses_key)
382 if (args->lstio_bat_namep == NULL ||
383 args->lstio_bat_nmlen <= 0 ||
384 args->lstio_bat_nmlen > LST_NAME_SIZE)
387 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
391 if (copy_from_user(name, args->lstio_bat_namep,
392 args->lstio_bat_nmlen)) {
393 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
397 name[args->lstio_bat_nmlen] = 0;
399 rc = lstcon_batch_add(name);
401 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
407 lst_batch_run_ioctl(struct lstio_batch_run_args *args)
412 if (args->lstio_bat_key != console_session.ses_key)
415 if (args->lstio_bat_namep == NULL ||
416 args->lstio_bat_nmlen <= 0 ||
417 args->lstio_bat_nmlen > LST_NAME_SIZE)
420 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
424 if (copy_from_user(name, args->lstio_bat_namep,
425 args->lstio_bat_nmlen)) {
426 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
430 name[args->lstio_bat_nmlen] = 0;
432 rc = lstcon_batch_run(name, args->lstio_bat_timeout,
433 args->lstio_bat_resultp);
435 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
441 lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
446 if (args->lstio_bat_key != console_session.ses_key)
449 if (args->lstio_bat_resultp == NULL ||
450 args->lstio_bat_namep == NULL ||
451 args->lstio_bat_nmlen <= 0 ||
452 args->lstio_bat_nmlen > LST_NAME_SIZE)
455 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
459 if (copy_from_user(name, args->lstio_bat_namep,
460 args->lstio_bat_nmlen)) {
461 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
465 name[args->lstio_bat_nmlen] = 0;
467 rc = lstcon_batch_stop(name, args->lstio_bat_force,
468 args->lstio_bat_resultp);
470 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
476 lst_batch_query_ioctl(struct lstio_batch_query_args *args)
481 if (args->lstio_bat_key != console_session.ses_key)
484 if (args->lstio_bat_resultp == NULL ||
485 args->lstio_bat_namep == NULL ||
486 args->lstio_bat_nmlen <= 0 ||
487 args->lstio_bat_nmlen > LST_NAME_SIZE)
490 if (args->lstio_bat_testidx < 0)
493 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
497 if (copy_from_user(name, args->lstio_bat_namep,
498 args->lstio_bat_nmlen)) {
499 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
503 name[args->lstio_bat_nmlen] = 0;
505 rc = lstcon_test_batch_query(name,
506 args->lstio_bat_testidx,
507 args->lstio_bat_client,
508 args->lstio_bat_timeout,
509 args->lstio_bat_resultp);
511 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
517 lst_batch_list_ioctl(struct lstio_batch_list_args *args)
519 if (args->lstio_bat_key != console_session.ses_key)
522 if (args->lstio_bat_idx < 0 ||
523 args->lstio_bat_namep == NULL ||
524 args->lstio_bat_nmlen <= 0 ||
525 args->lstio_bat_nmlen > LST_NAME_SIZE)
528 return lstcon_batch_list(args->lstio_bat_idx,
529 args->lstio_bat_nmlen,
530 args->lstio_bat_namep);
534 lst_batch_info_ioctl(struct lstio_batch_info_args *args)
541 if (args->lstio_bat_key != console_session.ses_key)
544 if (args->lstio_bat_namep == NULL || /* batch name */
545 args->lstio_bat_nmlen <= 0 ||
546 args->lstio_bat_nmlen > LST_NAME_SIZE)
549 if (args->lstio_bat_entp == NULL && /* output: batch entry */
550 args->lstio_bat_dentsp == NULL) /* output: node entry */
553 if (args->lstio_bat_dentsp != NULL) { /* have node entry */
554 if (args->lstio_bat_idxp == NULL || /* node index */
555 args->lstio_bat_ndentp == NULL) /* # of node entry */
558 if (copy_from_user(&index, args->lstio_bat_idxp,
560 copy_from_user(&ndent, args->lstio_bat_ndentp,
564 if (ndent <= 0 || index < 0)
568 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
572 if (copy_from_user(name, args->lstio_bat_namep,
573 args->lstio_bat_nmlen)) {
574 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
578 name[args->lstio_bat_nmlen] = 0;
580 rc = lstcon_batch_info(name,
581 args->lstio_bat_entp, args->lstio_bat_server,
582 args->lstio_bat_testidx, &index, &ndent,
583 args->lstio_bat_dentsp);
585 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
590 if (args->lstio_bat_dentsp != NULL &&
591 (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
592 copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
599 lst_stat_query_ioctl(struct lstio_stat_args *args)
604 /* TODO: not finished */
605 if (args->lstio_sta_key != console_session.ses_key)
608 if (args->lstio_sta_resultp == NULL)
611 if (args->lstio_sta_idsp != NULL) {
612 if (args->lstio_sta_count <= 0)
615 rc = lstcon_nodes_stat(args->lstio_sta_count,
616 args->lstio_sta_idsp,
617 args->lstio_sta_timeout,
618 args->lstio_sta_resultp);
619 } else if (args->lstio_sta_namep != NULL) {
620 if (args->lstio_sta_nmlen <= 0 ||
621 args->lstio_sta_nmlen > LST_NAME_SIZE)
624 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
628 rc = copy_from_user(name, args->lstio_sta_namep,
629 args->lstio_sta_nmlen);
631 rc = lstcon_group_stat(name, args->lstio_sta_timeout,
632 args->lstio_sta_resultp);
641 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
645 static int lst_test_add_ioctl(struct lstio_test_args *args)
648 char *src_name = NULL;
649 char *dst_name = NULL;
654 if (args->lstio_tes_resultp == NULL ||
655 args->lstio_tes_retp == NULL ||
656 args->lstio_tes_bat_name == NULL || /* no specified batch */
657 args->lstio_tes_bat_nmlen <= 0 ||
658 args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
659 args->lstio_tes_sgrp_name == NULL || /* no source group */
660 args->lstio_tes_sgrp_nmlen <= 0 ||
661 args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
662 args->lstio_tes_dgrp_name == NULL || /* no target group */
663 args->lstio_tes_dgrp_nmlen <= 0 ||
664 args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
667 if (args->lstio_tes_loop == 0 || /* negative is infinite */
668 args->lstio_tes_concur <= 0 ||
669 args->lstio_tes_dist <= 0 ||
670 args->lstio_tes_span <= 0)
673 /* have parameter, check if parameter length is valid */
674 if (args->lstio_tes_param != NULL &&
675 (args->lstio_tes_param_len <= 0 ||
676 args->lstio_tes_param_len >
677 PAGE_SIZE - sizeof(struct lstcon_test)))
680 LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
681 if (batch_name == NULL)
684 LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
685 if (src_name == NULL)
688 LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
689 if (dst_name == NULL)
692 if (args->lstio_tes_param != NULL) {
693 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
696 if (copy_from_user(param, args->lstio_tes_param,
697 args->lstio_tes_param_len)) {
704 if (copy_from_user(batch_name, args->lstio_tes_bat_name,
705 args->lstio_tes_bat_nmlen) ||
706 copy_from_user(src_name, args->lstio_tes_sgrp_name,
707 args->lstio_tes_sgrp_nmlen) ||
708 copy_from_user(dst_name, args->lstio_tes_dgrp_name,
709 args->lstio_tes_dgrp_nmlen))
712 rc = lstcon_test_add(batch_name,
713 args->lstio_tes_type,
714 args->lstio_tes_loop,
715 args->lstio_tes_concur,
716 args->lstio_tes_dist, args->lstio_tes_span,
717 src_name, dst_name, param,
718 args->lstio_tes_param_len,
719 &ret, args->lstio_tes_resultp);
722 rc = (copy_to_user(args->lstio_tes_retp, &ret,
723 sizeof(ret))) ? -EFAULT : 0;
725 if (batch_name != NULL)
726 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
728 if (src_name != NULL)
729 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
731 if (dst_name != NULL)
732 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
735 LIBCFS_FREE(param, args->lstio_tes_param_len);
741 lstcon_ioctl_entry(struct notifier_block *nb,
742 unsigned long cmd, void *vdata)
744 struct libcfs_ioctl_hdr *hdr = vdata;
745 struct libcfs_ioctl_data *data;
750 if (cmd != IOC_LIBCFS_LNETST)
753 data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
755 opc = data->ioc_u32[0];
757 if (data->ioc_plen1 > PAGE_SIZE)
760 LIBCFS_ALLOC(buf, data->ioc_plen1);
766 /* copy in parameter */
767 if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
772 mutex_lock(&console_session.ses_mutex);
774 console_session.ses_laststamp = ktime_get_real_seconds();
776 if (console_session.ses_shutdown) {
781 if (console_session.ses_expired)
782 lstcon_session_end();
784 if (opc != LSTIO_SESSION_NEW &&
785 console_session.ses_state == LST_SESSION_NONE) {
786 CDEBUG(D_NET, "LST no active session\n");
791 memset(&console_session.ses_trans_stat, 0,
792 sizeof(struct lstcon_trans_stat));
795 case LSTIO_SESSION_NEW:
797 case LSTIO_SESSION_END:
799 case LSTIO_SESSION_INFO:
803 rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
805 case LSTIO_GROUP_ADD:
806 rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
808 case LSTIO_GROUP_DEL:
809 rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
811 case LSTIO_GROUP_UPDATE:
812 rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
814 case LSTIO_NODES_ADD:
815 rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
817 case LSTIO_GROUP_LIST:
818 rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
820 case LSTIO_GROUP_INFO:
821 rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
823 case LSTIO_BATCH_ADD:
824 rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
826 case LSTIO_BATCH_START:
827 rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
829 case LSTIO_BATCH_STOP:
830 rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
832 case LSTIO_BATCH_QUERY:
833 rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
835 case LSTIO_BATCH_LIST:
836 rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
838 case LSTIO_BATCH_INFO:
839 rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
842 rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
844 case LSTIO_STAT_QUERY:
845 rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
852 if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
853 sizeof(struct lstcon_trans_stat)))
856 mutex_unlock(&console_session.ses_mutex);
858 LIBCFS_FREE(buf, data->ioc_plen1);
860 return notifier_from_ioctl_errno(rc);
863 static struct genl_family lst_family;
865 static const struct ln_key_list lst_session_keys = {
866 .lkl_maxattr = LNET_SELFTEST_SESSION_MAX,
868 [LNET_SELFTEST_SESSION_HDR] = {
869 .lkp_value = "session",
870 .lkp_key_format = LNKF_MAPPING,
871 .lkp_data_type = NLA_NUL_STRING,
873 [LNET_SELFTEST_SESSION_NAME] = {
875 .lkp_data_type = NLA_STRING,
877 [LNET_SELFTEST_SESSION_KEY] = {
879 .lkp_data_type = NLA_U32,
881 [LNET_SELFTEST_SESSION_TIMESTAMP] = {
882 .lkp_value = "timestamp",
883 .lkp_data_type = NLA_S64,
885 [LNET_SELFTEST_SESSION_NID] = {
887 .lkp_data_type = NLA_STRING,
889 [LNET_SELFTEST_SESSION_NODE_COUNT] = {
890 .lkp_value = "nodes",
891 .lkp_data_type = NLA_U16,
896 static int lst_sessions_show_dump(struct sk_buff *msg,
897 struct netlink_callback *cb)
899 const struct ln_key_list *all[] = {
900 &lst_session_keys, NULL
902 #ifdef HAVE_NL_PARSE_WITH_EXT_ACK
903 struct netlink_ext_ack *extack = NULL;
905 int portid = NETLINK_CB(cb->skb).portid;
906 int seq = cb->nlh->nlmsg_seq;
907 unsigned int node_count = 0;
908 struct lstcon_ndlink *ndl;
909 int flag = NLM_F_MULTI;
913 #ifdef HAVE_NL_DUMP_WITH_EXT_ACK
916 if (console_session.ses_state != LST_SESSION_ACTIVE) {
917 NL_SET_ERR_MSG(extack, "session is not active");
918 GOTO(out_unlock, rc = -ESRCH);
921 list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
924 rc = lnet_genl_send_scalar_list(msg, portid, seq, &lst_family,
925 NLM_F_CREATE | NLM_F_MULTI,
926 LNET_SELFTEST_CMD_SESSIONS, all);
928 NL_SET_ERR_MSG(extack, "failed to send key table");
929 GOTO(out_unlock, rc);
932 if (console_session.ses_force)
933 flag |= NLM_F_REPLACE;
935 hdr = genlmsg_put(msg, portid, seq, &lst_family, flag,
936 LNET_SELFTEST_CMD_SESSIONS);
938 NL_SET_ERR_MSG(extack, "failed to send values");
939 genlmsg_cancel(msg, hdr);
940 GOTO(out_unlock, rc = -EMSGSIZE);
943 nla_put_string(msg, LNET_SELFTEST_SESSION_NAME,
944 console_session.ses_name);
945 nla_put_u32(msg, LNET_SELFTEST_SESSION_KEY,
946 console_session.ses_key);
947 nla_put_u64_64bit(msg, LNET_SELFTEST_SESSION_TIMESTAMP,
948 console_session.ses_id.ses_stamp,
949 LNET_SELFTEST_SESSION_PAD);
950 nla_put_string(msg, LNET_SELFTEST_SESSION_NID,
951 libcfs_nidstr(&console_session.ses_id.ses_nid));
952 nla_put_u16(msg, LNET_SELFTEST_SESSION_NODE_COUNT,
954 genlmsg_end(msg, hdr);
956 return lnet_nl_send_error(cb->skb, portid, seq, rc);
959 static int lst_sessions_cmd(struct sk_buff *skb, struct genl_info *info)
961 struct sk_buff *msg = NULL;
964 mutex_lock(&console_session.ses_mutex);
966 console_session.ses_laststamp = ktime_get_real_seconds();
968 if (console_session.ses_shutdown) {
969 GENL_SET_ERR_MSG(info, "session is shutdown");
970 GOTO(out_unlock, rc = -ESHUTDOWN);
973 if (console_session.ses_expired)
974 lstcon_session_end();
976 if (!(info->nlhdr->nlmsg_flags & NLM_F_CREATE) &&
977 console_session.ses_state == LST_SESSION_NONE) {
978 GENL_SET_ERR_MSG(info, "session is not active");
979 GOTO(out_unlock, rc = -ESRCH);
982 memset(&console_session.ses_trans_stat, 0,
983 sizeof(struct lstcon_trans_stat));
985 if (!(info->nlhdr->nlmsg_flags & NLM_F_CREATE)) {
986 lstcon_session_end();
987 GOTO(out_unlock, rc);
990 if (info->attrs[LN_SCALAR_ATTR_LIST]) {
991 struct genlmsghdr *gnlh = nlmsg_data(info->nlhdr);
992 const struct ln_key_list *all[] = {
993 &lst_session_keys, NULL
995 char name[LST_NAME_SIZE];
996 struct nlmsghdr *nlh;
1003 if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
1006 nla_for_each_nested(item, info->attrs[LN_SCALAR_ATTR_LIST],
1008 if (nla_type(item) != LN_SCALAR_ATTR_VALUE)
1011 if (nla_strcmp(item, "name") == 0) {
1014 item = nla_next(item, &rem);
1015 if (nla_type(item) != LN_SCALAR_ATTR_VALUE)
1016 GOTO(err_conf, rc = -EINVAL);
1018 len = nla_strscpy(name, item, sizeof(name));
1021 } else if (nla_strcmp(item, "timeout") == 0) {
1022 item = nla_next(item, &rem);
1023 if (nla_type(item) !=
1024 LN_SCALAR_ATTR_INT_VALUE)
1025 GOTO(err_conf, rc = -EINVAL);
1027 timeout = nla_get_s64(item);
1033 GENL_SET_ERR_MSG(info,
1034 "failed to get config");
1035 GOTO(out_unlock, rc);
1039 rc = lstcon_session_new(name, info->nlhdr->nlmsg_pid,
1040 gnlh->version, timeout,
1043 GENL_SET_ERR_MSG(info, "new session creation failed");
1044 lstcon_session_end();
1045 GOTO(out_unlock, rc);
1048 msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1050 GENL_SET_ERR_MSG(info, "msg allocation failed");
1051 GOTO(out_unlock, rc = -ENOMEM);
1054 rc = lnet_genl_send_scalar_list(msg, info->snd_portid,
1055 info->snd_seq, &lst_family,
1056 NLM_F_CREATE | NLM_F_MULTI,
1057 LNET_SELFTEST_CMD_SESSIONS,
1060 GENL_SET_ERR_MSG(info, "failed to send key table");
1061 GOTO(out_unlock, rc);
1064 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
1065 &lst_family, NLM_F_MULTI,
1066 LNET_SELFTEST_CMD_SESSIONS);
1068 GENL_SET_ERR_MSG(info, "failed to send values");
1069 genlmsg_cancel(msg, hdr);
1070 GOTO(out_unlock, rc = -EMSGSIZE);
1073 nla_put_string(msg, LNET_SELFTEST_SESSION_NAME,
1074 console_session.ses_name);
1075 nla_put_u32(msg, LNET_SELFTEST_SESSION_KEY,
1076 console_session.ses_key);
1077 nla_put_u64_64bit(msg, LNET_SELFTEST_SESSION_TIMESTAMP,
1078 console_session.ses_id.ses_stamp,
1079 LNET_SELFTEST_SESSION_PAD);
1080 nla_put_string(msg, LNET_SELFTEST_SESSION_NID,
1081 libcfs_nidstr(&console_session.ses_id.ses_nid));
1082 nla_put_u16(msg, LNET_SELFTEST_SESSION_NODE_COUNT, 0);
1084 genlmsg_end(msg, hdr);
1086 nlh = nlmsg_put(msg, info->snd_portid, info->snd_seq,
1087 NLMSG_DONE, 0, NLM_F_MULTI);
1089 GENL_SET_ERR_MSG(info, "failed to complete message");
1090 genlmsg_cancel(msg, hdr);
1091 GOTO(out_unlock, rc = -ENOMEM);
1093 rc = genlmsg_reply(msg, info);
1095 GENL_SET_ERR_MSG(info, "failed to send reply");
1100 mutex_unlock(&console_session.ses_mutex);
1104 static const struct genl_multicast_group lst_mcast_grps[] = {
1105 { .name = "sessions", },
1108 static const struct genl_ops lst_genl_ops[] = {
1110 .cmd = LNET_SELFTEST_CMD_SESSIONS,
1111 .dumpit = lst_sessions_show_dump,
1112 .doit = lst_sessions_cmd,
1116 static struct genl_family lst_family = {
1117 .name = LNET_SELFTEST_GENL_NAME,
1118 .version = LNET_SELFTEST_GENL_VERSION,
1119 .maxattr = LN_SCALAR_MAX,
1120 .module = THIS_MODULE,
1121 .ops = lst_genl_ops,
1122 .n_ops = ARRAY_SIZE(lst_genl_ops),
1123 .mcgrps = lst_mcast_grps,
1124 .n_mcgrps = ARRAY_SIZE(lst_mcast_grps),
1127 int lstcon_init_netlink(void)
1129 return genl_register_family(&lst_family);
1132 void lstcon_fini_netlink(void)
1134 genl_unregister_family(&lst_family);