Motr  M0
plan.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2021 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  * Original author: Andriy Tkachuk <andriy.tkachuk@seagate.com>
21  * Original creation date: 27-Apr-2021
22  */
23 
24 
25 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LAYOUT
26 #include "lib/trace.h" /* M0_LOG */
27 
28 #include "lib/errno.h" /* ENOENT */
29 #include "lib/vec.h" /* m0_indexvec_alloc */
30 #include "rpc/rpclib.h" /* m0_rpc_server_start */
31 #include "ut/ut.h"
32 #include "ut/misc.h"
33 #include "motr/client_internal.h" /* m0_op_obj */
34 #include "motr/io.h" /* m0_op_io */
35 #include "motr/ut/client.h" /* ut_realm_entity_setup */
36 #include "layout/plan.h"
37 
38 static struct m0_client *client_inst = NULL;
39 
40 #define SERVER_ENDPOINT_ADDR "0@lo:12345:34:1"
41 #define SERVER_ENDPOINT M0_NET_XPRT_PREFIX_DEFAULT":"SERVER_ENDPOINT_ADDR
42 #define CLIENT_ENDPOINT_ADDR "0@lo:12345:34:2"
43 
44 static const char SERVER_LOGFILE[] = "lap_ut.log";
45 
46 static char *lap_ut_server_args[] = { "m0d", "-T", "AD",
47  "-D", "db", "-S", "stob",
48  "-A", "linuxstob:addb-stob",
49  "-f", M0_UT_CONF_PROCESS,
50  "-w", "10",
51  "-G", SERVER_ENDPOINT,
52  "-e", SERVER_ENDPOINT,
54  "-c", M0_SRC_PATH("motr/ut/dix_conf.xc")};
55 
56 static struct m0_rpc_server_ctx lap_ut_sctx = {
58  .rsx_argc = ARRAY_SIZE(lap_ut_server_args),
59  .rsx_log_file_name = SERVER_LOGFILE,
60 };
61 
62 static int lap_ut_server_start(void)
63 {
66 
68 }
69 
70 static void lap_ut_server_stop(void)
71 {
73 }
74 
75 static struct m0_idx_dix_config dix_conf = {
76  .kc_create_meta = false,
77 };
78 
79 static struct m0_config client_conf = {
80  .mc_is_oostore = true,
81  .mc_is_read_verify = false,
82  .mc_layout_id = 1,
83  .mc_local_addr = CLIENT_ENDPOINT_ADDR,
84  .mc_ha_addr = SERVER_ENDPOINT_ADDR,
85  .mc_profile = M0_UT_CONF_PROFILE,
86  .mc_process_fid = M0_UT_CONF_PROCESS,
87  .mc_tm_recv_queue_min_len = M0_NET_TM_RECV_QUEUE_DEF_LEN,
88  .mc_max_rpc_msg_size = M0_RPC_DEF_MAX_RPC_MSG_SIZE,
89  .mc_idx_service_id = M0_IDX_DIX,
90  .mc_idx_service_conf = &dix_conf,
91 };
92 
93 static int lap_ut_client_start(void)
94 {
95  int rc;
96 
97  m0_fi_enable_once("ha_init", "skip-ha-init");
98  /* Skip HA finalisation in case of failure path. */
99  m0_fi_enable("ha_fini", "skip-ha-fini");
100  /*
101  * We can't use m0_fi_enable_once() here, because
102  * initlift_addb2() may be called twice in case of failure path.
103  */
104  m0_fi_enable("initlift_addb2", "no-addb2");
105  m0_fi_enable("ha_process_event", "no-link");
107  M0_ASSERT_INFO(rc == 0, "rc=%d", rc);
108  m0_fi_disable("ha_process_event", "no-link");
109  m0_fi_disable("initlift_addb2", "no-addb2");
110  m0_fi_disable("ha_fini", "skip-ha-fini");
111 
112  return 0;
113 }
114 
115 static void lap_ut_client_stop(void)
116 {
117  m0_fi_enable_once("ha_fini", "skip-ha-fini");
118  m0_fi_enable_once("initlift_addb2", "no-addb2");
119  m0_fi_enable("ha_process_event", "no-link");
120  m0_client_fini(client_inst, false);
121  m0_fi_disable("ha_process_event", "no-link");
122 }
123 
124 static void test_plan_build_fini(void)
125 {
126  int rc;
127  struct m0_client *cinst = client_inst;
128  struct m0_pool_version *pv;
129  struct m0_layout_plan *plan;
130  struct m0_op *op = NULL;
131  struct m0_indexvec ext;
132  struct m0_bufvec data;
133  struct m0_bufvec attr;
134  struct m0_realm realm;
135  struct m0_obj obj = {};
136 
137  M0_ENTRY();
138 
139  M0_UT_ASSERT(m0_indexvec_alloc(&ext, 1) == 0);
142  M0_UT_ASSERT(m0_bufvec_alloc(&attr, 1, 1) == 0);
143 
145  M0_UT_ASSERT(rc == 0);
146  ut_realm_entity_setup(&realm, &obj.ob_entity, cinst);
147  obj.ob_attr.oa_bshift = M0_MIN_BUF_SHIFT;
148  obj.ob_attr.oa_pver = pv->pv_id;
149  obj.ob_attr.oa_layout_id = M0_DEFAULT_LAYOUT_ID;
150 
151  rc = m0_obj_op(&obj, M0_OC_READ, &ext, &data, &attr, 0, 0, &op);
152  M0_UT_ASSERT(rc == 0);
153 
154  /* check happy path */
155  plan = m0_layout_plan_build(op);
156  M0_UT_ASSERT(plan != NULL);
157 
158  m0_layout_plan_fini(plan);
159 
160  /* check error paths */
161  m0_fi_enable_once("pargrp_iomap_init", "no-mem-err");
162  plan = m0_layout_plan_build(op);
163  M0_UT_ASSERT(plan == NULL);
164 
165  m0_fi_enable_once("target_ioreq_init", "no-mem-err");
166  plan = m0_layout_plan_build(op);
167  M0_UT_ASSERT(plan == NULL);
168 
169  m0_op_fini(op);
170  m0_op_free(op);
171 
172  m0_entity_fini(&obj.ob_entity);
173 
176  m0_indexvec_free(&ext);
177 
178  M0_LEAVE();
179 }
180 
181 static void test_plan_get_done(void)
182 {
183  int rc;
184  struct m0_client *cinst = client_inst;
185  struct m0_pool_version *pv;
186  struct m0_layout_plan *plan;
187  struct m0_op *op = NULL;
188  struct m0_layout_plop *plop;
189  struct m0_layout_io_plop *iopl;
190  struct m0_layout_plop_rel *plrel;
191  struct m0_indexvec ext;
192  struct m0_bufvec data;
193  struct m0_bufvec attr;
194  struct m0_realm realm;
195  struct m0_obj obj = {};
196 
197  M0_ENTRY();
198 
199  M0_UT_ASSERT(m0_indexvec_alloc(&ext, 2) == 0);
202  ext.iv_index[0] = 0;
205  M0_UT_ASSERT(m0_bufvec_alloc(&attr, 2, 1) == 0);
206 
208  M0_UT_ASSERT(rc == 0);
209  ut_realm_entity_setup(&realm, &obj.ob_entity, cinst);
210  obj.ob_attr.oa_bshift = M0_MIN_BUF_SHIFT;
211  obj.ob_attr.oa_pver = pv->pv_id;
212  obj.ob_attr.oa_layout_id = M0_DEFAULT_LAYOUT_ID;
213 
214  rc = m0_obj_op(&obj, M0_OC_READ, &ext, &data, &attr, 0, 0, &op);
215  M0_UT_ASSERT(rc == 0);
216 
217  plan = m0_layout_plan_build(op);
218  M0_UT_ASSERT(plan != NULL);
219 
220  /* 1st unit */
221  rc = m0_layout_plan_get(plan, 0, &plop);
222  M0_UT_ASSERT(rc == 0);
223  M0_UT_ASSERT(plop != NULL);
224  M0_UT_ASSERT(plop->pl_type == M0_LAT_READ);
225  M0_UT_ASSERT(plop->pl_ent.f_container != 0 ||
226  plop->pl_ent.f_key != 0);
227  iopl = container_of(plop, struct m0_layout_io_plop, iop_base);
228  M0_UT_ASSERT(iopl->iop_session != NULL);
229  M0_UT_ASSERT(iopl->iop_ext.iv_index != NULL);
230  M0_UT_ASSERT(iopl->iop_goff == 0);
233  M0_UT_ASSERT(iopl->iop_data.ov_buf != NULL);
234 
235  m0_layout_plop_start(plop);
236  plop->pl_rc = 0;
237  m0_layout_plop_done(plop);
238 
239  rc = m0_layout_plan_get(plan, 0, &plop);
240  M0_UT_ASSERT(rc == 0);
241  M0_UT_ASSERT(plop != NULL);
243  plrel = pldeps_tlist_head(&plop->pl_deps);
244  M0_UT_ASSERT(plrel != NULL);
245  M0_UT_ASSERT(plrel->plr_dep == &iopl->iop_base);
246  M0_UT_ASSERT(plrel->plr_rdep == plop);
247  m0_layout_plop_start(plop);
248  m0_layout_plop_done(plop);
249 
250  /* 2nd unit */
251  rc = m0_layout_plan_get(plan, 0, &plop);
252  M0_UT_ASSERT(rc == 0);
253  M0_UT_ASSERT(plop != NULL);
254  M0_UT_ASSERT(plop->pl_type == M0_LAT_READ);
255  M0_UT_ASSERT(plop->pl_ent.f_container != 0 ||
256  plop->pl_ent.f_key != 0);
257  iopl = container_of(plop, struct m0_layout_io_plop, iop_base);
258  M0_UT_ASSERT(iopl->iop_session != NULL);
259  M0_UT_ASSERT(iopl->iop_ext.iv_index != NULL);
263  M0_UT_ASSERT(iopl->iop_data.ov_buf != NULL);
264 
265  m0_layout_plop_start(plop);
266  plop->pl_rc = 0;
267  m0_layout_plop_done(plop);
268 
269  rc = m0_layout_plan_get(plan, 0, &plop);
270  M0_UT_ASSERT(rc == 0);
271  M0_UT_ASSERT(plop != NULL);
273  plrel = pldeps_tlist_head(&plop->pl_deps);
274  M0_UT_ASSERT(plrel != NULL);
275  M0_UT_ASSERT(plrel->plr_dep == &iopl->iop_base);
276  M0_UT_ASSERT(plrel->plr_rdep == plop);
277  m0_layout_plop_start(plop);
278  m0_layout_plop_done(plop);
279 
280  rc = m0_layout_plan_get(plan, 0, &plop);
281  M0_UT_ASSERT(rc == 0);
282  M0_UT_ASSERT(plop != NULL);
283  M0_UT_ASSERT(plop->pl_type == M0_LAT_DONE);
284  m0_layout_plop_start(plop);
285  m0_layout_plop_done(plop);
286 
287  m0_layout_plan_fini(plan);
288 
289  m0_op_fini(op);
290  m0_op_free(op);
291 
292  m0_entity_fini(&obj.ob_entity);
293 
296  m0_indexvec_free(&ext);
297 
298  M0_LEAVE();
299 }
300 
301 /*
302  * Note: In test_init() and test_fini(), need to use M0_ASSERT()
303  * instead of M0_UT_ASSERT().
304  */
305 static int lap_ut_init(void)
306 {
307  int rc;
308 
310  M0_ASSERT(rc == 0);
311 
313  M0_ASSERT(rc == 0);
314 
315  return 0;
316 }
317 
318 static int lap_ut_fini(void)
319 {
322 
323  return 0;
324 }
325 
327  .ts_name = "layout-access-plan-ut",
328  .ts_owners = "Andriy T.",
329  .ts_init = lap_ut_init,
330  .ts_fini = lap_ut_fini,
331  .ts_tests = {
332  { "layout-access-plan-build-fini", test_plan_build_fini },
333  { "layout-access-plan-get-done", test_plan_get_done },
334  { NULL, NULL }
335  }
336 };
337 M0_EXPORTED(layout_access_plan_ut);
338 
339 #undef M0_TRACE_SUBSYSTEM
340 
341 /*
342  * Local variables:
343  * c-indentation-style: "K&R"
344  * c-basic-offset: 8
345  * tab-width: 8
346  * fill-column: 80
347  * scroll-step: 1
348  * End:
349  */
int32_t pl_rc
Definition: plan.h:403
#define M0_UT_CONF_PROFILE
Definition: misc.h:43
M0_INTERNAL void m0_layout_plop_done(struct m0_layout_plop *plop)
Definition: plan.c:311
void m0_entity_fini(struct m0_entity *entity)
Definition: client.c:438
Definition: client.h:788
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
#define NULL
Definition: misc.h:38
#define CLIENT_ENDPOINT_ADDR
Definition: plan.c:42
M0_INTERNAL int m0_layout_plan_get(struct m0_layout_plan *plan, uint64_t colour, struct m0_layout_plop **plop)
Definition: plan.c:278
void m0_op_fini(struct m0_op *op)
Definition: client.c:847
struct m0_pool_version * pv
Definition: dir.c:629
char ** rsx_argv
Definition: rpclib.h:77
M0_LEAVE()
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
#define UT_DEFAULT_BLOCK_SIZE
Definition: client.h:67
struct m0_tl pl_deps
Definition: plan.h:388
static struct m0_rpc_server_ctx lap_ut_sctx
Definition: plan.c:56
void m0_client_fini(struct m0_client *m0c, bool fini_m0)
Definition: client_init.c:1711
Definition: idx.h:70
struct m0_bufvec data
Definition: di.c:40
struct m0_fid pl_ent
Definition: plan.h:398
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
static void test_plan_get_done(void)
Definition: plan.c:181
struct m0_ut_suite layout_access_plan_ut
Definition: plan.c:326
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SRC_PATH(name)
Definition: misc.h:48
int m0_client_init(struct m0_client **m0c, struct m0_config *conf, bool init_m0)
Definition: client_init.c:1533
Definition: ut.h:77
#define SERVER_ENDPOINT_ADDR
Definition: plan.c:40
void ** ov_buf
Definition: vec.h:149
static struct foo * obj
Definition: tlist.c:302
static int lap_ut_server_start(void)
Definition: plan.c:62
static void lap_ut_server_stop(void)
Definition: plan.c:70
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
struct m0_vec iv_vec
Definition: vec.h:139
op
Definition: libdemo.c:64
int m0_obj_op(struct m0_obj *obj, enum m0_obj_opcode opcode, struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr, uint64_t mask, uint32_t flags, struct m0_op **op)
Definition: io.c:717
static struct m0_idx_dix_config dix_conf
Definition: plan.c:75
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
m0_bindex_t * iv_index
Definition: vec.h:141
struct m0_pools_common m0c_pools_common
Definition: client.h:641
M0_INTERNAL void ut_realm_entity_setup(struct m0_realm *realm, struct m0_entity *ent, struct m0_client *cinst)
Definition: client.c:60
static int lap_ut_client_start(void)
Definition: plan.c:93
struct m0_bufvec iop_data
Definition: plan.h:499
M0_INTERNAL int m0_pool_version_get(struct m0_pools_common *pc, const struct m0_fid *pool, struct m0_pool_version **pv)
Definition: pool.c:662
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
struct m0_fid pv_id
Definition: pool.h:113
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
#define M0_ASSERT(cond)
m0_bindex_t iop_goff
Definition: plan.h:489
static struct m0_client * client_inst
Definition: plan.c:38
enum m0_layout_plop_type pl_type
Definition: plan.h:357
static void lap_ut_client_stop(void)
Definition: plan.c:115
int m0_net_xprt_nr(void)
Definition: net.c:168
M0_INTERNAL int m0_layout_plop_start(struct m0_layout_plop *plop)
Definition: plan.c:299
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
uint64_t f_container
Definition: fid.h:39
static const char SERVER_LOGFILE[]
Definition: plan.c:44
struct m0_layout_plop * plr_rdep
Definition: plan.h:418
static int lap_ut_init(void)
Definition: plan.c:305
m0_bcount_t * v_count
Definition: vec.h:53
struct m0_layout_plop iop_base
Definition: plan.h:479
struct m0_rpc_session * iop_session
Definition: plan.h:482
M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
Definition: vec.c:53
struct m0_indexvec iop_ext
Definition: plan.h:486
static struct m0_client cinst
Definition: sync.c:84
M0_INTERNAL void m0_layout_plan_fini(struct m0_layout_plan *plan)
Definition: plan.c:229
const char * ts_name
Definition: ut.h:99
static void test_plan_build_fini(void)
Definition: plan.c:124
int rsx_xprts_nr
Definition: rpclib.h:71
uint64_t f_key
Definition: fid.h:40
static struct m0_realm realm
Definition: sync.c:87
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
bool kc_create_meta
Definition: idx.h:183
M0_INTERNAL struct m0_layout_plan * m0_layout_plan_build(struct m0_op *op)
Definition: plan.c:136
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
static char * lap_ut_server_args[]
Definition: plan.c:46
#define M0_ASSERT_INFO(cond, fmt,...)
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
void m0_op_free(struct m0_op *op)
Definition: client.c:885
struct m0_layout_plop * plr_dep
Definition: plan.h:416
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define SERVER_ENDPOINT
Definition: plan.c:41
#define M0_UT_ASSERT(a)
Definition: ut.h:46
Definition: vec.h:145
static int lap_ut_fini(void)
Definition: plan.c:318