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 flags)
450 {
451  struct m0_container realm;
452  struct m0_idx idx;
453  struct m0_fid ifid;
454  struct m0_op *op = NULL;
455  struct m0_bufvec keys;
456  struct m0_bufvec vals;
457  uint64_t i;
458  bool eof;
459  uint64_t accum;
460  uint64_t recs_nr;
461  uint64_t cur_key;
462  int rc;
463  int *rcs;
464  struct m0_op_common *oc;
465  struct m0_op_idx *oi;
466 
467  idx_dix_ut_init();
468  general_ifid_fill(&ifid, dist);
470  m0_idx_init(&idx, &realm.co_realm, (struct m0_uint128 *)&ifid);
473 
474  /* Create index. */
475  rc = m0_entity_create(NULL, &idx.in_entity, &op);
476  M0_UT_ASSERT(rc == 0);
477  oc = M0_AMB(oc, op, oc_op);
478  oi = M0_AMB(oi, oc, oi_oc);
479  oi->oi_flags = flags;
480  m0_op_launch(&op, 1);
482  M0_UT_ASSERT(rc == 0);
483  m0_op_fini(op);
484  m0_free0(&op);
485 
486  /* Get non-existing key. */
487  rcs = rcs_alloc(1);
488  rc = m0_bufvec_alloc(&keys, 1, sizeof(uint64_t)) ?:
489  m0_bufvec_empty_alloc(&vals, 1);
490  M0_UT_ASSERT(rc == 0);
491  *(uint64_t*)keys.ov_buf[0] = dix_key(10);
492  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, flags,
493  &op);
494  M0_UT_ASSERT(rc == 0);
495  m0_op_launch(&op, 1);
497  M0_UT_ASSERT(rc == 0);
498  M0_UT_ASSERT(vals.ov_buf[0] == NULL);
499  M0_UT_ASSERT(vals.ov_vec.v_count[0] == 0);
500  M0_UT_ASSERT(rcs[0] == -ENOENT);
501  m0_bufvec_free(&keys);
502  m0_bufvec_free(&vals);
503  m0_op_fini(op);
504  m0_free0(&op);
505  m0_free0(&rcs);
506 
507 
508  /* Add records to the index. */
509  rcs = rcs_alloc(CNT);
510  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
511  m0_bufvec_alloc(&vals, CNT, sizeof(uint64_t));
512  M0_UT_ASSERT(rc == 0);
513  for (i = 0; i < keys.ov_vec.v_nr; i++) {
514  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
515  *(uint64_t *)vals.ov_buf[i] = dix_val(i);
516  }
517  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs, 0,
518  &op);
519  M0_UT_ASSERT(rc == 0);
520  m0_op_launch(&op, 1);
522  M0_UT_ASSERT(rc == 0);
524  rcs[i] == 0 &&
525  *(uint64_t *)vals.ov_buf[i] == dix_val(i)));
526  m0_op_fini(op);
527  m0_free0(&op);
528  m0_free0(&rcs);
529 
530  /* Try to add recs again without OVERWRITE flag. */
531  rcs = rcs_alloc(CNT);
532  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs, 0,
533  &op);
534  M0_UT_ASSERT(rc == 0);
535  m0_op_launch(&op, 1);
537  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
538  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == -EEXIST));
539  m0_op_fini(op);
540  m0_free0(&op);
541  m0_free0(&rcs);
542 
543  /* Try to add recs again with OVERWRITE flag. */
544  rcs = rcs_alloc(CNT);
545  for (i = 0; i < keys.ov_vec.v_nr; i++)
546  *(uint64_t *)vals.ov_buf[i] = dix_val(i * 10);
547 
548  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs,
549  M0_OIF_OVERWRITE, &op);
550  M0_UT_ASSERT(rc == 0);
551  m0_op_launch(&op, 1);
553  M0_UT_ASSERT(rc == 0);
554  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
555  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
556  m0_op_fini(op);
557  m0_free0(&op);
558  m0_free0(&rcs);
559 
560  m0_bufvec_free(&keys);
561  m0_bufvec_free(&vals);
562 
563  /* Get records from the index by keys. */
564  rcs = rcs_alloc(CNT);
565  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
566  m0_bufvec_empty_alloc(&vals, CNT);
567  M0_UT_ASSERT(rc == 0);
568  for (i = 0; i < keys.ov_vec.v_nr; i++)
569  *(uint64_t*)keys.ov_buf[i] = dix_key(i);
570  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, 0,
571  &op);
572  M0_UT_ASSERT(rc == 0);
573  m0_op_launch(&op, 1);
575  M0_UT_ASSERT(rc == 0);
577  rcs[i] == 0 &&
578  *(uint64_t *)vals.ov_buf[i] == dix_val(i * 10)));
579  m0_bufvec_free(&keys);
580  m0_bufvec_free(&vals);
581  m0_op_fini(op);
582  m0_free0(&op);
583  m0_free0(&rcs);
584 
585  /* Get records with all existing keys, except the one. */
586  rcs = rcs_alloc(CNT);
587  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
588  m0_bufvec_empty_alloc(&vals, CNT);
589  M0_UT_ASSERT(rc == 0);
590  for (i = 0; i < keys.ov_vec.v_nr; i++)
591  *(uint64_t*)keys.ov_buf[i] = dix_key(i);
592  *(uint64_t *)keys.ov_buf[5] = dix_key(999);
593  rc = m0_idx_op(&idx, M0_IC_GET, &keys, &vals, rcs, 0,
594  &op);
595  M0_UT_ASSERT(rc == 0);
596  m0_op_launch(&op, 1);
598  M0_UT_ASSERT(rc == 0);
599  for (i = 0; i < CNT; i++) {
600  if (i != 5) {
601  M0_UT_ASSERT(rcs[i] == 0);
602  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[i] ==
603  dix_val(i * 10));
604  } else {
605  M0_UT_ASSERT(rcs[i] == -ENOENT);
606  M0_UT_ASSERT(vals.ov_buf[5] == NULL);
607  }
608  }
609  m0_bufvec_free(&keys);
610  m0_bufvec_free(&vals);
611  m0_op_fini(op);
612  m0_free0(&op);
613  m0_free0(&rcs);
614 
615  /* Iterate over all records in the index. */
616  rcs = rcs_alloc(CNT + 1);
617  rc = m0_bufvec_empty_alloc(&keys, CNT + 1) ?:
618  m0_bufvec_empty_alloc(&vals, CNT + 1);
619  M0_UT_ASSERT(rc == 0);
620  cur_key = dix_key(0);
621  keys.ov_buf[0] = &cur_key;
622  keys.ov_vec.v_count[0] = sizeof(uint64_t);
623  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals, rcs, 0, &op);
624  M0_UT_ASSERT(rc == 0);
625  m0_op_launch(&op, 1);
627  M0_UT_ASSERT(rc == 0);
629  rcs[i] == 0 &&
630  *(uint64_t*)keys.ov_buf[i] == dix_key(i) &&
631  *(uint64_t*)vals.ov_buf[i] == dix_val(i * 10)));
632  M0_UT_ASSERT(rcs[CNT] == -ENOENT);
633  M0_UT_ASSERT(keys.ov_buf[CNT] == NULL);
634  M0_UT_ASSERT(vals.ov_buf[CNT] == NULL);
635  m0_bufvec_free(&keys);
636  m0_bufvec_free(&vals);
637  m0_op_fini(op);
638  m0_free0(&op);
639  m0_free0(&rcs);
640 
641  /* Iterate over all records in the index excluding the start key. */
642  rcs = rcs_alloc(CNT + 1);
643  rc = m0_bufvec_empty_alloc(&keys, CNT + 1) ?:
644  m0_bufvec_empty_alloc(&vals, CNT + 1);
645  M0_UT_ASSERT(rc == 0);
646  cur_key = dix_key(0);
647  keys.ov_buf[0] = &cur_key;
648  keys.ov_vec.v_count[0] = sizeof(uint64_t);
649  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals, rcs,
651  M0_UT_ASSERT(rc == 0);
652  m0_op_launch(&op, 1);
654  M0_UT_ASSERT(rc == 0);
656  rcs[i] == 0 &&
657  *(uint64_t*)keys.ov_buf[i] == dix_key(i + 1) &&
658  *(uint64_t*)vals.ov_buf[i] ==
659  dix_val((i + 1) * 10)));
660  M0_UT_ASSERT(rcs[CNT - 1] == -ENOENT);
661  M0_UT_ASSERT(keys.ov_buf[CNT - 1] == NULL);
662  M0_UT_ASSERT(vals.ov_buf[CNT - 1] == NULL);
663  m0_bufvec_free(&keys);
664  m0_bufvec_free(&vals);
665  m0_op_fini(op);
666  m0_free0(&op);
667  m0_free0(&rcs);
668 
669  /* Try to add recs again with OVERWRITE flag. */
670  rcs = rcs_alloc(CNT + 1);
671  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t)) ?:
672  m0_bufvec_alloc(&vals, CNT, sizeof(uint64_t));
673  M0_UT_ASSERT(rc == 0);
674  for (i = 0; i < keys.ov_vec.v_nr; i++) {
675  *(uint64_t *)vals.ov_buf[i] = dix_val(i);
676  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
677  }
678 
679  rc = m0_idx_op(&idx, M0_IC_PUT, &keys, &vals, rcs,
680  M0_OIF_OVERWRITE, &op);
681  M0_UT_ASSERT(rc == 0);
682  m0_op_launch(&op, 1);
684  M0_UT_ASSERT(rc == 0);
685  M0_UT_ASSERT(op->op_sm.sm_rc == 0);
686  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
687  m0_op_fini(op);
688  m0_free0(&op);
689  m0_free0(&rcs);
690  m0_bufvec_free(&vals);
691  m0_bufvec_free(&keys);
692  /*
693  * Iterate over all records in the index, starting from the beginning
694  * and requesting two records at a time.
695  */
696  accum = 0;
697  cur_key = 0;
698  do {
699  rcs = rcs_alloc(2);
700  rc = m0_bufvec_empty_alloc(&keys, 2) ?:
701  m0_bufvec_empty_alloc(&vals, 2);
702  M0_UT_ASSERT(rc == 0);
703  if (cur_key != 0) {
704  keys.ov_buf[0] = &cur_key;
705  keys.ov_vec.v_count[0] = sizeof(uint64_t);
706  } else {
707  /*
708  * Pass NULL in order to request records starting from
709  * the smallest key.
710  */
711  keys.ov_buf[0] = NULL;
712  keys.ov_vec.v_count[0] = 0;
713  }
714  rc = m0_idx_op(&idx, M0_IC_NEXT, &keys, &vals,
715  rcs, 0, &op);
716  M0_UT_ASSERT(rc == 0);
717  m0_op_launch(&op, 1);
719  WAIT_TIMEOUT);
720  M0_UT_ASSERT(rc == 0);
721  for (i = 0; i < vals.ov_vec.v_nr && rcs[i] == 0; i++)
722  ;
723  recs_nr = i;
724  eof = recs_nr < keys.ov_vec.v_nr;
725  for (i = 0; i < recs_nr; i++) {
726  M0_UT_ASSERT(*(uint64_t *)keys.ov_buf[i] ==
727  dix_key(accum + i));
728  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[i] ==
729  dix_val(accum + i));
730  cur_key = *(uint64_t *)keys.ov_buf[i];
731  }
732  m0_bufvec_free(&keys);
733  m0_bufvec_free(&vals);
734  m0_op_fini(op);
735  m0_free0(&op);
736  m0_free0(&rcs);
737  /*
738  * Starting key is also included in returned number of records,
739  * so extract 1. The only exception is the first request, when
740  * starting key is unknown. It is accounted before accum check
741  * after eof is reached.
742  */
743  accum += recs_nr - 1;
744  } while (!eof);
745  accum++;
746  M0_UT_ASSERT(accum == CNT);
747 
748  /* Remove the records from the index. */
749  rcs = rcs_alloc(CNT);
750  rc = m0_bufvec_alloc(&keys, CNT, sizeof(uint64_t));
751  M0_UT_ASSERT(rc == 0);
752  for (i = 0; i < keys.ov_vec.v_nr; i++)
753  *(uint64_t *)keys.ov_buf[i] = dix_key(i);
754  rc = m0_idx_op(&idx, M0_IC_DEL, &keys, NULL, rcs, 0, &op);
755  M0_UT_ASSERT(rc == 0);
756  m0_op_launch(&op, 1);
758  M0_UT_ASSERT(rc == 0);
759  M0_UT_ASSERT(m0_forall(i, CNT, rcs[i] == 0));
760  m0_bufvec_free(&keys);
761  m0_op_fini(op);
762  m0_free0(&op);
763  m0_free0(&rcs);
764 
765  /* Remove the index. */
766  rc = m0_entity_delete(&idx.in_entity, &op);
767  M0_UT_ASSERT(rc == 0);
768  m0_op_launch(&op, 1);
770  M0_UT_ASSERT(rc == 0);
771  m0_op_fini(op);
772  m0_free0(&op);
773 
774  m0_idx_fini(&idx);
775  idx_dix_ut_fini();
776 }
777 
779 {
780  uint32_t flags = M0_OIF_SKIP_LAYOUT;
781  ut_dix_record_ops(true, flags);
782 }
783 
785 {
786  uint32_t flags = M0_OIF_SKIP_LAYOUT | M0_OIF_CROW;
787  ut_dix_record_ops(true, flags);
788 }
789 
790 static void ut_dix_record_ops_dist(void)
791 {
792  ut_dix_record_ops(true, 0);
793 }
794 
795 static void ut_dix_record_ops_non_dist(void)
796 {
797  ut_dix_record_ops(false, 0);
798 }
799 
801  .ts_name = "idx-dix",
802  .ts_owners = "Egor",
803  .ts_init = NULL,
804  .ts_fini = NULL,
805  .ts_tests = {
806  { "init-fini", ut_dix_init_fini, "Egor" },
807  { "namei-ops-dist", ut_dix_namei_ops_dist, "Egor" },
808  { "namei-ops-non-dist", ut_dix_namei_ops_non_dist, "Egor" },
809  { "record-ops-dist", ut_dix_record_ops_dist, "Egor" },
810  { "record-ops-non-dist", ut_dix_record_ops_non_dist, "Egor" },
811  { "namei-ops-cancel-dist", ut_dix_namei_ops_cancel_dist,
812  "Vikram" },
813  { "namei-ops-cancel-non-dist", ut_dix_namei_ops_cancel_non_dist,
814  "Vikram" },
815  { "namei-ops-dist-skip-layout",
817  "Venky" },
818  { "record-ops-dist-skip-layout",
820  "Venky" },
821  { "namei-ops-dist-skip-layout-enable-crow",
823  "Venky" },
824  { "record-ops-dist-skip-layout-enable-crow",
826  "Venky" },
827  { NULL, NULL }
828  }
829 };
830 
831 static int ut_suite_mt_idx_dix_init(void)
832 {
833  idx_dix_ut_init();
834  return 0;
835 }
836 
837 static int ut_suite_mt_idx_dix_fini(void)
838 {
839  idx_dix_ut_fini();
840  return 0;
841 }
842 
843 extern void st_mt(void);
844 extern void st_lsfid(void);
845 extern void st_lsfid_cancel(void);
846 
848 {
849  return ut_m0c;
850 }
851 
852 #include "dtm0/helper.h"
853 #include "dtm0/service.h"
854 
855 struct dtm0_ut_ctx {
856  struct m0_idx duc_idx;
858  struct m0_fid duc_ifid;
859 };
860 
861 static struct dtm0_ut_ctx duc = {};
862 static struct m0_fid cli_dtm0_fid = M0_FID_INIT(0x7300000000000001, 0x1a);
863 
864 static int duc_setup(void)
865 {
866  int rc;
867  struct m0_container *realm = &duc.duc_realm;
868 
869  m0_fi_enable("m0_dtm0_in_ut", "ut");
871  M0_UT_ASSERT(rc == 0);
872 
874 
875  if (ENABLE_DTM0) {
877  }
878 
880 
881  return 0;
882 }
883 
884 static void idx_setup(void)
885 {
886  struct m0_op *op = NULL;
887  struct m0_idx *idx = &duc.duc_idx;
888  struct m0_container *realm = &duc.duc_realm;
889  int rc;
890  struct m0_fid *ifid = &duc.duc_ifid;
891 
892  m0_idx_init(idx, &realm->co_realm, (struct m0_uint128 *) ifid);
893 
894  /* Create the index */
895  rc = m0_entity_create(NULL, &idx->in_entity, &op);
896  M0_UT_ASSERT(rc == 0);
897  m0_op_launch(&op, 1);
899  M0_UT_ASSERT(rc == 0);
900  m0_op_fini(op);
901  m0_op_free(op);
902  op = NULL;
903 }
904 
905 static void idx_teardown(void)
906 {
907  struct m0_op *op = NULL;
908  int rc;
909 
910  /* Delete the index */
912  M0_UT_ASSERT(rc == 0);
913  m0_op_launch(&op, 1);
915  M0_UT_ASSERT(rc == 0);
916  m0_op_fini(op);
917  m0_op_free(op);
919  M0_SET0(&duc.duc_idx);
920 }
921 
922 
923 static int duc_teardown(void)
924 {
925  int rc;
926 
928  m0_fi_disable("m0_dtm0_in_ut", "ut");
929  return rc;
930 }
931 
932 /* Submits multiple M0 client (PUT|DEL) operations and then waits on "phase1"
933  * states, and then waits on "phase2" states.
934  */
935 static void run_m0ops(uint64_t nr, enum m0_idx_opcode opcode,
936  uint64_t phase1wait,
937  uint64_t phase2wait)
938 {
939  struct m0_idx *idx = &duc.duc_idx;
940  struct m0_op **ops;
941  int *rcs;
942  struct m0_bufvec *key_vecs;
943  char *val = NULL;
944  struct m0_bufvec vals = {};
945  m0_bcount_t len = 1;
946  int flags = 0;
947  uint64_t i;
948  int rc;
949 
950  M0_PRE(M0_IN(opcode, (M0_IC_PUT, M0_IC_DEL)));
951  M0_ALLOC_ARR(ops, nr);
952  M0_UT_ASSERT(ops != NULL);
953  M0_ALLOC_ARR(rcs, nr);
954  M0_UT_ASSERT(rcs != NULL);
955  M0_ALLOC_ARR(key_vecs, nr);
956  M0_UT_ASSERT(key_vecs != NULL);
957 
958  if (opcode == M0_IC_PUT) {
959  val = m0_strdup("ItIsAValue");
960  M0_UT_ASSERT(val != NULL);
961  vals = M0_BUFVEC_INIT_BUF((void **) &val, &len);
962  }
963 
964  /* Execute the ops */
965  for (i = 0; i < nr; ++i) {
966  rc = m0_bufvec_alloc(&key_vecs[i], 1, sizeof(i));
967  M0_UT_ASSERT(rc == 0);
968  M0_UT_ASSERT(key_vecs[i].ov_vec.v_count[0] == sizeof(i));
969  memcpy(key_vecs[i].ov_buf[0], &i, sizeof(i));
970 
971  rc = m0_idx_op(idx, opcode, &key_vecs[i],
972  opcode == M0_IC_DEL ? NULL : &vals,
973  &rcs[i], flags, &ops[i]);
974  M0_UT_ASSERT(rc == 0);
975  m0_op_launch(&ops[i], 1);
976 
977  if (phase1wait != 0)
978  rc = m0_op_wait(ops[i], phase1wait, WAIT_TIMEOUT);
979  else
980  rc = 0;
981  M0_LOG(M0_DEBUG, "Got phase1 %" PRIu64, i);
982  if (rc == -ESRCH)
983  M0_UT_ASSERT(ops[i]->op_sm.sm_state == M0_OS_STABLE);
984  }
985 
986  /* Wait until they get stable */
987  for (i = 0; i < nr; ++i) {
988  if (phase2wait != 0)
989  rc = m0_op_wait(ops[i], phase2wait, WAIT_TIMEOUT);
990  else
991  rc = 0;
992  M0_LOG(M0_DEBUG, "Got phase2 %" PRIu64, i);
993  M0_UT_ASSERT(rc == 0);
994  M0_UT_ASSERT(ops[i]->op_rc == 0);
995  M0_UT_ASSERT(rcs[0] == 0);
996  m0_op_fini(ops[i]);
997  m0_op_free(ops[i]);
998  ops[i] = NULL;
999  m0_bufvec_free(&key_vecs[i]);
1000  }
1001 
1003  m0_free(key_vecs);
1004  m0_free(ops);
1005  m0_free(val);
1006 }
1007 
1011 static void exec_then_stable(uint64_t nr, enum m0_idx_opcode opcode)
1012 {
1014 }
1015 
1018 static void exec_one_by_one(uint64_t nr, enum m0_idx_opcode opcode)
1019 {
1021 }
1022 
1026 static void exec_concurrent(uint64_t nr, enum m0_idx_opcode opcode)
1027 {
1029 }
1030 
1031 static void st_dtm0(void)
1032 {
1033  idx_setup();
1035  idx_teardown();
1036 }
1037 
1038 static void st_dtm0_putdel(void)
1039 {
1040  idx_setup();
1043  idx_teardown();
1044 
1045  idx_setup();
1046  exec_one_by_one(100, M0_IC_PUT);
1047  exec_one_by_one(100, M0_IC_DEL);
1048  idx_teardown();
1049 }
1050 
1051 static void st_dtm0_e_then_s(void)
1052 {
1053  idx_setup();
1056  idx_teardown();
1057 }
1058 
1059 static void st_dtm0_c(void)
1060 {
1061  idx_setup();
1062  exec_concurrent(100, M0_IC_PUT);
1063  exec_concurrent(100, M0_IC_DEL);
1064  idx_teardown();
1065 }
1066 
1067 static void dtm0_ut_cas_op_prepare(const struct m0_fid *cfid,
1068  struct m0_cas_op *op,
1069  struct m0_cas_rec *rec,
1070  uint64_t *key,
1071  uint64_t *val,
1072  struct m0_dtm0_tx_desc *txr)
1073 {
1074  int rc;
1075  struct m0_buf buf_key = { .b_nob = sizeof(uint64_t),
1076  .b_addr = key };
1077  struct m0_buf buf_val = { .b_nob = sizeof(uint64_t),
1078  .b_addr = val };
1079  struct m0_rpc_at_buf at_buf_key = { .u.ab_buf = buf_key,
1080  .ab_type = M0_RPC_AT_INLINE };
1081  struct m0_rpc_at_buf at_buf_val = { .u.ab_buf = buf_val,
1082  .ab_type = M0_RPC_AT_INLINE };
1083 
1084  rec->cr_key = at_buf_key;
1085  rec->cr_val = at_buf_val;
1086 
1087  op->cg_id.ci_layout.dl_type = DIX_LTYPE_DESCR;
1088  rc = m0_dix_ldesc_init(&op->cg_id.ci_layout.u.dl_desc,
1089  &(struct m0_ext) { .e_start = 0,
1090  .e_end = IMASK_INF }, 1, HASH_FNC_CITY,
1091  &pver);
1092  M0_UT_ASSERT(rc == 0);
1093 
1094  op->cg_id.ci_fid = *cfid;
1095  op->cg_rec.cr_nr = 1;
1096  op->cg_rec.cr_rec = rec;
1097  if (txr != NULL) {
1098  rc = m0_dtm0_tx_desc_copy(txr, &op->cg_txd);
1099  M0_UT_ASSERT(rc == 0);
1100  }
1101 }
1102 
1103 static void dtm0_ut_send_redo(const struct m0_fid *ifid,
1104  uint64_t *key, uint64_t *val)
1105 {
1106  int rc;
1107  struct dtm0_req_fop req = { .dtr_msg = DTM_REDO };
1108  struct m0_dtm0_tx_desc txr = {};
1109  struct m0_dtm0_clk_src dcs;
1110  struct m0_dtm0_ts now;
1111  struct m0_dtm0_service *dtm0 = ut_m0c->m0c_dtms;
1112  struct m0_buf payload;
1113  struct m0_cas_op cas_op = {};
1114  struct m0_cas_rec cas_rec = {};
1115  struct m0_fid srv_dtm0_fid;
1116  struct m0_fid srv_proc_fid;
1117  struct m0_fid cctg_fid;
1118  /*
1119  * FIXME: this zeroed fom is added by DTM0 team mates' request
1120  * to make the merge easier as there is a massive parallel work.
1121  * This fom is passed to m0_dtm0_req_post() to get sm_id without
1122  * checks and errors.
1123  * This fom must be and will be deleted in the next patch by
1124  * Ivan Alekhin.
1125  */
1126  struct m0_fom zero_fom_to_be_deleted = {};
1127  /* Extreme hack to convert index fid to component catalogue fid. */
1128  uint32_t sdev_idx = 10;
1129 
1131  m0_dtm0_clk_src_now(&dcs, &now);
1132 
1133  rc = m0_dtm0_tx_desc_init(&txr, 1);
1134  M0_UT_ASSERT(rc == 0);
1135 
1136  /*
1137  * Use zero fid here intentionally to skip triggering of the
1138  * pmsg send logic on the client side as we check REDOs only.
1139  */
1140  txr.dtd_ps.dtp_pa[0].p_fid = M0_FID0;
1141  txr.dtd_ps.dtp_pa[0].p_state = M0_DTPS_PERSISTENT;
1142  txr.dtd_id = (struct m0_dtm0_tid) {
1143  .dti_ts = now,
1144  .dti_fid = cli_dtm0_fid
1145  };
1146 
1147  m0_dix_fid_convert_dix2cctg(ifid, &cctg_fid, sdev_idx);
1148 
1149  dtm0_ut_cas_op_prepare(&cctg_fid, &cas_op, &cas_rec, key, val, &txr);
1150 
1151  rc = m0_xcode_obj_enc_to_buf(&M0_XCODE_OBJ(m0_cas_op_xc, &cas_op),
1152  &payload.b_addr, &payload.b_nob);
1153  M0_UT_ASSERT(rc == 0);
1154 
1155  req.dtr_txr = txr;
1156  req.dtr_payload = payload;
1157 
1158  rc = m0_fid_sscanf(ut_m0_config.mc_process_fid, &srv_proc_fid);
1159  M0_UT_ASSERT(rc == 0);
1161  &srv_proc_fid,
1162  M0_CST_DTM0, &srv_dtm0_fid);
1163  M0_UT_ASSERT(rc == 0);
1164 
1165  rc = m0_dtm0_req_post(dtm0, NULL, &req, &srv_dtm0_fid,
1166  &zero_fom_to_be_deleted, false);
1167  M0_UT_ASSERT(rc == 0);
1168 }
1169 
1170 static void dtm0_ut_read_and_check(uint64_t key, uint64_t val)
1171 {
1172  struct m0_idx *idx = &duc.duc_idx;
1173  struct m0_op *op = NULL;
1174  struct m0_bufvec keys;
1175  struct m0_bufvec vals;
1176  int rc;
1177  int *rcs;
1178 
1179  rcs = rcs_alloc(1);
1180  rc = m0_bufvec_alloc(&keys, 1, sizeof(uint64_t)) ?:
1181  m0_bufvec_empty_alloc(&vals, 1);
1182  M0_UT_ASSERT(rc == 0);
1183  *(uint64_t*)keys.ov_buf[0] = key;
1184  rc = m0_idx_op(idx, M0_IC_GET, &keys, &vals, rcs, 0, &op);
1185  M0_UT_ASSERT(rc == 0);
1186  m0_op_launch(&op, 1);
1188  M0_UT_ASSERT(rc == 0);
1189  M0_UT_ASSERT(rcs[0] == 0);
1190  M0_UT_ASSERT(vals.ov_vec.v_nr == 1);
1191  M0_UT_ASSERT(vals.ov_vec.v_count[0] == sizeof(val));
1192  M0_UT_ASSERT(vals.ov_buf[0] != NULL);
1193  M0_UT_ASSERT(*(uint64_t *)vals.ov_buf[0] == val);
1194  m0_bufvec_free(&keys);
1195  m0_bufvec_free(&vals);
1196  m0_op_fini(op);
1197  m0_free0(&op);
1198  m0_free0(&rcs);
1199 }
1200 
1201 static void st_dtm0_r(void)
1202 {
1203  m0_time_t rem;
1204  uint64_t key = 111;
1205  uint64_t val = 222;
1206 
1207  if (!ENABLE_DTM0)
1208  return;
1209 
1210  idx_setup();
1213 
1214  /* XXX dirty hack, but now we don't have completion notification */
1215  rem = 2ULL * M0_TIME_ONE_SECOND;
1216  while (rem != 0)
1217  m0_nanosleep(rem, &rem);
1218 
1220  idx_teardown();
1221 }
1222 
1224  .ts_name = "idx-dix-mt",
1225  .ts_owners = "Anatoliy",
1226  .ts_init = duc_setup,
1227  .ts_fini = duc_teardown,
1228  .ts_tests = {
1229  { "fom", st_mt, "Anatoliy" },
1230  { "lsf", st_lsfid, "Anatoliy" },
1231  { "lsfc", st_lsfid_cancel, "Vikram" },
1232  { "dtm0", st_dtm0, "Anatoliy" },
1233  { "dtm0_putdel", st_dtm0_putdel, "Ivan" },
1234  { "dtm0_e_then_s", st_dtm0_e_then_s, "Ivan" },
1235  { "dtm0_c", st_dtm0_c, "Ivan" },
1236  { "dtm0_r", st_dtm0_r, "Sergey" },
1237  { NULL, NULL }
1238  }
1239 };
1240 
1241 #undef M0_TRACE_SUBSYSTEM
1242 
1243 /*
1244  * Local variables:
1245  * c-indentation-style: "K&R"
1246  * c-basic-offset: 8
1247  * tab-width: 8
1248  * fill-column: 80
1249  * scroll-step: 1
1250  * End:
1251  */
1252 /*
1253  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
1254  */
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:784
#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:97
#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:1201
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
Definition: client.h:835
#define m0_strdup(s)
Definition: string.h:43
struct m0_dix_ldesc kc_layout_ldesc
Definition: idx.h:189
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:1026
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:937
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:837
void m0_op_fini(struct m0_op *op)
Definition: client.c:847
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:858
static void idx_dix_ut_fini()
Definition: idx_dix.c:154
struct m0_vec ov_vec
Definition: vec.h:147
static void ut_dix_record_ops_dist_skip_layout(void)
Definition: idx_dix.c:778
static void idx_teardown(void)
Definition: idx_dix.c:905
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:158
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:643
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:861
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:1067
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:739
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:554
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:800
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:836
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:1031
#define PRIu64
Definition: types.h:58
static void ut_dix_record_ops_non_dist(void)
Definition: idx_dix.c:795
const char * mc_ha_addr
Definition: client.h:935
Definition: client.h:641
static void ut_dix_record_ops(bool dist, uint32_t flags)
Definition: idx_dix.c:449
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:168
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:790
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:1059
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:1103
bool mc_is_oostore
Definition: client.h:920
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:725
static void exec_then_stable(uint64_t nr, enum m0_idx_opcode opcode)
Definition: idx_dix.c:1011
int m0_net_xprt_nr(void)
Definition: net.c:168
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:857
union m0_rpc_at_buf::@447 u
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:639
struct m0_ut_suite ut_suite_mt_idx_dix
Definition: idx_dix.c:1223
static void st_dtm0_putdel(void)
Definition: idx_dix.c:1038
static void idx_dix_ut_m0_client_init()
Definition: idx_dix.c:107
bool mc_is_read_verify
Definition: client.h:925
Definition: cas.h:372
void * mc_idx_service_conf
Definition: client.h:957
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:195
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:76
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:1051
uint32_t mc_max_rpc_msg_size
Definition: client.h:949
int rsx_xprts_nr
Definition: rpclib.h:71
const char * mc_local_addr
Definition: client.h:933
int mc_idx_service_id
Definition: client.h:956
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:164
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
static int duc_setup(void)
Definition: idx_dix.c:864
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
struct m0_client * st_get_instance()
Definition: idx_dix.c:847
bool kc_create_meta
Definition: idx.h:183
void st_lsfid(void)
Definition: mt_fom.c:516
uint32_t mc_tm_recv_queue_min_len
Definition: client.h:944
static void idx_setup(void)
Definition: idx_dix.c:884
static uint64_t dix_key(uint64_t i)
Definition: idx_dix.c:439
static int duc_teardown(void)
Definition: idx_dix.c:923
static void run_m0ops(uint64_t nr, enum m0_idx_opcode opcode, uint64_t phase1wait, uint64_t phase2wait)
Definition: idx_dix.c:935
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:938
uint32_t en_flags
Definition: client.h:738
static struct m0_cas_op * cas_op(const struct m0_fom *fom)
Definition: service.c:1761
static void exec_one_by_one(uint64_t nr, enum m0_idx_opcode opcode)
Definition: idx_dix.c:1018
void m0_op_free(struct m0_op *op)
Definition: client.c:885
#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
struct m0_fom_ops ops
Definition: io_foms.c:623
static struct m0_fid cli_dtm0_fid
Definition: idx_dix.c:862
static uint8_t ifid_type(bool dist)
Definition: idx_dix.c:188
struct m0_idx duc_idx
Definition: idx_dix.c:856
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:831
void m0_idx_init(struct m0_idx *idx, struct m0_realm *parent, const struct m0_uint128 *id)
Definition: idx.c:626
#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:1170
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