Motr  M0
rcredits.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "lib/trace.h"
24 #include "lib/chan.h"
25 #include "lib/semaphore.h"
26 #include "rm/rm.h"
27 #include "rm/rm_internal.h"
28 #include "ut/ut.h"
29 #include "rm/ut/rmut.h"
30 #include "rm/ut/rings.h"
31 
32 /* Maximum test servers for all test cases */
37 
41 };
42 
43 static void server1_in_complete(struct m0_rm_incoming *in, int32_t rc)
44 {
45  M0_UT_ASSERT(in != NULL);
47 }
48 
49 static void server1_in_conflict(struct m0_rm_incoming *in)
50 {
52 }
53 
56  .rio_conflict = server1_in_conflict
57 };
58 
59 static void server2_in_complete(struct m0_rm_incoming *in, int32_t rc)
60 {
61  M0_UT_ASSERT(in != NULL);
63 }
64 
65 static void server2_in_conflict(struct m0_rm_incoming *in)
66 {
68 }
69 
72  .rio_conflict = server2_in_conflict
73 };
74 
75 static void server3_in_complete(struct m0_rm_incoming *in, int32_t rc)
76 {
77  M0_UT_ASSERT(in != NULL);
79 }
80 
81 static void server3_in_conflict(struct m0_rm_incoming *in)
82 {
84 }
85 
88  .rio_conflict = server3_in_conflict
89 };
90 
91 static void trick_in_complete(struct m0_rm_incoming *in, int32_t rc)
92 {
93  M0_UT_ASSERT(in != NULL);
95 }
96 
97 static void trick1_in_conflict(struct m0_rm_incoming *in)
98 {
101 
102  in2->rin_reserve.rrp_time = in2->rin_req_time = in1->rin_req_time - 1;
104 }
105 
108  .rio_conflict = trick1_in_conflict
109 };
110 
111 static void trick2_in_conflict(struct m0_rm_incoming *in)
112 {
115 
116  in2->rin_reserve.rrp_time = in2->rin_req_time = in1->rin_req_time;
118  &in2->rin_reserve.rrp_owner) < 0);
120 }
121 
124  .rio_conflict = trick2_in_conflict
125 };
126 
127 /*
128  * Hierarchy description:
129  * SERVER_1 is downward debtor for SERVER_2.
130  * SERVER_2 is upward creditor for SERVER_1 and downward debtor for SERVER_3.
131  * SERVER_3 is upward creditor for SERVER_2.
132  */
133 static void chain_hier_config(void)
134 {
138 
142 
146 }
147 
148 static void star_hier_config(void)
149 {
153 
157 
162 }
163 
164 static void remote_credits_utinit(enum rcredits_hier_type hier_type)
165 {
166  uint32_t i;
167 
168  M0_PRE(M0_IN(hier_type, (RCREDITS_HIER_CHAIN, RCREDITS_HIER_STAR)));
169  test_servers_nr = 3;
170  for (i = 0; i < test_servers_nr; ++i)
171  rm_ctx_init(&rm_ctxs[i], i);
172 
174 
175  if (hier_type == RCREDITS_HIER_CHAIN)
177  else if (hier_type == RCREDITS_HIER_STAR)
179 
180  /* Start RM servers */
181  for (i = 0; i < test_servers_nr; ++i) {
182  rings_utdata_ops_set(&rm_ctxs[i].rc_test_data);
184  M0_UT_ASSERT(!rm_ctxs[i].rc_is_dead);
185  }
186 
187  /* Set creditors cookie, so incoming RM service requests
188  * will be handled by owners stored in rm_ctxs[] context */
189  if (hier_type == RCREDITS_HIER_CHAIN) {
191  } else if (hier_type == RCREDITS_HIER_STAR) {
193  }
195 }
196 
197 static void remote_credits_utfini(void)
198 {
199  int32_t i;
200 
201  /*
202  * Following loops cannot be combined.
203  * The ops within the loops need sync points. Hence they are separate.
204  */
205  /* De-construct RM objects hierarchy */
206  for (i = test_servers_nr - 1; i >= 0; --i)
208 
209  /* Disconnect the servers */
210  for (i = test_servers_nr - 1; i >= 0; --i)
213 
214  /*
215  * Finalise the servers. Must be done in the reverse order, so that the
216  * first initialised reqh is finalised last.
217  */
218  for (i = test_servers_nr - 1; i >= 0; --i)
219  rm_ctx_fini(&rm_ctxs[i]);
220 }
221 
222 static void credit_setup(enum rm_server srv_id,
224  uint64_t value)
225 {
226  struct m0_rm_incoming *in = &rm_ctxs[srv_id].rc_test_data.rd_in;
227  struct m0_rm_owner *owner = rm_ctxs[srv_id].rc_test_data.rd_owner;
228 
230  in->rin_want.cr_datum = value;
231  switch (srv_id) {
232  case SERVER_1:
234  break;
235  case SERVER_2:
237  break;
238  case SERVER_3:
240  break;
241  default:
242  M0_IMPOSSIBLE("Invalid server id");
243  break;
244  }
245 }
246 
247 static void credit_get_and_hold_nowait(enum rm_server debtor_id,
249  uint64_t credit_value)
250 {
251  struct m0_rm_incoming *in = &rm_ctxs[debtor_id].rc_test_data.rd_in;
252 
253  credit_setup(debtor_id, flags, credit_value);
254  m0_rm_credit_get(in);
255 }
256 
257 static void wait_for_credit(enum rm_server srv_id)
258 {
259  struct m0_rm_incoming *in = &rm_ctxs[srv_id].rc_test_data.rd_in;
260 
261  m0_chan_wait(&rm_ctxs[srv_id].rc_clink);
263  M0_UT_ASSERT(in->rin_rc == 0);
264 }
265 
266 static void credit_get_and_hold(enum rm_server debtor_id,
268  uint64_t credit_value)
269 {
270  credit_get_and_hold_nowait(debtor_id, flags, credit_value);
271  wait_for_credit(debtor_id);
272 }
273 
274 static void held_credit_cache(enum rm_server srv_id)
275 {
276  struct m0_rm_incoming *in = &rm_ctxs[srv_id].rc_test_data.rd_in;
277 
279  &rm_ctxs[srv_id].rc_test_data.rd_owner->ro_owned[OWOS_HELD]));
280  m0_rm_credit_put(in);
282 }
283 
284 static void credit_get_and_cache(enum rm_server debtor_id,
286  uint64_t credit_value)
287 {
288  credit_get_and_hold(debtor_id, flags, credit_value);
289  held_credit_cache(debtor_id);
290 }
291 
292 static void borrow_and_cache(enum rm_server debtor_id,
293  uint64_t credit_value)
294 {
295  return credit_get_and_cache(debtor_id, RIF_MAY_BORROW, credit_value);
296 }
297 
298 static void borrow_and_hold(enum rm_server debtor_id,
299  uint64_t credit_value)
300 {
301  return credit_get_and_hold(debtor_id, RIF_MAY_BORROW, credit_value);
302 }
303 
305 {
307 
308  /* Get NENYA from Server-3 to Server-2 */
310 
311  /* Get NENYA from Server-2 and DURIN from Server-3 via Server-2 */
313 
320 
322 }
323 
325 {
327 
328  /* Get NENYA from Server-3 to Server-1 */
330 
331  /*
332  * NENYA is on SERVER_1. VILYA is on SERVER_3.
333  * Make sure both borrow and revoke succeed in a single request.
334  */
336  NENYA | VILYA);
337 
343 
345 }
346 
347 static void test_revoke_with_hop(void)
348 {
349  /*
350  * Test case checks credit revoking through intermediate owner.
351  */
353 
354  /* ANGMAR is on SERVER_3, SERVER_1 borrows it through SERVER_2 */
356 
357  /* ANGMAR is revoked from SERVER_1 through SERVER_2 */
359 
364 
366 }
367 
368 static void test_no_borrow_flag(void)
369 {
371 
373 
374  /*
375  * Don't specify RIF_MAY_BORROW flag.
376  * We should get the error -EREMOTE as NENYA is on SERVER_3.
377  */
379  m0_rm_credit_get(in);
380  m0_chan_wait(&rm_ctxs[SERVER_2].rc_clink);
382  M0_UT_ASSERT(in->rin_rc == -EREMOTE);
384 
386 }
387 
388 static void test_simple_borrow(void)
389 {
391 
392  /* Get NENYA from SERVER_3 to SERVER_2 */
394 
399 
401 }
402 
404 {
406 
411 
413 }
414 
416 {
419 
422 
424  NENYA);
429 
433 
436 }
437 
439 {
441 
443 
446 
448  NENYA);
449  m0_chan_wait(&rm_ctxs[SERVER_3].rc_clink);
451  M0_UT_ASSERT(in3->rin_rc == -EBUSY);
452 
455 
458 }
459 
461 {
464 
467 
472 
477 
481 }
482 
484 {
486 
488 
491 
493  SHARED_RING);
494  m0_chan_wait(&rm_ctxs[SERVER_3].rc_clink);
496  M0_UT_ASSERT(in3->rin_rc == -EBUSY);
497 
500 
503 }
504 
506 {
508 
511 
512  /*
513  * Held non-conflicting credits shouldn't be borrowed.
514  */
516 
522 
525 }
526 
528 {
530 
534 
539 
545 
549 }
550 
551 static void test_starvation(void)
552 {
553  enum {
554  CREDIT_GET_LOOPS = 10,
555  };
556  int i;
557 
558  /*
559  * Test idea is to simulate starvation for incoming request, when
560  * two credits satisfying this request are constantly borrowed/revoked,
561  * but not owned together at any given time.
562  */
566 
571 
573 
574  for (i = 0; i < CREDIT_GET_LOOPS; i++) {
575  /*
576  * Do cache/hold cycle for NARYA and NENYA, so SERVER_3 will
577  * check incoming request for ALLRINGS constantly after each
578  * successful revoke. But SERVER_3 owns either NARYA or NENYA at
579  * a given time, not both.
580  */
586  NARYA);
588 
594  NENYA);
596  }
597  /* Request for all rings is not satisfied yet */
604 
608 }
609 
610 static void test_barrier(void)
611 {
615 
616  /*
617  * Test checks that credits suitable for request with RIF_RESERVE
618  * flag are reserved, so they are not granted to other requests without
619  * RIF_RESERVE flag.
620  */
625 
627  ALLRINGS);
628 
633  /*
634  * Try to get NARYA back, while NENYA is on SERVER_2. Normally
635  * request would succeed, but SERVER_3 use RIF_RESERVE
636  * flag forcing NARYA revocation and holding on SERVER_3 until
637  * request for all rings is granted.
638  */
641  /* Request is not satisfied within 1 second */
643  m0_time_from_now(1, 0)));
645 
650 
651  /* Credits for all rings are granted */
654 
655  /* Allow request for NARYA to complete */
660 
664 }
665 
667 {
668  struct m0_rm_incoming trick_in;
669  struct m0_rm_owner *owner2;
670 
671  remote_credits_utinit(hier);
674 
675  /*
676  * Test checks that barrier (M0_RPF_BARRIER) set for credit can be
677  * overcome by request with smaller origination timestamp.
678  *
679  * Credit flow diagram to check in case of star topology:
680  * SERVER_1 SERVER_3 SERVER_2
681  * | ---| |
682  * | hold NENYA | | |
683  * | -->| |
684  * | | ---|
685  * | | NENYA | |
686  * | | -->|
687  * |--- | |
688  * | | NENYA | |
689  * |<-- | |
690  * | borrow NENYA | |
691  * |-------------------------->| |
692  * | | borrow NENYA |
693  * | |<--------------------------|
694  * | ---| |
695  * | release NENYA | | |
696  * | -->| |
697  * | | grant NENYA |
698  * | |-------------------------->|
699  *
700  * SERVER_3 grants NENYA to SERVER_2 instead of SERVER_1 because
701  * local request for NENYA was earlier on SERVER_2.
702  *
703  * Special trick is implemented to simulate such events ordering.
704  * Actually local request for NENYA on SERVER_2 is issued later than on
705  * SERVER_1, but timestamp is overridden in trick1_in_conflict()
706  * callback. In order to invoke this callback SERVER_2 gets NARYA and
707  * after that NARYA | NENYA, therefore provoking conflict.
708  *
709  * Chain topology case:
710  * SERVER_1 SERVER_2 SERVER_3
711  * | | ---|
712  * | | hold NENYA | |
713  * | | -->|
714  * | |--- |
715  * | | | NENYA (t2) |
716  * | |<-- |
717  * | borrow NENYA (t1) | |
718  * |-------------------------->| |
719  * | | borrow NENYA (t1) |
720  * | |-------------------------->|
721  * | | ---|
722  * | | release NENYA | |
723  * | | -->|
724  * | | grant NENYA |
725  * | |<--------------------------|
726  * | |--- |
727  * | | | grant NENYA |
728  * | |<-- |
729  *
730  * On diagram above t1, t2 denotes timestamps of original local request.
731  * Because of t2<t1 SERVER_2 local request is granted before borrow
732  * request from SERVER_1.
733  */
734 
735  /* Hold NARYA to make trick with timestamp overwrite */
737  m0_rm_incoming_init(&trick_in, owner2, M0_RIT_LOCAL, RINGS_RIP,
739  trick_in.rin_want.cr_datum = NARYA;
740  trick_in.rin_ops = &trick1_incoming_ops;
741  m0_rm_credit_get(&trick_in);
742  m0_chan_wait(&rm_ctxs[SERVER_2].rc_clink);
744 
751  NARYA | NENYA);
752 
754  m0_rm_credit_put(&trick_in);
755  m0_rm_incoming_fini(&trick_in);
758 
759  /*
760  * In case of chain topology only one borrow request is sent, so
761  * conflict callback called only once on SERVER_3.
762  */
763  if (hier == RCREDITS_HIER_STAR)
774 
778 }
779 
780 static void test_barrier_overcome_star(void)
781 {
783 }
784 
786 {
788 }
789 
790 static void test_barrier_same_time(void)
791 {
792  struct m0_rm_incoming trick_in;
793  struct m0_rm_owner *owner2;
794 
798 
799  /*
800  * Test checks that if timestamps of two requests with RIF_RESERVE flag
801  * are equal, then credit is reserved for request originated by owner
802  * with smaller fid.
803  *
804  * Credits flow is similar to test_barrier_overcome_star(), but in this
805  * test SERVER_1 is granted NENYA first. Also similar trick is used to
806  * set equal timestamps for two requests.
807  */
809  m0_rm_incoming_init(&trick_in, owner2, M0_RIT_LOCAL, RINGS_RIP,
811  trick_in.rin_want.cr_datum = NARYA;
812  trick_in.rin_ops = &trick2_incoming_ops;
813  m0_rm_credit_get(&trick_in);
814  m0_chan_wait(&rm_ctxs[SERVER_2].rc_clink);
816 
823  NARYA | NENYA);
824 
826  m0_rm_credit_put(&trick_in);
827  m0_rm_incoming_fini(&trick_in);
830 
841 
845 }
846 
847 static void remote_ha_state_update(enum rm_server server,
848  enum m0_ha_obj_state new_state)
849 {
850  struct m0_ha_note n1[] = {
851  { M0_FID_TINIT('s', 0, rm_ctxs[server].rc_id), new_state },
852  };
853  struct m0_ha_nvec nvec = { ARRAY_SIZE(n1), n1 };
854 
855  m0_ha_state_accept(&nvec, false);
856 }
857 
858 /* creditor/debtor death - simulate HA note acceptance */
859 static void remote_die(enum rm_server server)
860 {
862  rm_ctxs[server].rc_is_dead = true;
863 }
864 
865 static void rm_server_restart(enum rm_server server)
866 {
868  rm_ctx_server_stop(server);
869  rm_ctx_server_start(server);
870  rm_ctxs[server].rc_is_dead = false;
871 }
872 
873 static void remote_online(enum rm_server server)
874 {
875  rm_server_restart(server);
877 }
878 
880  enum rm_server waiter)
881 {
882  struct rm_ctx *sctx = &rm_ctxs[dead];
883  struct rm_ctx *wctx = &rm_ctxs[waiter];
884  struct m0_rm_remote *remote;
885  struct m0_rm_resource *res;
886  struct m0_cookie cookie;
887  bool death_accepted;
888 
889  res = wctx->rc_test_data.rd_res;
890  m0_cookie_init(&cookie, &sctx->rc_test_data.rd_owner->ro_id);
891  m0_mutex_lock(&res->r_mutex);
892  remote = m0_tl_find(m0_remotes, other, &res->r_remotes,
893  m0_cookie_is_eq(&other->rem_cookie, &cookie));
894  if (remote != NULL)
896  m0_mutex_unlock(&res->r_mutex);
897  if (remote == NULL)
898  return;
899  /* Busy loop to wait until remote->rem_dead flag is set */
900  do {
902  death_accepted = remote->rem_dead;
904  } while (!death_accepted);
906 }
907 
908 static void test_debtor_death(void)
909 {
911 
912  /* Get NENYA from SERVER_3 to SERVER_2 */
914 
919 
921  /*
922  * Debtor death is handled asynchronously through AST,
923  * wait until AST is executed.
924  */
926 
927  /* SERVER_3 revoked automatically all sub-let loans to SERVER_2 */
930 
932 }
933 
934 static void rm_ctx_creditor_track(enum rm_server srv_id)
935 {
936  struct m0_rm_owner *owner = rm_ctxs[srv_id].rc_test_data.rd_owner;
937  struct m0_rm_remote *creditor = owner->ro_creditor;
938  struct m0_confc *confc;
939  const char *rem_ep;
940  int rc;
941 
942  confc = m0_reqh2confc(&rm_ctxs[srv_id].rc_rmach_ctx.rmc_reqh);
945  M0_ASSERT(rc == 0);
946 }
947 
948 static void test_creditor_death(void)
949 {
950  int rc;
951  struct m0_rm_remote *rem_creditor;
952 
954 
957  /* Get NENYA from SERVER_3 to SERVER_1 through SERVER_2 */
959 
966 
968 
969  /*
970  * SERVER_3 is dead.
971  * SERVER_2 makes "self-windup" on loosing the creditor (in order to
972  * cleanup all borrowed credits). It implies revoking NENYA from
973  * SERVER_1. SERVER_2 eventually transits to ROS_FINAL state.
974  */
975  rc = m0_rm_owner_timedwait(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
977  M0_ASSERT(rc == 0);
982 
983  /*
984  * SERVER_1 receive -ENODEV for NENYA request since SERVER_2 is in
985  * ROS_DEAD_CREDITOR state.
986  */
988  m0_chan_wait(&rm_ctxs[SERVER_1].rc_clink);
989  M0_UT_ASSERT(rm_ctxs[SERVER_1].rc_test_data.rd_in.rin_rc == -ESTALE);
990 
991  /* Re-init SERVER_2 for clean UT finalisation */
993  m0_rm_owner_fini(rm_ctxs[SERVER_2].rc_test_data.rd_owner);
994  m0_rm_owner_init_rfid(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
997  rem_creditor);
998 
1000 }
1001 
1002 static void test_creditor_death2(void)
1003 {
1004  int rc;
1005  struct m0_rm_remote *rem_creditor;
1006 
1008 
1011 
1014 
1015  /*
1016  * SERVER_2 calls conflict callback for all held credits, since these
1017  * credits are not valid anymore because of the creditor's death.
1018  * Wait until conflict callback is called and put credit, so owner can
1019  * proceed with "self-windup".
1020  */
1023  rc = m0_rm_owner_timedwait(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
1025  M0_ASSERT(rc == 0);
1028 
1029  /* Re-init SERVER_2 for clean UT finalisation */
1031  m0_rm_owner_fini(rm_ctxs[SERVER_2].rc_test_data.rd_owner);
1032  m0_rm_owner_init_rfid(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
1033  &m0_rm_no_group,
1035  rem_creditor);
1036 
1039 }
1040 
1041 static void test_creditor_recovered(void)
1042 {
1043  int rc;
1044 
1046 
1049 
1053 
1054  rc = m0_rm_owner_timedwait(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
1056  M0_ASSERT(rc == 0);
1057 
1060 
1062  m0_chan_wait(&rm_ctxs[SERVER_2].rc_clink);
1063  M0_UT_ASSERT(rm_ctxs[SERVER_2].rc_test_data.rd_in.rin_rc == -ENODEV);
1064 
1065  /* Imitate HA notification that creditor is M0_NC_ONLINE again */
1067  rc = m0_rm_owner_timedwait(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
1069  M0_ASSERT(rc == 0);
1071 
1072  /* Now credit request is granted */
1076 
1078 }
1079 
1080 static void test_creditor_reset(void)
1081 {
1082  int rc;
1083  struct m0_rm_owner *owner2;
1084 
1086 
1089 
1092 
1094 
1095  rc = m0_rm_owner_timedwait(rm_ctxs[SERVER_2].rc_test_data.rd_owner,
1097  M0_ASSERT(rc == 0);
1100 
1102  m0_chan_wait(&rm_ctxs[SERVER_2].rc_clink);
1103  M0_UT_ASSERT(rm_ctxs[SERVER_2].rc_test_data.rd_in.rin_rc == -ENODEV);
1104 
1105  /*
1106  * Reset creditor for SERVER_2, so SERVER_2 local owner is ROS_ACTIVE
1107  * again. Actually it is the same creditor, but rm owner is indifferent
1108  * to this trick. Restart SERVER_3 to re-initialise possessed credits.
1109  */
1112  m0_rm_owner_creditor_reset(owner2, owner2->ro_creditor);
1114 
1115  /* Now credit request is granted */
1119 
1121 }
1122 
1124  .ts_name = "rm-rcredits-ut",
1125  .ts_tests = {
1126  { "no-borrow-flag" , test_no_borrow_flag },
1127  { "simple-borrow" , test_simple_borrow },
1128  { "two-borrows-single-req" , test_two_borrows_single_req },
1129  { "borrow-revoke-single-req" , test_borrow_revoke_single_req },
1130  { "revoke-with-hop" , test_revoke_with_hop },
1131  { "revoke-conflicting-wait" , test_revoke_conflicting_wait },
1132  { "revoke-conflicting-try" , test_revoke_conflicting_try },
1133  { "borrow-non-conflicting" , test_borrow_non_conflicting },
1134  { "revoke-no-conflict-wait" , test_revoke_no_conflict_wait },
1135  { "revoke-no-conflict-try" , test_revoke_no_conflict_try },
1136  { "borrow-held-no-conflict" , test_borrow_held_no_conflict },
1137  { "borrow-held-conflicting" , test_borrow_held_conflicting },
1138  { "starvation" , test_starvation },
1139  { "barrier" , test_barrier },
1140  { "barrier-overcome-star" , test_barrier_overcome_star },
1141  { "barrier-overcome-chain" , test_barrier_overcome_chain },
1142  { "barrier-same-time" , test_barrier_same_time },
1143  { "debtor-death" , test_debtor_death },
1144  { "creditor-death" , test_creditor_death },
1145  { "creditor-death2" , test_creditor_death2 },
1146  { "creditor-recovered" , test_creditor_recovered },
1147  { "creditor-reset" , test_creditor_reset },
1148  { NULL, NULL }
1149  }
1150 };
1151 
1152 /*
1153  * Local variables:
1154  * c-indentation-style: "K&R"
1155  * c-basic-offset: 8
1156  * tab-width: 8
1157  * fill-column: 80
1158  * scroll-step: 1
1159  * End:
1160  */
Definition: rmut.h:47
static void test_revoke_no_conflict_wait(void)
Definition: rcredits.c:460
Definition: rm.h:886
static void test_no_borrow_flag(void)
Definition: rcredits.c:368
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
static void remote_ha_state_update(enum rm_server server, enum m0_ha_obj_state new_state)
Definition: rcredits.c:847
static void test_simple_borrow(void)
Definition: rcredits.c:388
#define M0_PRE(cond)
static void test_barrier_overcome(enum rcredits_hier_type hier)
Definition: rcredits.c:666
static void rm_ctx_creditor_track(enum rm_server srv_id)
Definition: rcredits.c:934
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
static void star_hier_config(void)
Definition: rcredits.c:148
m0_time_t rin_req_time
Definition: rm.h:1473
static const struct m0_rm_incoming_ops server2_incoming_ops
Definition: rcredits.c:70
M0_INTERNAL void m0_chan_broadcast_lock(struct m0_chan *chan)
Definition: chan.c:178
int const char const void size_t int flags
Definition: dir.c:328
uint64_t cr_datum
Definition: rm.h:514
#define NULL
Definition: misc.h:38
static void server3_in_conflict(struct m0_rm_incoming *in)
Definition: rcredits.c:81
static struct m0_rm_remote creditor
Definition: file.c:95
struct rm_ctx rm_ctxs[SERVER_NR]
Definition: rmut.c:54
struct m0_rm_remote * ro_creditor
Definition: rm.h:1026
void creditor_cookie_setup(enum rm_server dsrv_id, enum rm_server csrv_id)
Definition: rmut.c:420
static void credit_get_and_hold_nowait(enum rm_server debtor_id, enum m0_rm_incoming_flags flags, uint64_t credit_value)
Definition: rcredits.c:247
static const struct m0_rm_incoming_ops server1_incoming_ops
Definition: rcredits.c:54
static void test_borrow_non_conflicting(void)
Definition: rcredits.c:403
void(* rio_complete)(struct m0_rm_incoming *in, int32_t rc)
Definition: rm.h:1493
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static void test_creditor_recovered(void)
Definition: rcredits.c:1041
struct m0_fid rrp_owner
Definition: rm.h:1255
M0_INTERNAL bool m0_semaphore_timeddown(struct m0_semaphore *semaphore, const m0_time_t abs_timeout)
Definition: semaphore.c:75
static void rm_ctx_init(struct m0_rm_lock_ctx *ctx, struct m0_client *m0c, struct m0_fid *fid)
Definition: obj_lock.c:114
struct rm_ut_data rc_test_data
Definition: rmut.h:133
static void test_revoke_conflicting_try(void)
Definition: rcredits.c:438
static void wait_for_credit(enum rm_server srv_id)
Definition: rcredits.c:257
struct m0_rm_ha_tracker rem_tracker
Definition: rm.h:784
static void test_revoke_conflicting_wait(void)
Definition: rcredits.c:415
static void chain_hier_config(void)
Definition: rcredits.c:133
static void test_revoke_with_hop(void)
Definition: rcredits.c:347
int const char const void * value
Definition: dir.c:325
struct m0_rm_owner * rd_owner
Definition: rmut.h:112
static void remote_die(enum rm_server server)
Definition: rcredits.c:859
static const struct m0_rm_incoming_ops server3_incoming_ops
Definition: rcredits.c:86
m0_time_t rrp_time
Definition: rm.h:1251
static void test_borrow_held_no_conflict(void)
Definition: rcredits.c:505
static void test_revoke_no_conflict_try(void)
Definition: rcredits.c:483
#define M0_BITS(...)
Definition: misc.h:236
struct m0_rm_credit rin_want
Definition: rm.h:1450
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
struct m0_rpc_session * rem_session
Definition: rm.h:755
Definition: ut.h:77
M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:170
static void test_debtor_death(void)
Definition: rcredits.c:908
static void remote_online(enum rm_server server)
Definition: rcredits.c:873
M0_INTERNAL int m0_rm_owner_timedwait(struct m0_rm_owner *owner, uint64_t state, const m0_time_t abs_timeout)
Definition: rm.c:892
static void remote_credits_utinit(enum rcredits_hier_type hier_type)
Definition: rcredits.c:164
Definition: rings.h:41
static const struct m0_rm_incoming_ops trick2_incoming_ops
Definition: rcredits.c:122
Definition: rmut.h:48
static void credit_get_and_hold(enum rm_server debtor_id, enum m0_rm_incoming_flags flags, uint64_t credit_value)
Definition: rcredits.c:266
static void trick_in_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: rcredits.c:91
M0_INTERNAL const char * m0_rpc_conn_addr(const struct m0_rpc_conn *conn)
Definition: conn.c:1306
m0_rm_incoming_flags
Definition: rm.h:1183
static void borrow_and_hold(enum rm_server debtor_id, uint64_t credit_value)
Definition: rcredits.c:298
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
static enum rm_server test_servers_nr
Definition: rcredits.c:33
static void rm_ctx_fini(struct m0_ref *ref)
Definition: obj_lock.c:168
int i
Definition: dir.c:1033
static void debtor_death_acceptance_wait(enum rm_server dead, enum rm_server waiter)
Definition: rcredits.c:879
Definition: rmut.h:123
Definition: rmut.h:46
static void test_creditor_reset(void)
Definition: rcredits.c:1080
Definition: rings.h:38
M0_INTERNAL void m0_rm_incoming_init(struct m0_rm_incoming *in, struct m0_rm_owner *owner, enum m0_rm_incoming_type type, enum m0_rm_incoming_policy policy, uint64_t flags)
Definition: rm.c:1060
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
rm_server
Definition: rmut.h:45
static void rm_server_restart(enum rm_server server)
Definition: rcredits.c:865
rcredits_hier_type
Definition: rcredits.c:38
const struct m0_uint128 m0_rm_no_group
Definition: rm.c:211
#define M0_ASSERT(cond)
static struct m0_confc * confc
Definition: file.c:94
Definition: rm.h:828
static enum m0_rm_incoming_state incoming_state(const struct m0_rm_incoming *in)
Definition: rm_internal.h:285
#define M0_RM_REMOTE_PUT(remote)
Definition: rm.h:1971
Definition: rings.h:96
M0_INTERNAL void m0_rm_owner_init_rfid(struct m0_rm_owner *owner, const struct m0_uint128 *group, struct m0_rm_resource *res, struct m0_rm_remote *creditor)
Definition: rm.c:649
M0_INTERNAL void m0_rm_owner_fini(struct m0_rm_owner *owner)
Definition: rm.c:943
void rm_ctxs_conf_fini(struct rm_ctx *rm_ctxs, int ctxs_nr)
Definition: rmut.c:382
Definition: rings.h:94
static void server2_in_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: rcredits.c:59
bool rc_is_dead
Definition: rmut.h:135
static void test_two_borrows_single_req(void)
Definition: rcredits.c:304
m0_ha_obj_state
Definition: note.h:119
static void test_borrow_revoke_single_req(void)
Definition: rcredits.c:324
const struct m0_rm_incoming_ops * rin_ops
Definition: rm.h:1471
int32_t rin_rc
Definition: rm.h:1446
M0_INTERNAL bool m0_chan_trywait(struct m0_clink *link)
Definition: chan.c:331
static void held_credit_cache(enum rm_server srv_id)
Definition: rcredits.c:274
enum rm_server debtor_id[SERVER_NR - 1]
Definition: rmut.h:137
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
static struct m0_semaphore conflict1_sem
Definition: rcredits.c:34
static struct m0_rpc_server_ctx sctx
Definition: console.c:88
static void test_barrier_overcome_star(void)
Definition: rcredits.c:780
static struct m0_sm_group * resource_grp(const struct m0_rm_resource *res)
Definition: rm_internal.h:303
static void server3_in_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: rcredits.c:75
static void test_barrier(void)
Definition: rcredits.c:610
M0_INTERNAL int m0_rm_ha_subscribe_sync(struct m0_confc *confc, const char *rem_ep, struct m0_rm_ha_tracker *tracker)
Definition: rm_ha.c:360
Definition: rings.h:35
uint32_t rc_debtors_nr
Definition: rmut.h:134
void rm_ctxs_conf_init(struct rm_ctx *rm_ctxs, int ctxs_nr)
Definition: rmut.c:345
static void trick1_in_conflict(struct m0_rm_incoming *in)
Definition: rcredits.c:97
const char * ts_name
Definition: ut.h:99
Definition: rmut.h:88
M0_INTERNAL void m0_rm_credit_put(struct m0_rm_incoming *in)
Definition: rm.c:1797
static void credit_get_and_cache(enum rm_server debtor_id, enum m0_rm_incoming_flags flags, uint64_t credit_value)
Definition: rcredits.c:284
static void server2_in_conflict(struct m0_rm_incoming *in)
Definition: rcredits.c:65
static void server1_in_conflict(struct m0_rm_incoming *in)
Definition: rcredits.c:49
#define M0_RM_REMOTE_GET(remote)
Definition: rm.h:1957
static void test_barrier_same_time(void)
Definition: rcredits.c:790
static void borrow_and_cache(enum rm_server debtor_id, uint64_t credit_value)
Definition: rcredits.c:292
Definition: rings.h:57
M0_INTERNAL bool m0_chan_timedwait(struct m0_clink *link, const m0_time_t abs_timeout)
Definition: chan.c:349
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
bool m0_rm_ur_tlist_is_empty(const struct m0_tl *list)
static struct m0_rm_remote * remote
Definition: rm_fops.c:35
static bool flag
Definition: nucleus.c:266
enum rm_server creditor_id
Definition: rmut.h:136
static void test_creditor_death2(void)
Definition: rcredits.c:1002
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
static struct m0_semaphore conflict2_sem
Definition: rcredits.c:35
M0_INTERNAL void m0_rm_incoming_fini(struct m0_rm_incoming *in)
Definition: rm.c:1099
struct m0_rm_incoming rd_in
Definition: rmut.h:113
struct m0_ut_suite rm_rcredits_ut
Definition: rcredits.c:1123
static void trick2_in_conflict(struct m0_rm_incoming *in)
Definition: rcredits.c:111
Definition: rings.h:45
M0_INTERNAL void m0_rm_owner_creditor_reset(struct m0_rm_owner *owner, struct m0_rm_remote *creditor)
Definition: rm.c:904
void rings_utdata_ops_set(struct rm_ut_data *data)
Definition: rings.c:375
static void test_barrier_overcome_chain(void)
Definition: rcredits.c:785
void credits_are_equal(enum rm_server srv_id, enum rm_ut_credits_list list_id, uint64_t value)
Definition: rmut.c:429
static void test_starvation(void)
Definition: rcredits.c:551
struct m0_rm_resource * rd_res
Definition: rmut.h:111
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
M0_INTERNAL void m0_ha_state_accept(const struct m0_ha_nvec *note, bool ignore_same_state)
Definition: note.c:189
static void test_borrow_held_conflicting(void)
Definition: rcredits.c:527
void rm_ctx_server_stop(enum rm_server srv_id)
Definition: rmut.c:291
static void credit_setup(enum rm_server srv_id, enum m0_rm_incoming_flags flag, uint64_t value)
Definition: rcredits.c:222
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
static void server1_in_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: rcredits.c:43
static struct m0_semaphore conflict3_sem
Definition: rcredits.c:36
static void remote_credits_utfini(void)
Definition: rcredits.c:197
struct m0_rm_reserve_prio rin_reserve
Definition: rm.h:1475
static void test_creditor_death(void)
Definition: rcredits.c:948
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
static const struct m0_rm_incoming_ops trick1_incoming_ops
Definition: rcredits.c:106
struct m0_rpc_conn * s_conn
Definition: session.h:312
void rm_ctx_server_start(enum rm_server srv_id)
Definition: rmut.c:222
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_rm_credit_get(struct m0_rm_incoming *in)
Definition: rm.c:1758
void rm_ctx_server_owner_windup(enum rm_server srv_id)
Definition: rmut.c:264
#define M0_IMPOSSIBLE(fmt,...)
bool rem_dead
Definition: rm.h:788