blob: a0fcbf3bcc950545ef12b91ef4ba6695b68988f4 [file] [log] [blame]
Peng Taod7e09d02013-05-02 16:46:55 +08001/*
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
Oleg Drokin6a5b99a2016-06-14 23:33:40 -040018 * http://www.gnu.org/licenses/gpl-2.0.html
Peng Taod7e09d02013-05-02 16:46:55 +080019 *
Peng Taod7e09d02013-05-02 16:46:55 +080020 * 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 * Infrastructure of LST console
35 *
36 * Author: Liang Zhen <liangzhen@clusterfs.com>
37 */
38
Greg Kroah-Hartman9fdaf8c2014-07-11 20:51:16 -070039#include "../../include/linux/libcfs/libcfs.h"
40#include "../../include/linux/lnet/lib-lnet.h"
Peng Taod7e09d02013-05-02 16:46:55 +080041#include "console.h"
42#include "conrpc.h"
43
Asaf Vertz13534f82015-02-01 13:29:23 +020044#define LST_NODE_STATE_COUNTER(nd, p) \
45do { \
46 if ((nd)->nd_state == LST_NODE_ACTIVE) \
47 (p)->nle_nactive++; \
James Simmonsb794d792016-03-11 20:29:47 -050048 else if ((nd)->nd_state == LST_NODE_BUSY) \
Asaf Vertz13534f82015-02-01 13:29:23 +020049 (p)->nle_nbusy++; \
James Simmonsb794d792016-03-11 20:29:47 -050050 else if ((nd)->nd_state == LST_NODE_DOWN) \
Asaf Vertz13534f82015-02-01 13:29:23 +020051 (p)->nle_ndown++; \
52 else \
53 (p)->nle_nunknown++; \
54 (p)->nle_nnode++; \
Peng Taod7e09d02013-05-02 16:46:55 +080055} while (0)
56
Bhumika Goyal541ac712016-02-19 19:13:52 +053057struct lstcon_session console_session;
Peng Taod7e09d02013-05-02 16:46:55 +080058
Himangi Saraogi18ce30c2014-03-13 01:34:39 +053059static void
James Simmonsf1e34162016-04-06 15:25:42 -040060lstcon_node_get(struct lstcon_node *nd)
Peng Taod7e09d02013-05-02 16:46:55 +080061{
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +020062 LASSERT(nd->nd_ref >= 1);
Peng Taod7e09d02013-05-02 16:46:55 +080063
64 nd->nd_ref++;
65}
66
67static int
James Simmonsf1e34162016-04-06 15:25:42 -040068lstcon_node_find(lnet_process_id_t id, struct lstcon_node **ndpp, int create)
Peng Taod7e09d02013-05-02 16:46:55 +080069{
James Simmonse00f9782016-04-06 15:25:43 -040070 struct lstcon_ndlink *ndl;
Mike Shuey74d68012015-05-19 10:14:38 -040071 unsigned int idx = LNET_NIDADDR(id.nid) % LST_GLOBAL_HASHSIZE;
Peng Taod7e09d02013-05-02 16:46:55 +080072
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +020073 LASSERT(id.nid != LNET_NID_ANY);
Peng Taod7e09d02013-05-02 16:46:55 +080074
James Simmons2df122b2016-03-11 20:29:51 -050075 list_for_each_entry(ndl, &console_session.ses_ndl_hash[idx],
76 ndl_hlink) {
Peng Taod7e09d02013-05-02 16:46:55 +080077 if (ndl->ndl_node->nd_id.nid != id.nid ||
78 ndl->ndl_node->nd_id.pid != id.pid)
79 continue;
80
81 lstcon_node_get(ndl->ndl_node);
82 *ndpp = ndl->ndl_node;
83 return 0;
84 }
85
86 if (!create)
87 return -ENOENT;
88
James Simmonse00f9782016-04-06 15:25:43 -040089 LIBCFS_ALLOC(*ndpp, sizeof(struct lstcon_node) + sizeof(struct lstcon_ndlink));
James Simmons06ace262016-02-12 12:06:08 -050090 if (!*ndpp)
Peng Taod7e09d02013-05-02 16:46:55 +080091 return -ENOMEM;
92
James Simmonse00f9782016-04-06 15:25:43 -040093 ndl = (struct lstcon_ndlink *)(*ndpp + 1);
Peng Taod7e09d02013-05-02 16:46:55 +080094
95 ndl->ndl_node = *ndpp;
96
James Simmonsec436b92016-03-11 20:29:46 -050097 ndl->ndl_node->nd_ref = 1;
98 ndl->ndl_node->nd_id = id;
Peng Taod7e09d02013-05-02 16:46:55 +080099 ndl->ndl_node->nd_stamp = cfs_time_current();
100 ndl->ndl_node->nd_state = LST_NODE_UNKNOWN;
101 ndl->ndl_node->nd_timeout = 0;
James Simmonsdc4f95f2016-04-06 15:25:40 -0400102 memset(&ndl->ndl_node->nd_ping, 0, sizeof(struct lstcon_rpc));
Peng Taod7e09d02013-05-02 16:46:55 +0800103
James Simmons4420cfd2016-02-12 12:06:00 -0500104 /*
105 * queued in global hash & list, no refcount is taken by
Peng Taod7e09d02013-05-02 16:46:55 +0800106 * global hash & list, if caller release his refcount,
James Simmons4420cfd2016-02-12 12:06:00 -0500107 * node will be released
108 */
Peng Taod7e09d02013-05-02 16:46:55 +0800109 list_add_tail(&ndl->ndl_hlink, &console_session.ses_ndl_hash[idx]);
110 list_add_tail(&ndl->ndl_link, &console_session.ses_ndl_list);
111
112 return 0;
113}
114
Himangi Saraogi18ce30c2014-03-13 01:34:39 +0530115static void
James Simmonsf1e34162016-04-06 15:25:42 -0400116lstcon_node_put(struct lstcon_node *nd)
Peng Taod7e09d02013-05-02 16:46:55 +0800117{
James Simmonse00f9782016-04-06 15:25:43 -0400118 struct lstcon_ndlink *ndl;
Peng Taod7e09d02013-05-02 16:46:55 +0800119
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200120 LASSERT(nd->nd_ref > 0);
Peng Taod7e09d02013-05-02 16:46:55 +0800121
122 if (--nd->nd_ref > 0)
123 return;
124
James Simmonse00f9782016-04-06 15:25:43 -0400125 ndl = (struct lstcon_ndlink *)(nd + 1);
Peng Taod7e09d02013-05-02 16:46:55 +0800126
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200127 LASSERT(!list_empty(&ndl->ndl_link));
128 LASSERT(!list_empty(&ndl->ndl_hlink));
Peng Taod7e09d02013-05-02 16:46:55 +0800129
130 /* remove from session */
131 list_del(&ndl->ndl_link);
132 list_del(&ndl->ndl_hlink);
133
James Simmonse00f9782016-04-06 15:25:43 -0400134 LIBCFS_FREE(nd, sizeof(struct lstcon_node) + sizeof(struct lstcon_ndlink));
Peng Taod7e09d02013-05-02 16:46:55 +0800135}
136
137static int
138lstcon_ndlink_find(struct list_head *hash,
James Simmonse00f9782016-04-06 15:25:43 -0400139 lnet_process_id_t id, struct lstcon_ndlink **ndlpp, int create)
Peng Taod7e09d02013-05-02 16:46:55 +0800140{
Mike Shuey74d68012015-05-19 10:14:38 -0400141 unsigned int idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE;
James Simmonse00f9782016-04-06 15:25:43 -0400142 struct lstcon_ndlink *ndl;
James Simmonsf1e34162016-04-06 15:25:42 -0400143 struct lstcon_node *nd;
Mike Shuey74d68012015-05-19 10:14:38 -0400144 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800145
146 if (id.nid == LNET_NID_ANY)
147 return -EINVAL;
148
149 /* search in hash */
150 list_for_each_entry(ndl, &hash[idx], ndl_hlink) {
151 if (ndl->ndl_node->nd_id.nid != id.nid ||
152 ndl->ndl_node->nd_id.pid != id.pid)
153 continue;
154
155 *ndlpp = ndl;
156 return 0;
157 }
158
James Simmons5fd88332016-02-12 12:06:09 -0500159 if (!create)
Peng Taod7e09d02013-05-02 16:46:55 +0800160 return -ENOENT;
161
162 /* find or create in session hash */
163 rc = lstcon_node_find(id, &nd, (create == 1) ? 1 : 0);
James Simmons5fd88332016-02-12 12:06:09 -0500164 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +0800165 return rc;
166
James Simmonse00f9782016-04-06 15:25:43 -0400167 LIBCFS_ALLOC(ndl, sizeof(struct lstcon_ndlink));
James Simmons06ace262016-02-12 12:06:08 -0500168 if (!ndl) {
Peng Taod7e09d02013-05-02 16:46:55 +0800169 lstcon_node_put(nd);
170 return -ENOMEM;
171 }
172
173 *ndlpp = ndl;
174
175 ndl->ndl_node = nd;
176 INIT_LIST_HEAD(&ndl->ndl_link);
177 list_add_tail(&ndl->ndl_hlink, &hash[idx]);
178
James Simmonsec436b92016-03-11 20:29:46 -0500179 return 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800180}
181
182static void
James Simmonse00f9782016-04-06 15:25:43 -0400183lstcon_ndlink_release(struct lstcon_ndlink *ndl)
Peng Taod7e09d02013-05-02 16:46:55 +0800184{
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200185 LASSERT(list_empty(&ndl->ndl_link));
186 LASSERT(!list_empty(&ndl->ndl_hlink));
Peng Taod7e09d02013-05-02 16:46:55 +0800187
188 list_del(&ndl->ndl_hlink); /* delete from hash */
189 lstcon_node_put(ndl->ndl_node);
190
191 LIBCFS_FREE(ndl, sizeof(*ndl));
192}
193
194static int
James Simmons6bd88c72016-04-06 15:25:44 -0400195lstcon_group_alloc(char *name, struct lstcon_group **grpp)
Peng Taod7e09d02013-05-02 16:46:55 +0800196{
James Simmons6bd88c72016-04-06 15:25:44 -0400197 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -0400198 int i;
Peng Taod7e09d02013-05-02 16:46:55 +0800199
James Simmons6bd88c72016-04-06 15:25:44 -0400200 LIBCFS_ALLOC(grp, offsetof(struct lstcon_group,
Peng Taod7e09d02013-05-02 16:46:55 +0800201 grp_ndl_hash[LST_NODE_HASHSIZE]));
James Simmons06ace262016-02-12 12:06:08 -0500202 if (!grp)
Peng Taod7e09d02013-05-02 16:46:55 +0800203 return -ENOMEM;
204
Peng Taod7e09d02013-05-02 16:46:55 +0800205 grp->grp_ref = 1;
Sebastien Buisson661489a2016-03-02 17:01:51 -0500206 if (name) {
James Simmonsd47e33e2016-03-11 20:29:44 -0500207 if (strlen(name) > sizeof(grp->grp_name) - 1) {
James Simmons6bd88c72016-04-06 15:25:44 -0400208 LIBCFS_FREE(grp, offsetof(struct lstcon_group,
Sebastien Buisson661489a2016-03-02 17:01:51 -0500209 grp_ndl_hash[LST_NODE_HASHSIZE]));
210 return -E2BIG;
211 }
212 strncpy(grp->grp_name, name, sizeof(grp->grp_name));
213 }
Peng Taod7e09d02013-05-02 16:46:55 +0800214
215 INIT_LIST_HEAD(&grp->grp_link);
216 INIT_LIST_HEAD(&grp->grp_ndl_list);
217 INIT_LIST_HEAD(&grp->grp_trans_list);
218
219 for (i = 0; i < LST_NODE_HASHSIZE; i++)
220 INIT_LIST_HEAD(&grp->grp_ndl_hash[i]);
221
222 *grpp = grp;
223
224 return 0;
225}
226
227static void
James Simmons6bd88c72016-04-06 15:25:44 -0400228lstcon_group_addref(struct lstcon_group *grp)
Peng Taod7e09d02013-05-02 16:46:55 +0800229{
Asaf Vertz13534f82015-02-01 13:29:23 +0200230 grp->grp_ref++;
Peng Taod7e09d02013-05-02 16:46:55 +0800231}
232
James Simmons6bd88c72016-04-06 15:25:44 -0400233static void lstcon_group_ndlink_release(struct lstcon_group *, struct lstcon_ndlink *);
Peng Taod7e09d02013-05-02 16:46:55 +0800234
235static void
James Simmons6bd88c72016-04-06 15:25:44 -0400236lstcon_group_drain(struct lstcon_group *grp, int keep)
Peng Taod7e09d02013-05-02 16:46:55 +0800237{
James Simmonse00f9782016-04-06 15:25:43 -0400238 struct lstcon_ndlink *ndl;
239 struct lstcon_ndlink *tmp;
Peng Taod7e09d02013-05-02 16:46:55 +0800240
241 list_for_each_entry_safe(ndl, tmp, &grp->grp_ndl_list, ndl_link) {
James Simmons5fd88332016-02-12 12:06:09 -0500242 if (!(ndl->ndl_node->nd_state & keep))
Peng Taod7e09d02013-05-02 16:46:55 +0800243 lstcon_group_ndlink_release(grp, ndl);
244 }
245}
246
247static void
James Simmons6bd88c72016-04-06 15:25:44 -0400248lstcon_group_decref(struct lstcon_group *grp)
Peng Taod7e09d02013-05-02 16:46:55 +0800249{
Mike Shuey74d68012015-05-19 10:14:38 -0400250 int i;
Peng Taod7e09d02013-05-02 16:46:55 +0800251
252 if (--grp->grp_ref > 0)
253 return;
254
255 if (!list_empty(&grp->grp_link))
256 list_del(&grp->grp_link);
257
258 lstcon_group_drain(grp, 0);
259
James Simmons06f2f2f2016-02-12 12:06:07 -0500260 for (i = 0; i < LST_NODE_HASHSIZE; i++)
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200261 LASSERT(list_empty(&grp->grp_ndl_hash[i]));
Peng Taod7e09d02013-05-02 16:46:55 +0800262
James Simmons6bd88c72016-04-06 15:25:44 -0400263 LIBCFS_FREE(grp, offsetof(struct lstcon_group,
Peng Taod7e09d02013-05-02 16:46:55 +0800264 grp_ndl_hash[LST_NODE_HASHSIZE]));
265}
266
267static int
James Simmons6bd88c72016-04-06 15:25:44 -0400268lstcon_group_find(const char *name, struct lstcon_group **grpp)
Peng Taod7e09d02013-05-02 16:46:55 +0800269{
James Simmons6bd88c72016-04-06 15:25:44 -0400270 struct lstcon_group *grp;
Peng Taod7e09d02013-05-02 16:46:55 +0800271
272 list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) {
James Simmons5fd88332016-02-12 12:06:09 -0500273 if (strncmp(grp->grp_name, name, LST_NAME_SIZE))
Peng Taod7e09d02013-05-02 16:46:55 +0800274 continue;
275
James Simmonsdae05872016-03-12 13:00:36 -0500276 lstcon_group_addref(grp); /* +1 ref for caller */
Peng Taod7e09d02013-05-02 16:46:55 +0800277 *grpp = grp;
278 return 0;
279 }
280
281 return -ENOENT;
282}
283
Peng Taod7e09d02013-05-02 16:46:55 +0800284static int
James Simmons6bd88c72016-04-06 15:25:44 -0400285lstcon_group_ndlink_find(struct lstcon_group *grp, lnet_process_id_t id,
James Simmonse00f9782016-04-06 15:25:43 -0400286 struct lstcon_ndlink **ndlpp, int create)
Peng Taod7e09d02013-05-02 16:46:55 +0800287{
Mike Shuey74d68012015-05-19 10:14:38 -0400288 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800289
290 rc = lstcon_ndlink_find(&grp->grp_ndl_hash[0], id, ndlpp, create);
James Simmons5fd88332016-02-12 12:06:09 -0500291 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +0800292 return rc;
293
294 if (!list_empty(&(*ndlpp)->ndl_link))
295 return 0;
296
297 list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list);
Asaf Vertz13534f82015-02-01 13:29:23 +0200298 grp->grp_nnode++;
Peng Taod7e09d02013-05-02 16:46:55 +0800299
300 return 0;
301}
302
303static void
James Simmons6bd88c72016-04-06 15:25:44 -0400304lstcon_group_ndlink_release(struct lstcon_group *grp, struct lstcon_ndlink *ndl)
Peng Taod7e09d02013-05-02 16:46:55 +0800305{
306 list_del_init(&ndl->ndl_link);
307 lstcon_ndlink_release(ndl);
Mike Rapoportb2952d62015-09-03 11:49:13 +0300308 grp->grp_nnode--;
Peng Taod7e09d02013-05-02 16:46:55 +0800309}
310
311static void
James Simmons6bd88c72016-04-06 15:25:44 -0400312lstcon_group_ndlink_move(struct lstcon_group *old,
313 struct lstcon_group *new, struct lstcon_ndlink *ndl)
Peng Taod7e09d02013-05-02 16:46:55 +0800314{
315 unsigned int idx = LNET_NIDADDR(ndl->ndl_node->nd_id.nid) %
James Simmons2df122b2016-03-11 20:29:51 -0500316 LST_NODE_HASHSIZE;
Peng Taod7e09d02013-05-02 16:46:55 +0800317
318 list_del(&ndl->ndl_hlink);
319 list_del(&ndl->ndl_link);
Mike Rapoportb2952d62015-09-03 11:49:13 +0300320 old->grp_nnode--;
Peng Taod7e09d02013-05-02 16:46:55 +0800321
322 list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);
323 list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);
Asaf Vertz13534f82015-02-01 13:29:23 +0200324 new->grp_nnode++;
Peng Taod7e09d02013-05-02 16:46:55 +0800325}
326
327static void
James Simmons6bd88c72016-04-06 15:25:44 -0400328lstcon_group_move(struct lstcon_group *old, struct lstcon_group *new)
Peng Taod7e09d02013-05-02 16:46:55 +0800329{
James Simmonse00f9782016-04-06 15:25:43 -0400330 struct lstcon_ndlink *ndl;
Peng Taod7e09d02013-05-02 16:46:55 +0800331
332 while (!list_empty(&old->grp_ndl_list)) {
333 ndl = list_entry(old->grp_ndl_list.next,
James Simmonse00f9782016-04-06 15:25:43 -0400334 struct lstcon_ndlink, ndl_link);
Peng Taod7e09d02013-05-02 16:46:55 +0800335 lstcon_group_ndlink_move(old, new, ndl);
336 }
337}
338
Himangi Saraogi18ce30c2014-03-13 01:34:39 +0530339static int
James Simmonsf1e34162016-04-06 15:25:42 -0400340lstcon_sesrpc_condition(int transop, struct lstcon_node *nd, void *arg)
Peng Taod7e09d02013-05-02 16:46:55 +0800341{
James Simmons6bd88c72016-04-06 15:25:44 -0400342 struct lstcon_group *grp = (struct lstcon_group *)arg;
Peng Taod7e09d02013-05-02 16:46:55 +0800343
344 switch (transop) {
345 case LST_TRANS_SESNEW:
346 if (nd->nd_state == LST_NODE_ACTIVE)
347 return 0;
348 break;
349
350 case LST_TRANS_SESEND:
351 if (nd->nd_state != LST_NODE_ACTIVE)
352 return 0;
353
James Simmons06ace262016-02-12 12:06:08 -0500354 if (grp && nd->nd_ref > 1)
Peng Taod7e09d02013-05-02 16:46:55 +0800355 return 0;
356 break;
357
358 case LST_TRANS_SESQRY:
359 break;
360
361 default:
362 LBUG();
363 }
364
365 return 1;
366}
367
Himangi Saraogi18ce30c2014-03-13 01:34:39 +0530368static int
James Simmonsfd7a1a32016-04-06 15:25:48 -0400369lstcon_sesrpc_readent(int transop, struct srpc_msg *msg,
Frank Zago08816b22016-01-03 12:06:00 -0500370 lstcon_rpc_ent_t __user *ent_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800371{
James Simmons45d2f4f2016-04-12 12:16:02 -0400372 struct srpc_debug_reply *rep;
Peng Taod7e09d02013-05-02 16:46:55 +0800373
374 switch (transop) {
375 case LST_TRANS_SESNEW:
376 case LST_TRANS_SESEND:
377 return 0;
378
379 case LST_TRANS_SESQRY:
380 rep = &msg->msg_body.dbg_reply;
381
382 if (copy_to_user(&ent_up->rpe_priv[0],
James Simmonsc314c312016-02-12 12:06:01 -0500383 &rep->dbg_timeout, sizeof(int)) ||
Peng Taod7e09d02013-05-02 16:46:55 +0800384 copy_to_user(&ent_up->rpe_payload[0],
James Simmonsc314c312016-02-12 12:06:01 -0500385 &rep->dbg_name, LST_NAME_SIZE))
Peng Taod7e09d02013-05-02 16:46:55 +0800386 return -EFAULT;
387
388 return 0;
389
390 default:
391 LBUG();
392 }
393
394 return 0;
395}
396
397static int
James Simmons6bd88c72016-04-06 15:25:44 -0400398lstcon_group_nodes_add(struct lstcon_group *grp,
Frank Zago08816b22016-01-03 12:06:00 -0500399 int count, lnet_process_id_t __user *ids_up,
400 unsigned *featp, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800401{
James Simmonsd8742c82016-04-06 15:25:41 -0400402 struct lstcon_rpc_trans *trans;
James Simmonse00f9782016-04-06 15:25:43 -0400403 struct lstcon_ndlink *ndl;
James Simmons6bd88c72016-04-06 15:25:44 -0400404 struct lstcon_group *tmp;
Mike Shuey74d68012015-05-19 10:14:38 -0400405 lnet_process_id_t id;
406 int i;
407 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800408
409 rc = lstcon_group_alloc(NULL, &tmp);
James Simmons5fd88332016-02-12 12:06:09 -0500410 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800411 CERROR("Out of memory\n");
412 return -ENOMEM;
413 }
414
415 for (i = 0 ; i < count; i++) {
416 if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
417 rc = -EFAULT;
418 break;
419 }
420
421 /* skip if it's in this group already */
422 rc = lstcon_group_ndlink_find(grp, id, &ndl, 0);
James Simmons5fd88332016-02-12 12:06:09 -0500423 if (!rc)
Peng Taod7e09d02013-05-02 16:46:55 +0800424 continue;
425
426 /* add to tmp group */
427 rc = lstcon_group_ndlink_find(tmp, id, &ndl, 1);
James Simmons5fd88332016-02-12 12:06:09 -0500428 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800429 CERROR("Can't create ndlink, out of memory\n");
430 break;
431 }
432 }
433
James Simmons5fd88332016-02-12 12:06:09 -0500434 if (rc) {
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530435 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +0800436 return rc;
437 }
438
439 rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,
440 &tmp->grp_trans_list, LST_TRANS_SESNEW,
441 tmp, lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -0500442 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800443 CERROR("Can't create transaction: %d\n", rc);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530444 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +0800445 return rc;
446 }
447
448 /* post all RPCs */
449 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
450
451 rc = lstcon_rpc_trans_interpreter(trans, result_up,
452 lstcon_sesrpc_readent);
453 *featp = trans->tas_features;
454
455 /* destroy all RPGs */
456 lstcon_rpc_trans_destroy(trans);
457
458 lstcon_group_move(tmp, grp);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530459 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +0800460
461 return rc;
462}
463
464static int
James Simmons6bd88c72016-04-06 15:25:44 -0400465lstcon_group_nodes_remove(struct lstcon_group *grp,
Frank Zago08816b22016-01-03 12:06:00 -0500466 int count, lnet_process_id_t __user *ids_up,
467 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800468{
James Simmonsd8742c82016-04-06 15:25:41 -0400469 struct lstcon_rpc_trans *trans;
James Simmonse00f9782016-04-06 15:25:43 -0400470 struct lstcon_ndlink *ndl;
James Simmons6bd88c72016-04-06 15:25:44 -0400471 struct lstcon_group *tmp;
Mike Shuey74d68012015-05-19 10:14:38 -0400472 lnet_process_id_t id;
473 int rc;
474 int i;
Peng Taod7e09d02013-05-02 16:46:55 +0800475
476 /* End session and remove node from the group */
477
478 rc = lstcon_group_alloc(NULL, &tmp);
James Simmons5fd88332016-02-12 12:06:09 -0500479 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800480 CERROR("Out of memory\n");
481 return -ENOMEM;
482 }
483
484 for (i = 0; i < count; i++) {
485 if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
486 rc = -EFAULT;
487 goto error;
488 }
489
490 /* move node to tmp group */
James Simmons5fd88332016-02-12 12:06:09 -0500491 if (!lstcon_group_ndlink_find(grp, id, &ndl, 0))
Peng Taod7e09d02013-05-02 16:46:55 +0800492 lstcon_group_ndlink_move(grp, tmp, ndl);
493 }
494
495 rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,
496 &tmp->grp_trans_list, LST_TRANS_SESEND,
497 tmp, lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -0500498 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800499 CERROR("Can't create transaction: %d\n", rc);
500 goto error;
501 }
502
503 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
504
505 rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
506
507 lstcon_rpc_trans_destroy(trans);
508 /* release nodes anyway, because we can't rollback status */
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530509 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +0800510
511 return rc;
512error:
513 lstcon_group_move(tmp, grp);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530514 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +0800515
516 return rc;
517}
518
519int
520lstcon_group_add(char *name)
521{
James Simmons6bd88c72016-04-06 15:25:44 -0400522 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -0400523 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800524
James Simmonsd47e33e2016-03-11 20:29:44 -0500525 rc = lstcon_group_find(name, &grp) ? 0 : -EEXIST;
James Simmons5fd88332016-02-12 12:06:09 -0500526 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800527 /* find a group with same name */
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530528 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800529 return rc;
530 }
531
532 rc = lstcon_group_alloc(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500533 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800534 CERROR("Can't allocate descriptor for group %s\n", name);
535 return -ENOMEM;
536 }
537
538 list_add_tail(&grp->grp_link, &console_session.ses_grp_list);
539
540 return rc;
541}
542
543int
Frank Zago08816b22016-01-03 12:06:00 -0500544lstcon_nodes_add(char *name, int count, lnet_process_id_t __user *ids_up,
545 unsigned *featp, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800546{
James Simmons6bd88c72016-04-06 15:25:44 -0400547 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -0400548 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800549
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200550 LASSERT(count > 0);
James Simmons06ace262016-02-12 12:06:08 -0500551 LASSERT(ids_up);
Peng Taod7e09d02013-05-02 16:46:55 +0800552
553 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500554 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800555 CDEBUG(D_NET, "Can't find group %s\n", name);
556 return rc;
557 }
558
559 if (grp->grp_ref > 2) {
560 /* referred by other threads or test */
561 CDEBUG(D_NET, "Group %s is busy\n", name);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530562 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800563
564 return -EBUSY;
565 }
566
567 rc = lstcon_group_nodes_add(grp, count, ids_up, featp, result_up);
568
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530569 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800570
571 return rc;
572}
573
574int
575lstcon_group_del(char *name)
576{
James Simmonsd8742c82016-04-06 15:25:41 -0400577 struct lstcon_rpc_trans *trans;
James Simmons6bd88c72016-04-06 15:25:44 -0400578 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -0400579 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800580
581 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500582 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800583 CDEBUG(D_NET, "Can't find group: %s\n", name);
584 return rc;
585 }
586
587 if (grp->grp_ref > 2) {
588 /* referred by others threads or test */
589 CDEBUG(D_NET, "Group %s is busy\n", name);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530590 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800591 return -EBUSY;
592 }
593
594 rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
595 &grp->grp_trans_list, LST_TRANS_SESEND,
596 grp, lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -0500597 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800598 CERROR("Can't create transaction: %d\n", rc);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530599 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800600 return rc;
601 }
602
603 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
604
605 lstcon_rpc_trans_destroy(trans);
606
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530607 lstcon_group_decref(grp);
James Simmons4420cfd2016-02-12 12:06:00 -0500608 /*
609 * -ref for session, it's destroyed,
610 * status can't be rolled back, destroy group anyway
611 */
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530612 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800613
614 return rc;
615}
616
617int
618lstcon_group_clean(char *name, int args)
619{
James Simmons6bd88c72016-04-06 15:25:44 -0400620 struct lstcon_group *grp = NULL;
Mike Shuey74d68012015-05-19 10:14:38 -0400621 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800622
623 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500624 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800625 CDEBUG(D_NET, "Can't find group %s\n", name);
626 return rc;
627 }
628
629 if (grp->grp_ref > 2) {
630 /* referred by test */
631 CDEBUG(D_NET, "Group %s is busy\n", name);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530632 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800633 return -EBUSY;
634 }
635
636 args = (LST_NODE_ACTIVE | LST_NODE_BUSY |
637 LST_NODE_DOWN | LST_NODE_UNKNOWN) & ~args;
638
639 lstcon_group_drain(grp, args);
640
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530641 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800642 /* release empty group */
643 if (list_empty(&grp->grp_ndl_list))
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530644 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800645
646 return 0;
647}
648
649int
Frank Zago08816b22016-01-03 12:06:00 -0500650lstcon_nodes_remove(char *name, int count, lnet_process_id_t __user *ids_up,
651 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800652{
James Simmons6bd88c72016-04-06 15:25:44 -0400653 struct lstcon_group *grp = NULL;
Mike Shuey74d68012015-05-19 10:14:38 -0400654 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800655
656 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500657 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800658 CDEBUG(D_NET, "Can't find group: %s\n", name);
659 return rc;
660 }
661
662 if (grp->grp_ref > 2) {
663 /* referred by test */
664 CDEBUG(D_NET, "Group %s is busy\n", name);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530665 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800666 return -EBUSY;
667 }
668
669 rc = lstcon_group_nodes_remove(grp, count, ids_up, result_up);
670
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530671 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800672 /* release empty group */
673 if (list_empty(&grp->grp_ndl_list))
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530674 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800675
676 return rc;
677}
678
679int
Frank Zago08816b22016-01-03 12:06:00 -0500680lstcon_group_refresh(char *name, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800681{
James Simmonsd8742c82016-04-06 15:25:41 -0400682 struct lstcon_rpc_trans *trans;
James Simmons6bd88c72016-04-06 15:25:44 -0400683 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -0400684 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800685
686 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500687 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800688 CDEBUG(D_NET, "Can't find group: %s\n", name);
689 return rc;
690 }
691
692 if (grp->grp_ref > 2) {
693 /* referred by test */
694 CDEBUG(D_NET, "Group %s is busy\n", name);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530695 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800696 return -EBUSY;
697 }
698
699 /* re-invite all inactive nodes int the group */
700 rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
701 &grp->grp_trans_list, LST_TRANS_SESNEW,
702 grp, lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -0500703 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800704 /* local error, return */
705 CDEBUG(D_NET, "Can't create transaction: %d\n", rc);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530706 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800707 return rc;
708 }
709
710 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
711
712 rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
713
714 lstcon_rpc_trans_destroy(trans);
715 /* -ref for me */
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530716 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800717
718 return rc;
719}
720
721int
Frank Zago08816b22016-01-03 12:06:00 -0500722lstcon_group_list(int index, int len, char __user *name_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800723{
James Simmons6bd88c72016-04-06 15:25:44 -0400724 struct lstcon_group *grp;
Peng Taod7e09d02013-05-02 16:46:55 +0800725
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200726 LASSERT(index >= 0);
James Simmons06ace262016-02-12 12:06:08 -0500727 LASSERT(name_up);
Peng Taod7e09d02013-05-02 16:46:55 +0800728
729 list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) {
James Simmons5fd88332016-02-12 12:06:09 -0500730 if (!index--) {
Peng Taod7e09d02013-05-02 16:46:55 +0800731 return copy_to_user(name_up, grp->grp_name, len) ?
James Simmons0b4427d2016-03-12 13:00:35 -0500732 -EFAULT : 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800733 }
734 }
735
736 return -ENOENT;
737}
738
739static int
740lstcon_nodes_getent(struct list_head *head, int *index_p,
Frank Zago08816b22016-01-03 12:06:00 -0500741 int *count_p, lstcon_node_ent_t __user *dents_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800742{
James Simmonse00f9782016-04-06 15:25:43 -0400743 struct lstcon_ndlink *ndl;
James Simmonsf1e34162016-04-06 15:25:42 -0400744 struct lstcon_node *nd;
Mike Shuey74d68012015-05-19 10:14:38 -0400745 int count = 0;
746 int index = 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800747
James Simmons06ace262016-02-12 12:06:08 -0500748 LASSERT(index_p && count_p);
749 LASSERT(dents_up);
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200750 LASSERT(*index_p >= 0);
751 LASSERT(*count_p > 0);
Peng Taod7e09d02013-05-02 16:46:55 +0800752
753 list_for_each_entry(ndl, head, ndl_link) {
754 if (index++ < *index_p)
755 continue;
756
757 if (count >= *count_p)
758 break;
759
760 nd = ndl->ndl_node;
761 if (copy_to_user(&dents_up[count].nde_id,
James Simmonsc314c312016-02-12 12:06:01 -0500762 &nd->nd_id, sizeof(nd->nd_id)) ||
Peng Taod7e09d02013-05-02 16:46:55 +0800763 copy_to_user(&dents_up[count].nde_state,
James Simmonsc314c312016-02-12 12:06:01 -0500764 &nd->nd_state, sizeof(nd->nd_state)))
Peng Taod7e09d02013-05-02 16:46:55 +0800765 return -EFAULT;
766
Asaf Vertz13534f82015-02-01 13:29:23 +0200767 count++;
Peng Taod7e09d02013-05-02 16:46:55 +0800768 }
769
770 if (index <= *index_p)
771 return -ENOENT;
772
773 *count_p = count;
774 *index_p = index;
775
776 return 0;
777}
778
779int
Frank Zago08816b22016-01-03 12:06:00 -0500780lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p,
781 int *index_p, int *count_p,
782 lstcon_node_ent_t __user *dents_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800783{
784 lstcon_ndlist_ent_t *gentp;
James Simmons6bd88c72016-04-06 15:25:44 -0400785 struct lstcon_group *grp;
James Simmonse00f9782016-04-06 15:25:43 -0400786 struct lstcon_ndlink *ndl;
Mike Shuey74d68012015-05-19 10:14:38 -0400787 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800788
789 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -0500790 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800791 CDEBUG(D_NET, "Can't find group %s\n", name);
792 return rc;
793 }
794
Sachin Kamataad7b602013-10-09 15:58:27 +0530795 if (dents_up) {
Peng Taod7e09d02013-05-02 16:46:55 +0800796 /* verbose query */
797 rc = lstcon_nodes_getent(&grp->grp_ndl_list,
798 index_p, count_p, dents_up);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530799 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800800
801 return rc;
802 }
803
804 /* non-verbose query */
805 LIBCFS_ALLOC(gentp, sizeof(lstcon_ndlist_ent_t));
James Simmons06ace262016-02-12 12:06:08 -0500806 if (!gentp) {
Peng Taod7e09d02013-05-02 16:46:55 +0800807 CERROR("Can't allocate ndlist_ent\n");
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530808 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800809
810 return -ENOMEM;
811 }
812
Peng Taod7e09d02013-05-02 16:46:55 +0800813 list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link)
814 LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp);
815
816 rc = copy_to_user(gents_p, gentp,
James Simmonsc314c312016-02-12 12:06:01 -0500817 sizeof(lstcon_ndlist_ent_t)) ? -EFAULT : 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800818
819 LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t));
820
Shivani Bhardwaj33db6862015-10-29 11:02:23 +0530821 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +0800822
823 return 0;
824}
825
Himangi Saraogi18ce30c2014-03-13 01:34:39 +0530826static int
James Simmonsdcdc7c82016-04-06 15:25:46 -0400827lstcon_batch_find(const char *name, struct lstcon_batch **batpp)
Peng Taod7e09d02013-05-02 16:46:55 +0800828{
James Simmonsdcdc7c82016-04-06 15:25:46 -0400829 struct lstcon_batch *bat;
Peng Taod7e09d02013-05-02 16:46:55 +0800830
831 list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) {
James Simmons5fd88332016-02-12 12:06:09 -0500832 if (!strncmp(bat->bat_name, name, LST_NAME_SIZE)) {
Peng Taod7e09d02013-05-02 16:46:55 +0800833 *batpp = bat;
834 return 0;
835 }
836 }
837
838 return -ENOENT;
839}
840
841int
842lstcon_batch_add(char *name)
843{
James Simmonsdcdc7c82016-04-06 15:25:46 -0400844 struct lstcon_batch *bat;
Mike Shuey74d68012015-05-19 10:14:38 -0400845 int i;
846 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800847
James Simmons5fd88332016-02-12 12:06:09 -0500848 rc = !lstcon_batch_find(name, &bat) ? -EEXIST : 0;
849 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800850 CDEBUG(D_NET, "Batch %s already exists\n", name);
851 return rc;
852 }
853
James Simmonsdcdc7c82016-04-06 15:25:46 -0400854 LIBCFS_ALLOC(bat, sizeof(struct lstcon_batch));
James Simmons06ace262016-02-12 12:06:08 -0500855 if (!bat) {
Peng Taod7e09d02013-05-02 16:46:55 +0800856 CERROR("Can't allocate descriptor for batch %s\n", name);
857 return -ENOMEM;
858 }
859
860 LIBCFS_ALLOC(bat->bat_cli_hash,
861 sizeof(struct list_head) * LST_NODE_HASHSIZE);
James Simmons06ace262016-02-12 12:06:08 -0500862 if (!bat->bat_cli_hash) {
Peng Taod7e09d02013-05-02 16:46:55 +0800863 CERROR("Can't allocate hash for batch %s\n", name);
James Simmonsdcdc7c82016-04-06 15:25:46 -0400864 LIBCFS_FREE(bat, sizeof(struct lstcon_batch));
Peng Taod7e09d02013-05-02 16:46:55 +0800865
866 return -ENOMEM;
867 }
868
869 LIBCFS_ALLOC(bat->bat_srv_hash,
870 sizeof(struct list_head) * LST_NODE_HASHSIZE);
James Simmons06ace262016-02-12 12:06:08 -0500871 if (!bat->bat_srv_hash) {
Peng Taod7e09d02013-05-02 16:46:55 +0800872 CERROR("Can't allocate hash for batch %s\n", name);
873 LIBCFS_FREE(bat->bat_cli_hash, LST_NODE_HASHSIZE);
James Simmonsdcdc7c82016-04-06 15:25:46 -0400874 LIBCFS_FREE(bat, sizeof(struct lstcon_batch));
Peng Taod7e09d02013-05-02 16:46:55 +0800875
876 return -ENOMEM;
877 }
878
Sebastien Buisson661489a2016-03-02 17:01:51 -0500879 if (strlen(name) > sizeof(bat->bat_name) - 1) {
880 LIBCFS_FREE(bat->bat_srv_hash, LST_NODE_HASHSIZE);
881 LIBCFS_FREE(bat->bat_cli_hash, LST_NODE_HASHSIZE);
James Simmonsdcdc7c82016-04-06 15:25:46 -0400882 LIBCFS_FREE(bat, sizeof(struct lstcon_batch));
Sebastien Buisson661489a2016-03-02 17:01:51 -0500883 return -E2BIG;
884 }
885 strncpy(bat->bat_name, name, sizeof(bat->bat_name));
Peng Taod7e09d02013-05-02 16:46:55 +0800886 bat->bat_hdr.tsb_index = 0;
887 bat->bat_hdr.tsb_id.bat_id = ++console_session.ses_id_cookie;
888
889 bat->bat_ntest = 0;
890 bat->bat_state = LST_BATCH_IDLE;
891
892 INIT_LIST_HEAD(&bat->bat_cli_list);
893 INIT_LIST_HEAD(&bat->bat_srv_list);
894 INIT_LIST_HEAD(&bat->bat_test_list);
895 INIT_LIST_HEAD(&bat->bat_trans_list);
896
897 for (i = 0; i < LST_NODE_HASHSIZE; i++) {
898 INIT_LIST_HEAD(&bat->bat_cli_hash[i]);
899 INIT_LIST_HEAD(&bat->bat_srv_hash[i]);
900 }
901
902 list_add_tail(&bat->bat_link, &console_session.ses_bat_list);
903
904 return rc;
905}
906
907int
Frank Zago08816b22016-01-03 12:06:00 -0500908lstcon_batch_list(int index, int len, char __user *name_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800909{
James Simmonsdcdc7c82016-04-06 15:25:46 -0400910 struct lstcon_batch *bat;
Peng Taod7e09d02013-05-02 16:46:55 +0800911
James Simmons06ace262016-02-12 12:06:08 -0500912 LASSERT(name_up);
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +0200913 LASSERT(index >= 0);
Peng Taod7e09d02013-05-02 16:46:55 +0800914
915 list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) {
James Simmons5fd88332016-02-12 12:06:09 -0500916 if (!index--) {
Greg Donald1d8cb702014-08-25 20:07:19 -0500917 return copy_to_user(name_up, bat->bat_name, len) ?
James Simmons2df122b2016-03-11 20:29:51 -0500918 -EFAULT : 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800919 }
920 }
921
922 return -ENOENT;
923}
924
925int
Frank Zago08816b22016-01-03 12:06:00 -0500926lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up,
927 int server, int testidx, int *index_p, int *ndent_p,
928 lstcon_node_ent_t __user *dents_up)
Peng Taod7e09d02013-05-02 16:46:55 +0800929{
930 lstcon_test_batch_ent_t *entp;
Mike Shuey74d68012015-05-19 10:14:38 -0400931 struct list_head *clilst;
932 struct list_head *srvlst;
James Simmonsee3b6f12016-04-12 12:16:01 -0400933 struct lstcon_test *test = NULL;
James Simmonsdcdc7c82016-04-06 15:25:46 -0400934 struct lstcon_batch *bat;
James Simmonse00f9782016-04-06 15:25:43 -0400935 struct lstcon_ndlink *ndl;
Mike Shuey74d68012015-05-19 10:14:38 -0400936 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +0800937
938 rc = lstcon_batch_find(name, &bat);
James Simmons5fd88332016-02-12 12:06:09 -0500939 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +0800940 CDEBUG(D_NET, "Can't find batch %s\n", name);
941 return -ENOENT;
942 }
943
944 if (testidx > 0) {
945 /* query test, test index start from 1 */
946 list_for_each_entry(test, &bat->bat_test_list, tes_link) {
947 if (testidx-- == 1)
948 break;
949 }
950
951 if (testidx > 0) {
952 CDEBUG(D_NET, "Can't find specified test in batch\n");
953 return -ENOENT;
954 }
955 }
956
James Simmons06ace262016-02-12 12:06:08 -0500957 clilst = !test ? &bat->bat_cli_list :
958 &test->tes_src_grp->grp_ndl_list;
959 srvlst = !test ? &bat->bat_srv_list :
960 &test->tes_dst_grp->grp_ndl_list;
Peng Taod7e09d02013-05-02 16:46:55 +0800961
James Simmons06ace262016-02-12 12:06:08 -0500962 if (dents_up) {
Mike Rapoportb2952d62015-09-03 11:49:13 +0300963 rc = lstcon_nodes_getent((server ? srvlst : clilst),
Peng Taod7e09d02013-05-02 16:46:55 +0800964 index_p, ndent_p, dents_up);
965 return rc;
966 }
967
968 /* non-verbose query */
969 LIBCFS_ALLOC(entp, sizeof(lstcon_test_batch_ent_t));
James Simmons06ace262016-02-12 12:06:08 -0500970 if (!entp)
Peng Taod7e09d02013-05-02 16:46:55 +0800971 return -ENOMEM;
972
James Simmons06ace262016-02-12 12:06:08 -0500973 if (!test) {
Peng Taod7e09d02013-05-02 16:46:55 +0800974 entp->u.tbe_batch.bae_ntest = bat->bat_ntest;
975 entp->u.tbe_batch.bae_state = bat->bat_state;
Peng Taod7e09d02013-05-02 16:46:55 +0800976 } else {
James Simmonsec436b92016-03-11 20:29:46 -0500977 entp->u.tbe_test.tse_type = test->tes_type;
978 entp->u.tbe_test.tse_loop = test->tes_loop;
Peng Taod7e09d02013-05-02 16:46:55 +0800979 entp->u.tbe_test.tse_concur = test->tes_concur;
980 }
981
982 list_for_each_entry(ndl, clilst, ndl_link)
983 LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_cli_nle);
984
985 list_for_each_entry(ndl, srvlst, ndl_link)
986 LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_srv_nle);
987
988 rc = copy_to_user(ent_up, entp,
James Simmonsc314c312016-02-12 12:06:01 -0500989 sizeof(lstcon_test_batch_ent_t)) ? -EFAULT : 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800990
991 LIBCFS_FREE(entp, sizeof(lstcon_test_batch_ent_t));
992
993 return rc;
994}
995
Himangi Saraogi18ce30c2014-03-13 01:34:39 +0530996static int
James Simmonsf1e34162016-04-06 15:25:42 -0400997lstcon_batrpc_condition(int transop, struct lstcon_node *nd, void *arg)
Peng Taod7e09d02013-05-02 16:46:55 +0800998{
999 switch (transop) {
1000 case LST_TRANS_TSBRUN:
1001 if (nd->nd_state != LST_NODE_ACTIVE)
1002 return -ENETDOWN;
1003 break;
1004
1005 case LST_TRANS_TSBSTOP:
1006 if (nd->nd_state != LST_NODE_ACTIVE)
1007 return 0;
1008 break;
1009
1010 case LST_TRANS_TSBCLIQRY:
1011 case LST_TRANS_TSBSRVQRY:
1012 break;
1013 }
1014
1015 return 1;
1016}
1017
1018static int
James Simmonsdcdc7c82016-04-06 15:25:46 -04001019lstcon_batch_op(struct lstcon_batch *bat, int transop,
Frank Zago08816b22016-01-03 12:06:00 -05001020 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001021{
James Simmonsd8742c82016-04-06 15:25:41 -04001022 struct lstcon_rpc_trans *trans;
Mike Shuey74d68012015-05-19 10:14:38 -04001023 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001024
1025 rc = lstcon_rpc_trans_ndlist(&bat->bat_cli_list,
1026 &bat->bat_trans_list, transop,
1027 bat, lstcon_batrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001028 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001029 CERROR("Can't create transaction: %d\n", rc);
1030 return rc;
1031 }
1032
1033 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
1034
1035 rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
1036
1037 lstcon_rpc_trans_destroy(trans);
1038
1039 return rc;
1040}
1041
1042int
Frank Zago08816b22016-01-03 12:06:00 -05001043lstcon_batch_run(char *name, int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001044{
James Simmonsdcdc7c82016-04-06 15:25:46 -04001045 struct lstcon_batch *bat;
Mike Shuey74d68012015-05-19 10:14:38 -04001046 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001047
James Simmons5fd88332016-02-12 12:06:09 -05001048 if (lstcon_batch_find(name, &bat)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001049 CDEBUG(D_NET, "Can't find batch %s\n", name);
1050 return -ENOENT;
1051 }
1052
1053 bat->bat_arg = timeout;
1054
1055 rc = lstcon_batch_op(bat, LST_TRANS_TSBRUN, result_up);
1056
1057 /* mark batch as running if it's started in any node */
James Simmons5fd88332016-02-12 12:06:09 -05001058 if (lstcon_tsbop_stat_success(lstcon_trans_stat(), 0))
Peng Taod7e09d02013-05-02 16:46:55 +08001059 bat->bat_state = LST_BATCH_RUNNING;
1060
1061 return rc;
1062}
1063
1064int
Frank Zago08816b22016-01-03 12:06:00 -05001065lstcon_batch_stop(char *name, int force, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001066{
James Simmonsdcdc7c82016-04-06 15:25:46 -04001067 struct lstcon_batch *bat;
Mike Shuey74d68012015-05-19 10:14:38 -04001068 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001069
James Simmons5fd88332016-02-12 12:06:09 -05001070 if (lstcon_batch_find(name, &bat)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001071 CDEBUG(D_NET, "Can't find batch %s\n", name);
1072 return -ENOENT;
1073 }
1074
1075 bat->bat_arg = force;
1076
1077 rc = lstcon_batch_op(bat, LST_TRANS_TSBSTOP, result_up);
1078
1079 /* mark batch as stopped if all RPCs finished */
James Simmons5fd88332016-02-12 12:06:09 -05001080 if (!lstcon_tsbop_stat_failure(lstcon_trans_stat(), 0))
Peng Taod7e09d02013-05-02 16:46:55 +08001081 bat->bat_state = LST_BATCH_IDLE;
1082
1083 return rc;
1084}
1085
1086static void
James Simmonsdcdc7c82016-04-06 15:25:46 -04001087lstcon_batch_destroy(struct lstcon_batch *bat)
Peng Taod7e09d02013-05-02 16:46:55 +08001088{
James Simmonse00f9782016-04-06 15:25:43 -04001089 struct lstcon_ndlink *ndl;
James Simmonsee3b6f12016-04-12 12:16:01 -04001090 struct lstcon_test *test;
Mike Shuey74d68012015-05-19 10:14:38 -04001091 int i;
Peng Taod7e09d02013-05-02 16:46:55 +08001092
1093 list_del(&bat->bat_link);
1094
1095 while (!list_empty(&bat->bat_test_list)) {
1096 test = list_entry(bat->bat_test_list.next,
James Simmonsee3b6f12016-04-12 12:16:01 -04001097 struct lstcon_test, tes_link);
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001098 LASSERT(list_empty(&test->tes_trans_list));
Peng Taod7e09d02013-05-02 16:46:55 +08001099
1100 list_del(&test->tes_link);
1101
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301102 lstcon_group_decref(test->tes_src_grp);
1103 lstcon_group_decref(test->tes_dst_grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001104
James Simmonsee3b6f12016-04-12 12:16:01 -04001105 LIBCFS_FREE(test, offsetof(struct lstcon_test,
Peng Taod7e09d02013-05-02 16:46:55 +08001106 tes_param[test->tes_paramlen]));
1107 }
1108
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001109 LASSERT(list_empty(&bat->bat_trans_list));
Peng Taod7e09d02013-05-02 16:46:55 +08001110
1111 while (!list_empty(&bat->bat_cli_list)) {
1112 ndl = list_entry(bat->bat_cli_list.next,
James Simmonse00f9782016-04-06 15:25:43 -04001113 struct lstcon_ndlink, ndl_link);
Peng Taod7e09d02013-05-02 16:46:55 +08001114 list_del_init(&ndl->ndl_link);
1115
1116 lstcon_ndlink_release(ndl);
1117 }
1118
1119 while (!list_empty(&bat->bat_srv_list)) {
1120 ndl = list_entry(bat->bat_srv_list.next,
James Simmonse00f9782016-04-06 15:25:43 -04001121 struct lstcon_ndlink, ndl_link);
Peng Taod7e09d02013-05-02 16:46:55 +08001122 list_del_init(&ndl->ndl_link);
1123
1124 lstcon_ndlink_release(ndl);
1125 }
1126
1127 for (i = 0; i < LST_NODE_HASHSIZE; i++) {
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001128 LASSERT(list_empty(&bat->bat_cli_hash[i]));
1129 LASSERT(list_empty(&bat->bat_srv_hash[i]));
Peng Taod7e09d02013-05-02 16:46:55 +08001130 }
1131
1132 LIBCFS_FREE(bat->bat_cli_hash,
1133 sizeof(struct list_head) * LST_NODE_HASHSIZE);
1134 LIBCFS_FREE(bat->bat_srv_hash,
1135 sizeof(struct list_head) * LST_NODE_HASHSIZE);
James Simmonsdcdc7c82016-04-06 15:25:46 -04001136 LIBCFS_FREE(bat, sizeof(struct lstcon_batch));
Peng Taod7e09d02013-05-02 16:46:55 +08001137}
1138
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301139static int
James Simmonsf1e34162016-04-06 15:25:42 -04001140lstcon_testrpc_condition(int transop, struct lstcon_node *nd, void *arg)
Peng Taod7e09d02013-05-02 16:46:55 +08001141{
James Simmonsee3b6f12016-04-12 12:16:01 -04001142 struct lstcon_test *test;
James Simmonsdcdc7c82016-04-06 15:25:46 -04001143 struct lstcon_batch *batch;
James Simmonse00f9782016-04-06 15:25:43 -04001144 struct lstcon_ndlink *ndl;
Mike Shuey74d68012015-05-19 10:14:38 -04001145 struct list_head *hash;
1146 struct list_head *head;
Peng Taod7e09d02013-05-02 16:46:55 +08001147
James Simmonsee3b6f12016-04-12 12:16:01 -04001148 test = (struct lstcon_test *)arg;
James Simmons06ace262016-02-12 12:06:08 -05001149 LASSERT(test);
Peng Taod7e09d02013-05-02 16:46:55 +08001150
1151 batch = test->tes_batch;
James Simmons06ace262016-02-12 12:06:08 -05001152 LASSERT(batch);
Peng Taod7e09d02013-05-02 16:46:55 +08001153
1154 if (test->tes_oneside &&
1155 transop == LST_TRANS_TSBSRVADD)
1156 return 0;
1157
1158 if (nd->nd_state != LST_NODE_ACTIVE)
1159 return -ENETDOWN;
1160
1161 if (transop == LST_TRANS_TSBCLIADD) {
1162 hash = batch->bat_cli_hash;
1163 head = &batch->bat_cli_list;
1164
1165 } else {
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001166 LASSERT(transop == LST_TRANS_TSBSRVADD);
Peng Taod7e09d02013-05-02 16:46:55 +08001167
1168 hash = batch->bat_srv_hash;
1169 head = &batch->bat_srv_list;
1170 }
1171
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001172 LASSERT(nd->nd_id.nid != LNET_NID_ANY);
Peng Taod7e09d02013-05-02 16:46:55 +08001173
James Simmons5fd88332016-02-12 12:06:09 -05001174 if (lstcon_ndlink_find(hash, nd->nd_id, &ndl, 1))
Peng Taod7e09d02013-05-02 16:46:55 +08001175 return -ENOMEM;
1176
1177 if (list_empty(&ndl->ndl_link))
1178 list_add_tail(&ndl->ndl_link, head);
1179
1180 return 1;
1181}
1182
1183static int
James Simmonsee3b6f12016-04-12 12:16:01 -04001184lstcon_test_nodes_add(struct lstcon_test *test, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001185{
James Simmonsd8742c82016-04-06 15:25:41 -04001186 struct lstcon_rpc_trans *trans;
James Simmons6bd88c72016-04-06 15:25:44 -04001187 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -04001188 int transop;
1189 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001190
James Simmons06ace262016-02-12 12:06:08 -05001191 LASSERT(test->tes_src_grp);
1192 LASSERT(test->tes_dst_grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001193
1194 transop = LST_TRANS_TSBSRVADD;
James Simmonsec436b92016-03-11 20:29:46 -05001195 grp = test->tes_dst_grp;
Peng Taod7e09d02013-05-02 16:46:55 +08001196again:
1197 rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
1198 &test->tes_trans_list, transop,
1199 test, lstcon_testrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001200 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001201 CERROR("Can't create transaction: %d\n", rc);
1202 return rc;
1203 }
1204
1205 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
1206
James Simmons5fd88332016-02-12 12:06:09 -05001207 if (lstcon_trans_stat()->trs_rpc_errno ||
1208 lstcon_trans_stat()->trs_fwk_errno) {
Peng Taod7e09d02013-05-02 16:46:55 +08001209 lstcon_rpc_trans_interpreter(trans, result_up, NULL);
1210
1211 lstcon_rpc_trans_destroy(trans);
1212 /* return if any error */
Joe Perches2d00bd12014-11-23 11:28:50 -08001213 CDEBUG(D_NET, "Failed to add test %s, RPC error %d, framework error %d\n",
Peng Taod7e09d02013-05-02 16:46:55 +08001214 transop == LST_TRANS_TSBCLIADD ? "client" : "server",
1215 lstcon_trans_stat()->trs_rpc_errno,
1216 lstcon_trans_stat()->trs_fwk_errno);
1217
1218 return rc;
1219 }
1220
1221 lstcon_rpc_trans_destroy(trans);
1222
1223 if (transop == LST_TRANS_TSBCLIADD)
1224 return rc;
1225
1226 transop = LST_TRANS_TSBCLIADD;
1227 grp = test->tes_src_grp;
1228 test->tes_cliidx = 0;
1229
1230 /* requests to test clients */
1231 goto again;
1232}
1233
Amir Shehata4f317742013-11-21 22:24:50 +08001234static int
James Simmonsdcdc7c82016-04-06 15:25:46 -04001235lstcon_verify_batch(const char *name, struct lstcon_batch **batch)
Peng Taod7e09d02013-05-02 16:46:55 +08001236{
Amir Shehata4f317742013-11-21 22:24:50 +08001237 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001238
Amir Shehata4f317742013-11-21 22:24:50 +08001239 rc = lstcon_batch_find(name, batch);
James Simmons5fd88332016-02-12 12:06:09 -05001240 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001241 CDEBUG(D_NET, "Can't find batch %s\n", name);
1242 return rc;
1243 }
1244
Amir Shehata4f317742013-11-21 22:24:50 +08001245 if ((*batch)->bat_state != LST_BATCH_IDLE) {
Peng Taod7e09d02013-05-02 16:46:55 +08001246 CDEBUG(D_NET, "Can't change running batch %s\n", name);
Amir Shehata4f317742013-11-21 22:24:50 +08001247 return -EINVAL;
1248 }
1249
1250 return 0;
1251}
1252
1253static int
James Simmons6bd88c72016-04-06 15:25:44 -04001254lstcon_verify_group(const char *name, struct lstcon_group **grp)
Amir Shehata4f317742013-11-21 22:24:50 +08001255{
Mike Shuey74d68012015-05-19 10:14:38 -04001256 int rc;
James Simmonse00f9782016-04-06 15:25:43 -04001257 struct lstcon_ndlink *ndl;
Amir Shehata4f317742013-11-21 22:24:50 +08001258
1259 rc = lstcon_group_find(name, grp);
James Simmons5fd88332016-02-12 12:06:09 -05001260 if (rc) {
Amir Shehata4f317742013-11-21 22:24:50 +08001261 CDEBUG(D_NET, "can't find group %s\n", name);
Peng Taod7e09d02013-05-02 16:46:55 +08001262 return rc;
1263 }
1264
Amir Shehata4f317742013-11-21 22:24:50 +08001265 list_for_each_entry(ndl, &(*grp)->grp_ndl_list, ndl_link) {
1266 if (ndl->ndl_node->nd_state == LST_NODE_ACTIVE)
1267 return 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001268 }
1269
Amir Shehata4f317742013-11-21 22:24:50 +08001270 CDEBUG(D_NET, "Group %s has no ACTIVE nodes\n", name);
1271
1272 return -EINVAL;
1273}
1274
1275int
1276lstcon_test_add(char *batch_name, int type, int loop,
1277 int concur, int dist, int span,
1278 char *src_name, char *dst_name,
1279 void *param, int paramlen, int *retp,
Frank Zago08816b22016-01-03 12:06:00 -05001280 struct list_head __user *result_up)
Amir Shehata4f317742013-11-21 22:24:50 +08001281{
James Simmonsee3b6f12016-04-12 12:16:01 -04001282 struct lstcon_test *test = NULL;
James Simmons00b5fdb2016-03-11 20:29:45 -05001283 int rc;
James Simmons6bd88c72016-04-06 15:25:44 -04001284 struct lstcon_group *src_grp = NULL;
1285 struct lstcon_group *dst_grp = NULL;
James Simmonsdcdc7c82016-04-06 15:25:46 -04001286 struct lstcon_batch *batch = NULL;
Amir Shehata4f317742013-11-21 22:24:50 +08001287
1288 /*
1289 * verify that a batch of the given name exists, and the groups
1290 * that will be part of the batch exist and have at least one
1291 * active node
1292 */
1293 rc = lstcon_verify_batch(batch_name, &batch);
James Simmons5fd88332016-02-12 12:06:09 -05001294 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001295 goto out;
Amir Shehata4f317742013-11-21 22:24:50 +08001296
1297 rc = lstcon_verify_group(src_name, &src_grp);
James Simmons5fd88332016-02-12 12:06:09 -05001298 if (rc)
Amir Shehata4f317742013-11-21 22:24:50 +08001299 goto out;
1300
1301 rc = lstcon_verify_group(dst_name, &dst_grp);
James Simmons5fd88332016-02-12 12:06:09 -05001302 if (rc)
Amir Shehata4f317742013-11-21 22:24:50 +08001303 goto out;
Peng Taod7e09d02013-05-02 16:46:55 +08001304
1305 if (dst_grp->grp_userland)
1306 *retp = 1;
1307
James Simmonsee3b6f12016-04-12 12:16:01 -04001308 LIBCFS_ALLOC(test, offsetof(struct lstcon_test, tes_param[paramlen]));
Peng Taod7e09d02013-05-02 16:46:55 +08001309 if (!test) {
1310 CERROR("Can't allocate test descriptor\n");
1311 rc = -ENOMEM;
1312
1313 goto out;
1314 }
1315
James Simmonsec436b92016-03-11 20:29:46 -05001316 test->tes_hdr.tsb_id = batch->bat_hdr.tsb_id;
1317 test->tes_batch = batch;
1318 test->tes_type = type;
1319 test->tes_oneside = 0; /* TODO */
1320 test->tes_loop = loop;
1321 test->tes_concur = concur;
1322 test->tes_stop_onerr = 1; /* TODO */
1323 test->tes_span = span;
1324 test->tes_dist = dist;
1325 test->tes_cliidx = 0; /* just used for creating RPC */
1326 test->tes_src_grp = src_grp;
1327 test->tes_dst_grp = dst_grp;
Peng Taod7e09d02013-05-02 16:46:55 +08001328 INIT_LIST_HEAD(&test->tes_trans_list);
1329
James Simmons06ace262016-02-12 12:06:08 -05001330 if (param) {
Peng Taod7e09d02013-05-02 16:46:55 +08001331 test->tes_paramlen = paramlen;
1332 memcpy(&test->tes_param[0], param, paramlen);
1333 }
1334
1335 rc = lstcon_test_nodes_add(test, result_up);
1336
James Simmons5fd88332016-02-12 12:06:09 -05001337 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001338 goto out;
1339
James Simmons5fd88332016-02-12 12:06:09 -05001340 if (lstcon_trans_stat()->trs_rpc_errno ||
1341 lstcon_trans_stat()->trs_fwk_errno)
Amir Shehata4f317742013-11-21 22:24:50 +08001342 CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type,
1343 batch_name);
Peng Taod7e09d02013-05-02 16:46:55 +08001344
1345 /* add to test list anyway, so user can check what's going on */
1346 list_add_tail(&test->tes_link, &batch->bat_test_list);
1347
Asaf Vertz13534f82015-02-01 13:29:23 +02001348 batch->bat_ntest++;
Peng Taod7e09d02013-05-02 16:46:55 +08001349 test->tes_hdr.tsb_index = batch->bat_ntest;
1350
1351 /* hold groups so nobody can change them */
1352 return rc;
1353out:
James Simmons06ace262016-02-12 12:06:08 -05001354 if (test)
James Simmonsee3b6f12016-04-12 12:16:01 -04001355 LIBCFS_FREE(test, offsetof(struct lstcon_test, tes_param[paramlen]));
Peng Taod7e09d02013-05-02 16:46:55 +08001356
James Simmons06ace262016-02-12 12:06:08 -05001357 if (dst_grp)
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301358 lstcon_group_decref(dst_grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001359
James Simmons06ace262016-02-12 12:06:08 -05001360 if (src_grp)
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301361 lstcon_group_decref(src_grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001362
1363 return rc;
1364}
1365
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301366static int
James Simmonsee3b6f12016-04-12 12:16:01 -04001367lstcon_test_find(struct lstcon_batch *batch, int idx, struct lstcon_test **testpp)
Peng Taod7e09d02013-05-02 16:46:55 +08001368{
James Simmonsee3b6f12016-04-12 12:16:01 -04001369 struct lstcon_test *test;
Peng Taod7e09d02013-05-02 16:46:55 +08001370
1371 list_for_each_entry(test, &batch->bat_test_list, tes_link) {
1372 if (idx == test->tes_hdr.tsb_index) {
1373 *testpp = test;
1374 return 0;
1375 }
1376 }
1377
1378 return -ENOENT;
1379}
1380
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301381static int
James Simmonsfd7a1a32016-04-06 15:25:48 -04001382lstcon_tsbrpc_readent(int transop, struct srpc_msg *msg,
Frank Zago08816b22016-01-03 12:06:00 -05001383 lstcon_rpc_ent_t __user *ent_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001384{
James Simmons45d2f4f2016-04-12 12:16:02 -04001385 struct srpc_batch_reply *rep = &msg->msg_body.bat_reply;
Peng Taod7e09d02013-05-02 16:46:55 +08001386
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001387 LASSERT(transop == LST_TRANS_TSBCLIQRY ||
James Simmonsc314c312016-02-12 12:06:01 -05001388 transop == LST_TRANS_TSBSRVQRY);
Peng Taod7e09d02013-05-02 16:46:55 +08001389
1390 /* positive errno, framework error code */
James Simmonsc314c312016-02-12 12:06:01 -05001391 if (copy_to_user(&ent_up->rpe_priv[0], &rep->bar_active,
1392 sizeof(rep->bar_active)))
Peng Taod7e09d02013-05-02 16:46:55 +08001393 return -EFAULT;
1394
1395 return 0;
1396}
1397
1398int
1399lstcon_test_batch_query(char *name, int testidx, int client,
Frank Zago08816b22016-01-03 12:06:00 -05001400 int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001401{
James Simmonsd8742c82016-04-06 15:25:41 -04001402 struct lstcon_rpc_trans *trans;
Mike Shuey74d68012015-05-19 10:14:38 -04001403 struct list_head *translist;
1404 struct list_head *ndlist;
James Simmons7299d182016-04-06 15:25:45 -04001405 struct lstcon_tsb_hdr *hdr;
James Simmonsdcdc7c82016-04-06 15:25:46 -04001406 struct lstcon_batch *batch;
James Simmonsee3b6f12016-04-12 12:16:01 -04001407 struct lstcon_test *test = NULL;
Mike Shuey74d68012015-05-19 10:14:38 -04001408 int transop;
1409 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001410
1411 rc = lstcon_batch_find(name, &batch);
James Simmons5fd88332016-02-12 12:06:09 -05001412 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001413 CDEBUG(D_NET, "Can't find batch: %s\n", name);
1414 return rc;
1415 }
1416
James Simmons5fd88332016-02-12 12:06:09 -05001417 if (!testidx) {
Peng Taod7e09d02013-05-02 16:46:55 +08001418 translist = &batch->bat_trans_list;
James Simmonsec436b92016-03-11 20:29:46 -05001419 ndlist = &batch->bat_cli_list;
1420 hdr = &batch->bat_hdr;
Peng Taod7e09d02013-05-02 16:46:55 +08001421 } else {
1422 /* query specified test only */
1423 rc = lstcon_test_find(batch, testidx, &test);
James Simmons5fd88332016-02-12 12:06:09 -05001424 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001425 CDEBUG(D_NET, "Can't find test: %d\n", testidx);
1426 return rc;
1427 }
1428
1429 translist = &test->tes_trans_list;
James Simmonsec436b92016-03-11 20:29:46 -05001430 ndlist = &test->tes_src_grp->grp_ndl_list;
1431 hdr = &test->tes_hdr;
Peng Taod7e09d02013-05-02 16:46:55 +08001432 }
1433
1434 transop = client ? LST_TRANS_TSBCLIQRY : LST_TRANS_TSBSRVQRY;
1435
1436 rc = lstcon_rpc_trans_ndlist(ndlist, translist, transop, hdr,
1437 lstcon_batrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001438 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001439 CERROR("Can't create transaction: %d\n", rc);
1440 return rc;
1441 }
1442
1443 lstcon_rpc_trans_postwait(trans, timeout);
1444
James Simmonsdae05872016-03-12 13:00:36 -05001445 /* query a batch, not a test */
1446 if (!testidx &&
James Simmons5fd88332016-02-12 12:06:09 -05001447 !lstcon_rpc_stat_failure(lstcon_trans_stat(), 0) &&
1448 !lstcon_tsbqry_stat_run(lstcon_trans_stat(), 0)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001449 /* all RPCs finished, and no active test */
1450 batch->bat_state = LST_BATCH_IDLE;
1451 }
1452
1453 rc = lstcon_rpc_trans_interpreter(trans, result_up,
1454 lstcon_tsbrpc_readent);
1455 lstcon_rpc_trans_destroy(trans);
1456
1457 return rc;
1458}
1459
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301460static int
James Simmonsfd7a1a32016-04-06 15:25:48 -04001461lstcon_statrpc_readent(int transop, struct srpc_msg *msg,
Frank Zago08816b22016-01-03 12:06:00 -05001462 lstcon_rpc_ent_t __user *ent_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001463{
James Simmons45d2f4f2016-04-12 12:16:02 -04001464 struct srpc_stat_reply *rep = &msg->msg_body.stat_reply;
Frank Zago08816b22016-01-03 12:06:00 -05001465 sfw_counters_t __user *sfwk_stat;
1466 srpc_counters_t __user *srpc_stat;
1467 lnet_counters_t __user *lnet_stat;
Peng Taod7e09d02013-05-02 16:46:55 +08001468
James Simmons5fd88332016-02-12 12:06:09 -05001469 if (rep->str_status)
Peng Taod7e09d02013-05-02 16:46:55 +08001470 return 0;
1471
Frank Zago08816b22016-01-03 12:06:00 -05001472 sfwk_stat = (sfw_counters_t __user *)&ent_up->rpe_payload[0];
Niranjan Dighed60fc1b2016-02-14 08:51:48 +05301473 srpc_stat = (srpc_counters_t __user *)(sfwk_stat + 1);
1474 lnet_stat = (lnet_counters_t __user *)(srpc_stat + 1);
Peng Taod7e09d02013-05-02 16:46:55 +08001475
1476 if (copy_to_user(sfwk_stat, &rep->str_fw, sizeof(*sfwk_stat)) ||
1477 copy_to_user(srpc_stat, &rep->str_rpc, sizeof(*srpc_stat)) ||
1478 copy_to_user(lnet_stat, &rep->str_lnet, sizeof(*lnet_stat)))
1479 return -EFAULT;
1480
1481 return 0;
1482}
1483
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301484static int
Peng Taod7e09d02013-05-02 16:46:55 +08001485lstcon_ndlist_stat(struct list_head *ndlist,
Frank Zago08816b22016-01-03 12:06:00 -05001486 int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001487{
Mike Shuey74d68012015-05-19 10:14:38 -04001488 struct list_head head;
James Simmonsd8742c82016-04-06 15:25:41 -04001489 struct lstcon_rpc_trans *trans;
Mike Shuey74d68012015-05-19 10:14:38 -04001490 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001491
1492 INIT_LIST_HEAD(&head);
1493
1494 rc = lstcon_rpc_trans_ndlist(ndlist, &head,
1495 LST_TRANS_STATQRY, NULL, NULL, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001496 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001497 CERROR("Can't create transaction: %d\n", rc);
1498 return rc;
1499 }
1500
1501 lstcon_rpc_trans_postwait(trans, LST_VALIDATE_TIMEOUT(timeout));
1502
1503 rc = lstcon_rpc_trans_interpreter(trans, result_up,
1504 lstcon_statrpc_readent);
1505 lstcon_rpc_trans_destroy(trans);
1506
1507 return rc;
1508}
1509
1510int
Frank Zago08816b22016-01-03 12:06:00 -05001511lstcon_group_stat(char *grp_name, int timeout,
1512 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001513{
James Simmons6bd88c72016-04-06 15:25:44 -04001514 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -04001515 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001516
1517 rc = lstcon_group_find(grp_name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -05001518 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001519 CDEBUG(D_NET, "Can't find group %s\n", grp_name);
1520 return rc;
1521 }
1522
1523 rc = lstcon_ndlist_stat(&grp->grp_ndl_list, timeout, result_up);
1524
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301525 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001526
1527 return rc;
1528}
1529
1530int
Frank Zago08816b22016-01-03 12:06:00 -05001531lstcon_nodes_stat(int count, lnet_process_id_t __user *ids_up,
1532 int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001533{
James Simmonse00f9782016-04-06 15:25:43 -04001534 struct lstcon_ndlink *ndl;
James Simmons6bd88c72016-04-06 15:25:44 -04001535 struct lstcon_group *tmp;
Mike Shuey74d68012015-05-19 10:14:38 -04001536 lnet_process_id_t id;
1537 int i;
1538 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001539
1540 rc = lstcon_group_alloc(NULL, &tmp);
James Simmons5fd88332016-02-12 12:06:09 -05001541 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001542 CERROR("Out of memory\n");
1543 return -ENOMEM;
1544 }
1545
1546 for (i = 0 ; i < count; i++) {
1547 if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
1548 rc = -EFAULT;
1549 break;
1550 }
1551
1552 /* add to tmp group */
1553 rc = lstcon_group_ndlink_find(tmp, id, &ndl, 2);
James Simmons5fd88332016-02-12 12:06:09 -05001554 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001555 CDEBUG((rc == -ENOMEM) ? D_ERROR : D_NET,
1556 "Failed to find or create %s: %d\n",
1557 libcfs_id2str(id), rc);
1558 break;
1559 }
1560 }
1561
James Simmons5fd88332016-02-12 12:06:09 -05001562 if (rc) {
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301563 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +08001564 return rc;
1565 }
1566
1567 rc = lstcon_ndlist_stat(&tmp->grp_ndl_list, timeout, result_up);
1568
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301569 lstcon_group_decref(tmp);
Peng Taod7e09d02013-05-02 16:46:55 +08001570
1571 return rc;
1572}
1573
Himangi Saraogi18ce30c2014-03-13 01:34:39 +05301574static int
Peng Taod7e09d02013-05-02 16:46:55 +08001575lstcon_debug_ndlist(struct list_head *ndlist,
1576 struct list_head *translist,
Frank Zago08816b22016-01-03 12:06:00 -05001577 int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001578{
James Simmonsd8742c82016-04-06 15:25:41 -04001579 struct lstcon_rpc_trans *trans;
James Simmons00b5fdb2016-03-11 20:29:45 -05001580 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001581
1582 rc = lstcon_rpc_trans_ndlist(ndlist, translist, LST_TRANS_SESQRY,
1583 NULL, lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001584 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001585 CERROR("Can't create transaction: %d\n", rc);
1586 return rc;
1587 }
1588
1589 lstcon_rpc_trans_postwait(trans, LST_VALIDATE_TIMEOUT(timeout));
1590
1591 rc = lstcon_rpc_trans_interpreter(trans, result_up,
1592 lstcon_sesrpc_readent);
1593 lstcon_rpc_trans_destroy(trans);
1594
1595 return rc;
1596}
1597
1598int
Frank Zago08816b22016-01-03 12:06:00 -05001599lstcon_session_debug(int timeout, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001600{
1601 return lstcon_debug_ndlist(&console_session.ses_ndl_list,
1602 NULL, timeout, result_up);
1603}
1604
1605int
1606lstcon_batch_debug(int timeout, char *name,
Frank Zago08816b22016-01-03 12:06:00 -05001607 int client, struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001608{
James Simmonsdcdc7c82016-04-06 15:25:46 -04001609 struct lstcon_batch *bat;
Mike Shuey74d68012015-05-19 10:14:38 -04001610 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001611
1612 rc = lstcon_batch_find(name, &bat);
James Simmons5fd88332016-02-12 12:06:09 -05001613 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001614 return -ENOENT;
1615
1616 rc = lstcon_debug_ndlist(client ? &bat->bat_cli_list :
1617 &bat->bat_srv_list,
1618 NULL, timeout, result_up);
1619
1620 return rc;
1621}
1622
1623int
1624lstcon_group_debug(int timeout, char *name,
Frank Zago08816b22016-01-03 12:06:00 -05001625 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001626{
James Simmons6bd88c72016-04-06 15:25:44 -04001627 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -04001628 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001629
1630 rc = lstcon_group_find(name, &grp);
James Simmons5fd88332016-02-12 12:06:09 -05001631 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001632 return -ENOENT;
1633
1634 rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL,
1635 timeout, result_up);
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301636 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001637
1638 return rc;
1639}
1640
1641int
1642lstcon_nodes_debug(int timeout,
Frank Zago08816b22016-01-03 12:06:00 -05001643 int count, lnet_process_id_t __user *ids_up,
1644 struct list_head __user *result_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001645{
Mike Shuey74d68012015-05-19 10:14:38 -04001646 lnet_process_id_t id;
James Simmonse00f9782016-04-06 15:25:43 -04001647 struct lstcon_ndlink *ndl;
James Simmons6bd88c72016-04-06 15:25:44 -04001648 struct lstcon_group *grp;
Mike Shuey74d68012015-05-19 10:14:38 -04001649 int i;
1650 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08001651
1652 rc = lstcon_group_alloc(NULL, &grp);
James Simmons5fd88332016-02-12 12:06:09 -05001653 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001654 CDEBUG(D_NET, "Out of memory\n");
1655 return rc;
1656 }
1657
1658 for (i = 0; i < count; i++) {
1659 if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
1660 rc = -EFAULT;
1661 break;
1662 }
1663
1664 /* node is added to tmp group */
1665 rc = lstcon_group_ndlink_find(grp, id, &ndl, 1);
James Simmons5fd88332016-02-12 12:06:09 -05001666 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001667 CERROR("Can't create node link\n");
1668 break;
1669 }
1670 }
1671
James Simmons5fd88332016-02-12 12:06:09 -05001672 if (rc) {
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301673 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001674 return rc;
1675 }
1676
1677 rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL,
1678 timeout, result_up);
1679
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301680 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001681
1682 return rc;
1683}
1684
1685int
1686lstcon_session_match(lst_sid_t sid)
1687{
James Simmonsec436b92016-03-11 20:29:46 -05001688 return (console_session.ses_id.ses_nid == sid.ses_nid &&
James Simmonsb794d792016-03-11 20:29:47 -05001689 console_session.ses_id.ses_stamp == sid.ses_stamp) ? 1 : 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001690}
1691
1692static void
1693lstcon_new_session_id(lst_sid_t *sid)
1694{
Mike Shuey74d68012015-05-19 10:14:38 -04001695 lnet_process_id_t id;
Peng Taod7e09d02013-05-02 16:46:55 +08001696
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001697 LASSERT(console_session.ses_state == LST_SESSION_NONE);
Peng Taod7e09d02013-05-02 16:46:55 +08001698
1699 LNetGetId(1, &id);
James Simmonsec436b92016-03-11 20:29:46 -05001700 sid->ses_nid = id.nid;
Peng Taod7e09d02013-05-02 16:46:55 +08001701 sid->ses_stamp = cfs_time_current();
1702}
1703
Peng Taod7e09d02013-05-02 16:46:55 +08001704int
1705lstcon_session_new(char *name, int key, unsigned feats,
Frank Zago08816b22016-01-03 12:06:00 -05001706 int timeout, int force, lst_sid_t __user *sid_up)
Peng Taod7e09d02013-05-02 16:46:55 +08001707{
Mike Shuey74d68012015-05-19 10:14:38 -04001708 int rc = 0;
1709 int i;
Peng Taod7e09d02013-05-02 16:46:55 +08001710
1711 if (console_session.ses_state != LST_SESSION_NONE) {
1712 /* session exists */
1713 if (!force) {
1714 CNETERR("Session %s already exists\n",
1715 console_session.ses_name);
1716 return -EEXIST;
1717 }
1718
1719 rc = lstcon_session_end();
1720
1721 /* lstcon_session_end() only return local error */
James Simmonsb794d792016-03-11 20:29:47 -05001722 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001723 return rc;
1724 }
1725
James Simmons5fd88332016-02-12 12:06:09 -05001726 if (feats & ~LST_FEATS_MASK) {
Peng Taod7e09d02013-05-02 16:46:55 +08001727 CNETERR("Unknown session features %x\n",
1728 (feats & ~LST_FEATS_MASK));
1729 return -EINVAL;
1730 }
1731
1732 for (i = 0; i < LST_GLOBAL_HASHSIZE; i++)
1733 LASSERT(list_empty(&console_session.ses_ndl_hash[i]));
1734
1735 lstcon_new_session_id(&console_session.ses_id);
1736
Mike Shuey74d68012015-05-19 10:14:38 -04001737 console_session.ses_key = key;
1738 console_session.ses_state = LST_SESSION_ACTIVE;
1739 console_session.ses_force = !!force;
Peng Taod7e09d02013-05-02 16:46:55 +08001740 console_session.ses_features = feats;
1741 console_session.ses_feats_updated = 0;
1742 console_session.ses_timeout = (timeout <= 0) ?
1743 LST_CONSOLE_TIMEOUT : timeout;
Sebastien Buisson661489a2016-03-02 17:01:51 -05001744
James Simmonsd47e33e2016-03-11 20:29:44 -05001745 if (strlen(name) > sizeof(console_session.ses_name) - 1)
Sebastien Buisson661489a2016-03-02 17:01:51 -05001746 return -E2BIG;
Dmitry Ereminea25f452016-03-12 13:00:32 -05001747 strlcpy(console_session.ses_name, name,
Dmitry Eremin9563fe82015-11-04 13:40:00 -05001748 sizeof(console_session.ses_name));
Peng Taod7e09d02013-05-02 16:46:55 +08001749
1750 rc = lstcon_batch_add(LST_DEFAULT_BATCH);
James Simmons5fd88332016-02-12 12:06:09 -05001751 if (rc)
Peng Taod7e09d02013-05-02 16:46:55 +08001752 return rc;
1753
1754 rc = lstcon_rpc_pinger_start();
James Simmons5fd88332016-02-12 12:06:09 -05001755 if (rc) {
James Simmonsdcdc7c82016-04-06 15:25:46 -04001756 struct lstcon_batch *bat = NULL;
Peng Taod7e09d02013-05-02 16:46:55 +08001757
1758 lstcon_batch_find(LST_DEFAULT_BATCH, &bat);
1759 lstcon_batch_destroy(bat);
1760
1761 return rc;
1762 }
1763
James Simmons5fd88332016-02-12 12:06:09 -05001764 if (!copy_to_user(sid_up, &console_session.ses_id,
1765 sizeof(lst_sid_t)))
Peng Taod7e09d02013-05-02 16:46:55 +08001766 return rc;
1767
1768 lstcon_session_end();
1769
1770 return -EFAULT;
1771}
1772
1773int
Frank Zago08816b22016-01-03 12:06:00 -05001774lstcon_session_info(lst_sid_t __user *sid_up, int __user *key_up,
1775 unsigned __user *featp,
1776 lstcon_ndlist_ent_t __user *ndinfo_up,
1777 char __user *name_up, int len)
Peng Taod7e09d02013-05-02 16:46:55 +08001778{
1779 lstcon_ndlist_ent_t *entp;
James Simmonse00f9782016-04-06 15:25:43 -04001780 struct lstcon_ndlink *ndl;
Mike Shuey74d68012015-05-19 10:14:38 -04001781 int rc = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001782
1783 if (console_session.ses_state != LST_SESSION_ACTIVE)
1784 return -ESRCH;
1785
1786 LIBCFS_ALLOC(entp, sizeof(*entp));
James Simmons06ace262016-02-12 12:06:08 -05001787 if (!entp)
Peng Taod7e09d02013-05-02 16:46:55 +08001788 return -ENOMEM;
1789
Peng Taod7e09d02013-05-02 16:46:55 +08001790 list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
1791 LST_NODE_STATE_COUNTER(ndl->ndl_node, entp);
1792
1793 if (copy_to_user(sid_up, &console_session.ses_id,
James Simmonsc314c312016-02-12 12:06:01 -05001794 sizeof(lst_sid_t)) ||
Peng Taod7e09d02013-05-02 16:46:55 +08001795 copy_to_user(key_up, &console_session.ses_key,
James Simmonsc314c312016-02-12 12:06:01 -05001796 sizeof(*key_up)) ||
Peng Taod7e09d02013-05-02 16:46:55 +08001797 copy_to_user(featp, &console_session.ses_features,
James Simmonsc314c312016-02-12 12:06:01 -05001798 sizeof(*featp)) ||
Peng Taod7e09d02013-05-02 16:46:55 +08001799 copy_to_user(ndinfo_up, entp, sizeof(*entp)) ||
1800 copy_to_user(name_up, console_session.ses_name, len))
1801 rc = -EFAULT;
1802
1803 LIBCFS_FREE(entp, sizeof(*entp));
1804
1805 return rc;
1806}
1807
1808int
Emil Goode7d46a212013-07-28 00:38:55 +02001809lstcon_session_end(void)
Peng Taod7e09d02013-05-02 16:46:55 +08001810{
James Simmonsd8742c82016-04-06 15:25:41 -04001811 struct lstcon_rpc_trans *trans;
James Simmons6bd88c72016-04-06 15:25:44 -04001812 struct lstcon_group *grp;
James Simmonsdcdc7c82016-04-06 15:25:46 -04001813 struct lstcon_batch *bat;
Mike Shuey74d68012015-05-19 10:14:38 -04001814 int rc = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001815
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001816 LASSERT(console_session.ses_state == LST_SESSION_ACTIVE);
Peng Taod7e09d02013-05-02 16:46:55 +08001817
1818 rc = lstcon_rpc_trans_ndlist(&console_session.ses_ndl_list,
1819 NULL, LST_TRANS_SESEND, NULL,
1820 lstcon_sesrpc_condition, &trans);
James Simmons5fd88332016-02-12 12:06:09 -05001821 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001822 CERROR("Can't create transaction: %d\n", rc);
1823 return rc;
1824 }
1825
1826 console_session.ses_shutdown = 1;
1827
1828 lstcon_rpc_pinger_stop();
1829
1830 lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
1831
1832 lstcon_rpc_trans_destroy(trans);
1833 /* User can do nothing even rpc failed, so go on */
1834
1835 /* waiting for orphan rpcs to die */
1836 lstcon_rpc_cleanup_wait();
1837
James Simmonsec436b92016-03-11 20:29:46 -05001838 console_session.ses_id = LST_INVALID_SID;
Peng Taod7e09d02013-05-02 16:46:55 +08001839 console_session.ses_state = LST_SESSION_NONE;
James Simmonsec436b92016-03-11 20:29:46 -05001840 console_session.ses_key = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001841 console_session.ses_force = 0;
1842 console_session.ses_feats_updated = 0;
1843
1844 /* destroy all batches */
1845 while (!list_empty(&console_session.ses_bat_list)) {
1846 bat = list_entry(console_session.ses_bat_list.next,
James Simmonsdcdc7c82016-04-06 15:25:46 -04001847 struct lstcon_batch, bat_link);
Peng Taod7e09d02013-05-02 16:46:55 +08001848
1849 lstcon_batch_destroy(bat);
1850 }
1851
1852 /* destroy all groups */
1853 while (!list_empty(&console_session.ses_grp_list)) {
1854 grp = list_entry(console_session.ses_grp_list.next,
James Simmons6bd88c72016-04-06 15:25:44 -04001855 struct lstcon_group, grp_link);
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001856 LASSERT(grp->grp_ref == 1);
Peng Taod7e09d02013-05-02 16:46:55 +08001857
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301858 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001859 }
1860
1861 /* all nodes should be released */
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02001862 LASSERT(list_empty(&console_session.ses_ndl_list));
Peng Taod7e09d02013-05-02 16:46:55 +08001863
1864 console_session.ses_shutdown = 0;
James Simmonsec436b92016-03-11 20:29:46 -05001865 console_session.ses_expired = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001866
1867 return rc;
1868}
1869
1870int
1871lstcon_session_feats_check(unsigned feats)
1872{
1873 int rc = 0;
1874
James Simmons5fd88332016-02-12 12:06:09 -05001875 if (feats & ~LST_FEATS_MASK) {
Peng Taod7e09d02013-05-02 16:46:55 +08001876 CERROR("Can't support these features: %x\n",
1877 (feats & ~LST_FEATS_MASK));
1878 return -EPROTO;
1879 }
1880
1881 spin_lock(&console_session.ses_rpc_lock);
1882
1883 if (!console_session.ses_feats_updated) {
1884 console_session.ses_feats_updated = 1;
1885 console_session.ses_features = feats;
1886 }
1887
1888 if (console_session.ses_features != feats)
1889 rc = -EPROTO;
1890
1891 spin_unlock(&console_session.ses_rpc_lock);
1892
James Simmons5fd88332016-02-12 12:06:09 -05001893 if (rc) {
Joe Perches2d00bd12014-11-23 11:28:50 -08001894 CERROR("remote features %x do not match with session features %x of console\n",
Peng Taod7e09d02013-05-02 16:46:55 +08001895 feats, console_session.ses_features);
1896 }
1897
1898 return rc;
1899}
1900
1901static int
Shraddha Barke168c7a12015-11-01 12:21:37 +05301902lstcon_acceptor_handle(struct srpc_server_rpc *rpc)
Peng Taod7e09d02013-05-02 16:46:55 +08001903{
James Simmonsfd7a1a32016-04-06 15:25:48 -04001904 struct srpc_msg *rep = &rpc->srpc_replymsg;
1905 struct srpc_msg *req = &rpc->srpc_reqstbuf->buf_msg;
James Simmons45d2f4f2016-04-12 12:16:02 -04001906 struct srpc_join_reqst *jreq = &req->msg_body.join_reqst;
1907 struct srpc_join_reply *jrep = &rep->msg_body.join_reply;
James Simmons6bd88c72016-04-06 15:25:44 -04001908 struct lstcon_group *grp = NULL;
James Simmonse00f9782016-04-06 15:25:43 -04001909 struct lstcon_ndlink *ndl;
James Simmons00b5fdb2016-03-11 20:29:45 -05001910 int rc = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001911
1912 sfw_unpack_message(req);
1913
1914 mutex_lock(&console_session.ses_mutex);
1915
1916 jrep->join_sid = console_session.ses_id;
1917
1918 if (console_session.ses_id.ses_nid == LNET_NID_ANY) {
1919 jrep->join_status = ESRCH;
1920 goto out;
1921 }
1922
James Simmons5fd88332016-02-12 12:06:09 -05001923 if (lstcon_session_feats_check(req->msg_ses_feats)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001924 jrep->join_status = EPROTO;
1925 goto out;
1926 }
1927
1928 if (jreq->join_sid.ses_nid != LNET_NID_ANY &&
James Simmonsc314c312016-02-12 12:06:01 -05001929 !lstcon_session_match(jreq->join_sid)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001930 jrep->join_status = EBUSY;
1931 goto out;
1932 }
1933
James Simmons5fd88332016-02-12 12:06:09 -05001934 if (lstcon_group_find(jreq->join_group, &grp)) {
Peng Taod7e09d02013-05-02 16:46:55 +08001935 rc = lstcon_group_alloc(jreq->join_group, &grp);
James Simmons5fd88332016-02-12 12:06:09 -05001936 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001937 CERROR("Out of memory\n");
1938 goto out;
1939 }
1940
1941 list_add_tail(&grp->grp_link,
James Simmonsc314c312016-02-12 12:06:01 -05001942 &console_session.ses_grp_list);
Peng Taod7e09d02013-05-02 16:46:55 +08001943 lstcon_group_addref(grp);
1944 }
1945
1946 if (grp->grp_ref > 2) {
1947 /* Group in using */
1948 jrep->join_status = EBUSY;
1949 goto out;
1950 }
1951
1952 rc = lstcon_group_ndlink_find(grp, rpc->srpc_peer, &ndl, 0);
James Simmons5fd88332016-02-12 12:06:09 -05001953 if (!rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001954 jrep->join_status = EEXIST;
1955 goto out;
1956 }
1957
1958 rc = lstcon_group_ndlink_find(grp, rpc->srpc_peer, &ndl, 1);
James Simmons5fd88332016-02-12 12:06:09 -05001959 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08001960 CERROR("Out of memory\n");
1961 goto out;
1962 }
1963
James Simmonsec436b92016-03-11 20:29:46 -05001964 ndl->ndl_node->nd_state = LST_NODE_ACTIVE;
Peng Taod7e09d02013-05-02 16:46:55 +08001965 ndl->ndl_node->nd_timeout = console_session.ses_timeout;
1966
James Simmons5fd88332016-02-12 12:06:09 -05001967 if (!grp->grp_userland)
Peng Taod7e09d02013-05-02 16:46:55 +08001968 grp->grp_userland = 1;
1969
Dmitry Eremin9563fe82015-11-04 13:40:00 -05001970 strlcpy(jrep->join_session, console_session.ses_name,
1971 sizeof(jrep->join_session));
Peng Taod7e09d02013-05-02 16:46:55 +08001972 jrep->join_timeout = console_session.ses_timeout;
James Simmonsec436b92016-03-11 20:29:46 -05001973 jrep->join_status = 0;
Peng Taod7e09d02013-05-02 16:46:55 +08001974
1975out:
1976 rep->msg_ses_feats = console_session.ses_features;
James Simmons06ace262016-02-12 12:06:08 -05001977 if (grp)
Shivani Bhardwaj33db6862015-10-29 11:02:23 +05301978 lstcon_group_decref(grp);
Peng Taod7e09d02013-05-02 16:46:55 +08001979
1980 mutex_unlock(&console_session.ses_mutex);
1981
1982 return rc;
1983}
1984
James Simmons682513b2016-04-06 15:25:33 -04001985static struct srpc_service lstcon_acceptor_service;
1986
Heena Sirwani28f54a82014-10-01 13:39:28 +05301987static void lstcon_init_acceptor_service(void)
Peng Taod7e09d02013-05-02 16:46:55 +08001988{
1989 /* initialize selftest console acceptor service table */
James Simmonsec436b92016-03-11 20:29:46 -05001990 lstcon_acceptor_service.sv_name = "join session";
1991 lstcon_acceptor_service.sv_handler = lstcon_acceptor_handle;
1992 lstcon_acceptor_service.sv_id = SRPC_SERVICE_JOIN;
Peng Taod7e09d02013-05-02 16:46:55 +08001993 lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;
1994}
1995
Luca Ceresolif3731cd2015-01-18 15:06:52 +01001996static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
Peng Taod7e09d02013-05-02 16:46:55 +08001997
1998/* initialize console */
1999int
2000lstcon_console_init(void)
2001{
Mike Shuey74d68012015-05-19 10:14:38 -04002002 int i;
2003 int rc;
Peng Taod7e09d02013-05-02 16:46:55 +08002004
Bhumika Goyal541ac712016-02-19 19:13:52 +05302005 memset(&console_session, 0, sizeof(struct lstcon_session));
Peng Taod7e09d02013-05-02 16:46:55 +08002006
James Simmonsec436b92016-03-11 20:29:46 -05002007 console_session.ses_id = LST_INVALID_SID;
2008 console_session.ses_state = LST_SESSION_NONE;
2009 console_session.ses_timeout = 0;
2010 console_session.ses_force = 0;
2011 console_session.ses_expired = 0;
Mike Shuey74d68012015-05-19 10:14:38 -04002012 console_session.ses_feats_updated = 0;
James Simmonsec436b92016-03-11 20:29:46 -05002013 console_session.ses_features = LST_FEATS_MASK;
2014 console_session.ses_laststamp = ktime_get_real_seconds();
Peng Taod7e09d02013-05-02 16:46:55 +08002015
2016 mutex_init(&console_session.ses_mutex);
2017
2018 INIT_LIST_HEAD(&console_session.ses_ndl_list);
2019 INIT_LIST_HEAD(&console_session.ses_grp_list);
2020 INIT_LIST_HEAD(&console_session.ses_bat_list);
2021 INIT_LIST_HEAD(&console_session.ses_trans_list);
2022
2023 LIBCFS_ALLOC(console_session.ses_ndl_hash,
2024 sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
James Simmons06ace262016-02-12 12:06:08 -05002025 if (!console_session.ses_ndl_hash)
Peng Taod7e09d02013-05-02 16:46:55 +08002026 return -ENOMEM;
2027
2028 for (i = 0; i < LST_GLOBAL_HASHSIZE; i++)
2029 INIT_LIST_HEAD(&console_session.ses_ndl_hash[i]);
2030
Peng Taod7e09d02013-05-02 16:46:55 +08002031 /* initialize acceptor service table */
2032 lstcon_init_acceptor_service();
2033
2034 rc = srpc_add_service(&lstcon_acceptor_service);
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02002035 LASSERT(rc != -EBUSY);
James Simmons5fd88332016-02-12 12:06:09 -05002036 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08002037 LIBCFS_FREE(console_session.ses_ndl_hash,
2038 sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
2039 return rc;
2040 }
2041
2042 rc = srpc_service_add_buffers(&lstcon_acceptor_service,
2043 lstcon_acceptor_service.sv_wi_total);
James Simmons5fd88332016-02-12 12:06:09 -05002044 if (rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08002045 rc = -ENOMEM;
2046 goto out;
2047 }
2048
2049 rc = libcfs_register_ioctl(&lstcon_ioctl_handler);
2050
James Simmons5fd88332016-02-12 12:06:09 -05002051 if (!rc) {
Peng Taod7e09d02013-05-02 16:46:55 +08002052 lstcon_rpc_module_init();
2053 return 0;
2054 }
2055
2056out:
2057 srpc_shutdown_service(&lstcon_acceptor_service);
2058 srpc_remove_service(&lstcon_acceptor_service);
2059
2060 LIBCFS_FREE(console_session.ses_ndl_hash,
2061 sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
2062
2063 srpc_wait_service_shutdown(&lstcon_acceptor_service);
2064
2065 return rc;
2066}
2067
2068int
2069lstcon_console_fini(void)
2070{
Mike Shuey74d68012015-05-19 10:14:38 -04002071 int i;
Peng Taod7e09d02013-05-02 16:46:55 +08002072
2073 libcfs_deregister_ioctl(&lstcon_ioctl_handler);
2074
2075 mutex_lock(&console_session.ses_mutex);
2076
2077 srpc_shutdown_service(&lstcon_acceptor_service);
2078 srpc_remove_service(&lstcon_acceptor_service);
2079
2080 if (console_session.ses_state != LST_SESSION_NONE)
2081 lstcon_session_end();
2082
2083 lstcon_rpc_module_fini();
2084
2085 mutex_unlock(&console_session.ses_mutex);
2086
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02002087 LASSERT(list_empty(&console_session.ses_ndl_list));
2088 LASSERT(list_empty(&console_session.ses_grp_list));
2089 LASSERT(list_empty(&console_session.ses_bat_list));
2090 LASSERT(list_empty(&console_session.ses_trans_list));
Peng Taod7e09d02013-05-02 16:46:55 +08002091
James Simmons06f2f2f2016-02-12 12:06:07 -05002092 for (i = 0; i < LST_NODE_HASHSIZE; i++)
Hatice ERTÜRK7c30daa2015-02-27 22:21:50 +02002093 LASSERT(list_empty(&console_session.ses_ndl_hash[i]));
Peng Taod7e09d02013-05-02 16:46:55 +08002094
2095 LIBCFS_FREE(console_session.ses_ndl_hash,
2096 sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
2097
2098 srpc_wait_service_shutdown(&lstcon_acceptor_service);
2099
2100 return 0;
2101}