Motr  M0
pool_trigger.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_POOL
24 #include "lib/trace.h"
25 
26 #include "lib/assert.h"
27 #include "lib/misc.h" /* M0_IN */
28 #include "lib/memory.h"
29 #include "fop/fop.h"
30 #include "net/lnet/lnet.h"
31 #include "rpc/rpc.h"
32 #include "rpc/rpclib.h"
33 #include "lib/getopts.h"
34 #include "motr/init.h"
35 #include "pool/pool.h"
36 #include "pool/pool_fops.h"
37 #include "module/instance.h" /* m0 */
38 
39 static struct m0_net_domain cl_ndom;
40 static struct m0_rpc_client_ctx cl_ctx;
41 static struct m0_fid cl_process_fid = M0_FID_TINIT('r', 0, 1);
42 
43 enum {
45  MAX_DEV_NR = 100,
46  MAX_SERVERS = 1024
47 };
48 
49 static const char *cl_ep_addr;
50 static const char *srv_ep_addr[MAX_SERVERS];
52 static int64_t device_state_arr[MAX_DEV_NR];
53 static int di = 0;
54 static int ds = 0;
55 static uint32_t dev_nr = 0;
56 
57 struct rpc_ctx {
60  const char *ctx_sep;
61 };
62 
63 static int poolmach_client_init(void)
64 {
65  int rc;
66 
68  if (rc != 0)
69  return M0_ERR(rc);
70 
71  cl_ctx.rcx_net_dom = &cl_ndom;
72  cl_ctx.rcx_local_addr = cl_ep_addr;
73  cl_ctx.rcx_remote_addr = srv_ep_addr[0];
74  cl_ctx.rcx_max_rpcs_in_flight = MAX_RPCS_IN_FLIGHT;
75  cl_ctx.rcx_fid = &cl_process_fid;
76 
78  if (rc != 0)
80  return M0_RC(rc);
81 }
82 
83 static void poolmach_client_fini(void)
84 {
85  int rc;
86 
88  if (rc != 0)
89  M0_LOG(M0_DEBUG, "Failed to stop client");
90 
92 }
93 
94 static int poolmach_rpc_ctx_init(struct rpc_ctx *ctx, const char *sep)
95 {
96  ctx->ctx_sep = sep;
97  return m0_rpc_client_find_connect(&ctx->ctx_conn, &ctx->ctx_session,
98  &cl_ctx.rcx_rpc_machine,
99  ctx->ctx_sep, M0_CST_IOS,
102 }
103 
104 static void poolmach_rpc_ctx_fini(struct rpc_ctx *ctx)
105 {
106  int rc;
107 
108  rc = m0_rpc_session_destroy(&ctx->ctx_session, M0_TIME_NEVER);
109  if (rc != 0)
110  M0_LOG(M0_DEBUG, "Failed to destroy session to %s",
111  ctx->ctx_sep);
112  rc = m0_rpc_conn_destroy(&ctx->ctx_conn, M0_TIME_NEVER);
113  if (rc != 0)
114  M0_LOG(M0_DEBUG, "Failed to destroy connection to %s",
115  ctx->ctx_sep);
116 }
117 
119 static struct m0_chan poolmach_wait;
120 static int32_t srv_cnt = 0;
121 
122 extern struct m0_fop_type trigger_fop_fopt;
123 
124 static void print_help(void)
125 {
126  fprintf(stdout,
127 "-O Q(uery) or S(et): Query device state or Set device state\n"
128 "-I device_fid\n"
129 "[-s device_state]: if Set, the device state. The states supported are:\n"
130 " 0: M0_PNDS_ONLINE\n"
131 " 1: M0_PNDS_FAILED\n"
132 " 2: M0_PNDS_OFFLINE\n"
133 "-C Client_end_point\n"
134 "-S Server_end_point [-S Server_end_point ]: max number is %d\n", MAX_SERVERS);
135 }
136 
137 int main(int argc, char *argv[])
138 {
139  static struct m0 instance;
140 
141  struct rpc_ctx *ctxs;
142  const char *op = NULL;
144  m0_time_t delta;
145  int rc;
146  int i;
147  int j;
148 
149  rc = m0_init(&instance);
150  if (rc != 0) {
151  fprintf(stderr, "Cannot init Motr: %d\n", rc);
152  return M0_ERR(rc);
153  }
154  rc = M0_GETOPTS("poolmach", argc, argv,
155  M0_STRINGARG('O',
156  "Q(uery) or S(et)",
157  LAMBDA(void, (const char *str) {
158  op = str;
159  if (!M0_IN(op[0], ('Q', 'q',
160  'S', 's')))
161  rc = -EINVAL;
162  })),
163  M0_FORMATARG('N', "Number of devices", "%u", &dev_nr),
164  M0_STRINGARG('I', "device fid",
165  LAMBDA(void, (const char *str)
166  {
167  m0_fid_sscanf(str,
168  &device_fid_arr[di]);
169  M0_CNT_INC(di);
170  M0_ASSERT(di <= MAX_DEV_NR);
171  })),
172  M0_NUMBERARG('s', "device state",
173  LAMBDA(void, (int64_t device_state)
174  {
176  device_state;
177  M0_CNT_INC(ds);
178  M0_ASSERT(di <= MAX_DEV_NR);
179  })),
180  M0_STRINGARG('C', "Client endpoint",
181  LAMBDA(void, (const char *str) {
182  cl_ep_addr = str;
183  })),
184  M0_STRINGARG('S', "Server endpoint",
185  LAMBDA(void, (const char *str) {
186  srv_ep_addr[srv_cnt] = str;
187  ++srv_cnt;
189  })),
190  );
191  if (rc != 0) {
192  print_help();
193  return M0_ERR(rc);
194  }
195 
196  if (op == NULL || dev_nr == 0 ||
197  dev_nr > MAX_DEV_NR || cl_ep_addr == NULL || srv_cnt == 0 ||
198  di != dev_nr || ((op[0] == 'S'||op[0] == 's') && ds!=dev_nr)
199  ) {
200  print_help();
201  fprintf(stderr, "Insane arguments: op=%s cl_ep=%s "
202  "dev_nr=%d di=%d ds=%d srv_cnt=%d\n",
204  return M0_ERR(-EINVAL);
205  }
206 
207  for (i = 0; i < dev_nr; ++i) {
210  fprintf(stderr, "invalid device state: %lld\n",
211  (long long)device_state_arr[i]);
212  return M0_ERR(-EINVAL);
213  }
214  }
215 
217  if (rc != 0) {
218  fprintf(stderr, "Cannot init client: %d\n", rc);
219  return M0_ERR(rc);
220  }
221 
224 
225  M0_ALLOC_ARR(ctxs, srv_cnt);
226  if (ctxs == NULL) {
227  fprintf(stderr, "Not enough memory. srv count = %d\n", srv_cnt);
228  return M0_ERR(-ENOMEM);
229  }
230 
231  for (i = 1; i < srv_cnt; ++i) {
232  /* connection to srv_ep_addr[0] is establish in
233  * poolmach_client_init() already */
234  rc = poolmach_rpc_ctx_init(&ctxs[i], srv_ep_addr[i]);
235  if (rc != 0) {
236  fprintf(stderr, "Cannot init rpc ctx = %d\n", rc);
237  return M0_ERR(rc);
238  }
239  }
240 
243  start = m0_time_now();
244  for (i = 0; i < srv_cnt; ++i) {
245  struct m0_fop *req;
246  struct m0_rpc_session *session;
247 
248  session = i == 0 ? &cl_ctx.rcx_session : &ctxs[i].ctx_session;
249 
250  if (op[0] == 'Q' || op[0] == 'q') {
251  struct m0_fop_poolmach_query *query_fop;
252 
255  if (req == NULL) {
256  fprintf(stderr, "Not enough memory for fop\n");
257  return M0_ERR(-ENOMEM);
258  }
259 
260  query_fop = m0_fop_data(req);
261  query_fop->fpq_type = M0_POOL_DEVICE;
262  M0_ALLOC_ARR(query_fop->fpq_dev_idx.fpx_fid, dev_nr);
263  query_fop->fpq_dev_idx.fpx_nr = dev_nr;
264  for (j = 0; j < dev_nr; ++j)
265  query_fop->fpq_dev_idx.fpx_fid[j] =
266  device_fid_arr[j];
267  } else {
268  struct m0_fop_poolmach_set *set_fop;
269 
272  if (req == NULL) {
273  fprintf(stderr, "Not enough memory for fop\n");
274  return M0_ERR(-ENOMEM);
275  }
276 
277  set_fop = m0_fop_data(req);
278  set_fop->fps_type = M0_POOL_DEVICE;
280  set_fop->fps_dev_info.fpi_nr = dev_nr;
281  for (j = 0; j < dev_nr; ++j) {
282  set_fop->fps_dev_info.fpi_dev[j].fpd_fid =
283  device_fid_arr[j];
284  set_fop->fps_dev_info.fpi_dev[j].fpd_state =
285  device_state_arr[j];
286  }
287  }
288 
289  fprintf(stderr, "sending/posting to %s\n", srv_ep_addr[i]);
291  if (rc != 0) {
293  return M0_ERR(rc);
294  }
295  if (op[0] == 'Q' || op[0] == 'q') {
296  struct m0_fop_poolmach_query_rep *query_fop_rep;
297  struct m0_fop *rep;
298  int i;
299 
300  rep = m0_rpc_item_to_fop(req->f_item.ri_reply);
301  query_fop_rep = m0_fop_data(rep);
302  for (i = 0; i < dev_nr; ++i) {
303  fprintf(stderr,
304  "Query: fid = "FID_F" state= %d rc = %d\n",
305  FID_P(&query_fop_rep->fqr_dev_info.
306  fpi_dev[i].fpd_fid),
307  (int)query_fop_rep->fqr_dev_info.
309  (int)query_fop_rep->fqr_rc);
310  }
311  } else {
312  struct m0_fop_poolmach_set_rep *set_fop_rep;
313  struct m0_fop *rep;
314  rep = m0_rpc_item_to_fop(req->f_item.ri_reply);
315  set_fop_rep = m0_fop_data(rep);
316  fprintf(stderr, "Set got reply: rc = %d\n",
317  (int)set_fop_rep->fps_rc);
318  }
320  if (rc != 0)
321  return M0_ERR(rc);
322  }
323  delta = m0_time_sub(m0_time_now(), start);
324  printf("Time: %lu.%2.2lu sec\n", (unsigned long)m0_time_seconds(delta),
325  (unsigned long)m0_time_nanoseconds(delta) * 100 /
327  for (i = 1; i < srv_cnt; ++i)
328  poolmach_rpc_ctx_fini(&ctxs[i]);
330  m0_fini();
331 
332  return M0_RC(rc);
333 }
334 
335 #undef M0_TRACE_SUBSYSTEM
336 
337 /*
338  * Local variables:
339  * c-indentation-style: "K&R"
340  * c-basic-offset: 8
341  * tab-width: 8
342  * fill-column: 80
343  * scroll-step: 1
344  * End:
345  */
#define M0_GETOPTS(progname, argc, argv,...)
Definition: getopts.h:169
struct m0_fop_poolmach_dev_idx fpq_dev_idx
Definition: pool_fops.h:72
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
static int poolmach_client_init(void)
Definition: pool_trigger.c:63
#define NULL
Definition: misc.h:38
void m0_fini(void)
Definition: init.c:318
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static struct io_request req
Definition: file.c:100
static struct m0_mutex poolmach_wait_mutex
Definition: pool_trigger.c:118
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
struct m0_fop_poolmach_dev * fpi_dev
Definition: pool_fops.h:41
M0_INTERNAL int m0_rpc_client_find_connect(struct m0_rpc_conn *conn, struct m0_rpc_session *session, struct m0_rpc_machine *rpc_mach, const char *remote_addr, enum m0_conf_service_type stype, uint64_t max_rpcs_in_flight, m0_time_t abs_timeout)
Definition: rpclib.c:134
uint64_t m0_time_nanoseconds(const m0_time_t time)
Definition: time.c:89
struct m0_fid fpd_fid
Definition: pool_fops.h:52
int m0_rpc_session_destroy(struct m0_rpc_session *session, m0_time_t abs_timeout)
Definition: session.c:559
static int32_t srv_cnt
Definition: pool_trigger.c:120
struct m0_fop_poolmach_dev * fpi_dev
Definition: pool_fops.h:47
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
static struct m0_chan poolmach_wait
Definition: pool_trigger.c:119
static uint32_t dev_nr
Definition: pool_trigger.c:55
static int di
Definition: pool_trigger.c:53
int m0_init(struct m0 *instance)
Definition: init.c:310
static struct m0_rpc_session session
Definition: formation2.c:38
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
static struct m0_fid device_fid_arr[MAX_DEV_NR]
Definition: pool_trigger.c:51
struct m0_fop_getxattr_rep * rep
Definition: dir.c:455
uint32_t fps_type
Definition: pool_fops.h:56
uint32_t fpd_state
Definition: pool_fops.h:51
static const char * cl_ep_addr
Definition: pool_trigger.c:49
#define M0_NUMBERARG(ch, desc, func)
Definition: getopts.h:187
return M0_RC(rc)
op
Definition: libdemo.c:64
#define M0_STRINGARG(ch, desc, func)
Definition: getopts.h:207
int i
Definition: dir.c:1033
return M0_ERR(-EOPNOTSUPP)
static void print_help(void)
Definition: pool_trigger.c:124
#define LAMBDA(T,...)
Definition: thread.h:153
struct m0_fop_type m0_fop_poolmach_set_fopt
Definition: pool_fops.c:39
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define M0_FORMATARG(ch, desc, fmt, ptr)
Definition: getopts.h:218
int main(int argc, char *argv[])
Definition: pool_trigger.c:137
M0_INTERNAL void m0_chan_init(struct m0_chan *chan, struct m0_mutex *ch_guard)
Definition: chan.c:96
#define M0_ASSERT(cond)
static int poolmach_rpc_ctx_init(struct rpc_ctx *ctx, const char *sep)
Definition: pool_trigger.c:94
m0_time_t m0_time_now(void)
Definition: time.c:134
struct m0_fop_type m0_fop_poolmach_query_fopt
Definition: pool_fops.c:37
struct m0_fop_poolmach_dev_info fps_dev_info
Definition: pool_fops.h:57
int m0_rpc_conn_destroy(struct m0_rpc_conn *conn, m0_time_t abs_timeout)
Definition: conn.c:974
int m0_rpc_client_stop(struct m0_rpc_client_ctx *cctx)
Definition: rpclib.c:217
Definition: instance.h:80
struct m0_net_xprt * m0_net_xprt_default_get(void)
Definition: net.c:151
int m0_rpc_client_start(struct m0_rpc_client_ctx *cctx)
Definition: rpclib.c:160
struct m0_fop_poolmach_dev_info fqr_dev_info
Definition: pool_fops.h:62
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
struct m0_fop_type trigger_fop_fopt
int m0_rpc_post_sync(struct m0_fop *fop, struct m0_rpc_session *session, const struct m0_rpc_item_ops *ri_ops, m0_time_t deadline)
Definition: rpclib.c:284
struct m0_rpc_session ctx_session
Definition: pool_trigger.c:59
Definition: chan.h:229
M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
Definition: fid.c:227
#define FID_P(f)
Definition: fid.h:77
uint64_t m0_time_seconds(const m0_time_t time)
Definition: time.c:83
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
static struct m0_fid cl_process_fid
Definition: pool_trigger.c:41
#define M0_CNT_INC(cnt)
Definition: arith.h:226
Definition: fid.h:38
struct m0_rpc_conn ctx_conn
Definition: pool_trigger.c:58
static void poolmach_rpc_ctx_fini(struct rpc_ctx *ctx)
Definition: pool_trigger.c:104
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
struct m0_fid * fpx_fid
Definition: pool_fops.h:67
m0_time_t m0_time_sub(const m0_time_t t1, const m0_time_t t2)
Definition: time.c:65
struct m0_fop * m0_fop_alloc_at(struct m0_rpc_session *sess, struct m0_fop_type *fopt)
Definition: fop.c:122
static int start(struct m0_fom *fom)
Definition: trigger_fom.c:321
void m0_fop_put_lock(struct m0_fop *fop)
Definition: fop.c:199
static struct m0 instance
Definition: main.c:78
struct m0_fop * m0_rpc_item_to_fop(const struct m0_rpc_item *item)
Definition: fop.c:346
Definition: nucleus.c:42
const char * ctx_sep
Definition: pool_trigger.c:60
Definition: mutex.h:47
static int ds
Definition: pool_trigger.c:54
int32_t rc
Definition: trigger_fop.h:47
static void poolmach_client_fini(void)
Definition: pool_trigger.c:83
static const char * srv_ep_addr[MAX_SERVERS]
Definition: pool_trigger.c:50
Definition: fop.h:79
#define FID_F
Definition: fid.h:75
static struct m0_net_domain cl_ndom
Definition: pool_trigger.c:39
static int64_t device_state_arr[MAX_DEV_NR]
Definition: pool_trigger.c:52