Motr  M0
client.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 #include <stdlib.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <sys/time.h>
28 #include <getopt.h>
29 #include <libgen.h>
30 
31 #include "lib/string.h"
32 #include "conf/obj.h"
33 #include "fid/fid.h"
34 #include "lib/memory.h"
35 #include "lib/trace.h"
36 #include "motr/client.h"
37 #include "motr/idx.h"
38 #include "motr/st/utils/helper.h"
39 #include "motr/client_internal.h"
40 #include "lib/getopts.h"
41 
42 enum { CMD_SIZE = 128 };
43 
44 /* Client parameters */
45 
46 static struct m0_client *m0_instance = NULL;
47 static struct m0_container container;
48 static struct m0_config conf;
50 
51 extern struct m0_addb_ctx m0_addb_ctx;
52 
53 static void help(void)
54 {
55  m0_console_printf("Help:\n");
56  m0_console_printf("touch OBJ_ID\n");
57  m0_console_printf("write OBJ_ID SRC_FILE BLOCK_SIZE BLOCK_COUNT "
58  "BLOCKS_PER_IO UPDATE_FLAG OFFSET\n");
59  m0_console_printf("read OBJ_ID DEST_FILE BLOCK_SIZE BLOCK_COUNT "
60  "BLOCKS_PER_IO\n");
61  m0_console_printf("delete OBJ_ID\n");
62  m0_console_printf("help\n");
63  m0_console_printf("quit\n");
64 }
65 
66 #define GET_ARG(arg, cmd, saveptr) \
67  arg = strtok_r(cmd, "\n ", saveptr); \
68  if (arg == NULL) { \
69  help(); \
70  continue; \
71  }
72 
73 #define GET_COMMON_ARG(arg, fname, saveptr, id, \
74  block_size, block_count, blocks_per_io) \
75  GET_ARG(arg, NULL, &saveptr); \
76  m0_obj_id_sscanf(arg, &id); \
77  GET_ARG(arg, NULL, &saveptr); \
78  fname = strdup(arg); \
79  GET_ARG(arg, NULL, &saveptr); \
80  block_size = atoi(arg); \
81  GET_ARG(arg, NULL, &saveptr); \
82  block_count = atoi(arg); \
83  GET_ARG(arg, NULL, &saveptr); \
84  blocks_per_io = atoi(arg);
85 
86 static void c0client_usage(FILE *file, char *prog_name)
87 {
88  fprintf(file, "Usage: %s [OPTION]...\n"
89 "Launches Client client.\n"
90 "\n"
91 "Mandatory arguments to long options are mandatory for short options too.\n"
92 " -l, --local ADDR Local endpoint address\n"
93 " -H, --ha ADDR HA endpoint address\n"
94 " -p, --profile FID Profile FID\n"
95 " -P, --process FID Process FID\n"
96 " -L, --layout-id INT Layout ID, range: [1-14]\n"
97 " -e, --enable-locks Enables acquiring and releasing RW locks "
98  "before and after performing IO.\n"
99 " -b --blocks-per-io INT Number of blocks (>=0) per IO. Default=100 "
100  "if 0 or nothing is provided.\n"
101 " -r, --read-verify Verify parity after reading the data\n"
102 " -S, --msg_size INT Max RPC msg size 64k i.e 65536\n"
103  "%*c Note: this should match with m0d's current "
104  "rpc msg size\n"
105 " -q, --min_queue INT Minimum length of the receive queue i.e 16\n"
106 " -h, --help Shows this help text and exit\n"
107 , prog_name, WIDTH, ' ');
108 }
109 
110 int main(int argc, char **argv)
111 {
112  struct m0_utility_param params;
113  struct m0_fid fid;
114  int rc;
115  char *arg;
116  char *saveptr;
117  char *cmd;
118  char *fname = NULL;
119  struct m0_uint128 id = M0_ID_APP;
120  int block_size;
121  int block_count;
122  int blocks_per_io;
123  uint64_t offset;
124  bool update_flag;
125 
126  m0_utility_args_init(argc, argv, &params,
128 
130  if (rc < 0) {
131  fprintf(stderr, "init failed! rc = %d\n", rc);
132  exit(EXIT_FAILURE);
133  }
134 
135  memset(&fid, 0, sizeof fid);
136 
137  cmd = m0_alloc(CMD_SIZE);
138  if (cmd == NULL) {
139  M0_ERR(-ENOMEM);
140  goto cleanup;
141  }
142 
143  do {
144  fflush(stdin);
145  offset = 0;
146  update_flag = false;
147  m0_console_printf("m0client >>");
148  arg = fgets(cmd, CMD_SIZE, stdin);
149  if (arg == NULL)
150  continue;
151  GET_ARG(arg, cmd, &saveptr);
152  if (strcmp(arg, "read") == 0) {
153  GET_COMMON_ARG(arg, fname, saveptr, id,
154  block_size, block_count,
155  blocks_per_io);
156  if (*saveptr != 0) {
157  GET_ARG(arg, NULL, &saveptr);
158  if (m0_bcount_get(arg, &offset) == 0) {
159  if (offset % BLK_SIZE_4k != 0) {
160  continue;
161  }
162  }
163  }
164  if (!entity_id_is_valid(&id))
165  continue;
166  rc = m0_read(&container, id, fname,
167  block_size, block_count, offset,
168  blocks_per_io,
169  params.cup_take_locks,
170  0, NULL);
171  } else if (strcmp(arg, "write") == 0) {
172  GET_COMMON_ARG(arg, fname, saveptr, id,
173  block_size, block_count,
174  blocks_per_io);
175  if (blocks_per_io > M0_MAX_BLOCK_COUNT) {
176  fprintf(stderr, "Blocks per IO (%d) is out of "
177  "range. Max is %d for write "
178  "operation!\n", blocks_per_io,
180  continue;
181  }
182  if (*saveptr != 0) {
183  GET_ARG(arg, NULL, &saveptr);
184  update_flag = atoi(arg) ? true : false;
185  }
186  if (*saveptr != 0) {
187  GET_ARG(arg, NULL, &saveptr);
188  if (m0_bcount_get(arg, &offset) == 0) {
189  if (offset % BLK_SIZE_4k != 0) {
190  continue;
191  }
192  }
193  }
194  if (!entity_id_is_valid(&id))
195  continue;
196  rc = m0_write(&container, fname, id,
197  block_size, block_count, offset,
198  blocks_per_io, params.cup_take_locks,
199  update_flag);
200  } else if (strcmp(arg, "touch") == 0) {
201  GET_ARG(arg, NULL, &saveptr);
202  m0_obj_id_sscanf(arg, &id);
203  if (!entity_id_is_valid(&id))
204  continue;
205  rc = touch(&container, id,
206  params.cup_take_locks);
207  } else if (strcmp(arg, "delete") == 0) {
208  GET_ARG(arg, NULL, &saveptr);
209  m0_obj_id_sscanf(arg, &id);
210  if (!entity_id_is_valid(&id))
211  continue;
212  rc = m0_unlink(&container, id,
213  params.cup_take_locks);
214  } else if (strcmp(arg, "help") == 0)
215  help();
216  else
217  help();
218  if (rc < 0) {
219  fprintf(stderr, "IO failed! rc = %d\n", rc);
220  }
221  } while (arg == NULL || strcmp(arg, "quit") != 0);
222 
223  m0_free(cmd);
224  if (fname != NULL)
225  free(fname);
226 
227 cleanup:
228  /* Clean-up */
230 
231  return 0;
232 }
233 
234 /*
235  * Local variables:
236  * c-indentation-style: "K&R"
237  * c-basic-offset: 8
238  * tab-width: 8
239  * fill-column: 80
240  * scroll-step: 1
241  * End:
242  */
uint64_t id
Definition: cob.h:2380
#define NULL
Definition: misc.h:38
M0_INTERNAL bool entity_id_is_valid(const struct m0_uint128 *id)
Definition: client.c:354
static struct m0_container container
Definition: client.c:47
struct m0_file file
Definition: di.c:36
void m0_console_printf(const char *fmt,...)
Definition: trace.c:801
int m0_obj_id_sscanf(char *idstr, struct m0_uint128 *obj_id)
Definition: helper.c:199
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
Definition: conf.py:1
static void help(void)
Definition: client.c:53
M0_INTERNAL void client_init(struct sim *s, struct client_conf *conf)
Definition: client.c:148
#define GET_ARG(arg, cmd, saveptr)
Definition: client.c:66
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
struct m0_fid fid
Definition: di.c:46
return M0_ERR(-EOPNOTSUPP)
struct m0_addb_ctx m0_addb_ctx
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
int touch(struct m0_container *container, struct m0_uint128 id, bool take_locks)
Definition: helper.c:310
int main(int argc, char **argv)
Definition: client.c:110
void * m0_alloc(size_t size)
Definition: memory.c:126
static void c0client_usage(FILE *file, char *prog_name)
Definition: client.c:86
static m0_bindex_t offset
Definition: dump.c:173
Definition: fid.h:38
M0_INTERNAL int m0_bcount_get(const char *arg, m0_bcount_t *out)
Definition: getopts.c:35
#define GET_COMMON_ARG(arg, fname, saveptr, id, block_size, block_count, blocks_per_io)
Definition: client.c:73
Definition: common.h:34
Definition: helper.h:53
M0_INTERNAL void client_fini(struct client_conf *conf)
Definition: client.c:177
static struct m0_idx_dix_config dix_conf
Definition: client.c:49
int m0_read(struct m0_container *container, struct m0_uint128 id, char *dest, uint32_t block_size, uint32_t block_count, uint64_t offset, int blks_per_io, bool take_locks, uint32_t flags, struct m0_fid *read_pver)
Definition: helper.c:466
int m0_unlink(struct m0_container *container, struct m0_uint128 id, bool take_locks)
Definition: helper.c:683
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47