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;
    }
}
Exemplo n.º 2
0
void dm_hash_remove(struct dm_hash_table *t, const char *key)
{
	dm_hash_remove_binary(t, key, strlen(key) + 1);
}
static int read_from_tcpsock(struct local_client *client, char *buf, int len, char *csid,
			     struct local_client **new_client)
{
    struct sockaddr_in6 addr;
    socklen_t slen = sizeof(addr);
    struct clvm_header *header = (struct clvm_header *)buf;
    int status;
    uint32_t arglen;

    DEBUGLOG("read_from_tcpsock fd %d\n", client->fd);
    *new_client = NULL;

    /* Get "csid" */
    getpeername(client->fd, (struct sockaddr *)&addr, &slen);
    memcpy(csid, &addr.sin6_addr, GULM_MAX_CSID_LEN);

    /* Read just the header first, then get the rest if there is any.
     * Stream sockets, sigh.
     */
    status = really_read(client->fd, buf, sizeof(struct clvm_header));
    if (status > 0)
    {
	    int status2;

	    arglen = ntohl(header->arglen);

	    /* Get the rest */
	    if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
	    {
		    status2 = really_read(client->fd, buf+status, arglen);
		    if (status2 > 0)
			    status += status2;
		    else
			    status = status2;
	    }
    }

    DEBUGLOG("read_from_tcpsock, status = %d(errno = %d)\n", status, errno);

    /* Remove it from the hash table if there's an error, clvmd will
       remove the socket from its lists and free the client struct */
    if (status == 0 ||
	(status < 0 && errno != EAGAIN && errno != EINTR))
    {
	char remcsid[GULM_MAX_CSID_LEN];

	memcpy(remcsid, csid, GULM_MAX_CSID_LEN);
	close(client->fd);

	/* If the csid was mangled, then make sure we remove the right entry */
	if (client->bits.net.flags)
	    remcsid[0] ^= 0x80;
	dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);

	/* Tell cluster manager layer */
	add_down_node(remcsid);
    }
    else {
	    gulm_add_up_node(csid);
	    /* Send it back to clvmd */
	    process_message(client, buf, status, csid);
    }
    return status;
}