Motr  M0
cancel.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 /*
24  * Client API system tests to check if Client API matches its
25  * specifications.
26  */
27 
28 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
29 #include "lib/trace.h"
30 #include "lib/misc.h" /* M0_SET0 */
31 #include "motr/client.h"
32 #include "motr/st/st.h"
33 #include "motr/st/st_misc.h"
34 #include "motr/st/st_assert.h"
35 
36 #include "lib/memory.h"
37 
39 extern struct m0_addb_ctx m0_addb_ctx;
40 static const uint32_t UNIT_SIZE = DEFAULT_PARGRP_UNIT_SIZE;
41 static uint64_t layout_id;
42 
43 static void create_obj(struct m0_uint128 *oid)
44 {
45  int rc;
46  struct m0_uint128 id;
47  struct m0_op *op = NULL;
48  struct m0_obj obj;
49 
50  M0_SET0(&obj);
51 
52  /* get oid */
53  oid_get(&id);
54 
55  /* Create an entity */
58  &id, layout_id);
59 
60  st_entity_create(NULL, &obj.ob_entity, &op);
61  M0_ASSERT(op != NULL);
62 
63  st_op_launch(&op, 1);
64 
65  /* Wait for op to complete */
67  M0_OS_STABLE),
69  M0_ASSERT(rc == 0);
70  M0_ASSERT(op->op_sm.sm_state == M0_OS_STABLE);
71  M0_ASSERT(op->op_sm.sm_rc == 0);
72 
73  /* fini and release */
74  st_op_fini(op);
75  st_op_free(op);
76  st_entity_fini(&obj.ob_entity);
77 
78  *oid = id;
79 }
80 
81 static void op_cancel(struct m0_op **ops, int obj_cnt, int start_obj)
82 {
83  int i;
84  int rc;
85  int cur_obj;
86 
87  for (i = 0; i < obj_cnt; ++i) {
88  cur_obj = start_obj + i;
89  m0_op_cancel(&ops[cur_obj], 1);
90  }
91  for (i = 0; i < obj_cnt; ++i) {
92  cur_obj = start_obj + i;
93  rc = st_op_wait(ops[cur_obj],
95  M0_OS_STABLE),
97  ST_ASSERT_FATAL(rc == 0);
98  }
99 }
100 
104 static void m0_write_cancel(void)
105 {
106  enum {OBJECT_NR = 20};
107 
108  int i;
109  int rc;
110  int obj_cnt;
111  int start_obj;
112  int cur_obj;
113  int blk_cnt;
114  int blk_size;
115  uint64_t last_index;
116  struct m0_uint128 *ids;
117  struct m0_obj *objs;
118  struct m0_op **ops;
119  struct m0_indexvec ext;
120  struct m0_bufvec data;
121  struct m0_bufvec attr;
122 
123  MEM_ALLOC_ARR(objs, OBJECT_NR);
124  ST_ASSERT_FATAL(objs != NULL);
125  MEM_ALLOC_ARR(ids, OBJECT_NR);
127  MEM_ALLOC_ARR(ops, OBJECT_NR);
129 
130  for (i = 0; i < OBJECT_NR; ++i)
131  create_obj(ids + i);
132 
133  /* Prepare the data with 'value' */
134  blk_cnt = 1000;
135  blk_size = UNIT_SIZE;
136 
137  rc = m0_bufvec_alloc(&data, blk_cnt, blk_size);
138  ST_ASSERT_FATAL(rc == 0);
139 
140  for (i = 0; i < blk_cnt; i++)
141  memset(data.ov_buf[i], 'A', blk_size);
142 
143  /* Prepare indexvec for write */
144  rc = m0_bufvec_alloc(&attr, blk_cnt, 1);
145  ST_ASSERT_FATAL(rc == 0);
146  rc = m0_indexvec_alloc(&ext, blk_cnt);
147  ST_ASSERT_FATAL(rc == 0);
148 
149  last_index = 0;
150  for (i = 0; i < blk_cnt; i++) {
151  ext.iv_index[i] = last_index ;
152  ext.iv_vec.v_count[i] = blk_size;
153  last_index += blk_size;
154  /* we don't want any attributes */
155  attr.ov_vec.v_count[i] = 0;
156  }
157  for (i = 0; i < OBJECT_NR; ++i) {
158  M0_SET0(&objs[i]);
159  ops[i] = NULL;
160  /* Set the object entity we want to write */
161  st_obj_init(&objs[i],
163  &ids[i], layout_id);
164  st_entity_open(&objs[i].ob_entity);
165  /* Create the write request */
166  st_obj_op(&objs[i], M0_OC_WRITE, &ext, &data,
167  NULL, 0, 0, &ops[i]);
168  }
169  /*
170  * Launch the write request for half of the objects and
171  * cancel them immediately
172  */
173  obj_cnt = OBJECT_NR / 2;
174  start_obj = 0;
175  st_op_launch(ops, obj_cnt);
176  for (i = 0; i < obj_cnt; ++i) {
177  rc = st_op_wait(ops[i],
179  M0_TIME_NEVER);
180  ST_ASSERT_FATAL(rc == 0);
181  }
182  op_cancel(ops, obj_cnt, start_obj);
183 
184  /*
185  * Launch the write request for first half of the remaining
186  * objects and wait for the 1st write for 2s and then go for
187  * canceling all the write operations
188  */
189  obj_cnt = OBJECT_NR / 4;
190  start_obj = OBJECT_NR / 2;
191  for (i = 0; i < obj_cnt; ++i) {
192  cur_obj = start_obj + i;
193  st_op_launch(&ops[cur_obj], 1);
194  }
195  rc = st_op_wait(ops[start_obj],
197  M0_OS_STABLE),
198  m0_time_from_now(2, 0));
199 
200  op_cancel(ops, obj_cnt, start_obj);
201 
202  /*
203  * Launch the write request for the second half of the remaining
204  * objects and wait for the 1st write for completion and then go
205  * for canceling all the write operations
206  */
207  start_obj = OBJECT_NR - OBJECT_NR / 4;
208  for (i = 0; i < obj_cnt; ++i) {
209  cur_obj = start_obj + i;
210  st_op_launch(&ops[cur_obj], 1);
211  }
212  rc = st_op_wait(ops[start_obj],
214  M0_OS_STABLE),
215  M0_TIME_NEVER);
216  ST_ASSERT_FATAL(rc == 0);
217 
218  op_cancel(ops, obj_cnt, start_obj);
219 
220  for (i = 0; i < OBJECT_NR; ++i) {
221  /* fini and release */
222  st_op_fini(ops[i]);
223  st_op_free(ops[i]);
224  st_entity_fini(&objs[i].ob_entity);
225  }
228  m0_indexvec_free(&ext);
229  mem_free(objs);
230  mem_free(ids);
231  mem_free(ops);
232 }
233 
237 static int st_cancel_suite_init(void)
238 {
239  int rc;
240 
241  /*
242  * Retrieve the uber realm. We don't need to open this,
243  * as realms are not actually implemented yet
244  */
247  st_get_instance());
249  if (rc != 0) {
250  console_printf("Failed to open uber realm\n");
251  return M0_RC(rc);
252  }
254  return M0_RC(rc);
255 }
256 
260 static int st_cancel_suite_fini(void)
261 {
262  return 0;
263 }
264 
266  .ss_name = "cancel_st",
267  .ss_init = st_cancel_suite_init,
268  .ss_fini = st_cancel_suite_fini,
269  .ss_tests = {
270  { "cancel_while_write",
271  &m0_write_cancel },
272  { NULL, NULL }
273  }
274 };
275 
276 #undef M0_TRACE_SUBSYSTEM
277 
278 /*
279  * Local variables:
280  * c-indentation-style: "K&R"
281  * c-basic-offset: 8
282  * tab-width: 8
283  * fill-column: 80
284  * scroll-step: 1
285  * End:
286  */
uint64_t id
Definition: cob.h:2380
int st_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: api.c:71
static void op_cancel(struct m0_op **ops, int obj_cnt, int start_obj)
Definition: cancel.c:81
void st_op_free(struct m0_op *op)
Definition: api.c:147
Definition: client.h:788
static int st_cancel_suite_fini(void)
Definition: cancel.c:260
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
#define NULL
Definition: misc.h:38
static uint64_t layout_id
Definition: cancel.c:41
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
struct m0_bufvec data
Definition: di.c:40
uint64_t m0_client_layout_id(const struct m0_client *instance)
Definition: obj.c:859
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
#define M0_BITS(...)
Definition: misc.h:236
#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
void ** ov_buf
Definition: vec.h:149
static struct foo * obj
Definition: tlist.c:302
static void create_obj(struct m0_uint128 *oid)
Definition: cancel.c:43
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
return M0_RC(rc)
op
Definition: libdemo.c:64
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
m0_bindex_t * iv_index
Definition: vec.h:141
int i
Definition: dir.c:1033
struct m0_realm co_realm
Definition: client.h:881
Definition: client.h:641
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
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
static int st_cancel_suite_init(void)
Definition: cancel.c:237
int oid_get(struct m0_uint128 *oid)
Definition: oid.c:373
#define M0_ASSERT(cond)
Definition: st.h:83
struct m0_addb_ctx m0_addb_ctx
struct st_suite st_suite_cancel
Definition: cancel.c:265
struct m0_container st_cancel_container
Definition: cancel.c:38
int32_t sm_rc
Definition: sm.h:336
m0_bcount_t * v_count
Definition: vec.h:53
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
void m0_op_cancel(struct m0_op **op, uint32_t nr)
Definition: client.c:639
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
void st_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: api.c:100
#define MEM_ALLOC_ARR(arr, nr)
Definition: st_misc.h:80
static void m0_write_cancel(void)
Definition: cancel.c:104
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
struct m0_client * st_get_instance()
Definition: st.c:57
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
const char * ss_name
Definition: st.h:85
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
void st_op_fini(struct m0_op *op)
Definition: api.c:142
int32_t rc
Definition: trigger_fop.h:47
Definition: vec.h:145
static const uint32_t UNIT_SIZE
Definition: cancel.c:40