Motr  M0
example.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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_CLIENT
24 #include "lib/trace.h"
25 
26 #include "motr/client.h"
27 #include "motr/st/st.h"
28 #include "motr/st/st_misc.h"
29 #include "motr/st/st_assert.h"
30 
32 static struct m0_uint128 test_id;
33 static uint64_t layout_id;
34 
35 /*
36  * copy-cat of st_obj_delete_multiple just to show
37  * how to write a more complicated test using new assert method.
38  */
39 static void example_abitmorecomplicated(void)
40 {
41  uint32_t n_objs = 5;
42  uint32_t rounds = 20;
43  uint32_t max_ops = 4; /* max. ops in one launch() */
44  struct m0_uint128 *ids = NULL;
45  struct m0_obj *objs = NULL;
46  struct m0_op **ops = NULL;
47  bool *obj_exists = NULL;
48  bool *already_chosen = NULL;
49  uint32_t i;
50  uint32_t j;
51  uint32_t idx;
52  uint32_t n_ops;
53  int rc;
54 
55 
57 
58  /*
59  * Don't worry about freeing memory, ST will do it for you
60  * if you forget to do so.
61  * Note: use client ST self-ownned MEM_XXX and mem_xxx rather
62  * than motr stuff
63  */
64  MEM_ALLOC_ARR(ids, n_objs);
66  MEM_ALLOC_ARR(objs, n_objs);
67  ST_ASSERT_FATAL(objs != NULL);
68  MEM_ALLOC_ARR(obj_exists, n_objs);
69  ST_ASSERT_FATAL(obj_exists != NULL);
70  MEM_ALLOC_ARR(already_chosen, n_objs);
71  ST_ASSERT_FATAL(already_chosen != NULL);
72 
73  MEM_ALLOC_ARR(ops, max_ops);
75  for (i = 0; i < max_ops; i++)
76  ops[i] = NULL;
77 
78  /*
79  * Initialise the objects. Closed set.
80  *
81  * Note: use client api wrapper (xxx) instead of
82  * m0_xxx directly
83  */
84  for (i = 0; i < n_objs; ++i)
85  oid_get(ids + i);
86 
87  /* Repeat several rounds. */
88  for (i = 0; i < rounds; ++i) {
89  /* Each round, a different number of ops in the same launch. */
90  n_ops = generate_random(max_ops) + 1;
91  memset(already_chosen, 0, n_objs*sizeof(already_chosen[0]));
92 
93  /* Set the ops. */
94  for (j = 0; j < n_ops; ++j) {
95  /* Pick n_ops objects. */
96  do {
97  //XXX this is broken in kernel mode
98  idx = generate_random(n_objs);
99  } while(already_chosen[idx]);
100  already_chosen[idx] = true;
101 
102  M0_SET0(&objs[idx]);
103  st_obj_init(&objs[idx],
105  &ids[idx], layout_id);
106  if (obj_exists[idx]) {
107  st_entity_open(&objs[idx].ob_entity);
109  &objs[idx].ob_entity, &ops[j]);
110  obj_exists[idx] = false;
111  ST_ASSERT_FATAL(ops[j] != NULL);
112  } else {
114  NULL, &objs[idx].ob_entity, &ops[j]);
115  obj_exists[idx] = true;
116  ST_ASSERT_FATAL(ops[j] != NULL);
117  }
118  ST_ASSERT_FATAL(rc == 0);
119  ST_ASSERT_FATAL(ops[j] != NULL);
120  ST_ASSERT_FATAL(ops[j]->op_sm.sm_rc == 0);
121  }
122 
123  /* Launch and check. */
124  st_op_launch(ops, n_ops);
125 
126  for (j = 0; j < n_ops; ++j) {
127  rc = st_op_wait(ops[j],
129  M0_OS_STABLE),
130  M0_TIME_NEVER);
131  ST_ASSERT_FATAL(rc == 0);
134  || ops[j]->op_sm.sm_state == M0_OS_FAILED);
135  st_op_fini(ops[j]);
136  }
137  }
138 
139  /* No operations should be pending at this point. */
140  for (i = 0; i < max_ops; ++i)
141  st_op_free(ops[i]);
142 
143  for (i = 0; i < n_objs; ++i)
144  st_entity_fini(&objs[i].ob_entity);
145 
146  /*
147  * Release all the allocated structs. If you want, you can
148  *` ask ST to do the dirty job for you by skipping this step.
149  */
150  if (ids != NULL)
151  mem_free(ids);
152  if (objs != NULL)
153  mem_free(objs);
154  if (obj_exists != NULL)
155  mem_free(obj_exists);
156  if (already_chosen != NULL)
157  mem_free(already_chosen);
158  if (ops != NULL)
159  mem_free(ops);
160 }
161 
162 /* copy-cat of st_obj_create_multiple */
163 static void example_simple(void)
164 {
165  enum { CREATE_MULTIPLE_N_OBJS = 20 };
166  uint32_t i;
167  struct m0_op *ops[CREATE_MULTIPLE_N_OBJS] = {NULL};
168  struct m0_obj **objs = NULL;
169  struct m0_uint128 ids[CREATE_MULTIPLE_N_OBJS];
170  int rc;
171 
173 
174  MEM_ALLOC_ARR(objs, CREATE_MULTIPLE_N_OBJS);
175  ST_ASSERT_FATAL(objs != NULL);
176  for (i = 0; i < CREATE_MULTIPLE_N_OBJS; ++i) {
177  MEM_ALLOC_PTR(objs[i]);
178  ST_ASSERT_FATAL(objs[i] != NULL);
179  memset(objs[i], 0, sizeof *objs[i]);
180  }
181 
182  oid_get_many(ids, CREATE_MULTIPLE_N_OBJS);
183 
184  /* Create different objects. */
185  for (i = 0; i < CREATE_MULTIPLE_N_OBJS; ++i) {
186  st_obj_init(objs[i],
188  &ids[i], layout_id);
190  &objs[i]->ob_entity, &ops[i]);
191  ST_ASSERT_FATAL(rc == 0);
192  ST_ASSERT_FATAL(ops[i] != NULL);
193  ST_ASSERT_FATAL(ops[i]->op_sm.sm_rc == 0);
194  }
195 
197 
198  /* We wait for each op. */
199  for (i = 0; i < CREATE_MULTIPLE_N_OBJS; ++i) {
201  M0_OS_STABLE),
202  time_from_now(5,0));
203  ST_ASSERT_FATAL(rc == 0 || rc == -ETIMEDOUT);
204  }
205 
206  /* All correctly created. */
207  for (i = 0; i < CREATE_MULTIPLE_N_OBJS; ++i) {
208  st_op_fini(ops[i]);
209  st_op_free(ops[i]);
210 
211  st_entity_fini(&objs[i]->ob_entity);
212  mem_free(objs[i]);
213  }
214 
215  mem_free(objs);
216 }
217 
218 static int st_example_init(void)
219 {
220  int rc = 0;
221 
222  /*
223  * Retrieve the uber realm. We don't need to open this,
224  * as realms are not actually implemented yet
225  */
227  &M0_UBER_REALM,
228  st_get_instance());
230 
231  if (rc != 0)
232  console_printf("Failed to open uber realm\n");
233 
234  test_id = M0_ID_APP;
236  return rc;
237 }
238 
239 static int st_example_fini(void)
240 {
241  return 0;
242 }
243 
245  .ss_name = "example_st",
246  .ss_init = st_example_init,
247  .ss_fini = st_example_fini,
248  .ss_tests = {
249  { "example_simple",
250  &example_simple},
251  { "example_abitmorecomplicated",
253  { NULL, NULL }
254  }
255 };
256 
257 #undef M0_TRACE_SUBSYSTEM
258 
259 /*
260  * Local variables:
261  * c-indentation-style: "K&R"
262  * c-basic-offset: 8
263  * tab-width: 8
264  * fill-column: 80
265  * scroll-step: 1
266  * End:
267  */
int st_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: api.c:71
static void example_simple(void)
Definition: example.c:163
void st_op_free(struct m0_op *op)
Definition: api.c:147
Definition: client.h:788
#define NULL
Definition: misc.h:38
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static struct m0_uint128 test_id
Definition: example.c:32
#define MEM_ALLOC_PTR(arr)
Definition: st_misc.h:81
static void example_abitmorecomplicated(void)
Definition: example.c:39
uint64_t m0_client_layout_id(const struct m0_client *instance)
Definition: obj.c:859
uint64_t oid_get_many(struct m0_uint128 *oids, uint64_t nr_oids)
Definition: oid.c:397
#define M0_BITS(...)
Definition: misc.h:236
static int st_example_fini(void)
Definition: example.c:239
#define M0_SET0(obj)
Definition: misc.h:64
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
#define ST_ASSERT_FATAL(a)
Definition: st_assert.h:31
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
static int st_example_init(void)
Definition: example.c:218
int i
Definition: dir.c:1033
struct m0_realm co_realm
Definition: client.h:881
Definition: client.h:641
struct m0_sm op_sm
Definition: client.h:656
void st_container_init(struct m0_container *con, struct m0_realm *parent, const struct m0_uint128 *id, struct m0_client *instance)
Definition: api.c:34
struct m0_entity re_entity
Definition: client.h:871
int oid_get(struct m0_uint128 *oid)
Definition: oid.c:373
Definition: st.h:83
struct st_suite st_suite_example
Definition: example.c:244
int32_t sm_rc
Definition: sm.h:336
void console_printf(const char *fmt,...)
Definition: st_misc.c:155
static void mem_free(const struct m0_be_btree *btree, struct m0_be_tx *tx, void *ptr)
Definition: btree.c:102
struct m0_addb2__id_intrp ids[]
Definition: dump.c:1074
void st_obj_init(struct m0_obj *obj, struct m0_realm *parent, const struct m0_uint128 *id, uint64_t layout_id)
Definition: api.c:42
#define MEM_ALLOC_ARR(arr, nr)
Definition: st_misc.h:80
struct m0_client * st_get_instance()
Definition: st.c:57
#define M0_CLIENT_THREAD_ENTER
void st_op_launch(struct m0_op **op, uint32_t nr)
Definition: api.c:129
void st_entity_fini(struct m0_entity *entity)
Definition: api.c:94
uint32_t generate_random(uint32_t max)
Definition: st_misc.c:164
const char * ss_name
Definition: st.h:85
int st_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: api.c:83
struct m0_container st_example_container
Definition: example.c:31
void st_entity_open(struct m0_entity *entity)
Definition: api.c:153
struct m0_sm en_sm
Definition: client.h:732
struct m0_fom_ops ops
Definition: io_foms.c:623
int32_t st_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: api.c:136
uint32_t sm_state
Definition: sm.h:307
void st_op_fini(struct m0_op *op)
Definition: api.c:142
static uint64_t layout_id
Definition: example.c:33
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
uint64_t time_from_now(uint64_t secs, uint64_t ns)
Definition: st_misc.c:89