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);
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  m0_free(recs);
454 }
455 
456 static bool rec_check(const struct m0_cas_rec *rec, int rc, int key, int val)
457 {
458  return ergo(rc != BANY, rc == rec->cr_rc) &&
459  ergo(key != BANY, m0_rpc_at_is_set(&rec->cr_key) == key) &&
460  ergo(val != BANY, m0_rpc_at_is_set(&rec->cr_val) == val);
461 }
462 
463 static bool rep_check(int recno, uint64_t rc, int key, int val)
464 {
465  return rec_check(&rep.cgr_rep.cr_rec[recno], rc, key, val);
466 }
467 
468 static void meta_cid_submit(struct m0_fop_type *fopt,
469  struct m0_cas_id *cid)
470 {
471  int rc;
472  struct m0_rpc_at_buf at_buf;
473 
474  rc = cid_enc(cid, &at_buf);
475  M0_UT_ASSERT(rc == 0);
477  (struct m0_cas_rec[]) {
478  { .cr_key = at_buf },
479  { .cr_rc = ~0ULL } });
480 
481  M0_UT_ASSERT(ergo(!mt, rep.cgr_rc == 0));
482  M0_UT_ASSERT(ergo(!mt, rep.cgr_rep.cr_nr == 1));
483  m0_rpc_at_fini(&at_buf);
484 }
485 
486 static void meta_fid_submit(struct m0_fop_type *fopt, struct m0_fid *fid)
487 {
488  struct m0_cas_id cid = { .ci_fid = *fid };
489 
490  meta_cid_submit(fopt, &cid);
491 }
492 
496 static void meta_lookup_none(void)
497 {
498  init();
500  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
501  fini();
502 }
503 
507 static void meta_lookup_2none(void)
508 {
509  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
510  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
511 
512  init();
514  (struct meta_rec[]) {
515  { .cid = nonce0 },
516  { .cid = nonce1 } },
517  2);
518  M0_UT_ASSERT(rep.cgr_rc == 0);
520  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
521  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
522  fini();
523 }
524 
528 static void meta_lookup_Nnone(void)
529 {
530  struct meta_rec nonce[N] = {};
531  int i;
532 
533  for (i = 0; i < ARRAY_SIZE(nonce); ++i)
534  nonce[i].cid.ci_fid = IFID(2, 3 + i);
535 
536  init();
537  meta_fop_submit(&cas_get_fopt, nonce, N);
538  M0_UT_ASSERT(rep.cgr_rc == 0);
540  M0_UT_ASSERT(m0_forall(i, N, rep_check(i, -ENOENT, BUNSET, BUNSET)));
541  fini();
542 }
543 
547 static void create(void)
548 {
549  init();
552  fini();
553 }
554 
558 static void cctg_create(void)
559 {
560  int rc;
561  struct m0_cas_id cid1 = { .ci_fid = TFID(1, 1) };
562  struct m0_cas_id cid2 = { .ci_fid = TFID(1, 2) };
563  struct m0_dix_ldesc *desc = NULL;
564  struct m0_ext range[] = {
565  { .e_start = 1, .e_end = 3 },
566  { .e_start = 5, .e_end = 7 },
567  { .e_start = 9, .e_end = 11 },
568  };
569 
570  init();
573  /* Submit CID with empty imask ranges. */
574  meta_cid_submit(&cas_put_fopt, &cid1);
576  /* Submit CID with non-empty imask ranges. */
577  desc = &cid2.ci_layout.u.dl_desc;
578  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
579  &M0_FID_INIT(10, 10));
580  M0_UT_ASSERT(rc == 0);
581  meta_cid_submit(&cas_put_fopt, &cid2);
583  m0_dix_ldesc_fini(desc);
584  fini();
585 }
586 
590 static void cctg_create_lookup(void)
591 {
592  int rc;
593  struct m0_cas_id cid = { .ci_fid = TFID(1, 1) };
594  struct m0_dix_ldesc *desc = NULL;
595  struct m0_ext range[] = {
596  { .e_start = 1, .e_end = 3 },
597  { .e_start = 5, .e_end = 7 },
598  { .e_start = 9, .e_end = 11 },
599  };
600 
601  init();
603  desc = &cid.ci_layout.u.dl_desc;
604  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
605  &M0_FID_INIT(10, 10));
606  M0_UT_ASSERT(rc == 0);
611  m0_dix_ldesc_fini(desc);
612  fini();
613 }
614 
618 static void cctg_create_delete(void)
619 {
620  int rc;
621  struct m0_cas_id cid = { .ci_fid = TFID(1, 1) };
622  struct m0_dix_ldesc *desc = NULL;
623  struct m0_ext range[] = {
624  { .e_start = 1, .e_end = 3 },
625  { .e_start = 5, .e_end = 7 },
626  { .e_start = 9, .e_end = 11 },
627  };
628 
629  init();
631 
632  /* Test operations with empty imask ranges. */
638  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
639 
640  /* Test operations with non-empty imask ranges. */
641  desc = &cid.ci_layout.u.dl_desc;
642  rc = m0_dix_ldesc_init(desc, range, ARRAY_SIZE(range), HASH_FNC_CITY,
643  &M0_FID_INIT(10, 10));
644  M0_UT_ASSERT(rc == 0);
650  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
651  m0_dix_ldesc_fini(desc);
652  fini();
653 }
654 
658 static void create_lookup(void)
659 {
660  init();
665  fini();
666 }
667 
671 static void create_create(void)
672 {
673  init();
677  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
680  fini();
681 }
682 
686 static void create_delete(void)
687 {
688  init();
694  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
695  fini();
696 }
697 
701 static void recreate(void)
702 {
703  init();
709  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
714  fini();
715 }
716 
720 static void meta_cur_1(void)
721 {
722  struct m0_cas_id cid = { .ci_fid = ifid };
723 
724  init();
728  (struct meta_rec[]) {
729  { .cid = cid, .rc = 1 } },
730  1);
731  M0_UT_ASSERT(rep.cgr_rc == 0);
734  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
735  fini();
736 }
737 
741 static void meta_cur_eot(void)
742 {
743  struct m0_cas_id cid = { .ci_fid = ifid };
744 
745  init();
749  (struct meta_rec[]) {
750  { .cid = cid, .rc = 2 } },
751  1);
752  M0_UT_ASSERT(rep.cgr_rc == 0);
755  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
756  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
757  fini();
758 }
759 
763 static void meta_cur_0(void)
764 {
765  struct m0_cas_id cid = { .ci_fid = ifid };
766 
767  init();
771  (struct meta_rec[]) {
772  { .cid = cid, .rc = 0 } },
773  1);
774  M0_UT_ASSERT(rep.cgr_rc == 0);
776  fini();
777 }
778 
782 static void meta_cur_empty(void)
783 {
784  struct m0_cas_id cid = { .ci_fid = ifid };
785 
786  init();
788  (struct meta_rec[]) {
789  { .cid = cid, .rc = 1 } },
790  1);
791  M0_UT_ASSERT(rep.cgr_rc == 0);
793  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
794  fini();
795 }
796 
800 static void meta_cur_none(void)
801 {
802  struct m0_cas_id cid = { .ci_fid = IFID(8,9) };
803 
804  init();
808  (struct meta_rec[]) {
809  { .cid = cid, .rc = 4 } },
810  1);
811  M0_UT_ASSERT(rep.cgr_rc == 0);
813  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
817  fini();
818 }
819 
823 static void meta_cur_all(void)
824 {
825  struct m0_fid fid = IFID(1, 0);
826  struct m0_cas_id cid = { .ci_fid = m0_cas_meta_fid };
827 
828  init();
832  (struct meta_rec[]) {
833  { .cid = cid , .rc = 5 } },
834  1);
835  M0_UT_ASSERT(rep.cgr_rc == 0);
837  /* meta-index record */
839  /* catalogue-index index record */
841  /* moved meta record */
843  /* newly inserted record */
845  /* nonexistent record */
846  M0_UT_ASSERT(rep_check(4, -ENOENT, BUNSET, BUNSET));
847  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr,
848  &m0_cas_meta_fid));
849  M0_UT_ASSERT(m0_fid_eq(repv[1].cr_key.u.ab_buf.b_addr,
850  &m0_cas_ctidx_fid));
851  M0_UT_ASSERT(m0_fid_eq(repv[2].cr_key.u.ab_buf.b_addr,
853  M0_UT_ASSERT(m0_fid_eq(repv[3].cr_key.u.ab_buf.b_addr, &fid));
854  fini();
855 }
856 
857 static struct m0_fop_type *ft[] = {
858  &cas_put_fopt,
859  &cas_get_fopt,
860  &cas_del_fopt,
861  &cas_cur_fopt
862 };
863 
867 static void meta_random(void)
868 {
869  enum { K = 10 };
870  struct m0_fid fid;
871  struct meta_rec mrecs[K];
872  int i;
873  int j;
874  int total;
875  uint64_t seed = time(NULL)*time(NULL);
876 
877  init();
878  for (i = 0; i < 50; ++i) {
879  struct m0_fop_type *type = ft[m0_rnd64(&seed) % ARRAY_SIZE(ft)];
880 
881  memset(mrecs, 0, sizeof(mrecs));
882  total = 0;
883  /*
884  * Keep number of operations in a fop small to avoid too large
885  * transactions.
886  */
887  for (j = 0; j < K; ++j) {
889  2, m0_rnd64(&seed) % 5);
890  mrecs[j].cid.ci_fid = fid;
891  if (type == &cas_cur_fopt) {
892  int n = m0_rnd64(&seed) % 1000;
893  if (total + n < ARRAY_SIZE(repv))
894  total += mrecs[j].rc = n;
895  }
896  }
897  meta_fop_submit(type, mrecs, K);
898  M0_UT_ASSERT(rep.cgr_rc == 0);
899  if (type != &cas_cur_fopt) {
902  BUNSET)));
903  } else {
905  }
906  }
907  fini();
908 }
909 
913 static void meta_invalid(void)
914 {
915  enum { M = 16*1024 };
916  uint64_t buf[M + M];
917  struct m0_cas_rec op[N + 1] = {};
918  int i;
919  int j;
920  uint64_t seed = time(NULL)*time(NULL);
921 
922  init();
923  for (i = 0; i < ARRAY_SIZE(buf); ++i)
924  buf[i] = m0_rnd64(&seed);
925  for (i = 0; i < 200; ++i) {
926  for (j = 0; j < 10; ++j) {
928  op[j].cr_key = (struct m0_rpc_at_buf) {
929  .ab_type = 1,
930  .u.ab_buf = M0_BUF_INIT(size,
931  buf + m0_rnd64(&seed) % M)
932  };
933 
934  }
935  op[j].cr_rc = ~0ULL;
937  &m0_cas_meta_fid, op);
938  M0_UT_ASSERT(rep.cgr_rc == -EPROTO);
939  }
940  fini();
941 }
942 
943 static void index_op_rc(struct m0_fop_type *ft, struct m0_fid *index,
944  uint64_t key, uint64_t val, uint64_t rc)
945 {
946  struct m0_buf no = M0_BUF_INIT(0, NULL);
947 
949  (struct m0_cas_rec[]) {
950  { .cr_key.u.ab_buf = key != 0 ?
951  M0_BUF_INIT(sizeof key, &key) : no,
952  .cr_key.ab_type = key != 0 ? M0_RPC_AT_INLINE :
954  .cr_val.u.ab_buf = !M0_IN(val, (NOVAL, EMPTYVAL)) ?
955  M0_BUF_INIT(sizeof val, &val) : no,
956  .cr_val.ab_type = val != NOVAL ? M0_RPC_AT_INLINE :
958  .cr_rc = rc },
959  { .cr_rc = ~0ULL } });
960 }
961 
962 static void index_op(struct m0_fop_type *ft, struct m0_fid *index,
963  uint64_t key, uint64_t val)
964 {
965  index_op_rc(ft, index, key, val, 0);
966 }
967 
971 static void insert(void)
972 {
973  init();
976  index_op(&cas_put_fopt, &ifid, 1, 2);
977  M0_UT_ASSERT(rep.cgr_rc == 0);
980  fini();
981 }
982 
986 static void insert_lookup(void)
987 {
988  init();
991  index_op(&cas_put_fopt, &ifid, 1, 2);
992  M0_UT_ASSERT(rep.cgr_rc == 0);
996  M0_UT_ASSERT(rep.cgr_rc == 0);
999  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob
1000  == sizeof (uint64_t));
1001  M0_UT_ASSERT(2 ==
1002  *(uint64_t *)rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr);
1003  fini();
1004 }
1005 
1009 static void insert_delete(void)
1010 {
1011  init();
1014  index_op(&cas_put_fopt, &ifid, 1, 2);
1015  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1016  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1017  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1019  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1020  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1021  fini();
1022 }
1023 
1027 static void lookup_none(void)
1028 {
1029  init();
1032  index_op(&cas_put_fopt, &ifid, 1, 2);
1033  index_op(&cas_get_fopt, &ifid, 3, NOVAL);
1034  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1035  fini();
1036 }
1037 
1041 static void empty_value(void)
1042 {
1043  init();
1047  M0_UT_ASSERT(rep.cgr_rc == 0);
1048  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1050  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1051  M0_UT_ASSERT(rep.cgr_rc == 0);
1052  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1053  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1054  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob == 0);
1055  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1056  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1057  M0_UT_ASSERT(rep.cgr_rc == 0);
1059  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1060  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1061  fini();
1062 }
1063 
1067 static void insert_2(void)
1068 {
1069  init();
1072  index_op(&cas_put_fopt, &ifid, 1, 2);
1074  index_op(&cas_put_fopt, &ifid, 1, 2);
1075  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
1076  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1077  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1078  fini();
1079 }
1080 
1084 static void delete_2(void)
1085 {
1086  init();
1089  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1090  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1091  fini();
1092 }
1093 
1094 enum {
1095  INSERTS = 1500,
1097 };
1098 
1099 #define CB(x) m0_byteorder_cpu_to_be64(x)
1100 #define BC(x) m0_byteorder_be64_to_cpu(x)
1101 
1102 static void insert_odd(struct m0_fid *index)
1103 {
1104  int i;
1105 
1106  for (i = 1; i < INSERTS; i += 2) {
1107  /*
1108  * Convert to big-endian to get predictable iteration order.
1109  */
1110  index_op(&cas_put_fopt, index, CB(i), i*i);
1112  }
1113 }
1114 
1115 static void lookup_all(struct m0_fid *index)
1116 {
1117  int i;
1118 
1119  for (i = 1; i < INSERTS; ++i) {
1121  if (i & 1) {
1122  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1123  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob ==
1124  sizeof (uint64_t));
1125  M0_UT_ASSERT(i * i ==
1126  *(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr);
1127  } else {
1128  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1129  }
1130  }
1131 }
1132 
1136 static void lookup_N(void)
1137 {
1138  init();
1140  insert_odd(&ifid);
1141  lookup_all(&ifid);
1142  fini();
1143 }
1144 
1148 static void lookup_restart(void)
1149 {
1150  int result;
1151 
1152  init();
1154  insert_odd(&ifid);
1155  lookup_all(&ifid);
1156  service_stop();
1157 
1158  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
1160 
1162  M0_UT_ASSERT(result == 0);
1164  result = m0_reqh_service_start(fdmi);
1165  M0_UT_ASSERT(result == 0);
1166 
1168  M0_UT_ASSERT(result == 0);
1172  lookup_all(&ifid);
1173  fini();
1174 }
1175 
1179 static void cur_N(void)
1180 {
1181  int i;
1182  int result;
1183 
1184  init();
1186  insert_odd(&ifid);
1187  service_stop();
1188 
1189  m0_reqh_rpc_mach_tlink_init_at_tail(&rpc_machine,
1191 
1193  M0_UT_ASSERT(result == 0);
1195  result = m0_reqh_service_start(fdmi);
1196  M0_UT_ASSERT(result == 0);
1197 
1199  M0_UT_ASSERT(result == 0);
1203 
1204  for (i = 1; i < INSERTS; ++i) {
1205  int j;
1206  int k;
1207 
1209  if (!(i & 1)) {
1210  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1211  continue;
1212  }
1213  for (j = i, k = 0; j < INSERTS; j += 2, ++k) {
1214  struct m0_cas_rec *r = &repv[k];
1215  struct m0_buf *buf;
1216 
1217  buf = &r->cr_val.u.ab_buf;
1218  M0_UT_ASSERT(rep_check(k, k + 1, BSET, BSET));
1219  M0_UT_ASSERT(buf->b_nob == sizeof (uint64_t));
1220  M0_UT_ASSERT(*(uint64_t *)buf->b_addr == j * j);
1221  buf = &r->cr_key.u.ab_buf;
1222  M0_UT_ASSERT(buf->b_nob == sizeof (uint64_t));
1223  M0_UT_ASSERT(*(uint64_t *)buf->b_addr == CB(j));
1224  }
1225  M0_UT_ASSERT(rep_check(k, -ENOENT, BUNSET, BUNSET));
1227  }
1228  fini();
1229 }
1230 
1231 static struct m0_thread t[8];
1232 
1233 static void meta_mt_thread(int idx)
1234 {
1235  uint64_t seed = time(NULL) * (idx + 6);
1236  int i;
1237 
1238  M0_UT_ASSERT(0 <= idx && idx < ARRAY_SIZE(t));
1239 
1240  for (i = 0; i < 20; ++i) {
1242  &IFID(2, m0_rnd64(&seed) % 5));
1243  /*
1244  * Cannot check anything: global rep and repv are corrupted.
1245  */
1246  }
1247 }
1248 
1252 static void meta_mt(void)
1253 {
1254  int i;
1255  int result;
1256 
1257  init();
1258  mt = true;
1259  for (i = 0; i < ARRAY_SIZE(t); ++i) {
1260  result = M0_THREAD_INIT(&t[i], int, NULL, &meta_mt_thread, i,
1261  "meta-mt-%i", i);
1262  M0_UT_ASSERT(result == 0);
1263  }
1264  for (i = 0; i < ARRAY_SIZE(t); ++i) {
1265  m0_thread_join(&t[i]);
1266  m0_thread_fini(&t[i]);
1267  }
1268  mt = false;
1269  fini();
1270 }
1271 
1272 static void meta_insert_fail(void)
1273 {
1274  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1275  init();
1277  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1278  index_op(&cas_put_fopt, &ifid, 1, 2);
1279  M0_UT_ASSERT(rep.cgr_rc == -ENOENT);
1280  /* Lookup process should return zero records. */
1282  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1283  fini();
1284 }
1285 
1286 static void meta_lookup_fail(void)
1287 {
1288  init();
1291  M0_UT_ASSERT(rep.cgr_rc == 0);
1292  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1293  /* Lookup process should return ENOMEM code */
1294  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1296  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1297  /* Lookup without ENOMEM returns record. */
1300  fini();
1301 }
1302 
1303 static void meta_delete_fail(void)
1304 {
1305  init();
1308  /* Delete record with fail. */
1309  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1311  M0_UT_ASSERT(rep_check(0, -ENOMEM, BUNSET, BUNSET));
1312  /* Lookup should return record. */
1315  fini();
1316 }
1317 
1318 static void insert_fail(void)
1319 {
1320  init();
1321  /* Insert meta OK. */
1324  M0_UT_ASSERT(rep.cgr_rc == 0);
1325  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1326  /* Insert key ENOMEM - fi. */
1327  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1328  index_op(&cas_put_fopt, &ifid, 1, 2);
1329  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1330  /* Search meta OK. */
1333  /* Search key, ENOENT. */
1334  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1335  M0_UT_ASSERT(rep.cgr_rc == 0);
1336  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1337  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_rc == -ENOENT);
1338  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1339  fini();
1340 }
1341 
1342 static void lookup_fail(void)
1343 {
1344  init();
1345  /* Insert meta OK. */
1348  M0_UT_ASSERT(rep.cgr_rc == 0);
1349  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1350  /* Insert key OK. */
1351  index_op(&cas_put_fopt, &ifid, 1, 2);
1353  M0_UT_ASSERT(rep.cgr_rc == 0);
1354  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1355  /* Search meta OK. */
1358  /* Search key, ENOMEM - fi. */
1359  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1360  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1361  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1362  /* Secondary search OK. */
1363  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1364  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1365  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1366  M0_UT_ASSERT(rep.cgr_rc == 0);
1367  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1368  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1369  fini();
1370 }
1371 
1372 static void delete_fail(void)
1373 {
1374  init();
1375  /* Insert meta OK. */
1378  M0_UT_ASSERT(rep.cgr_rc == 0);
1379  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1380  /* Insert key OK. */
1381  index_op(&cas_put_fopt, &ifid, 1, 2);
1383  M0_UT_ASSERT(rep.cgr_rc == 0);
1384  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1385  /* Search key OK. */
1386  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1387  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1388  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1389  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1390  /* Delete key, ENOMEM - fi. */
1391  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1392  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1393  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1394  /* Search key OK. */
1395  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1396  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1397  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1398  M0_UT_ASSERT(rep.cgr_rc == 0);
1399  M0_UT_ASSERT(repv[0].cr_val.u.ab_buf.b_nob == sizeof (uint64_t));
1400  M0_UT_ASSERT(*(uint64_t *)repv[0].cr_val.u.ab_buf.b_addr == 2);
1401  /* Delete key OK. */
1402  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1404  /* Search key, ENOENT. */
1405  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1406  M0_UT_ASSERT(rep.cgr_rc == 0);
1407  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1408  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_rc == -ENOENT);
1409  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr == NULL);
1410  fini();
1411 }
1412 
1413 struct record
1414 {
1415  uint64_t key;
1416  uint64_t value;
1417 };
1418 
1419 static void multi_values_insert(struct record *recs, int recs_count)
1420 {
1421  struct m0_cas_rec cas_recs[MULTI_INS];
1422  int i;
1423 
1425  for (i = 0; i < recs_count - 1; i++) {
1426  cas_recs[i] = (struct m0_cas_rec) {
1427  .cr_key = (struct m0_rpc_at_buf) {
1428  .ab_type = 1,
1429  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1430  &recs[i].key)
1431  },
1432  .cr_val = (struct m0_rpc_at_buf) {
1433  .ab_type = 1,
1434  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].value,
1435  &recs[i].value)
1436  },
1437  .cr_rc = 0 };
1438  }
1439  cas_recs[recs_count - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1440  fop_submit(&cas_put_fopt, &ifid, cas_recs);
1441 }
1442 
1443 static void cur_fail(void)
1444 {
1445  struct record recs[MULTI_INS];
1446  int i;
1447 
1448  init();
1449  /* Insert meta OK. */
1452  M0_UT_ASSERT(rep.cgr_rc == 0);
1453  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1454  /* Insert keys OK. */
1455  for (i = 0; i < MULTI_INS; i++) {
1456  recs[i].key = i+1;
1457  recs[i].value = i * i;
1458  }
1460  M0_UT_ASSERT(rep.cgr_rc == 0);
1463  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1464  /* Iterate from beginning, -ENOMEM. */
1465  m0_fi_enable_once("ctg_kbuf_get", "cas_alloc_fail");
1467  M0_UT_ASSERT(rep.cgr_rc == -ENOMEM);
1468  /*
1469  * Iterate from begining, first - OK, second - fail.
1470  * Service stops request processing after failure, all other reply
1471  * records are empty.
1472  */
1473  m0_fi_enable_off_n_on_m("m0_ctg_op_rc", "be-failure", 3, 2);
1475  m0_fi_disable("m0_ctg_op_rc", "be-failure");
1476  M0_UT_ASSERT(rep.cgr_rc == 0);
1478  M0_UT_ASSERT(repv[0].cr_rc == 1);
1479  M0_UT_ASSERT(repv[1].cr_rc == -ENOMEM);
1480  for (i = 2; i < MULTI_INS - 1; i++)
1481  M0_UT_ASSERT(repv[i].cr_rc == 0);
1482 
1483  fini();
1484 }
1485 
1486 static void multi_values_lookup(struct record *recs, int recs_count)
1487 {
1488  struct m0_cas_rec cas_recs[MULTI_INS];
1489  int i;
1490 
1492  for (i = 0; i < MULTI_INS - 1; i++) {
1493  cas_recs[i] = (struct m0_cas_rec){
1494  .cr_key = (struct m0_rpc_at_buf) {
1495  .ab_type = 1,
1496  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1497  &recs[i].key)
1498  },
1499  .cr_val = (struct m0_rpc_at_buf) {
1500  .ab_type = 0,
1501  .u.ab_buf = M0_BUF_INIT(0, NULL)
1502  },
1503  .cr_rc = 0 };
1504  }
1505  cas_recs[MULTI_INS - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1506  fop_submit(&cas_get_fopt, &ifid, cas_recs);
1507 }
1508 
1509 static void multi_values_delete(struct record *recs, int recs_count)
1510 {
1511  struct m0_cas_rec cas_recs[MULTI_INS];
1512  int i;
1513 
1515  for (i = 0; i < MULTI_INS - 1; i++) {
1516  cas_recs[i] = (struct m0_cas_rec){
1517  .cr_key = (struct m0_rpc_at_buf) {
1518  .ab_type = 1,
1519  .u.ab_buf = M0_BUF_INIT(sizeof recs[i].key,
1520  &recs[i].key)
1521  },
1522  .cr_val = (struct m0_rpc_at_buf) {
1523  .ab_type = 0,
1524  .u.ab_buf = M0_BUF_INIT(0, NULL)
1525  },
1526  .cr_rc = 0 };
1527  }
1528  cas_recs[MULTI_INS - 1] = (struct m0_cas_rec) { .cr_rc = ~0ULL };
1529  fop_submit(&cas_del_fopt, &ifid, cas_recs);
1530 }
1531 
1532 static void multi_insert(void)
1533 {
1534  struct record recs[MULTI_INS];
1535 
1536  init();
1537  /* Fill array with pair: [key, value]. */
1538  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1539  /* Insert meta OK. */
1542  M0_UT_ASSERT(rep.cgr_rc == 0);
1543  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1544  /* Insert several keys and values OK. */
1546  M0_UT_ASSERT(rep.cgr_rc == 0);
1549  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1550  fini();
1551 }
1552 
1553 static void multi_lookup(void)
1554 {
1555  struct record recs[MULTI_INS];
1556 
1557  init();
1558  /* Fill array with pair: [key, value]. */
1559  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1560  /* Insert meta OK. */
1563  M0_UT_ASSERT(rep.cgr_rc == 0);
1564  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1565  /* Insert several keys and values OK. */
1567  M0_UT_ASSERT(rep.cgr_rc == 0);
1570  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1571  /* Lookup values. */
1573  M0_UT_ASSERT(rep.cgr_rc == 0);
1576  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1578  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i * i));
1579  fini();
1580 }
1581 
1582 static void multi_delete(void)
1583 {
1584  struct record recs[MULTI_INS];
1585 
1586  init();
1587  /* Fill array with pair: [key, value]. */
1588  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1589  /* Insert meta OK. */
1592  M0_UT_ASSERT(rep.cgr_rc == 0);
1593  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1594  /* Insert several keys and values OK. */
1596  M0_UT_ASSERT(rep.cgr_rc == 0);
1599  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1600  /* Delete all values. */
1602  M0_UT_ASSERT(rep.cgr_rc == 0);
1605  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1606  /* Lookup values: ENOENT. */
1608  M0_UT_ASSERT(rep.cgr_rc == 0);
1611  rep.cgr_rep.cr_rec[i].cr_rc == -ENOENT));
1613  repv[i].cr_val.u.ab_buf.b_addr == NULL));
1614  fini();
1615 }
1616 
1617 static void multi_insert_fail(void)
1618 {
1619  struct record recs[MULTI_INS];
1620 
1621  init();
1622  /* Fill array with pair: [key, value]. */
1623  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i * i, true));
1624  /* Insert meta OK. */
1627  M0_UT_ASSERT(rep.cgr_rc == 0);
1628  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1629  /* Insert several keys and values OK. */
1630  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1632  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1633  M0_UT_ASSERT(rep.cgr_rc == 0);
1636  i % 2 ?
1637  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1638  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1639  fini();
1640 }
1641 
1642 static void multi_lookup_fail(void)
1643 {
1644  struct record recs[MULTI_INS];
1645 
1646  init();
1647  /* Fill array with pair: [key, value]. */
1648  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1649  /* Insert meta OK. */
1652  M0_UT_ASSERT(rep.cgr_rc == 0);
1653  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1654  /* Insert several keys and values OK. */
1656  M0_UT_ASSERT(rep.cgr_rc == 0);
1659  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1660  /* Lookup values. */
1661  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1663  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1664  M0_UT_ASSERT(rep.cgr_rc == 0);
1667  i % 2 ?
1668  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1669  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1671  i % 2 ?
1672  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i*i :
1673  repv[i].cr_val.u.ab_buf.b_addr == NULL));
1674  fini();
1675 }
1676 
1677 static void multi_delete_fail(void)
1678 {
1679  struct record recs[MULTI_INS];
1680 
1681  init();
1682  /* Fill array with pair: [key, value]. */
1683  m0_forall(i, MULTI_INS, (recs[i].key = i, recs[i].value = i*i, true));
1684  /* Insert meta OK. */
1687  M0_UT_ASSERT(rep.cgr_rc == 0);
1688  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1689  /* Insert several keys and values OK. */
1691  M0_UT_ASSERT(rep.cgr_rc == 0);
1694  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1695  /* Delete several recs. */
1696  m0_fi_enable_off_n_on_m("ctg_kbuf_get", "cas_alloc_fail", 1, 1);
1698  m0_fi_disable("ctg_kbuf_get", "cas_alloc_fail");
1699  M0_UT_ASSERT(rep.cgr_rc == 0);
1702  i % 2 ?
1703  rep.cgr_rep.cr_rec[i].cr_rc == 0 :
1704  rep.cgr_rep.cr_rec[i].cr_rc == -ENOMEM));
1705  /* Lookup values. */
1707  M0_UT_ASSERT(rep.cgr_rc == 0);
1710  i % 2 ?
1711  rep.cgr_rep.cr_rec[i].cr_rc == -ENOENT :
1712  rep.cgr_rep.cr_rec[i].cr_rc == 0));
1714  i % 2 ?
1715  repv[i].cr_val.u.ab_buf.b_addr == NULL :
1716  *(uint64_t *)repv[i].cr_val.u.ab_buf.b_addr == i * i));
1717  fini();
1718 }
1719 
1726 static void server_restart_nomkfs(void)
1727 {
1728  struct m0_cas_id cid = { .ci_fid = ifid };
1729 
1730  init();
1733  index_op(&cas_put_fopt, &ifid, 1, 2);
1734  M0_UT_ASSERT(rep.cgr_rc == 0);
1735  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1737 
1738  /* Check that index and record are present. */
1739  reinit_nomkfs();
1741  (struct meta_rec[]) {
1742  { .cid = cid, .rc = 1 } },
1743  1);
1744  M0_UT_ASSERT(rep.cgr_rc == 0);
1745  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1746  M0_UT_ASSERT(rep_check(0, 1, BSET, BUNSET));
1747  M0_UT_ASSERT(m0_fid_eq(repv[0].cr_key.u.ab_buf.b_addr, &ifid));
1748 
1749  index_op(&cas_get_fopt, &ifid, 1, NOVAL);
1750  M0_UT_ASSERT(rep.cgr_rc == 0);
1751  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1752  M0_UT_ASSERT(rep_check(0, 0, BUNSET, BSET));
1753  M0_UT_ASSERT(rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_nob
1754  == sizeof (uint64_t));
1755  M0_UT_ASSERT(2 ==
1756  *(uint64_t *)rep.cgr_rep.cr_rec[0].cr_val.u.ab_buf.b_addr);
1757 
1758  /* Check that the same record can't be inserted. */
1759  reinit_nomkfs();
1760  index_op(&cas_put_fopt, &ifid, 1, 2);
1761  M0_UT_ASSERT(rep.cgr_rc == 0);
1762  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1763  M0_UT_ASSERT(rep_check(0, -EEXIST, BUNSET, BUNSET));
1764 
1765  /* Check that record can be deleted. */
1766  reinit_nomkfs();
1767  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1769 
1770  /* Check that record was really deleted. */
1771  reinit_nomkfs();
1772  index_op(&cas_del_fopt, &ifid, 1, NOVAL);
1773  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1774 
1775  /* Check that index can deleted. */
1776  reinit_nomkfs();
1779 
1780  /* Check that index was deleted. */
1781  reinit_nomkfs();
1783  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1784 
1785  fini();
1786 }
1787 
1788 static void multi_create_drop(void)
1789 {
1790  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
1791  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
1792 
1793  init();
1795  (struct meta_rec[]) {
1796  { .cid = nonce0 },
1797  { .cid = nonce1 } },
1798  2);
1799  M0_UT_ASSERT(rep.cgr_rc == 0);
1800  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1801 
1803  (struct meta_rec[]) {
1804  { .cid = nonce0 },
1805  { .cid = nonce1 } },
1806  2);
1809 
1811  (struct meta_rec[]) {
1812  { .cid = nonce0 },
1813  { .cid = nonce1 } },
1814  2);
1815  M0_UT_ASSERT(rep.cgr_rc == 0);
1816  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1817 
1819  (struct meta_rec[]) {
1820  { .cid = nonce0 },
1821  { .cid = nonce1 } },
1822  2);
1823  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1824  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
1825 
1827  (struct meta_rec[]) {
1828  { .cid = nonce0 },
1829  { .cid = nonce1 } },
1830  2);
1831  M0_UT_ASSERT(rep.cgr_rc == 0);
1832  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1833 
1835  (struct meta_rec[]) {
1836  { .cid = nonce0 },
1837  { .cid = nonce1 } },
1838  2);
1841 
1842  fini();
1843 }
1844 
1845 enum {
1846  /*
1847  * Better have more rows, for 3-levels b-tree and multiple transactions,
1848  * but only 7000 can fit into typical 1Mb file.
1849  * 2000 is enough to test multiple transactions if decrease transaction
1850  * size limit by using -c switch.
1851  */
1853  /*
1854  * Number of rows for 2-level btree.
1855  */
1857 };
1858 
1865 static void create_insert_drop_with_fail(bool inject_fail)
1866 {
1867  struct m0_cas_id nonce0 = { .ci_fid = IFID(2, 3) };
1868  struct m0_cas_id nonce1 = { .ci_fid = IFID(2, 4) };
1869  int i;
1870 
1871  /*
1872  * Use small credits in order to split big transaction into smaller
1873  * ones. BE performs quadratic number of checks inside invariants
1874  * comparing to number of capture operations.
1875  */
1876  _init(true, true);
1877  /*
1878  * Create 2 catalogs.
1879  */
1881  (struct meta_rec[]) {
1882  { .cid = nonce0 },
1883  { .cid = nonce1 } },
1884  2);
1885  M0_UT_ASSERT(rep.cgr_rc == 0);
1886  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1887 
1888  for (i = 0 ; i < BIG_ROWS_NUMBER ; ++i) {
1889  index_op(&cas_put_fopt, &nonce0.ci_fid, i+1, i+2);
1890  M0_UT_ASSERT(rep.cgr_rc == 0);
1891  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1893  }
1894  for (i = 0 ; i < SMALL_ROWS_NUMBER ; ++i) {
1895  index_op(&cas_put_fopt, &nonce1.ci_fid, i+1, i+2);
1896  M0_UT_ASSERT(rep.cgr_rc == 0);
1897  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 1);
1899  }
1900 
1901  /*
1902  * Drop 2 catalogs.
1903  */
1905  (struct meta_rec[]) {
1906  { .cid = nonce0 },
1907  { .cid = nonce1 } },
1908  2);
1909  M0_UT_ASSERT(rep.cgr_rc == 0);
1910  M0_UT_ASSERT(rep.cgr_rep.cr_nr == 2);
1911 
1912  /*
1913  * Check that both catalogs are dropped.
1914  */
1916  (struct meta_rec[]) {
1917  { .cid = nonce0 },
1918  { .cid = nonce1 } },
1919  2);
1920  M0_UT_ASSERT(rep_check(0, -ENOENT, BUNSET, BUNSET));
1921  M0_UT_ASSERT(rep_check(1, -ENOENT, BUNSET, BUNSET));
1922 
1923  if (inject_fail)
1924  m0_fi_enable_once("cgc_fom_tick", "fail_after_index_found");
1925  /*
1926  * Wait for GC complete.
1927  */
1929  (struct meta_rec[]) {
1930  { .cid = nonce0 }},
1931  1);
1932  if (inject_fail)
1933  m0_fi_disable("cgc_fom_tick", "fail_after_index_found");
1934  fini();
1935 }
1936 
1937 static void create_insert_drop()
1938 {
1940 }
1941 
1943 {
1945 }
1946 
1947 static void init_cgc_fail_fini(void)
1948 {
1949  m0_fi_enable_once("cgc_fom_tick", "fail_in_cgc_generic_phase");
1950  init();
1951  fini();
1952  m0_fi_disable("cgc_fom_tick", "fail_in_cgc_generic_phase");
1953 
1954  m0_fi_enable_once("cgc_fom_tick", "fail_after_index_found");
1955  init();
1956  fini();
1957  m0_fi_disable("cgc_fom_tick", "fail_after_index_found");
1958 }
1959 
1961  .ts_name = "cas-service",
1962  .ts_owners = "Nikita",
1963  .ts_init = NULL,
1964  .ts_fini = NULL,
1965  .ts_tests = {
1966  { "init-fini", &init_fini, "Nikita" },
1967  { "init-fail", &init_fail, "Leonid" },
1968  { "re-init", &reinit, "Egor" },
1969  { "re-start", &restart, "Nikita" },
1970  { "meta-lookup-none", &meta_lookup_none, "Nikita" },
1971  { "meta-lookup-2-none", &meta_lookup_2none, "Nikita" },
1972  { "meta-lookup-N-none", &meta_lookup_Nnone, "Nikita" },
1973  { "create", &create, "Nikita" },
1974  { "create-lookup", &create_lookup, "Nikita" },
1975  { "create-create", &create_create, "Nikita" },
1976  { "create-delete", &create_delete, "Nikita" },
1977  { "recreate", &recreate, "Nikita" },
1978  { "meta-cur-1", &meta_cur_1, "Nikita" },
1979  { "meta-cur-0", &meta_cur_0, "Nikita" },
1980  { "meta-cur-eot", &meta_cur_eot, "Nikita" },
1981  { "meta-cur-empty", &meta_cur_empty, "Nikita" },
1982  { "meta-cur-none", &meta_cur_none, "Nikita" },
1983  { "meta-cur-all", &meta_cur_all, "Leonid" },
1984  { "meta-random", &meta_random, "Nikita" },
1985  { "meta-invalid", &meta_invalid, "Nikita" },
1986  { "insert", &insert, "Nikita" },
1987  { "insert-lookup", &insert_lookup, "Nikita" },
1988  { "insert-delete", &insert_delete, "Nikita" },
1989  { "lookup-none", &lookup_none, "Nikita" },
1990  { "empty-value", &empty_value, "Egor" },
1991  { "insert-2", &insert_2, "Nikita" },
1992  { "delete-2", &delete_2, "Nikita" },
1993  { "lookup-N", &lookup_N, "Nikita" },
1994  { "lookup-restart", &lookup_restart, "Nikita" },
1995  { "cur-N", &cur_N, "Nikita" },
1996  { "meta-mt", &meta_mt, "Nikita" },
1997  { "meta-insert-fail", &meta_insert_fail, "Leonid" },
1998  { "meta-lookup-fail", &meta_lookup_fail, "Leonid" },
1999  { "meta-delete-fail", &meta_delete_fail, "Leonid" },
2000  { "insert-fail", &insert_fail, "Leonid" },
2001  { "lookup-fail", &lookup_fail, "Leonid" },
2002  { "delete-fail", &delete_fail, "Leonid" },
2003  { "cur-fail", &cur_fail, "Egor" },
2004  { "multi-insert", &multi_insert, "Leonid" },
2005  { "multi-lookup", &multi_lookup, "Leonid" },
2006  { "multi-delete", &multi_delete, "Leonid" },
2007  { "multi-insert-fail", &multi_insert_fail, "Leonid" },
2008  { "multi-lookup-fail", &multi_lookup_fail, "Leonid" },
2009  { "multi-delete-fail", &multi_delete_fail, "Leonid" },
2010  { "multi-create-drop", &multi_create_drop, "Eugene" },
2011  { "create-insert-drop", &create_insert_drop, "Eugene" },
2012  { "create-insert-drop-fail", &create_insert_drop_fail, "Hua" },
2013  { "init-cgc-fail-fini", &init_cgc_fail_fini, "Hua" },
2014  { "cctg-create", &cctg_create, "Sergey" },
2015  { "cctg-create-lookup", &cctg_create_lookup, "Sergey" },
2016  { "cctg-create-delete", &cctg_create_delete, "Sergey" },
2017  { "server-restart-nomkfs", &server_restart_nomkfs, "Egor" },
2018  { NULL, NULL }
2019  }
2020 };
2021 
2022 #undef M0_TRACE_SUBSYSTEM
2023 
2026 /*
2027  * Local variables:
2028  * c-indentation-style: "K&R"
2029  * c-basic-offset: 8
2030  * tab-width: 8
2031  * fill-column: 80
2032  * scroll-step: 1
2033  * End:
2034  */
2035 /*
2036  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
2037  */
uint64_t cr_rc
Definition: cas.h:340
M0_EXTERN struct m0_reqh_service_type m0_fdmi_service_type
Definition: fdmi.h:194
static void lookup_none(void)
Definition: service_ut.c:1027
struct m0_rpc_at_buf cr_val
Definition: cas.h:301
static void multi_insert(void)
Definition: service_ut.c:1532
#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:1416
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:701
#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:686
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:78
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:1179
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:763
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:1937
static void create(void)
Definition: service_ut.c:547
static void cb_done(struct m0_fom *fom)
Definition: service_ut.c:345
static void insert(void)
Definition: service_ut.c:971
static void create_lookup(void)
Definition: service_ut.c:658
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:463
M0_INTERNAL const struct m0_fid m0_cas_meta_fid
Definition: cas.c:147
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:159
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:219
struct m0_cas_recv cgr_rep
Definition: cas.h:431
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:1041
static void create_create(void)
Definition: service_ut.c:671
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:1009
Definition: ut.h:77
static void multi_create_drop(void)
Definition: service_ut.c:1788
struct m0_be_tx_credit bec_tx_size_max
Definition: engine.h:73
static void lookup_restart(void)
Definition: service_ut.c:1148
static void meta_cur_1(void)
Definition: service_ut.c:720
static void insert_fail(void)
Definition: service_ut.c:1318
M0_EXTERN struct m0_reqh_service_type m0_cas_service_type
Definition: cas.h:437
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:189
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:1102
Definition: buf.h:37
static void meta_cur_empty(void)
Definition: service_ut.c:782
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:1342
struct m0_rpc_at_buf cr_key
Definition: cas.h:172
static void init_cgc_fail_fini(void)
Definition: service_ut.c:1947
int i
Definition: dir.c:1033
static void meta_lookup_Nnone(void)
Definition: service_ut.c:528
uint64_t cr_nr
Definition: cas.h:235
static void meta_insert_fail(void)
Definition: service_ut.c:1272
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:1443
static void cctg_create_delete(void)
Definition: service_ut.c:618
static void meta_invalid(void)
Definition: service_ut.c:913
#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:1509
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:1233
struct m0_xcode_type * m0_cas_id_xc
Definition: cas_xc.c:11
static void delete_fail(void)
Definition: service_ut.c:1372
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:1231
static void multi_insert_fail(void)
Definition: service_ut.c:1617
union m0_rpc_at_buf::@448 u
struct m0_tl rh_rpc_machines
Definition: reqh.h:135
static void meta_random(void)
Definition: service_ut.c:867
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:48
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:590
static void index_op(struct m0_fop_type *ft, struct m0_fid *index, uint64_t key, uint64_t val)
Definition: service_ut.c:962
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:1677
static void cb_fini(struct m0_fom *fom)
Definition: service_ut.c:380
static void multi_lookup_fail(void)
Definition: service_ut.c:1642
M0_INTERNAL struct m0_fop_type cas_cur_fopt
Definition: cas.c:51
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
uint32_t dl_type
Definition: layout.h:100
M0_INTERNAL const struct m0_fid m0_cas_dead_index_fid
Definition: cas.c:157
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:800
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:1419
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:741
static bool mt
Definition: service_ut.c:67
Definition: cas.h:376
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:496
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:53
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:50
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:1115
uint64_t n
Definition: fops.h:107
static void insert_lookup(void)
Definition: service_ut.c:986
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:1720
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:943
struct m0_list_link t_link
Definition: tlist.h:266
M0_INTERNAL void m0_fop_release(struct m0_ref *ref)
Definition: fop.c:147
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:1486
static int r[NR]
Definition: thread.c:46
static void meta_lookup_fail(void)
Definition: service_ut.c:1286
M0_INTERNAL int m0_cas_module_init(void)
Definition: cas.c:174
#define CB(x)
Definition: service_ut.c:1099
static void fop_release(struct m0_ref *ref)
Definition: service_ut.c:336
int32_t cgr_rc
Definition: cas.h:420
m0_bcount_t size
Definition: di.c:39
struct m0_ut_suite cas_service_ut
Definition: service_ut.c:1960
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:1726
struct m0_rpc_at_buf cr_key
Definition: cas.h:291
static void create_insert_drop_with_fail(bool inject_fail)
Definition: service_ut.c:1865
static void meta_cid_submit(struct m0_fop_type *fopt, struct m0_cas_id *cid)
Definition: service_ut.c:468
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:456
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:1582
uint64_t key
Definition: service_ut.c:1415
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:49
Definition: finject.c:59
static struct m0_fop_type * ft[]
Definition: service_ut.c:857
static struct m0_cas_rec repv[N]
Definition: service_ut.c:65
static void insert_2(void)
Definition: service_ut.c:1067
static void meta_cur_all(void)
Definition: service_ut.c:823
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:152
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:1084
void m0_free(void *data)
Definition: memory.c:146
static void meta_delete_fail(void)
Definition: service_ut.c:1303
uint64_t cr_rc
Definition: cas.h:221
Definition: cas.h:107
static void meta_lookup_2none(void)
Definition: service_ut.c:507
#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:1136
#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:1721
Definition: fop.h:80
static void cctg_create(void)
Definition: service_ut.c:558
static struct flock_ut_fom fs[NR]
Definition: flock.c:59
struct m0_cas_id cg_id
Definition: cas.h:378
static void multi_lookup(void)
Definition: service_ut.c:1553
static void meta_fid_submit(struct m0_fop_type *fopt, struct m0_fid *fid)
Definition: service_ut.c:486
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:1942
static void meta_mt(void)
Definition: service_ut.c:1252