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 
63 
64 static int lap_ut_server_start(void)
65 {
69 
71 }
72 
73 static void lap_ut_server_stop(void)
74 {
77 }
78 
79 static struct m0_idx_dix_config dix_conf = {
80  .kc_create_meta = false,
81 };
82 
83 static struct m0_config client_conf = {
84  .mc_is_oostore = true,
85  .mc_is_read_verify = false,
86  .mc_layout_id = 1,
87  .mc_local_addr = CLIENT_ENDPOINT_ADDR,
88  .mc_ha_addr = SERVER_ENDPOINT_ADDR,
89  .mc_profile = M0_UT_CONF_PROFILE,
90  .mc_process_fid = M0_UT_CONF_PROCESS,
91  .mc_tm_recv_queue_min_len = M0_NET_TM_RECV_QUEUE_DEF_LEN,
92  .mc_max_rpc_msg_size = M0_RPC_DEF_MAX_RPC_MSG_SIZE,
93  .mc_idx_service_id = M0_IDX_DIX,
94  .mc_idx_service_conf = &dix_conf,
95 };
96 
97 static int lap_ut_client_start(void)
98 {
99  int rc;
100 
101  m0_fi_enable_once("ha_init", "skip-ha-init");
102  /* Skip HA finalisation in case of failure path. */
103  m0_fi_enable("ha_fini", "skip-ha-fini");
104  /*
105  * We can't use m0_fi_enable_once() here, because
106  * initlift_addb2() may be called twice in case of failure path.
107  */
108  m0_fi_enable("initlift_addb2", "no-addb2");
109  m0_fi_enable("ha_process_event", "no-link");
111  M0_ASSERT_INFO(rc == 0, "rc=%d", rc);
112  m0_fi_disable("ha_process_event", "no-link");
113  m0_fi_disable("initlift_addb2", "no-addb2");
114  m0_fi_disable("ha_fini", "skip-ha-fini");
115 
116  return 0;
117 }
118 
119 static void lap_ut_client_stop(void)
120 {
121  m0_fi_enable_once("ha_fini", "skip-ha-fini");
122  m0_fi_enable_once("initlift_addb2", "no-addb2");
123  m0_fi_enable("ha_process_event", "no-link");
124  m0_client_fini(client_inst, false);
125  m0_fi_disable("ha_process_event", "no-link");
126  client_inst = NULL;
127 }
128 
129 static void test_plan_build_fini(void)
130 {
131  int rc;
132  struct m0_client *cinst = client_inst;
133  struct m0_pool_version *pv;
134  struct m0_layout_plan *plan;
135  struct m0_op *op = NULL;
136  struct m0_indexvec ext;
137  struct m0_bufvec data;
138  struct m0_bufvec attr;
139  struct m0_realm realm;
140  struct m0_obj obj = {};
141 
142  M0_ENTRY();
143 
144  M0_UT_ASSERT(m0_indexvec_alloc(&ext, 1) == 0);
147  M0_UT_ASSERT(m0_bufvec_alloc(&attr, 1, 1) == 0);
148 
150  M0_UT_ASSERT(rc == 0);
151  ut_realm_entity_setup(&realm, &obj.ob_entity, cinst);
152  obj.ob_attr.oa_bshift = M0_MIN_BUF_SHIFT;
153  obj.ob_attr.oa_pver = pv->pv_id;
154  obj.ob_attr.oa_layout_id = M0_DEFAULT_LAYOUT_ID;
155 
156  rc = m0_obj_op(&obj, M0_OC_READ, &ext, &data, &attr, 0, 0, &op);
157  M0_UT_ASSERT(rc == 0);
158 
159  /* check happy path */
160  plan = m0_layout_plan_build(op);
161  M0_UT_ASSERT(plan != NULL);
162 
163  m0_layout_plan_fini(plan);
164 
165  /* check error paths */
166  m0_fi_enable_once("pargrp_iomap_init", "no-mem-err");
167  plan = m0_layout_plan_build(op);
168  M0_UT_ASSERT(plan == NULL);
169 
170  m0_fi_enable_once("target_ioreq_init", "no-mem-err");
171  plan = m0_layout_plan_build(op);
172  M0_UT_ASSERT(plan == NULL);
173 
174  m0_op_fini(op);
175  m0_op_free(op);
176 
177  m0_entity_fini(&obj.ob_entity);
178 
181  m0_indexvec_free(&ext);
182 
183  M0_LEAVE();
184 }
185 
186 static void test_plan_get_done(void)
187 {
188  int rc;
189  struct m0_client *cinst = client_inst;
190  struct m0_pool_version *pv;
191  struct m0_layout_plan *plan;
192  struct m0_op *op = NULL;
193  struct m0_layout_plop *plop;
194  struct m0_layout_io_plop *iopl;
195  struct m0_layout_plop_rel *plrel;
196  struct m0_indexvec ext;
197  struct m0_bufvec data;
198  struct m0_bufvec attr;
199  struct m0_realm realm;
200  struct m0_obj obj = {};
201 
202  M0_ENTRY();
203 
204  M0_UT_ASSERT(m0_indexvec_alloc(&ext, 2) == 0);
207  ext.iv_index[0] = 0;
210  M0_UT_ASSERT(m0_bufvec_alloc(&attr, 2, 1) == 0);
211 
213  M0_UT_ASSERT(rc == 0);
214  ut_realm_entity_setup(&realm, &obj.ob_entity, cinst);
215  obj.ob_attr.oa_bshift = M0_MIN_BUF_SHIFT;
216  obj.ob_attr.oa_pver = pv->pv_id;
217  obj.ob_attr.oa_layout_id = M0_DEFAULT_LAYOUT_ID;
218 
219  rc = m0_obj_op(&obj, M0_OC_READ, &ext, &data, &attr, 0, 0, &op);
220  M0_UT_ASSERT(rc == 0);
221 
222  plan = m0_layout_plan_build(op);
223  M0_UT_ASSERT(plan != NULL);
224 
225  /* 1st unit */
226  rc = m0_layout_plan_get(plan, 0, &plop);
227  M0_UT_ASSERT(rc == 0);
228  M0_UT_ASSERT(plop != NULL);
229  M0_UT_ASSERT(plop->pl_type == M0_LAT_READ);
230  M0_UT_ASSERT(plop->pl_ent.f_container != 0 ||
231  plop->pl_ent.f_key != 0);
232  iopl = container_of(plop, struct m0_layout_io_plop, iop_base);
233  M0_UT_ASSERT(iopl->iop_session != NULL);
234  M0_UT_ASSERT(iopl->iop_ext.iv_index != NULL);
235  M0_UT_ASSERT(iopl->iop_goff == 0);
238  M0_UT_ASSERT(iopl->iop_data.ov_buf != NULL);
239 
240  m0_layout_plop_start(plop);
241  plop->pl_rc = 0;
242  m0_layout_plop_done(plop);
243 
244  rc = m0_layout_plan_get(plan, 0, &plop);
245  M0_UT_ASSERT(rc == 0);
246  M0_UT_ASSERT(plop != NULL);
248  plrel = pldeps_tlist_head(&plop->pl_deps);
249  M0_UT_ASSERT(plrel != NULL);
250  M0_UT_ASSERT(plrel->plr_dep == &iopl->iop_base);
251  M0_UT_ASSERT(plrel->plr_rdep == plop);
252  m0_layout_plop_start(plop);
253  m0_layout_plop_done(plop);
254 
255  /* 2nd unit */
256  rc = m0_layout_plan_get(plan, 0, &plop);
257  M0_UT_ASSERT(rc == 0);
258  M0_UT_ASSERT(plop != NULL);
259  M0_UT_ASSERT(plop->pl_type == M0_LAT_READ);
260  M0_UT_ASSERT(plop->pl_ent.f_container != 0 ||
261  plop->pl_ent.f_key != 0);
262  iopl = container_of(plop, struct m0_layout_io_plop, iop_base);
263  M0_UT_ASSERT(iopl->iop_session != NULL);
264  M0_UT_ASSERT(iopl->iop_ext.iv_index != NULL);
268  M0_UT_ASSERT(iopl->iop_data.ov_buf != NULL);
269 
270  m0_layout_plop_start(plop);
271  plop->pl_rc = 0;
272  m0_layout_plop_done(plop);
273 
274  rc = m0_layout_plan_get(plan, 0, &plop);
275  M0_UT_ASSERT(rc == 0);
276  M0_UT_ASSERT(plop != NULL);
278  plrel = pldeps_tlist_head(&plop->pl_deps);
279  M0_UT_ASSERT(plrel != NULL);
280  M0_UT_ASSERT(plrel->plr_dep == &iopl->iop_base);
281  M0_UT_ASSERT(plrel->plr_rdep == plop);
282  m0_layout_plop_start(plop);
283  m0_layout_plop_done(plop);
284 
285  rc = m0_layout_plan_get(plan, 0, &plop);
286  M0_UT_ASSERT(rc == 0);
287  M0_UT_ASSERT(plop != NULL);
288  M0_UT_ASSERT(plop->pl_type == M0_LAT_DONE);
289  m0_layout_plop_start(plop);
290  m0_layout_plop_done(plop);
291 
292  m0_layout_plan_fini(plan);
293 
294  m0_op_fini(op);
295  m0_op_free(op);
296 
297  m0_entity_fini(&obj.ob_entity);
298 
301  m0_indexvec_free(&ext);
302 
303  M0_LEAVE();
304 }
305 
306 /*
307  * Note: In test_init() and test_fini(), need to use M0_ASSERT()
308  * instead of M0_UT_ASSERT().
309  */
310 static int lap_ut_init(void)
311 {
312  int rc;
313 
315  M0_ASSERT(rc == 0);
316 
318  M0_ASSERT(rc == 0);
319 
320  return 0;
321 }
322 
323 static int lap_ut_fini(void)
324 {
327 
328  return 0;
329 }
330 
332  .ts_name = "layout-access-plan-ut",
333  .ts_owners = "Andriy T.",
334  .ts_init = lap_ut_init,
335  .ts_fini = lap_ut_fini,
336  .ts_tests = {
337  { "layout-access-plan-build-fini", test_plan_build_fini },
338  { "layout-access-plan-get-done", test_plan_get_done },
339  { NULL, NULL }
340  }
341 };
342 M0_EXPORTED(layout_access_plan_ut);
343 
344 #undef M0_TRACE_SUBSYSTEM
345 
346 /*
347  * Local variables:
348  * c-indentation-style: "K&R"
349  * c-basic-offset: 8
350  * tab-width: 8
351  * fill-column: 80
352  * scroll-step: 1
353  * End:
354  */
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:794
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:848
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:186
struct m0_ut_suite layout_access_plan_ut
Definition: plan.c:331
#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 m0_rpc_server_ctx lap_ut_sctx0
Definition: plan.c:62
static struct foo * obj
Definition: tlist.c:302
static int lap_ut_server_start(void)
Definition: plan.c:64
static void lap_ut_server_stop(void)
Definition: plan.c:73
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:79
#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:647
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:97
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:119
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:310
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:129
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:189
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:886
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:323