Motr  M0
console.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "lib/arith.h" /* min_check */
24 #include "lib/memory.h" /* M0_ALLOC_PTR */
25 #include "lib/misc.h" /* M0_SET0 */
26 #include "lib/errno.h" /* ETIMEDOUT */
27 
28 #include "net/test/console.h"
29 
30 #define NET_TEST_MODULE_NAME console
31 #include "net/test/debug.h" /* LOGD */
32 
33 
45  struct m0_net_test_console_cfg *cfg,
46  enum m0_net_test_role role)
47 {
48  struct m0_net_test_slist *nodes;
49  char *addr_console;
50  int rc = -ENOMEM;
51 
52  if (cfg == NULL)
53  goto fini;
54 
55  M0_SET0(ctx);
56 
59  nodes = role == M0_NET_TEST_ROLE_CLIENT ?
60  &cfg->ntcc_clients : &cfg->ntcc_servers;
61 
62  M0_ALLOC_PTR(ctx->ntcrc_cmd);
63  if (ctx->ntcrc_cmd == NULL)
64  goto fail;
65  M0_ALLOC_PTR(ctx->ntcrc_sd);
66  if (ctx->ntcrc_sd == NULL)
67  goto fini_cmd;
68  ctx->ntcrc_nr = nodes->ntsl_nr;
69  M0_ALLOC_ARR(ctx->ntcrc_errno, ctx->ntcrc_nr);
70  if (ctx->ntcrc_errno == NULL)
71  goto fini_sd;
72  M0_ALLOC_ARR(ctx->ntcrc_status, ctx->ntcrc_nr);
73  if (ctx->ntcrc_status == NULL)
74  goto fini_errno;
75 
78  if (rc != 0)
79  goto fini_status;
80 
81  rc = 0;
82  goto success;
83 
84 fini:
85  rc = 0;
86  m0_net_test_commands_fini(ctx->ntcrc_cmd);
87 fini_status:
88  m0_free(ctx->ntcrc_status);
89 fini_errno:
90  m0_free(ctx->ntcrc_errno);
91 fini_sd:
92  m0_free(ctx->ntcrc_sd);
93 fini_cmd:
94  m0_free(ctx->ntcrc_cmd);
95 fail:
96 success:
97  return rc;
98 }
99 
101  struct m0_net_test_console_cfg *cfg)
102 {
103  int rc;
104 
105  M0_PRE(ctx != NULL);
106 
107  ctx->ntcc_cfg = cfg;
108  rc = console_role_init_fini(&ctx->ntcc_clients, cfg,
110  if (rc == 0)
111  rc = console_role_init_fini(&ctx->ntcc_servers, cfg,
113  return rc;
114 }
115 
117  struct m0_net_test_console_cfg *cfg)
118 {
119  return console_init_fini(ctx, cfg);
120 }
121 
123 {
124  int rc = console_init_fini(ctx, NULL);
125  M0_POST(rc == 0);
126 }
127 
129  enum m0_net_test_role role,
130  struct m0_net_test_cmd_init *cinit)
131 {
132  cinit->ntci_role = role;
133  cinit->ntci_type = cfg->ntcc_test_type;
134  cinit->ntci_msg_nr = cfg->ntcc_msg_nr;
135  cinit->ntci_msg_size = cfg->ntcc_msg_size;
136  cinit->ntci_bd_buf_nr = role == M0_NET_TEST_ROLE_CLIENT ?
137  cfg->ntcc_bd_buf_nr_client :
139  cinit->ntci_bd_buf_size = cfg->ntcc_bd_buf_size;
140  cinit->ntci_bd_nr_max = cfg->ntcc_bd_nr_max;
146  cinit->ntci_ep = role == M0_NET_TEST_ROLE_CLIENT ?
147  cfg->ntcc_data_servers :
148  cfg->ntcc_data_clients;
149 }
150 
152 {
153  /* Statistics reset order is not important here */
154  struct m0_net_test_msg_nr * const msg_nr[] = {
155  &sd->ntcsd_msg_nr_send,
156  &sd->ntcsd_msg_nr_recv,
157  &sd->ntcsd_bulk_nr_send,
158  &sd->ntcsd_bulk_nr_recv,
159  &sd->ntcsd_transfers,
160  };
161  struct m0_net_test_stats * const stats[] = {
164  &sd->ntcsd_rtt,
165  };
166  size_t i;
167 
168  M0_SET0(sd);
169  for (i = 0; i < ARRAY_SIZE(msg_nr); ++i)
170  m0_net_test_msg_nr_reset(msg_nr[i]);
171  for (i = 0; i < ARRAY_SIZE(stats); ++i)
173  sd->ntcsd_finished = true;
175  sd->ntcsd_time_finish = 0;
176 }
177 
178 static void status_data_add(struct m0_net_test_cmd_status_data *all_sd,
179  const struct m0_net_test_cmd_status_data *cmd_sd)
180 {
181  /* Parts of statistics are independent here, so order isn't important */
182  const struct {
183  struct m0_net_test_msg_nr *nr_all;
184  const struct m0_net_test_msg_nr *nr_node;
185  } msg_nr[] = {
186  { .nr_all = &all_sd->ntcsd_msg_nr_send,
187  .nr_node = &cmd_sd->ntcsd_msg_nr_send },
188  { .nr_all = &all_sd->ntcsd_msg_nr_recv,
189  .nr_node = &cmd_sd->ntcsd_msg_nr_recv },
190  { .nr_all = &all_sd->ntcsd_bulk_nr_send,
191  .nr_node = &cmd_sd->ntcsd_bulk_nr_send },
192  { .nr_all = &all_sd->ntcsd_bulk_nr_recv,
193  .nr_node = &cmd_sd->ntcsd_bulk_nr_recv },
194  { .nr_all = &all_sd->ntcsd_transfers,
195  .nr_node = &cmd_sd->ntcsd_transfers },
196  };
197  const struct {
198  struct m0_net_test_stats *s_all;
199  const struct m0_net_test_stats *s_node;
200  } stats[] = {
201  { .s_all = &all_sd->ntcsd_mps_send.ntmps_stats,
202  .s_node = &cmd_sd->ntcsd_mps_send.ntmps_stats },
203  { .s_all = &all_sd->ntcsd_mps_recv.ntmps_stats,
204  .s_node = &cmd_sd->ntcsd_mps_recv.ntmps_stats },
205  { .s_all = &all_sd->ntcsd_rtt,
206  .s_node = &cmd_sd->ntcsd_rtt, },
207  };
208  size_t i;
209 
210  LOGD("sent=%lu recvd=%lu finished=%d",
213  cmd_sd->ntcsd_finished);
214  for (i = 0; i < ARRAY_SIZE(msg_nr); ++i)
215  m0_net_test_msg_nr_add(msg_nr[i].nr_all, msg_nr[i].nr_node);
216  for (i = 0; i < ARRAY_SIZE(stats); ++i)
217  m0_net_test_stats_add_stats(stats[i].s_all, stats[i].s_node);
218  all_sd->ntcsd_finished &= cmd_sd->ntcsd_finished;
219  if (cmd_sd->ntcsd_finished) {
220  all_sd->ntcsd_time_start = min_check(all_sd->ntcsd_time_start,
221  cmd_sd->ntcsd_time_start);
222  all_sd->ntcsd_time_finish =
224  cmd_sd->ntcsd_time_finish);
225  }
226 }
227 
229  enum m0_net_test_role role,
230  enum m0_net_test_cmd_type cmd_type)
231 {
233  struct m0_net_test_console_cfg *cfg;
234  struct m0_net_test_cmd_ctx *cmd_ctx;
235  struct m0_net_test_cmd *cmd;
236  struct m0_net_test_cmd_status_data *sd = NULL;
237  int i;
238  int j;
239  int rc;
240  struct m0_net_test_slist *nodes;
241  struct m0_net_test_slist *nodes_data;
242  bool role_client;
243  m0_time_t deadline;
244  size_t success_nr = 0;
245  size_t failures_nr = 0;
246  size_t rcvd_nr = 0;
247  enum m0_net_test_cmd_type answer[] = {
252  };
253 
254  M0_PRE(ctx != NULL);
256  role == M0_NET_TEST_ROLE_CLIENT);
257  M0_PRE(cmd_type == M0_NET_TEST_CMD_INIT ||
258  cmd_type == M0_NET_TEST_CMD_START ||
259  cmd_type == M0_NET_TEST_CMD_STOP ||
260  cmd_type == M0_NET_TEST_CMD_STATUS);
261 
262  M0_ALLOC_PTR(cmd);
263  if (cmd == NULL) {
264  rc = -ENOMEM;
265  goto done;
266  }
267  cfg = ctx->ntcc_cfg;
268 
269  if (cmd_type == M0_NET_TEST_CMD_INIT)
270  console_cmd_init_fill(cfg, role, &cmd->ntc_init);
271 
272  role_client = role == M0_NET_TEST_ROLE_CLIENT;
273  cmd->ntc_type = cmd_type;
274  nodes = role_client ? &cfg->ntcc_clients : &cfg->ntcc_servers;
275  nodes_data = role_client ? &cfg->ntcc_data_clients :
276  &cfg->ntcc_data_servers;
277  rctx = role_client ? &ctx->ntcc_clients : &ctx->ntcc_servers;
278  cmd_ctx = rctx->ntcrc_cmd;
279 
280  /* clear commands receive queue */
281  while ((rc = m0_net_test_commands_recv(cmd_ctx, cmd, m0_time_now())) !=
282  -ETIMEDOUT) {
283  /*
284  * Exit from this loop after nodes->ntsl_nr failures.
285  * It will prevent from infinite loop if after every
286  * m0_net_test_commands_recv_enqueue() will be
287  * unsuccessful m0_net_test_commands_recv().
288  */
289  failures_nr += rc != 0;
290  if (failures_nr > nodes->ntsl_nr)
291  break;
293  cmd->ntc_buf_index);
294  if (rc != 0)
295  ++rctx->ntcrc_recv_enqueue_errors;
297  }
298  /* send all commands */
299  for (i = 0; i < nodes->ntsl_nr; ++i) {
300  if (cmd_type == M0_NET_TEST_CMD_INIT)
301  cmd->ntc_init.ntci_tm_ep = nodes_data->ntsl_list[i];
302  cmd->ntc_ep_index = i;
303  rctx->ntcrc_errno[i] = m0_net_test_commands_send(cmd_ctx, cmd);
304  }
306 
307  /* receive answers */
308  if (answer[cmd_type] == M0_NET_TEST_CMD_STATUS_DATA) {
309  sd = rctx->ntcrc_sd;
310  status_data_reset(sd);
311  }
312  deadline = m0_time_add(m0_time_now(), cfg->ntcc_cmd_recv_timeout);
313  while (m0_time_now() <= deadline && rcvd_nr < nodes->ntsl_nr) {
314  rc = m0_net_test_commands_recv(cmd_ctx, cmd, deadline);
315  /* deadline reached */
316  if (rc == -ETIMEDOUT)
317  break;
318  if (rc != 0) {
319  ++rctx->ntcrc_recv_errors;
320  continue;
321  }
322  rcvd_nr++;
323  /* reject unknown sender */
324  j = cmd->ntc_ep_index;
325  if (j < 0)
326  goto reuse_cmd;
327  /* reject unexpected command type */
328  if (cmd->ntc_type != answer[cmd_type])
329  goto reuse_cmd;
330  /*
331  * reject command from node, which can't have outgoing cmd
332  * because m0_net_test_commands_send() to this node failed.
333  */
334  M0_ASSERT(j >= 0 && j < nodes->ntsl_nr);
335  if (rctx->ntcrc_errno[j] != 0)
336  goto reuse_cmd;
337  /* handle incoming command */
338  if (answer[cmd_type] == M0_NET_TEST_CMD_STATUS_DATA) {
339  status_data_add(sd, &cmd->ntc_status_data);
340  success_nr++;
341  } else {
342  rctx->ntcrc_status[j] = cmd->ntc_done.ntcd_errno;
343  if (rctx->ntcrc_status[j] == 0)
344  success_nr++;
345  }
346 reuse_cmd:
348  cmd->ntc_buf_index);
349  if (rc != 0)
350  ++rctx->ntcrc_recv_enqueue_errors;
351  if (j != -1) {
352  M0_ASSERT(j >= 0 && j < nodes->ntsl_nr);
353  rctx->ntcrc_errno[j] = rc;
354  }
356  }
357 
358 done:
359  m0_free(cmd);
360  LOGD("console: rc = %d\n", rc);
361 
362  return success_nr;
363 }
364 
365 #undef NET_TEST_MODULE_NAME
366 
371 /*
372  * Local variables:
373  * c-indentation-style: "K&R"
374  * c-basic-offset: 8
375  * tab-width: 8
376  * fill-column: 79
377  * scroll-step: 1
378  * End:
379  */
m0_time_t ntcc_buf_send_timeout
Definition: console.h:83
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
struct m0_net_test_slist ntci_ep
Definition: commands.h:157
int m0_net_test_commands_init(struct m0_net_test_cmd_ctx *ctx, const char *cmd_ep, m0_time_t send_timeout, m0_net_test_commands_send_cb_t send_cb, struct m0_net_test_slist *ep_list)
Definition: commands.c:441
m0_time_t ntci_buf_bulk_timeout
Definition: commands.h:153
#define NULL
Definition: misc.h:38
struct m0_net_test_mps ntcsd_mps_recv
Definition: commands.h:186
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
enum m0_net_test_type ntcc_test_type
Definition: console.h:92
struct m0_net_test_stats ntcsd_rtt
Definition: commands.h:192
uint64_t m0_time_t
Definition: time.h:37
struct m0_net_test_cmd_status_data ntc_status_data
Definition: commands.h:209
#define min_check(a, b)
Definition: arith.h:88
m0_net_test_cmd_type
Definition: commands.h:78
static void console_cmd_init_fill(struct m0_net_test_console_cfg *cfg, enum m0_net_test_role role, struct m0_net_test_cmd_init *cinit)
Definition: console.c:128
#define max_check(a, b)
Definition: arith.h:95
void m0_net_test_stats_reset(struct m0_net_test_stats *stats)
Definition: stats.c:46
uint64_t ntcc_concurrency_server
Definition: console.h:130
uint64_t ntcc_concurrency_client
Definition: console.h:135
int m0_net_test_commands_recv_enqueue(struct m0_net_test_cmd_ctx *ctx, size_t buf_index)
Definition: commands.c:570
void m0_net_test_msg_nr_add(struct m0_net_test_msg_nr *msg_nr, const struct m0_net_test_msg_nr *msg_nr2)
Definition: stats.c:316
static void m0_net_test_msg_nr_reset(struct m0_net_test_msg_nr *msg_nr)
Definition: stats.h:328
#define M0_SET0(obj)
Definition: misc.h:64
struct m0_net_test_msg_nr ntcsd_bulk_nr_send
Definition: commands.h:170
struct m0_net_test_msg_nr ntcsd_transfers
Definition: commands.h:174
uint64_t ntcc_bd_buf_nr_client
Definition: console.h:113
m0_bcount_t ntci_msg_size
Definition: commands.h:118
m0_time_t ntcc_cmd_send_timeout
Definition: console.h:79
static int console_init_fini(struct m0_net_test_console_ctx *ctx, struct m0_net_test_console_cfg *cfg)
Definition: console.c:100
struct m0_reqh_context rctx
void m0_net_test_console_fini(struct m0_net_test_console_ctx *ctx)
Definition: console.c:122
int i
Definition: dir.c:1033
#define LOGD(...)
Definition: tx_regmap.c:37
m0_time_t ntci_buf_send_timeout
Definition: commands.h:151
void m0_net_test_commands_received_free(struct m0_net_test_cmd *cmd)
Definition: commands.c:578
uint64_t ntci_bd_nr_max
Definition: commands.h:136
m0_time_t ntcc_cmd_recv_timeout
Definition: console.h:81
void m0_net_test_commands_fini(struct m0_net_test_cmd_ctx *ctx)
Definition: commands.c:451
struct m0_net_test_cmd_init ntc_init
Definition: commands.h:208
enum m0_net_test_role ntci_role
Definition: commands.h:104
size_t m0_net_test_console_cmd(struct m0_net_test_console_ctx *ctx, enum m0_net_test_role role, enum m0_net_test_cmd_type cmd_type)
Definition: console.c:228
int m0_net_test_commands_send(struct m0_net_test_cmd_ctx *ctx, struct m0_net_test_cmd *cmd)
Definition: commands.c:457
#define M0_ASSERT(cond)
static void status_data_add(struct m0_net_test_cmd_status_data *all_sd, const struct m0_net_test_cmd_status_data *cmd_sd)
Definition: console.c:178
char * ntcc_addr_console4servers
Definition: console.h:52
m0_time_t m0_time_now(void)
Definition: time.c:134
void m0_net_test_commands_send_wait_all(struct m0_net_test_cmd_ctx *ctx)
Definition: commands.c:490
static struct net_test_cmd_node nodes[NTC_MULTIPLE_NODES]
Definition: commands.c:74
static void status_data_reset(struct m0_net_test_cmd_status_data *sd)
Definition: console.c:151
struct m0_net_test_mps ntcsd_mps_send
Definition: commands.h:184
struct m0_net_test_msg_nr ntcsd_msg_nr_recv
Definition: commands.h:168
int m0_net_test_commands_recv(struct m0_net_test_cmd_ctx *ctx, struct m0_net_test_cmd *cmd, m0_time_t deadline)
Definition: commands.c:511
size_t ntsl_nr
Definition: slist.h:49
#define M0_POST(cond)
m0_bcount_t ntci_bd_buf_size
Definition: commands.h:130
m0_net_test_role
Definition: commands.h:59
uint64_t ntci_msg_nr
Definition: commands.h:112
uint64_t ntci_msg_concurrency
Definition: commands.h:144
size_t ntmn_total
Definition: stats.h:308
m0_time_t m0_time_add(const m0_time_t t1, const m0_time_t t2)
Definition: time.c:47
struct m0_net_test_slist ntcc_data_clients
Definition: console.h:77
struct m0_net_test_msg_nr ntcsd_msg_nr_send
Definition: commands.h:166
enum m0_net_test_type ntci_type
Definition: commands.h:106
uint64_t ntci_bd_buf_nr
Definition: commands.h:124
ssize_t ntc_ep_index
Definition: commands.h:218
static char * addr_console
Definition: node_k.c:38
static uint8_t fail[DATA_UNIT_COUNT_MAX+PARITY_UNIT_COUNT_MAX]
size_t ntc_buf_index
Definition: commands.h:220
uint64_t ntcc_bd_nr_max
Definition: console.h:125
struct m0_net_test_cmd_done ntc_done
Definition: commands.h:207
m0_bcount_t ntcc_bd_buf_size
Definition: console.h:118
m0_bcount_t ntcc_msg_size
Definition: console.h:101
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
Definition: beck.c:130
uint64_t ntcc_msg_nr
Definition: console.h:94
int m0_net_test_console_init(struct m0_net_test_console_ctx *ctx, struct m0_net_test_console_cfg *cfg)
Definition: console.c:116
char * ntcc_addr_console4clients
Definition: console.h:54
struct m0_net_test_msg_nr ntcsd_bulk_nr_recv
Definition: commands.h:172
struct m0_net_test_slist ntcc_servers
Definition: console.h:60
enum m0_net_test_cmd_type ntc_type
Definition: commands.h:204
int fini(struct workload *w)
void m0_net_test_stats_add_stats(struct m0_net_test_stats *stats, const struct m0_net_test_stats *stats2)
Definition: stats.c:91
static unsigned done
Definition: storage.c:91
Definition: nucleus.c:42
struct m0_net_test_slist ntcc_clients
Definition: console.h:65
struct m0_net_test_slist ntcc_data_servers
Definition: console.h:72
void m0_free(void *data)
Definition: memory.c:146
uint64_t ntcc_bd_buf_nr_server
Definition: console.h:107
int32_t rc
Definition: trigger_fop.h:47
struct m0_net_test_stats ntmps_stats
Definition: stats.h:250
#define ARRAY_SIZE(a)
Definition: misc.h:45
char ** ntsl_list
Definition: slist.h:53
m0_time_t ntcc_buf_bulk_timeout
Definition: console.h:90
static int console_role_init_fini(struct m0_net_test_console_role_ctx *ctx, struct m0_net_test_console_cfg *cfg, enum m0_net_test_role role)
Definition: console.c:44