Motr  M0
ham.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-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 
43 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_HA
44 #include "lib/trace.h"
45 
46 #include "module/instance.h" /* m0 */
47 #include "motr/init.h" /* m0_init */
48 #include "net/net.h" /* m0_net_domain */
49 #include "net/buffer_pool.h" /* m0_net_buffer_pool */
50 #include "reqh/reqh.h" /* m0_reqh */
51 #include "rpc/rpc_machine.h" /* m0_rpc_machine */
52 #include "rpc/rpc.h" /* m0_rpc_net_buffer_pool_setup */
53 #include "ha/ha.h" /* m0_ha_cfg */
54 #include "ha/link.h" /* m0_ha_link_wait_delivery */
55 #include "lib/memory.h" /* m0_alloc_aligned */
56 #include "lib/string.h" /* m0_streq */
57 #include <libgen.h> /* basename */
58 #include <getopt.h> /* getopt_long */
59 #include <unistd.h> /* isatty */
60 
61 #define HAM_SERVER_EP_DEFAULT "0@lo:12345:43:100"
62 #define HAM_CLIENT_EP_DEFAULT "0@lo:12345:43:101"
63 #define HAM_SERVER_WAIT_DEFAULT 0
64 
66 
67 enum {
68  HAM_ID = 72 /* = 'H', the constant used in m0ham fids */
69 };
70 
71 static struct ham_params {
73  const char *hp_ep_local;
74  const char *hp_ep_remote; /* connect mode only */
75  bool hp_verbose;
76  unsigned int hp_wait; /* listen mode only */
77  const char *hp_progname;
78 } g_params;
79 
80 static struct m0_semaphore g_sem;
81 static struct m0_ha_msg *g_msg;
82 static struct m0_uint128 g_self_req_id;
83 
84 struct ham_rpc_ctx {
87  struct m0_reqh mrc_reqh;
89 };
90 
120 static void *
121 xcode_read_as(const struct m0_xcode_type *type, const char *str, int *rc)
122 {
123  void *ptr;
124  int _rc;
125 
126  M0_ENTRY("type=%s", type->xct_name);
127  M0_PRE(str != NULL && *str != '\0');
128 
129  if (rc == NULL)
130  rc = &_rc;
131  ptr = m0_alloc(type->xct_sizeof);
132  if (ptr == NULL) {
133  *rc = M0_ERR(-ENOMEM);
134  return NULL;
135  }
136  *rc = m0_xcode_read(&M0_XCODE_OBJ(type, ptr), str);
137  if (*rc != 0) {
138  m0_xcode_free_obj(&M0_XCODE_OBJ(type, ptr)); /* frees `ptr' */
139  ptr = NULL;
140  M0_LOG(M0_ERROR, "Cannot read %s from string (rc=%d):\n%s\n",
141  type->xct_name, *rc, str);
142  }
143  M0_POST(ptr == NULL ? *rc < 0 : *rc == 0);
144  M0_LEAVE("retval=%p", ptr);
145  return ptr;
146 }
147 
149 static bool ha_msg_is_one_way(const struct m0_ha_msg *msg)
150 {
151  switch (msg->hm_data.hed_type) {
152  case M0_HA_MSG_NVEC:
153  return msg->hm_data.u.hed_nvec.hmnv_type == M0_HA_NVEC_SET;
154  /* XXX FUTURE: Add support for other types. */
155  default:
156  return true;
157  }
158 }
159 
160 static void ham_say(const char *format, ...)
161 {
162  if (g_params.hp_verbose) {
163  va_list ap;
164 
165  va_start(ap, format);
166  fprintf(stderr, "%s: ", g_params.hp_progname);
167  vfprintf(stderr, format, ap);
168  fputs(".\n", stderr);
169  va_end(ap);
170  }
171 }
172 
173 /*
174  * XXX TODO: Define generic m0_xcode_obj_to_str().
175  * Use it in ham_xcode_print() and m0_confx_to_string() implementations.
176  */
177 static void ham_xcode_print(const struct m0_xcode_obj *x)
178 {
180  char *buf;
181  int rc;
182 
183  size = m0_xcode_print(x, NULL, 0) + 1;
184  M0_ASSERT(size > 0);
185  buf = m0_alloc(size);
186  if (buf == NULL) {
187  M0_LOG(M0_ERROR, "Memory allocation failed");
188  return;
189  }
190  rc = m0_xcode_print(x, buf, size);
191  if (rc < 0 || rc > size)
192  M0_LOG(M0_ERROR, "m0_xcode_print() failed: rc=%d size=%"PRIu64,
193  rc, size);
194  puts(buf);
195  m0_free(buf);
196 }
197 
201 static int ham_fread_str(char *dest, size_t size, FILE *src)
202 {
203  size_t n;
204 
205  if (isatty(fileno(src)))
206  /*
207  * Don't let fread() block.
208  * XXX FUTURE: We may want to use select(), like ncat does.
209  */
210  return 0;
211  M0_PRE(size > 1);
212  n = fread(dest, 1, size-1, src);
213  if (!feof(src)) {
214  if (ferror(src))
215  return M0_ERR_INFO(-EIO, "IO error");
216  M0_ASSERT(n == size-1);
217  return M0_ERR_INFO(-E2BIG, "Input file is too big"
218  " (> %lu bytes)", (unsigned long)size-1);
219  }
220  dest[n] = '\0';
221  return n;
222 }
223 
224 /*
225  * XXX Code duplication!
226  * This function duplicates the code of m0_ut_rpc_machine_start() and
227  * m0_ha_ut_rpc_ctx_init().
228  */
229 static void ham_rpc_ctx_init(struct ham_rpc_ctx *ctx,
230  const char *local_endpoint,
231  const struct m0_fid *local_process)
232 {
233  enum { NR_TMS = 1 };
234  int rc;
235 
236  M0_PRE(local_endpoint != NULL && *local_endpoint != '\0');
237  M0_PRE(m0_conf_fid_type(local_process) == &M0_CONF_PROCESS_TYPE);
238 
239  rc = m0_net_domain_init(&ctx->mrc_net_dom, m0_net_xprt_default_get());
240  M0_ASSERT(rc == 0);
242  &ctx->mrc_net_dom,
243  &ctx->mrc_buf_pool,
245  NR_TMS);
246  M0_ASSERT(rc == 0);
247  rc = M0_REQH_INIT(&ctx->mrc_reqh,
248  .rhia_dtm = (void *)1,
249  .rhia_mdstore = (void *)1,
250  .rhia_fid = local_process);
251  M0_ASSERT(rc == 0);
252  m0_reqh_start(&ctx->mrc_reqh);
253  rc = m0_rpc_machine_init(&ctx->mrc_rpc_mach, &ctx->mrc_net_dom,
254  local_endpoint, &ctx->mrc_reqh,
255  &ctx->mrc_buf_pool, M0_BUFFER_ANY_COLOUR,
258  M0_ASSERT(rc == 0);
259 }
260 
261 /*
262  * XXX Code duplication!
263  * This function duplicates the code of m0_ut_rpc_machine_stop() and
264  * m0_ha_ut_rpc_ctx_fini().
265  */
266 static void ham_rpc_ctx_fini(struct ham_rpc_ctx *ctx)
267 {
268  m0_reqh_shutdown_wait(&ctx->mrc_reqh);
269  m0_rpc_machine_fini(&ctx->mrc_rpc_mach);
270  m0_reqh_services_terminate(&ctx->mrc_reqh);
271  m0_reqh_fini(&ctx->mrc_reqh);
272  m0_rpc_net_buffer_pool_cleanup(&ctx->mrc_buf_pool);
273  m0_net_domain_fini(&ctx->mrc_net_dom);
274 }
275 
276 static const struct m0_ha_msg ham_self_check_msg_default = {
277  .hm_data = { // m0_ha_msg_data
279  .u.hed_nvec = { // m0_ha_msg_nvec
280  .hmnv_type = M0_HA_NVEC_SET,
281  .hmnv_id_of_get = 0,
282  .hmnv_ignore_same_state = false,
283  .hmnv_nr = 1,
284  .hmnv_arr = { // m0_ha_msg_nvec_array
285  .hmna_arr = {
286  { // m0_ha_note
287  .no_id = M0_FID_TINIT(
288  'c', 1, 1),
289  .no_state = M0_NC_FAILED
290  }
291  }
292  }
293  }
294  }
295 };
296 
297 static void
298 ham_send(struct m0_ha *ha, struct m0_ha_link *hl, const struct m0_ha_msg *msg)
299 {
300  uint64_t tag;
301 
302  if (g_params.hp_mode == HM_SELF_CHECK && msg == NULL)
304  if (msg != NULL) {
305  m0_ha_send(ha, hl, msg, &tag);
306  ham_say("Sent message #%"PRIu64, tag);
307  }
308 }
309 
310 /*
311  * ---------------------------------------------------------------------
312  * m0_ha_ops
313  */
314 
319 static void ham_entrypoint_request(struct m0_ha *ha,
320  const struct m0_ha_entrypoint_req *req,
321  const struct m0_uint128 *req_id)
322 {
323  struct m0_ha_link *hl;
324  struct m0_ha_entrypoint_rep rep = {
325  .hae_quorum = 1,
326  .hae_confd_fids = {},
327  .hae_confd_eps = NULL,
328  .hae_active_rm_fid = M0_FID_TINIT('s', HAM_ID, 1),
329  .hae_active_rm_ep = NULL,
330  .hae_control = M0_HA_ENTRYPOINT_CONSUME,
331  };
332 
333  ham_say("Got entrypoint request. Replying");
334  if (m0_streq(g_params.hp_ep_local, req->heq_rpc_endpoint)) {
336  g_self_req_id = *req_id;
337  }
338  m0_ha_entrypoint_reply(ha, req_id, &rep, &hl);
339 }
340 
345 static void
347 {
348  ham_say("Got entrypoint reply");
349  /* XXX TODO: Show entrypoint fields: quorum, confds, rm. */
350 }
351 
352 static void ham_msg_received(struct m0_ha *ha, struct m0_ha_link *hl,
353  struct m0_ha_msg *msg, uint64_t tag)
354 {
355  ham_say("Got message #%"PRIu64, tag);
357  ham_xcode_print(&M0_XCODE_OBJ(m0_ha_msg_xc, msg));
358  m0_ha_delivered(ha, hl, msg);
360 }
361 
362 static void
363 ham_msg_is_delivered(struct m0_ha *ha, struct m0_ha_link *hl, uint64_t tag)
364 {
365  ham_say("Message #%" PRIu64 " is delivered", tag);
366 }
367 
368 static void
369 ham_msg_is_not_delivered(struct m0_ha *ha, struct m0_ha_link *hl, uint64_t tag)
370 {
371  ham_say("Message #%" PRIu64 " is NOT delivered", tag);
372 }
373 
375 static void ham_link_connected(struct m0_ha *ha,
376  const struct m0_uint128 *req_id,
377  struct m0_ha_link *hl)
378 {
379  ham_say("Connection established");
381  if (!m0_uint128_eq(req_id, &g_self_req_id))
382  ham_send(ha, hl, g_msg);
383 }
384 
385 static void ham_link_reused(struct m0_ha *ha, const struct m0_uint128 *req_id,
386  struct m0_ha_link *hl)
387 {
388  M0_IMPOSSIBLE("XXX Not implemented");
389 }
390 
391 static void ham_link_absent(struct m0_ha *ha, const struct m0_uint128 *req_id)
392 {
393  M0_IMPOSSIBLE("XXX Not implemented");
394 }
395 
396 static void ham_link_is_disconnecting(struct m0_ha *ha, struct m0_ha_link *hl)
397 {
399 }
400 
401 static void ham_link_disconnected(struct m0_ha *ha, struct m0_ha_link *hl)
402 {
403  ham_say("Disconnected");
404 #if 1
405  /*
406  * .hao_link_disconnected is called from m0_ha_stop() only.
407  * XXX @max plans to fix this; see
408  * https://seagate.slack.com/archives/motr-kiev/p1475484199001743
409  *
410  * For now, if none of the parties sends m0_ha_msg, the only way
411  * to stop a listening process is to kill it with a signal.
412  */
413 #else /* XXX RESTOREME */
414  if (g_params.hp_mode == HM_LISTEN)
416 #endif
417 }
418 
419 static const struct m0_ha_ops ham_ha_ops = {
421  .hao_entrypoint_replied = ham_entrypoint_replied,
422  .hao_msg_received = ham_msg_received,
423  .hao_msg_is_delivered = ham_msg_is_delivered,
424  .hao_msg_is_not_delivered = ham_msg_is_not_delivered,
425  .hao_link_connected = ham_link_connected,
426  .hao_link_reused = ham_link_reused,
427  .hao_link_absent = ham_link_absent,
428  .hao_link_is_disconnecting = ham_link_is_disconnecting,
429  .hao_link_disconnected = ham_link_disconnected
430 };
431 
432 /*
433  * ---------------------------------------------------------------------
434  * signal handling
435  */
436 
437 static void ham_sighandler(int signum)
438 {
439  ham_say("Interrupted by signal %d", signum);
441  /* Restore default handlers. */
442  signal(SIGINT, SIG_DFL);
443  signal(SIGTERM, SIG_DFL);
444 }
445 
446 static int ham_sighandler_init(void)
447 {
448  struct sigaction sa = { .sa_handler = ham_sighandler };
449  int rc;
450 
451  sigemptyset(&sa.sa_mask);
452  /* Block these signals while the handler runs. */
453  sigaddset(&sa.sa_mask, SIGINT);
454  sigaddset(&sa.sa_mask, SIGTERM);
455 
456  rc = sigaction(SIGINT, &sa, NULL) ?: sigaction(SIGTERM, &sa, NULL);
457  return rc == 0 ? 0 : M0_ERR(errno);
458 }
459 
460 /*
461  * ---------------------------------------------------------------------
462  * CLI arguments
463  */
464 
465 static int ham_params_check(struct ham_params *params);
466 
467 static void ham_help(FILE *stream, char *progname)
468 {
469  fprintf(stream,
470 "Usage: %s [option] [endpoint]\n"
471 "Send/receive data over HA link.\n"
472 "\n"
473 " -h, --help Display this help screen\n"
474 " -l, --listen Listen for incoming connections\n"
475 " -s, --source addr Specify source address to use (doesn't affect -l);\n"
476 " defaults to "HAM_CLIENT_EP_DEFAULT"\n"
477 " -w, --wait time Wait in seconds before finishing listening mode\n"
478 " Default is zero second\n"
479 " -v, --verbose Explain what is being done\n",
480  /*
481  * `--self-check' is intentionally left undocumented.
482  * XXX Do we need self-check mode at all?
483  */
484  basename(progname));
485 }
486 
492 static int
493 ham_args_parse(struct ham_params *params, int argc, char *const *argv)
494 {
495  /*
496  * XXX FUTURE: We may want to add
497  * -k, --keep-open (Accept multiple connections)
498  * options in the future; see ncat(1).
499  */
500  const struct option opts[] = {
501  { "self-check", no_argument, NULL, 'c' },
502  { "help", no_argument, NULL, 'h' },
503  { "listen", no_argument, NULL, 'l' },
504  { "source", required_argument, NULL, 's' },
505  { "wait", required_argument, NULL, 'w' },
506  { "verbose", no_argument, NULL, 'v' },
507  {} /* terminator */
508  };
509  int c;
510 
511  *params = (struct ham_params){
512  .hp_mode = HM_CONNECT,
513  .hp_ep_local = NULL,
514  .hp_ep_remote = NULL,
515  .hp_verbose = false,
516  .hp_wait = HAM_SERVER_WAIT_DEFAULT,
517  .hp_progname = basename(argv[0])
518  };
519  while ((c = getopt_long(argc, argv, "hls:w:v", opts, NULL)) != -1) {
520  switch (c) {
521  case 'c':
522  params->hp_mode = HM_SELF_CHECK;
523  break;
524  case 'h':
525  ham_help(stdout, argv[0]);
526  return 1;
527  case 'l':
528  params->hp_mode = HM_LISTEN;
529  break;
530  case 's':
531  params->hp_ep_local = optarg;
532  break;
533  case 'v':
534  params->hp_verbose = true;
535  break;
536  case 'w':
537  params->hp_wait = atoi(optarg);
538  break;
539  default:
540  goto err;
541  }
542  }
543  if (params->hp_ep_local != NULL && params->hp_mode != HM_CONNECT) {
544  fprintf(stderr, "`-s' can only be used in connect mode\n");
545  return -EINVAL; /* cannot use M0_ERR() */
546  }
547  if (optind == argc) { /* no arguments */
548  if (params->hp_mode == HM_CONNECT) {
549  fprintf(stderr, "Remote endpoint is missing\n");
550  goto err;
551  }
552  return ham_params_check(params);
553  }
554  if (optind + 1 == argc) { /* one argument */
555  if (params->hp_mode == HM_LISTEN)
556  params->hp_ep_local = argv[optind];
557  else
558  params->hp_ep_remote = argv[optind];
559  return ham_params_check(params);
560  }
561  fprintf(stderr, "Too many arguments\n");
562 err:
563  fprintf(stderr, "Type `%s --help' for usage\n", basename(argv[0]));
564  return -EINVAL; /* cannot use M0_ERR() before m0_init() */
565 }
566 
567 static void ham_maybe_set(const char **dest, const char *value)
568 {
569  M0_PRE(value != NULL && *value != '\0');
570  if (*dest == NULL)
571  *dest = value;
572 }
573 
574 static int ham_params_check(struct ham_params *params)
575 {
576  switch (params->hp_mode) {
577  case HM_CONNECT:
579  M0_ASSERT(params->hp_ep_remote != NULL);
580  if (m0_streq(params->hp_ep_local, params->hp_ep_remote)) {
581  fprintf(stderr, "Remote and local endpoints must"
582  " differ\n");
583  return -EINVAL; /* cannot use M0_ERR() */
584  }
585  return 0;
586  case HM_LISTEN:
587  case HM_SELF_CHECK:
589  M0_ASSERT(params->hp_ep_remote == NULL);
590  params->hp_ep_remote = params->hp_ep_local;
591  return 0;
592  default:
593  M0_IMPOSSIBLE("");
594  }
595 }
596 
597 /*
598  * ---------------------------------------------------------------------
599  * main
600  */
601 
602 int main(int argc, char **argv)
603 {
604  enum { BUFSIZE = 2 << 21 /* 4 MB */ };
605  static char buf[BUFSIZE]; /* XXX TODO: expand the buffer dynamically */
606 
607  struct m0 inst = {};
608  struct ham_rpc_ctx rpc_ctx;
609  struct m0_ha ha = {};
610  struct m0_ha_link *hl;
611  struct m0_ha_cfg ha_cfg = {
612  .hcf_ops = ham_ha_ops,
613  .hcf_rpc_machine = &rpc_ctx.mrc_rpc_mach,
614  .hcf_reqh = &rpc_ctx.mrc_reqh,
615  .hcf_addr = NULL,
616  .hcf_process_fid = M0_FID_TINIT('r', HAM_ID, HAM_ID),
617  };
618  int rc;
619 
620  rc = ham_args_parse(&g_params, argc, argv);
621  if (rc < 0)
622  return -rc;
623  if (rc == 1)
624  return 0;
625 
626  rc = m0_semaphore_init(&g_sem, 0);
627  if (rc != 0)
628  return M0_ERR(errno);
629  rc = ham_sighandler_init() ?: m0_init(&inst);
630  if (rc != 0)
631  goto sem_fini;
632 
633  rc = ham_fread_str(buf, sizeof buf, stdin);
634  if (rc > 0) {
635  g_msg = xcode_read_as(m0_ha_msg_xc, buf, &rc);
636  if (g_msg == NULL) {
637  M0_ASSERT(rc < 0);
638  goto m0_fini;
639  }
640  g_msg->hm_tag = 0; /* Let `ha' layer set this value. */
641  }
642  if (rc < 0)
643  goto m0_fini;
644 
645  ha_cfg.hcf_addr = g_params.hp_ep_remote;
646  ha_cfg.hcf_process_fid =
649  &ha_cfg.hcf_process_fid);
650  rc = m0_ha_init(&ha, &ha_cfg);
651  if (rc != 0)
652  goto rpc_fini;
653  rc = m0_ha_start(&ha);
654  if (rc != 0)
655  goto ha_fini;
656  if (g_params.hp_mode == HM_CONNECT)
657  ham_say("Connecting to %s", g_params.hp_ep_remote);
658  hl = m0_ha_connect(&ha);
659  if (hl == NULL) {
660  rc = M0_ERR(1);
661  goto ha_stop;
662  }
663  M0_ASSERT(hl == ha.h_link);
664 
665  if (g_params.hp_mode == HM_LISTEN) {
666  ham_say("Listening at %s", g_params.hp_ep_local);
669  } else {
670  ham_send(&ha, hl, g_msg);
671  }
672  if (g_params.hp_mode == HM_CONNECT && g_msg != NULL &&
674  ham_say("Awaiting reply");
677  }
678  if (g_params.hp_mode == HM_LISTEN && g_params.hp_wait > 0) {
680  }
681  ham_say("Finishing");
682  m0_ha_flush(&ha, hl);
683  m0_ha_disconnect(&ha);
684 ha_stop:
685  m0_ha_stop(&ha);
686 ha_fini:
687  m0_ha_fini(&ha);
688 rpc_fini:
690  m0_xcode_free_obj(&M0_XCODE_OBJ(m0_ha_msg_xc, g_msg));
691 m0_fini:
692  m0_fini();
693 sem_fini:
695  return M0_RC(rc < 0 ? -rc : rc);
696 }
697 
698 #undef M0_TRACE_SUBSYSTEM
699 
uint64_t hed_type
Definition: msg.h:88
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:440
M0_INTERNAL int m0_xcode_print(const struct m0_xcode_obj *obj, char *str, int nr)
Definition: string.c:278
static void ham_help(FILE *stream, char *progname)
Definition: ham.c:467
int optind
#define M0_PRE(cond)
void m0_rpc_machine_fini(struct m0_rpc_machine *machine)
Definition: rpc_machine.c:233
struct m0_net_domain mrc_net_dom
Definition: ham.c:85
static void rpc_fini(struct m0_client *m0c)
Definition: client_init.c:509
M0_INTERNAL void m0_reqh_services_terminate(struct m0_reqh *reqh)
Definition: reqh.c:675
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
static void ham_sighandler(int signum)
Definition: ham.c:437
#define NULL
Definition: misc.h:38
M0_INTERNAL struct m0_ha_link * m0_ha_connect(struct m0_ha *ha)
Definition: ha.c:687
static const struct m0_ha_msg ham_self_check_msg_default
Definition: ham.c:276
M0_INTERNAL void m0_ha_fini(struct m0_ha *ha)
Definition: ha.c:679
void m0_fini(void)
Definition: init.c:318
static void ham_msg_is_delivered(struct m0_ha *ha, struct m0_ha_link *hl, uint64_t tag)
Definition: ham.c:363
static bool x
Definition: sm.c:168
#define M0_REQH_INIT(reqh,...)
Definition: reqh.h:262
static struct io_request req
Definition: file.c:100
M0_INTERNAL bool m0_uint128_eq(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:39
static uint64_t tag(uint8_t code, uint64_t id)
Definition: addb2.c:1047
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
const struct m0_conf_obj_type * m0_conf_fid_type(const struct m0_fid *fid)
Definition: obj.c:368
M0_INTERNAL int m0_xcode_read(struct m0_xcode_obj *obj, const char *str)
Definition: string.c:162
M0_INTERNAL int m0_ha_start(struct m0_ha *ha)
Definition: ha.c:659
ham_mode
Definition: ham.c:65
static struct m0_semaphore g_sem
Definition: ham.c:80
static struct m0_uint128 g_self_req_id
Definition: ham.c:82
const char * hp_ep_local
Definition: ham.c:73
M0_INTERNAL void m0_ha_send(struct m0_ha *ha, struct m0_ha_link *hl, const struct m0_ha_msg *msg, uint64_t *tag)
Definition: ha.c:862
int const char const void * value
Definition: dir.c:325
struct m0_ha_msg_data hm_data
Definition: msg.h:122
static struct m0_ha_msg * g_msg
Definition: ham.c:81
M0_INTERNAL void m0_xcode_free_obj(struct m0_xcode_obj *obj)
Definition: xcode.c:248
char * optarg
uint64_t m0_bcount_t
Definition: types.h:77
struct m0_ha_ops hcf_ops
Definition: ha.h:273
static int void * buf
Definition: dir.c:1019
int m0_init(struct m0 *instance)
Definition: init.c:310
static void ham_link_reused(struct m0_ha *ha, const struct m0_uint128 *req_id, struct m0_ha_link *hl)
Definition: ham.c:385
M0_INTERNAL void m0_reqh_fini(struct m0_reqh *reqh)
Definition: reqh.c:320
m0_time_t m0_time(uint64_t secs, long ns)
Definition: time.c:41
struct m0_fop_getxattr_rep * rep
Definition: dir.c:455
Definition: sock.c:887
void(* hao_entrypoint_request)(struct m0_ha *ha, const struct m0_ha_entrypoint_req *req, const struct m0_uint128 *req_id)
Definition: ha.h:241
M0_INTERNAL void m0_reqh_shutdown_wait(struct m0_reqh *reqh)
Definition: reqh.c:647
return M0_RC(rc)
const char * hp_progname
Definition: ham.c:77
M0_INTERNAL void m0_ha_disconnect(struct m0_ha *ha)
Definition: ha.c:707
#define M0_ENTRY(...)
Definition: trace.h:170
#define PRIu64
Definition: types.h:58
static void * xcode_read_as(const struct m0_xcode_type *type, const char *str, int *rc)
Definition: ham.c:121
static void ham_msg_received(struct m0_ha *ha, struct m0_ha_link *hl, struct m0_ha_msg *msg, uint64_t tag)
Definition: ham.c:352
static void ham_link_connected(struct m0_ha *ha, const struct m0_uint128 *req_id, struct m0_ha_link *hl)
Definition: ham.c:375
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_ha_flush(struct m0_ha *ha, struct m0_ha_link *hl)
Definition: ha.c:966
M0_INTERNAL unsigned m0_semaphore_value(struct m0_semaphore *semaphore)
Definition: semaphore.c:70
M0_INTERNAL void m0_ha_stop(struct m0_ha *ha)
Definition: ha.c:672
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
M0_INTERNAL void m0_ha_delivered(struct m0_ha *ha, struct m0_ha_link *hl, struct m0_ha_msg *msg)
Definition: ha.c:870
struct m0_ha_link * h_link
Definition: ha.h:298
#define M0_ASSERT(cond)
Definition: ham.c:71
static void ham_rpc_ctx_init(struct ham_rpc_ctx *ctx, const char *local_endpoint, const struct m0_fid *local_process)
Definition: ham.c:229
static struct m0_addb2_callback c
Definition: consumer.c:41
M0_INTERNAL int m0_rpc_net_buffer_pool_setup(struct m0_net_domain *ndom, struct m0_net_buffer_pool *app_pool, uint32_t bufs_nr, uint32_t tm_nr)
Definition: rpc.c:229
#define m0_streq(a, b)
Definition: string.h:34
M0_INTERNAL uint32_t m0_rpc_bufs_nr(uint32_t len, uint32_t tms_nr)
Definition: rpc.c:271
uint64_t hm_tag
Definition: msg.h:125
static void ham_xcode_print(const struct m0_xcode_obj *x)
Definition: ham.c:177
Definition: instance.h:80
const char * hcf_addr
Definition: ha.h:277
M0_INTERNAL int m0_rpc_machine_init(struct m0_rpc_machine *machine, struct m0_net_domain *net_dom, const char *ep_addr, struct m0_reqh *reqh, struct m0_net_buffer_pool *receive_pool, uint32_t colour, m0_bcount_t msg_size, uint32_t queue_len)
Definition: rpc_machine.c:123
struct m0_net_xprt * m0_net_xprt_default_get(void)
Definition: net.c:151
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
void * m0_alloc(size_t size)
Definition: memory.c:126
static const char * progname
Definition: traced.c:65
#define HAM_SERVER_EP_DEFAULT
Definition: ham.c:61
Definition: msg.h:115
#define M0_POST(cond)
static void ham_msg_is_not_delivered(struct m0_ha *ha, struct m0_ha_link *hl, uint64_t tag)
Definition: ham.c:369
Definition: reqh.h:94
unsigned int hp_wait
Definition: ham.c:76
static void ha_fini(struct m0_client *m0c)
Definition: client_init.c:751
static int ham_fread_str(char *dest, size_t size, FILE *src)
Definition: ham.c:201
struct m0_rpc_machine mrc_rpc_mach
Definition: ham.c:88
static int ham_params_check(struct ham_params *params)
Definition: ham.c:574
static int ham_args_parse(struct ham_params *params, int argc, char *const *argv)
Definition: ham.c:493
#define HAM_CLIENT_EP_DEFAULT
Definition: ham.c:62
M0_INTERNAL void m0_ha_disconnect_incoming(struct m0_ha *ha, struct m0_ha_link *hl)
Definition: ha.c:714
Definition: ha.h:289
Definition: ham.c:65
Definition: ham.c:65
static void ham_link_absent(struct m0_ha *ha, const struct m0_uint128 *req_id)
Definition: ham.c:391
format
Definition: hist.py:128
static struct ham_params g_params
M0_INTERNAL void m0_reqh_start(struct m0_reqh *reqh)
Definition: reqh.c:711
uint64_t n
Definition: fops.h:107
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
static int ham_sighandler_init(void)
Definition: ham.c:446
union m0_ha_msg_data::@212 u
static void ham_link_is_disconnecting(struct m0_ha *ha, struct m0_ha_link *hl)
Definition: ham.c:396
static void ham_send(struct m0_ha *ha, struct m0_ha_link *hl, const struct m0_ha_msg *msg)
Definition: ham.c:298
static void ham_rpc_ctx_fini(struct ham_rpc_ctx *ctx)
Definition: ham.c:266
Definition: fid.h:38
static void ham_maybe_set(const char **dest, const char *value)
Definition: ham.c:567
M0_INTERNAL int m0_ha_init(struct m0_ha *ha, struct m0_ha_cfg *ha_cfg)
Definition: ha.c:641
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
enum ham_mode hp_mode
Definition: ham.c:72
struct m0_reqh mrc_reqh
Definition: ham.c:87
static void ham_link_disconnected(struct m0_ha *ha, struct m0_ha_link *hl)
Definition: ham.c:401
Definition: ha.h:272
Definition: common.h:34
m0_bcount_t size
Definition: di.c:39
#define HAM_SERVER_WAIT_DEFAULT
Definition: ham.c:63
Definition: ha.h:239
int main(int argc, char **argv)
Definition: ham.c:602
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
Definition: ham.c:68
void m0_ha_entrypoint_reply(struct m0_ha *ha, const struct m0_uint128 *req_id, const struct m0_ha_entrypoint_rep *rep, struct m0_ha_link **hl_ptr)
Definition: ha.c:844
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
const struct m0_conf_obj_type M0_CONF_PROCESS_TYPE
Definition: process.c:161
struct m0_net_buffer_pool mrc_buf_pool
Definition: ham.c:86
Definition: nucleus.c:42
int type
Definition: dir.c:1031
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
static void ham_entrypoint_request(struct m0_ha *ha, const struct m0_ha_entrypoint_req *req, const struct m0_uint128 *req_id)
Definition: ham.c:319
void m0_rpc_net_buffer_pool_cleanup(struct m0_net_buffer_pool *app_pool)
Definition: rpc.c:264
bool hp_verbose
Definition: ham.c:75
static void ham_entrypoint_replied(struct m0_ha *ha, struct m0_ha_entrypoint_rep *rep)
Definition: ham.c:346
const char * hp_ep_remote
Definition: ham.c:74
void m0_free(void *data)
Definition: memory.c:146
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
static bool ha_msg_is_one_way(const struct m0_ha_msg *msg)
Definition: ham.c:149
struct m0_fid hcf_process_fid
Definition: ha.h:279
static void ham_say(const char *format,...)
Definition: ham.c:160
#define M0_IMPOSSIBLE(fmt,...)
static const struct m0_ha_ops ham_ha_ops
Definition: ham.c:419
int m0_nanosleep(const m0_time_t req, m0_time_t *rem)
Definition: ktime.c:73