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_SET0(&cm_ut[ut_cm_id].ut_cm);
155  M0_UT_ASSERT(rc != 0);
156 }
157 
158 static void cm_setup_failure_ut(void)
159 {
160  int rc;
161 
163  m0_fi_enable_once("m0_cm_setup", "setup_failure_2");
165  M0_UT_ASSERT(rc != 0);
167 }
168 
169 static void cm_prepare_failure_ut(void)
170 {
171  struct m0_cm *cm;
172  int rc;
173 
176  M0_UT_ASSERT(rc == 0);
177  cm = cm_ut_sctx2cm();
179  m0_fi_enable_once("m0_cm_prepare", "prepare_failure");
180  rc = m0_cm_prepare(cm);
181  M0_UT_ASSERT(rc != 0);
184 }
185 
186 static void cm_ready_failure_ut(void)
187 {
188  struct m0_cm *cm;
189  int rc;
190 
193  M0_UT_ASSERT(rc == 0);
194  cm = cm_ut_sctx2cm();
195  m0_fi_enable_once("m0_cm_ready", "ready_failure");
196  rc = m0_cm_prepare(cm);
197  M0_UT_ASSERT(rc == 0);
198  do {
199  usleep(200);
200  rc = m0_cm_ready(cm);
201  } while (rc == -EAGAIN);
202  M0_UT_ASSERT(rc == 0);
203  M0_UT_ASSERT(cm->cm_mach.sm_rc != 0);
206 }
207 
208 static void cm_start_failure_ut(void)
209 {
210  struct m0_cm *cm;
211  int rc;
212 
215  M0_UT_ASSERT(rc == 0);
216  cm = cm_ut_sctx2cm();
217  m0_fi_enable_once("m0_cm_start", "start_failure");
218  rc = m0_cm_prepare(cm);
219  M0_UT_ASSERT(rc == 0);
220  rc = m0_cm_ready(cm);
221  M0_UT_ASSERT(rc == 0);
222  do {
223  usleep(200);
224  rc = m0_cm_start(cm);
225  } while (rc == -EAGAIN);
226  M0_UT_ASSERT(rc == 0);
227  M0_UT_ASSERT(cm->cm_mach.sm_rc != 0);
230 }
231 
232 static void ag_id_assign(struct m0_cm_ag_id *id, uint64_t hi_hi, uint64_t hi_lo,
233  uint64_t lo_hi, uint64_t lo_lo)
234 {
235  id->ai_hi.u_hi = hi_hi;
236  id->ai_hi.u_lo = hi_lo;
237  id->ai_lo.u_hi = lo_hi;
238  id->ai_lo.u_lo = lo_lo;
239 }
240 
241 static void ag_id_test_cmp()
242 {
243  struct m0_cm_ag_id id0;
244  struct m0_cm_ag_id id1;
245  int rc;
246 
247  /* Assign random test values to aggregation group ids. */
248  ag_id_assign(&id0, 2, 3, 4, 5);
249  ag_id_assign(&id1, 4, 4, 4, 4);
250  rc = m0_cm_ag_id_cmp(&id0, &id1);
251  M0_UT_ASSERT(rc < 0);
252  rc = m0_cm_ag_id_cmp(&id1, &id0);
253  M0_UT_ASSERT(rc > 0);
254  rc = m0_cm_ag_id_cmp(&id0, &id0);
255  M0_UT_ASSERT(rc == 0);
256 }
257 
258 static void ag_id_test_find()
259 {
260  struct m0_cm_ag_id id;
261  int i;
262  int rc;
263  struct m0_cm_aggr_group *ag;
264  struct m0_cm *cm = &cm_ut[0].ut_cm;
265 
266  for (i = AG_ID_NR - 1; i >= 0; --i) {
267  ag_id_assign(&id, i, i, i, i);
268  ag = m0_cm_aggr_group_locate(cm, &id, false);
269  M0_UT_ASSERT(ag != NULL);
270  rc = m0_cm_ag_id_cmp(&id, &ag->cag_id);
271  M0_UT_ASSERT(rc == 0);
272  }
273  ag_id_assign(&id, 10, 35, 2, 3);
274  ag = m0_cm_aggr_group_locate(cm, &id, false);
275  M0_UT_ASSERT(ag == NULL);
276 }
277 
278 static void ag_list_test_sort()
279 {
280  struct m0_cm_aggr_group *found;
281  struct m0_cm_aggr_group *prev_ag;
282  struct m0_cm *cm = &cm_ut[0].ut_cm;
283 
284  prev_ag = aggr_grps_out_tlist_head(&cm->cm_aggr_grps_out);
285  m0_tl_for(aggr_grps_out, &cm->cm_aggr_grps_out, found) {
287  &found->cag_id) <= 0);
288  prev_ag = found;
289  } m0_tl_endfor;
290 
291 }
292 
293 static void cm_ag_ut(void)
294 {
295  int i;
296  int j;
297  int rc;
298  struct m0_cm_ag_id ag_ids[AG_ID_NR];
299  struct m0_cm_aggr_group ags[AG_ID_NR];
300  struct m0_cm *cm;
301 
302  test_ready_fop = false;
303  M0_UT_ASSERT(ut_cm_id == 0);
304  cm = &cm_ut[ut_cm_id].ut_cm;
307  M0_UT_ASSERT(rc == 0);
308 
309  m0_cm_lock(cm);
310  /* Populate ag & ag ids with test values. */
311  for(i = AG_ID_NR - 1, j = 0; i >= 0 ; --i, ++j) {
312  ag_id_assign(&ag_ids[j], i, i, i, i);
313  m0_cm_aggr_group_init(&ags[j], cm, &ag_ids[j],
314  false, &cm_ag_ut_ops);
315  m0_cm_aggr_group_add(cm, &ags[j], false);
316  }
317 
318  /* Test 3-way comparision. */
319  ag_id_test_cmp();
320 
321  /* Test aggregation group id search. */
322  ag_id_test_find();
323 
324  /* Test to check if the aggregation group list is sorted. */
326 
327  /* Cleanup. */
328  for(i = 0; i < AG_ID_NR; i++)
330  m0_cm_unlock(cm);
331 
334 }
335 
337  .ts_name = "cm-ut",
338  .ts_init = &cm_ut_init,
339  .ts_fini = &cm_ut_fini,
340  .ts_tests = {
341  { "cm_setup_ut", cm_setup_ut },
342  { "cm_setup_failure_ut", cm_setup_failure_ut },
343  { "cm_init_failure_ut", cm_init_failure_ut },
344  { "cm_prepare_failure_ut", cm_prepare_failure_ut },
345  { "cm_ready_failure_ut", cm_ready_failure_ut },
346  { "cm_start_failure_ut", cm_start_failure_ut },
347  { "cm_ag_ut", cm_ag_ut },
348  { NULL, NULL }
349  }
350 };
351 
352 #undef M0_TRACE_SUBSYSTEM
353 /*
354  * Local variables:
355  * c-indentation-style: "K&R"
356  * c-basic-offset: 8
357  * tab-width: 8
358  * fill-column: 80
359  * scroll-step: 1
360  * End:
361  */
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:241
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:158
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:169
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:186
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:232
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:336
int i
Definition: dir.c:1033
static void ag_list_test_sort()
Definition: cm.c:278
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:208
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:293
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:258
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:259
#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