Motr  M0
bulk_mem_ut.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-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"
24 #include "lib/assert.h"
25 #include "lib/misc.h"
26 #include "lib/thread.h"
27 #include "ut/ut.h"
28 
31 
32 /* Create buffers with different shapes but same total size.
33  Also create identical buffers for exact shape testing.
34 */
35 enum { NR_BUFS = 10 };
36 
37 static void test_buf_copy(void)
38 {
39  static struct {
40  uint32_t num_segs;
42  } shapes[NR_BUFS] = {
43  [0] = { 1, 48 },
44  [1] = { 1, 48 },
45  [2] = { 2, 24 },
46  [3] = { 2, 24 },
47  [4] = { 3, 16 },
48  [5] = { 3, 16 },
49  [6] = { 4, 12 },
50  [7] = { 4, 12 },
51  [8] = { 6, 8 },
52  [9] = { 6, 8 },
53  };
54  static const char *msg = "abcdefghijklmnopqrstuvwxyz0123456789"
55  "ABCDEFGHIJK";
56  size_t msglen = strlen(msg)+1;
57  static struct m0_net_buffer bufs[NR_BUFS];
58  int i;
59  struct m0_net_buffer *nb;
60 
61  M0_SET_ARR0(bufs);
62  for (i = 0; i < NR_BUFS; ++i) {
63  M0_UT_ASSERT(msglen == shapes[i].num_segs * shapes[i].seg_size);
65  shapes[i].num_segs,
66  shapes[i].seg_size) == 0);
67  }
68  nb = &bufs[0]; /* single buffer */
70  memcpy(nb->nb_buffer.ov_buf[0], msg, msglen);
71  M0_UT_ASSERT(memcmp(nb->nb_buffer.ov_buf[0], msg, msglen) == 0);
72  for (i = 1; i < NR_BUFS; ++i) {
73  int j;
74  const char *p = msg;
75  M0_UT_ASSERT(mem_copy_buffer(&bufs[i],&bufs[i-1],msglen) == 0);
76  M0_UT_ASSERT(bufs[i].nb_length == 0); /* does not set field */
77  for (j = 0; j < bufs[i].nb_buffer.ov_vec.v_nr; ++j) {
78  int k;
79  char *q;
80  for (k = 0;
81  k < bufs[i].nb_buffer.ov_vec.v_count[j]; ++k) {
82  q = bufs[i].nb_buffer.ov_buf[j] + k;
83  M0_UT_ASSERT(*p++ == *q);
84  }
85  }
86 
87  }
88  for (i = 0; i < NR_BUFS; ++i)
89  m0_bufvec_free(&bufs[i].nb_buffer);
90 }
91 
92 void tf_tm_cb1(const struct m0_net_tm_event *ev);
93 static void test_ep(void)
94 {
95  /* dom1 */
96  static struct m0_net_domain dom1 = {
97  .nd_xprt = NULL
98  };
99  static struct m0_net_tm_callbacks tm_cbs1 = {
101  };
102  static struct m0_net_transfer_mc d1tm1 = {
103  .ntm_callbacks = &tm_cbs1,
104  .ntm_state = M0_NET_TM_UNDEFINED
105  };
106  struct m0_clink tmwait;
107  static struct m0_net_end_point *ep1;
108  static struct m0_net_end_point *ep2;
109  static struct m0_net_end_point *ep3;
110  const char *addr;
111 
113  M0_UT_ASSERT(!m0_net_tm_init(&d1tm1, &dom1));
114 
115  m0_clink_init(&tmwait, NULL);
116  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait);
117  M0_UT_ASSERT(!m0_net_tm_start(&d1tm1, "255.255.255.255:54321"));
118  m0_chan_wait(&tmwait);
119  m0_clink_del_lock(&tmwait);
120  M0_UT_ASSERT(d1tm1.ntm_ep != NULL);
121 
122  addr = "255.255.255.255:65535:4294967295";
123  M0_UT_ASSERT(m0_net_end_point_create(&ep1, &d1tm1, addr) == -EINVAL);
124  addr = "255.255.255.255:65535";
125  M0_UT_ASSERT(!m0_net_end_point_create(&ep1, &d1tm1, addr));
126  M0_UT_ASSERT(strcmp(ep1->nep_addr, addr) == 0);
128  M0_UT_ASSERT(ep1->nep_addr != addr);
129 
130  M0_UT_ASSERT(!m0_net_end_point_create(&ep2, &d1tm1, addr));
131  M0_UT_ASSERT(strcmp(ep2->nep_addr, addr) == 0);
132  M0_UT_ASSERT(ep2->nep_addr != addr);
134  M0_UT_ASSERT(ep1 == ep2);
135 
136  M0_UT_ASSERT(!m0_net_end_point_create(&ep3, &d1tm1, addr));
137 
138  M0_UT_ASSERT(strcmp(ep3->nep_addr, "255.255.255.255:65535") == 0);
139  M0_UT_ASSERT(strcmp(ep3->nep_addr, addr) == 0);
140  M0_UT_ASSERT(ep3->nep_addr != addr);
142  M0_UT_ASSERT(ep1 == ep3);
143 
147 
148  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait);
149  M0_UT_ASSERT(!m0_net_tm_stop(&d1tm1, false));
150  m0_chan_wait(&tmwait);
151  m0_clink_del_lock(&tmwait);
152 
153  m0_net_tm_fini(&d1tm1);
154  m0_net_domain_fini(&dom1);
155 }
156 
159 static struct m0_net_buffer *cb_nb1;
161 static int32_t cb_status1;
162 void tf_tm_cb1(const struct m0_net_tm_event *ev)
163 {
164  cb_evt1 = ev->nte_type;
165  cb_nb1 = NULL;
167  cb_tms1 = ev->nte_next_state;
168  cb_status1 = ev->nte_status;
169 }
170 
171 void tf_buf_cb1(const struct m0_net_buffer_event *ev)
172 {
174  cb_nb1 = ev->nbe_buffer;
177  cb_status1 = ev->nbe_status;
178 }
179 
180 void tf_cbreset1(void)
181 {
183  cb_nb1 = NULL;
186  cb_status1 = 9999999;
187 }
188 
191 static struct m0_net_buffer *cb_nb2;
193 static int32_t cb_status2;
194 void tf_tm_cb2(const struct m0_net_tm_event *ev)
195 {
196  cb_evt2 = ev->nte_type;
197  cb_nb2 = NULL;
199  cb_tms2 = ev->nte_next_state;
200  cb_status2 = ev->nte_status;
201 }
202 
203 void tf_buf_cb2(const struct m0_net_buffer_event *ev)
204 {
206  cb_nb2 = ev->nbe_buffer;
209  cb_status2 = ev->nbe_status;
210 }
211 
212 void tf_cbreset2(void)
213 {
215  cb_nb2 = NULL;
218  cb_status2 = 9999999;
219 }
220 
221 void tf_cbreset(void)
222 {
223  tf_cbreset1();
224  tf_cbreset2();
225 }
226 
227 static void test_failure(void)
228 {
229  /* some variables below are static to reduce kernel stack
230  consumption. */
231 
232  /* dom1 */
233  static struct m0_net_domain dom1 = {
234  .nd_xprt = NULL
235  };
236  static struct m0_net_tm_callbacks tm_cbs1 = {
238  };
239  static struct m0_net_transfer_mc d1tm1 = {
240  .ntm_callbacks = &tm_cbs1,
241  .ntm_state = M0_NET_TM_UNDEFINED
242  };
243  static struct m0_net_buffer_callbacks buf_cbs1 = {
244  .nbc_cb = {
251  },
252  };
253  static struct m0_net_buffer d1nb1;
254  static struct m0_net_buffer d1nb2;
255  static struct m0_clink tmwait1;
256 
257  /* dom 2 */
258  static struct m0_net_domain dom2 = {
259  .nd_xprt = NULL
260  };
261  static const struct m0_net_tm_callbacks tm_cbs2 = {
263  };
264  static struct m0_net_transfer_mc d2tm1 = {
265  .ntm_callbacks = &tm_cbs2,
266  .ntm_state = M0_NET_TM_UNDEFINED
267  };
268  static struct m0_net_transfer_mc d2tm2 = {
269  .ntm_callbacks = &tm_cbs2,
270  .ntm_state = M0_NET_TM_UNDEFINED
271  };
272  static const struct m0_net_buffer_callbacks buf_cbs2 = {
273  .nbc_cb = {
280  },
281  };
282  static struct m0_net_buffer d2nb1;
283  static struct m0_net_buffer d2nb2;
284  static m0_bcount_t d2nb2_len;
285  static struct m0_clink tmwait2;
286 
287  static struct m0_net_end_point *ep;
288  static struct m0_net_qstats qs;
289 
290  /* setup the first dom */
292  M0_UT_ASSERT(!m0_net_tm_init(&d1tm1, &dom1));
293  m0_clink_init(&tmwait1, NULL);
294  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
295  M0_UT_ASSERT(!m0_net_tm_start(&d1tm1, "127.0.0.1:10"));
296  m0_chan_wait(&tmwait1);
297  m0_clink_del_lock(&tmwait1);
299  M0_UT_ASSERT(strcmp(d1tm1.ntm_ep->nep_addr, "127.0.0.1:10") == 0);
300  M0_SET0(&d1nb1);
301  M0_UT_ASSERT(!m0_bufvec_alloc(&d1nb1.nb_buffer, 4, 10));
302  M0_UT_ASSERT(!m0_net_buffer_register(&d1nb1, &dom1));
303  d1nb1.nb_callbacks = &buf_cbs1;
304  M0_SET0(&d1nb2);
305  M0_UT_ASSERT(!m0_bufvec_alloc(&d1nb2.nb_buffer, 1, 10));
306  M0_UT_ASSERT(!m0_net_buffer_register(&d1nb2, &dom1));
307  d1nb2.nb_callbacks = &buf_cbs1;
308 
309  /* setup the second dom */
311  M0_UT_ASSERT(!m0_net_tm_init(&d2tm1, &dom2));
312  /* don't start the TM on port 20 yet */
313  M0_UT_ASSERT(!m0_net_tm_init(&d2tm2, &dom2));
314  m0_clink_init(&tmwait2, NULL);
315  m0_clink_add_lock(&d2tm2.ntm_chan, &tmwait2);
316  M0_UT_ASSERT(!m0_net_tm_start(&d2tm2, "127.0.0.1:21"));
317  m0_chan_wait(&tmwait2);
318  m0_clink_del_lock(&tmwait2);
320  M0_UT_ASSERT(strcmp(d2tm2.ntm_ep->nep_addr, "127.0.0.1:21") == 0);
321 
322  M0_SET0(&d2nb1);
323  M0_UT_ASSERT(!m0_bufvec_alloc(&d2nb1.nb_buffer, 4, 10));
324  M0_UT_ASSERT(!m0_net_buffer_register(&d2nb1, &dom2));
325  d2nb1.nb_callbacks = &buf_cbs2;
326  M0_SET0(&d2nb2);
327  M0_UT_ASSERT(!m0_bufvec_alloc(&d2nb2.nb_buffer, 1, 10));
328  d2nb2_len = 1 * 10;
329  M0_UT_ASSERT(!m0_net_buffer_register(&d2nb2, &dom2));
330  d2nb2.nb_callbacks = &buf_cbs2;
331 
332  /* test failure situations */
333 
334  /* TEST
335  Send a message from d1tm1 to d2tm1 - should fail because
336  the destination TM not started.
337  */
338  tf_cbreset();
339  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d1tm1, "127.0.0.1:20"));
340  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:20") == 0);
342  d1nb1.nb_ep = ep;
343  d1nb1.nb_length = 10; /* don't care */
344  m0_clink_init(&tmwait1, NULL);
345  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
346  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
348  m0_chan_wait(&tmwait1);
349  m0_clink_del_lock(&tmwait1);
351  M0_UT_ASSERT(cb_nb1 == &d1nb1);
352  M0_UT_ASSERT(cb_status1 == -ENETUNREACH);
353 
354  /* start the TM on port 20 in the second dom */
355  m0_clink_init(&tmwait2, NULL);
356  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
357  M0_UT_ASSERT(!m0_net_tm_start(&d2tm1, "127.0.0.1:20"));
358  m0_chan_wait(&tmwait2);
359  m0_clink_del_lock(&tmwait2);
361  M0_UT_ASSERT(strcmp(d2tm1.ntm_ep->nep_addr, "127.0.0.1:20") == 0);
362 
363  /* TEST
364  Send a message from d1tm1 to d2tm1 - should fail because
365  no receive buffers available.
366  The failure count on the receive queue of d2tm1 should
367  be bumped, and an -ENOBUFS error callback delivered.
368  */
369  tf_cbreset();
371  m0_clink_init(&tmwait2, NULL);
372  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
373 
375  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d1tm1, "127.0.0.1:20"));
376  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:20") == 0);
378  d1nb1.nb_ep = ep;
379  d1nb1.nb_length = 10; /* don't care */
380  m0_clink_init(&tmwait1, NULL);
381  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
382  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
384  m0_chan_wait(&tmwait1);
385  m0_clink_del_lock(&tmwait1);
387  M0_UT_ASSERT(cb_nb1 == &d1nb1);
388  M0_UT_ASSERT(cb_status1 == -ENOBUFS);
392  M0_UT_ASSERT(qs.nqs_num_adds == 1);
393  M0_UT_ASSERT(qs.nqs_num_dels == 0);
394 
395  m0_chan_wait(&tmwait2);
396  m0_clink_del_lock(&tmwait2);
400  M0_UT_ASSERT(qs.nqs_num_adds == 0);
401  M0_UT_ASSERT(qs.nqs_num_dels == 0);
403  M0_UT_ASSERT(cb_status2 == -ENOBUFS);
404 
405  /* TEST
406  Add a receive buffer in d2tm1.
407  Send a larger message from d1tm1 to d2tm1.
408  Both buffers should fail with -EMSGSIZE.
409  */
410  tf_cbreset();
413  d2nb2.nb_ep = NULL;
414  d2nb2.nb_min_receive_size = d2nb2_len;
415  d2nb2.nb_max_receive_msgs = 1;
416  m0_clink_init(&tmwait2, NULL);
417  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
418  M0_UT_ASSERT(!m0_net_buffer_add(&d2nb2, &d2tm1));
419 
421  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d1tm1, "127.0.0.1:20"));
422  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:20") == 0);
424  d1nb1.nb_ep = ep;
425  d1nb1.nb_length = 40;
426  m0_clink_init(&tmwait1, NULL);
427  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
428  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
430  m0_chan_wait(&tmwait1);
431  m0_clink_del_lock(&tmwait1);
433  M0_UT_ASSERT(cb_nb1 == &d1nb1);
434  M0_UT_ASSERT(cb_status1 == -EMSGSIZE);
438  M0_UT_ASSERT(qs.nqs_num_adds == 1);
439  M0_UT_ASSERT(qs.nqs_num_dels == 0);
440 
441  m0_chan_wait(&tmwait2);
442  m0_clink_del_lock(&tmwait2);
444  M0_UT_ASSERT(cb_nb2 == &d2nb2);
445  M0_UT_ASSERT(cb_status2 == -EMSGSIZE);
449  M0_UT_ASSERT(qs.nqs_num_adds == 1);
450  M0_UT_ASSERT(qs.nqs_num_dels == 0);
451 
452  /* TEST
453  Set up a passive receive buffer in one dom, and
454  try to actively receive from it.
455  */
456  tf_cbreset();
458  &qs,true));
459  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d2tm1, "127.0.0.1:10"));
460  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:10") == 0);
462  d2nb1.nb_ep = ep;
463  m0_clink_init(&tmwait2, NULL);
464  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
465  M0_UT_ASSERT(!m0_net_buffer_add(&d2nb1, &d2tm1));
466  M0_UT_ASSERT(d2nb1.nb_desc.nbd_len != 0);
468 
470  &qs,true));
471  M0_UT_ASSERT(!m0_net_desc_copy(&d2nb1.nb_desc, &d1nb1.nb_desc));
473  d1nb1.nb_length = 10;
474  m0_clink_init(&tmwait1, NULL);
475  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
476  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
477  m0_chan_wait(&tmwait1);
478  m0_clink_del_lock(&tmwait1);
480  M0_UT_ASSERT(cb_nb1 == &d1nb1);
481  M0_UT_ASSERT(cb_status1 == -EPERM);
483  &qs,true));
486  M0_UT_ASSERT(qs.nqs_num_adds == 1);
487  M0_UT_ASSERT(qs.nqs_num_dels == 0);
488  m0_net_desc_free(&d1nb1.nb_desc);
489 
490  m0_net_buffer_del(&d2nb1, &d2tm1);
491  m0_chan_wait(&tmwait2);
492  m0_clink_del_lock(&tmwait2);
494  M0_UT_ASSERT(cb_nb2 == &d2nb1);
495  M0_UT_ASSERT(cb_status2 == -ECANCELED);
497  &qs,true));
500  M0_UT_ASSERT(qs.nqs_num_adds == 1);
501  M0_UT_ASSERT(qs.nqs_num_dels == 1);
502  m0_net_desc_free(&d2nb1.nb_desc);
503 
504  /* TEST
505  Set up a passive receive buffer in one dom, and
506  try to send a larger message from the other dom.
507  */
508  tf_cbreset();
510  &qs,true));
511  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d2tm1, "127.0.0.1:10"));
512  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:10") == 0);
514  d2nb2.nb_ep = ep;
515  m0_clink_init(&tmwait2, NULL);
516  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
517  M0_UT_ASSERT(!m0_net_buffer_add(&d2nb2, &d2tm1));
518  M0_UT_ASSERT(d2nb2.nb_desc.nbd_len != 0);
520 
522  &qs,true));
523  M0_UT_ASSERT(!m0_net_desc_copy(&d2nb2.nb_desc, &d1nb1.nb_desc));
525  d1nb1.nb_length = 40; /* larger than d2nb2 */
526  m0_clink_init(&tmwait1, NULL);
527  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
528  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
529  m0_chan_wait(&tmwait1);
530  m0_clink_del_lock(&tmwait1);
532  M0_UT_ASSERT(cb_nb1 == &d1nb1);
533  M0_UT_ASSERT(cb_status1 == -EFBIG);
535  &qs,true));
538  M0_UT_ASSERT(qs.nqs_num_adds == 1);
539  M0_UT_ASSERT(qs.nqs_num_dels == 0);
540  m0_net_desc_free(&d1nb1.nb_desc);
541 
542  m0_chan_wait(&tmwait2);
543  m0_clink_del_lock(&tmwait2);
545  M0_UT_ASSERT(cb_nb2 == &d2nb2);
546  M0_UT_ASSERT(cb_status2 == -EFBIG);
548  &qs,true));
551  M0_UT_ASSERT(qs.nqs_num_adds == 1);
552  M0_UT_ASSERT(qs.nqs_num_dels == 0);
553  m0_net_desc_free(&d2nb2.nb_desc);
554 
555  /* TEST
556  Setup a passive send buffer and add it. Save the descriptor in the
557  active buffer of the other dom. Do not start the active operation
558  yet. Del the passive buffer. Re-submit the same buffer for the same
559  passive operation. Try the active operation in the other dom, using
560  the original desc. Should fail because buffer id changes per add.
561  */
562  tf_cbreset();
564  &qs,true));
565  M0_UT_ASSERT(!m0_net_end_point_create(&ep, &d2tm1, "127.0.0.1:10"));
566  M0_UT_ASSERT(strcmp(ep->nep_addr, "127.0.0.1:10") == 0);
568  d2nb1.nb_ep = ep;
569  m0_clink_init(&tmwait2, NULL);
570  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
571  M0_UT_ASSERT(!m0_net_buffer_add(&d2nb1, &d2tm1));
572  M0_UT_ASSERT(d2nb1.nb_desc.nbd_len != 0);
573  /* m0_net_end_point_put(ep); reuse it on resubmit */
574 
575  /* copy the desc but don't start the active operation yet */
576  M0_UT_ASSERT(!m0_net_desc_copy(&d2nb1.nb_desc, &d1nb1.nb_desc));
577 
578  /* cancel the original passive operation */
579  m0_net_buffer_del(&d2nb1, &d2tm1);
580  m0_chan_wait(&tmwait2);
581  m0_clink_del_lock(&tmwait2);
583  M0_UT_ASSERT(cb_nb2 == &d2nb1);
584  M0_UT_ASSERT(cb_status2 == -ECANCELED);
585  m0_net_desc_free(&d2nb1.nb_desc);
586 
587  /* resubmit */
588  tf_cbreset2();
590  d2nb1.nb_ep = ep;
591  m0_clink_init(&tmwait2, NULL);
592  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
593  M0_UT_ASSERT(!m0_net_buffer_add(&d2nb1, &d2tm1));
594  M0_UT_ASSERT(d2nb1.nb_desc.nbd_len != 0);
596 
597  /* descriptors should have changed */
598  M0_UT_ASSERT(d1nb1.nb_desc.nbd_len != d2nb1.nb_desc.nbd_len ||
599  memcmp(d1nb1.nb_desc.nbd_data, d2nb1.nb_desc.nbd_data,
600  d1nb1.nb_desc.nbd_len) != 0);
601 
602  /* start the active operation */
603  tf_cbreset1();
605  &qs,true));
607  d1nb1.nb_length = 10;
608  m0_clink_init(&tmwait1, NULL);
609  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
610  M0_UT_ASSERT(!m0_net_buffer_add(&d1nb1, &d1tm1));
611  m0_chan_wait(&tmwait1);
612  m0_clink_del_lock(&tmwait1);
614  M0_UT_ASSERT(cb_nb1 == &d1nb1);
615  M0_UT_ASSERT(cb_status1 == -ENOENT);
617  &qs,true));
620  M0_UT_ASSERT(qs.nqs_num_adds == 1);
621  M0_UT_ASSERT(qs.nqs_num_dels == 0);
622  m0_net_desc_free(&d1nb1.nb_desc);
623 
624  m0_net_buffer_del(&d2nb1, &d2tm1);
625  m0_chan_wait(&tmwait2);
626  m0_clink_del_lock(&tmwait2);
628  M0_UT_ASSERT(cb_nb2 == &d2nb1);
629  M0_UT_ASSERT(cb_status2 == -ECANCELED);
631  &qs,true));
634  M0_UT_ASSERT(qs.nqs_num_adds == 2);
635  M0_UT_ASSERT(qs.nqs_num_dels == 2);
636  m0_net_desc_free(&d2nb1.nb_desc);
637 
638  /* fini */
639  m0_net_buffer_deregister(&d1nb1, &dom1);
640  m0_bufvec_free(&d1nb1.nb_buffer);
641  m0_net_buffer_deregister(&d1nb2, &dom1);
642  m0_bufvec_free(&d1nb2.nb_buffer);
643  m0_net_buffer_deregister(&d2nb1, &dom2);
644  m0_bufvec_free(&d2nb1.nb_buffer);
645  m0_net_buffer_deregister(&d2nb2, &dom2);
646  m0_bufvec_free(&d2nb2.nb_buffer);
647 
648  m0_clink_init(&tmwait1, NULL);
649  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
650  M0_UT_ASSERT(!m0_net_tm_stop(&d1tm1, false));
651  m0_chan_wait(&tmwait1);
652  m0_clink_del_lock(&tmwait1);
654 
655  m0_clink_init(&tmwait2, NULL);
656  m0_clink_add_lock(&d2tm1.ntm_chan, &tmwait2);
657  M0_UT_ASSERT(!m0_net_tm_stop(&d2tm1, false));
658  m0_chan_wait(&tmwait2);
659  m0_clink_del_lock(&tmwait2);
661 
662  m0_clink_init(&tmwait2, NULL);
663  m0_clink_add_lock(&d2tm2.ntm_chan, &tmwait2);
664  M0_UT_ASSERT(!m0_net_tm_stop(&d2tm2, false));
665  m0_chan_wait(&tmwait2);
666  m0_clink_del_lock(&tmwait2);
668 
669  m0_net_tm_fini(&d1tm1);
670  m0_net_tm_fini(&d2tm1);
671  m0_net_tm_fini(&d2tm2);
672 
673  m0_net_domain_fini(&dom1);
674  m0_net_domain_fini(&dom2);
675 }
676 
677 enum {
683 };
684 static int quiet_printf(const char *fmt, ...)
685 {
686  return 0;
687 }
688 
689 static struct ping_ops quiet_ops = {
690  .pf = quiet_printf
691 };
692 
693 static void test_ping(void)
694 {
695  /* some variables below are static to reduce kernel stack
696  consumption. */
697 
698  static struct ping_ctx cctx = {
699  .pc_ops = &quiet_ops,
700  .pc_xprt = &m0_net_bulk_mem_xprt,
701  .pc_nr_bufs = PING_NR_BUFS,
702  .pc_segments = PING_CLIENT_SEGMENTS,
703  .pc_seg_size = PING_CLIENT_SEGMENT_SIZE,
704  .pc_tm = {
705  .ntm_state = M0_NET_TM_UNDEFINED
706  }
707  };
708  static struct ping_ctx sctx = {
709  .pc_ops = &quiet_ops,
710  .pc_xprt = &m0_net_bulk_mem_xprt,
711  .pc_nr_bufs = PING_NR_BUFS,
712  .pc_segments = PING_SERVER_SEGMENTS,
713  .pc_seg_size = PING_SERVER_SEGMENT_SIZE,
714  .pc_tm = {
715  .ntm_state = M0_NET_TM_UNDEFINED
716  }
717  };
718  int rc;
719  struct m0_net_end_point *server_ep;
720  struct m0_thread server_thread;
721  int i;
722  char *data;
723  int len;
724 
725  m0_mutex_init(&sctx.pc_mutex);
726  m0_cond_init(&sctx.pc_cond, &sctx.pc_mutex);
727  m0_mutex_init(&cctx.pc_mutex);
728  m0_cond_init(&cctx.pc_cond, &cctx.pc_mutex);
729 
730  M0_UT_ASSERT(ping_client_init(&cctx, &server_ep) == 0);
731  /* client times out because server is not ready */
732  M0_UT_ASSERT(ping_client_msg_send_recv(&cctx, server_ep, NULL) != 0);
733  /* server runs in background thread */
736  &ping_server, &sctx, "ping_server");
737  if (rc != 0) {
738  M0_IMPOSSIBLE("failed to start ping server");
739  return;
740  }
741 
742  M0_UT_ASSERT(ping_client_msg_send_recv(&cctx, server_ep, NULL) == 0);
743  M0_UT_ASSERT(ping_client_passive_recv(&cctx, server_ep) == 0);
744  M0_UT_ASSERT(ping_client_passive_send(&cctx, server_ep, NULL) == 0);
745 
746  /* test sending/receiving a bigger payload */
748  M0_UT_ASSERT(data != NULL);
750  for (i = 0; i < len; ++i)
751  data[i] = "abcdefghi"[i % 9];
752  M0_UT_ASSERT(ping_client_msg_send_recv(&cctx, server_ep, data) == 0);
753  M0_UT_ASSERT(ping_client_passive_send(&cctx, server_ep, data) == 0);
754 
755  M0_UT_ASSERT(ping_client_fini(&cctx, server_ep) == 0);
756 
759 
760  m0_cond_fini(&cctx.pc_cond);
761  m0_mutex_fini(&cctx.pc_mutex);
762  m0_cond_fini(&sctx.pc_cond);
763  m0_mutex_fini(&sctx.pc_mutex);
764  m0_free(data);
765 }
766 
767 static void ntc_event_callback(const struct m0_net_tm_event *ev)
768 {
769 }
770 
771 static void test_tm(void)
772 {
773  static struct m0_net_domain dom1 = {
774  .nd_xprt = NULL
775  };
776  const struct m0_net_tm_callbacks cbs1 = {
778  };
779  struct m0_net_transfer_mc d1tm1 = {
780  .ntm_callbacks = &cbs1,
781  .ntm_state = M0_NET_TM_UNDEFINED
782  };
783  struct m0_clink tmwait1;
784 
785  /* should be able to init/fini a dom back-to-back */
787  m0_net_domain_fini(&dom1);
788 
790  M0_UT_ASSERT(!m0_net_tm_init(&d1tm1, &dom1));
791 
792  /* should be able to fini it immediately */
793  m0_net_tm_fini(&d1tm1);
795 
796  /* should be able to init it again */
797  M0_UT_ASSERT(!m0_net_tm_init(&d1tm1, &dom1));
800 
801  /* check thread counts */
805 
806  /* fini */
807  if (d1tm1.ntm_state > M0_NET_TM_INITIALIZED) {
808  m0_clink_init(&tmwait1, NULL);
809  m0_clink_add_lock(&d1tm1.ntm_chan, &tmwait1);
810  M0_UT_ASSERT(!m0_net_tm_stop(&d1tm1, false));
811  m0_chan_wait(&tmwait1);
812  m0_clink_del_lock(&tmwait1);
814  }
815  m0_net_tm_fini(&d1tm1);
816  m0_net_domain_fini(&dom1);
817 }
818 
820  .ts_name = "net-bulk-mem",
821  .ts_init = NULL,
822  .ts_fini = NULL,
823  .ts_tests = {
824  { "net_bulk_mem_buf_copy_test", test_buf_copy },
825  { "net_bulk_mem_tm_test", test_tm },
826  { "net_bulk_mem_ep", test_ep },
827  { "net_bulk_mem_failure_tests", test_failure },
828  { "net_bulk_mem_ping_tests", test_ping },
829  { NULL, NULL }
830  }
831 };
832 M0_EXPORTED(m0_net_bulk_mem_ut);
833 
834 /*
835  * Local variables:
836  * c-indentation-style: "K&R"
837  * c-basic-offset: 8
838  * tab-width: 8
839  * fill-column: 80
840  * scroll-step: 1
841  * End:
842  */
static m0_bcount_t seg_size
Definition: net.c:118
void ping_server(struct ping_ctx *ctx)
Definition: ping.c:907
int(* pf)(const char *format,...) __attribute__((format(printf
Definition: ping.h:33
uint64_t nqs_num_f_events
Definition: net.h:784
static struct m0_addb2_philter p
Definition: consumer.c:40
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
uint64_t nqs_num_adds
Definition: net.h:764
void tf_cbreset1(void)
Definition: bulk_mem_ut.c:180
static struct m0_net_buffer * cb_nb1
Definition: bulk_mem_ut.c:159
static int32_t cb_status2
Definition: bulk_mem_ut.c:193
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
static struct ping_ops quiet_ops
Definition: bulk_mem_ut.c:689
M0_INTERNAL int m0_net_tm_start(struct m0_net_transfer_mc *tm, const char *addr)
Definition: tm.c:261
static struct m0_thread server_thread
uint64_t nqs_num_s_events
Definition: net.h:774
M0_INTERNAL void m0_net_bulk_mem_tm_set_num_threads(struct m0_net_transfer_mc *tm, size_t num)
Definition: mem_xprt_xo.c:594
static struct m0_semaphore q
Definition: rwlock.c:55
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
struct m0_bufvec nb_buffer
Definition: net.h:1322
M0_INTERNAL int m0_net_buffer_register(struct m0_net_buffer *buf, struct m0_net_domain *dom)
Definition: buf.c:65
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
uint32_t nbd_len
Definition: net_otw_types.h:37
uint64_t nqs_num_dels
Definition: net.h:769
static void test_failure(void)
Definition: bulk_mem_ut.c:227
static int mem_copy_buffer(struct m0_net_buffer *dest_nb, struct m0_net_buffer *src_nb, m0_bcount_t num_bytes)
static enum m0_net_tm_ev_type cb_evt1
Definition: bulk_mem_ut.c:157
M0_INTERNAL int m0_net_tm_stats_get(struct m0_net_transfer_mc *tm, enum m0_net_queue_type qtype, struct m0_net_qstats *qs, bool reset)
Definition: tm.c:343
uint8_t * nbd_data
Definition: net_otw_types.h:38
struct m0_vec ov_vec
Definition: vec.h:147
enum m0_net_tm_state ntm_state
Definition: net.h:819
struct m0_bufvec data
Definition: di.c:40
m0_bcount_t nb_length
Definition: net.h:1334
static struct m0_rpc_client_ctx cctx
Definition: rconfc.c:69
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
M0_INTERNAL bool m0_net_buffer_del(struct m0_net_buffer *buf, struct m0_net_transfer_mc *tm)
Definition: buf.c:261
int ping_client_fini(struct ping_ctx *ctx, struct m0_net_end_point *server_ep)
Definition: ping.c:1292
m0_bcount_t nb_min_receive_size
Definition: net.h:1496
const char * nep_addr
Definition: net.h:503
#define M0_SET0(obj)
Definition: misc.h:64
Definition: ut.h:77
struct m0_net_buffer * nbe_buffer
Definition: net.h:1194
static enum m0_net_queue_type cb_qt1
Definition: bulk_mem_ut.c:158
void ** ov_buf
Definition: vec.h:149
M0_INTERNAL void m0_cond_init(struct m0_cond *cond, struct m0_mutex *mutex)
Definition: cond.c:40
int ping_client_init(struct ping_ctx *ctx, struct m0_net_end_point **server_ep)
Definition: ping.c:1261
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
Definition: sock.c:754
struct m0_chan ntm_chan
Definition: net.h:874
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
int ping_client_passive_recv(struct ping_ctx *ctx, struct m0_net_end_point *server_ep)
Definition: ping.c:1088
static char * addr
Definition: node_k.c:37
int i
Definition: dir.c:1033
#define M0_SET_ARR0(arr)
Definition: misc.h:72
int32_t nbe_status
Definition: net.h:1218
enum m0_net_tm_state nte_next_state
Definition: net.h:723
static enum m0_net_tm_state cb_tms2
Definition: bulk_mem_ut.c:192
M0_INTERNAL int m0_net_tm_init(struct m0_net_transfer_mc *tm, struct m0_net_domain *dom)
Definition: tm.c:160
static void test_buf_copy(void)
Definition: bulk_mem_ut.c:37
enum m0_net_queue_type nb_qtype
Definition: net.h:1363
uint32_t nb_max_receive_msgs
Definition: net.h:1502
M0_INTERNAL void m0_net_tm_fini(struct m0_net_transfer_mc *tm)
Definition: tm.c:204
const struct m0_net_xprt * nd_xprt
Definition: net.h:396
void tf_buf_cb1(const struct m0_net_buffer_event *ev)
Definition: bulk_mem_ut.c:171
M0_INTERNAL void m0_cond_fini(struct m0_cond *cond)
Definition: cond.c:46
void(* ntc_event_cb)(const struct m0_net_tm_event *ev)
Definition: net.h:752
static void test_ping(void)
Definition: bulk_mem_ut.c:693
struct m0_atomic64 ref_cnt
Definition: refs.h:38
m0_net_tm_state
Definition: net.h:630
m0_net_tm_ev_type
Definition: net.h:641
struct m0_list_link ntm_dom_linkage
Definition: net.h:883
char * fmt(const char *format,...) __attribute__((format(printf
void * m0_alloc(size_t size)
Definition: memory.c:126
const struct m0_net_buffer_callbacks * nb_callbacks
Definition: net.h:1369
static struct m0_rpc_server_ctx sctx
Definition: console.c:88
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
static enum m0_net_tm_ev_type cb_evt2
Definition: bulk_mem_ut.c:189
M0_INTERNAL bool m0_list_contains(const struct m0_list *list, const struct m0_list_link *link)
Definition: list.c:87
Definition: xcode.h:73
M0_INTERNAL void m0_net_desc_free(struct m0_net_buf_desc *desc)
Definition: net.c:87
uint32_t v_nr
Definition: vec.h:51
m0_net_buffer_cb_proc_t nbc_cb[M0_NET_QT_NR]
Definition: net.h:1272
M0_INTERNAL int m0_net_desc_copy(const struct m0_net_buf_desc *from_desc, struct m0_net_buf_desc *to_desc)
Definition: net.c:74
m0_bcount_t * v_count
Definition: vec.h:53
void tf_tm_cb2(const struct m0_net_tm_event *ev)
Definition: bulk_mem_ut.c:194
M0_INTERNAL int m0_net_tm_stop(struct m0_net_transfer_mc *tm, bool abort)
Definition: tm.c:293
int ping_client_passive_send(struct ping_ctx *ctx, struct m0_net_end_point *server_ep, const char *data)
Definition: ping.c:1172
struct m0_ref nep_ref
Definition: net.h:491
static enum m0_net_queue_type cb_qt2
Definition: bulk_mem_ut.c:190
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
void m0_net_end_point_put(struct m0_net_end_point *ep)
Definition: ep.c:98
const char * ts_name
Definition: ut.h:99
void tf_tm_cb1(const struct m0_net_tm_event *ev)
Definition: bulk_mem_ut.c:162
M0_INTERNAL void m0_net_buffer_deregister(struct m0_net_buffer *buf, struct m0_net_domain *dom)
Definition: buf.c:107
static void ntc_event_callback(const struct m0_net_tm_event *ev)
Definition: bulk_mem_ut.c:767
Definition: ping.h:41
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
char * ep
Definition: sw.h:132
struct m0_net_end_point * ntm_ep
Definition: net.h:868
m0_net_queue_type
Definition: net.h:591
M0_INTERNAL int m0_net_buffer_add(struct m0_net_buffer *buf, struct m0_net_transfer_mc *tm)
Definition: buf.c:247
void tf_buf_cb2(const struct m0_net_buffer_event *ev)
Definition: bulk_mem_ut.c:203
static int32_t cb_status1
Definition: bulk_mem_ut.c:161
void tf_cbreset(void)
Definition: bulk_mem_ut.c:221
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
void tf_cbreset2(void)
Definition: bulk_mem_ut.c:212
static enum m0_net_tm_state cb_tms1
Definition: bulk_mem_ut.c:160
static int quiet_printf(const char *fmt,...)
Definition: bulk_mem_ut.c:684
void ping_server_should_stop(struct ping_ctx *ctx)
Definition: ping.c:990
static void test_ep(void)
Definition: bulk_mem_ut.c:93
struct m0_net_buf_desc nb_desc
Definition: net.h:1412
static void test_tm(void)
Definition: bulk_mem_ut.c:771
enum m0_net_tm_ev_type nte_type
Definition: net.h:691
static struct m0_net_buffer * cb_nb2
Definition: bulk_mem_ut.c:191
M0_INTERNAL size_t m0_net_bulk_mem_tm_get_num_threads(const struct m0_net_transfer_mc *tm)
Definition: mem_xprt_xo.c:606
int ping_client_msg_send_recv(struct ping_ctx *ctx, struct m0_net_end_point *server_ep, const char *data)
Definition: ping.c:1007
void m0_free(void *data)
Definition: memory.c:146
struct m0_ut_suite m0_net_bulk_mem_ut
Definition: bulk_mem_ut.c:819
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL int m0_net_end_point_create(struct m0_net_end_point **epp, struct m0_net_transfer_mc *tm, const char *addr)
Definition: ep.c:56
const struct m0_net_tm_callbacks * ntm_callbacks
Definition: net.h:816
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_list nd_tms
Definition: net.h:390
int32_t nte_status
Definition: net.h:715
const struct m0_net_xprt m0_net_bulk_mem_xprt
Definition: mem_xprt_xo.c:761
Definition: ping.h:32
struct m0_net_end_point * nb_ep
Definition: net.h:1424
#define M0_IMPOSSIBLE(fmt,...)