int alloc_client(int fd, const char *c_csid, struct local_client **new_client)
{
    struct local_client *client;
    char csid[GULM_MAX_CSID_LEN];
    memcpy(csid, c_csid, sizeof csid);

    DEBUGLOG("alloc_client %d csid = %s\n", fd, print_csid(csid));

    /* Create a local_client and return it */
    client = malloc(sizeof(struct local_client));
    if (!client)
    {
	DEBUGLOG("malloc failed\n");
	return -1;
    }

    memset(client, 0, sizeof(struct local_client));
    client->fd = fd;
    client->type = CLUSTER_DATA_SOCK;
    client->callback = read_from_tcpsock;
    if (new_client)
	*new_client = client;

    /* Add to our list of node sockets */
    if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
    {
	DEBUGLOG("alloc_client mangling CSID for second connection\n");
	/* This is a duplicate connection but we can't close it because
	   the other end may already have started sending.
	   So, we mangle the IP address and keep it, all sending will
	   go out of the main FD
	*/
	csid[0] ^= 0x80;
	client->bits.net.flags = 1; /* indicate mangled CSID */

        /* If it still exists then kill the connection as we should only
           ever have one incoming connection from each node */
        if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
        {
	    DEBUGLOG("Multiple incoming connections from node\n");
            syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);

	    free(client);
            errno = ECONNREFUSED;
            return -1;
        }
    }
    dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);

    return 0;
}
void tcp_remove_client(const char *c_csid)
{
    struct local_client *client;
    char csid[GULM_MAX_CSID_LEN];
    unsigned int i;
    memcpy(csid, c_csid, sizeof csid);
    DEBUGLOG("tcp_remove_client\n");

    /* Don't actually close the socket here - that's the
       job of clvmd.c whch will do the job when it notices the
       other end has gone. We just need to remove the client(s) from
       the hash table so we don't try to use it for sending any more */
    for (i = 0; i < 2; i++)
    {
	client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
	if (client)
	{
	    dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
	    client->removeme = 1;
	    close(client->fd);
	}
	/* Look for a mangled one too, on the 2nd iteration. */
	csid[0] ^= 0x80;
    }
}
/* Send a message to a known CSID */
static int tcp_send_message(void *buf, int msglen, const char *csid, const char *errtext)
{
    int status;
    struct local_client *client;
    char ourcsid[GULM_MAX_CSID_LEN];

    assert(csid);

    DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);

    /* Don't connect to ourself */
    get_our_gulm_csid(ourcsid);
    if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
	return msglen;

    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
    if (!client)
    {
	status = gulm_connect_csid(csid, &client);
	if (status)
	    return -1;
    }
    DEBUGLOG("tcp_send_message, fd = %d\n", client->fd);

    return write(client->fd, buf, msglen);
}
Exemplo n.º 4
0
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
				 const struct cpg_name *groupName,
				 const struct cpg_address *member_list, size_t member_list_entries,
				 const struct cpg_address *left_list, size_t left_list_entries,
				 const struct cpg_address *joined_list, size_t joined_list_entries)
{
	int i;
	struct node_info *ninfo;

	DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
		 joined_list_entries, left_list_entries, member_list_entries);

	for (i=0; i<joined_list_entries; i++) {
		ninfo = dm_hash_lookup_binary(node_hash,
					      (char *)&joined_list[i].nodeid,
					      COROSYNC_CSID_LEN);
		if (!ninfo) {
			ninfo = malloc(sizeof(struct node_info));
			if (!ninfo) {
				break;
			}
			else {
				ninfo->nodeid = joined_list[i].nodeid;
				dm_hash_insert_binary(node_hash,
						      (char *)&ninfo->nodeid,
						      COROSYNC_CSID_LEN, ninfo);
			}
		}
		ninfo->state = NODE_CLVMD;
	}

	for (i=0; i<left_list_entries; i++) {
		ninfo = dm_hash_lookup_binary(node_hash,
					      (char *)&left_list[i].nodeid,
					      COROSYNC_CSID_LEN);
		if (ninfo)
			ninfo->state = NODE_DOWN;
	}

	num_nodes = member_list_entries;
}
Exemplo n.º 5
0
/* Corosync doesn't really have nmode names so we
   just use the node ID in hex instead */
static int _csid_from_name(char *csid, const char *name)
{
	int nodeid;
	struct node_info *ninfo;

	if (sscanf(name, "%x", &nodeid) == 1) {
		ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
		if (ninfo)
			return nodeid;
	}
	return -1;
}
Exemplo n.º 6
0
static int _name_from_csid(const char *csid, char *name)
{
	struct node_info *ninfo;

	ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
	if (!ninfo)
	{
		sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
		return -1;
	}

	sprintf(name, "%x", ninfo->nodeid);
	return 0;
}
Exemplo n.º 7
0
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
	struct node_info *ninfo;

	ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
	if (!ninfo) {
		DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
			 print_corosync_csid(csid));
		return;
	}

	DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);

	ninfo->state = NODE_CLVMD;

	return;
}
Exemplo n.º 8
0
void *dm_hash_lookup(struct dm_hash_table *t, const char *key)
{
	return dm_hash_lookup_binary(t, key, strlen(key) + 1);
}