Motr  M0
storage_dev_ut.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2015-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_IOSERVICE
24 #include "lib/trace.h"
25 
26 #include <unistd.h> /* get_current_dir_name */
27 
28 #include "ioservice/storage_dev.h" /* m0_storage_devs */
29 #include "balloc/balloc.h" /* BALLOC_DEF_BLOCK_SHIFT */
30 #include "rpc/rpclib.h" /* m0_rpc_server_ctx */
31 #include "lib/finject.h"
32 #include "stob/stob.h"
33 #include "ut/misc.h" /* M0_UT_PATH */
34 #include "ut/ut.h"
35 
36 #define SERVER_ENDPOINT_ADDR "0@lo:12345:34:1"
37 
38 enum {
39  CID1 = 10,
40  CID2 = 12,
41  CID3 = 13,
42 };
43 
44 static int rpc_start(struct m0_rpc_server_ctx *rpc_srv)
45 {
46  enum {
47  LOG_NAME_MAX_LEN = 128,
48  EP_MAX_LEN = 24,
49  RPC_SIZE_MAX_LEN = 32,
50  };
51  const char *confd_ep = SERVER_ENDPOINT_ADDR;
52 
53  char log_name[LOG_NAME_MAX_LEN];
54  char full_ep[EP_MAX_LEN];
55  char max_rpc_size[RPC_SIZE_MAX_LEN];
56 
57  snprintf(full_ep, EP_MAX_LEN, "%s:%s", M0_NET_XPRT_PREFIX_DEFAULT,
58  confd_ep);
59  snprintf(max_rpc_size, RPC_SIZE_MAX_LEN,
61 
62 #define NAME(ext) "io_sdev" ext
63  char *argv[] = {
64  NAME(""), "-T", "AD", "-D", NAME(".db"),
65  "-S", NAME(".stob"), "-A", "linuxstob:"NAME(""),
66  "-w", "10", "-e", full_ep, "-H", SERVER_ENDPOINT_ADDR,
67  "-f", M0_UT_CONF_PROCESS,
68  "-m", max_rpc_size,
69  "-c", M0_UT_PATH("conf.xc")
70  };
71 #undef NAME
72 
73  M0_SET0(rpc_srv);
74 
75  rpc_srv->rsx_xprts = m0_net_all_xprt_get();
76  rpc_srv->rsx_xprts_nr = m0_net_xprt_nr();
77  rpc_srv->rsx_argv = argv;
78  rpc_srv->rsx_argc = ARRAY_SIZE(argv);
79  snprintf(log_name, LOG_NAME_MAX_LEN, "confd_%s.log", confd_ep);
80  rpc_srv->rsx_log_file_name = log_name;
81 
82  return m0_rpc_server_start(rpc_srv);
83 }
84 
85 static int create_test_file(const char *filename)
86 {
87  int rc;
88  FILE *file;
89  char str[0x1000]="rfb";
90 
91  file = fopen(filename, "w+");
92  if (file == NULL)
93  return errno;
94  rc = fwrite(str, 0x1000, 1, file) == 1 ? 0 : -EINVAL;
95  fclose(file);
96  return rc;
97 }
98 
99 static void storage_dev_test(void)
100 {
101  int rc;
102  struct m0_storage_devs devs;
103  const char *location = "linuxstob:io_sdev";
104  struct m0_stob_domain *domain;
105  struct m0_storage_dev *dev1, *dev2, *dev3;
106  struct m0_storage_space space;
107  struct m0_rpc_server_ctx rpc_srv;
108  int total_size;
109  int grp_size;
110  char *cwd;
111  char tmp_location[128];
112  char *fname1, *fname2;
113  int block_size = 1 << BALLOC_DEF_BLOCK_SHIFT;
114  struct m0_conf_sdev sdev = {
115  .sd_obj = { .co_id = M0_FID_TINIT(
117  .sd_bsize = block_size };
118 
119 
120  /* pre-init */
121  rc = rpc_start(&rpc_srv);
122  M0_UT_ASSERT(rc == 0);
123 
124  cwd = get_current_dir_name();
125  M0_UT_ASSERT(cwd != NULL);
126  rc = asprintf(&fname1, "%s/test1", cwd);
127  M0_UT_ASSERT(rc > 0);
128  rc = asprintf(&fname2, "%s/test2", cwd);
129  M0_UT_ASSERT(rc > 0);
130  rc = create_test_file(fname1);
131  M0_UT_ASSERT(rc == 0);
132  rc = create_test_file(fname2);
133  M0_UT_ASSERT(rc == 0);
134 
135  /* init */
136  snprintf(tmp_location, 128, "%s-%d", location, (int)m0_pid());
137  domain = m0_stob_domain_find_by_location(tmp_location);
138  rc = m0_storage_devs_init(&devs,
141  domain,
142  &rpc_srv.rsx_motr_ctx.cc_reqh_ctx.rc_reqh);
143  M0_UT_ASSERT(rc == 0);
144  m0_storage_devs_lock(&devs);
145 
146  /* attach */
147  /*
148  * Total size accounts space for reserved groups and one non-reserved
149  * group.
150  */
151  grp_size = BALLOC_DEF_BLOCKS_PER_GROUP * block_size;
152  total_size = grp_size;
153  rc = m0_storage_dev_new(&devs, 10, fname2, total_size,
154  NULL, false, &dev1);
155  M0_UT_ASSERT(rc == 0);
156  m0_storage_dev_attach(dev1, &devs);
157 
158  sdev.sd_size = total_size;
159  sdev.sd_filename = fname1;
160  sdev.sd_dev_idx = 12;
161  m0_fi_enable("m0_storage_dev_new_by_conf", "no-conf-dev");
162  rc = m0_storage_dev_new_by_conf(&devs, &sdev, false, &dev2);
163  M0_UT_ASSERT(rc == 0);
164  m0_storage_dev_attach(dev2, &devs);
165  m0_fi_disable("m0_storage_dev_new_by_conf", "no-conf-dev");
166 
167  m0_fi_enable_once("m0_alloc", "fail_allocation");
168  rc = m0_storage_dev_new(&devs, 13, "../../some-file", total_size,
169  NULL, false, &dev3);
170  M0_UT_ASSERT(rc == -ENOMEM);
171 
172  m0_fi_enable_off_n_on_m("m0_alloc", "fail_allocation", 1, 1);
173  rc = m0_storage_dev_new(&devs, 13, "../../some-file", total_size,
174  NULL, false, &dev3);
175  m0_fi_disable("m0_alloc", "fail_allocation");
176  M0_UT_ASSERT(rc == -ENOMEM);
177 
178  /* find*/
179  dev1 = m0_storage_devs_find_by_cid(&devs, 10);
180  M0_UT_ASSERT(dev1 != NULL);
181 
182  dev2 = m0_storage_devs_find_by_cid(&devs, 12);
183  M0_UT_ASSERT(dev2 != NULL);
184 
185  dev3 = m0_storage_devs_find_by_cid(&devs, 13);
186  M0_UT_ASSERT(dev3 == NULL);
187 
188  /* space */
189  m0_storage_dev_space(dev1, &space);
190  M0_UT_ASSERT(space.sds_block_size == block_size);
191  /*
192  * Free blocks don't include blocks for reserved groups and we have
193  * only one non-reserved group
194  */
196  M0_UT_ASSERT(space.sds_total_size == total_size);
197 
198  /* detach */
199  m0_storage_dev_detach(dev1);
200  m0_storage_dev_detach(dev2);
201 
202  /* fini */
203  m0_storage_devs_unlock(&devs);
204  m0_storage_devs_fini(&devs);
205 
206  m0_rpc_server_stop(&rpc_srv);
207  rc = unlink(fname1);
208  M0_UT_ASSERT(rc == 0);
209  rc = unlink(fname2);
210  M0_UT_ASSERT(rc == 0);
211  free(fname1);
212  free(fname2);
213  free(cwd);
214 }
215 
216 static void storage_dev_linux(void)
217 {
218  struct m0_rpc_server_ctx *rpc_srv;
219  struct m0_storage_devs *devs;
220  struct m0_storage_dev *dev1;
221  struct m0_storage_dev *dev2;
222  struct m0_stob_id stob_id;
223  struct m0_stob *stob;
224  char *cwd;
225  char *path1;
226  char *path2;
227  char *location1;
228  char *location2;
229  int rc;
230 
231  cwd = get_current_dir_name();
232  M0_UT_ASSERT(cwd != NULL);
233  rc = asprintf(&path1, "%s/test1", cwd);
234  M0_UT_ASSERT(rc > 0);
235  rc = asprintf(&path2, "%s/test2", cwd);
236  M0_UT_ASSERT(rc > 0);
237 
238  M0_ALLOC_PTR(devs);
239  M0_ALLOC_PTR(rpc_srv);
240  rc = rpc_start(rpc_srv);
241  M0_UT_ASSERT(rc == 0);
243  &rpc_srv->rsx_motr_ctx.cc_reqh_ctx.rc_reqh);
244  M0_UT_ASSERT(rc == 0);
245 
246  rc = m0_storage_dev_new(devs, CID1, path1, 0, NULL, false, &dev1);
247  M0_UT_ASSERT(rc == 0);
248  M0_UT_ASSERT(dev1 != NULL);
249  rc = m0_storage_dev_new(devs, CID2, path2, 0, NULL, false, &dev2);
250  M0_UT_ASSERT(rc == 0);
251  M0_UT_ASSERT(dev2 != NULL);
252  m0_storage_devs_lock(devs);
253  m0_storage_dev_attach(dev1, devs);
254  m0_storage_dev_attach(dev2, devs);
258 
261 
262  m0_stob_id_make(0, 1, &dev1->isd_domain->sd_id, &stob_id);
263  rc = m0_storage_dev_stob_create(devs, &stob_id, NULL);
264  M0_UT_ASSERT(rc == 0);
265  rc = m0_storage_dev_stob_find(devs, &stob_id, &stob);
266  M0_UT_ASSERT(rc == 0);
270 
271  m0_storage_devs_lock(devs);
272  m0_storage_dev_detach(dev1);
275  rc = m0_storage_dev_stob_find(devs, &stob_id, &stob);
276  M0_UT_ASSERT(rc != 0);
277 
278  rc = m0_storage_dev_new(devs, CID1, path1, 0, NULL, false, &dev1);
279  M0_UT_ASSERT(rc == 0);
280  M0_UT_ASSERT(dev1 != NULL);
281  m0_storage_devs_lock(devs);
282  m0_storage_dev_attach(dev1, devs);
285  rc = m0_storage_dev_stob_find(devs, &stob_id, &stob);
286  M0_UT_ASSERT(rc == 0);
288  /* Mark the stob state as CSS_DELETE */
291  M0_UT_ASSERT(rc == 0);
292 
293  /* force option */
294  rc = m0_storage_dev_stob_create(devs, &stob_id, NULL);
295  M0_UT_ASSERT(rc == 0);
296  rc = m0_storage_dev_stob_find(devs, &stob_id, &stob);
297  M0_UT_ASSERT(rc == 0);
300  m0_storage_devs_lock(devs);
301  m0_storage_dev_detach(dev1);
303  rc = m0_storage_dev_new(devs, CID1, path1, 0, NULL, true, &dev1);
304  M0_UT_ASSERT(rc == 0);
305  M0_UT_ASSERT(dev1 != NULL);
306  m0_storage_devs_lock(devs);
307  m0_storage_dev_attach(dev1, devs);
309  rc = m0_storage_dev_stob_find(devs, &stob_id, &stob);
310  M0_UT_ASSERT(rc == 0);
313 
314  m0_storage_devs_lock(devs);
317  rc = m0_stob_domain_destroy_location(location1);
318  M0_UT_ASSERT(rc == 0);
319  rc = m0_stob_domain_destroy_location(location2);
320  M0_UT_ASSERT(rc == 0);
321  m0_free(location1);
322  m0_free(location2);
323  m0_storage_devs_fini(devs);
324  m0_rpc_server_stop(rpc_srv);
325  m0_free(rpc_srv);
326  m0_free(devs);
327 
328  free(path1);
329  free(path2);
330  free(cwd);
331 }
332 
334  .ts_name = "storage-dev-ut",
335  .ts_init = NULL,
336  .ts_fini = NULL,
337  .ts_tests = {
338  { "storage-dev-test", storage_dev_test },
339  { "storage-dev-linux", storage_dev_linux },
340  { NULL, NULL },
341  },
342 };
343 M0_EXPORTED(storage_dev_ut);
344 
345 #undef M0_TRACE_SUBSYSTEM
346 
347 /*
348  * Local variables:
349  * c-indentation-style: "K&R"
350  * c-basic-offset: 8
351  * tab-width: 8
352  * fill-column: 80
353  * scroll-step: 1
354  * End:
355  */
const char * sd_filename
Definition: obj.h:649
struct m0_fid co_id
Definition: obj.h:208
M0_INTERNAL struct m0_stob_domain * m0_stob_dom_get(struct m0_stob *stob)
Definition: stob.c:338
M0_INTERNAL struct m0_storage_dev * m0_storage_devs_find_by_cid(struct m0_storage_devs *devs, uint64_t cid)
Definition: storage_dev.c:152
#define m0_strdup(s)
Definition: string.h:43
#define NULL
Definition: misc.h:38
m0_bcount_t sds_free_blocks
Definition: storage_dev.h:273
M0_INTERNAL int m0_storage_dev_stob_find(struct m0_storage_devs *devs, struct m0_stob_id *sid, struct m0_stob **stob)
Definition: storage_dev.c:868
M0_INTERNAL void m0_storage_dev_attach(struct m0_storage_dev *dev, struct m0_storage_devs *devs)
Definition: storage_dev.c:633
M0_INTERNAL void m0_storage_dev_stob_put(struct m0_storage_devs *devs, struct m0_stob *stob)
Definition: storage_dev.c:912
struct m0_file file
Definition: di.c:36
static void storage_dev_test(void)
char ** rsx_argv
Definition: rpclib.h:77
uint8_t ft_id
Definition: fid.h:101
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
struct m0_stob_domain * isd_domain
Definition: storage_dev.h:79
const struct m0_conf_obj_type M0_CONF_SDEV_TYPE
Definition: sdev.c:122
#define M0_SET0(obj)
Definition: misc.h:64
Definition: ut.h:77
const char * location
Definition: storage.c:50
#define SERVER_ENDPOINT_ADDR
M0_INTERNAL int m0_storage_dev_new_by_conf(struct m0_storage_devs *devs, struct m0_conf_sdev *sdev, bool force, struct m0_storage_dev **dev)
Definition: storage_dev.c:590
M0_INTERNAL struct m0_stob_domain * m0_stob_domain_find_by_location(const char *location)
Definition: domain.c:284
uint32_t sd_dev_idx
Definition: obj.h:635
M0_INTERNAL int m0_storage_dev_new(struct m0_storage_devs *devs, uint64_t cid, const char *path, uint64_t size, struct m0_conf_sdev *conf_sdev, bool force, struct m0_storage_dev **dev)
Definition: storage_dev.c:576
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
const char * rsx_log_file_name
Definition: rpclib.h:81
M0_INTERNAL void m0_storage_devs_lock(struct m0_storage_devs *devs)
Definition: storage_dev.c:71
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
Definition: stob.h:163
#define M0_NET_XPRT_PREFIX_DEFAULT
Definition: net.h:98
const struct m0_fid_type cot_ftype
Definition: obj.h:314
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
static struct m0_stob * stob
Definition: storage.c:39
struct m0_be_seg * rc_beseg
Definition: setup.h:268
M0_INTERNAL int m0_storage_dev_stob_destroy(struct m0_storage_devs *devs, struct m0_stob *stob, struct m0_dtx *dtx)
Definition: storage_dev.c:836
struct m0_reqh rc_reqh
Definition: setup.h:312
int m0_net_xprt_nr(void)
Definition: net.c:168
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
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
M0_INTERNAL void m0_storage_devs_fini(struct m0_storage_devs *devs)
Definition: storage_dev.c:107
uint64_t sd_size
Definition: obj.h:643
M0_INTERNAL void m0_storage_devs_detach_all(struct m0_storage_devs *devs)
Definition: storage_dev.c:743
M0_INTERNAL int m0_storage_devs_init(struct m0_storage_devs *devs, enum m0_storage_dev_type type, struct m0_be_seg *be_seg, struct m0_stob_domain *bstore_dom, struct m0_reqh *reqh)
Definition: storage_dev.c:83
static void m0_fi_enable_off_n_on_m(const char *func, const char *tag, uint32_t n, uint32_t m)
Definition: finject.h:346
M0_INTERNAL int m0_stob_domain_destroy_location(const char *location)
Definition: domain.c:242
struct m0_fid sd_id
Definition: domain.h:96
const char * ts_name
Definition: ut.h:99
m0_bcount_t sds_block_size
Definition: storage_dev.h:274
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
Definition: stob.h:91
int rsx_xprts_nr
Definition: rpclib.h:71
#define NAME(ext)
struct m0_reqh_context cc_reqh_ctx
Definition: setup.h:361
M0_INTERNAL void m0_storage_dev_detach(struct m0_storage_dev *dev)
Definition: storage_dev.c:652
M0_INTERNAL const char * m0_stob_domain_location_get(const struct m0_stob_domain *dom)
Definition: domain.c:306
M0_INTERNAL void m0_storage_dev_space(struct m0_storage_dev *dev, struct m0_storage_space *space)
Definition: storage_dev.c:674
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_storage_dev_stob_create(struct m0_storage_devs *devs, struct m0_stob_id *sid, struct m0_dtx *dtx)
Definition: storage_dev.c:810
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
struct m0_conf_obj sd_obj
Definition: obj.h:616
static int create_test_file(const char *filename)
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
M0_INTERNAL void m0_storage_devs_unlock(struct m0_storage_devs *devs)
Definition: storage_dev.c:77
struct m0_ut_suite storage_dev_ut
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
static int rpc_start(struct m0_rpc_server_ctx *rpc_srv)
M0_INTERNAL void m0_stob_delete_mark(struct m0_stob *stob)
Definition: stob.c:193
#define M0_UT_PATH(name)
Definition: misc.h:41
M0_INTERNAL uint64_t m0_pid(void)
Definition: kthread.c:290
static void storage_dev_linux(void)
m0_bcount_t sds_total_size
Definition: storage_dev.h:276
static struct m0_layout_domain domain
Definition: layout.c:49
void m0_free(void *data)
Definition: memory.c:146
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