Motr  M0
copy_mt.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2019-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 <stdlib.h>
24 #include <stdio.h>
25 #include <getopt.h>
26 
27 #include "lib/memory.h" /* m0_free() */
28 #include "lib/trace.h"
29 #include "motr/client.h"
30 #include "motr/client_internal.h"
31 #include "motr/st/utils/helper.h"
32 
33 static struct m0_client *m0_instance = NULL;
34 static struct m0_container container;
35 static struct m0_config conf;
37 
39 {
40  int index;
41 
42  /* lock ensures that each thread writes on different object id */
43  m0_mutex_lock(&args->cma_mutex);
44  index = args->cma_index;
45  args->cma_utility->cup_id = args->cma_ids[index];
46  args->cma_index++;
47  m0_mutex_unlock(&args->cma_mutex);
48  args->cma_rc[index] = m0_write(&container,
49  args->cma_utility->cup_file,
50  args->cma_utility->cup_id,
51  args->cma_utility->cup_block_size,
52  args->cma_utility->cup_block_count,
53  args->cma_utility->cup_offset,
54  args->cma_utility->cup_blks_per_io,
55  false,
56  args->cma_utility->cup_update_mode);
57 }
58 
59 static void copy_mt_usage(FILE *file, char *prog_name)
60 {
61  fprintf(file, "Usage: %s [OPTION]... SOURCE\n"
62 "Copy SOURCE to MOTR (Multithreaded: One thread per object).\n"
63 "Designed to dump large amount of data into Motr"
64 "\n"
65 "Mandatory arguments to long options are mandatory for short options too.\n"
66 " -l, --local ADDR Local endpoint address.\n"
67 " -H, --ha ADDR HA endpoint address.\n"
68 " -p, --profile FID Profile FID.\n"
69 " -P, --process FID Process FID.\n"
70 " -o, --object FID ID of the first motr object.\n"
71 " -n, --n_obj INT No of objects to write.\n"
72 " -s, --block-size INT Block size multiple of 4k in bytes or with "
73  "suffix b/k/m/g.\n%*c Ex: 1k=1024, "
74  "1m=1024*1024. Range: [4k-32m]\n"
75 " -c, --block-count INT Number of blocks (>0) to copy, can give with "
76  "suffix b/k/m/g/K/M/G.\n%*c Ex: 1k=1024, "
77  "1m=1024*1024, 1K=1000 1M=1000*1000.\n"
78 " -L, --layout-id INT Layout ID, Range: [1-14].\n"
79 " -b, --blocks-per-io INT Number of blocks (>=0) per IO. Default=100 "
80  "if 0 or nothing is provided.\n"
81 " -O, --offset INT Updates the exisiting object from given "
82  "offset. \n%*c Default=0 if not provided. "
83  "Offset should be multiple of 4k.\n"
84 " -r, --read-verify Verify parity after reading the data.\n"
85 " -S, --msg_size INT Max RPC msg size 64k i.e 65536\n"
86  "%*c Note: this should match with m0d's current "
87  "rpc msg size\n"
88 " -q, --min_queue INT Minimum length of the receive queue i.e 16\n"
89 " -u, --update_mode INT Object update mode\n"
90 " -h, --help Shows this help text and exit.\n"
91 , prog_name, WIDTH, ' ', WIDTH, ' ', WIDTH, ' ', WIDTH, ' ');
92 }
93 
94 
95 int main(int argc, char **argv)
96 {
97  struct m0_utility_param copy_mt_params;
98  struct m0_copy_mt_args copy_mt_args;
99  struct m0_thread *copy_th = NULL;
100  int i = 0;
101  int rc;
102  int obj_nr;
103 
104  m0_utility_args_init(argc, argv, &copy_mt_params,
106 
107  /* Read Verify is only for m0cat */
108  conf.mc_is_read_verify = false;
109 
110  if (copy_mt_params.cup_blks_per_io > M0_MAX_BLOCK_COUNT) {
111  fprintf(stderr, "Blocks per IO (%d) is out of range. "
112  "Max is %d for write operation!\n",
113  copy_mt_params.cup_blks_per_io,
115  return -EINVAL;
116  }
117 
119  if (rc < 0) {
120  fprintf(stderr, "init failed! rc = %d\n", rc);
121  exit(EXIT_FAILURE);
122  }
123 
124  if (argv[optind] != NULL)
125  copy_mt_params.cup_file = strdup(argv[optind]);
126 
127  copy_mt_args.cma_index = 0;
128  copy_mt_args.cma_utility = &copy_mt_params;
129  m0_mutex_init(&copy_mt_args.cma_mutex);
130  obj_nr = copy_mt_params.cup_n_obj;
131 
132  M0_ALLOC_ARR(copy_th, obj_nr);
133  M0_ALLOC_ARR(copy_mt_args.cma_ids, obj_nr);
134  M0_ALLOC_ARR(copy_mt_args.cma_rc, obj_nr);
135 
136  for (i = 0; i < obj_nr; ++i) {
137  copy_mt_args.cma_ids[i] = copy_mt_params.cup_id;
138  copy_mt_args.cma_ids[i].u_lo = copy_mt_params.cup_id.u_lo + i;
139  }
140 
141  /* launch one thread per object */
142  for (i = 0; i < obj_nr; ++i)
143  M0_THREAD_INIT(&copy_th[i], struct m0_copy_mt_args *,
144  NULL, &copy_thread_launch, &copy_mt_args,
145  "Writer");
146 
147  for (i = 0; i < obj_nr; ++i) {
148  m0_thread_join(&copy_th[i]);
149  m0_thread_fini(&copy_th[i]);
150  if (copy_mt_args.cma_rc[i] != 0) {
151  if (copy_mt_args.cma_rc[i] == -EEXIST) {
152  fprintf(stderr, "Object exists for Id: " U128X_F
153  ". To update an existing "
154  "object use -u=start index! "
155  "rc = %d\n",
156  U128_P(&copy_mt_args.
157  cma_ids[i]),
158  copy_mt_args.cma_rc[i]);
159  rc = -EEXIST;
160  } else {
161  fprintf(stderr, "copy failed for "
162  "object Id: " U128X_F
163  " rc = %d\n",
164  U128_P(&copy_mt_args.
165  cma_ids[i]),
166  copy_mt_args.cma_rc[i]);
167  /*
168  * If any write fails, m0cp_mt operation is
169  * considered as unsuccessful.
170  */
171  rc = -EIO;
172  }
173  }
174  }
175 
176  /* Clean-up */
177  m0_mutex_fini(&copy_mt_args.cma_mutex);
179  m0_free(copy_mt_args.cma_rc);
180  m0_free(copy_mt_args.cma_ids);
181  m0_free(copy_th);
182  return M0_RC(rc);
183 }
184 
185 /*
186  * Local variables:
187  * c-indentation-style: "K&R"
188  * c-basic-offset: 8
189  * tab-width: 8
190  * fill-column: 80
191  * scroll-step: 1
192  * End:
193  */
int optind
#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
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
struct m0_file file
Definition: di.c:36
static struct m0_container container
Definition: copy_mt.c:34
int m0_write(struct m0_container *container, char *src, struct m0_uint128 id, uint32_t block_size, uint32_t block_count, uint64_t update_offset, int blks_per_io, bool take_locks, bool update_mode)
Definition: helper.c:352
static void copy_mt_usage(FILE *file, char *prog_name)
Definition: copy_mt.c:59
Definition: conf.py:1
M0_INTERNAL void client_init(struct sim *s, struct client_conf *conf)
Definition: client.c:148
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
struct m0_utility_param * cma_utility
Definition: helper.h:80
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
Definition: ub.c:49
return M0_RC(rc)
int i
Definition: dir.c:1033
int main(int argc, char **argv)
Definition: copy_mt.c:95
int m0_utility_args_init(int argc, char **argv, struct m0_utility_param *params, struct m0_idx_dix_config *dix_conf, struct m0_config *conf, void(*utility_usage)(FILE *, char *))
Definition: helper.c:915
#define U128_P(x)
Definition: types.h:45
struct m0_mutex cma_mutex
Definition: helper.h:82
void m0_thread_fini(struct m0_thread *q)
Definition: thread.c:92
struct m0_uint128 * cma_ids
Definition: helper.h:81
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
static struct m0_idx_dix_config dix_conf
Definition: copy_mt.c:36
struct m0_uint128 cup_id
Definition: helper.h:65
#define U128X_F
Definition: types.h:42
int cup_blks_per_io
Definition: helper.h:73
char * cup_file
Definition: helper.h:72
static void copy_thread_launch(struct m0_copy_mt_args *args)
Definition: copy_mt.c:38
int * cma_rc
Definition: helper.h:83
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
Definition: helper.h:53
M0_INTERNAL void client_fini(struct client_conf *conf)
Definition: client.c:177
uint64_t u_lo
Definition: types.h:37
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
int cma_index
Definition: helper.h:84