Motr  M0
stob.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2014-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 "be/ut/helper.h" /* m0_be_ut_backend, m0_be_ut_seg */
24 #include "lib/errno.h"
25 #include "lib/memory.h"
26 #include "lib/semaphore.h"
27 #include "module/instance.h" /* m0_get */
28 #include "ut/ut.h" /* M0_UT_ASSERT */
29 #include "ut/stob.h" /* m0_ut_stob_linux_get */
30 #include "ut/threads.h"
31 
32 #include "stob/ad.h" /* m0_stob_ad_cfg_make */
33 #include "stob/domain.h"
34 #include "stob/stob.h"
35 
36 enum {
41 };
42 
43 struct stob_ut_ctx {
44  struct m0_mutex *su_lock;
47  uint64_t su_stob_key;
49  const char *su_cfg;
51 };
52 
53 static void stob_ut_stob_thread(void *param)
54 {
55  struct stob_ut_ctx *ctx = (struct stob_ut_ctx *)param;
56  struct m0_be_ut_backend *ut_be = ctx->su_ut_be;
57  struct m0_be_domain *be_dom;
58  struct m0_stob *stob;
59  bool stob_creator = false;
60  int rc;
61  int i;
62  struct m0_stob_id stob_id;
63 
64  be_dom = ut_be == NULL ? NULL : &ut_be->but_dom;
65  m0_stob_id_make(0, ctx->su_stob_key, &ctx->su_domain->sd_id, &stob_id);
66  rc = m0_stob_find(&stob_id, &stob);
67  M0_UT_ASSERT(rc == 0);
69 
70  m0_mutex_lock(ctx->su_lock);
75  M0_UT_ASSERT(rc == 0);
76  }
78  rc = m0_ut_stob_create(stob, ctx->su_cfg, be_dom);
79  M0_UT_ASSERT(rc == 0);
80  stob_creator = true;
81  }
83  m0_mutex_unlock(ctx->su_lock);
84 
85  /* Reference counting */
88 
89  if (!stob_creator) {
91  m0_semaphore_up(ctx->su_destroy_sem);
92  } else {
93  for (i = 0; i < ctx->su_users_nr - 1; ++i)
94  m0_semaphore_down(ctx->su_destroy_sem);
95  rc = m0_ut_stob_destroy(stob, be_dom);
96  M0_UT_ASSERT(rc == 0);
97  }
98 
99  /*
100  * m0_ut_stob_create() makes implicit m0_be_ut_backend_sm_group_lookup()
101  * therefore we need to call m0_be_ut_backend_thread_exit() for every
102  * thread that has called the helper. Otherwise, m0_be_ut_backend_fini()
103  * fails because of unlocked thread's sm group.
104  * Simplify this task and call the exit function for all threads.
105  */
106  if (ut_be != NULL) {
109  }
110 }
111 
113 
115  const char *location,
116  const char *dom_cfg,
117  const char *dom_init_cfg,
118  const char *stob_cfg,
119  int thread_nr,
120  int stob_nr)
121 {
122  struct stob_ut_ctx *ctxs;
123  struct m0_mutex *stob_mtxs;
124  struct m0_semaphore *destroy_sems;
125  struct m0_stob_domain *dom;
126  uint64_t dom_key = 0xec0de;
127  int rc;
128  int i;
129 
130  M0_UT_ASSERT(stob_nr <= thread_nr);
131  /* simplification */
132  M0_UT_ASSERT(thread_nr % stob_nr == 0);
133 
134  M0_ALLOC_ARR(ctxs, thread_nr);
135  M0_UT_ASSERT(ctxs != NULL);
136  M0_ALLOC_ARR(stob_mtxs, stob_nr);
137  M0_UT_ASSERT(stob_mtxs != NULL);
138  M0_ALLOC_ARR(destroy_sems, stob_nr);
139  M0_UT_ASSERT(destroy_sems != NULL);
140 
141  rc = m0_stob_domain_create(location, dom_init_cfg, dom_key,
142  dom_cfg, &dom);
143  M0_UT_ASSERT(rc == 0);
144 
145  for (i = 0; i < stob_nr; ++i) {
146  m0_mutex_init(&stob_mtxs[i]);
147  m0_semaphore_init(&destroy_sems[i], 0);
148  }
149  for (i = 0; i < thread_nr; ++i) {
150  ctxs[i] = (struct stob_ut_ctx) {
151  .su_lock = &stob_mtxs[i % stob_nr],
152  .su_destroy_sem = &destroy_sems[i % stob_nr],
153  .su_users_nr = thread_nr / stob_nr,
154  .su_stob_key = i % stob_nr + 1,
155  .su_domain = dom,
156  .su_cfg = stob_cfg,
157  .su_ut_be = ut_be,
158  };
159  }
160 
161  M0_UT_THREADS_START(stob_ut_stob, thread_nr, ctxs);
162  M0_UT_THREADS_STOP(stob_ut_stob);
163 
164  for (i = 0; i < stob_nr; ++i)
165  m0_mutex_fini(&stob_mtxs[i]);
166  m0_free(stob_mtxs);
167  m0_free(ctxs);
168 
170 }
171 
173  const char *location,
174  const char *dom_cfg,
175  const char *dom_init_cfg,
176  const char *stob_cfg)
177 {
178  struct m0_be_domain *be_dom = ut_be == NULL ? NULL : &ut_be->but_dom;
179  struct m0_stob_domain *dom;
180  struct m0_stob *stob;
181  struct m0_stob *stob2;
182  struct m0_stob_id stob_id;
183  uint64_t dom_key = 0xec0de;
184  uint64_t stob_key = 0xc0deba5e;
185  int rc;
186 
187  rc = m0_stob_domain_create(location, dom_init_cfg,
188  dom_key, dom_cfg, &dom);
189  M0_UT_ASSERT(rc == 0);
190 
191  m0_stob_id_make(0, stob_key, &dom->sd_id, &stob_id);
192  rc = m0_stob_find(&stob_id, &stob);
193  M0_UT_ASSERT(rc == 0);
194  M0_UT_ASSERT(stob != NULL);
196 
198  M0_UT_ASSERT(rc == 0);
200 
201  rc = m0_ut_stob_create(stob, stob_cfg, be_dom);
202  M0_UT_ASSERT(rc == 0);
205  rc = m0_ut_stob_create(stob, stob_cfg, be_dom);
206  M0_UT_ASSERT(rc == -EEXIST);
207 
208  rc = m0_stob_lookup(&stob_id, &stob2);
209  M0_UT_ASSERT(rc == 0);
210  M0_UT_ASSERT(stob2 == stob);
211  m0_stob_put(stob2);
212 
213  m0_stob_get(stob);
214  m0_stob_put(stob);
215 
216  stob_id = *m0_stob_id_get(stob);
217 
218  m0_stob_put(stob);
220 
221  rc = m0_stob_domain_init(location, dom_init_cfg, &dom);
222  M0_UT_ASSERT(rc == 0);
223  rc = m0_stob_find(&stob_id, &stob);
224  M0_UT_ASSERT(rc == 0);
225  M0_UT_ASSERT(stob != NULL);
228  M0_UT_ASSERT(rc == 0);
231 
232  rc = m0_stob_lookup(&stob_id, &stob2);
233  M0_UT_ASSERT(rc == 0);
234  M0_UT_ASSERT(stob2 == stob);
235  m0_stob_put(stob2);
236 
237  rc = m0_ut_stob_destroy(stob, be_dom);
238  M0_UT_ASSERT(rc == 0);
240  M0_UT_ASSERT(rc == 0);
241 }
242 
244 {
246  stob_ut_stob_single(NULL, "nullstob:path", NULL, NULL, NULL);
247  stob_ut_stob_multi(NULL,"nullstob:path", NULL, NULL, NULL,
249 }
250 
251 #ifndef __KERNEL__
253 {
254  stob_ut_stob_single(NULL, "linuxstob:./__s", NULL, NULL, NULL);
255  stob_ut_stob_multi(NULL, "linuxstob:./__s", NULL, NULL, NULL,
257 }
258 
260 {
261  stob_ut_stob_single(NULL, "perfstob:./__s", NULL, NULL, NULL);
262  stob_ut_stob_multi(NULL, "perfstob:./__s", NULL, NULL, NULL,
264 }
265 
267 {
268  stob_ut_stob_single(NULL, "perfstob:./__s", "null=true", NULL, NULL);
269  stob_ut_stob_multi(NULL, "perfstob:./__s", "null=true", NULL, NULL,
271 }
272 
273 extern void m0_stob_ut_ad_init(struct m0_be_ut_backend *ut_be,
274  struct m0_be_ut_seg *ut_seg);
275 extern void m0_stob_ut_ad_fini(struct m0_be_ut_backend *ut_be,
276  struct m0_be_ut_seg *ut_seg);
277 
279 {
280  struct m0_be_ut_backend ut_be;
281  struct m0_be_ut_seg ut_seg;
282  struct m0_stob *stob;
283  char *dom_cfg;
284  char *dom_init_cfg;
285 
288  M0_UT_ASSERT(stob != NULL);
289 
291  M0_UT_ASSERT(dom_cfg != NULL);
292  m0_stob_ad_init_cfg_make(&dom_init_cfg, &ut_be.but_dom);
293  M0_UT_ASSERT(dom_init_cfg != NULL);
294 
295  stob_ut_stob_single(&ut_be, "adstob:some_suffix",
296  dom_cfg, dom_init_cfg, NULL);
297  stob_ut_stob_multi(&ut_be, "adstob:some_suffix", dom_cfg, dom_init_cfg,
299 
300  m0_free(dom_cfg);
301  m0_free(dom_init_cfg);
302  m0_ut_stob_put(stob, true);
304 }
305 #endif
306 
307 /*
308  * Local variables:
309  * c-indentation-style: "K&R"
310  * c-basic-offset: 8
311  * tab-width: 8
312  * fill-column: 80
313  * scroll-step: 1
314  * End:
315  */
316 /*
317  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
318  */
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
#define NULL
Definition: misc.h:38
static void stob_ut_stob_single(struct m0_be_ut_backend *ut_be, const char *location, const char *dom_cfg, const char *dom_init_cfg, const char *stob_cfg)
Definition: stob.c:172
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
static void stob_ut_stob_multi(struct m0_be_ut_backend *ut_be, const char *location, const char *dom_cfg, const char *dom_init_cfg, const char *stob_cfg, int thread_nr, int stob_nr)
Definition: stob.c:114
struct m0_semaphore * su_destroy_sem
Definition: stob.c:45
M0_INTERNAL int m0_stob_domain_destroy(struct m0_stob_domain *dom)
Definition: domain.c:227
#define M0_CASSERT(cond)
void m0_stob_ut_stob_linux(void)
Definition: stob.c:252
struct m0_be_seg * bus_seg
Definition: helper.h:119
uint64_t su_stob_key
Definition: stob.c:47
M0_INTERNAL int m0_ut_stob_destroy(struct m0_stob *stob, struct m0_be_domain *be_dom)
Definition: stob.c:222
struct m0_be_ut_seg ut_seg
Definition: ad.c:73
M0_INTERNAL const struct m0_fid * m0_stob_fid_get(struct m0_stob *stob)
Definition: stob.c:255
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:170
M0_INTERNAL void m0_stob_ad_init_cfg_make(char **str, struct m0_be_domain *dom)
Definition: ad.c:212
struct m0_stob_domain * su_domain
Definition: stob.c:46
const char * location
Definition: storage.c:50
M0_INTERNAL int m0_stob_lookup(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:119
void m0_stob_ut_stob_ad(void)
Definition: stob.c:278
struct m0_be_ut_backend * su_ut_be
Definition: stob.c:50
int i
Definition: dir.c:1033
M0_INTERNAL struct m0_stob * m0_ut_stob_linux_get(void)
Definition: stob.c:169
M0_INTERNAL int m0_stob_domain_create(const char *location, const char *str_cfg_init, uint64_t dom_key, const char *str_cfg_create, struct m0_stob_domain **out)
Definition: domain.c:217
void m0_stob_ut_stob_null(void)
Definition: stob.c:243
void m0_stob_ut_ad_init(struct m0_be_ut_backend *ut_be, struct m0_be_ut_seg *ut_seg)
struct m0_be_ut_backend ut_be
Definition: ad.c:72
M0_INTERNAL const struct m0_stob_id * m0_stob_id_get(struct m0_stob *stob)
Definition: stob.c:250
Definition: stob.h:163
static struct m0_stob * stob
Definition: storage.c:39
static struct m0_stob_domain * dom
Definition: storage.c:38
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_fid si_fid
Definition: stob.h:105
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
struct m0_sm_group * m0_be_ut_backend_sm_group_lookup(struct m0_be_ut_backend *ut_be)
Definition: stubs.c:277
struct m0_mutex * su_lock
Definition: stob.c:44
struct m0_be_domain but_dom
Definition: helper.h:47
M0_INTERNAL void m0_ut_stob_put(struct m0_stob *stob, bool destroy)
Definition: stob.c:185
M0_INTERNAL void m0_stob_domain_fini(struct m0_stob_domain *dom)
Definition: domain.c:204
struct m0_fid sd_id
Definition: domain.h:96
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
const char * su_cfg
Definition: stob.c:49
Definition: stob.h:91
M0_INTERNAL int m0_stob_domain_init(const char *location, const char *str_cfg_init, struct m0_stob_domain **out)
Definition: domain.c:195
M0_UT_THREADS_DEFINE(stob_ut_stob, stob_ut_stob_thread)
void m0_stob_ut_stob_perf(void)
Definition: stob.c:259
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
void m0_stob_ut_stob_perf_null(void)
Definition: stob.c:266
#define M0_UT_THREADS_STOP(name)
Definition: threads.h:55
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
static void stob_ut_stob_thread(void *param)
Definition: stob.c:53
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
Definition: nucleus.c:42
M0_INTERNAL int m0_ut_stob_create(struct m0_stob *stob, const char *str_cfg, struct m0_be_domain *be_dom)
Definition: stob.c:202
M0_INTERNAL void m0_stob_ad_cfg_make(char **str, const struct m0_be_seg *seg, const struct m0_stob_id *bstore_id, const m0_bcount_t size)
Definition: ad.c:220
#define M0_UT_THREADS_START(name, thread_nr, param_array)
Definition: threads.h:51
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
void m0_stob_ut_ad_fini(struct m0_be_ut_backend *ut_be, struct m0_be_ut_seg *ut_seg)
Definition: ad.c:106
int su_users_nr
Definition: stob.c:48
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
M0_INTERNAL void m0_stob_get(struct m0_stob *stob)
Definition: stob.c:275
int32_t rc
Definition: trigger_fop.h:47
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_stob_put(struct m0_stob *stob)
Definition: stob.c:291
void m0_be_ut_backend_thread_exit(struct m0_be_ut_backend *ut_be)
Definition: stubs.c:282