| /* |
| * GPL HEADER START |
| * |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 only, |
| * as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License version 2 for more details (a copy is included |
| * in the LICENSE file that accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License |
| * version 2 along with this program; If not, see |
| * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| * |
| * GPL HEADER END |
| */ |
| /* |
| * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
| * Use is subject to license terms. |
| * |
| * Copyright (c) 2012, Intel Corporation. |
| */ |
| /* |
| * This file is part of Lustre, http://www.lustre.org/ |
| * Lustre is a trademark of Sun Microsystems, Inc. |
| * |
| * lnet/selftest/conctl.c |
| * |
| * IOC handle in kernel |
| * |
| * Author: Liang Zhen <liangzhen@clusterfs.com> |
| */ |
| |
| #include "../../include/linux/libcfs/libcfs.h" |
| #include "../../include/linux/lnet/lib-lnet.h" |
| #include "../../include/linux/lnet/lnetst.h" |
| #include "console.h" |
| |
| static int |
| lst_session_new_ioctl(lstio_session_new_args_t *args) |
| { |
| char *name; |
| int rc; |
| |
| if (args->lstio_ses_idp == NULL || /* address for output sid */ |
| args->lstio_ses_key == 0 || /* no key is specified */ |
| args->lstio_ses_namep == NULL || /* session name */ |
| args->lstio_ses_nmlen <= 0 || |
| args->lstio_ses_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_ses_namep, |
| args->lstio_ses_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_ses_nmlen] = 0; |
| |
| rc = lstcon_session_new(name, |
| args->lstio_ses_key, |
| args->lstio_ses_feats, |
| args->lstio_ses_force, |
| args->lstio_ses_timeout, |
| args->lstio_ses_idp); |
| |
| LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); |
| return rc; |
| } |
| |
| static int |
| lst_session_end_ioctl(lstio_session_end_args_t *args) |
| { |
| if (args->lstio_ses_key != console_session.ses_key) |
| return -EACCES; |
| |
| return lstcon_session_end(); |
| } |
| |
| static int |
| lst_session_info_ioctl(lstio_session_info_args_t *args) |
| { |
| /* no checking of key */ |
| |
| if (args->lstio_ses_idp == NULL || /* address for output sid */ |
| args->lstio_ses_keyp == NULL || /* address for output key */ |
| args->lstio_ses_featp == NULL || /* address for output features */ |
| args->lstio_ses_ndinfo == NULL || /* address for output ndinfo */ |
| args->lstio_ses_namep == NULL || /* address for output name */ |
| args->lstio_ses_nmlen <= 0 || |
| args->lstio_ses_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| return lstcon_session_info(args->lstio_ses_idp, |
| args->lstio_ses_keyp, |
| args->lstio_ses_featp, |
| args->lstio_ses_ndinfo, |
| args->lstio_ses_namep, |
| args->lstio_ses_nmlen); |
| } |
| |
| static int |
| lst_debug_ioctl(lstio_debug_args_t *args) |
| { |
| char *name = NULL; |
| int client = 1; |
| int rc; |
| |
| if (args->lstio_dbg_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_dbg_resultp == NULL) |
| return -EINVAL; |
| |
| if (args->lstio_dbg_namep != NULL && /* name of batch/group */ |
| (args->lstio_dbg_nmlen <= 0 || |
| args->lstio_dbg_nmlen > LST_NAME_SIZE)) |
| return -EINVAL; |
| |
| if (args->lstio_dbg_namep != NULL) { |
| LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, args->lstio_dbg_namep, |
| args->lstio_dbg_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); |
| |
| return -EFAULT; |
| } |
| |
| name[args->lstio_dbg_nmlen] = 0; |
| } |
| |
| rc = -EINVAL; |
| |
| switch (args->lstio_dbg_type) { |
| case LST_OPC_SESSION: |
| rc = lstcon_session_debug(args->lstio_dbg_timeout, |
| args->lstio_dbg_resultp); |
| break; |
| |
| case LST_OPC_BATCHSRV: |
| client = 0; |
| case LST_OPC_BATCHCLI: |
| if (name == NULL) |
| goto out; |
| |
| rc = lstcon_batch_debug(args->lstio_dbg_timeout, |
| name, client, args->lstio_dbg_resultp); |
| break; |
| |
| case LST_OPC_GROUP: |
| if (name == NULL) |
| goto out; |
| |
| rc = lstcon_group_debug(args->lstio_dbg_timeout, |
| name, args->lstio_dbg_resultp); |
| break; |
| |
| case LST_OPC_NODES: |
| if (args->lstio_dbg_count <= 0 || |
| args->lstio_dbg_idsp == NULL) |
| goto out; |
| |
| rc = lstcon_nodes_debug(args->lstio_dbg_timeout, |
| args->lstio_dbg_count, |
| args->lstio_dbg_idsp, |
| args->lstio_dbg_resultp); |
| break; |
| |
| default: |
| break; |
| } |
| |
| out: |
| if (name != NULL) |
| LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_group_add_ioctl(lstio_group_add_args_t *args) |
| { |
| char *name; |
| int rc; |
| |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_grp_namep, |
| args->lstio_grp_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_grp_nmlen); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_grp_nmlen] = 0; |
| |
| rc = lstcon_group_add(name); |
| |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_group_del_ioctl(lstio_group_del_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_grp_namep, |
| args->lstio_grp_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_grp_nmlen] = 0; |
| |
| rc = lstcon_group_del(name); |
| |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_group_update_ioctl(lstio_group_update_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_resultp == NULL || |
| args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_grp_namep, |
| args->lstio_grp_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_grp_nmlen] = 0; |
| |
| switch (args->lstio_grp_opc) { |
| case LST_GROUP_CLEAN: |
| rc = lstcon_group_clean(name, args->lstio_grp_args); |
| break; |
| |
| case LST_GROUP_REFRESH: |
| rc = lstcon_group_refresh(name, args->lstio_grp_resultp); |
| break; |
| |
| case LST_GROUP_RMND: |
| if (args->lstio_grp_count <= 0 || |
| args->lstio_grp_idsp == NULL) { |
| rc = -EINVAL; |
| break; |
| } |
| rc = lstcon_nodes_remove(name, args->lstio_grp_count, |
| args->lstio_grp_idsp, |
| args->lstio_grp_resultp); |
| break; |
| |
| default: |
| rc = -EINVAL; |
| break; |
| } |
| |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) |
| { |
| unsigned feats; |
| int rc; |
| char *name; |
| |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_idsp == NULL || /* array of ids */ |
| args->lstio_grp_count <= 0 || |
| args->lstio_grp_resultp == NULL || |
| args->lstio_grp_featp == NULL || |
| args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, args->lstio_grp_namep, |
| args->lstio_grp_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| |
| return -EFAULT; |
| } |
| |
| name[args->lstio_grp_nmlen] = 0; |
| |
| rc = lstcon_nodes_add(name, args->lstio_grp_count, |
| args->lstio_grp_idsp, &feats, |
| args->lstio_grp_resultp); |
| |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| if (rc == 0 && |
| copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) { |
| return -EINVAL; |
| } |
| |
| return rc; |
| } |
| |
| static int |
| lst_group_list_ioctl(lstio_group_list_args_t *args) |
| { |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_idx < 0 || |
| args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| return lstcon_group_list(args->lstio_grp_idx, |
| args->lstio_grp_nmlen, |
| args->lstio_grp_namep); |
| } |
| |
| static int |
| lst_group_info_ioctl(lstio_group_info_args_t *args) |
| { |
| char *name; |
| int ndent; |
| int index; |
| int rc; |
| |
| if (args->lstio_grp_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_grp_namep == NULL || |
| args->lstio_grp_nmlen <= 0 || |
| args->lstio_grp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| if (args->lstio_grp_entp == NULL && /* output: group entry */ |
| args->lstio_grp_dentsp == NULL) /* output: node entry */ |
| return -EINVAL; |
| |
| if (args->lstio_grp_dentsp != NULL) { /* have node entry */ |
| if (args->lstio_grp_idxp == NULL || /* node index */ |
| args->lstio_grp_ndentp == NULL) /* # of node entry */ |
| return -EINVAL; |
| |
| if (copy_from_user(&ndent, args->lstio_grp_ndentp, |
| sizeof(ndent)) || |
| copy_from_user(&index, args->lstio_grp_idxp, |
| sizeof(index))) |
| return -EFAULT; |
| |
| if (ndent <= 0 || index < 0) |
| return -EINVAL; |
| } |
| |
| LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_grp_namep, |
| args->lstio_grp_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_grp_nmlen] = 0; |
| |
| rc = lstcon_group_info(name, args->lstio_grp_entp, |
| &index, &ndent, args->lstio_grp_dentsp); |
| |
| LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); |
| |
| if (rc != 0) |
| return rc; |
| |
| if (args->lstio_grp_dentsp != NULL && |
| (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) || |
| copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent)))) |
| return -EFAULT; |
| |
| return 0; |
| } |
| |
| static int |
| lst_batch_add_ioctl(lstio_batch_add_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_namep == NULL || |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_bat_namep, |
| args->lstio_bat_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_bat_nmlen] = 0; |
| |
| rc = lstcon_batch_add(name); |
| |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_batch_run_ioctl(lstio_batch_run_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_namep == NULL || |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_bat_namep, |
| args->lstio_bat_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_bat_nmlen] = 0; |
| |
| rc = lstcon_batch_run(name, args->lstio_bat_timeout, |
| args->lstio_bat_resultp); |
| |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_resultp == NULL || |
| args->lstio_bat_namep == NULL || |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_bat_namep, |
| args->lstio_bat_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_bat_nmlen] = 0; |
| |
| rc = lstcon_batch_stop(name, args->lstio_bat_force, |
| args->lstio_bat_resultp); |
| |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_batch_query_ioctl(lstio_batch_query_args_t *args) |
| { |
| char *name; |
| int rc; |
| |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_resultp == NULL || |
| args->lstio_bat_namep == NULL || |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| if (args->lstio_bat_testidx < 0) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_bat_namep, |
| args->lstio_bat_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_bat_nmlen] = 0; |
| |
| rc = lstcon_test_batch_query(name, |
| args->lstio_bat_testidx, |
| args->lstio_bat_client, |
| args->lstio_bat_timeout, |
| args->lstio_bat_resultp); |
| |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int |
| lst_batch_list_ioctl(lstio_batch_list_args_t *args) |
| { |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_idx < 0 || |
| args->lstio_bat_namep == NULL || |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| return lstcon_batch_list(args->lstio_bat_idx, |
| args->lstio_bat_nmlen, |
| args->lstio_bat_namep); |
| } |
| |
| static int |
| lst_batch_info_ioctl(lstio_batch_info_args_t *args) |
| { |
| char *name; |
| int rc; |
| int index; |
| int ndent; |
| |
| if (args->lstio_bat_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_bat_namep == NULL || /* batch name */ |
| args->lstio_bat_nmlen <= 0 || |
| args->lstio_bat_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| if (args->lstio_bat_entp == NULL && /* output: batch entry */ |
| args->lstio_bat_dentsp == NULL) /* output: node entry */ |
| return -EINVAL; |
| |
| if (args->lstio_bat_dentsp != NULL) { /* have node entry */ |
| if (args->lstio_bat_idxp == NULL || /* node index */ |
| args->lstio_bat_ndentp == NULL) /* # of node entry */ |
| return -EINVAL; |
| |
| if (copy_from_user(&index, args->lstio_bat_idxp, |
| sizeof(index)) || |
| copy_from_user(&ndent, args->lstio_bat_ndentp, |
| sizeof(ndent))) |
| return -EFAULT; |
| |
| if (ndent <= 0 || index < 0) |
| return -EINVAL; |
| } |
| |
| LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, |
| args->lstio_bat_namep, args->lstio_bat_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| name[args->lstio_bat_nmlen] = 0; |
| |
| rc = lstcon_batch_info(name, |
| args->lstio_bat_entp, args->lstio_bat_server, |
| args->lstio_bat_testidx, &index, &ndent, |
| args->lstio_bat_dentsp); |
| |
| LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); |
| |
| if (rc != 0) |
| return rc; |
| |
| if (args->lstio_bat_dentsp != NULL && |
| (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) || |
| copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent)))) |
| rc = -EFAULT; |
| |
| return rc; |
| } |
| |
| static int |
| lst_stat_query_ioctl(lstio_stat_args_t *args) |
| { |
| int rc; |
| char *name; |
| |
| /* TODO: not finished */ |
| if (args->lstio_sta_key != console_session.ses_key) |
| return -EACCES; |
| |
| if (args->lstio_sta_resultp == NULL || |
| (args->lstio_sta_namep == NULL && |
| args->lstio_sta_idsp == NULL) || |
| args->lstio_sta_nmlen <= 0 || |
| args->lstio_sta_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| if (args->lstio_sta_idsp != NULL && |
| args->lstio_sta_count <= 0) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1); |
| if (name == NULL) |
| return -ENOMEM; |
| |
| if (copy_from_user(name, args->lstio_sta_namep, |
| args->lstio_sta_nmlen)) { |
| LIBCFS_FREE(name, args->lstio_sta_nmlen + 1); |
| return -EFAULT; |
| } |
| |
| if (args->lstio_sta_idsp == NULL) { |
| rc = lstcon_group_stat(name, args->lstio_sta_timeout, |
| args->lstio_sta_resultp); |
| } else { |
| rc = lstcon_nodes_stat(args->lstio_sta_count, |
| args->lstio_sta_idsp, |
| args->lstio_sta_timeout, |
| args->lstio_sta_resultp); |
| } |
| |
| LIBCFS_FREE(name, args->lstio_sta_nmlen + 1); |
| |
| return rc; |
| } |
| |
| static int lst_test_add_ioctl(lstio_test_args_t *args) |
| { |
| char *batch_name; |
| char *src_name = NULL; |
| char *dst_name = NULL; |
| void *param = NULL; |
| int ret = 0; |
| int rc = -ENOMEM; |
| |
| if (args->lstio_tes_resultp == NULL || |
| args->lstio_tes_retp == NULL || |
| args->lstio_tes_bat_name == NULL || /* no specified batch */ |
| args->lstio_tes_bat_nmlen <= 0 || |
| args->lstio_tes_bat_nmlen > LST_NAME_SIZE || |
| args->lstio_tes_sgrp_name == NULL || /* no source group */ |
| args->lstio_tes_sgrp_nmlen <= 0 || |
| args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE || |
| args->lstio_tes_dgrp_name == NULL || /* no target group */ |
| args->lstio_tes_dgrp_nmlen <= 0 || |
| args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE) |
| return -EINVAL; |
| |
| if (args->lstio_tes_loop == 0 || /* negative is infinite */ |
| args->lstio_tes_concur <= 0 || |
| args->lstio_tes_dist <= 0 || |
| args->lstio_tes_span <= 0) |
| return -EINVAL; |
| |
| /* have parameter, check if parameter length is valid */ |
| if (args->lstio_tes_param != NULL && |
| (args->lstio_tes_param_len <= 0 || |
| args->lstio_tes_param_len > PAGE_CACHE_SIZE - sizeof(lstcon_test_t))) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1); |
| if (batch_name == NULL) |
| return rc; |
| |
| LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1); |
| if (src_name == NULL) |
| goto out; |
| |
| LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1); |
| if (dst_name == NULL) |
| goto out; |
| |
| if (args->lstio_tes_param != NULL) { |
| LIBCFS_ALLOC(param, args->lstio_tes_param_len); |
| if (param == NULL) |
| goto out; |
| } |
| |
| rc = -EFAULT; |
| if (copy_from_user(batch_name, args->lstio_tes_bat_name, |
| args->lstio_tes_bat_nmlen) || |
| copy_from_user(src_name, args->lstio_tes_sgrp_name, |
| args->lstio_tes_sgrp_nmlen) || |
| copy_from_user(dst_name, args->lstio_tes_dgrp_name, |
| args->lstio_tes_dgrp_nmlen) || |
| copy_from_user(param, args->lstio_tes_param, |
| args->lstio_tes_param_len)) |
| goto out; |
| |
| rc = lstcon_test_add(batch_name, |
| args->lstio_tes_type, |
| args->lstio_tes_loop, |
| args->lstio_tes_concur, |
| args->lstio_tes_dist, args->lstio_tes_span, |
| src_name, dst_name, param, |
| args->lstio_tes_param_len, |
| &ret, args->lstio_tes_resultp); |
| |
| if (ret != 0) |
| rc = (copy_to_user(args->lstio_tes_retp, &ret, |
| sizeof(ret))) ? -EFAULT : 0; |
| out: |
| if (batch_name != NULL) |
| LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1); |
| |
| if (src_name != NULL) |
| LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1); |
| |
| if (dst_name != NULL) |
| LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1); |
| |
| if (param != NULL) |
| LIBCFS_FREE(param, args->lstio_tes_param_len); |
| |
| return rc; |
| } |
| |
| int |
| lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data) |
| { |
| char *buf; |
| int opc = data->ioc_u32[0]; |
| int rc; |
| |
| if (cmd != IOC_LIBCFS_LNETST) |
| return -EINVAL; |
| |
| if (data->ioc_plen1 > PAGE_CACHE_SIZE) |
| return -EINVAL; |
| |
| LIBCFS_ALLOC(buf, data->ioc_plen1); |
| if (buf == NULL) |
| return -ENOMEM; |
| |
| /* copy in parameter */ |
| if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) { |
| LIBCFS_FREE(buf, data->ioc_plen1); |
| return -EFAULT; |
| } |
| |
| mutex_lock(&console_session.ses_mutex); |
| |
| console_session.ses_laststamp = ktime_get_real_seconds(); |
| |
| if (console_session.ses_shutdown) { |
| rc = -ESHUTDOWN; |
| goto out; |
| } |
| |
| if (console_session.ses_expired) |
| lstcon_session_end(); |
| |
| if (opc != LSTIO_SESSION_NEW && |
| console_session.ses_state == LST_SESSION_NONE) { |
| CDEBUG(D_NET, "LST no active session\n"); |
| rc = -ESRCH; |
| goto out; |
| } |
| |
| memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t)); |
| |
| switch (opc) { |
| case LSTIO_SESSION_NEW: |
| rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf); |
| break; |
| case LSTIO_SESSION_END: |
| rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf); |
| break; |
| case LSTIO_SESSION_INFO: |
| rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf); |
| break; |
| case LSTIO_DEBUG: |
| rc = lst_debug_ioctl((lstio_debug_args_t *)buf); |
| break; |
| case LSTIO_GROUP_ADD: |
| rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf); |
| break; |
| case LSTIO_GROUP_DEL: |
| rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf); |
| break; |
| case LSTIO_GROUP_UPDATE: |
| rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf); |
| break; |
| case LSTIO_NODES_ADD: |
| rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf); |
| break; |
| case LSTIO_GROUP_LIST: |
| rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf); |
| break; |
| case LSTIO_GROUP_INFO: |
| rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf); |
| break; |
| case LSTIO_BATCH_ADD: |
| rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf); |
| break; |
| case LSTIO_BATCH_START: |
| rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf); |
| break; |
| case LSTIO_BATCH_STOP: |
| rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf); |
| break; |
| case LSTIO_BATCH_QUERY: |
| rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf); |
| break; |
| case LSTIO_BATCH_LIST: |
| rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf); |
| break; |
| case LSTIO_BATCH_INFO: |
| rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf); |
| break; |
| case LSTIO_TEST_ADD: |
| rc = lst_test_add_ioctl((lstio_test_args_t *)buf); |
| break; |
| case LSTIO_STAT_QUERY: |
| rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf); |
| break; |
| default: |
| rc = -EINVAL; |
| } |
| |
| if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat, |
| sizeof(lstcon_trans_stat_t))) |
| rc = -EFAULT; |
| out: |
| mutex_unlock(&console_session.ses_mutex); |
| |
| LIBCFS_FREE(buf, data->ioc_plen1); |
| |
| return rc; |
| } |
| |
| EXPORT_SYMBOL(lstcon_ioctl_entry); |