Motr  M0
service_ut.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2016-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 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CAS
31 
32 #include "ut/ut.h"
33 #include "lib/misc.h" /* M0_SET0 */
34 #include "lib/finject.h"
35 #include "lib/semaphore.h"
36 #include "lib/byteorder.h"
37 #include "fop/fop.h"
38 #include "reqh/reqh.h"
39 #include "reqh/reqh_service.h"
40 #include "be/ut/helper.h" /* m0_be_ut_backend */
41 
42 #include "cas/cas.h"
43 #include "cas/cas_xc.h"
44 #include "rpc/at.h"
45 #include "fdmi/fdmi.h"
46 #include "rpc/rpc_machine.h"
47 
48 #define IFID(x, y) M0_FID_TINIT('i', (x), (y))
49 #define TFID(x, y) M0_FID_TINIT('T', (x), (y))
50 
51 enum { N = 4096 };
52 
53 struct meta_rec {
54  struct m0_cas_id cid;
55  uint64_t rc;
56 };
57 
58 static struct m0_reqh reqh;
59 static struct m0_be_ut_backend be;
60 static struct m0_be_seg *seg0;
61 static struct m0_reqh_service *cas;
62 static struct m0_reqh_service *fdmi;
64 static struct m0_cas_rep rep;
65 static struct m0_cas_rec repv[N];
66 static struct m0_fid ifid = IFID(2, 3);
67 static bool mt;
68 
69 extern void (*cas__ut_cb_done)(struct m0_fom *fom);
70 extern void (*cas__ut_cb_fini)(struct m0_fom *fom);
71 
72 static void cb_done(struct m0_fom *fom);
73 static void cb_fini(struct m0_fom *fom);
74 
75 static int cid_enc(struct m0_cas_id *cid, struct m0_rpc_at_buf *at_buf)
76 {
77  int rc;
78  struct m0_buf buf;
79 
80  M0_PRE(cid != NULL);
81  M0_PRE(at_buf != NULL);
82 
83  m0_rpc_at_init(at_buf);
84  rc = m0_xcode_obj_enc_to_buf(&M0_XCODE_OBJ(m0_cas_id_xc, cid),
85  &buf.b_addr, &buf.b_nob);
86  M0_UT_ASSERT(rc == 0);
87 
88  at_buf->ab_type = M0_RPC_AT_INLINE;
89  at_buf->u.ab_buf = buf;
90  return rc;
91 }
92 
93 static void rep_clear(void)
94 {
95  int i;
96 
97  rep.cgr_rc = -EINVAL;
98  rep.cgr_rep.cr_nr = 0;
100  for (i = 0; i < ARRAY_SIZE(repv); ++i) {
103  repv[i].cr_rc = -EINVAL;
104  }
105 }
106 
107 static int at_inline_fill(struct m0_rpc_at_buf *dst, struct m0_rpc_at_buf *src)
108 {
109  dst->ab_type = src->ab_type;
110  dst->u.ab_buf = M0_BUF_INIT0;
111  return m0_buf_copy(&dst->u.ab_buf, &src->u.ab_buf);
112 }
113 
114 static void reqh_init(bool mkfs, bool use_small_credits)
115 {
116  struct m0_be_domain_cfg cfg = {};
117  int result;
118 
119  M0_SET0(&reqh);
120  M0_SET0(&be);
121  m0_fi_enable("cas_in_ut", "ut");
123  result = M0_REQH_INIT(&reqh,
124  .rhia_db = seg0,
125  .rhia_mdstore = (void *)1,
126  .rhia_fid = &g_process_fid);
127  M0_UT_ASSERT(result == 0);
130  if (use_small_credits || m0_ut_small_credits())
132  M0_BE_TX_CREDIT(6 << 10, 5 << 18);
133  result = m0_be_ut_backend_init_cfg(&be, &cfg, mkfs);
134  M0_ASSERT(result == 0);
135 }
136 
137 static void _init(bool mkfs, bool use_small_credits)
138 {
139  int result;
140 
141  /* Check validity of IFID definition. */
143  reqh_init(mkfs, use_small_credits);
144 
145  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
147 
149  M0_UT_ASSERT(result == 0);
151  result = m0_reqh_service_start(fdmi);
152  M0_UT_ASSERT(result == 0);
153 
155  M0_UT_ASSERT(result == 0);
162 }
163 
164 static void init(void)
165 {
166  _init(true, false);
167 }
168 
169 static void service_stop(void)
170 {
171  m0_reqh_rpc_mach_tlist_pop(&reqh.rh_rpc_machines);
176 
181 }
182 
183 static void fini(void)
184 {
185  service_stop();
187  m0_fi_disable("cas_in_ut", "ut");
188  rep_clear();
191 }
192 
193 static void reinit_nomkfs(void)
194 {
195  fini();
196  _init(false, false);
197 }
198 
202 static void init_fini(void)
203 {
204  init();
205  fini();
206 }
207 
211 static void init_fail(void)
212 {
213  int rc;
214 
215  reqh_init(true, false);
216 
217  /* Failure to add meta-index to segment dictionary. */
219  M0_UT_ASSERT(rc == 0);
221  m0_fi_enable_once("m0_be_seg_dict_insert", "dict_insert_fail");
224  M0_UT_ASSERT(rc == -ENOENT);
226 
227  /* Failure to create meta-index. */
229  M0_UT_ASSERT(rc == 0);
231  m0_fi_enable_once("m0_ctg_create", "ctg_create_failure");
234  M0_UT_ASSERT(rc == -EFAULT);
236 
237  /* Failure to add meta-index to itself. */
239  M0_UT_ASSERT(rc == 0);
241  m0_fi_enable_once("btree_save", "already_exists");
244  M0_UT_ASSERT(rc == -EEXIST);
246 
247  /* Failure to create catalogue-index index. */
249  M0_UT_ASSERT(rc == 0);
251  m0_fi_enable_off_n_on_m("m0_ctg_create", "ctg_create_failure",
252  1, 1);
255  m0_fi_disable("m0_ctg_create", "ctg_create_failure");
256  M0_UT_ASSERT(rc == -EFAULT);
258 
259  /* Failure to add catalogue-index index to meta-index. */
261  M0_UT_ASSERT(rc == 0);
263  m0_fi_enable_off_n_on_m("btree_save", "already_exists",
264  1, 1);
267  m0_fi_disable("btree_save", "already_exists");
268  M0_UT_ASSERT(rc == -EEXIST);
270 
271  /* Normal start (fdmi service is needed). */
272  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
274 
276  M0_UT_ASSERT(rc == 0);
279  M0_UT_ASSERT(rc == 0);
280 
282  M0_UT_ASSERT(rc == 0);
286  M0_UT_ASSERT(rc == 0);
288 
289  fini();
290 }
291 
295 M0_INTERNAL int m0_cas_module_init(void);
296 M0_INTERNAL void m0_cas_module_fini(void);
297 
298 static void reinit(void)
299 {
300  /*
301  * CAS module is already initialised as part of general motr
302  * initialisation in motr/init.c, see m0_cas_module_init().
303  * Finalise it first and then initialise again.
304  */
307 }
308 
312 static void restart(void)
313 {
314  int result;
315 
316  init();
317  service_stop();
318 
319  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
321 
323  M0_UT_ASSERT(result == 0);
325  result = m0_reqh_service_start(fdmi);
326  M0_UT_ASSERT(result == 0);
327 
329  M0_UT_ASSERT(result == 0);
333  fini();
334 }
335 
336 static void fop_release(struct m0_ref *ref)
337 {
338 }
339 
340 struct fopsem {
342  struct m0_fop fs_fop;
343 };
344 
345 static void cb_done(struct m0_fom *fom)
346 {
347  struct m0_cas_rep *reply = m0_fop_data(fom->fo_rep_fop);
348  int i;
349  struct fopsem *fs = M0_AMB(fs, fom->fo_fop, fs_fop);
350 
351  M0_UT_ASSERT(reply != NULL);
352  M0_UT_ASSERT(reply->cgr_rep.cr_nr <= ARRAY_SIZE(repv));
353  rep.cgr_rc = reply->cgr_rc;
354  rep.cgr_rep.cr_nr = reply->cgr_rep.cr_nr;
356  for (i = 0; !mt && i < rep.cgr_rep.cr_nr; ++i) {
357  struct m0_cas_rec *rec = &reply->cgr_rep.cr_rec[i];
358  int rc;
359 
360  repv[i].cr_hint = rec->cr_hint;
361  repv[i].cr_rc = rec->cr_rc;
362  rc = at_inline_fill(&repv[i].cr_key, &rec->cr_key);
363  M0_UT_ASSERT(rc == 0);
364  rc = at_inline_fill(&repv[i].cr_val, &rec->cr_val);
365  M0_UT_ASSERT(rc == 0);
366  }
367  m0_ref_put(&fom->fo_fop->f_ref);
368  fom->fo_fop = NULL;
369  m0_ref_put(&fom->fo_rep_fop->f_ref);
370  m0_fop_release(&fom->fo_rep_fop->f_ref);
371  fom->fo_rep_fop = NULL;
372  {
373  struct m0_tlink *link = &fom->fo_tx.tx_betx.t_engine_linkage;
374  M0_ASSERT(ergo(link->t_link.ll_next != NULL,
375  !m0_list_link_is_in(&link->t_link)));
376  }
377  m0_semaphore_up(&fs->fs_end);
378 }
379 
380 static void cb_fini(struct m0_fom *fom)
381 {
382 }
383 
384 static void fop_submit(struct m0_fop_type *ft, const struct m0_fid *index,
385  struct m0_cas_rec *rec)
386 {
387  int result;
388  struct fopsem fs;
389  struct m0_cas_op op = {
390  .cg_id = { .ci_fid = *index },
391  .cg_rec = { .cr_rec = rec }
392  };
393 
396  while (rec[op.cg_rec.cr_nr].cr_rc != ~0ULL)
397  ++ op.cg_rec.cr_nr;
398  m0_fop_init(&fs.fs_fop, ft, &op, &fop_release);
399  fs.fs_fop.f_item.ri_rmachine = (void *)1;
400  m0_semaphore_init(&fs.fs_end, 0);
401  rep_clear();
402  result = m0_reqh_fop_handle(&reqh, &fs.fs_fop);
403  M0_UT_ASSERT(result == 0);
404  m0_semaphore_down(&fs.fs_end);
409  m0_semaphore_fini(&fs.fs_end);
410 }
411 
412 enum {
413  BSET = true,
414  BUNSET = false,
415  BANY = 2
416 };
417 
418 enum {
423  EMPTYVAL = 0,
424 
429  NOVAL = (uint64_t)-1,
430 };
431 
432 static void meta_fop_submit(struct m0_fop_type *fopt,
433  struct meta_rec *meta_recs,
434  int meta_recs_num)
435 {
436  int i;
437  int rc;
438  struct m0_cas_rec *recs;
439 
440  M0_ALLOC_ARR(recs, meta_recs_num + 1);
441  M0_UT_ASSERT(recs != NULL);
442  for (i = 0; i < meta_recs_num; i++) {
443  rc = cid_enc(&meta_recs[i].cid, &recs[i].cr_key);
444  M0_UT_ASSERT(rc == 0);
445  recs[i].cr_rc = meta_recs[i].rc;
446  }
447  recs[meta_recs_num] = (struct m0_cas_rec){ .cr_rc = ~0ULL };
448 
449  fop_submit(fopt, &m0_cas_meta_fid, recs);
450 
451  for (i = 0; i < meta_recs_num; i++)
452  m0_rpc_at_fini(&recs[i].cr_key);
453 }
454 
455 static bool rec_check(const struct m0_cas_rec *rec, int rc, int key, int val)
456 {
457  return ergo(rc != BANY, rc == rec->cr_rc) &&
458  ergo(key != BANY, m0_rpc_at_is_set(&rec->cr_key) == key) &&
459  ergo(val != BANY, m0_rpc_at_is_set(&rec->cr_val) == val);
460 }
461 
462 static bool rep_check(int recno, uint64_t rc, int key, int val)
463 {
464  return rec_check(&rep.cgr_rep.cr_rec[recno], rc, key, val);
465 }
466 
467 static void meta_cid_submit(struct m0_fop_type *fopt,
468  struct m0_cas_id *cid)
469 {
470  int rc;
471  struct m0_rpc_at_buf at_buf;
472 
473  rc = cid_enc(cid, &at_buf);
474  M0_UT_ASSERT(rc == 0);
476  (struct m0_cas_rec[]) {
477  { .cr_key = at_buf },
478  { .cr_rc = ~0ULL } });
479 
480  M0_UT_ASSERT(ergo(!mt, rep.cgr_rc == 0));
481  M0_UT_ASSERT(ergo(!mt, rep.cgr_rep.cr_nr == 1));
482  m0_rpc_at_fini(&at_buf);
483 }
484 
485 static void meta_fid_submit(struct m0_fop_type *fopt, struct m0_fid *fid)
486 {
487  struct m0_cas_id cid = { .ci_fid = *fid };
488 
489  meta_cid_submit(fopt, &cid);
490 }
491 
495 static void meta_lookup_none(void)
496 {
497  init();
499  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
500  fini();
501 }
502 
506 static void meta_lookup_2none(void)
507 {
508  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
509  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
510 
511  init();
513  (struct meta_rec[]) {
514  { .cid = nonce0 },
515  { .cid = nonce1 } },
516  2);
517  M0_UT_ASSERT(rep.cgr_rc == 0);
519  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
520  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
521  fini();
522 }
523 
527 static void meta_lookup_Nnone(void)
528 {
529  struct meta_rec nonce[N] = {};
530  int i;
531 
532  for (i = 0; i < ARRAY_SIZE(nonce); ++i)
533  nonce[i].cid.ci_fid = IFID(2, 3 + i);
534 
535  init();
536  meta_fop_submit(&cas_get_fopt, nonce, N);
537  M0_UT_ASSERT(rep.cgr_rc == 0);
539  M0_UT_ASSERT(m0_forall(i, N, rep_check(i, -ENOENT, BUNSET, BUNSET)));
540  fini();
541 }
542 
546 static void create(void)
547 {
548  init();
551  fini();
552 }
553 
557 static void cctg_create(void)
558 {
559  int rc;
560  struct m0_cas_id cid1 = { .ci_fid = TFID(1, 1) };
561  struct m0_cas_id cid2 = { .ci_fid = TFID(1, 2) };
562  struct m0_dix_ldesc *desc = NULL;
563  struct m0_ext range[] = {
564  { .e_start = 1, .e_end = 3 },
565  { .e_start = 5, .e_end = 7 },
566  { .e_start = 9, .e_end = 11 },
567  };
568 
569  init();
572  /* Submit CID with empty imask ranges. */
573  meta_cid_submit(&cas_put_fopt, &cid1);
575  /* Submit CID with non-empty imask ranges. */
576  desc = &cid2.ci_layout.u.dl_desc;
577  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
578  &M0_FID_INIT(10, 10));
579  M0_UT_ASSERT(rc == 0);
580  meta_cid_submit(&cas_put_fopt, &cid2);
582  m0_dix_ldesc_fini(desc);
583  fini();
584 }
585 
589 static void cctg_create_lookup(void)
590 {
591  int rc;
592  struct m0_cas_id cid = { .ci_fid = TFID(1, 1) };
593  struct m0_dix_ldesc *desc = NULL;
594  struct m0_ext range[] = {
595  { .e_start = 1, .e_end = 3 },
596  { .e_start = 5, .e_end = 7 },
597  { .e_start = 9, .e_end = 11 },
598  };
599 
600  init();
602  desc = &cid.ci_layout.u.dl_desc;
603  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
604  &M0_FID_INIT(10, 10));
605  M0_UT_ASSERT(rc == 0);
610  m0_dix_ldesc_fini(desc);
611  fini();
612 }
613 
617 static void cctg_create_delete(void)
618 {
619  int rc;
620  struct m0_cas_id cid = { .ci_fid = TFID(1, 1) };
621  struct m0_dix_ldesc *desc = NULL;
622  struct m0_ext range[] = {
623  { .e_start = 1, .e_end = 3 },
624  { .e_start = 5, .e_end = 7 },
625  { .e_start = 9, .e_end = 11 },
626  };
627 
628  init();
630 
631  /* Test operations with empty imask ranges. */
637  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
638 
639  /* Test operations with non-empty imask ranges. */
640  desc = &cid.ci_layout.u.dl_desc;
641  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
642  &M0_FID_INIT(10, 10));
643  M0_UT_ASSERT(rc == 0);
649  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
650  m0_dix_ldesc_fini(desc);
651  fini();
652 }
653 
657 static void create_lookup(void)
658 {
659  init();
664  fini();
665 }
666 
670 static void create_create(void)
671 {
672  init();
676  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
679  fini();
680 }
681 
685 static void create_delete(void)
686 {
687  init();
693  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
694  fini();
695 }
696 
700 static void recreate(void)
701 {
702  init();
708  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
713  fini();
714 }
715 
719 static void meta_cur_1(void)
720 {
721  struct m0_cas_id cid = { .ci_fid = ifid };
722 
723  init();
727  (struct meta_rec[]) {
728  { .cid = cid, .rc = 1 } },
729  1);
730  M0_UT_ASSERT(rep.cgr_rc == 0);
733  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
734  fini();
735 }
736 
740 static void meta_cur_eot(void)
741 {
742  struct m0_cas_id cid = { .ci_fid = ifid };
743 
744  init();
748  (struct meta_rec[]) {
749  { .cid = cid, .rc = 2 } },
750  1);
751  M0_UT_ASSERT(rep.cgr_rc == 0);
754  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
755  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
756  fini();
757 }
758 
762 static void meta_cur_0(void)
763 {
764  struct m0_cas_id cid = { .ci_fid = ifid };
765 
766  init();
770  (struct meta_rec[]) {
771  { .cid = cid, .rc = 0 } },
772  1);
773  M0_UT_ASSERT(rep.cgr_rc == 0);
775  fini();
776 }
777 
781 static void meta_cur_empty(void)
782 {
783  struct m0_cas_id cid = { .ci_fid = ifid };
784 
785  init();
787  (struct meta_rec[]) {
788  { .cid = cid, .rc = 1 } },
789  1);
790  M0_UT_ASSERT(rep.cgr_rc == 0);
792  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
793  fini();
794 }
795 
799 static void meta_cur_none(void)
800 {
801  struct m0_cas_id cid = { .ci_fid = IFID(8,9) };
802 
803  init();
807  (struct meta_rec[]) {
808  { .cid = cid, .rc = 4 } },
809  1);
810  M0_UT_ASSERT(rep.cgr_rc == 0);
812  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
816  fini();
817 }
818 
822 static void meta_cur_all(void)
823 {
824  struct m0_fid fid = IFID(1, 0);
825  struct m0_cas_id cid = { .ci_fid = m0_cas_meta_fid };
826 
827  init();
831  (struct meta_rec[]) {
832  { .cid = cid , .rc = 5 } },
833  1);
834  M0_UT_ASSERT(rep.cgr_rc == 0);
836  /* meta-index record */
838  /* catalogue-index index record */
840  /* moved meta record */
842  /* newly inserted record */
844  /* nonexistent record */
845  M0_UT_ASSERT(rep_check(4, -ENOENT, BUNSET, BUNSET));
846  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr,
847  &m0_cas_meta_fid));
848  M0_UT_ASSERT(m0_fid_eq(repv[1].cr_key.u.ab_buf.b_addr,
849  &m0_cas_ctidx_fid));
850  M0_UT_ASSERT(m0_fid_eq(repv[2].cr_key.u.ab_buf.b_addr,
852  M0_UT_ASSERT(m0_fid_eq(repv[3].cr_key.u.ab_buf.b_addr, &fid));
853  fini();
854 }
855 
856 static struct m0_fop_type *ft[] = {
857  &cas_put_fopt,
858  &cas_get_fopt,
859  &cas_del_fopt,
860  &cas_cur_fopt
861 };
862 
866 static void meta_random(void)
867 {
868  enum { K = 10 };
869  struct m0_fid fid;
870  struct meta_rec mrecs[K];
871  int i;
872  int j;
873  int total;
874  uint64_t seed = time(NULL)*time(NULL);
875 
876  init();
877  for (i = 0; i < 50; ++i) {
878  struct m0_fop_type *type = ft[m0_rnd64(&seed) % ARRAY_SIZE(ft)];
879 
880  memset(mrecs, 0, sizeof(mrecs));
881  total = 0;
882  /*
883  * Keep number of operations in a fop small to avoid too large
884  * transactions.
885  */
886  for (j = 0; j < K; ++j) {
888  2, m0_rnd64(&seed) % 5);
889  mrecs[j].cid.ci_fid = fid;
890  if (type == &cas_cur_fopt) {
891  int n = m0_rnd64(&seed) % 1000;
892  if (total + n < ARRAY_SIZE(repv))
893  total += mrecs[j].rc = n;
894  }
895  }
896  meta_fop_submit(type, mrecs, K);
897  M0_UT_ASSERT(rep.cgr_rc == 0);
898  if (type != &cas_cur_fopt) {
901  BUNSET)));
902  } else {
904  }
905  }
906  fini();
907 }
908 
912 static void meta_invalid(void)
913 {
914  enum { M = 16*1024 };
915  uint64_t buf[M + M];
916  struct m0_cas_rec op[N + 1] = {};
917  int i;
918  int j;
919  uint64_t seed = time(NULL)*time(NULL);
920 
921  init();
922  for (i = 0; i < ARRAY_SIZE(buf); ++i)
923  buf[i] = m0_rnd64(&seed);
924  for (i = 0; i < 200; ++i) {
925  for (j = 0; j < 10; ++j) {
927  op[j].cr_key = (struct m0_rpc_at_buf) {
928  .ab_type = 1,
929  .u.ab_buf = M0_BUF_INIT(size,
930  buf + m0_rnd64(&seed) % M)
931  };
932 
933  }
934  op[j].cr_rc = ~0ULL;
936  &m0_cas_meta_fid, op);
937  M0_UT_ASSERT(rep.cgr_rc == -EPROTO);
938  }
939  fini();
940 }
941 
942 static void index_op_rc(struct m0_fop_type *ft, struct m0_fid *index,
943  uint64_t key, uint64_t val, uint64_t rc)
944 {
945  struct m0_buf no = M0_BUF_INIT(0, NULL);
946 
948  (struct m0_cas_rec[]) {
949  { .cr_key.u.ab_buf = key != 0 ?
950  M0_BUF_INIT(sizeof key, &key) : no,
951  .cr_key.ab_type = key != 0 ? M0_RPC_AT_INLINE :
953  .cr_val.u.ab_buf = !M0_IN(val, (NOVAL, EMPTYVAL)) ?
954  M0_BUF_INIT(sizeof val, &val) : no,
955  .cr_val.ab_type = val != NOVAL ? M0_RPC_AT_INLINE :
957  .cr_rc = rc },
958  { .cr_rc = ~0ULL } });
959 }
960 
961 static void index_op(struct m0_fop_type *ft, struct m0_fid *index,
962  uint64_t key, uint64_t val)
963 {
964  index_op_rc(ft, index, key, val, 0);
965 }
966 
970 static void insert(void)
971 {
972  init();
975  index_op(&cas_put_fopt, &ifid, 1, 2);
976  M0_UT_ASSERT(rep.cgr_rc == 0);
979  fini();
980 }
981 
985 static void insert_lookup(void)
986 {
987  init();
990  index_op(&cas_put_fopt, &ifid, 1, 2);
991  M0_UT_ASSERT(rep.cgr_rc == 0);
995  M0_UT_ASSERT(rep.cgr_rc == 0);
998  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob
999  == sizeof (uint64_t));
1000  M0_UT_ASSERT(2 ==
1001  *(uint64_t *)rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr);
1002  fini();
1003 }
1004 
1008 static void insert_delete(void)
1009 {
1010  init();
1013  index_op(&cas_put_fopt, &ifid, 1, 2);
1014  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1015  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1016  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1018  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1019  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1020  fini();
1021 }
1022 
1026 static void lookup_none(void)
1027 {
1028  init();
1031  index_op(&cas_put_fopt, &ifid, 1, 2);
1032  index_op(&cas_get_fopt, &ifid, 3, NOVAL);
1033  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1034  fini();
1035 }
1036 
1040 static void empty_value(void)
1041 {
1042  init();
1046  M0_UT_ASSERT(rep.cgr_rc == 0);
1047  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1049  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1050  M0_UT_ASSERT(rep.cgr_rc == 0);
1051  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1052  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1053  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob == 0);
1054  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1055  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1056  M0_UT_ASSERT(rep.cgr_rc == 0);
1058  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1059  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1060  fini();
1061 }
1062 
1066 static void insert_2(void)
1067 {
1068  init();
1071  index_op(&cas_put_fopt, &ifid, 1, 2);
1073  index_op(&cas_put_fopt, &ifid, 1, 2);
1074  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
1075  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1076  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1077  fini();
1078 }
1079 
1083 static void delete_2(void)
1084 {
1085  init();
1088  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1089  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1090  fini();
1091 }
1092 
1093 enum {
1094  INSERTS = 1500,
1096 };
1097 
1098 #define CB(x) m0_byteorder_cpu_to_be64(x)
1099 #define BC(x) m0_byteorder_be64_to_cpu(x)
1100 
1101 static void insert_odd(struct m0_fid *index)
1102 {
1103  int i;
1104 
1105  for (i = 1; i < INSERTS; i += 2) {
1106  /*
1107  * Convert to big-endian to get predictable iteration order.
1108  */
1109  index_op(&cas_put_fopt, index, CB(i), i*i);
1111  }
1112 }
1113 
1114 static void lookup_all(struct m0_fid *index)
1115 {
1116  int i;
1117 
1118  for (i = 1; i < INSERTS; ++i) {
1120  if (i & 1) {
1121  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1122  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob ==
1123  sizeof (uint64_t));
1124  M0_UT_ASSERT(i * i ==
1125  *(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr);
1126  } else {
1127  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1128  }
1129  }
1130 }
1131 
1135 static void lookup_N(void)
1136 {
1137  init();
1139  insert_odd(&ifid);
1140  lookup_all(&ifid);
1141  fini();
1142 }
1143 
1147 static void lookup_restart(void)
1148 {
1149  int result;
1150 
1151  init();
1153  insert_odd(&ifid);
1154  lookup_all(&ifid);
1155  service_stop();
1156 
1157  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
1159 
1161  M0_UT_ASSERT(result == 0);
1163  result = m0_reqh_service_start(fdmi);
1164  M0_UT_ASSERT(result == 0);
1165 
1167  M0_UT_ASSERT(result == 0);
1171  lookup_all(&ifid);
1172  fini();
1173 }
1174 
1178 static void cur_N(void)
1179 {
1180  int i;
1181  int result;
1182 
1183  init();
1185  insert_odd(&ifid);
1186  service_stop();
1187 
1188  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
1190 
1192  M0_UT_ASSERT(result == 0);
1194  result = m0_reqh_service_start(fdmi);
1195  M0_UT_ASSERT(result == 0);
1196 
1198  M0_UT_ASSERT(result == 0);
1202 
1203  for (i = 1; i < INSERTS; ++i) {
1204  int j;
1205  int k;
1206 
1208  if (!(i & 1)) {
1209  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1210  continue;
1211  }
1212  for (j = i, k = 0; j < INSERTS; j += 2, ++k) {
1213  struct m0_cas_rec *r = &repv[k];
1214  struct m0_buf *buf;
1215 
1216  buf = &r->cr_val.u.ab_buf;
1217  M0_UT_ASSERT(rep_check(k, k + 1, BSET, BSET));
1218  M0_UT_ASSERT(buf->b_nob == sizeof (uint64_t));
1219  M0_UT_ASSERT(*(uint64_t *)buf->b_addr == j * j);
1220  buf = &r->cr_key.u.ab_buf;
1221  M0_UT_ASSERT(buf->b_nob == sizeof (uint64_t));
1222  M0_UT_ASSERT(*(uint64_t *)buf->b_addr == CB(j));
1223  }
1224  M0_UT_ASSERT(rep_check(k, -ENOENT, BUNSET, BUNSET));
1226  }
1227  fini();
1228 }
1229 
1230 static struct m0_thread t[8];
1231 
1232 static void meta_mt_thread(int idx)
1233 {
1234  uint64_t seed = time(NULL) * (idx + 6);
1235  int i;
1236 
1237  M0_UT_ASSERT(0 <= idx && idx < ARRAY_SIZE(t));
1238 
1239  for (i = 0; i < 20; ++i) {
1241  &IFID(2, m0_rnd64(&seed) % 5));
1242  /*
1243  * Cannot check anything: global rep and repv are corrupted.
1244  */
1245  }
1246 }
1247 
1251 static void meta_mt(void)
1252 {
1253  int i;
1254  int result;
1255 
1256  init();
1257  mt = true;
1258  for (i = 0; i < ARRAY_SIZE(t); ++i) {
1259  result = M0_THREAD_INIT(&t[i], int, NULL, &meta_mt_thread, i,
1260  "meta-mt-%i", i);
1261  M0_UT_ASSERT(result == 0);
1262  }
1263  for (i = 0; i < ARRAY_SIZE(t); ++i) {
1264  m0_thread_join(&t[i]);
1265  m0_thread_fini(&t[i]);
1266  }
1267  mt = false;
1268  fini();
1269 }
1270 
1271 static void meta_insert_fail(void)
1272 {
1273  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1274  init();
1276  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1277  index_op(&cas_put_fopt, &ifid, 1, 2);
1278  M0_UT_ASSERT(rep.cgr_rc == -ENOENT);
1279  /* Lookup process should return zero records. */
1281  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1282  fini();
1283 }
1284 
1285 static void meta_lookup_fail(void)
1286 {
1287  init();
1290  M0_UT_ASSERT(rep.cgr_rc == 0);
1291  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1292  /* Lookup process should return ENOMEM code */
1293  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1295  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1296  /* Lookup without ENOMEM returns record. */
1299  fini();
1300 }
1301 
1302 static void meta_delete_fail(void)
1303 {
1304  init();
1307  /* Delete record with fail. */
1308  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1310  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1311  /* Lookup should return record. */
1314  fini();
1315 }
1316 
1317 static void insert_fail(void)
1318 {
1319  init();
1320  /* Insert meta OK. */
1323  M0_UT_ASSERT(rep.cgr_rc == 0);
1324  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1325  /* Insert key ENOMEM - fi. */
1326  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1327  index_op(&cas_put_fopt, &ifid, 1, 2);
1328  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1329  /* Search meta OK. */
1332  /* Search key, ENOENT. */
1333  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1334  M0_UT_ASSERT(rep.cgr_rc == 0);
1335  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1336  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_rc == -ENOENT);
1337  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1338  fini();
1339 }
1340 
1341 static void lookup_fail(void)
1342 {
1343  init();
1344  /* Insert meta OK. */
1347  M0_UT_ASSERT(rep.cgr_rc == 0);
1348  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1349  /* Insert key OK. */
1350  index_op(&cas_put_fopt, &ifid, 1, 2);
1352  M0_UT_ASSERT(rep.cgr_rc == 0);
1353  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1354  /* Search meta OK. */
1357  /* Search key, ENOMEM - fi. */
1358  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1359  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1360  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1361  /* Secondary search OK. */
1362  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1363  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1364  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1365  M0_UT_ASSERT(rep.cgr_rc == 0);
1366  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1367  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1368  fini();
1369 }
1370 
1371 static void delete_fail(void)
1372 {
1373  init();
1374  /* Insert meta OK. */
1377  M0_UT_ASSERT(rep.cgr_rc == 0);
1378  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1379  /* Insert key OK. */
1380  index_op(&cas_put_fopt, &ifid, 1, 2);
1382  M0_UT_ASSERT(rep.cgr_rc == 0);
1383  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1384  /* Search key OK. */
1385  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1386  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1387  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1388  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1389  /* Delete key, ENOMEM - fi. */
1390  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1391  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1392  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1393  /* Search key OK. */
1394  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1395  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1396  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1397  M0_UT_ASSERT(rep.cgr_rc == 0);
1398  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1399  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1400  /* Delete key OK. */
1401  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1403  /* Search key, ENOENT. */
1404  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1405  M0_UT_ASSERT(rep.cgr_rc == 0);
1406  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1407  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_rc == -ENOENT);
1408  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1409  fini();
1410 }
1411 
1412 struct record
1413 {
1414  uint64_t key;
1415  uint64_t value;
1416 };
1417 
1418 static void multi_values_insert(struct record *recs, int recs_count)
1419 {
1420  struct m0_cas_rec cas_recs[MULTI_INS];
1421  int i;
1422 
1424  for (i = 0; i < recs_count - 1; i++) {
1425  cas_recs[i] = (struct m0_cas_rec) {
1426  .cr_key = (struct m0_rpc_at_buf) {
1427  .ab_type = 1,
1428  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1429  &recs[i].key)
1430  },
1431  .cr_val = (struct m0_rpc_at_buf) {
1432  .ab_type = 1,
1433  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].value,
1434  &recs[i].value)
1435  },
1436  .cr_rc = 0 };
1437  }
1438  cas_recs[recs_count - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1439  fop_submit(&cas_put_fopt, &ifid, cas_recs);
1440 }
1441 
1442 static void cur_fail(void)
1443 {
1444  struct record recs[MULTI_INS];
1445  int i;
1446 
1447  init();
1448  /* Insert meta OK. */
1451  M0_UT_ASSERT(rep.cgr_rc == 0);
1452  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1453  /* Insert keys OK. */
1454  for (i = 0; i < MULTI_INS; i++) {
1455  recs[i].key = i+1;
1456  recs[i].value = i * i;
1457  }
1459  M0_UT_ASSERT(rep.cgr_rc == 0);
1462  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1463  /* Iterate from beginning, -ENOMEM. */
1464  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1466  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1467  /*
1468  * Iterate from begining, first - OK, second - fail.
1469  * Service stops request processing after failure, all other reply
1470  * records are empty.
1471  */
1472  m0_fi_enable_off_n_on_m("m0_ctg_op_rc", "be-failure", 3, 2);
1474  m0_fi_disable("m0_ctg_op_rc", "be-failure");
1475  M0_UT_ASSERT(rep.cgr_rc == 0);
1477  M0_UT_ASSERT(repv[0].cr_rc == 1);
1478  M0_UT_ASSERT(repv[1].cr_rc == -ENOMEM);
1479  for (i = 2; i < MULTI_INS - 1; i++)
1480  M0_UT_ASSERT(repv[i].cr_rc == 0);
1481 
1482  fini();
1483 }
1484 
1485 static void multi_values_lookup(struct record *recs, int recs_count)
1486 {
1487  struct m0_cas_rec cas_recs[MULTI_INS];
1488  int i;
1489 
1491  for (i = 0; i < MULTI_INS - 1; i++) {
1492  cas_recs[i] = (struct m0_cas_rec){
1493  .cr_key = (struct m0_rpc_at_buf) {
1494  .ab_type = 1,
1495  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1496  &recs[i].key)
1497  },
1498  .cr_val = (struct m0_rpc_at_buf) {
1499  .ab_type = 0,
1500  .u.ab_buf = M0_BUF_INIT(0, NULL)
1501  },
1502  .cr_rc = 0 };
1503  }
1504  cas_recs[MULTI_INS - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1505  fop_submit(&cas_get_fopt, &ifid, cas_recs);
1506 }
1507 
1508 static void multi_values_delete(struct record *recs, int recs_count)
1509 {
1510  struct m0_cas_rec cas_recs[MULTI_INS];
1511  int i;
1512 
1514  for (i = 0; i < MULTI_INS - 1; i++) {
1515  cas_recs[i] = (struct m0_cas_rec){
1516  .cr_key = (struct m0_rpc_at_buf) {
1517  .ab_type = 1,
1518  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1519  &recs[i].key)
1520  },
1521  .cr_val = (struct m0_rpc_at_buf) {
1522  .ab_type = 0,
1523  .u.ab_buf = M0_BUF_INIT(0, NULL)
1524  },
1525  .cr_rc = 0 };
1526  }
1527  cas_recs[MULTI_INS - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1528  fop_submit(&cas_del_fopt, &ifid, cas_recs);
1529 }
1530 
1531 static void multi_insert(void)
1532 {
1533  struct record recs[MULTI_INS];
1534 
1535  init();
1536  /* Fill array with pair: [key, value]. */
1537  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1538  /* Insert meta OK. */
1541  M0_UT_ASSERT(rep.cgr_rc == 0);
1542  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1543  /* Insert several keys and values OK. */
1545  M0_UT_ASSERT(rep.cgr_rc == 0);
1548  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1549  fini();
1550 }
1551 
1552 static void multi_lookup(void)
1553 {
1554  struct record recs[MULTI_INS];
1555 
1556  init();
1557  /* Fill array with pair: [key, value]. */
1558  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1559  /* Insert meta OK. */
1562  M0_UT_ASSERT(rep.cgr_rc == 0);
1563  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1564  /* Insert several keys and values OK. */
1566  M0_UT_ASSERT(rep.cgr_rc == 0);
1569  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1570  /* Lookup values. */
1572  M0_UT_ASSERT(rep.cgr_rc == 0);
1575  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1577  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i * i));
1578  fini();
1579 }
1580 
1581 static void multi_delete(void)
1582 {
1583  struct record recs[MULTI_INS];
1584 
1585  init();
1586  /* Fill array with pair: [key, value]. */
1587  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1588  /* Insert meta OK. */
1591  M0_UT_ASSERT(rep.cgr_rc == 0);
1592  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1593  /* Insert several keys and values OK. */
1595  M0_UT_ASSERT(rep.cgr_rc == 0);
1598  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1599  /* Delete all values. */
1601  M0_UT_ASSERT(rep.cgr_rc == 0);
1604  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1605  /* Lookup values: ENOENT. */
1607  M0_UT_ASSERT(rep.cgr_rc == 0);
1610  rep.cgr_rep.cr_rec[i].cr_rc == -ENOENT));
1612  repv[i].cr_val.u.ab_buf.b_addr == NULL));
1613  fini();
1614 }
1615 
1616 static void multi_insert_fail(void)
1617 {
1618  struct record recs[MULTI_INS];
1619 
1620  init();
1621  /* Fill array with pair: [key, value]. */
1622  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1623  /* Insert meta OK. */
1626  M0_UT_ASSERT(rep.cgr_rc == 0);
1627  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1628  /* Insert several keys and values OK. */
1629  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1631  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1632  M0_UT_ASSERT(rep.cgr_rc == 0);
1635  i % 2 ?
1636  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1637  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1638  fini();
1639 }
1640 
1641 static void multi_lookup_fail(void)
1642 {
1643  struct record recs[MULTI_INS];
1644 
1645  init();
1646  /* Fill array with pair: [key, value]. */
1647  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1648  /* Insert meta OK. */
1651  M0_UT_ASSERT(rep.cgr_rc == 0);
1652  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1653  /* Insert several keys and values OK. */
1655  M0_UT_ASSERT(rep.cgr_rc == 0);
1658  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1659  /* Lookup values. */
1660  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1662  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1663  M0_UT_ASSERT(rep.cgr_rc == 0);
1666  i % 2 ?
1667  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1668  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1670  i % 2 ?
1671  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i*i :
1672  repv[i].cr_val.u.ab_buf.b_addr == NULL));
1673  fini();
1674 }
1675 
1676 static void multi_delete_fail(void)
1677 {
1678  struct record recs[MULTI_INS];
1679 
1680  init();
1681  /* Fill array with pair: [key, value]. */
1682  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1683  /* Insert meta OK. */
1686  M0_UT_ASSERT(rep.cgr_rc == 0);
1687  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1688  /* Insert several keys and values OK. */
1690  M0_UT_ASSERT(rep.cgr_rc == 0);
1693  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1694  /* Delete several recs. */
1695  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1697  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1698  M0_UT_ASSERT(rep.cgr_rc == 0);
1701  i % 2 ?
1702  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1703  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1704  /* Lookup values. */
1706  M0_UT_ASSERT(rep.cgr_rc == 0);
1709  i % 2 ?
1710  rep.cgr_rep.cr_rec[i].cr_rc == -ENOENT :
1711  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1713  i % 2 ?
1714  repv[i].cr_val.u.ab_buf.b_addr == NULL :
1715  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i * i));
1716  fini();
1717 }
1718 
1725 static void server_restart_nomkfs(void)
1726 {
1727  struct m0_cas_id cid = { .ci_fid = ifid };
1728 
1729  init();
1732  index_op(&cas_put_fopt, &ifid, 1, 2);
1733  M0_UT_ASSERT(rep.cgr_rc == 0);
1734  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1736 
1737  /* Check that index and record are present. */
1738  reinit_nomkfs();
1740  (struct meta_rec[]) {
1741  { .cid = cid, .rc = 1 } },
1742  1);
1743  M0_UT_ASSERT(rep.cgr_rc == 0);
1744  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1745  M0_UT_ASSERT(rep_check(0, 1, BSET, BUNSET));
1746  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
1747 
1748  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1749  M0_UT_ASSERT(rep.cgr_rc == 0);
1750  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1751  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1752  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob
1753  == sizeof (uint64_t));
1754  M0_UT_ASSERT(2 ==
1755  *(uint64_t *)rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr);
1756 
1757  /* Check that the same record can't be inserted. */
1758  reinit_nomkfs();
1759  index_op(&cas_put_fopt, &ifid, 1, 2);
1760  M0_UT_ASSERT(rep.cgr_rc == 0);
1761  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1762  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
1763 
1764  /* Check that record can be deleted. */
1765  reinit_nomkfs();
1766  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1768 
1769  /* Check that record was really deleted. */
1770  reinit_nomkfs();
1771  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1772  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1773 
1774  /* Check that index can deleted. */
1775  reinit_nomkfs();
1778 
1779  /* Check that index was deleted. */
1780  reinit_nomkfs();
1782  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1783 
1784  fini();
1785 }
1786 
1787 static void multi_create_drop(void)
1788 {
1789  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
1790  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
1791 
1792  init();
1794  (struct meta_rec[]) {
1795  { .cid = nonce0 },
1796  { .cid = nonce1 } },
1797  2);
1798  M0_UT_ASSERT(rep.cgr_rc == 0);
1799  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1800 
1802  (struct meta_rec[]) {
1803  { .cid = nonce0 },
1804  { .cid = nonce1 } },
1805  2);
1808 
1810  (struct meta_rec[]) {
1811  { .cid = nonce0 },
1812  { .cid = nonce1 } },
1813  2);
1814  M0_UT_ASSERT(rep.cgr_rc == 0);
1815  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1816 
1818  (struct meta_rec[]) {
1819  { .cid = nonce0 },
1820  { .cid = nonce1 } },
1821  2);
1822  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1823  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
1824 
1826  (struct meta_rec[]) {
1827  { .cid = nonce0 },
1828  { .cid = nonce1 } },
1829  2);
1830  M0_UT_ASSERT(rep.cgr_rc == 0);
1831  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1832 
1834  (struct meta_rec[]) {
1835  { .cid = nonce0 },
1836  { .cid = nonce1 } },
1837  2);
1840 
1841  fini();
1842 }
1843 
1844 enum {
1845  /*
1846  * Better have more rows, for 3-levels b-tree and multiple transactions,
1847  * but only 7000 can fit into typical 1Mb file.
1848  * 2000 is enough to test multiple transactions if decrease transaction
1849  * size limit by using -c switch.
1850  */
1852  /*
1853  * Number of rows for 2-level btree.
1854  */
1856 };
1857 
1864 static void create_insert_drop_with_fail(bool inject_fail)
1865 {
1866  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
1867  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
1868  int i;
1869 
1870  /*
1871  * Use small credits in order to split big transaction into smaller
1872  * ones. BE performs quadratic number of checks inside invariants
1873  * comparing to number of capture operations.
1874  */
1875  _init(true, true);
1876  /*
1877  * Create 2 catalogs.
1878  */
1880  (struct meta_rec[]) {
1881  { .cid = nonce0 },
1882  { .cid = nonce1 } },
1883  2);
1884  M0_UT_ASSERT(rep.cgr_rc == 0);
1885  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1886 
1887  for (i = 0 ; i < BIG_ROWS_NUMBER ; ++i) {
1888  index_op(&cas_put_fopt, &nonce0.ci_fid, i+1, i+2);
1889  M0_UT_ASSERT(rep.cgr_rc == 0);
1890  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1892  }
1893  for (i = 0 ; i < SMALL_ROWS_NUMBER ; ++i) {
1894  index_op(&cas_put_fopt, &nonce1.ci_fid, i+1, i+2);
1895  M0_UT_ASSERT(rep.cgr_rc == 0);
1896  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1898  }
1899 
1900  /*
1901  * Drop 2 catalogs.
1902  */
1904  (struct meta_rec[]) {
1905  { .cid = nonce0 },
1906  { .cid = nonce1 } },
1907  2);
1908  M0_UT_ASSERT(rep.cgr_rc == 0);
1909  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1910 
1911  /*
1912  * Check that both catalogs are dropped.
1913  */
1915  (struct meta_rec[]) {
1916  { .cid = nonce0 },
1917  { .cid = nonce1 } },
1918  2);
1919  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1920  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
1921 
1922  if (inject_fail)
1923  m0_fi_enable_once("cgc_fom_tick", "fail_after_index_found");
1924  /*
1925  * Wait for GC complete.
1926  */
1928  (struct meta_rec[]) {
1929  { .cid = nonce0 }},
1930  1);
1931  if (inject_fail)
1932  m0_fi_disable("cgc_fom_tick", "fail_after_index_found");
1933  fini();
1934 }
1935 
1936 static void create_insert_drop()
1937 {
1939 }
1940 
1942 {
1944 }
1945 
1946 static void init_cgc_fail_fini(void)
1947 {
1948  m0_fi_enable_once("cgc_fom_tick", "fail_in_cgc_generic_phase");
1949  init();
1950  fini();
1951  m0_fi_disable("cgc_fom_tick", "fail_in_cgc_generic_phase");
1952 
1953  m0_fi_enable_once("cgc_fom_tick", "fail_after_index_found");
1954  init();
1955  fini();
1956  m0_fi_disable("cgc_fom_tick", "fail_after_index_found");
1957 }
1958 
1960  .ts_name = "cas-service",
1961  .ts_owners = "Nikita",
1962  .ts_init = NULL,
1963  .ts_fini = NULL,
1964  .ts_tests = {
1965  { "init-fini", &init_fini, "Nikita" },
1966  { "init-fail", &init_fail, "Leonid" },
1967  { "re-init", &reinit, "Egor" },
1968  { "re-start", &restart, "Nikita" },
1969  { "meta-lookup-none", &meta_lookup_none, "Nikita" },
1970  { "meta-lookup-2-none", &meta_lookup_2none, "Nikita" },
1971  { "meta-lookup-N-none", &meta_lookup_Nnone, "Nikita" },
1972  { "create", &create, "Nikita" },
1973  { "create-lookup", &create_lookup, "Nikita" },
1974  { "create-create", &create_create, "Nikita" },
1975  { "create-delete", &create_delete, "Nikita" },
1976  { "recreate", &recreate, "Nikita" },
1977  { "meta-cur-1", &meta_cur_1, "Nikita" },
1978  { "meta-cur-0", &meta_cur_0, "Nikita" },
1979  { "meta-cur-eot", &meta_cur_eot, "Nikita" },
1980  { "meta-cur-empty", &meta_cur_empty, "Nikita" },
1981  { "meta-cur-none", &meta_cur_none, "Nikita" },
1982  { "meta-cur-all", &meta_cur_all, "Leonid" },
1983  { "meta-random", &meta_random, "Nikita" },
1984  { "meta-invalid", &meta_invalid, "Nikita" },
1985  { "insert", &insert, "Nikita" },
1986  { "insert-lookup", &insert_lookup, "Nikita" },
1987  { "insert-delete", &insert_delete, "Nikita" },
1988  { "lookup-none", &lookup_none, "Nikita" },
1989  { "empty-value", &empty_value, "Egor" },
1990  { "insert-2", &insert_2, "Nikita" },
1991  { "delete-2", &delete_2, "Nikita" },
1992  { "lookup-N", &lookup_N, "Nikita" },
1993  { "lookup-restart", &lookup_restart, "Nikita" },
1994  { "cur-N", &cur_N, "Nikita" },
1995  { "meta-mt", &meta_mt, "Nikita" },
1996  { "meta-insert-fail", &meta_insert_fail, "Leonid" },
1997  { "meta-lookup-fail", &meta_lookup_fail, "Leonid" },
1998  { "meta-delete-fail", &meta_delete_fail, "Leonid" },
1999  { "insert-fail", &insert_fail, "Leonid" },
2000  { "lookup-fail", &lookup_fail, "Leonid" },
2001  { "delete-fail", &delete_fail, "Leonid" },
2002  { "cur-fail", &cur_fail, "Egor" },
2003  { "multi-insert", &multi_insert, "Leonid" },
2004  { "multi-lookup", &multi_lookup, "Leonid" },
2005  { "multi-delete", &multi_delete, "Leonid" },
2006  { "multi-insert-fail", &multi_insert_fail, "Leonid" },
2007  { "multi-lookup-fail", &multi_lookup_fail, "Leonid" },
2008  { "multi-delete-fail", &multi_delete_fail, "Leonid" },
2009  { "multi-create-drop", &multi_create_drop, "Eugene" },
2010  { "create-insert-drop", &create_insert_drop, "Eugene" },
2011  { "create-insert-drop-fail", &create_insert_drop_fail, "Hua" },
2012  { "init-cgc-fail-fini", &init_cgc_fail_fini, "Hua" },
2013  { "cctg-create", &cctg_create, "Sergey" },
2014  { "cctg-create-lookup", &cctg_create_lookup, "Sergey" },
2015  { "cctg-create-delete", &cctg_create_delete, "Sergey" },
2016  { "server-restart-nomkfs", &server_restart_nomkfs, "Egor" },
2017  { NULL, NULL }
2018  }
2019 };
2020 
2021 #undef M0_TRACE_SUBSYSTEM
2022 
2025 /*
2026  * Local variables:
2027  * c-indentation-style: "K&R"
2028  * c-basic-offset: 8
2029  * tab-width: 8
2030  * fill-column: 80
2031  * scroll-step: 1
2032  * End:
2033  */
2034 /*
2035  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
2036  */
uint64_t cr_rc
Definition: cas.h:339
M0_EXTERN struct m0_reqh_service_type m0_fdmi_service_type
Definition: fdmi.h:194
static void lookup_none(void)
Definition: service_ut.c:1026
struct m0_rpc_at_buf cr_val
Definition: cas.h:300
static void multi_insert(void)
Definition: service_ut.c:1531
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL int m0_reqh_service_start(struct m0_reqh_service *service)
Definition: reqh_service.c:343
M0_INTERNAL int m0_be_ut_backend_init_cfg(struct m0_be_ut_backend *ut_be, const struct m0_be_domain_cfg *cfg, bool mkfs)
Definition: stubs.c:231
static void reinit(void)
Definition: service_ut.c:298
uint64_t value
Definition: service_ut.c:1415
M0_INTERNAL void m0_reqh_service_stop(struct m0_reqh_service *service)
Definition: reqh_service.c:402
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
#define TFID(x, y)
Definition: service_ut.c:49
Definition: idx_mock.c:52
#define ergo(a, b)
Definition: misc.h:293
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
static void recreate(void)
Definition: service_ut.c:700
#define M0_REQH_INIT(reqh,...)
Definition: reqh.h:262
static void rep_clear(void)
Definition: service_ut.c:93
static struct m0_be_seg * seg0
Definition: service_ut.c:60
static void create_delete(void)
Definition: service_ut.c:685
M0_INTERNAL void m0_fop_init(struct m0_fop *fop, struct m0_fop_type *fopt, void *data, void(*fop_release)(struct m0_ref *))
Definition: fop.c:79
M0_INTERNAL int m0_reqh_fop_handle(struct m0_reqh *reqh, struct m0_fop *fop)
Definition: reqh.c:546
M0_INTERNAL void m0_rpc_at_init(struct m0_rpc_at_buf *ab)
Definition: at.c:433
M0_INTERNAL void m0_reqh_service_prepare_to_stop(struct m0_reqh_service *service)
Definition: reqh_service.c:375
static void cur_N(void)
Definition: service_ut.c:1178
static struct m0_cas_rep rep
Definition: service_ut.c:64
uint8_t ft_id
Definition: fid.h:101
static void meta_cur_0(void)
Definition: service_ut.c:762
M0_INTERNAL bool m0_rpc_at_is_set(const struct m0_rpc_at_buf *ab)
Definition: at.c:492
static void fini(void)
Definition: service_ut.c:183
#define M0_FID_INIT(container, key)
Definition: fid.h:84
static void create_insert_drop()
Definition: service_ut.c:1936
static void create(void)
Definition: service_ut.c:546
static void cb_done(struct m0_fom *fom)
Definition: service_ut.c:345
static void insert(void)
Definition: service_ut.c:970
static void create_lookup(void)
Definition: service_ut.c:657
static void init_fini(void)
Definition: service_ut.c:202
static bool rep_check(int recno, uint64_t rc, int key, int val)
Definition: service_ut.c:462
M0_INTERNAL const struct m0_fid m0_cas_meta_fid
Definition: cas.c:146
M0_INTERNAL void m0_cas__ut_svc_be_set(struct m0_reqh_service *svc, struct m0_be_domain *dom)
Definition: service.c:545
struct m0_dix_layout ci_layout
Definition: cas.h:120
int const char const void * value
Definition: dir.c:325
M0_INTERNAL struct m0_be_seg * m0_be_domain_seg0_get(struct m0_be_domain *dom)
Definition: domain.c:466
M0_INTERNAL const struct m0_fid_type m0_cas_index_fid_type
Definition: cas.c:158
static void reqh_init(bool mkfs, bool use_small_credits)
Definition: service_ut.c:114
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
struct m0_cas_recv cgr_rep
Definition: cas.h:427
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
struct m0_fop fs_fop
Definition: service_ut.c:342
static void empty_value(void)
Definition: service_ut.c:1040
static void create_create(void)
Definition: service_ut.c:670
static int void * buf
Definition: dir.c:1019
static void init(void)
Definition: service_ut.c:164
#define M0_SET0(obj)
Definition: misc.h:64
static void insert_delete(void)
Definition: service_ut.c:1008
Definition: ut.h:77
static void multi_create_drop(void)
Definition: service_ut.c:1787
struct m0_be_tx_credit bec_tx_size_max
Definition: engine.h:73
static void lookup_restart(void)
Definition: service_ut.c:1147
static void meta_cur_1(void)
Definition: service_ut.c:719
static void insert_fail(void)
Definition: service_ut.c:1317
M0_EXTERN struct m0_reqh_service_type m0_cas_service_type
Definition: cas.h:433
Definition: sock.c:887
struct m0_rpc_at_buf cr_val
Definition: cas.h:182
struct m0_fid fid
Definition: di.c:46
M0_INTERNAL void m0_cas_module_fini(void)
Definition: cas.c:188
op
Definition: libdemo.c:64
#define M0_BE_TX_CREDIT(nr, size)
Definition: tx_credit.h:94
static void insert_odd(struct m0_fid *index)
Definition: service_ut.c:1101
Definition: buf.h:37
static void meta_cur_empty(void)
Definition: service_ut.c:781
struct m0_cas_rec * cr_rec
Definition: cas.h:236
struct m0_reqh * bec_reqh
Definition: engine.h:84
static void lookup_fail(void)
Definition: service_ut.c:1341
struct m0_rpc_at_buf cr_key
Definition: cas.h:172
static void init_cgc_fail_fini(void)
Definition: service_ut.c:1946
int i
Definition: dir.c:1033
static void meta_lookup_Nnone(void)
Definition: service_ut.c:527
uint64_t cr_nr
Definition: cas.h:235
static void meta_insert_fail(void)
Definition: service_ut.c:1271
void m0_be_ut_backend_cfg_default(struct m0_be_domain_cfg *cfg)
Definition: stubs.c:227
M0_INTERNAL void m0_ref_put(struct m0_ref *ref)
Definition: refs.c:38
uint64_t rc
Definition: service_ut.c:55
static void cur_fail(void)
Definition: service_ut.c:1442
static void cctg_create_delete(void)
Definition: service_ut.c:617
static void meta_invalid(void)
Definition: service_ut.c:912
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
Definition: refs.h:34
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
static struct m0_reqh reqh
Definition: service_ut.c:58
static void multi_values_delete(struct record *recs, int recs_count)
Definition: service_ut.c:1508
struct m0_semaphore fs_end
Definition: service_ut.c:341
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
static struct m0_reqh_service * cas
Definition: service_ut.c:61
#define M0_ASSERT(cond)
static void meta_mt_thread(int idx)
Definition: service_ut.c:1232
static void delete_fail(void)
Definition: service_ut.c:1371
M0_INTERNAL void m0_reqh_service_fini(struct m0_reqh_service *service)
Definition: reqh_service.c:457
static struct m0_thread t[8]
Definition: service_ut.c:1230
static void multi_insert_fail(void)
Definition: service_ut.c:1616
struct m0_tl rh_rpc_machines
Definition: reqh.h:135
static void meta_random(void)
Definition: service_ut.c:866
void m0_thread_fini(struct m0_thread *q)
Definition: thread.c:92
static int cid_enc(struct m0_cas_id *cid, struct m0_rpc_at_buf *at_buf)
Definition: service_ut.c:75
#define M0_BUF_INIT0
Definition: buf.h:71
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 struct m0_fop_type cas_get_fopt
Definition: cas.c:47
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 void cctg_create_lookup(void)
Definition: service_ut.c:589
static void index_op(struct m0_fop_type *ft, struct m0_fid *index, uint64_t key, uint64_t val)
Definition: service_ut.c:961
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
Definition: service_ut.c:51
static void multi_delete_fail(void)
Definition: service_ut.c:1676
static void cb_fini(struct m0_fom *fom)
Definition: service_ut.c:380
static void multi_lookup_fail(void)
Definition: service_ut.c:1641
M0_INTERNAL struct m0_fop_type cas_cur_fopt
Definition: cas.c:50
M0_INTERNAL int m0_reqh_service_allocate(struct m0_reqh_service **out, const struct m0_reqh_service_type *stype, struct m0_reqh_context *rctx)
Definition: reqh_service.c:185
static void init_fail(void)
Definition: service_ut.c:211
Definition: reqh.h:94
union m0_rpc_at_buf::@447 u
uint32_t dl_type
Definition: layout.h:100
M0_INTERNAL const struct m0_fid m0_cas_dead_index_fid
Definition: cas.c:156
Definition: dump.c:103
struct m0_fid ci_fid
Definition: cas.h:113
static int at_inline_fill(struct m0_rpc_at_buf *dst, struct m0_rpc_at_buf *src)
Definition: service_ut.c:107
M0_INTERNAL void m0_reqh_service_init(struct m0_reqh_service *service, struct m0_reqh *reqh, const struct m0_fid *fid)
Definition: reqh_service.c:428
union m0_dix_layout::@145 u
static void meta_cur_none(void)
Definition: service_ut.c:799
Definition: seg.h:66
M0_INTERNAL int m0_buf_copy(struct m0_buf *dest, const struct m0_buf *src)
Definition: buf.c:104
static void multi_values_insert(struct record *recs, int recs_count)
Definition: service_ut.c:1418
struct m0_be_domain but_dom
Definition: helper.h:47
static void recs_count(void)
Definition: client_ut.c:3512
struct m0_cas_hint cr_hint
Definition: cas.h:200
static void fop_submit(struct m0_fop_type *ft, const struct m0_fid *index, struct m0_cas_rec *rec)
Definition: service_ut.c:384
static void meta_cur_eot(void)
Definition: service_ut.c:740
static bool mt
Definition: service_ut.c:67
Definition: cas.h:372
M0_INTERNAL bool m0_list_link_is_in(const struct m0_list_link *link)
Definition: list.c:181
static void m0_fi_enable_off_n_on_m(const char *func, const char *tag, uint32_t n, uint32_t m)
Definition: finject.h:346
static void meta_lookup_none(void)
Definition: service_ut.c:495
M0_INTERNAL void m0_dix_ldesc_fini(struct m0_dix_ldesc *ld)
Definition: layout.c:197
M0_INTERNAL struct m0_fop_type cas_gc_fopt
Definition: cas.c:52
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
M0_INTERNAL struct m0_fop_type cas_del_fopt
Definition: cas.c:49
Definition: fom.h:481
struct m0_be_domain_cfg but_dom_cfg
Definition: helper.h:53
const char * ts_name
Definition: ut.h:99
M0_INTERNAL void m0_reqh_start(struct m0_reqh *reqh)
Definition: reqh.c:711
static void lookup_all(struct m0_fid *index)
Definition: service_ut.c:1114
uint64_t n
Definition: fops.h:107
static void insert_lookup(void)
Definition: service_ut.c:985
M0_INTERNAL uint64_t m0_rnd64(uint64_t *seed)
Definition: misc.c:100
Definition: ext.h:37
Definition: fid.h:38
m0_bindex_t e_start
Definition: ext.h:39
void(* cas__ut_cb_done)(struct m0_fom *fom)
Definition: service.c:1712
static void index_op_rc(struct m0_fop_type *ft, struct m0_fid *index, uint64_t key, uint64_t val, uint64_t rc)
Definition: service_ut.c:942
struct m0_list_link t_link
Definition: tlist.h:266
M0_INTERNAL void m0_fop_release(struct m0_ref *ref)
Definition: fop.c:148
static void meta_fop_submit(struct m0_fop_type *fopt, struct meta_rec *meta_recs, int meta_recs_num)
Definition: service_ut.c:432
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
static void multi_values_lookup(struct record *recs, int recs_count)
Definition: service_ut.c:1485
static int r[NR]
Definition: thread.c:46
static void meta_lookup_fail(void)
Definition: service_ut.c:1285
M0_INTERNAL int m0_cas_module_init(void)
Definition: cas.c:173
#define CB(x)
Definition: service_ut.c:1098
static void fop_release(struct m0_ref *ref)
Definition: service_ut.c:336
int32_t cgr_rc
Definition: cas.h:416
m0_bcount_t size
Definition: di.c:39
struct m0_ut_suite cas_service_ut
Definition: service_ut.c:1959
M0_INTERNAL void m0_rpc_at_fini(struct m0_rpc_at_buf *ab)
Definition: at.c:441
static void server_restart_nomkfs(void)
Definition: service_ut.c:1725
struct m0_rpc_at_buf cr_key
Definition: cas.h:290
static void create_insert_drop_with_fail(bool inject_fail)
Definition: service_ut.c:1864
static void meta_cid_submit(struct m0_fop_type *fopt, struct m0_cas_id *cid)
Definition: service_ut.c:467
void m0_be_ut_backend_fini(struct m0_be_ut_backend *ut_be)
Definition: stubs.c:242
static bool rec_check(const struct m0_cas_rec *rec, int rc, int key, int val)
Definition: service_ut.c:455
M0_INTERNAL void m0_reqh_idle_wait_for(struct m0_reqh *reqh, struct m0_reqh_service *service)
Definition: reqh.c:591
M0_INTERNAL bool m0_ut_small_credits(void)
Definition: ut.c:645
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
Definition: record.py:1
static void multi_delete(void)
Definition: service_ut.c:1581
uint64_t key
Definition: service_ut.c:1414
static void restart(void)
Definition: service_ut.c:312
#define IFID(x, y)
Definition: service_ut.c:48
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
M0_INTERNAL struct m0_fop_type cas_put_fopt
Definition: cas.c:48
Definition: finject.c:59
static struct m0_fop_type * ft[]
Definition: service_ut.c:856
static struct m0_cas_rec repv[N]
Definition: service_ut.c:65
static void insert_2(void)
Definition: service_ut.c:1066
static void meta_cur_all(void)
Definition: service_ut.c:822
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
static void service_stop(void)
Definition: service_ut.c:169
static int total
Definition: base.c:302
M0_INTERNAL const struct m0_fid m0_cas_ctidx_fid
Definition: cas.c:151
static struct m0_reqh_service * fdmi
Definition: service_ut.c:62
int type
Definition: dir.c:1031
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
static void reinit_nomkfs(void)
Definition: service_ut.c:193
static struct m0_dtm_oper_descr reply
Definition: transmit.c:94
static void delete_2(void)
Definition: service_ut.c:1083
static void meta_delete_fail(void)
Definition: service_ut.c:1302
uint64_t cr_rc
Definition: cas.h:221
Definition: cas.h:107
static void meta_lookup_2none(void)
Definition: service_ut.c:506
#define M0_BUF_INIT(size, data)
Definition: buf.h:64
struct m0_be_engine_cfg bc_engine
Definition: domain.h:79
struct m0_pdclust_src_addr src
Definition: fd.c:108
struct m0_cas_id cid
Definition: service_ut.c:54
static struct m0_rpc_machine rpc_machine
Definition: service_ut.c:63
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
struct m0_fid g_process_fid
Definition: ut.c:689
static void lookup_N(void)
Definition: service_ut.c:1135
#define M0_UT_ASSERT(a)
Definition: ut.h:46
static struct m0_be_ut_backend be
Definition: service_ut.c:59
void(* cas__ut_cb_fini)(struct m0_fom *fom)
Definition: service.c:1713
Definition: fop.h:79
static void cctg_create(void)
Definition: service_ut.c:557
static struct flock_ut_fom fs[NR]
Definition: flock.c:59
struct m0_cas_id cg_id
Definition: cas.h:374
static void multi_lookup(void)
Definition: service_ut.c:1552
static void meta_fid_submit(struct m0_fop_type *fopt, struct m0_fid *fid)
Definition: service_ut.c:485
uint32_t ab_type
Definition: at.h:251
Definition: idx_mock.c:47
static void _init(bool mkfs, bool use_small_credits)
Definition: service_ut.c:137
static void create_insert_drop_fail()
Definition: service_ut.c:1941
static void meta_mt(void)
Definition: service_ut.c:1251