Motr  M0
idx_dix.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2020-2021 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 
24 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
25 #include "lib/trace.h"
26 
27 #include "lib/misc.h" /* M0_SRC_PATH */
28 #include "lib/finject.h"
29 #include "ut/ut.h"
30 #include "ut/misc.h" /* M0_UT_CONF_PROFILE */
31 #include "rpc/rpclib.h" /* m0_rpc_server_ctx */
32 #include "fid/fid.h"
33 #include "motr/client.h"
34 #include "motr/client_internal.h"
35 #include "motr/idx.h"
36 #include "dix/layout.h"
37 #include "dix/client.h"
38 #include "dix/meta.h"
39 #include "fop/fom_simple.h" /* m0_fom_simple */
40 #include "cas/cas_xc.h"
41 #include "dtm0/fop.h"
42 #include "dtm0/drlink.h"
43 #include "conf/helpers.h"
44 #include "dix/fid_convert.h"
45 #include "be/dtm0_log.h"
46 
47 #define WAIT_TIMEOUT M0_TIME_NEVER
48 #define SERVER_LOG_FILE_NAME "cas_server.log"
49 
50 static struct m0_client *ut_m0c;
51 static struct m0_config ut_m0_config;
53 
54 enum {
56  CNT = 10,
57  BATCH_SZ = 128,
58 };
59 
60 static char *cas_startup_cmd[] = {
61  "m0d", "-T", "linux",
62  "-D", "cs_sdb", "-S", "cs_stob",
63  "-A", "linuxstob:cs_addb_stob",
64  "-e", M0_NET_XPRT_PREFIX_DEFAULT":0@lo:12345:34:1",
65  "-H", "0@lo:12345:34:1",
66  "-w", "10", "-F",
67  "-f", M0_UT_CONF_PROCESS,
68  "-c", M0_SRC_PATH("motr/ut/dix_conf.xc")
69 };
70 
71 static const char *local_ep_addr = "0@lo:12345:34:2";
72 static const char *srv_ep_addr = { "0@lo:12345:34:1" };
73 static const char *process_fid = M0_UT_CONF_PROCESS;
74 struct m0_fid pver = M0_FID_TINIT('v', 1, 100);
75 
76 static struct m0_rpc_server_ctx dix_ut_sctx = {
78  .rsx_argc = ARRAY_SIZE(cas_startup_cmd),
79  .rsx_log_file_name = SERVER_LOG_FILE_NAME
80 };
81 
82 static void dix_config_init()
83 {
84  int rc;
85  struct m0_ext range[] = {{ .e_start = 0, .e_end = IMASK_INF }};
86 
87  /* Create meta indices (root, layout, layout-descr). */
89  ARRAY_SIZE(range), HASH_FNC_FNV1, &pver);
90  M0_UT_ASSERT(rc == 0);
92  ARRAY_SIZE(range), HASH_FNC_FNV1, &pver);
93  M0_UT_ASSERT(rc == 0);
94  /*
95  * motr/setup.c creates meta indices now. Therefore, we must not
96  * create it twice or it will fail with -EEXIST error.
97  */
99 }
100 
101 static void dix_config_fini()
102 {
105 }
106 
108 {
109  int rc;
110 
111  ut_m0c = NULL;
117  /* Use fake fid, see initlift_resource_manager(). */
123 
124  m0_fi_enable_once("ha_init", "skip-ha-init");
125  /* Skip HA finalisation in case of failure path. */
126  m0_fi_enable("ha_fini", "skip-ha-fini");
127  /*
128  * We can't use m0_fi_enable_once() here, because
129  * initlift_addb2() may be called twice in case of failure path.
130  */
131  m0_fi_enable("initlift_addb2", "no-addb2");
132  m0_fi_enable("ha_process_event", "no-link");
133  rc = m0_client_init(&ut_m0c, &ut_m0_config, false);
134  M0_UT_ASSERT(rc == 0);
135  m0_fi_disable("ha_process_event", "no-link");
136  m0_fi_disable("initlift_addb2", "no-addb2");
137  m0_fi_disable("ha_fini", "skip-ha-fini");
138  ut_m0c->m0c_motr = m0_get();
139 }
140 
141 static void idx_dix_ut_init()
142 {
143  int rc;
144 
149  M0_ASSERT(rc == 0);
150  dix_config_init();
152 }
153 
154 static void idx_dix_ut_fini()
155 {
156  /*
157  * Meta-indices are destroyed automatically during m0_rpc_server_stop()
158  * along with the whole BE data.
159  */
160  dix_config_fini();
161  m0_fi_enable_once("ha_fini", "skip-ha-fini");
162  m0_fi_enable_once("initlift_addb2", "no-addb2");
163  m0_fi_enable("ha_process_event", "no-link");
164  m0_client_fini(ut_m0c, false);
165  m0_fi_disable("ha_process_event", "no-link");
167 }
168 
169 static void ut_dix_init_fini(void)
170 {
171  idx_dix_ut_init();
172  idx_dix_ut_fini();
173 }
174 
175 static int *rcs_alloc(int count)
176 {
177  int i;
178  int *rcs;
179 
180  M0_ALLOC_ARR(rcs, count);
181  M0_UT_ASSERT(rcs != NULL);
182  for (i = 0; i < count; i++)
183  /* Set to some value to assert that UT actually changed rc. */
184  rcs[i] = 0xdb;
185  return rcs;
186 }
187 
188 static uint8_t ifid_type(bool dist)
189 {
191 }
192 
193 static void general_ifid_fill(struct m0_fid *ifid, bool dist)
194 {
195  *ifid = M0_FID_TINIT(ifid_type(dist), 2, 1);
196 }
197 
198 static void general_ifid_fill_batch(struct m0_fid *ifid, bool dist, int i)
199 {
200  *ifid = M0_FID_TINIT(ifid_type(dist), 2, i);
201 }
202 
203 static void ut_dix_namei_ops_cancel(bool dist)
204 {
205  struct m0_container realm;
206  struct m0_idx idx[BATCH_SZ];
207  struct m0_fid ifid[BATCH_SZ];
208  struct m0_op *op[BATCH_SZ] = { NULL };
209  int rc;
210  int i;
211 
212  idx_dix_ut_init();
215 
216  /* Create the index. */
217  for (i = 0; i < BATCH_SZ; i++) {
218  general_ifid_fill_batch(&ifid[i], dist, i);
219  /* Create the index. */
220  m0_idx_init(&idx[i], &realm.co_realm,
221  (struct m0_uint128 *)&ifid[i]);
222  rc = m0_entity_create(NULL, &idx[i].in_entity, &op[i]);
223  M0_UT_ASSERT(rc == 0);
224  }
226  for (i = 0; i < BATCH_SZ; i++) {
229  M0_OS_STABLE),
230  WAIT_TIMEOUT);
231  M0_UT_ASSERT(rc == 0);
232  }
234  for (i = 0; i < BATCH_SZ; i++) {
236  M0_OS_FAILED),
237  WAIT_TIMEOUT);
238  M0_UT_ASSERT(rc == 0);
239  m0_op_fini(op[i]);
240  m0_free0(&op[i]);
241  }
242 
243  /* Check that index exists. */
244  for (i = 0; i < BATCH_SZ; i++) {
245  rc = m0_idx_op(&idx[i], M0_IC_LOOKUP,
246  NULL, NULL, NULL, 0, &op[i]);
247  M0_UT_ASSERT(rc == 0);
248  }
250  for (i = 0; i < BATCH_SZ; i++) {
253  M0_OS_STABLE),
254  WAIT_TIMEOUT);
255  M0_UT_ASSERT(rc == 0);
256  }
258  for (i = 0; i < BATCH_SZ; i++) {
260  M0_OS_FAILED),
261  WAIT_TIMEOUT);
262  M0_UT_ASSERT(rc == 0);
263  m0_op_fini(op[i]);
264  m0_free0(&op[i]);
265  }
266 
267  /* Delete the index. */
268  for (i = 0; i < BATCH_SZ; i++) {
269  rc = m0_entity_delete(&idx[i].in_entity, &op[i]);
270  M0_UT_ASSERT(rc == 0);
271  }
273  for (i = 0; i < BATCH_SZ; i++) {
276  M0_OS_STABLE),
277  WAIT_TIMEOUT);
278  M0_UT_ASSERT(rc == 0);
279  }
281  for (i = 0; i < BATCH_SZ; i++) {
283  M0_OS_FAILED),
284  WAIT_TIMEOUT);
285  M0_UT_ASSERT(rc == 0);
286  m0_op_fini(op[i]);
287  m0_free0(&op[i]);
288  }
289 
290  for (i = 0; i < BATCH_SZ; i++)
291  m0_idx_fini(&idx[i]);
292  idx_dix_ut_fini();
293 }
294 
296 {
298 }
299 
301 {
303 }
304 
305 static void ut_dix_namei_ops(bool dist, uint32_t flags)
306 {
307  struct m0_container realm;
308  struct m0_idx idx;
309  struct m0_idx idup;
310  struct m0_fid ifid;
311  struct m0_op *op = NULL;
312  struct m0_bufvec keys;
313  int *rcs;
314  int rc;
315  struct m0_op_common *oc;
316  struct m0_op_idx *oi;
317 
318  idx_dix_ut_init();
320  general_ifid_fill(&ifid, dist);
321  /* Create the index. */
322  m0_idx_init(&idx, &realm.co_realm, (struct m0_uint128 *)&ifid);
323 
326  rc = m0_entity_create(NULL, &idx.in_entity, &op);
327  M0_UT_ASSERT(rc == 0);
328  oc = M0_AMB(oc, op, oc_op);
329  oi = M0_AMB(oi, oc, oi_oc);
330  oi->oi_flags = flags;
331  m0_op_launch(&op, 1);
333  M0_UT_ASSERT(rc == 0);
334  m0_op_fini(op);
335  m0_free0(&op);
336 
337  /* Create an index with the same fid once more => -EEXIST. */
338  m0_idx_init(&idup, &realm.co_realm, (struct m0_uint128 *)&ifid);
341  rc = m0_entity_create(NULL, &idup.in_entity, &op);
342  M0_UT_ASSERT(rc == 0);
343  oc = M0_AMB(oc, op, oc_op);
344  oi = M0_AMB(oi, oc, oi_oc);
345  oi->oi_flags = flags;
346  m0_op_launch(&op, 1);
348  M0_UT_ASSERT(rc == 0);
349  M0_UT_ASSERT(op->op_rc == -EEXIST);
350  m0_op_fini(op);
351  m0_free0(&op);
352  m0_idx_fini(&idup);
353 
354  /* Check that index exists. */
355  rc = m0_idx_op(&idx, M0_IC_LOOKUP, NULL, NULL, NULL, 0,
356  &op);
357  M0_UT_ASSERT(rc == 0);
358  m0_op_launch(&op, 1);
360  M0_UT_ASSERT(rc == 0);
361  m0_op_fini(op);
362  m0_free0(&op);
363 
364  /* List all indices (only one exists). */
365  rcs = rcs_alloc(2);
366  rc = m0_bufvec_alloc(&keys, 2, sizeof(struct m0_fid));
367  M0_UT_ASSERT(rc == 0);
368  rc = m0_idx_op(&idx, M0_IC_LIST, &keys, NULL, rcs, flags,
369  &op);
370  M0_UT_ASSERT(rc == 0);
371  m0_op_launch(&op, 1);
373  M0_UT_ASSERT(rc == 0);
374  if (flags & M0_OIF_SKIP_LAYOUT) {
375  M0_UT_ASSERT(rcs[0] == -ENOENT);
376  M0_UT_ASSERT(!m0_fid_eq(keys.ov_buf[0], &ifid));
377  } else {
378  M0_UT_ASSERT(rcs[0] == 0);
379  M0_UT_ASSERT(m0_fid_eq(keys.ov_buf[0], &ifid));
380  }
381  M0_UT_ASSERT(rcs[1] == -ENOENT);
382  M0_UT_ASSERT(keys.ov_vec.v_nr == 2);
383  M0_UT_ASSERT(keys.ov_vec.v_count[0] == sizeof(struct m0_fid));
384  M0_UT_ASSERT(keys.ov_vec.v_count[1] == sizeof(struct m0_fid));
385  M0_UT_ASSERT(!m0_fid_is_set(keys.ov_buf[1]));
386  m0_op_fini(op);
387  m0_free0(&op);
388  m0_free0(&rcs);
389  m0_bufvec_free(&keys);
390 
391  /* Delete the index. */
392  rc = m0_entity_delete(&idx.in_entity, &op);
393  M0_UT_ASSERT(rc == 0);
394  m0_op_launch(&op, 1);
396  M0_UT_ASSERT(rc == 0);
397  m0_op_fini(op);
398  m0_free0(&op);
399 
400  /* Delete an index with the same fid once more => -ENOENT. */
401  m0_idx_init(&idup, &realm.co_realm, (struct m0_uint128 *)&ifid);
402  rc = m0_entity_open(&idup.in_entity, &op);
403  M0_UT_ASSERT(rc == 0);
404  rc = m0_entity_delete(&idup.in_entity, &op);
405  M0_UT_ASSERT(rc == 0);
406  m0_op_launch(&op, 1);
408  M0_UT_ASSERT(rc == 0);
409  M0_UT_ASSERT(op->op_rc == -ENOENT);
410  m0_op_fini(op);
411  m0_free0(&op);
412 
413  m0_idx_fini(&idx);
414  idx_dix_ut_fini();
415 }
416 
417 static void ut_dix_namei_ops_dist(void)
418 {
419  ut_dix_namei_ops(true, 0);
420 }
421 
423 {
424  uint32_t flags = M0_OIF_SKIP_LAYOUT;
425  ut_dix_namei_ops(true, flags);
426 }
427 
429 {
430  uint32_t flags = M0_OIF_SKIP_LAYOUT | M0_OIF_CROW;
431  ut_dix_namei_ops(true, flags);
432 }
433 
434 static void ut_dix_namei_ops_non_dist(void)
435 {
436  ut_dix_namei_ops(false, 0);
437 }
438 
439 static uint64_t dix_key(uint64_t i)
440 {
441  return 100 + i;
442 }
443 
444 static uint64_t dix_val(uint64_t i)
445 {
446  return 100 + i * i;
447 }
448 
449 static void ut_dix_record_ops(bool dist, uint32_t cr_get_flags,
450  uint32_t put_del_flags)
451 {
452  struct m0_container realm;
453  struct m0_idx idx;
454  struct m0_fid ifid;
455  struct m0_op *op = NULL;
456  struct m0_bufvec keys;
457  struct m0_bufvec vals;
458  uint64_t i;
459  bool eof;
460  uint64_t accum;
461  uint64_t recs_nr;
462  uint64_t cur_key;
463  int rc;
464  int *rcs;
465  struct m0_op_common *oc;
466  struct m0_op_idx *oi;
467 
468  idx_dix_ut_init();
469  general_ifid_fill(&ifid, dist);
471  m0_idx_init(&idx, &realm.co_realm, (struct m0_uint128 *)&ifid);
472  if (cr_get_flags & M0_OIF_SKIP_LAYOUT)
474 
475  /* Create index. */
476  rc = m0_entity_create(NULL, &idx.in_entity, &op);
477  M0_UT_ASSERT(rc == 0);
478  oc = M0_AMB(oc, op, oc_op);
479  oi = M0_AMB(oi, oc, oi_oc);
480  oi->oi_flags = cr_get_flags;
481  m0_op_launch(&op, 1);
483  M0_UT_ASSERT(rc == 0);
484  m0_op_fini(op);
485  m0_free0(&op);
486 
487  /* Get non-existing key. */
488  rcs = rcs_alloc(1);
489  rc = m0_bufvec_alloc(&keys, 1, sizeof(uint64_t)) ?:
490  m0_bufvec_empty_alloc(&vals, 1);
491  M0_UT_ASSERT(rc == 0);
492  *(uint64_t*)keys.ov_buf[0] = dix_key(10);
493  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, cr_get_flags,
494  &op);
495  M0_UT_ASSERT(rc == 0);
496  m0_op_launch(&op, 1);
498  M0_UT_ASSERT(rc == 0);
499  M0_UT_ASSERT(vals.ov_buf[0] == NULL);
500  M0_UT_ASSERT(vals.ov_vec.v_count[0] == 0);
501  M0_UT_ASSERT(rcs[0] == -ENOENT);
502  m0_bufvec_free(&keys);
503  m0_bufvec_free(&vals);
504  m0_op_fini(op);
505  m0_free0(&op);
506  m0_free0(&rcs);
507 
508 
509  /* Add records to the index. */
510  rcs = rcs_alloc(CNT);
511  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
512  m0_bufvec_alloc(&vals, CNT, sizeof(uint64_t));
513  M0_UT_ASSERT(rc == 0);
514  for (i = 0; i < keys.ov_vec.v_nr; i++) {
515  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
516  *(uint64_t *)vals.ov_buf[i] = dix_val(i);
517  }
518  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs, put_del_flags,
519  &op);
520  M0_UT_ASSERT(rc == 0);
521  m0_op_launch(&op, 1);
523  M0_UT_ASSERT(rc == 0);
525  rcs[i] == 0 &&
526  *(uint64_t *)vals.ov_buf[i] == dix_val(i)));
527  m0_op_fini(op);
528  m0_free0(&op);
529  m0_free0(&rcs);
530 
531  /* Try to add recs again without OVERWRITE flag. */
532  rcs = rcs_alloc(CNT);
533  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs, put_del_flags,
534  &op);
535  M0_UT_ASSERT(rc == 0);
536  m0_op_launch(&op, 1);
538  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
539  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == -EEXIST));
540  m0_op_fini(op);
541  m0_free0(&op);
542  m0_free0(&rcs);
543 
544  /* Try to add recs again with OVERWRITE flag. */
545  rcs = rcs_alloc(CNT);
546  for (i = 0; i < keys.ov_vec.v_nr; i++)
547  *(uint64_t *)vals.ov_buf[i] = dix_val(i * 10);
548 
549  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs,
550  M0_OIF_OVERWRITE | put_del_flags, &op);
551  M0_UT_ASSERT(rc == 0);
552  m0_op_launch(&op, 1);
554  M0_UT_ASSERT(rc == 0);
555  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
556  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
557  m0_op_fini(op);
558  m0_free0(&op);
559  m0_free0(&rcs);
560 
561  m0_bufvec_free(&keys);
562  m0_bufvec_free(&vals);
563 
564  /* Get records from the index by keys. */
565  rcs = rcs_alloc(CNT);
566  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
567  m0_bufvec_empty_alloc(&vals, CNT);
568  M0_UT_ASSERT(rc == 0);
569  for (i = 0; i < keys.ov_vec.v_nr; i++)
570  *(uint64_t*)keys.ov_buf[i] = dix_key(i);
571  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, 0,
572  &op);
573  M0_UT_ASSERT(rc == 0);
574  m0_op_launch(&op, 1);
576  M0_UT_ASSERT(rc == 0);
578  rcs[i] == 0 &&
579  *(uint64_t *)vals.ov_buf[i] == dix_val(i * 10)));
580  m0_bufvec_free(&keys);
581  m0_bufvec_free(&vals);
582  m0_op_fini(op);
583  m0_free0(&op);
584  m0_free0(&rcs);
585 
586  /* Get records with all existing keys, except the one. */
587  rcs = rcs_alloc(CNT);
588  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
589  m0_bufvec_empty_alloc(&vals, CNT);
590  M0_UT_ASSERT(rc == 0);
591  for (i = 0; i < keys.ov_vec.v_nr; i++)
592  *(uint64_t*)keys.ov_buf[i] = dix_key(i);
593  *(uint64_t *)keys.ov_buf[5] = dix_key(999);
594  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, 0,
595  &op);
596  M0_UT_ASSERT(rc == 0);
597  m0_op_launch(&op, 1);
599  M0_UT_ASSERT(rc == 0);
600  for (i = 0; i < CNT; i++) {
601  if (i != 5) {
602  M0_UT_ASSERT(rcs[i] == 0);
603  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[i] ==
604  dix_val(i * 10));
605  } else {
606  M0_UT_ASSERT(rcs[i] == -ENOENT);
607  M0_UT_ASSERT(vals.ov_buf[5] == NULL);
608  }
609  }
610  m0_bufvec_free(&keys);
611  m0_bufvec_free(&vals);
612  m0_op_fini(op);
613  m0_free0(&op);
614  m0_free0(&rcs);
615 
616  /* Iterate over all records in the index. */
617  rcs = rcs_alloc(CNT + 1);
618  rc = m0_bufvec_empty_alloc(&keys, CNT + 1) ?:
619  m0_bufvec_empty_alloc(&vals, CNT + 1);
620  M0_UT_ASSERT(rc == 0);
621  cur_key = dix_key(0);
622  keys.ov_buf[0] = &cur_key;
623  keys.ov_vec.v_count[0] = sizeof(uint64_t);
624  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals, rcs, 0, &op);
625  M0_UT_ASSERT(rc == 0);
626  m0_op_launch(&op, 1);
628  M0_UT_ASSERT(rc == 0);
630  rcs[i] == 0 &&
631  *(uint64_t*)keys.ov_buf[i] == dix_key(i) &&
632  *(uint64_t*)vals.ov_buf[i] == dix_val(i * 10)));
633  M0_UT_ASSERT(rcs[CNT] == -ENOENT);
634  M0_UT_ASSERT(keys.ov_buf[CNT] == NULL);
635  M0_UT_ASSERT(vals.ov_buf[CNT] == NULL);
636  m0_bufvec_free(&keys);
637  m0_bufvec_free(&vals);
638  m0_op_fini(op);
639  m0_free0(&op);
640  m0_free0(&rcs);
641 
642  /* Iterate over all records in the index excluding the start key. */
643  rcs = rcs_alloc(CNT + 1);
644  rc = m0_bufvec_empty_alloc(&keys, CNT + 1) ?:
645  m0_bufvec_empty_alloc(&vals, CNT + 1);
646  M0_UT_ASSERT(rc == 0);
647  cur_key = dix_key(0);
648  keys.ov_buf[0] = &cur_key;
649  keys.ov_vec.v_count[0] = sizeof(uint64_t);
650  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals, rcs,
652  M0_UT_ASSERT(rc == 0);
653  m0_op_launch(&op, 1);
655  M0_UT_ASSERT(rc == 0);
657  rcs[i] == 0 &&
658  *(uint64_t*)keys.ov_buf[i] == dix_key(i + 1) &&
659  *(uint64_t*)vals.ov_buf[i] ==
660  dix_val((i + 1) * 10)));
661  M0_UT_ASSERT(rcs[CNT - 1] == -ENOENT);
662  M0_UT_ASSERT(keys.ov_buf[CNT - 1] == NULL);
663  M0_UT_ASSERT(vals.ov_buf[CNT - 1] == NULL);
664  m0_bufvec_free(&keys);
665  m0_bufvec_free(&vals);
666  m0_op_fini(op);
667  m0_free0(&op);
668  m0_free0(&rcs);
669 
670  /* Try to add recs again with OVERWRITE flag. */
671  rcs = rcs_alloc(CNT + 1);
672  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
673  m0_bufvec_alloc(&vals, CNT, sizeof(uint64_t));
674  M0_UT_ASSERT(rc == 0);
675  for (i = 0; i < keys.ov_vec.v_nr; i++) {
676  *(uint64_t *)vals.ov_buf[i] = dix_val(i);
677  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
678  }
679 
680  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs,
681  M0_OIF_OVERWRITE | put_del_flags, &op);
682  M0_UT_ASSERT(rc == 0);
683  m0_op_launch(&op, 1);
685  M0_UT_ASSERT(rc == 0);
686  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
687  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
688  m0_op_fini(op);
689  m0_free0(&op);
690  m0_free0(&rcs);
691  m0_bufvec_free(&vals);
692  m0_bufvec_free(&keys);
693  /*
694  * Iterate over all records in the index, starting from the beginning
695  * and requesting two records at a time.
696  */
697  accum = 0;
698  cur_key = 0;
699  do {
700  rcs = rcs_alloc(2);
701  rc = m0_bufvec_empty_alloc(&keys, 2) ?:
702  m0_bufvec_empty_alloc(&vals, 2);
703  M0_UT_ASSERT(rc == 0);
704  if (cur_key != 0) {
705  keys.ov_buf[0] = &cur_key;
706  keys.ov_vec.v_count[0] = sizeof(uint64_t);
707  } else {
708  /*
709  * Pass NULL in order to request records starting from
710  * the smallest key.
711  */
712  keys.ov_buf[0] = NULL;
713  keys.ov_vec.v_count[0] = 0;
714  }
715  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals,
716  rcs, 0, &op);
717  M0_UT_ASSERT(rc == 0);
718  m0_op_launch(&op, 1);
720  WAIT_TIMEOUT);
721  M0_UT_ASSERT(rc == 0);
722  for (i = 0; i < vals.ov_vec.v_nr && rcs[i] == 0; i++)
723  ;
724  recs_nr = i;
725  eof = recs_nr < keys.ov_vec.v_nr;
726  for (i = 0; i < recs_nr; i++) {
727  M0_UT_ASSERT(*(uint64_t *)keys.ov_buf[i] ==
728  dix_key(accum + i));
729  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[i] ==
730  dix_val(accum + i));
731  cur_key = *(uint64_t *)keys.ov_buf[i];
732  }
733  m0_bufvec_free(&keys);
734  m0_bufvec_free(&vals);
735  m0_op_fini(op);
736  m0_free0(&op);
737  m0_free0(&rcs);
738  /*
739  * Starting key is also included in returned number of records,
740  * so extract 1. The only exception is the first request, when
741  * starting key is unknown. It is accounted before accum check
742  * after eof is reached.
743  */
744  accum += recs_nr - 1;
745  } while (!eof);
746  accum++;
747  M0_UT_ASSERT(accum == CNT);
748 
749  /* Remove the records from the index. */
750  rcs = rcs_alloc(CNT);
751  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t));
752  M0_UT_ASSERT(rc == 0);
753  for (i = 0; i < keys.ov_vec.v_nr; i++)
754  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
755  rc = m0_idx_op(&idx, M0_IC_DEL, &keys, NULL, rcs, put_del_flags, &op);
756  M0_UT_ASSERT(rc == 0);
757  m0_op_launch(&op, 1);
759  M0_UT_ASSERT(rc == 0);
760  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
761  m0_bufvec_free(&keys);
762  m0_op_fini(op);
763  m0_free0(&op);
764  m0_free0(&rcs);
765 
766  /* Remove the index. */
767  rc = m0_entity_delete(&idx.in_entity, &op);
768  M0_UT_ASSERT(rc == 0);
769  m0_op_launch(&op, 1);
771  M0_UT_ASSERT(rc == 0);
772  m0_op_fini(op);
773  m0_free0(&op);
774 
775  m0_idx_fini(&idx);
776  idx_dix_ut_fini();
777 }
778 
780 {
781  uint32_t cr_get_flags = M0_OIF_SKIP_LAYOUT;
782  ut_dix_record_ops(true, cr_get_flags, 0);
783 }
784 
786 {
787  uint32_t cr_get_flags = M0_OIF_SKIP_LAYOUT | M0_OIF_CROW;
788  ut_dix_record_ops(true, cr_get_flags, 0);
789 }
790 
791 static void ut_dix_record_ops_dist(void)
792 {
793  ut_dix_record_ops(true, 0, 0);
794 }
795 
796 static void ut_dix_record_ops_non_dist(void)
797 {
798  ut_dix_record_ops(false, 0, 0);
799 }
800 
802 {
804 }
805 
807 {
808  ut_dix_record_ops(false, 0, M0_OIF_NO_DTM);
809 }
810 
811 
813  .ts_name = "idx-dix",
814  .ts_owners = "Egor",
815  .ts_init = NULL,
816  .ts_fini = NULL,
817  .ts_tests = {
818  { "init-fini", ut_dix_init_fini, "Egor" },
819  { "namei-ops-dist", ut_dix_namei_ops_dist, "Egor" },
820  { "namei-ops-non-dist", ut_dix_namei_ops_non_dist, "Egor" },
821  { "record-ops-dist", ut_dix_record_ops_dist, "Egor" },
822  { "record-ops-non-dist", ut_dix_record_ops_non_dist, "Egor" },
823  { "namei-ops-cancel-dist", ut_dix_namei_ops_cancel_dist,
824  "Vikram" },
825  { "namei-ops-cancel-non-dist", ut_dix_namei_ops_cancel_non_dist,
826  "Vikram" },
827  { "namei-ops-dist-skip-layout",
829  "Venky" },
830  { "record-ops-dist-skip-layout",
832  "Venky" },
833  { "namei-ops-dist-skip-layout-enable-crow",
835  "Venky" },
836  { "record-ops-dist-skip-layout-enable-crow",
838  "Venky" },
839  { "record-ops-dist-no-dtm",
840  ut_dix_record_ops_dist_no_dtm, "Huang Hua" },
841  { "record-ops-non-dist-no-dtm",
842  ut_dix_record_ops_non_dist_no_dtm, "Huang Hua" },
843  { NULL, NULL }
844  }
845 };
846 
847 static int ut_suite_mt_idx_dix_init(void)
848 {
849  idx_dix_ut_init();
850  return 0;
851 }
852 
853 static int ut_suite_mt_idx_dix_fini(void)
854 {
855  idx_dix_ut_fini();
856  return 0;
857 }
858 
859 extern void st_mt(void);
860 extern void st_lsfid(void);
861 extern void st_lsfid_cancel(void);
862 
864 {
865  return ut_m0c;
866 }
867 
868 #include "dtm0/helper.h"
869 #include "dtm0/service.h"
870 
871 struct dtm0_ut_ctx {
872  struct m0_idx duc_idx;
874  struct m0_fid duc_ifid;
875 };
876 
877 static struct dtm0_ut_ctx duc = {};
878 static struct m0_fid cli_dtm0_fid = M0_FID_INIT(0x7300000000000001, 0x1a);
879 
880 static int duc_setup(void)
881 {
882  int rc;
883  struct m0_container *realm = &duc.duc_realm;
884 
885  m0_fi_enable("m0_dtm0_in_ut", "ut");
887  M0_UT_ASSERT(rc == 0);
888 
890 
891  if (ENABLE_DTM0) {
893  }
894 
896 
897  return 0;
898 }
899 
900 static void idx_setup(void)
901 {
902  struct m0_op *op = NULL;
903  struct m0_idx *idx = &duc.duc_idx;
904  struct m0_container *realm = &duc.duc_realm;
905  int rc;
906  struct m0_fid *ifid = &duc.duc_ifid;
907 
908  m0_idx_init(idx, &realm->co_realm, (struct m0_uint128 *) ifid);
909 
910  /* Create the index */
911  if (ENABLE_DTM0)
913  rc = m0_entity_create(NULL, &idx->in_entity, &op);
914  M0_UT_ASSERT(rc == 0);
915  m0_op_launch(&op, 1);
917  M0_UT_ASSERT(rc == 0);
918  m0_op_fini(op);
919  m0_op_free(op);
920  op = NULL;
921 }
922 
923 static void idx_teardown(void)
924 {
925  struct m0_op *op = NULL;
926  int rc;
927 
928  /* Delete the index */
930  M0_UT_ASSERT(rc == 0);
931  m0_op_launch(&op, 1);
933  M0_UT_ASSERT(rc == 0);
934  m0_op_fini(op);
935  m0_op_free(op);
937  M0_SET0(&duc.duc_idx);
938 }
939 
940 
941 static int duc_teardown(void)
942 {
943  int rc;
944 
946  m0_fi_disable("m0_dtm0_in_ut", "ut");
947  return rc;
948 }
949 
950 /* Submits multiple M0 client (PUT|DEL) operations and then waits on "phase1"
951  * states, and then waits on "phase2" states.
952  */
953 static void run_m0ops(uint64_t nr, enum m0_idx_opcode opcode,
954  uint64_t phase1wait,
955  uint64_t phase2wait)
956 {
957  struct m0_idx *idx = &duc.duc_idx;
958  struct m0_op **ops;
959  int *rcs;
960  struct m0_bufvec *key_vecs;
961  char *val = NULL;
962  struct m0_bufvec vals = {};
963  m0_bcount_t len = 1;
964  int flags = 0;
965  uint64_t i;
966  int rc;
967 
968  M0_PRE(M0_IN(opcode, (M0_IC_PUT, M0_IC_DEL)));
969  M0_ALLOC_ARR(ops, nr);
970  M0_UT_ASSERT(ops != NULL);
971  M0_ALLOC_ARR(rcs, nr);
972  M0_UT_ASSERT(rcs != NULL);
973  M0_ALLOC_ARR(key_vecs, nr);
974  M0_UT_ASSERT(key_vecs != NULL);
975 
976  if (opcode == M0_IC_PUT) {
977  val = m0_strdup("ItIsAValue");
978  M0_UT_ASSERT(val != NULL);
979  vals = M0_BUFVEC_INIT_BUF((void **) &val, &len);
980  }
981 
982  /* Execute the ops */
983  for (i = 0; i < nr; ++i) {
984  rc = m0_bufvec_alloc(&key_vecs[i], 1, sizeof(i));
985  M0_UT_ASSERT(rc == 0);
986  M0_UT_ASSERT(key_vecs[i].ov_vec.v_count[0] == sizeof(i));
987  memcpy(key_vecs[i].ov_buf[0], &i, sizeof(i));
988 
989  rc = m0_idx_op(idx, opcode, &key_vecs[i],
990  opcode == M0_IC_DEL ? NULL : &vals,
991  &rcs[i], flags, &ops[i]);
992  M0_UT_ASSERT(rc == 0);
993  m0_op_launch(&ops[i], 1);
994 
995  if (phase1wait != 0)
996  rc = m0_op_wait(ops[i], phase1wait, WAIT_TIMEOUT);
997  else
998  rc = 0;
999  M0_LOG(M0_DEBUG, "Got phase1 %" PRIu64, i);
1000  if (rc == -ESRCH)
1001  M0_UT_ASSERT(ops[i]->op_sm.sm_state == M0_OS_STABLE);
1002  }
1003 
1004  /* Wait until they get stable */
1005  for (i = 0; i < nr; ++i) {
1006  if (phase2wait != 0)
1007  rc = m0_op_wait(ops[i], phase2wait, WAIT_TIMEOUT);
1008  else
1009  rc = 0;
1010  M0_LOG(M0_DEBUG, "Got phase2 %" PRIu64, i);
1011  M0_UT_ASSERT(rc == 0);
1012  M0_UT_ASSERT(ops[i]->op_rc == 0);
1013  M0_UT_ASSERT(rcs[0] == 0);
1014  m0_op_fini(ops[i]);
1015  m0_op_free(ops[i]);
1016  ops[i] = NULL;
1017  m0_bufvec_free(&key_vecs[i]);
1018  }
1019 
1021  m0_free(key_vecs);
1022  m0_free(ops);
1023  m0_free(val);
1024 }
1025 
1029 static void exec_then_stable(uint64_t nr, enum m0_idx_opcode opcode)
1030 {
1032 }
1033 
1036 static void exec_one_by_one(uint64_t nr, enum m0_idx_opcode opcode)
1037 {
1039 }
1040 
1044 static void exec_concurrent(uint64_t nr, enum m0_idx_opcode opcode)
1045 {
1047 }
1048 
1049 static void st_dtm0(void)
1050 {
1051  idx_setup();
1053  idx_teardown();
1054 }
1055 
1056 static void st_dtm0_putdel(void)
1057 {
1058  idx_setup();
1061  idx_teardown();
1062 
1063  idx_setup();
1064  exec_one_by_one(100, M0_IC_PUT);
1065  exec_one_by_one(100, M0_IC_DEL);
1066  idx_teardown();
1067 }
1068 
1069 static void st_dtm0_e_then_s(void)
1070 {
1071  idx_setup();
1074  idx_teardown();
1075 }
1076 
1077 static void st_dtm0_c(void)
1078 {
1079  idx_setup();
1080  exec_concurrent(100, M0_IC_PUT);
1081  exec_concurrent(100, M0_IC_DEL);
1082  idx_teardown();
1083 }
1084 
1085 static void dtm0_ut_cas_op_prepare(const struct m0_fid *cfid,
1086  struct m0_cas_op *op,
1087  struct m0_cas_rec *rec,
1088  uint64_t *key,
1089  uint64_t *val,
1090  struct m0_dtm0_tx_desc *txr)
1091 {
1092  int rc;
1093  struct m0_buf buf_key = { .b_nob = sizeof(uint64_t),
1094  .b_addr = key };
1095  struct m0_buf buf_val = { .b_nob = sizeof(uint64_t),
1096  .b_addr = val };
1097  struct m0_rpc_at_buf at_buf_key = { .u.ab_buf = buf_key,
1098  .ab_type = M0_RPC_AT_INLINE };
1099  struct m0_rpc_at_buf at_buf_val = { .u.ab_buf = buf_val,
1100  .ab_type = M0_RPC_AT_INLINE };
1101 
1102  rec->cr_key = at_buf_key;
1103  rec->cr_val = at_buf_val;
1104 
1105  op->cg_id.ci_layout.dl_type = DIX_LTYPE_DESCR;
1106  rc = m0_dix_ldesc_init(&op->cg_id.ci_layout.u.dl_desc,
1107  &(struct m0_ext) { .e_start = 0,
1108  .e_end = IMASK_INF }, 1, HASH_FNC_CITY,
1109  &pver);
1110  M0_UT_ASSERT(rc == 0);
1111 
1112  op->cg_id.ci_fid = *cfid;
1113  op->cg_rec.cr_nr = 1;
1114  op->cg_rec.cr_rec = rec;
1115  if (txr != NULL) {
1116  rc = m0_dtm0_tx_desc_copy(txr, &op->cg_txd);
1117  M0_UT_ASSERT(rc == 0);
1118  }
1119 }
1120 
1121 static void dtm0_ut_send_redo(const struct m0_fid *ifid,
1122  uint64_t *key, uint64_t *val)
1123 {
1124  int rc;
1125  struct dtm0_req_fop req = { .dtr_msg = DTM_REDO };
1126  struct m0_dtm0_tx_desc txr = {};
1127  struct m0_dtm0_clk_src dcs;
1128  struct m0_dtm0_ts now;
1129  struct m0_dtm0_service *dtm0 = ut_m0c->m0c_dtms;
1130  struct m0_buf payload;
1131  struct m0_cas_op cas_op = {};
1132  struct m0_cas_rec cas_rec = {};
1133  struct m0_fid srv_dtm0_fid;
1134  struct m0_fid srv_proc_fid;
1135  struct m0_fid cctg_fid;
1136  /*
1137  * FIXME: this zeroed fom is added by DTM0 team mates' request
1138  * to make the merge easier as there is a massive parallel work.
1139  * This fom is passed to m0_dtm0_req_post() to get sm_id without
1140  * checks and errors.
1141  * This fom must be and will be deleted in the next patch by
1142  * Ivan Alekhin.
1143  */
1144  struct m0_fom zero_fom_to_be_deleted = {};
1145  /* Extreme hack to convert index fid to component catalogue fid. */
1146  uint32_t sdev_idx = 10;
1147 
1149  m0_dtm0_clk_src_now(&dcs, &now);
1150 
1151  rc = m0_dtm0_tx_desc_init(&txr, 1);
1152  M0_UT_ASSERT(rc == 0);
1153 
1154  /*
1155  * Use zero fid here intentionally to skip triggering of the
1156  * pmsg send logic on the client side as we check REDOs only.
1157  */
1158  txr.dtd_ps.dtp_pa[0].p_fid = M0_FID0;
1159  txr.dtd_ps.dtp_pa[0].p_state = M0_DTPS_PERSISTENT;
1160  txr.dtd_id = (struct m0_dtm0_tid) {
1161  .dti_ts = now,
1162  .dti_fid = cli_dtm0_fid
1163  };
1164 
1165  m0_dix_fid_convert_dix2cctg(ifid, &cctg_fid, sdev_idx);
1166 
1167  dtm0_ut_cas_op_prepare(&cctg_fid, &cas_op, &cas_rec, key, val, &txr);
1168 
1170  &payload.b_addr, &payload.b_nob);
1171  M0_UT_ASSERT(rc == 0);
1172 
1173  req.dtr_txr = txr;
1174  req.dtr_payload = payload;
1175 
1176  rc = m0_fid_sscanf(ut_m0_config.mc_process_fid, &srv_proc_fid);
1177  M0_UT_ASSERT(rc == 0);
1179  &srv_proc_fid,
1180  M0_CST_DTM0, &srv_dtm0_fid);
1181  M0_UT_ASSERT(rc == 0);
1182 
1183  rc = m0_dtm0_req_post(dtm0, NULL, &req, &srv_dtm0_fid,
1184  &zero_fom_to_be_deleted, false);
1185  M0_UT_ASSERT(rc == 0);
1186 }
1187 
1188 static void dtm0_ut_read_and_check(uint64_t key, uint64_t val)
1189 {
1190  struct m0_idx *idx = &duc.duc_idx;
1191  struct m0_op *op = NULL;
1192  struct m0_bufvec keys;
1193  struct m0_bufvec vals;
1194  int rc;
1195  int *rcs;
1196 
1197  rcs = rcs_alloc(1);
1198  rc = m0_bufvec_alloc(&keys, 1, sizeof(uint64_t)) ?:
1199  m0_bufvec_empty_alloc(&vals, 1);
1200  M0_UT_ASSERT(rc == 0);
1201  *(uint64_t*)keys.ov_buf[0] = key;
1202  rc = m0_idx_op(idx, M0_IC_GET, &keys, &vals, rcs, 0, &op);
1203  M0_UT_ASSERT(rc == 0);
1204  m0_op_launch(&op, 1);
1206  M0_UT_ASSERT(rc == 0);
1207  M0_UT_ASSERT(rcs[0] == 0);
1208  M0_UT_ASSERT(vals.ov_vec.v_nr == 1);
1209  M0_UT_ASSERT(vals.ov_vec.v_count[0] == sizeof(val));
1210  M0_UT_ASSERT(vals.ov_buf[0] != NULL);
1211  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[0] == val);
1212  m0_bufvec_free(&keys);
1213  m0_bufvec_free(&vals);
1214  m0_op_fini(op);
1215  m0_free0(&op);
1216  m0_free0(&rcs);
1217 }
1218 
1219 static void st_dtm0_r(void)
1220 {
1221  m0_time_t rem;
1222  uint64_t key = 111;
1223  uint64_t val = 222;
1224 
1225  if (!ENABLE_DTM0)
1226  return;
1227 
1228  idx_setup();
1231 
1232  /* XXX dirty hack, but now we don't have completion notification */
1233  rem = 2ULL * M0_TIME_ONE_SECOND;
1234  while (rem != 0)
1235  m0_nanosleep(rem, &rem);
1236 
1238  idx_teardown();
1239 }
1240 
1242  .ts_name = "idx-dix-mt",
1243  .ts_owners = "Anatoliy",
1244  .ts_init = duc_setup,
1245  .ts_fini = duc_teardown,
1246  .ts_tests = {
1247  { "fom", st_mt, "Anatoliy" },
1248  { "lsf", st_lsfid, "Anatoliy" },
1249  { "lsfc", st_lsfid_cancel, "Vikram" },
1250  { "dtm0", st_dtm0, "Anatoliy" },
1251  { "dtm0_putdel", st_dtm0_putdel, "Ivan" },
1252  { "dtm0_e_then_s", st_dtm0_e_then_s, "Ivan" },
1253  { "dtm0_c", st_dtm0_c, "Ivan" },
1254  { "dtm0_r", st_dtm0_r, "Sergey" },
1255  { NULL, NULL }
1256  }
1257 };
1258 
1259 #undef M0_TRACE_SUBSYSTEM
1260 
1261 /*
1262  * Local variables:
1263  * c-indentation-style: "K&R"
1264  * c-basic-offset: 8
1265  * tab-width: 8
1266  * fill-column: 80
1267  * scroll-step: 1
1268  * End:
1269  */
1270 /*
1271  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
1272  */
static const char * srv_ep_addr
Definition: idx_dix.c:72
static void ut_dix_record_ops_dist_skip_layout_enable_crow(void)
Definition: idx_dix.c:785
#define M0_BUFVEC_INIT_BUF(addr_ptr, count_ptr)
Definition: vec.h:165
M0_INTERNAL int m0_dtm0_tx_desc_init(struct m0_dtm0_tx_desc *td, uint32_t nr_pa)
Definition: tx_desc.c:96
#define M0_UT_CONF_PROFILE
Definition: misc.h:43
static size_t nr
Definition: dump.c:1505
static void st_dtm0_r(void)
Definition: idx_dix.c:1219
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
Definition: client.h:841
#define m0_strdup(s)
Definition: string.h:43
struct m0_dix_ldesc kc_layout_ldesc
Definition: idx.h:195
int const char const void size_t int flags
Definition: dir.c:328
#define NULL
Definition: misc.h:38
m0_idx_opcode
Definition: client.h:550
static void exec_concurrent(uint64_t nr, enum m0_idx_opcode opcode)
Definition: idx_dix.c:1044
Definition: fop.h:50
static void ut_dix_namei_ops(bool dist, uint32_t flags)
Definition: idx_dix.c:305
const char * mc_process_fid
Definition: client.h:943
Definition: idx_mock.c:52
#define WAIT_TIMEOUT
Definition: idx_dix.c:47
static void ut_dix_namei_ops_dist_skip_layout_enable_crow(void)
Definition: idx_dix.c:428
static int ut_suite_mt_idx_dix_fini(void)
Definition: idx_dix.c:853
void m0_op_fini(struct m0_op *op)
Definition: client.c:848
static struct io_request req
Definition: file.c:100
uint64_t m0_time_t
Definition: time.h:37
char ** rsx_argv
Definition: rpclib.h:77
#define M0_LOG(level,...)
Definition: trace.h:167
uint8_t ft_id
Definition: fid.h:101
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
#define M0_FID_INIT(container, key)
Definition: fid.h:84
struct m0_fid duc_ifid
Definition: idx_dix.c:874
static void idx_dix_ut_fini()
Definition: idx_dix.c:154
static void ut_dix_record_ops(bool dist, uint32_t cr_get_flags, uint32_t put_del_flags)
Definition: idx_dix.c:449
struct m0_vec ov_vec
Definition: vec.h:147
static void ut_dix_record_ops_dist_skip_layout(void)
Definition: idx_dix.c:779
static void idx_teardown(void)
Definition: idx_dix.c:923
void m0_client_fini(struct m0_client *m0c, bool fini_m0)
Definition: client_init.c:1711
Definition: idx.h:70
static char * cas_startup_cmd[]
Definition: idx_dix.c:60
struct m0_dtm0_ts dti_ts
Definition: tx_desc.h:94
M0_INTERNAL const struct m0_fid_type m0_cas_index_fid_type
Definition: cas.c:159
static void ut_dix_namei_ops_cancel(bool dist)
Definition: idx_dix.c:203
#define M0_BITS(...)
Definition: misc.h:236
uint64_t m0_bcount_t
Definition: types.h:77
static void ut_dix_init_fini(void)
Definition: idx_dix.c:169
void m0_idx_fini(struct m0_idx *idx)
Definition: idx.c:644
M0_INTERNAL struct m0 * m0_get(void)
Definition: instance.c:41
#define M0_SRC_PATH(name)
Definition: misc.h:48
#define M0_SET0(obj)
Definition: misc.h:64
int m0_client_init(struct m0_client **m0c, struct m0_config *conf, bool init_m0)
Definition: client_init.c:1533
Definition: ut.h:77
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
struct m0_op_common oi_oc
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
static struct dtm0_ut_ctx duc
Definition: idx_dix.c:877
static void dix_config_fini()
Definition: idx_dix.c:101
void ** ov_buf
Definition: vec.h:149
static m0_bcount_t count
Definition: xcode.c:167
static void dtm0_ut_cas_op_prepare(const struct m0_fid *cfid, struct m0_cas_op *op, struct m0_cas_rec *rec, uint64_t *key, uint64_t *val, struct m0_dtm0_tx_desc *txr)
Definition: idx_dix.c:1085
struct m0_rpc_at_buf cr_val
Definition: cas.h:182
static void ut_dix_namei_ops_non_dist(void)
Definition: idx_dix.c:434
static void general_ifid_fill_batch(struct m0_fid *ifid, bool dist, int i)
Definition: idx_dix.c:198
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
int32_t m0_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: client.c:738
static struct m0_idx_dix_config ut_dix_config
Definition: idx_dix.c:52
uint32_t oi_flags
int m0_idx_op(struct m0_idx *idx, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals, int32_t *rcs, uint32_t flags, struct m0_op **op)
Definition: idx.c:555
op
Definition: libdemo.c:64
struct m0_dtm0_tid dtd_id
Definition: tx_desc.h:121
struct m0_ut_suite ut_suite_idx_dix
Definition: idx_dix.c:812
Definition: buf.h:37
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
static const char * local_ep_addr
Definition: idx_dix.c:71
struct m0_entity in_entity
Definition: client.h:842
static uint64_t dix_val(uint64_t i)
Definition: idx_dix.c:444
struct m0_rpc_at_buf cr_key
Definition: cas.h:172
int opcode
Definition: crate.c:301
int i
Definition: dir.c:1033
static void st_dtm0(void)
Definition: idx_dix.c:1049
#define PRIu64
Definition: types.h:58
static void ut_dix_record_ops_non_dist(void)
Definition: idx_dix.c:796
const char * mc_ha_addr
Definition: client.h:941
Definition: client.h:647
void * b_addr
Definition: buf.h:231
#define SERVER_LOG_FILE_NAME
Definition: idx_dix.c:48
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
#define M0_NET_XPRT_PREFIX_DEFAULT
Definition: net.h:98
#define ENABLE_DTM0
Definition: config.h:36
void st_mt(void)
Definition: mt_fom.c:511
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
#define m0_free0(pptr)
Definition: memory.h:77
static struct m0_config ut_m0_config
Definition: idx_dix.c:51
M0_INTERNAL const struct m0_fid_type m0_dix_fid_type
Definition: cas.c:169
m0_bcount_t b_nob
Definition: buf.h:38
#define M0_ASSERT(cond)
static void ut_dix_record_ops_dist(void)
Definition: idx_dix.c:791
M0_INTERNAL void m0_dtm0_clk_src_now(struct m0_dtm0_clk_src *cs, struct m0_dtm0_ts *now)
Definition: clk_src.c:71
struct m0_fid pver
Definition: idx_dix.c:74
void st_lsfid_cancel(void)
Definition: mt_fom.c:521
static void st_dtm0_c(void)
Definition: idx_dix.c:1077
struct m0_reqh m0c_reqh
static void dtm0_ut_send_redo(const struct m0_fid *ifid, uint64_t *key, uint64_t *val)
Definition: idx_dix.c:1121
bool mc_is_oostore
Definition: client.h:926
union m0_rpc_at_buf::@448 u
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:724
static void exec_then_stable(uint64_t nr, enum m0_idx_opcode opcode)
Definition: idx_dix.c:1029
int m0_net_xprt_nr(void)
Definition: net.c:168
struct m0_xcode_type * m0_cas_op_xc
Definition: cas_xc.c:17
M0_INTERNAL int m0_dix_ldesc_init(struct m0_dix_ldesc *ld, struct m0_ext *range, m0_bcount_t range_nr, enum m0_dix_hash_fnc_type htype, struct m0_fid *pver)
Definition: layout.c:171
M0_INTERNAL int m0_xcode_obj_enc_to_buf(struct m0_xcode_obj *obj, void **buf, m0_bcount_t *len)
Definition: xcode.c:832
static int * rcs_alloc(int count)
Definition: idx_dix.c:175
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
static struct m0_rpc_server_ctx dix_ut_sctx
Definition: idx_dix.c:76
struct m0_container duc_realm
Definition: idx_dix.c:873
uint32_t v_nr
Definition: vec.h:51
Definition: idx_dix.c:56
m0_bcount_t * v_count
Definition: vec.h:53
struct m0_fid p_fid
Definition: tx_desc.h:110
M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
Definition: fid.c:227
void m0_op_cancel(struct m0_op **op, uint32_t nr)
Definition: client.c:638
struct m0_ut_suite ut_suite_mt_idx_dix
Definition: idx_dix.c:1241
static void st_dtm0_putdel(void)
Definition: idx_dix.c:1056
static void idx_dix_ut_m0_client_init()
Definition: idx_dix.c:107
bool mc_is_read_verify
Definition: client.h:931
Definition: cas.h:376
void * mc_idx_service_conf
Definition: client.h:963
M0_INTERNAL void m0_dix_ldesc_fini(struct m0_dix_ldesc *ld)
Definition: layout.c:197
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
struct m0_dix_ldesc kc_ldescr_ldesc
Definition: idx.h:201
int m0_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:801
M0_INTERNAL int m0_conf_process2service_get(struct m0_confc *confc, const struct m0_fid *process_fid, enum m0_conf_service_type stype, struct m0_fid *sfid)
Definition: helpers.c:518
M0_INTERNAL int m0_dtm0_tx_desc_copy(const struct m0_dtm0_tx_desc *src, struct m0_dtm0_tx_desc *dst)
Definition: tx_desc.c:75
Definition: fom.h:481
const char * ts_name
Definition: ut.h:99
struct m0_dtm0_tx_pa * dtp_pa
Definition: tx_desc.h:117
static void st_dtm0_e_then_s(void)
Definition: idx_dix.c:1069
uint32_t mc_max_rpc_msg_size
Definition: client.h:955
int rsx_xprts_nr
Definition: rpclib.h:71
const char * mc_local_addr
Definition: client.h:939
int mc_idx_service_id
Definition: client.h:962
Definition: ext.h:37
Definition: fid.h:38
m0_bindex_t e_start
Definition: ext.h:39
#define M0_IS0(obj)
Definition: misc.h:70
static struct m0_realm realm
Definition: sync.c:87
M0_DTPS_PERSISTENT
Definition: tx_desc.h:171
static void ut_dix_record_ops_non_dist_no_dtm(void)
Definition: idx_dix.c:806
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
static int duc_setup(void)
Definition: idx_dix.c:880
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
struct m0_client * st_get_instance()
Definition: idx_dix.c:863
bool kc_create_meta
Definition: idx.h:189
void st_lsfid(void)
Definition: mt_fom.c:516
uint32_t mc_tm_recv_queue_min_len
Definition: client.h:950
static void idx_setup(void)
Definition: idx_dix.c:900
static uint64_t dix_key(uint64_t i)
Definition: idx_dix.c:439
static int duc_teardown(void)
Definition: idx_dix.c:941
static void run_m0ops(uint64_t nr, enum m0_idx_opcode opcode, uint64_t phase1wait, uint64_t phase2wait)
Definition: idx_dix.c:953
static void ut_dix_namei_ops_dist_skip_layout(void)
Definition: idx_dix.c:422
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
struct m0_dtm0_tx_participants dtd_ps
Definition: tx_desc.h:122
int m0_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:824
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
void m0_container_init(struct m0_container *con, struct m0_realm *parent, const struct m0_uint128 *id, struct m0_client *instance)
Definition: realm.c:31
const char * mc_profile
Definition: client.h:944
uint32_t en_flags
Definition: client.h:744
static struct m0_cas_op * cas_op(const struct m0_fom *fom)
Definition: service.c:1769
static void exec_one_by_one(uint64_t nr, enum m0_idx_opcode opcode)
Definition: idx_dix.c:1036
void m0_op_free(struct m0_op *op)
Definition: client.c:886
#define M0_FID0
Definition: fid.h:93
int m0_entity_open(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:885
static void ut_dix_namei_ops_cancel_dist(void)
Definition: idx_dix.c:295
static void dix_config_init()
Definition: idx_dix.c:82
static void ut_dix_record_ops_dist_no_dtm(void)
Definition: idx_dix.c:801
struct m0_fom_ops ops
Definition: io_foms.c:623
static struct m0_fid cli_dtm0_fid
Definition: idx_dix.c:878
static uint8_t ifid_type(bool dist)
Definition: idx_dix.c:188
struct m0_idx duc_idx
Definition: idx_dix.c:872
void m0_free(void *data)
Definition: memory.c:146
static struct m0_client * ut_m0c
Definition: idx_dix.c:50
static void ut_dix_namei_ops_cancel_non_dist(void)
Definition: idx_dix.c:300
M0_INTERNAL void m0_dtm0_clk_src_init(struct m0_dtm0_clk_src *cs, enum m0_dtm0_cs_types type)
Definition: clk_src.c:38
M0_INTERNAL void m0_dix_fid_convert_dix2cctg(const struct m0_fid *dix_fid, struct m0_fid *cctg_fid, uint32_t device_id)
Definition: fid_convert.c:54
static struct m0_fid ifid
Definition: service_ut.c:66
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
static int ut_suite_mt_idx_dix_init(void)
Definition: idx_dix.c:847
void m0_idx_init(struct m0_idx *idx, struct m0_realm *parent, const struct m0_uint128 *id)
Definition: idx.c:627
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_motr rsx_motr_ctx
Definition: rpclib.h:84
static void dtm0_ut_read_and_check(uint64_t key, uint64_t val)
Definition: idx_dix.c:1188
static const char * process_fid
Definition: idx_dix.c:73
static void general_ifid_fill(struct m0_fid *ifid, bool dist)
Definition: idx_dix.c:193
static void idx_dix_ut_init()
Definition: idx_dix.c:141
Definition: vec.h:145
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
static void ut_dix_namei_ops_dist(void)
Definition: idx_dix.c:417
const uint64_t payload[]
Definition: base.c:65
Definition: idx_mock.c:47
struct m0_dtm0_service * m0c_dtms
struct m0 * m0c_motr
int m0_nanosleep(const m0_time_t req, m0_time_t *rem)
Definition: ktime.c:73