Motr  M0
cp.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 "cm/cp.h"
24 #include "cm/cp.c"
25 #include "cm/ut/common_service.h"
26 #include "sns/cm/cp.h"
27 #include "ioservice/fid_convert.h" /* m0_fid_gob_make */
28 #include "lib/fs.h" /* m0_file_read */
29 #include "ut/misc.h" /* M0_UT_PATH */
30 #include "ut/ut.h"
31 
32 static struct m0_semaphore sem;
33 
34 /* Single thread test vars. */
35 static struct m0_sns_cm_cp s_sns_cp;
37 static struct m0_net_buffer_pool nbp;
38 static struct m0_cm_aggr_group s_ag;
39 
40 enum {
41  THREADS_NR = 17,
42 };
43 
45 {
46  M0_PRE(service != NULL);
47  return 0;
48 }
49 
51 {
52  M0_PRE(service != NULL);
53 }
54 
56 {
57  M0_PRE(service != NULL);
59 }
60 
61 static const struct m0_reqh_service_ops ut_cp_service_ops = {
63  .rso_stop = ut_cp_service_stop,
64  .rso_fini = ut_cp_service_fini
65 };
66 
68  const struct m0_reqh_service_type *stype)
69 {
70  struct m0_reqh_service *serv;
71 
72  M0_PRE(stype != NULL && service != NULL);
73 
74  M0_ALLOC_PTR(serv);
75  M0_ASSERT(serv != NULL);
76 
77  serv->rs_type = stype;
78  serv->rs_ops = &ut_cp_service_ops;
79  *service = serv;
80  return 0;
81 }
82 
85 };
86 
88  .rst_name = "ut-cp",
89  .rst_ops = &ut_cp_service_type_ops,
90  .rst_level = M0_RS_LEVEL_NORMAL,
91 };
92 
93 /* Multithreaded test vars. */
96 static struct m0_net_buffer m_nb[THREADS_NR];
97 
98 static int dummy_cp_read(struct m0_cm_cp *cp)
99 {
100  cp->c_io_op = M0_CM_CP_READ;
101  cp->c_ops->co_phase_next(cp);
102  return M0_FSO_AGAIN;
103 }
104 
105 static int dummy_cp_write_pre(struct m0_cm_cp *cp)
106 {
107  M0_IMPOSSIBLE("M0_CCP_WRITE_PRE phase shouldn't be used!");
108 }
109 
110 static int dummy_cp_write(struct m0_cm_cp *cp)
111 {
112  cp->c_io_op = M0_CM_CP_WRITE;
113  cp->c_ops->co_phase_next(cp);
114  return M0_FSO_AGAIN;
115 }
116 
117 static int dummy_cp_phase(struct m0_cm_cp *cp)
118 {
119  return cp->c_ops->co_phase_next(cp);
120 }
121 
122 static int dummy_cp_init(struct m0_cm_cp *cp)
123 {
124  int rc = m0_sns_cm_cp_init(cp);
125 
127  return rc;
128 }
129 
130 static int dummy_cp_phase_next(struct m0_cm_cp *cp)
131 {
132  int phase = m0_fom_phase(&cp->c_fom);
133 
134  if (phase == M0_CCP_XFORM) {
135  phase = M0_CCP_WRITE;
136  m0_fom_phase_set(&cp->c_fom, phase);
137  return M0_FSO_AGAIN;
138  } else
139  return m0_sns_cm_cp_phase_next(cp);
140 }
141 
143  .co_action = {
156  },
157  .co_action_nr = M0_CCP_NR,
158  .co_phase_next = &dummy_cp_phase_next,
159  .co_invariant = &m0_sns_cm_cp_invariant,
160  .co_home_loc_helper = &cp_home_loc_helper,
161  .co_complete = &m0_sns_cm_cp_complete,
162  .co_free = &m0_sns_cm_cp_free,
163 };
164 
165 /*
166  * Dummy fom fini function which finalises the copy packet by skipping the
167  * sw_fill functionality.
168  */
170 {
171  m0_cm_cp_fini(bob_of(fom, struct m0_cm_cp, c_fom, &cp_bob));
172 }
173 
174 /*
175  * Over-ridden copy packet FOM ops.
176  * This is done to bypass the sw_ag_fill call, which is to be tested
177  * separately.
178  */
179 static struct m0_fom_ops dummy_cp_fom_ops = {
181  .fo_tick = cp_fom_tick,
182  .fo_home_locality = cp_fom_locality
183 };
184 
185 /*
186  * Populates the copy packet and queues it to the request handler
187  * for processing.
188  */
189 static void cp_post(struct m0_sns_cm_cp *sns_cp, struct m0_cm_aggr_group *ag,
190  struct m0_net_buffer *nb)
191 {
192  struct m0_cm_cp *cp;
193  struct m0_fid gfid;
194 
195  m0_fid_gob_make(&gfid, 1, 1);
196  cp = &sns_cp->sc_base;
197  cp->c_ag = ag;
198  m0_stob_id_make(0, 1, &gfid, &sns_cp->sc_stob_id);
199  m0_fid_convert_gob2cob(&gfid, &sns_cp->sc_cobfid, 1);
202  m0_cm_cp_fom_init(ag->cag_cm, cp, NULL, NULL);
203  /* Over-ride the fom ops. */
205  m0_cm_cp_buf_add(cp, nb);
206  m0_fom_queue(&cp->c_fom);
208 }
209 
210 /*
211  * Tests the copy packet fom functionality by posting a single copy packet
212  * to the reqh.
213  */
214 static void test_cp_single_thread(void)
215 {
216  m0_semaphore_init(&sem, 0);
217  s_ag.cag_cm = &cm_ut[0].ut_cm;
218  s_ag.cag_cp_local_nr = 1;
219  s_nb.nb_pool = &nbp;
220  cp_post(&s_sns_cp, &s_ag, &s_nb);
221 
222  /*
223  * Wait until all the foms in the request handler locality runq are
224  * processed.
225  */
228 }
229 
230 static void cp_op(const int tid)
231 {
232  m_ag[tid].cag_cm = &cm_ut[0].ut_cm;
233  m_ag[tid].cag_cp_local_nr = 1;
234  m_nb[tid].nb_pool = &nbp;
235  cp_post(&m_sns_cp[tid], &m_ag[tid], &m_nb[tid]);
236 }
237 
238 /*
239  * Tests the copy packet fom functionality by posting multiple copy packets
240  * to the reqh.
241  */
242 static void test_cp_multi_thread(void)
243 {
244  int i;
245  struct m0_thread *cp_thread;
246 
247  m0_semaphore_init(&sem, 0);
248 
249  M0_ALLOC_ARR(cp_thread, THREADS_NR);
250  M0_UT_ASSERT(cp_thread != NULL);
251 
252  /* Post multiple copy packets to the request handler queue. */
253  for (i = 0; i < THREADS_NR; ++i)
254  M0_UT_ASSERT(M0_THREAD_INIT(&cp_thread[i], int, NULL, &cp_op, i,
255  "cp_thread_%d", i) == 0);
256 
257  for (i = 0; i < THREADS_NR; ++i)
258  m0_thread_join(&cp_thread[i]);
259  /*
260  * Wait until all the foms in the request handler locality runq are
261  * processed.
262  */
264  m0_free(cp_thread);
266 }
267 /*
268  * Initialises the request handler since copy packet fom has to be tested using
269  * request handler infrastructure.
270  */
271 static int cm_cp_init(void)
272 {
273  int rc;
274 
280  M0_ASSERT(rc == 0);
282 
284  M0_ASSERT(rc == 0);
285 
286  return 0;
287 }
288 
289 /* Finalises the request handler. */
290 static int cm_cp_fini(void)
291 {
295  return 0;
296 }
297 
299  .ts_name = "cm-cp-ut",
300  .ts_init = &cm_cp_init,
301  .ts_fini = &cm_cp_fini,
302  .ts_tests = {
303  { "cp-single_thread", test_cp_single_thread },
304  { "cp-multi_thread", test_cp_multi_thread },
305  { NULL, NULL }
306  }
307 };
308 
309 /*
310  * Local variables:
311  * c-indentation-style: "K&R"
312  * c-basic-offset: 8
313  * tab-width: 8
314  * fill-column: 80
315  * scroll-step: 1
316  * End:
317  */
uint64_t id
Definition: cob.h:240
M0_INTERNAL void m0_sns_cm_cp_free(struct m0_cm_cp *cp)
Definition: cp.c:338
static void cp_post(struct m0_sns_cm_cp *sns_cp, struct m0_cm_aggr_group *ag, struct m0_net_buffer *nb)
Definition: cp.c:189
M0_INTERNAL int m0_sns_cm_cp_init(struct m0_cm_cp *cp)
Definition: cp.c:100
#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 void m0_fid_gob_make(struct m0_fid *gob_fid, uint32_t container, uint64_t key)
Definition: fid_convert.c:46
M0_INTERNAL void m0_ut_rpc_mach_init_and_add(struct m0_ut_rpc_mach_ctx *ctx)
int(* rso_start)(struct m0_reqh_service *service)
Definition: reqh_service.h:360
struct m0_net_buffer_pool * nb_pool
Definition: net.h:1508
const struct m0_cm_cp_ops m0_sns_cm_cp_dummy_ops
Definition: cp.c:142
static struct m0_cm_aggr_group m_ag[THREADS_NR]
Definition: cp.c:95
#define NULL
Definition: misc.h:38
#define DUMMY_SERVER_ADDR
struct m0_stob_id sc_stob_id
Definition: cp.h:45
static struct m0_semaphore sem
Definition: cp.c:32
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
void cm_ut_service_alloc_init(struct m0_reqh *reqh)
struct m0_ut_rpc_mach_ctx cmut_rmach_ctx
M0_INTERNAL void m0_cm_type_deregister(struct m0_cm_type *cmtype)
Definition: cm.c:1019
Definition: cp.h:160
static int cp_fom_tick(struct m0_fom *fom)
Definition: cp.c:431
struct m0_cm ut_cm
static struct m0_sns_cm_cp s_sns_cp
Definition: cp.c:35
struct m0_ut_cm cm_ut[MAX_CM_NR]
static int cm_cp_fini(void)
Definition: cp.c:290
struct m0_cob_domain_id rmc_cob_id
M0_INTERNAL void m0_sns_cm_cp_complete(struct m0_cm_cp *cp)
Definition: cp.c:307
struct m0_net_buffer s_nb
Definition: cp.c:36
M0_INTERNAL void m0_cm_cp_fom_init(struct m0_cm *cm, struct m0_cm_cp *cp, struct m0_fop *fop, struct m0_fop *r_fop)
Definition: cp.c:610
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
#define M0_SET0(obj)
Definition: misc.h:64
static void cp_op(const int tid)
Definition: cp.c:230
Definition: ut.h:77
static void test_cp_single_thread(void)
Definition: cp.c:214
m0_fom_phase
Definition: fom.h:372
struct m0_cm_type cm_ut_cmt
struct m0_reqh_service * cm_ut_service
static int dummy_cp_write(struct m0_cm_cp *cp)
Definition: cp.c:110
static int cm_cp_init(void)
Definition: cp.c:271
Definition: cp.h:151
struct m0_fid sc_cobfid
Definition: cp.h:42
#define DUMMY_COB_ID
static struct m0_net_buffer_pool nbp
Definition: cp.c:37
void dummy_cp_fom_fini(struct m0_fom *fom)
Definition: cp.c:169
int i
Definition: dir.c:1033
struct m0_cm_cp sc_base
Definition: cp.h:39
enum m0_cm_cp_io_op c_io_op
Definition: cp.h:196
Definition: cp.c:41
static uint64_t cp_fom_locality(const struct m0_fom *fom)
Definition: cp.c:424
static const struct socktype stype[]
Definition: sock.c:1156
#define M0_ASSERT(cond)
static const struct m0_bob_type cp_bob
Definition: cp.c:397
static void test_cp_multi_thread(void)
Definition: cp.c:242
const char * rst_name
Definition: reqh_service.h:447
M0_INTERNAL int m0_sns_cm_cp_phase_next(struct m0_cm_cp *cp)
Definition: cp.c:261
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
struct m0_cm * cag_cm
Definition: ag.h:70
M0_INTERNAL void m0_cm_cp_fini(struct m0_cm_cp *cp)
Definition: cp.c:682
const struct m0_cm_cp_ops * c_ops
Definition: cp.h:169
M0_INTERNAL void m0_cm_cp_buf_add(struct m0_cm_cp *cp, struct m0_net_buffer *nb)
Definition: cp.c:703
M0_INTERNAL void m0_stob_id_make(uint64_t container, uint64_t key, const struct m0_fid *dom_id, struct m0_stob_id *stob_id)
Definition: stob.c:343
static void ut_cp_service_stop(struct m0_reqh_service *service)
Definition: cp.c:50
static const struct m0_reqh_service_type_ops ut_cp_service_type_ops
Definition: cp.c:83
M0_INTERNAL bool m0_sns_cm_cp_invariant(const struct m0_cm_cp *cp)
Definition: cp.c:62
int(* co_action[])(struct m0_cm_cp *cp)
Definition: cp.h:259
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
static int ut_cp_service_allocate(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: cp.c:67
static int dummy_cp_init(struct m0_cm_cp *cp)
Definition: cp.c:122
Definition: dump.c:103
struct m0_cm_aggr_group * c_ag
Definition: cp.h:172
struct m0_reqh rmc_reqh
void cm_ut_service_cleanup()
static int dummy_cp_phase_next(struct m0_cm_cp *cp)
Definition: cp.c:130
const struct m0_fom_ops * fo_ops
Definition: fom.h:486
static void ut_cp_service_fini(struct m0_reqh_service *service)
Definition: cp.c:55
M0_INTERNAL void m0_reqh_idle_wait(struct m0_reqh *reqh)
Definition: reqh.c:606
static int dummy_cp_write_pre(struct m0_cm_cp *cp)
Definition: cp.c:105
static struct m0_cm_aggr_group s_ag
Definition: cp.c:38
Definition: fom.h:481
static int dummy_cp_read(struct m0_cm_cp *cp)
Definition: cp.c:98
const char * ts_name
Definition: ut.h:99
int(* rsto_service_allocate)(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: reqh_service.h:435
static struct m0_sns_cm_cp m_sns_cp[THREADS_NR]
Definition: cp.c:94
Definition: fid.h:38
const struct m0_reqh_service_type * rs_type
Definition: reqh_service.h:227
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
const char * rmc_ep_addr
M0_INTERNAL void m0_ut_rpc_mach_fini(struct m0_ut_rpc_mach_ctx *ctx)
struct m0_reqh_service_type ut_cp_service_type
Definition: cp.c:87
uint64_t cag_cp_local_nr
Definition: ag.h:92
int(* co_phase_next)(struct m0_cm_cp *cp)
Definition: cp.h:232
M0_INTERNAL void m0_fom_queue(struct m0_fom *fom)
Definition: fom.c:624
M0_INTERNAL void m0_cm_cp_init(struct m0_cm_type *cmtype, const struct m0_fom_type_ops *ft_ops)
Definition: cp.c:580
void(* fo_fini)(struct m0_fom *fom)
Definition: fom.h:657
static int ut_cp_service_start(struct m0_reqh_service *service)
Definition: cp.c:44
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
static struct m0_fom_ops dummy_cp_fom_ops
Definition: cp.c:179
M0_INTERNAL void m0_fid_convert_gob2cob(const struct m0_fid *gob_fid, struct m0_fid *cob_fid, uint32_t device_id)
Definition: fid_convert.c:55
static int dummy_cp_phase(struct m0_cm_cp *cp)
Definition: cp.c:117
void m0_fom_phase_set(struct m0_fom *fom, int phase)
Definition: fom.c:1688
struct m0_fid gfid
Definition: dir.c:626
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
struct m0_fom c_fom
Definition: cp.h:161
M0_INTERNAL uint64_t cp_home_loc_helper(const struct m0_cm_cp *cp)
Definition: cp.c:80
struct m0_ut_suite cm_cp_ut
Definition: cp.c:298
void m0_free(void *data)
Definition: memory.c:146
static const struct m0_reqh_service_ops ut_cp_service_ops
Definition: cp.c:61
static struct m0_reqh_service * service[REQH_IN_UT_MAX]
Definition: long_lock_ut.c:46
static struct m0_net_buffer m_nb[THREADS_NR]
Definition: cp.c:96
int32_t rc
Definition: trigger_fop.h:47
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL int m0_sns_cm_cp_fini(struct m0_cm_cp *cp)
Definition: cp.c:352
const struct m0_reqh_service_ops * rs_ops
Definition: reqh_service.h:254
#define M0_IMPOSSIBLE(fmt,...)
M0_INTERNAL int m0_cm_type_register(struct m0_cm_type *cmtype)
Definition: cm.c:995