Motr  M0
adieu.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #include <stdlib.h> /* system */
23 #include <stdio.h> /* fopen, fgetc, ... */
24 #include <unistd.h> /* unlink */
25 #include <sys/stat.h> /* mkdir */
26 #include <sys/types.h> /* mkdir */
27 
28 #include "lib/misc.h" /* M0_SET0 */
29 #include "lib/memory.h" /* m0_alloc_align */
30 #include "lib/errno.h"
31 #include "lib/finject.h" /* M0_FI_ENABLED */
32 #include "lib/ub.h"
33 #include "ut/stob.h"
34 #include "ut/ut.h"
35 #include "lib/assert.h"
36 #include "lib/arith.h"
37 #include "stob/domain.h"
38 #include "stob/io.h"
39 #include "stob/stob.h"
40 #include "fol/fol.h"
41 #include "balloc/balloc.h" /* M0_BALLOC_NON_SPARE_ZONE */
42 
48 #define AD_ADIEU_CS_SZ 16
49 
50 enum {
51  NR = 4,
52  NR_SORT = 256,
53  MIN_BUF_SIZE = 4096,
55 };
56 
57 enum {
60 };
61 
63 #define PATH "./__s-adieu"
64 static const char linux_location[] = "linuxstob:" PATH;
65 static const char perf_location[] = "perfstob:" PATH;
66 static struct m0_stob_domain *dom;
67 static struct m0_stob *obj;
68 static const char linux_path[] = PATH "/o/100000000000000:2";
69 static const char perf_path[] = PATH "/backstore/o/100000000000000:2";
70 static struct m0_stob_io io;
72 static char *user_buf[NR];
73 static char *user_cksm_buf[NR];
74 static char *read_buf[NR];
75 static char *read_cksm_buf[NR];
76 static char *user_bufs[NR];
77 static char *read_bufs[NR];
79 static struct m0_clink clink;
80 static FILE *f;
81 static uint32_t block_shift;
82 static uint32_t buf_size;
83 
84 static int test_adieu_init(const char *location,
85  const char *dom_cfg,
86  const char *stob_cfg)
87 {
88  int i;
89  int rc;
90  struct m0_stob_id stob_id;
91  char cs_char = 'a';
92 
94  NULL, M0_STOB_UT_DOMAIN_KEY, dom_cfg, &dom);
95  M0_ASSERT(rc == 0);
96  M0_ASSERT(dom != NULL);
97 
99  rc = m0_stob_find(&stob_id, &obj);
100  M0_ASSERT(rc == 0);
101  rc = m0_stob_locate(obj);
102  M0_ASSERT(rc == 0);
103  rc = m0_ut_stob_create(obj, stob_cfg, NULL);
104  M0_ASSERT(rc == 0);
105 
107  /* buf_size is chosen so it would be at least MIN_BUF_SIZE in bytes
108  * or it would consist of at least MIN_BUF_SIZE_IN_BLOCKS blocks */
111 
112  for (i = 0; i < ARRAY_SIZE(user_buf); ++i) {
114  M0_ASSERT(user_buf[i] != NULL);
115  }
116 
117  // Allocate contigious buffer for i/p checksums
120  memset( user_cksm_buf[0], cs_char++, AD_ADIEU_CS_SZ);
121  for (i = 1; i < ARRAY_SIZE(user_cksm_buf); ++i) {
123  memset( user_cksm_buf[i], cs_char++, AD_ADIEU_CS_SZ);
124  }
125 
126  for (i = 0; i < ARRAY_SIZE(read_buf); ++i) {
128  M0_ASSERT(read_buf[i] != NULL);
129  }
130 
131  // Allocate contigious buffer for o/p checksums
134  memset( read_cksm_buf[0], 0, AD_ADIEU_CS_SZ);
135  for (i = 1; i < ARRAY_SIZE(read_cksm_buf); ++i) {
137  memset( read_cksm_buf[i], 0, AD_ADIEU_CS_SZ);
138  }
139 
140  for (i = 0; i < NR; ++i) {
144  stob_vec[i] = (buf_size * (2 * i + 1)) >> block_shift;
145  memset(user_buf[i], ('a' + i)|1, buf_size);
146  }
147  return rc;
148 }
149 
150 static void test_adieu_fini(void)
151 {
152  int i;
153  int rc;
154 
156  M0_ASSERT(rc == 0);
158  M0_ASSERT(rc == 0);
159 
160  for (i = 0; i < ARRAY_SIZE(user_buf); ++i)
161  m0_free(user_buf[i]);
162 
164 
165  for (i = 0; i < ARRAY_SIZE(read_buf); ++i)
166  m0_free(read_buf[i]);
167 
169 }
170 
171 static void test_write(int i)
172 {
173  int rc;
174  struct m0_fol_frag *fol_frag;
175 
176  M0_ALLOC_PTR(fol_frag);
177  M0_UB_ASSERT(fol_frag != NULL);
178 
180 
182  io.si_flags = 0;
183  io.si_fol_frag = fol_frag;
184  io.si_user.ov_vec.v_nr = i;
186  io.si_user.ov_buf = (void **)user_bufs;
187 
188  io.si_stob.iv_vec.v_nr = i;
191 
194  // Checksum for i buf_size blocks
196  io.si_cksum.b_nob = ( i * AD_ADIEU_CS_SZ );
197 
200 
202  M0_ASSERT(rc == 0);
203 
205 
206  M0_ASSERT(io.si_rc == 0);
208 
211 
213 }
214 
215 static void test_read(int i)
216 {
217  int rc;
218 
220 
222  io.si_flags = 0;
223  io.si_user.ov_vec.v_nr = i;
225  io.si_user.ov_buf = (void **)read_bufs;
226 
227  io.si_stob.iv_vec.v_nr = i;
230 
233  // Checksum for i buf_size blocks
235  io.si_cksum.b_nob = ( i * AD_ADIEU_CS_SZ );
236 
239 
241  M0_ASSERT(rc == 0);
242 
244 
245  M0_ASSERT(io.si_rc == 0);
247 
250 
252 }
253 
257 static void test_adieu(const char *path)
258 {
259  int ch;
260  int i;
261  int j;
262 
263  for (i = 1; i < NR; ++i) {
264  test_write(i);
265 
266  /* this works only for linuxstob */
267  f = fopen(path, "r");
268  for (j = 0; j < i; ++j) {
269  int k;
270 
271  for (k = 0; k < buf_size; ++k) {
272  ch = fgetc(f);
273  M0_ASSERT(ch == '\0');
274  M0_ASSERT(!feof(f));
275  }
276  for (k = 0; k < buf_size; ++k) {
277  ch = fgetc(f);
278  M0_ASSERT(ch != '\0');
279  M0_ASSERT(!feof(f));
280  }
281  }
282  ch = fgetc(f);
283  M0_ASSERT(ch == EOF);
284  fclose(f);
285  }
286 
287  for (i = 1; i < NR; ++i) {
288  test_read(i);
289  M0_ASSERT(memcmp(user_buf[i - 1], read_buf[i - 1], buf_size) == 0);
290  // TODO: Check how this can be enabled for linux stob
291  // M0_ASSERT(memcmp(user_cksm_buf[i - 1], read_cksm_buf[i - 1], AD_ADIEU_CS_SZ) == 0);
292  }
293 }
294 
296 {
297  int rc;
298 
300  M0_ASSERT(rc == 0);
302  test_adieu_fini();
303 }
304 
306 {
307  int rc;
308 
310  M0_ASSERT(rc == 0);
312  test_adieu_fini();
313 }
314 
315 /*
316  Adieu unit-benchmark
317  */
318 
319 static void ub_write(int i)
320 {
321  test_write(NR - 1);
322 }
323 
324 static void ub_read(int i)
325 {
326  test_read(NR - 1);
327 }
328 
330 static char *user_bufs1[NR_SORT];
332 
333 static void ub_iovec_init()
334 {
335  int i;
336 
337  for (i = 0; i < NR_SORT ; i++)
338  stob_vec1[i] = MIN_BUF_SIZE * i;
339 
341 
343  io.si_flags = 0;
344 
347  io.si_user.ov_buf = (void **)user_bufs1;
348 
352 }
353 
354 static void ub_iovec_invert()
355 {
356  int i;
357  bool swapped;
358 
359  /* Reverse sort index vecs. */
360  do {
361  swapped = false;
362  for (i = 0; i < NR_SORT - 1; i++) {
363  if (stob_vec1[i] < stob_vec1[i + 1]) {
364  m0_bindex_t tmp = stob_vec1[i];
365  stob_vec1[i] = stob_vec1[i + 1];
366  stob_vec1[i + 1] = tmp;
367  swapped = true;
368  }
369  }
370  } while(swapped);
371 }
372 
373 static void ub_iovec_sort()
374 {
376 }
377 
378 static void ub_iovec_sort_invert()
379 {
380  ub_iovec_invert();
382 }
383 
384 static int ub_init(const char *opts M0_UNUSED)
385 {
387 }
388 
389 static void ub_fini(void)
390 {
391  test_adieu_fini();
392 }
393 
394 enum {
395  UB_ITER = 100,
396  UB_ITER_SORT = 100000
397 };
398 
400  .us_name = "adieu-ub",
401  .us_init = ub_init,
402  .us_fini = ub_fini,
403  .us_run = {
404  { .ub_name = "write-prime",
405  .ub_iter = 1,
406  .ub_round = ub_write,
407  .ub_block_size = MIN_BUF_SIZE,
408  .ub_blocks_per_op = MIN_BUF_SIZE_IN_BLOCKS },
409 
410  { .ub_name = "write",
411  .ub_iter = UB_ITER,
412  .ub_block_size = MIN_BUF_SIZE,
413  .ub_blocks_per_op = MIN_BUF_SIZE_IN_BLOCKS,
414  .ub_round = ub_write },
415 
416  { .ub_name = "read",
417  .ub_iter = UB_ITER,
418  .ub_block_size = MIN_BUF_SIZE,
419  .ub_blocks_per_op = MIN_BUF_SIZE_IN_BLOCKS,
420  .ub_round = ub_read },
421 
422  { .ub_name = "iovec-sort",
423  .ub_iter = UB_ITER_SORT,
424  .ub_init = ub_iovec_init,
425  .ub_block_size = MIN_BUF_SIZE,
426  .ub_blocks_per_op = MIN_BUF_SIZE_IN_BLOCKS,
427  .ub_round = ub_iovec_sort },
428 
429  { .ub_name = "iovec-sort-invert",
430  .ub_iter = UB_ITER_SORT,
431  .ub_init = ub_iovec_init,
432  .ub_block_size = MIN_BUF_SIZE,
433  .ub_blocks_per_op = MIN_BUF_SIZE_IN_BLOCKS,
434  .ub_round = ub_iovec_sort_invert },
435 
436  { .ub_name = NULL }
437  }
438 };
439 
442 /*
443  * Local variables:
444  * c-indentation-style: "K&R"
445  * c-basic-offset: 8
446  * tab-width: 8
447  * fill-column: 80
448  * scroll-step: 1
449  * End:
450  */
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
static void ub_iovec_init()
Definition: adieu.c:333
enum m0_stob_io_flags si_flags
Definition: io.h:290
M0_INTERNAL void m0_stob_io_fini(struct m0_stob_io *io)
Definition: io.c:122
m0_bindex_t si_unit_sz
Definition: io.h:414
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
static void ub_iovec_sort()
Definition: adieu.c:373
Definition: io.h:230
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
#define M0_UB_ASSERT(cond)
Definition: ub.h:37
static void ub_fini(void)
Definition: adieu.c:389
void * b_addr
Definition: buf.h:39
static FILE * f
Definition: adieu.c:80
static m0_bindex_t stob_vec1[NR_SORT]
Definition: adieu.c:331
static struct m0_stob_domain * dom
Definition: adieu.c:66
M0_INTERNAL int m0_stob_domain_destroy(struct m0_stob_domain *dom)
Definition: domain.c:227
static void ub_read(int i)
Definition: adieu.c:324
static char * user_buf[NR]
Definition: adieu.c:72
struct m0_vec ov_vec
Definition: vec.h:147
#define max_check(a, b)
Definition: arith.h:95
static int ub_init(const char *opts M0_UNUSED)
Definition: adieu.c:384
static char * read_cksm_buf[NR]
Definition: adieu.c:75
Definition: adieu.c:395
Definition: adieu.c:51
static const char perf_location[]
Definition: adieu.c:65
static void test_adieu_fini(void)
Definition: adieu.c:150
uint64_t m0_bindex_t
Definition: types.h:80
struct m0_chan si_wait
Definition: io.h:318
uint64_t m0_bcount_t
Definition: types.h:77
struct m0_ub_set m0_adieu_ub
Definition: adieu.c:399
static m0_bcount_t user_vec[NR]
Definition: adieu.c:71
static void ub_iovec_sort_invert()
Definition: adieu.c:378
void ** ov_buf
Definition: vec.h:149
const char * location
Definition: storage.c:50
static void test_read(int i)
Definition: adieu.c:215
struct m0_vec iv_vec
Definition: vec.h:139
M0_INTERNAL uint32_t m0_stob_block_shift(struct m0_stob *stob)
Definition: stob.c:270
struct m0_bufvec si_user
Definition: io.h:300
void m0_stob_ut_adieu_linux(void)
Definition: adieu.c:295
m0_bindex_t * iv_index
Definition: vec.h:141
static char * user_bufs1[NR_SORT]
Definition: adieu.c:330
int i
Definition: dir.c:1033
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
static int test_adieu_init(const char *location, const char *dom_cfg, const char *stob_cfg)
Definition: adieu.c:84
#define AD_ADIEU_CS_SZ
Definition: adieu.c:48
M0_INTERNAL int m0_stob_io_prepare_and_launch(struct m0_stob_io *io, struct m0_stob *obj, struct m0_dtx *tx, struct m0_io_scope *scope)
Definition: io.c:219
struct m0_buf si_cksum
Definition: io.h:412
Definition: stob.h:163
struct m0_indexvec si_stob
Definition: io.h:311
int32_t si_rc
Definition: io.h:334
static const char linux_path[]
Definition: adieu.c:68
static const char perf_path[]
Definition: adieu.c:69
m0_bcount_t b_nob
Definition: buf.h:38
#define M0_ASSERT(cond)
const char * us_name
Definition: ub.h:76
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
M0_INTERNAL void * m0_stob_addr_pack(const void *buf, uint32_t shift)
Definition: io.c:293
void * m0_alloc(size_t size)
Definition: memory.c:126
static struct m0_stob * obj
Definition: adieu.c:67
struct m0_fol_frag * si_fol_frag
Definition: io.h:390
uint32_t v_nr
Definition: vec.h:51
static char * user_cksm_buf[NR]
Definition: adieu.c:73
Definition: io.h:285
static m0_bindex_t stob_vec[NR]
Definition: adieu.c:78
m0_bcount_t * v_count
Definition: vec.h:53
Definition: adieu.c:52
m0_bcount_t si_cksum_sz
Definition: io.h:416
static void test_write(int i)
Definition: adieu.c:171
static struct m0_stob_io io
Definition: adieu.c:70
m0_bcount_t si_count
Definition: io.h:340
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
struct m0_fid sd_id
Definition: domain.h:96
M0_INTERNAL int m0_stob_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
Definition: stob.c:200
static char * read_bufs[NR]
Definition: adieu.c:77
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_stob_iovec_sort(struct m0_stob_io *stob)
Definition: io.c:311
static char * read_buf[NR]
Definition: adieu.c:74
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
M0_INTERNAL void m0_stob_io_init(struct m0_stob_io *io)
Definition: io.c:111
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
static uint32_t buf_size
Definition: adieu.c:82
static char * user_bufs[NR]
Definition: adieu.c:76
#define PATH
Definition: adieu.c:63
static m0_bcount_t user_vec1[NR_SORT]
Definition: adieu.c:329
static uint32_t block_shift
Definition: adieu.c:81
M0_INTERNAL int m0_ut_stob_create(struct m0_stob *stob, const char *str_cfg, struct m0_be_domain *be_dom)
Definition: stob.c:204
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
Definition: io.h:229
static void ub_write(int i)
Definition: adieu.c:319
void m0_free(void *data)
Definition: memory.c:146
void m0_stob_ut_adieu_perf(void)
Definition: adieu.c:305
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
Definition: ub.h:74
static struct m0_clink clink
Definition: adieu.c:79
static void ub_iovec_invert()
Definition: adieu.c:354
static void test_adieu(const char *path)
Definition: adieu.c:257
static const char linux_location[]
Definition: adieu.c:64
enum m0_stob_io_opcode si_opcode
Definition: io.h:286
#define M0_UNUSED
Definition: misc.h:380