Motr  M0
cm.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CM
24 #include "lib/trace.h"
25 
26 #include <unistd.h> /* usleep */
27 
28 #include "sns/cm/cm.h"
29 #include "cm/ut/common_service.h" /* cmut_rmach_ctx */
30 #include "rpc/rpclib.h" /* m0_rpc_server_ctx */
31 #include "lib/fs.h" /* m0_file_read */
32 #include "ut/misc.h" /* M0_UT_PATH */
33 #include "ut/ut.h"
34 
36 static const char *SERVER_LOGFILE = "cm_ut.log";
37 char *cm_ut_server_args[] = {
38  "m0d", "-T", "LINUX",
39  "-D", "sr_db", "-S", "sr_stob",
40  "-A", "linuxstob:sr_addb_stob",
41  "-f", M0_UT_CONF_PROCESS,
42  "-w", "10",
43  "-F",
44  "-G", M0_NET_XPRT_PREFIX_DEFAULT":0@lo:12345:34:1",
45  "-e", M0_NET_XPRT_PREFIX_DEFAULT":0@lo:12345:34:1",
46  "-c", M0_UT_PATH("conf.xc")
47 };
48 
49 static void cm_ut_server_start(void)
50 {
51  int rc;
52 
59 
61  M0_UT_ASSERT(rc == 0);
62 }
63 
64 static void cm_ut_server_stop(void)
65 {
67 }
68 
69 static struct m0_cm *cm_ut_sctx2cm(void)
70 {
71  struct m0_reqh *reqh;
72  struct m0_reqh_service *svc;
73 
76  reqh);
77  M0_UT_ASSERT(svc != NULL);
78  return container_of(svc, struct m0_cm, cm_service);
79 }
80 
81 static int cm_ut_init(void)
82 {
83  int rc;
84 
89 
91  M0_ASSERT(rc == 0);
93 
95 
96  return 0;
97 }
98 
99 static int cm_ut_fini(void)
100 {
104 
105  return 0;
106 }
107 
108 static void cm_setup_ut(void)
109 {
110  struct m0_cm *cm;
111  int rc;
112 
114  /* Internally calls m0_cm_setup(). */
116  M0_UT_ASSERT(rc == 0);
117  cm = cm_ut_sctx2cm();
118  rc = m0_cm_prepare(cm);
119  M0_UT_ASSERT(rc == 0);
120  //m0_cm_lock(cm);
121  /*
122  * Start sliding window update FOM to avoid failure during
123  * m0_cm_stop().
124  */
125  //m0_cm_state_set(cm, M0_CMS_READY);
126  //m0_cm_unlock(cm);
127  rc = m0_cm_ready(cm);
128  M0_UT_ASSERT(rc == 0);
129  /* Checks if the restructuring process is started successfully. */
130  rc = m0_cm_start(cm);
131  M0_UT_ASSERT(rc == 0);
135  usleep(200);
136 
137  m0_cm_lock(cm);
139  m0_cm_unlock(cm);
142 }
143 
144 static void cm_init_failure_ut(void)
145 {
146  int rc;
147 
148  m0_fi_enable_once("m0_cm_init", "init_failure");
150  NULL);
151  /* Set the global cm_ut_service pointer to NULL */
153  ut_cm_id = 0;
154  M0_ASSERT(cm_ut[ut_cm_id].ut_cm.cm_sw_update.swu_fom.fo_cb.fc_ast.sa_cb == NULL);
155  M0_SET0(&cm_ut[ut_cm_id].ut_cm);
156  M0_UT_ASSERT(rc != 0);
157 }
158 
159 static void cm_setup_failure_ut(void)
160 {
161  int rc;
162 
164  m0_fi_enable_once("m0_cm_setup", "setup_failure_2");
166  M0_UT_ASSERT(rc != 0);
168 }
169 
170 static void cm_prepare_failure_ut(void)
171 {
172  struct m0_cm *cm;
173  int rc;
174 
177  M0_UT_ASSERT(rc == 0);
178  cm = cm_ut_sctx2cm();
180  m0_fi_enable_once("m0_cm_prepare", "prepare_failure");
181  rc = m0_cm_prepare(cm);
182  M0_UT_ASSERT(rc != 0);
185 }
186 
187 static void cm_ready_failure_ut(void)
188 {
189  struct m0_cm *cm;
190  int rc;
191 
194  M0_UT_ASSERT(rc == 0);
195  cm = cm_ut_sctx2cm();
196  m0_fi_enable_once("m0_cm_ready", "ready_failure");
197  rc = m0_cm_prepare(cm);
198  M0_UT_ASSERT(rc == 0);
199  do {
200  usleep(200);
201  rc = m0_cm_ready(cm);
202  } while (rc == -EAGAIN);
203  M0_UT_ASSERT(rc == 0);
204  M0_UT_ASSERT(cm->cm_mach.sm_rc != 0);
207 }
208 
209 static void cm_start_failure_ut(void)
210 {
211  struct m0_cm *cm;
212  int rc;
213 
216  M0_UT_ASSERT(rc == 0);
217  cm = cm_ut_sctx2cm();
218  m0_fi_enable_once("m0_cm_start", "start_failure");
219  rc = m0_cm_prepare(cm);
220  M0_UT_ASSERT(rc == 0);
221  rc = m0_cm_ready(cm);
222  M0_UT_ASSERT(rc == 0);
223  do {
224  usleep(200);
225  rc = m0_cm_start(cm);
226  } while (rc == -EAGAIN);
227  M0_UT_ASSERT(rc == 0);
228  M0_UT_ASSERT(cm->cm_mach.sm_rc != 0);
231 }
232 
233 static void ag_id_assign(struct m0_cm_ag_id *id, uint64_t hi_hi, uint64_t hi_lo,
234  uint64_t lo_hi, uint64_t lo_lo)
235 {
236  id->ai_hi.u_hi = hi_hi;
237  id->ai_hi.u_lo = hi_lo;
238  id->ai_lo.u_hi = lo_hi;
239  id->ai_lo.u_lo = lo_lo;
240 }
241 
242 static void ag_id_test_cmp()
243 {
244  struct m0_cm_ag_id id0;
245  struct m0_cm_ag_id id1;
246  int rc;
247 
248  /* Assign random test values to aggregation group ids. */
249  ag_id_assign(&id0, 2, 3, 4, 5);
250  ag_id_assign(&id1, 4, 4, 4, 4);
251  rc = m0_cm_ag_id_cmp(&id0, &id1);
252  M0_UT_ASSERT(rc < 0);
253  rc = m0_cm_ag_id_cmp(&id1, &id0);
254  M0_UT_ASSERT(rc > 0);
255  rc = m0_cm_ag_id_cmp(&id0, &id0);
256  M0_UT_ASSERT(rc == 0);
257 }
258 
259 static void ag_id_test_find()
260 {
261  struct m0_cm_ag_id id;
262  int i;
263  int rc;
264  struct m0_cm_aggr_group *ag;
265  struct m0_cm *cm = &cm_ut[0].ut_cm;
266 
267  for (i = AG_ID_NR - 1; i >= 0; --i) {
268  ag_id_assign(&id, i, i, i, i);
269  ag = m0_cm_aggr_group_locate(cm, &id, false);
270  M0_UT_ASSERT(ag != NULL);
271  rc = m0_cm_ag_id_cmp(&id, &ag->cag_id);
272  M0_UT_ASSERT(rc == 0);
273  }
274  ag_id_assign(&id, 10, 35, 2, 3);
275  ag = m0_cm_aggr_group_locate(cm, &id, false);
276  M0_UT_ASSERT(ag == NULL);
277 }
278 
279 static void ag_list_test_sort()
280 {
281  struct m0_cm_aggr_group *found;
282  struct m0_cm_aggr_group *prev_ag;
283  struct m0_cm *cm = &cm_ut[0].ut_cm;
284 
285  prev_ag = aggr_grps_out_tlist_head(&cm->cm_aggr_grps_out);
286  m0_tl_for(aggr_grps_out, &cm->cm_aggr_grps_out, found) {
288  &found->cag_id) <= 0);
289  prev_ag = found;
290  } m0_tl_endfor;
291 
292 }
293 
294 static void cm_ag_ut(void)
295 {
296  int i;
297  int j;
298  int rc;
299  struct m0_cm_ag_id ag_ids[AG_ID_NR];
300  struct m0_cm_aggr_group ags[AG_ID_NR];
301  struct m0_cm *cm;
302 
303  test_ready_fop = false;
304  M0_UT_ASSERT(ut_cm_id == 0);
305  cm = &cm_ut[ut_cm_id].ut_cm;
306  M0_SET0(cm);
309  M0_UT_ASSERT(rc == 0);
310 
311  m0_cm_lock(cm);
312  /* Populate ag & ag ids with test values. */
313  for(i = AG_ID_NR - 1, j = 0; i >= 0 ; --i, ++j) {
314  M0_SET0(&ag_ids[j]);
315  M0_SET0(&ags[j]);
316  ag_id_assign(&ag_ids[j], i, i, i, i);
317  m0_cm_aggr_group_init(&ags[j], cm, &ag_ids[j],
318  false, &cm_ag_ut_ops);
319  m0_cm_aggr_group_add(cm, &ags[j], false);
320  }
321 
322  /* Test 3-way comparision. */
323  ag_id_test_cmp();
324 
325  /* Test aggregation group id search. */
326  ag_id_test_find();
327 
328  /* Test to check if the aggregation group list is sorted. */
330 
331  /* Cleanup. */
332  for(i = 0; i < AG_ID_NR; i++)
334  m0_cm_unlock(cm);
335 
338 }
339 
341  .ts_name = "cm-ut",
342  .ts_init = &cm_ut_init,
343  .ts_fini = &cm_ut_fini,
344  .ts_tests = {
345  { "cm_setup_ut", cm_setup_ut },
346  { "cm_setup_failure_ut", cm_setup_failure_ut },
347  { "cm_init_failure_ut", cm_init_failure_ut },
348  { "cm_prepare_failure_ut", cm_prepare_failure_ut },
349  { "cm_ready_failure_ut", cm_ready_failure_ut },
350  { "cm_start_failure_ut", cm_start_failure_ut },
351  { "cm_ag_ut", cm_ag_ut },
352  { NULL, NULL }
353  }
354 };
355 
356 #undef M0_TRACE_SUBSYSTEM
357 /*
358  * Local variables:
359  * c-indentation-style: "K&R"
360  * c-basic-offset: 8
361  * tab-width: 8
362  * fill-column: 80
363  * scroll-step: 1
364  * End:
365  */
uint64_t id
Definition: cob.h:240
M0_INTERNAL void m0_cm_lock(struct m0_cm *cm)
Definition: cm.c:545
uint64_t ut_cm_id
static void ag_id_test_cmp()
Definition: cm.c:242
M0_INTERNAL int m0_reqh_service_start(struct m0_reqh_service *service)
Definition: reqh_service.c:343
M0_INTERNAL void m0_ut_rpc_mach_init_and_add(struct m0_ut_rpc_mach_ctx *ctx)
struct m0_reqh * m0_cs_reqh_get(struct m0_motr *cctx)
Definition: setup.c:1762
static int cm_ut_init(void)
Definition: cm.c:81
#define NULL
Definition: misc.h:38
bool test_ready_fop
#define DUMMY_SERVER_ADDR
void cm_ut_service_alloc_init(struct m0_reqh *reqh)
static void cm_ut_server_stop(void)
Definition: cm.c:64
struct m0_ut_rpc_mach_ctx cmut_rmach_ctx
M0_INTERNAL void m0_cm_aggr_group_add(struct m0_cm *cm, struct m0_cm_aggr_group *ag, bool has_incoming)
Definition: ag.c:301
M0_INTERNAL void m0_cm_type_deregister(struct m0_cm_type *cmtype)
Definition: cm.c:1019
char ** rsx_argv
Definition: rpclib.h:77
static void cm_setup_failure_ut(void)
Definition: cm.c:159
char * cm_ut_server_args[]
Definition: cm.c:37
struct m0_cm ut_cm
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
struct m0_ut_cm cm_ut[MAX_CM_NR]
struct m0_cob_domain_id rmc_cob_id
struct m0_cm_ag_id cag_id
Definition: ag.h:72
static void cm_prepare_failure_ut(void)
Definition: cm.c:170
M0_INTERNAL int m0_cm_start(struct m0_cm *cm)
Definition: cm.c:805
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
static void cm_ready_failure_ut(void)
Definition: cm.c:187
Definition: ut.h:77
static void ag_id_assign(struct m0_cm_ag_id *id, uint64_t hi_hi, uint64_t hi_lo, uint64_t lo_hi, uint64_t lo_lo)
Definition: cm.c:233
M0_INTERNAL void m0_cm_aggr_group_init(struct m0_cm_aggr_group *ag, struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming, const struct m0_cm_aggr_group_ops *ag_ops)
Definition: ag.c:153
struct m0_cm_type cm_ut_cmt
M0_INTERNAL struct m0_reqh_service_type * m0_reqh_service_type_find(const char *sname)
Definition: reqh_service.c:168
struct m0_reqh_service * cm_ut_service
#define m0_tl_endfor
Definition: tlist.h:700
static struct m0_uint128 id0[UPDATE_NR *DTM_NR]
Definition: dtx.c:57
static struct m0_cm * cm
Definition: cm.c:63
M0_INTERNAL void m0_cm_unlock(struct m0_cm *cm)
Definition: cm.c:550
M0_INTERNAL void m0_cm_complete_notify(struct m0_cm *cm)
Definition: cm.c:1133
#define DUMMY_COB_ID
struct m0_ut_suite cm_generic_ut
Definition: cm.c:340
int i
Definition: dir.c:1033
static void ag_list_test_sort()
Definition: cm.c:279
M0_INTERNAL bool m0_fom_domain_is_idle_for(const struct m0_reqh_service *svc)
Definition: fom.c:1281
static void cm_start_failure_ut(void)
Definition: cm.c:209
const char * rsx_log_file_name
Definition: rpclib.h:81
#define M0_NET_XPRT_PREFIX_DEFAULT
Definition: net.h:98
M0_INTERNAL int m0_cm_ag_id_cmp(const struct m0_cm_ag_id *id0, const struct m0_cm_ag_id *id1)
Definition: ag.c:73
#define M0_ASSERT(cond)
static const char * SERVER_LOGFILE
Definition: cm.c:36
M0_INTERNAL void m0_reqh_service_fini(struct m0_reqh_service *service)
Definition: reqh_service.c:457
struct m0_reqh rc_reqh
Definition: setup.h:312
int m0_net_xprt_nr(void)
Definition: net.c:168
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_aggr_group_locate(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming)
Definition: ag.c:262
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
static void cm_ag_ut(void)
Definition: cm.c:294
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
Definition: reqh.h:94
int32_t sm_rc
Definition: sm.h:336
void cm_ut_service_cleanup()
bool swu_is_complete
Definition: sw.h:85
M0_INTERNAL int m0_cm_ready(struct m0_cm *cm)
Definition: cm.c:759
M0_INTERNAL void m0_reqh_idle_wait(struct m0_reqh *reqh)
Definition: reqh.c:606
const char * ts_name
Definition: ut.h:99
struct m0_tl cm_aggr_grps_out
Definition: cm.h:231
M0_INTERNAL struct m0_reqh_service * m0_reqh_service_find(const struct m0_reqh_service_type *st, const struct m0_reqh *reqh)
Definition: reqh_service.c:538
M0_INTERNAL int m0_cm_prepare(struct m0_cm *cm)
Definition: cm.c:717
bool m0_cm_cp_pump_is_complete(const struct m0_cm_cp_pump *cp_pump)
Definition: pump.c:420
struct m0_reqh reqh
Definition: rm_foms.c:48
int rsx_xprts_nr
Definition: rpclib.h:71
struct m0_cm_sw_update cm_sw_update
Definition: cm.h:259
struct m0_reqh_context cc_reqh_ctx
Definition: setup.h:361
struct m0_cm_ag_id ag_ids[MAX_CM_NR][MAX_CM_NR]
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
const char * rmc_ep_addr
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
struct m0_reqh_service cm_service
Definition: cm.h:191
static struct m0_cm * cm_ut_sctx2cm(void)
Definition: cm.c:69
M0_INTERNAL void m0_ut_rpc_mach_fini(struct m0_ut_rpc_mach_ctx *ctx)
static struct m0_net_test_service svc
Definition: service.c:34
Definition: cm.h:166
static void cm_ut_server_start(void)
Definition: cm.c:49
struct m0_reqh_service_type ct_stype
Definition: cm.h:145
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
M0_INTERNAL void m0_cm_cp_init(struct m0_cm_type *cmtype, const struct m0_fom_type_ops *ft_ops)
Definition: cp.c:580
struct m0_cm_cp_pump cm_cp_pump
Definition: cm.h:257
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
static void cm_setup_ut(void)
Definition: cm.c:108
static uint64_t found
Definition: base.c:376
static void cm_init_failure_ut(void)
Definition: cm.c:144
#define M0_UT_PATH(name)
Definition: misc.h:41
static int cm_ut_fini(void)
Definition: cm.c:99
static void ag_id_test_find()
Definition: cm.c:259
struct m0_sm cm_mach
Definition: cm.h:167
static struct m0_rpc_server_ctx cm_ut_sctx
Definition: cm.c:35
struct m0_reqh * rs_reqh
Definition: reqh_service.h:260
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_motr rsx_motr_ctx
Definition: rpclib.h:84
Definition: ag.h:49
M0_INTERNAL void m0_cm_aggr_group_fini_and_progress(struct m0_cm_aggr_group *ag)
Definition: ag.c:207
const struct m0_cm_aggr_group_ops cm_ag_ut_ops
M0_INTERNAL int m0_cm_type_register(struct m0_cm_type *cmtype)
Definition: cm.c:995