Motr  M0
example1.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  * Example Motr application to create object, write to object,
24  * read from objet, and then delete the object.
25  */
26 
27 /*
28  * Please change the dir according to you development environment.
29  *
30  * How to build:
31  * gcc -I/work/cortx-motr -DM0_EXTERN=extern -DM0_INTERNAL= -Wno-attributes \
32  * -L/work/cortx-motr/motr/.libs -lmotr \
33  * example1.c -o example1
34  *
35  * Please change the configuration according to you development environment.
36  *
37  * How to run:
38  * LD_LIBRARY_PATH=/work/cortx-motr/motr/.libs/ \
39  * ./example1 172.16.154.179@tcp:12345:34:1 172.16.154.179@tcp:12345:33:1000 \
40  * "<0x7000000000000001:0>" "<0x7200000000000001:64>" 12345670
41  */
42 
43 #include "motr/client.h"
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <errno.h>
47 
48 static struct m0_client *m0_instance = NULL;
50 static struct m0_config motr_conf;
52 
53 struct m0_uint128 obj_id = { 0, 0 };
54 
56 {
57  struct m0_obj obj;
58  struct m0_client *instance;
59  struct m0_op *ops[1] = {NULL};
60  int rc;
61 
62  M0_SET0(&obj);
66 
67  rc = m0_entity_create(NULL, &obj.ob_entity, &ops[0]);
68  if (rc != 0) {
69  printf("Failed to create object: %d\n", rc);
70  return rc;
71  }
72 
73  m0_op_launch(ops, 1);
74  rc = m0_op_wait(ops[0],
77  if (rc == 0)
78  rc = ops[0]->op_rc;
79 
80  m0_op_fini(ops[0]);
81  m0_op_free(ops[0]);
82  ops[0] = NULL;
83 
84  m0_entity_fini(&obj.ob_entity);
85 
86  printf("Object (id=%lu) creation result: %d\n",
87  (unsigned long)obj_id.u_lo, rc);
88  return rc;
89 }
90 
91 static int object_open(struct m0_obj *obj)
92 {
93  struct m0_op *ops[1] = {NULL};
94  int rc;
95 
96  rc = m0_entity_open(&obj->ob_entity, &ops[0]);
97  if (rc != 0) {
98  printf("Failed to open object: %d\n", rc);
99  return rc;
100  }
101 
102  m0_op_launch(ops, 1);
103  rc = m0_op_wait(ops[0],
105  M0_TIME_NEVER);
106  if (rc == 0)
107  rc = ops[0]->op_rc;
108 
109  m0_op_fini(ops[0]);
110  m0_op_free(ops[0]);
111  ops[0] = NULL;
112 
113  /* obj is valid if open succeeded */
114  printf("Object (id=%lu) open result: %d\n",
115  (unsigned long)obj_id.u_lo, rc);
116  return rc;
117 }
118 
119 static int alloc_vecs(struct m0_indexvec *ext,
120  struct m0_bufvec *data,
121  struct m0_bufvec *attr,
122  uint32_t block_count,
123  uint32_t block_size)
124 {
125  int rc;
126 
127  rc = m0_indexvec_alloc(ext, block_count);
128  if (rc != 0)
129  return rc;
130 
131  /*
132  * this allocates <block_count> * <block_size> buffers for data,
133  * and initialises the bufvec for us.
134  */
135 
136  rc = m0_bufvec_alloc(data, block_count, block_size);
137  if (rc != 0) {
138  m0_indexvec_free(ext);
139  return rc;
140  }
141  rc = m0_bufvec_alloc(attr, block_count, 1);
142  if (rc != 0) {
143  m0_indexvec_free(ext);
145  return rc;
146  }
147  return rc;
148 }
149 
150 static void prepare_ext_vecs(struct m0_indexvec *ext,
151  struct m0_bufvec *data,
152  struct m0_bufvec *attr,
153  uint32_t block_count,
154  uint32_t block_size,
155  uint64_t *last_index,
156  char c)
157 {
158  int i;
159 
160  for (i = 0; i < block_count; ++i) {
161  ext->iv_index[i] = *last_index;
162  ext->iv_vec.v_count[i] = block_size;
163  *last_index += block_size;
164 
165  /* Fill the buffer with all `c`. */
166  memset(data->ov_buf[i], c, data->ov_vec.v_count[i]);
167  /* we don't want any attributes */
168  attr->ov_vec.v_count[i] = 0;
169  }
170 }
171 
172 static void cleanup_vecs(struct m0_indexvec *ext,
173  struct m0_bufvec *data,
174  struct m0_bufvec *attr)
175 {
176  /* Free bufvec's and indexvec's */
177  m0_indexvec_free(ext);
180 }
181 
182 static int write_data_to_object(struct m0_obj *obj,
183  struct m0_indexvec *ext,
184  struct m0_bufvec *data,
185  struct m0_bufvec *attr)
186 {
187  int rc;
188  struct m0_op *ops[1] = { NULL };
189 
190  /* Create the write request */
191  m0_obj_op(obj, M0_OC_WRITE, ext, data, attr, 0, 0, &ops[0]);
192  if (ops[0] == NULL) {
193  printf("Failed to init a write op\n");
194  return -EINVAL;
195  }
196 
197  /* Launch the write request*/
198  m0_op_launch(ops, 1);
199 
200  /* wait */
201  rc = m0_op_wait(ops[0],
203  M0_OS_STABLE),
204  M0_TIME_NEVER);
205  rc = rc ? : ops[0]->op_sm.sm_rc;
206 
207  /* fini and release the ops */
208  m0_op_fini(ops[0]);
209  m0_op_free(ops[0]);
210  printf("Object write result: %d\n", rc);
211  return rc;
212 }
213 
215 {
216  struct m0_obj obj;
217  struct m0_client *instance;
218  int rc;
219 
220  struct m0_indexvec ext;
221  struct m0_bufvec data;
222  struct m0_bufvec attr;
223 
224  uint64_t last_offset = 0;
225 
226  M0_SET0(&obj);
230 
231  rc = object_open(&obj);
232  if (rc != 0) {
233  printf("Failed to open object: rc=%d\n", rc);
234  return rc;
235  }
236 
237  /*
238  * alloc & prepare ext, data and attr. We will write 4k * 2.
239  */
240  rc = alloc_vecs(&ext, &data, &attr, 2, 4096);
241  if (rc != 0) {
242  printf("Failed to alloc ext & data & attr: %d\n", rc);
243  goto out;
244  }
245  prepare_ext_vecs(&ext, &data, &attr, 2, 4096, &last_offset, 'A');
246 
247  /* Start to write data to object */
248  rc = write_data_to_object(&obj, &ext, &data, &attr);
249  cleanup_vecs(&ext, &data, &attr);
250 
251 out:
252  /* Similar to close() */
253  m0_entity_fini(&obj.ob_entity);
254 
255  printf("Object write: %d\n", rc);
256  return rc;
257 }
258 
259 static int read_data_from_object(struct m0_obj *obj,
260  struct m0_indexvec *ext,
261  struct m0_bufvec *data,
262  struct m0_bufvec *attr)
263 {
264  int rc;
265  struct m0_op *ops[1] = { NULL };
266 
267  /* Create the read request */
268  m0_obj_op(obj, M0_OC_READ, ext, data, attr, 0, 0, &ops[0]);
269  if (ops[0] == NULL) {
270  printf("Failed to init a read op\n");
271  return -EINVAL;
272  }
273 
274  /* Launch the read request*/
275  m0_op_launch(ops, 1);
276 
277  /* wait */
278  rc = m0_op_wait(ops[0],
280  M0_OS_STABLE),
281  M0_TIME_NEVER);
282  rc = rc ? : ops[0]->op_sm.sm_rc;
283 
284  /* fini and release the ops */
285  m0_op_fini(ops[0]);
286  m0_op_free(ops[0]);
287  printf("Object read result: %d\n", rc);
288  return rc;
289 }
290 
291 static void verify_show_data(struct m0_bufvec *data,
292  char c)
293 {
294  int i, j;
295 
296  for (i = 0; i < data->ov_vec.v_nr; ++i) {
297  printf("Block %6d:\n", i);
298  printf("%.*s", (int)data->ov_vec.v_count[i],
299  (char *)data->ov_buf[i]);
300  printf("\n");
301  for (j = 0; j < data->ov_vec.v_count[i]; j++)
302  if (((char*) data->ov_buf[i])[j] != c) {
303  printf("verification failed at: %d:%d\n"
304  "Expected %c result %c\n",
305  i, j, c, ((char*)data->ov_buf[i])[j]);
306  }
307  }
308 }
309 
310 static int object_read(struct m0_container *container)
311 {
312  struct m0_obj obj;
313  struct m0_client *instance;
314  int rc;
315 
316  struct m0_indexvec ext;
317  struct m0_bufvec data;
318  struct m0_bufvec attr;
319 
320  uint64_t last_offset = 0;
321 
322  M0_SET0(&obj);
326 
327  rc = object_open(&obj);
328  if (rc != 0) {
329  printf("Failed to open object: rc=%d\n", rc);
330  return rc;
331  }
332 
333  /*
334  * alloc & prepare ext, data and attr. We will write 4k * 2.
335  */
336  rc = alloc_vecs(&ext, &data, &attr, 2, 4096);
337  if (rc != 0) {
338  printf("Failed to alloc ext & data & attr: %d\n", rc);
339  goto out;
340  }
341  prepare_ext_vecs(&ext, &data, &attr, 2, 4096, &last_offset, '\0');
342 
343  /* Start to read data to object */
344  rc = read_data_from_object(&obj, &ext, &data, &attr);
345  if (rc == 0) {
346  verify_show_data(&data, 'A');
347  }
348  cleanup_vecs(&ext, &data, &attr);
349 
350 out:
351  /* Similar to close() */
352  m0_entity_fini(&obj.ob_entity);
353 
354  printf("Object read: %d\n", rc);
355  return rc;
356 }
357 
359 {
360  struct m0_obj obj;
361  struct m0_client *instance;
362  struct m0_op *ops[1] = { NULL };
363  int rc;
364 
365  M0_SET0(&obj);
369 
370  rc = object_open(&obj);
371  if (rc != 0) {
372  printf("Failed to open object: rc=%d\n", rc);
373  return rc;
374  }
375 
376  m0_entity_delete(&obj.ob_entity, &ops[0]);
377  m0_op_launch(ops, 1);
378  rc = m0_op_wait(ops[0],
380  M0_TIME_NEVER);
381 
382  /* fini and release */
383  m0_op_fini(ops[0]);
384  m0_op_free(ops[0]);
385 
386  /* Similar to close() */
387  m0_entity_fini(&obj.ob_entity);
388 
389  printf("Object deletion: %d\n", rc);
390  return rc;
391 }
392 
393 
394 int main(int argc, char *argv[])
395 {
396  int rc;
397 
398  if (argc != 6) {
399  printf("%s HA_ADDR LOCAL_ADDR Profile_fid Process_fid obj_id\n",
400  argv[0]);
401  exit(-1);
402  }
403  obj_id.u_lo = atoll(argv[5]);
404  if (obj_id.u_lo < M0_ID_APP.u_lo) {
405  printf("obj_id invalid. Please refer to M0_ID_APP "
406  "in motr/client.c\n");
407  exit(-EINVAL);
408  }
409 
411 
412  motr_conf.mc_is_oostore = true;
414  motr_conf.mc_ha_addr = argv[1];
415  motr_conf.mc_local_addr = argv[2];
416  motr_conf.mc_profile = argv[3];
417  motr_conf.mc_process_fid = argv[4];
422 
424  if (rc != 0) {
425  printf("error in m0_client_init: %d\n", rc);
426  exit(rc);
427  }
428 
431  if (rc != 0) {
432  printf("error in m0_container_init: %d\n", rc);
433  goto out;
434  }
435 
437  if (rc == 0) {
439  if (rc == 0) {
441  }
443  }
444 
445 out:
447  printf("app completed: %d\n", rc);
448  return rc;
449 }
450 
451 /*
452  * Local variables:
453  * c-indentation-style: "K&R"
454  * c-basic-offset: 8
455  * tab-width: 8
456  * fill-column: 80
457  * scroll-step: 1
458  * End:
459  */
460 /*
461  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
462  */
static int object_open(struct m0_obj *obj)
Definition: example1.c:91
static int read_data_from_object(struct m0_obj *obj, struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr)
Definition: example1.c:259
static int alloc_vecs(struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr, uint32_t block_count, uint32_t block_size)
Definition: example1.c:119
void m0_entity_fini(struct m0_entity *entity)
Definition: client.c:438
static int object_create(struct m0_container *container)
Definition: example1.c:55
Definition: client.h:788
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
#define NULL
Definition: misc.h:38
const char * mc_process_fid
Definition: client.h:937
static void cleanup_vecs(struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr)
Definition: example1.c:172
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
void m0_op_fini(struct m0_op *op)
Definition: client.c:847
struct m0_container container
struct m0_vec ov_vec
Definition: vec.h:147
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
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
int m0_client_init(struct m0_client **m0c, struct m0_config *conf, bool init_m0)
Definition: client_init.c:1533
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
void ** ov_buf
Definition: vec.h:149
static struct foo * obj
Definition: tlist.c:302
static int object_delete(struct m0_container *container)
Definition: example1.c:358
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
int32_t m0_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: client.c:739
struct m0_vec iv_vec
Definition: vec.h:139
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 motr_dix_conf
Definition: example1.c:51
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
const char * mc_ha_addr
Definition: client.h:935
Definition: client.h:641
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
static void prepare_ext_vecs(struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr, uint32_t block_count, uint32_t block_size, uint64_t *last_index, char c)
Definition: example1.c:150
struct m0_entity re_entity
Definition: client.h:871
static struct m0_container motr_container
Definition: example1.c:49
static struct m0_addb2_callback c
Definition: consumer.c:41
static void verify_show_data(struct m0_bufvec *data, char c)
Definition: example1.c:291
bool mc_is_oostore
Definition: client.h:920
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:725
static struct m0_config motr_conf
Definition: example1.c:50
uint32_t v_nr
Definition: vec.h:51
int32_t sm_rc
Definition: sm.h:336
static int object_read(struct m0_container *container)
Definition: example1.c:310
struct m0_uint128 obj_id
Definition: example1.c:53
m0_bcount_t * v_count
Definition: vec.h:53
static int write_data_to_object(struct m0_obj *obj, struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr)
Definition: example1.c:182
bool mc_is_read_verify
Definition: client.h:925
void * mc_idx_service_conf
Definition: client.h:957
int m0_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:801
int main(int argc, char *argv[])
Definition: example1.c:394
uint32_t mc_max_rpc_msg_size
Definition: client.h:949
const char * mc_local_addr
Definition: client.h:933
static int object_write(struct m0_container *container)
Definition: example1.c:214
int mc_idx_service_id
Definition: client.h:956
bool kc_create_meta
Definition: idx.h:183
uint32_t mc_tm_recv_queue_min_len
Definition: client.h:944
void m0_obj_init(struct m0_obj *obj, struct m0_realm *parent, const struct m0_uint128 *id, uint64_t layout_id)
Definition: client.c:403
static struct m0 instance
Definition: main.c:78
int m0_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:824
void m0_container_init(struct m0_container *con, struct m0_realm *parent, const struct m0_uint128 *id, struct m0_client *instance)
Definition: realm.c:31
struct m0_client * re_instance
Definition: client.h:873
const char * mc_profile
Definition: client.h:938
#define out(...)
Definition: gen.c:41
void m0_op_free(struct m0_op *op)
Definition: client.c:885
struct m0_sm en_sm
Definition: client.h:732
int m0_entity_open(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:885
struct m0_fom_ops ops
Definition: io_foms.c:623
uint64_t u_lo
Definition: types.h:37
int32_t rc
Definition: trigger_fop.h:47
Definition: vec.h:145