Motr  M0
node.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 "lib/errno.h" /* ETIMEDOUT */
24 #include "lib/misc.h" /* M0_SET0 */
25 #include "lib/memory.h" /* M0_ALLOC_PTR */
26 #include "lib/trace.h" /* M0_LOG */
27 
28 #include "net/test/node.h" /* m0_net_test_node_ctx */
29 #include "net/test/node_stub.h" /* m0_net_test_node_stub_ops */
30 #include "net/test/node_ping.h" /* m0_net_test_node_ping_ops */
31 #include "net/test/node_bulk.h" /* m0_net_test_node_bulk_ops */
32 
33 #define NET_TEST_MODULE_NAME node
34 #include "net/test/debug.h"
35 
719 enum {
721 };
722 
723 static struct m0_net_test_service_ops *
725 {
727 
728  switch (cmd->ntc_init.ntci_type) {
735  default:
736  return NULL;
737  }
738 }
739 
740 static int node_cmd_get(struct m0_net_test_cmd_ctx *cmd_ctx,
741  struct m0_net_test_cmd *cmd,
742  m0_time_t deadline)
743 {
744  int rc = m0_net_test_commands_recv(cmd_ctx, cmd, deadline);
745  if (rc == 0)
747  cmd->ntc_buf_index);
748  if (rc == 0) {
749  LOGD("node_cmd_get: rc = %d", rc);
750  LOGD("node_cmd_get: cmd->ntc_type = %d", cmd->ntc_type);
751  LOGD("node_cmd_get: cmd->ntc_init.ntci_msg_nr = %lu",
752  (unsigned long) cmd->ntc_init.ntci_msg_nr);
753  }
754  return rc;
755 }
756 
758  struct m0_net_test_cmd *cmd,
760 {
761  m0_time_t deadline;
762  const int TIME_ONE_MS = M0_TIME_ONE_SECOND / 1000;
763  int rc;
764 
765  M0_PRE(ctx != NULL);
766  do {
768  TIME_ONE_MS);
769  rc = node_cmd_get(&ctx->ntnc_cmd, cmd, deadline);
770  if (rc != 0 && rc != -ETIMEDOUT)
771  return rc;
772  if (rc == 0 && cmd->ntc_type != type)
774  } while (!(rc == 0 && cmd->ntc_type == type) && !ctx->ntnc_exit_flag);
775  return 0;
776 }
777 
779 {
780  struct m0_net_test_service svc;
781  struct m0_net_test_service_ops *svc_ops;
782  enum m0_net_test_service_state svc_state;
783  struct m0_net_test_cmd *cmd;
784  struct m0_net_test_cmd *reply;
785  int rc;
786  bool skip_cmd_get;
787 
788  M0_PRE(ctx != NULL);
789 
790  M0_ALLOC_PTR(cmd);
792  if (cmd == NULL || reply == NULL) {
793  rc = -ENOMEM;
794  goto done;
795  }
796 
797  /* wait for INIT command */
798  ctx->ntnc_errno = node_cmd_wait(ctx, cmd, M0_NET_TEST_CMD_INIT);
799  if (ctx->ntnc_exit_flag) {
800  rc = 0;
802  goto done;
803  }
804  if (ctx->ntnc_errno != 0) {
805  rc = ctx->ntnc_errno;
806  goto done;
807  }
808  /* we have configuration; initialize test service */
809  svc_ops = service_ops_get(cmd);
810  if (svc_ops == NULL) {
811  rc = -ENODATA;
813  goto done;
814  }
815  rc = m0_net_test_service_init(&svc, svc_ops);
816  if (rc != 0) {
818  goto done;
819  }
820  /* handle INIT command inside main loop */
821  skip_cmd_get = true;
822  /* test service is initialized. start main loop */
823  do {
824  /* get command */
825  if (rc == 0 && !skip_cmd_get)
826  rc = node_cmd_get(&ctx->ntnc_cmd, cmd,
827  m0_time_from_now(0, 25000000));
828  // m0_time_now());
829  else
830  skip_cmd_get = false;
831  if (rc == 0)
832  LOGD("node_thread: cmd_get, "
833  "rc = %d, cmd.ntc_ep_index = %lu",
834  rc, cmd->ntc_ep_index);
835  if (rc == 0 && cmd->ntc_ep_index >= 0) {
836  LOGD("node_thread: have command");
837  /* we have command. handle it */
839  LOGD("node_thread: cmd handle: rc = %d", rc);
840  reply->ntc_ep_index = cmd->ntc_ep_index;
842  /* send reply */
843  LOGD("node_thread: reply.ntc_ep_index = %lu",
844  reply->ntc_ep_index);
846  rc = m0_net_test_commands_send(&ctx->ntnc_cmd, reply);
847  LOGD("node_thread: send reply: rc = %d", rc);
848  M0_SET0(cmd);
849  } else if (rc == -ETIMEDOUT) {
850  /* we haven't command. take a step. */
852  } else {
853  break;
854  }
855  svc_state = m0_net_test_service_state_get(&svc);
856  } while (svc_state != M0_NET_TEST_SERVICE_FAILED &&
857  svc_state != M0_NET_TEST_SERVICE_FINISHED &&
858  !ctx->ntnc_exit_flag &&
859  rc == 0);
860 
861  /* finalize test service */
863 
864 done:
865  m0_free(cmd);
866  m0_free(reply);
867  LOGD("rc = %d", rc);
868  ctx->ntnc_errno = rc;
869  m0_semaphore_up(&ctx->ntnc_thread_finished_sem);
870 }
871 
873  struct m0_net_test_node_cfg *cfg)
874 {
875  struct m0_net_test_slist ep_list;
876  int rc;
877 
878  M0_PRE(ctx != NULL);
879  if (cfg == NULL)
880  goto fini;
881 
882  M0_SET0(ctx);
883 
884  rc = m0_net_test_slist_init(&ep_list, cfg->ntnc_addr_console, '`');
885  if (rc != 0)
886  goto failed;
887  rc = m0_net_test_commands_init(&ctx->ntnc_cmd,
888  cfg->ntnc_addr,
889  cfg->ntnc_send_timeout,
890  NULL,
891  &ep_list);
892  m0_net_test_slist_fini(&ep_list);
893  if (rc != 0)
894  goto failed;
895  rc = m0_semaphore_init(&ctx->ntnc_thread_finished_sem, 0);
896  if (rc != 0)
897  goto commands_fini;
898 
899  return 0;
900 fini:
901  rc = 0;
902  m0_semaphore_fini(&ctx->ntnc_thread_finished_sem);
903 commands_fini:
904  m0_net_test_commands_fini(&ctx->ntnc_cmd);
905 failed:
906  return rc;
907 }
908 
910  struct m0_net_test_node_cfg *cfg)
911 {
912  return node_init_fini(ctx, cfg);
913 }
914 
916 {
917  int rc = node_init_fini(ctx, NULL);
918  M0_ASSERT(rc == 0);
919 }
920 
922 {
923  M0_PRE(ctx != NULL);
924 
925  ctx->ntnc_exit_flag = false;
926  ctx->ntnc_errno = 0;
927 
928  return M0_THREAD_INIT(&ctx->ntnc_thread, struct m0_net_test_node_ctx *,
929  NULL, &node_thread, ctx, "net_test_node");
930 }
931 
933 {
934  int rc;
935 
936  M0_PRE(ctx != NULL);
937 
938  ctx->ntnc_exit_flag = true;
940  rc = m0_thread_join(&ctx->ntnc_thread);
941  /*
942  * In either case when rc != 0 there is an unmatched
943  * m0_net_test_node_start() and m0_net_test_node_stop()
944  * or deadlock. If non-zero rc is returned as result of this function,
945  * then m0_net_test_node_stop() leaves m0_net_test_node_ctx in
946  * inconsistent state (also possible resource leak).
947  */
948  M0_ASSERT(rc == 0);
949  m0_thread_fini(&ctx->ntnc_thread);
950 }
951 
953 
955 {
956  int rc = 0;
957 
958  if (cfg == NULL)
959  goto fini;
960  if (cfg->ntnc_addr == NULL ||
961  cfg->ntnc_addr_console == NULL ||
962  cfg->ntnc_send_timeout == 0) {
963  rc = -EINVAL;
964  goto fail;
965  }
966 
969  rc = -ENOMEM;
970  goto fail;
971  }
973  if (rc != 0)
974  goto free_ctx;
976  if (rc != 0)
977  goto fini_node;
978 
979  goto success;
980 fini:
982 fini_node:
984 free_ctx:
986 fail:
987 success:
988  return rc;
989 }
991 
992 #undef NET_TEST_MODULE_NAME
993 
998 /*
999  * Local variables:
1000  * c-indentation-style: "K&R"
1001  * c-basic-offset: 8
1002  * tab-width: 8
1003  * fill-column: 79
1004  * scroll-step: 1
1005  * End:
1006  */
int m0_net_test_node_module_initfini(struct m0_net_test_node_cfg *cfg)
Definition: node.c:954
#define M0_PRE(cond)
static int node_init_fini(struct m0_net_test_node_ctx *ctx, struct m0_net_test_node_cfg *cfg)
Definition: node.c:872
int m0_net_test_commands_init(struct m0_net_test_cmd_ctx *ctx, const char *cmd_ep, m0_time_t send_timeout, m0_net_test_commands_send_cb_t send_cb, struct m0_net_test_slist *ep_list)
Definition: commands.c:441
void m0_net_test_node_stop(struct m0_net_test_node_ctx *ctx)
Definition: node.c:932
#define NULL
Definition: misc.h:38
enum m0_net_test_service_state m0_net_test_service_state_get(struct m0_net_test_service *svc)
Definition: service.c:159
static void node_thread(struct m0_net_test_node_ctx *ctx)
Definition: node.c:778
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
uint64_t m0_time_t
Definition: time.h:37
m0_net_test_cmd_type
Definition: commands.h:78
static struct m0_net_test_node_ctx * m0_net_test_node_module_ctx
Definition: node.c:952
static int node_cmd_wait(struct m0_net_test_node_ctx *ctx, struct m0_net_test_cmd *cmd, enum m0_net_test_cmd_type type)
Definition: node.c:757
int m0_net_test_commands_recv_enqueue(struct m0_net_test_cmd_ctx *ctx, size_t buf_index)
Definition: commands.c:570
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
#define M0_SET0(obj)
Definition: misc.h:64
int m0_net_test_slist_init(struct m0_net_test_slist *slist, const char *str, char delim)
Definition: slist.c:57
char * ntnc_addr_console
Definition: node.h:195
char * ntnc_addr
Definition: node.h:193
#define LOGD(...)
Definition: tx_regmap.c:37
void m0_net_test_commands_received_free(struct m0_net_test_cmd *cmd)
Definition: commands.c:578
int m0_net_test_node_start(struct m0_net_test_node_ctx *ctx)
Definition: node.c:921
int m0_net_test_service_step(struct m0_net_test_service *svc)
Definition: service.c:107
void m0_net_test_commands_fini(struct m0_net_test_cmd_ctx *ctx)
Definition: commands.c:451
struct m0_net_test_cmd_init ntc_init
Definition: commands.h:208
int m0_net_test_commands_send(struct m0_net_test_cmd_ctx *ctx, struct m0_net_test_cmd *cmd)
Definition: commands.c:457
#define M0_ASSERT(cond)
void m0_net_test_slist_fini(struct m0_net_test_slist *slist)
Definition: slist.c:120
void m0_net_test_commands_send_wait_all(struct m0_net_test_cmd_ctx *ctx)
Definition: commands.c:490
void m0_thread_fini(struct m0_thread *q)
Definition: thread.c:92
int m0_net_test_commands_recv(struct m0_net_test_cmd_ctx *ctx, struct m0_net_test_cmd *cmd, m0_time_t deadline)
Definition: commands.c:511
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
uint64_t ntci_msg_nr
Definition: commands.h:112
m0_time_t ntnc_send_timeout
Definition: node.h:197
enum m0_net_test_type ntci_type
Definition: commands.h:106
ssize_t ntc_ep_index
Definition: commands.h:218
void m0_net_test_service_fini(struct m0_net_test_service *svc)
Definition: service.c:88
int m0_net_test_service_cmd_handle(struct m0_net_test_service *svc, struct m0_net_test_cmd *cmd, struct m0_net_test_cmd *reply)
Definition: service.c:121
static uint8_t fail[DATA_UNIT_COUNT_MAX+PARITY_UNIT_COUNT_MAX]
size_t ntc_buf_index
Definition: commands.h:220
void m0_net_test_node_fini(struct m0_net_test_node_ctx *ctx)
Definition: node.c:915
int m0_net_test_node_init(struct m0_net_test_node_ctx *ctx, struct m0_net_test_node_cfg *cfg)
Definition: node.c:909
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
m0_net_test_service_state
Definition: service.h:60
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
static struct m0_net_test_service svc
Definition: service.c:34
struct m0_net_test_service_ops m0_net_test_node_ping_ops
Definition: node_ping.c:952
static struct m0_net_test_service_ops * service_ops_get(struct m0_net_test_cmd *cmd)
Definition: node.c:724
enum m0_net_test_cmd_type ntc_type
Definition: commands.h:204
struct m0_net_test_service_ops m0_net_test_node_bulk_ops
Definition: node_bulk.c:1672
int fini(struct workload *w)
static unsigned done
Definition: storage.c:91
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 struct m0_dtm_oper_descr reply
Definition: transmit.c:94
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
static int node_cmd_get(struct m0_net_test_cmd_ctx *cmd_ctx, struct m0_net_test_cmd *cmd, m0_time_t deadline)
Definition: node.c:740
struct m0_net_test_service_ops m0_net_test_node_stub_ops
Definition: node_stub.c:115
int m0_net_test_service_init(struct m0_net_test_service *svc, struct m0_net_test_service_ops *ops)
Definition: service.c:68