Esempio n. 1
0
int algopr_send_data(exa_nodeid_t node_id, void *buffer1, int size1,
                     void *buffer2, int size2)
{
    payload_t *payload;

    EXA_ASSERT(EXA_NODEID_VALID(node_id));

    /* FIXME see comment above definition of SIZEOF_ALGOPR_MSGNETWORK_T */
    EXA_ASSERT(size1 == SIZEOF_ALGOPR_MSGNETWORK_T);

    /* Send is local, just forwrd it */
    if (node_id == this_node_id)
    {
	algopr_new_msg(buffer1, size1, buffer2, size2);
	return 1;
    }

    /* Note: All nbd lists send_list[] share the same root so here we don't
     * care in which one is picked up the buffer */
    payload = nbd_list_remove(&eth.send_list[0].root->free, NULL, LISTWAIT);
    EXA_ASSERT(payload != NULL);

    memcpy(payload->payload, buffer1, size1);

    payload->size1 = size1;
    payload->size2 = size2;
    payload->buffer = buffer2;

    nbd_list_post(&eth.send_list[node_id], payload, -1);
    wq_wake(&eth.wq_send);

    return 1;
}
Esempio n. 2
0
/**
 * Thread responsible for accepting connections
 *
 * It's a separate thread because we accept do some memory allocation and we
 * must avoid that in recv thread.
 *
 * @param unused  Unused parameter
 */
static void accept_thread(void *unused)
{
    exalog_as(EXAMSG_ISCSI_ID);

    while (algopr_run)
    {
        exa_nodeid_t node_id;
        const char *ip_addr;
        struct sockaddr_in client_address;
        int size = sizeof(client_address);

        int sock =
            os_accept(eth.accept_sock, (struct sockaddr *)&client_address, &size);

        if (sock < 0)
            continue; /* it's a false accept */

        ip_addr = os_inet_ntoa(client_address.sin_addr);

        if (!suspended)
        {
            exalog_warning("Closing incoming connection from %s while not"
                           " suspended.", ip_addr);
            __close_socket(sock);
            continue;
        }

        internal_setsock_opt(sock, SOCK_FLAGS);

        node_id = get_peer_id_from_ip_addr(ip_addr);
        if (!EXA_NODEID_VALID(node_id))
        {
            exalog_warning("Closing incoming connection from unknown node %s.",
                           ip_addr);
            __close_socket(sock);
            continue;
        }

        set_peer_socket(node_id, ip_addr, sock);
    }
}
Esempio n. 3
0
/** \brief Initialization of examsgd daemon.
 *
 * Command line must contain the node name and the interface name to use
 * for control messages.
 *
 * Accepts hidden option -d (debugging mode).
 *
 * \param[in] argc	Argument count.
 * \param[in] argv	Array of argument values.
 *
 * \return exit code.
 */
int daemon_init(int argc, char *argv[])
{
  int s;

  /* getopt variables */
  static struct option long_opts[] =
    {
      { "cluster-id",  required_argument, NULL, 'c' },
      { "help",        no_argument,       NULL, 'h' },
      { "hostname",    required_argument, NULL, 'N' },
      { "incarnation", required_argument, NULL, 'I' },
      { "mcast-addr",  required_argument, NULL, 'm' },
      { "mcast-port",  required_argument, NULL, 'p' },
      { "node-id",     required_argument, NULL, 'i' },
      { "node-name",   required_argument, NULL, 'n' },
      { "stats",       no_argument,       NULL, 's' },
      { NULL,          0,                 NULL, 0   }
    };
  int long_idx, c;
  char *e;
  extern char *optarg;
  extern int optind;

  /* configurable options and default values */
  const char *node_name = NULL;
  const char *hostname = NULL;
  const char *mgroup = EXAMSG_MCASTIP;
  unsigned short mport = EXAMSG_PORT;
  unsigned short inca = 0;
  exa_uuid_t cluster_uuid;
  exa_nodeid_t nodeid;

  bool err = false;

  uuid_zero(&cluster_uuid);
  nodeid = EXA_NODEID_NONE;

  /* options parsing */
  while ((c = os_getopt_long(argc, argv, "c:dhi:I:m:n:N:p:s", long_opts, &long_idx))
	 != -1)
    switch (c)
      {
      case 'c':
	if (uuid_scan(optarg, &cluster_uuid) < 0)
	  {
	    fprintf(stderr, "invalid cluster id: '%s'\n", optarg);
	    return -EINVAL;
	  }
	break;

      case 'i':
	nodeid = (exa_nodeid_t)strtol(optarg, &e, 10);
	if (*e || !EXA_NODEID_VALID(nodeid))
	  {
	    fprintf(stderr, "invalid node id: '%s'\n", optarg);
	    return -EINVAL;
	  }
	break;

      case 'I':
	inca = (unsigned short)strtol(optarg, &e, 10);
	if (*e || inca == 0)
	  {
	    fprintf(stderr, "invalid incarnation: '%s'\n", optarg);
	    return -EINVAL;
	  }
	break;

	/* multicast group */
      case 'm':
	mgroup = optarg;
	break;

      case 'n':
	node_name = optarg;
	break;

	/* hostname */
      case 'N':
	hostname = optarg;
	break;

	/* communication port */
      case 'p':
	mport = strtol(optarg, &e, 0);
	if (*e != '\0')
	  {
	    fprintf(stderr, "invalid port number '%s'\n", optarg);
	    return -EINVAL;
	  }
	break;

      case 's':
	examsg_show_stats();
	return 0;
	break;

	/* usage */
      case 'h':
      case '?':
      default:
	usage(argv[0]);
	return -EINVAL;
      }

  if (uuid_is_zero(&cluster_uuid))
    {
      fprintf(stderr, "missing cluster id\n");
      err = true;
    }

  if (nodeid == EXA_NODEID_NONE)
    {
      fprintf(stderr, "missing node id\n");
      err = true;
    }

  if (node_name == NULL)
    {
      fprintf(stderr, "missing node name\n");
      err = true;
    }

  if (hostname == NULL)
    {
      fprintf(stderr, "missing hostname\n");
      err = true;
    }

  if (inca == 0)
    {
      fprintf(stderr, "missing incarnation\n");
      err = true;
    }

  if (err)
    return -EINVAL;

  /* Get cluster id, number of nodes, node id, node name
     and interface parameters */
  if (argc - optind != 0)
    {
      fprintf(stderr, "stray parameters\n");
      usage(argv[0]);
      return -EINVAL;
    }

  signal(SIGTERM, sig_term);
  signal(SIGINT, sig_term);

  s = examsg_static_init(EXAMSG_STATIC_GET);
  if (s)
  {
      fprintf(stderr, "Can't initialize messaging layer.");
      return s;
  }

  exalog_static_init();

  /* Log as exa_msgd by default */
  exalog_as(EXAMSG_CMSGD_ID);

#ifdef USE_YAOURT
  if (yaourt_init())
    exalog_debug("Yaourt: Examsgd init OK");
  else
    exalog_warning("Yaourt: Examsgd init FAILED (%s)", yaourt_error);
#endif

  /* set up network communication */
  return startup(&cluster_uuid, node_name, hostname, nodeid, mgroup, mport, inca);
}
Esempio n. 4
0
/**
 * init_plugin initialise internal data
 *
 * if we are server, try to bind and launch a thread to accept
 * launch the thread of receive data
 *
 * @param net_plugin  Info on the new instance that we will fill
 *
 * @return EXA_SUCCESS or error
 */
int algopr_init_plugin(exa_nodeid_t node_id, int max_buffer_size)
{
    struct sockaddr_in serv_addr;
    int retval = -NBD_ERR_MALLOC_FAILED;
    int i;

    EXA_ASSERT(EXA_NODEID_VALID(node_id));
    this_node_id = node_id;

    init_peers();

    eth.max_buffer_size = max_buffer_size + max_buffer_size;

    wq_init(&eth.wq_send);

    nbd_init_root(MAX_BIG_RECV_ELT, eth.max_buffer_size, &eth.root_list_big_recv);

    nbd_init_root(MAX_SEND_ELT, sizeof(payload_t), &eth.root_list_send);
    for (i = 0; i < EXA_MAX_NODES_NUMBER; i++)
        nbd_init_list(&eth.root_list_send, &eth.send_list[i]);

    algopr_run = true;

    if (!exathread_create_named(&eth.receive_thread,
		                NBD_THREAD_STACK_SIZE +
				MIN_THREAD_STACK_SIZE_OF_THIS_PLUGIN,
				algopr_receive_thread, NULL, "AlgoPrRcv"))
	return -NBD_ERR_THREAD_CREATION;

    if (!exathread_create_named(&eth.send_thread,
		                NBD_THREAD_STACK_SIZE +
				MIN_THREAD_STACK_SIZE_OF_THIS_PLUGIN,
				algopr_send_thread, NULL, "AlgoPrSnd"))
        return -NBD_ERR_THREAD_CREATION;

    eth.accept_sock = os_socket(PF_INET, SOCK_STREAM, 0);
    if (eth.accept_sock < 0)
        return -EXA_ERR_CREATE_SOCKET;

    /* bind a socket to SERVERD_DATA_PORT port and make it listen for incoming
     * connections */
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(algopr_network_port);

    retval = internal_setsock_opt(eth.accept_sock, SOCK_LISTEN_FLAGS);
    if (retval != EXA_SUCCESS)
        return retval;

    if (os_bind(eth.accept_sock, (struct sockaddr *) &serv_addr,
                sizeof(serv_addr)) < 0)
        return -EXA_ERR_CREATE_SOCKET;

    if (os_listen(eth.accept_sock, EXA_MAX_NODES_NUMBER) < 0)
        return -EXA_ERR_CREATE_SOCKET;

    if (!exathread_create_named(&eth.accept_thread,
		                NBD_THREAD_STACK_SIZE +
				MIN_THREAD_STACK_SIZE_OF_THIS_PLUGIN,
				accept_thread, NULL, "servEthAccPlugin"))
        return -NBD_ERR_THREAD_CREATION;

    return EXA_SUCCESS;
}