Exemple #1
0
int fdfs_recv_header(ConnectionInfo *pTrackerServer, int64_t *in_bytes)
{
	TrackerHeader resp;
	int result;

	if ((result=tcprecvdata_nb(pTrackerServer->sock, &resp, \
		sizeof(resp), g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"server: %s:%d, recv data fail, " \
			"errno: %d, error info: %s", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
		*in_bytes = 0;
		return result;
	}

	if (resp.status != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"server: %s:%d, response status %d != 0", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, resp.status);

		*in_bytes = 0;
		return resp.status;
	}

	*in_bytes = buff2long(resp.pkg_len);
	if (*in_bytes < 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"server: %s:%d, recv package size " \
			INT64_PRINTF_FORMAT" is not correct", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, *in_bytes);
		*in_bytes = 0;
		return EINVAL;
	}

	return resp.status;
}
Exemple #2
0
bool fdfs_is_trunk_file(const char *remote_filename, const int filename_len)
{
    int buff_len;
    char buff[64];
    int64_t file_size;

    if (filename_len != FDFS_TRUNK_LOGIC_FILENAME_LENGTH) //not trunk file
    {
        return false;
    }

    memset(buff, 0, sizeof(buff));
    base64_decode_auto(&g_fdfs_base64_context, (char *)remote_filename + \
                       FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
                       buff, &buff_len);

    file_size = buff2long(buff + sizeof(int) * 2);
    return IS_TRUNK_FILE(file_size);
}
Exemple #3
0
int tcprecvfile(int sock, const char *filename, const int64_t file_bytes, \
		const int fsync_after_written_bytes, const int timeout, \
		int64_t *true_file_bytes)
{
	int write_fd;
	char buff[FDFS_WRITE_BUFF_SIZE];
	int64_t remain_bytes;
	int recv_bytes;
	int written_bytes;
	int result;
	int flags;
	int count;
	tcprecvdata_exfunc recv_func;

	*true_file_bytes = 0;
	flags = fcntl(sock, F_GETFL, 0);
	if (flags < 0)
	{
		return errno != 0 ? errno : EACCES;
	}

	if (flags & O_NONBLOCK)
	{
		recv_func = tcprecvdata_nb_ex;
	}
	else
	{
		recv_func = tcprecvdata_ex;
	}

	write_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
	if (write_fd < 0)
	{
		return errno != 0 ? errno : EACCES;
	}

	written_bytes = 0;
	remain_bytes = file_bytes;
	while (remain_bytes > 0)
	{
		if (remain_bytes > sizeof(buff))
		{
			recv_bytes = sizeof(buff);
		}
		else
		{
			recv_bytes = remain_bytes;
		}

		result = recv_func(sock, buff, recv_bytes, \
				timeout, &count);
		if (result != 0)
		{
			if (file_bytes != INFINITE_FILE_SIZE)
			{
				close(write_fd);
				unlink(filename);
				return result;
			}
		}

		if (count > 0 && write(write_fd, buff, count) != count)
		{
			result = errno != 0 ? errno: EIO;
			close(write_fd);
			unlink(filename);
			return result;
		}

		*true_file_bytes += count;
		if (fsync_after_written_bytes > 0)
		{
			written_bytes += count;
			if (written_bytes >= fsync_after_written_bytes)
			{
				written_bytes = 0;
				if (fsync(write_fd) != 0)
				{
					result = errno != 0 ? errno: EIO;
					close(write_fd);
					unlink(filename);
					return result;
				}
			}
		}

		if (result != 0)  //recv infinite file, does not delete the file
		{
			int read_fd;
			read_fd = -1;

			do
			{
				if (*true_file_bytes < 8)
				{
					break;
				}

				read_fd = open(filename, O_RDONLY);
				if (read_fd < 0)
				{
					return errno != 0 ? errno : EACCES;
				}

				if (lseek(read_fd, -8, SEEK_END) < 0)
				{
					result = errno != 0 ? errno : EIO;
					break;
				}

				if (read(read_fd, buff, 8) != 8)
				{
					result = errno != 0 ? errno : EIO;
					break;
				}

				*true_file_bytes -= 8;
				if (buff2long(buff) != *true_file_bytes)
				{
					result = EINVAL;
					break;
				}

				if (ftruncate(write_fd, *true_file_bytes) != 0)
				{
					result = errno != 0 ? errno : EIO;
					break;
				}

				result = 0;
			} while (0);
		
			close(write_fd);
			if (read_fd >= 0)
			{
				close(read_fd);
			}

			if (result != 0)
			{
				unlink(filename);
			}

			return result;
		}

		remain_bytes -= count;
	}

	close(write_fd);
	return 0;
}
Exemple #4
0
int trunk_file_do_lstat_func_ex(const FDFSStorePaths *pStorePaths, \
                                const int store_path_index, const char *true_filename, \
                                const int filename_len, const int stat_func, \
                                struct stat *pStat, FDFSTrunkFullInfo *pTrunkInfo, \
                                FDFSTrunkHeader *pTrunkHeader, int *pfd)
{
    char full_filename[MAX_PATH_SIZE];
    char buff[128];
    char pack_buff[FDFS_TRUNK_FILE_HEADER_SIZE];
    int64_t file_size;
    int buff_len;
    int fd;
    int read_bytes;
    int result;

    pTrunkInfo->file.id = 0;
    if (filename_len != FDFS_TRUNK_FILENAME_LENGTH) //not trunk file
    {
        snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \
                 pStorePaths->paths[store_path_index], true_filename);

        if (stat_func == FDFS_STAT_FUNC_STAT)
        {
            result = stat(full_filename, pStat);
        }
        else
        {
            result = lstat(full_filename, pStat);
        }
        if (result == 0)
        {
            return 0;
        }
        else
        {
            return errno != 0 ? errno : ENOENT;
        }
    }

    memset(buff, 0, sizeof(buff));
    base64_decode_auto(&g_fdfs_base64_context, (char *)true_filename + \
                       FDFS_TRUE_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
                       buff, &buff_len);

    file_size = buff2long(buff + sizeof(int) * 2);
    if (!IS_TRUNK_FILE(file_size))  //slave file
    {
        snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \
                 pStorePaths->paths[store_path_index], true_filename);

        if (stat_func == FDFS_STAT_FUNC_STAT)
        {
            result = stat(full_filename, pStat);
        }
        else
        {
            result = lstat(full_filename, pStat);
        }
        if (result == 0)
        {
            return 0;
        }
        else
        {
            return errno != 0 ? errno : ENOENT;
        }
    }

    trunk_file_info_decode(true_filename + FDFS_TRUE_FILE_PATH_LEN + \
                           FDFS_FILENAME_BASE64_LENGTH, &pTrunkInfo->file);

    pTrunkHeader->file_size = FDFS_TRUNK_FILE_TRUE_SIZE(file_size);
    pTrunkHeader->mtime = buff2int(buff + sizeof(int));
    pTrunkHeader->crc32 = buff2int(buff + sizeof(int) * 4);
    memcpy(pTrunkHeader->formatted_ext_name, true_filename + \
           (filename_len - (FDFS_FILE_EXT_NAME_MAX_LEN + 1)), \
           FDFS_FILE_EXT_NAME_MAX_LEN + 2); //include tailing '\0'
    pTrunkHeader->alloc_size = pTrunkInfo->file.size;

    pTrunkInfo->path.store_path_index = store_path_index;
    pTrunkInfo->path.sub_path_high = strtol(true_filename, NULL, 16);
    pTrunkInfo->path.sub_path_low = strtol(true_filename + 3, NULL, 16);

    trunk_get_full_filename_ex(pStorePaths, pTrunkInfo, full_filename, \
                               sizeof(full_filename));
    fd = open(full_filename, O_RDONLY);
    if (fd < 0)
    {
        return errno != 0 ? errno : EIO;
    }

    if (lseek(fd, pTrunkInfo->file.offset, SEEK_SET) < 0)
    {
        result = errno != 0 ? errno : EIO;
        close(fd);
        return result;
    }

    read_bytes = read(fd, buff, FDFS_TRUNK_FILE_HEADER_SIZE);
    if (read_bytes == FDFS_TRUNK_FILE_HEADER_SIZE)
    {
        result = 0;
    }
    else
    {
        result = errno;
        close(fd);
        return result != 0 ? result : EINVAL;
    }

    memset(pStat, 0, sizeof(struct stat));
    pTrunkHeader->file_type = *(buff + FDFS_TRUNK_FILE_FILE_TYPE_OFFSET);
    if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_REGULAR)
    {
        pStat->st_mode = S_IFREG;
    }
    else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_LINK)
    {
        pStat->st_mode = S_IFLNK;
    }
    else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_NONE)
    {
        close(fd);
        return ENOENT;
    }
    else
    {
        close(fd);
        logError("file: "__FILE__", line: %d, " \
                 "Invalid file type: %d", __LINE__, \
                 pTrunkHeader->file_type);
        return ENOENT;
    }

    trunk_pack_header(pTrunkHeader, pack_buff);

    /*
    {
    char temp[265];
    char szHexBuff[2 * FDFS_TRUNK_FILE_HEADER_SIZE + 1];
    FDFSTrunkHeader trueTrunkHeader;

    fprintf(stderr, "file: "__FILE__", line: %d, true buff=%s\n", __LINE__, \
    	bin2hex(buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff));
    trunk_unpack_header(buff, &trueTrunkHeader);
    fprintf(stderr, "file: "__FILE__", line: %d, true fields=%s\n", __LINE__, \
    	trunk_header_dump(&trueTrunkHeader, full_filename, sizeof(full_filename)));

    fprintf(stderr, "file: "__FILE__", line: %d, my buff=%s\n", __LINE__, \
    	bin2hex(pack_buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff));
    fprintf(stderr, "file: "__FILE__", line: %d, my trunk=%s, my fields=%s\n", __LINE__, \
    	trunk_info_dump(pTrunkInfo, temp, sizeof(temp)), \
    	trunk_header_dump(pTrunkHeader, full_filename, sizeof(full_filename)));
    }
    */

    if (memcmp(pack_buff, buff, FDFS_TRUNK_FILE_HEADER_SIZE) != 0)
    {
        close(fd);
        return ENOENT;
    }

    pStat->st_size = pTrunkHeader->file_size;
    pStat->st_mtime = pTrunkHeader->mtime;

    if (pfd != NULL)
    {
        *pfd = fd;
    }
    else
    {
        close(fd);
    }

    return 0;
}
Exemple #5
0
static void client_sock_read(int sock, short event, void *arg)
{
	int bytes;
	int recv_bytes;
	struct fast_task_info *pTask;
        StorageClientInfo *pClientInfo;

	pTask = (struct fast_task_info *)arg;
        pClientInfo = (StorageClientInfo *)pTask->arg;
	if (pClientInfo->canceled)
	{
		return;
	}

	if (pClientInfo->stage != FDFS_STORAGE_STAGE_NIO_RECV)
	{
		if (event & IOEVENT_TIMEOUT) {
			pTask->event.timer.expires = g_current_time +
				g_fdfs_network_timeout;
			fast_timer_add(&pTask->thread_data->timer,
				&pTask->event.timer);
		}

		return;
	}

	if (event & IOEVENT_TIMEOUT)
	{
		if (pClientInfo->total_offset == 0 && pTask->req_count > 0)
		{
			pTask->event.timer.expires = g_current_time +
				g_fdfs_network_timeout;
			fast_timer_add(&pTask->thread_data->timer,
				&pTask->event.timer);
		}
		else
		{
			logError("file: "__FILE__", line: %d, " \
				"client ip: %s, recv timeout, " \
				"recv offset: %d, expect length: %d", \
				__LINE__, pTask->client_ip, \
				pTask->offset, pTask->length);

			task_finish_clean_up(pTask);
		}

		return;
	}

	if (event & IOEVENT_ERROR)
	{
		logDebug("file: "__FILE__", line: %d, " \
			"client ip: %s, recv error event: %d, "
			"close connection", __LINE__, pTask->client_ip, event);

		task_finish_clean_up(pTask);
		return;
	}

	fast_timer_modify(&pTask->thread_data->timer,
		&pTask->event.timer, g_current_time +
		g_fdfs_network_timeout);
	while (1)
	{
		if (pClientInfo->total_length == 0) //recv header
		{
			recv_bytes = sizeof(TrackerHeader) - pTask->offset;
		}
		else
		{
			recv_bytes = pTask->length - pTask->offset;
		}

		/*
		logInfo("total_length=%"PRId64", recv_bytes=%d, "
			"pTask->length=%d, pTask->offset=%d",
			pClientInfo->total_length, recv_bytes, 
			pTask->length, pTask->offset);
		*/

		bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0);
		if (bytes < 0)
		{
			if (errno == EAGAIN || errno == EWOULDBLOCK)
			{
			}
			else if (errno == EINTR)
			{
				continue;
			}
			else
			{
				logError("file: "__FILE__", line: %d, " \
					"client ip: %s, recv failed, " \
					"errno: %d, error info: %s", \
					__LINE__, pTask->client_ip, \
					errno, STRERROR(errno));

				task_finish_clean_up(pTask);
			}

			return;
		}
		else if (bytes == 0)
		{
			logDebug("file: "__FILE__", line: %d, " \
				"client ip: %s, recv failed, " \
				"connection disconnected.", \
				__LINE__, pTask->client_ip);

			task_finish_clean_up(pTask);
			return;
		}

		if (pClientInfo->total_length == 0) //header
		{
			if (pTask->offset + bytes < sizeof(TrackerHeader))
			{
				pTask->offset += bytes;
				return;
			}

			pClientInfo->total_length=buff2long(((TrackerHeader *) \
						pTask->data)->pkg_len);
			if (pClientInfo->total_length < 0)
			{
				logError("file: "__FILE__", line: %d, " \
					"client ip: %s, pkg length: " \
					"%"PRId64" < 0", \
					__LINE__, pTask->client_ip, \
					pClientInfo->total_length);

				task_finish_clean_up(pTask);
				return;
			}

			pClientInfo->total_length += sizeof(TrackerHeader);
			if (pClientInfo->total_length > pTask->size)
			{
				pTask->length = pTask->size;
			}
			else
			{
				pTask->length = pClientInfo->total_length;
			}
		}

		pTask->offset += bytes;
		if (pTask->offset >= pTask->length) //recv current pkg done
		{
			if (pClientInfo->total_offset + pTask->length >= \
					pClientInfo->total_length)
			{
				/* current req recv done */
				pClientInfo->stage = FDFS_STORAGE_STAGE_NIO_SEND;
				pTask->req_count++;
			}

			if (pClientInfo->total_offset == 0)
			{
				pClientInfo->total_offset = pTask->length;
				storage_deal_task(pTask);
			}
			else
			{
				pClientInfo->total_offset += pTask->length;

				/* continue write to file */
				storage_dio_queue_push(pTask);
			}

			return;
		}
	}

	return;
}
Exemple #6
0
static void client_sock_read(int sock, short event, void *arg)
{
    int bytes;
    int recv_bytes;
    struct fast_task_info *pTask;

    pTask = (struct fast_task_info *)arg;

    if (event & IOEVENT_TIMEOUT)
    {
        if (pTask->offset == 0 && pTask->req_count > 0)
        {
            pTask->event.timer.expires = g_current_time +
                                         g_fdfs_network_timeout;
            fast_timer_add(&pTask->thread_data->timer,
                           &pTask->event.timer);
        }
        else
        {
            logError("file: "__FILE__", line: %d, " \
                     "client ip: %s, recv timeout, " \
                     "recv offset: %d, expect length: %d", \
                     __LINE__, pTask->client_ip, \
                     pTask->offset, pTask->length);

            task_finish_clean_up(pTask);
        }

        return;
    }

    if (event & IOEVENT_ERROR)
    {
        logDebug("file: "__FILE__", line: %d, " \
                 "client ip: %s, recv error event: %d, "
                 "close connection", __LINE__, pTask->client_ip, event);

        task_finish_clean_up(pTask);
        return;
    }

    while (1)
    {
        fast_timer_modify(&pTask->thread_data->timer,
                          &pTask->event.timer, g_current_time +
                          g_fdfs_network_timeout);
        if (pTask->length == 0) //recv header
        {
            recv_bytes = sizeof(TrackerHeader) - pTask->offset;
        }
        else
        {
            recv_bytes = pTask->length - pTask->offset;
        }

        bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0);
        if (bytes < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
            }
            else if (errno == EINTR)
            {
                continue;
            }
            else
            {
                logError("file: "__FILE__", line: %d, " \
                         "client ip: %s, recv failed, " \
                         "errno: %d, error info: %s", \
                         __LINE__, pTask->client_ip, \
                         errno, STRERROR(errno));

                task_finish_clean_up(pTask);
            }

            return;
        }
        else if (bytes == 0)
        {
            logDebug("file: "__FILE__", line: %d, " \
                     "client ip: %s, recv failed, " \
                     "connection disconnected.", \
                     __LINE__, pTask->client_ip);

            task_finish_clean_up(pTask);
            return;
        }

        if (pTask->length == 0) //header
        {
            if (pTask->offset + bytes < sizeof(TrackerHeader))
            {
                pTask->offset += bytes;
                return;
            }

            pTask->length = buff2long(((TrackerHeader *) \
                                       pTask->data)->pkg_len);
            if (pTask->length < 0)
            {
                logError("file: "__FILE__", line: %d, " \
                         "client ip: %s, pkg length: %d < 0", \
                         __LINE__, pTask->client_ip, \
                         pTask->length);

                task_finish_clean_up(pTask);
                return;
            }

            pTask->length += sizeof(TrackerHeader);
            if (pTask->length > TRACKER_MAX_PACKAGE_SIZE)
            {
                logError("file: "__FILE__", line: %d, " \
                         "client ip: %s, pkg length: %d > " \
                         "max pkg size: %d", __LINE__, \
                         pTask->client_ip, pTask->length, \
                         TRACKER_MAX_PACKAGE_SIZE);

                task_finish_clean_up(pTask);
                return;
            }
        }

        pTask->offset += bytes;
        if (pTask->offset >= pTask->length) //recv done
        {
            pTask->req_count++;
            tracker_deal_task(pTask);
            return;
        }
    }

    return;
}
Exemple #7
0
int tracker_query_storage_store_list_with_group( \
	ConnectionInfo *pTrackerServer, const char *group_name, \
	ConnectionInfo *storageServers, const int nMaxServerCount, \
	int *storage_count, int *store_path_index)
{
	ConnectionInfo *pStorageServer;
	ConnectionInfo *pServerEnd;
	TrackerHeader *pHeader;
	ConnectionInfo *conn;
	bool new_connection;
	char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN];
	char in_buff[sizeof(TrackerHeader) + FDFS_MAX_SERVERS_EACH_GROUP * \
			TRACKER_QUERY_STORAGE_STORE_BODY_LEN];
	char returned_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
	char *pInBuff;
	char *p;
	int64_t in_bytes;
	int out_len;
	int ipPortsLen;
	int result;

	*storage_count = 0;
	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	pHeader = (TrackerHeader *)out_buff;
	memset(out_buff, 0, sizeof(out_buff));

	if (group_name == NULL || *group_name == '\0')
	{
	pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ALL;
	out_len = 0;
	}
	else
	{
	pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ALL;
	snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
			sizeof(TrackerHeader),  "%s", group_name);
	out_len = FDFS_GROUP_NAME_MAX_LEN;
	}

	long2buff(out_len, pHeader->pkg_len);
	if ((result=tcpsenddata_nb(conn->sock, out_buff, \
		sizeof(TrackerHeader) + out_len, g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = in_buff;
		result = fdfs_recv_response(conn, \
				&pInBuff, sizeof(in_buff), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		return result;
	}

	if (in_bytes < TRACKER_QUERY_STORAGE_STORE_BODY_LEN)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid, " \
			"expect length >= %d", __LINE__, \
			pTrackerServer->ip_addr, pTrackerServer->port, \
			in_bytes, TRACKER_QUERY_STORAGE_STORE_BODY_LEN);
		return EINVAL;
	}

#define RECORD_LENGTH  (IP_ADDRESS_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE)

	ipPortsLen = in_bytes - (FDFS_GROUP_NAME_MAX_LEN + 1);
	if (ipPortsLen % RECORD_LENGTH != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, in_bytes);
		return EINVAL;
	}

	*storage_count = ipPortsLen / RECORD_LENGTH;
	if (nMaxServerCount < *storage_count)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response storage server " \
			 "count: %d, exceeds max server count: %d!", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, *storage_count, nMaxServerCount);
		return ENOSPC;
	}

	memset(storageServers, 0, sizeof(ConnectionInfo) * nMaxServerCount);

	memcpy(returned_group_name, in_buff, FDFS_GROUP_NAME_MAX_LEN);
	p = in_buff + FDFS_GROUP_NAME_MAX_LEN;
	*(returned_group_name + FDFS_GROUP_NAME_MAX_LEN) = '\0';

	pServerEnd = storageServers + (*storage_count);
	for (pStorageServer=storageServers; pStorageServer<pServerEnd; \
		pStorageServer++)
	{
		pStorageServer->sock = -1;
		memcpy(pStorageServer->ip_addr, p, IP_ADDRESS_SIZE - 1);
		p += IP_ADDRESS_SIZE - 1;

		pStorageServer->port = (int)buff2long(p);
		p += FDFS_PROTO_PKG_LEN_SIZE;
	}

	*store_path_index = *p;

	return 0;
}
Exemple #8
0
int tracker_query_storage_store_with_group(ConnectionInfo *pTrackerServer, \
		const char *group_name, ConnectionInfo *pStorageServer, \
		int *store_path_index)
{
	TrackerHeader *pHeader;
	ConnectionInfo *conn;
	bool new_connection;
	char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN];
	char in_buff[sizeof(TrackerHeader) + \
		TRACKER_QUERY_STORAGE_STORE_BODY_LEN];
	char *pInBuff;
	int64_t in_bytes;
	int result;

	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	memset(pStorageServer, 0, sizeof(ConnectionInfo));
	pStorageServer->sock = -1;

	pHeader = (TrackerHeader *)out_buff;
	memset(out_buff, 0, sizeof(out_buff));
	snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
			sizeof(TrackerHeader),  "%s", group_name);
	
	long2buff(FDFS_GROUP_NAME_MAX_LEN, pHeader->pkg_len);
	pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE;
	if ((result=tcpsenddata_nb(conn->sock, out_buff, \
			sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, \
			g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = in_buff;
		result = fdfs_recv_response(conn, \
				&pInBuff, sizeof(in_buff), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		return result;
	}

	if (in_bytes != TRACKER_QUERY_STORAGE_STORE_BODY_LEN)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid, " \
			"expect length: %d", __LINE__, \
			pTrackerServer->ip_addr, pTrackerServer->port, \
			in_bytes, TRACKER_QUERY_STORAGE_STORE_BODY_LEN);
		return EINVAL;
	}

	memcpy(pStorageServer->ip_addr, in_buff + \
			FDFS_GROUP_NAME_MAX_LEN, IP_ADDRESS_SIZE-1);
	pStorageServer->port = (int)buff2long(in_buff + \
				FDFS_GROUP_NAME_MAX_LEN + IP_ADDRESS_SIZE - 1);
	*store_path_index = *(in_buff + FDFS_GROUP_NAME_MAX_LEN + \
			 IP_ADDRESS_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE);

	return 0;
}
Exemple #9
0
int tracker_query_storage_list(ConnectionInfo *pTrackerServer, \
		ConnectionInfo *pStorageServer, const int nMaxServerCount, \
		int *server_count, char *group_name, const char *filename)
{
	TrackerHeader *pHeader;
	ConnectionInfo *pServer;
	ConnectionInfo *pServerEnd;
	ConnectionInfo *conn;
	bool new_connection;
	char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + 128];
	char in_buff[sizeof(TrackerHeader) + \
		TRACKER_QUERY_STORAGE_FETCH_BODY_LEN + \
		FDFS_MAX_SERVERS_EACH_GROUP * IP_ADDRESS_SIZE];
	char *pInBuff;
	int64_t in_bytes;
	int result;
	int filename_len;

	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	memset(out_buff, 0, sizeof(out_buff));
	pHeader = (TrackerHeader *)out_buff;
	snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
			sizeof(TrackerHeader),  "%s", group_name);
	filename_len = snprintf(out_buff + sizeof(TrackerHeader) + \
			FDFS_GROUP_NAME_MAX_LEN, \
			sizeof(out_buff) - sizeof(TrackerHeader) - \
			FDFS_GROUP_NAME_MAX_LEN,  "%s", filename);
	
	long2buff(FDFS_GROUP_NAME_MAX_LEN + filename_len, pHeader->pkg_len);
	pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL;
	if ((result=tcpsenddata_nb(conn->sock, out_buff, \
		sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + 
		filename_len, g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = in_buff;
		result = fdfs_recv_response(conn, \
				&pInBuff, sizeof(in_buff), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		return result;
	}

	if ((in_bytes - TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) % \
		(IP_ADDRESS_SIZE - 1) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, in_bytes);
		return EINVAL;
	}

	*server_count = 1 + (in_bytes - TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) /
			(IP_ADDRESS_SIZE - 1);
	if (nMaxServerCount < *server_count)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response storage server " \
			 "count: %d, exceeds max server count: %d!", __LINE__, \
			pTrackerServer->ip_addr, pTrackerServer->port, \
			*server_count, nMaxServerCount);
		return ENOSPC;
	}

	memset(pStorageServer, 0, nMaxServerCount * sizeof(ConnectionInfo));
	pStorageServer->sock = -1;

	memcpy(group_name, pInBuff, FDFS_GROUP_NAME_MAX_LEN);
	*(group_name + FDFS_GROUP_NAME_MAX_LEN) = '\0';
	pInBuff += FDFS_GROUP_NAME_MAX_LEN;
	memcpy(pStorageServer->ip_addr, pInBuff, IP_ADDRESS_SIZE - 1);
	pInBuff += IP_ADDRESS_SIZE - 1;
	pStorageServer->port = (int)buff2long(pInBuff);
	pInBuff += FDFS_PROTO_PKG_LEN_SIZE;

	pServerEnd = pStorageServer + (*server_count);
	for (pServer=pStorageServer+1; pServer<pServerEnd; pServer++)
	{
		pServer->sock = -1;
		pServer->port = pStorageServer->port;
		memcpy(pServer->ip_addr, pInBuff, IP_ADDRESS_SIZE - 1);
		pInBuff += IP_ADDRESS_SIZE - 1;
	}

	return 0;
}
Exemple #10
0
int tracker_list_groups(ConnectionInfo *pTrackerServer, \
		FDFSGroupStat *group_stats, const int max_groups, \
		int *group_count)
{
	bool new_connection;
	TrackerHeader header;
	TrackerGroupStat stats[FDFS_MAX_GROUPS];
	char *pInBuff;
	ConnectionInfo *conn;
	TrackerGroupStat *pSrc;
	TrackerGroupStat *pEnd;
	FDFSGroupStat *pDest;
	int result;
	int64_t in_bytes;

	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	memset(&header, 0, sizeof(header));
	header.cmd = TRACKER_PROTO_CMD_SERVER_LIST_ALL_GROUPS;
	header.status = 0;
	if ((result=tcpsenddata_nb(conn->sock, &header, \
			sizeof(header), g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = (char *)stats;
		result = fdfs_recv_response(conn, \
			&pInBuff, sizeof(stats), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		*group_count = 0;
		return result;
	}

	if (in_bytes % sizeof(TrackerGroupStat) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, in_bytes);
		*group_count = 0;
		return EINVAL;
	}

	*group_count = in_bytes / sizeof(TrackerGroupStat);
	if (*group_count > max_groups)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d insufficent space, " \
			"max group count: %d, expect count: %d", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, max_groups, *group_count);
		*group_count = 0;
		return ENOSPC;
	}

	memset(group_stats, 0, sizeof(FDFSGroupStat) * max_groups);
	pDest = group_stats;
	pEnd = stats + (*group_count);
	for (pSrc=stats; pSrc<pEnd; pSrc++)
	{
		memcpy(pDest->group_name, pSrc->group_name, \
				FDFS_GROUP_NAME_MAX_LEN);
		pDest->total_mb = buff2long(pSrc->sz_total_mb);
		pDest->free_mb = buff2long(pSrc->sz_free_mb);
		pDest->trunk_free_mb = buff2long(pSrc->sz_trunk_free_mb);
		pDest->count= buff2long(pSrc->sz_count);
		pDest->storage_port= buff2long(pSrc->sz_storage_port);
		pDest->storage_http_port= buff2long(pSrc->sz_storage_http_port);
		pDest->active_count = buff2long(pSrc->sz_active_count);
		pDest->current_write_server = buff2long( \
				pSrc->sz_current_write_server);
		pDest->store_path_count = buff2long( \
				pSrc->sz_store_path_count);
		pDest->subdir_count_per_path = buff2long( \
				pSrc->sz_subdir_count_per_path);
		pDest->current_trunk_file_id = buff2long( \
				pSrc->sz_current_trunk_file_id);

		pDest++;
	}

	return 0;
}
Exemple #11
0
int tracker_list_one_group(ConnectionInfo *pTrackerServer, \
		const char *group_name, FDFSGroupStat *pDest)
{
	TrackerHeader *pHeader;
	ConnectionInfo *conn;
	bool new_connection;
	char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN];
	TrackerGroupStat src;
	char *pInBuff;
	int result;
	int64_t in_bytes;

	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	memset(out_buff, 0, sizeof(out_buff));
	pHeader = (TrackerHeader *)out_buff;
	snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
			sizeof(TrackerHeader),  "%s", group_name);
	pHeader->cmd = TRACKER_PROTO_CMD_SERVER_LIST_ONE_GROUP;
	long2buff(FDFS_GROUP_NAME_MAX_LEN, pHeader->pkg_len);
	if ((result=tcpsenddata_nb(conn->sock, out_buff, \
			sizeof(out_buff), g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = (char *)&src;
		result = fdfs_recv_response(conn, \
			&pInBuff, sizeof(TrackerGroupStat), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		return result;
	}

	if (in_bytes != sizeof(TrackerGroupStat))
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, in_bytes);
		return EINVAL;
	}

	memset(pDest, 0, sizeof(FDFSGroupStat));
	memcpy(pDest->group_name, src.group_name, FDFS_GROUP_NAME_MAX_LEN);
	pDest->total_mb = buff2long(src.sz_total_mb);
	pDest->free_mb = buff2long(src.sz_free_mb);
	pDest->trunk_free_mb = buff2long(src.sz_trunk_free_mb);
	pDest->count= buff2long(src.sz_count);
	pDest->storage_port= buff2long(src.sz_storage_port);
	pDest->storage_http_port= buff2long(src.sz_storage_http_port);
	pDest->active_count = buff2long(src.sz_active_count);
	pDest->current_write_server = buff2long(src.sz_current_write_server);
	pDest->store_path_count = buff2long(src.sz_store_path_count);
	pDest->subdir_count_per_path = buff2long(src.sz_subdir_count_per_path);
	pDest->current_trunk_file_id = buff2long(src.sz_current_trunk_file_id);

	return 0;
}
Exemple #12
0
int tracker_list_servers(ConnectionInfo *pTrackerServer, \
		const char *szGroupName, const char *szStorageId, \
		FDFSStorageInfo *storage_infos, const int max_storages, \
		int *storage_count)
{
	char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \
			IP_ADDRESS_SIZE];
	bool new_connection;
	TrackerHeader *pHeader;
	ConnectionInfo *conn;
	int result;
	int name_len;
	int id_len;
	TrackerStorageStat stats[FDFS_MAX_GROUPS];
	char *pInBuff;
	TrackerStorageStat *pSrc;
	TrackerStorageStat *pEnd;
	FDFSStorageStat *pStorageStat;
	FDFSStorageInfo *pDest;
	FDFSStorageStatBuff *pStatBuff;
	int64_t in_bytes;

	CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);

	memset(out_buff, 0, sizeof(out_buff));
	pHeader = (TrackerHeader *)out_buff;
	name_len = strlen(szGroupName);
	if (name_len > FDFS_GROUP_NAME_MAX_LEN)
	{
		name_len = FDFS_GROUP_NAME_MAX_LEN;
	}
	memcpy(out_buff + sizeof(TrackerHeader), szGroupName, name_len);

	if (szStorageId == NULL)
	{
		id_len = 0;
	}
	else
	{
		id_len = strlen(szStorageId);
		if (id_len >= FDFS_STORAGE_ID_MAX_SIZE)
		{
			id_len = FDFS_STORAGE_ID_MAX_SIZE - 1;
		}

		memcpy(out_buff+sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN,\
			szStorageId, id_len);
	}

	long2buff(FDFS_GROUP_NAME_MAX_LEN + id_len, pHeader->pkg_len);
	pHeader->cmd = TRACKER_PROTO_CMD_SERVER_LIST_STORAGE;
	if ((result=tcpsenddata_nb(conn->sock, out_buff, \
		sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + id_len, \
		g_fdfs_network_timeout)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
		        "send data to tracker server %s:%d fail, " \
			"errno: %d, error info: %s", __LINE__, \
			pTrackerServer->ip_addr, \
			pTrackerServer->port, \
			result, STRERROR(result));
	}
	else
	{
		pInBuff = (char *)stats;
		result = fdfs_recv_response(conn, &pInBuff, \
					sizeof(stats), &in_bytes);
	}

	if (new_connection)
	{
		tracker_disconnect_server_ex(conn, result != 0);
	}

	if (result != 0)
	{
		*storage_count = 0;
		return result;
	}

	if (in_bytes % sizeof(TrackerStorageStat) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"tracker server %s:%d response data " \
			"length: %"PRId64" is invalid", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, in_bytes);
		*storage_count = 0;
		return EINVAL;
	}

	*storage_count = in_bytes / sizeof(TrackerStorageStat);
	if (*storage_count > max_storages)
	{
		logError("file: "__FILE__", line: %d, " \
		 	"tracker server %s:%d insufficent space, " \
			"max storage count: %d, expect count: %d", \
			__LINE__, pTrackerServer->ip_addr, \
			pTrackerServer->port, max_storages, *storage_count);
		*storage_count = 0;
		return ENOSPC;
	}

	memset(storage_infos, 0, sizeof(FDFSStorageInfo) * max_storages);
	pDest = storage_infos;
	pEnd = stats + (*storage_count);
	for (pSrc=stats; pSrc<pEnd; pSrc++)
	{
		pStatBuff = &(pSrc->stat_buff);
		pStorageStat = &(pDest->stat);

		pDest->status = pSrc->status;
		memcpy(pDest->id, pSrc->id, FDFS_STORAGE_ID_MAX_SIZE - 1);
		memcpy(pDest->ip_addr, pSrc->ip_addr, IP_ADDRESS_SIZE - 1);
		memcpy(pDest->src_id, pSrc->src_id, \
			FDFS_STORAGE_ID_MAX_SIZE - 1);
		strcpy(pDest->domain_name, pSrc->domain_name);
		strcpy(pDest->version, pSrc->version);
		pDest->join_time = buff2long(pSrc->sz_join_time);
		pDest->up_time = buff2long(pSrc->sz_up_time);
		pDest->total_mb = buff2long(pSrc->sz_total_mb);
		pDest->free_mb = buff2long(pSrc->sz_free_mb);
		pDest->upload_priority = buff2long(pSrc->sz_upload_priority);
		pDest->store_path_count = buff2long(pSrc->sz_store_path_count);
		pDest->subdir_count_per_path = buff2long( \
					pSrc->sz_subdir_count_per_path);
		pDest->storage_port = buff2long(pSrc->sz_storage_port);
		pDest->storage_http_port = buff2long(pSrc->sz_storage_http_port);
		pDest->current_write_path = buff2long( \
					pSrc->sz_current_write_path);

		pStorageStat->total_upload_count = buff2long( \
			pStatBuff->sz_total_upload_count);
		pStorageStat->success_upload_count = buff2long( \
			pStatBuff->sz_success_upload_count);
		pStorageStat->total_append_count = buff2long( \
			pStatBuff->sz_total_append_count);
		pStorageStat->success_append_count = buff2long( \
			pStatBuff->sz_success_append_count);
		pStorageStat->total_modify_count = buff2long( \
			pStatBuff->sz_total_modify_count);
		pStorageStat->success_modify_count = buff2long( \
			pStatBuff->sz_success_modify_count);
		pStorageStat->total_truncate_count = buff2long( \
			pStatBuff->sz_total_truncate_count);
		pStorageStat->success_truncate_count = buff2long( \
			pStatBuff->sz_success_truncate_count);
		pStorageStat->total_set_meta_count = buff2long( \
			pStatBuff->sz_total_set_meta_count);
		pStorageStat->success_set_meta_count = buff2long( \
			pStatBuff->sz_success_set_meta_count);
		pStorageStat->total_delete_count = buff2long( \
			pStatBuff->sz_total_delete_count);
		pStorageStat->success_delete_count = buff2long( \
			pStatBuff->sz_success_delete_count);
		pStorageStat->total_download_count = buff2long( \
			pStatBuff->sz_total_download_count);
		pStorageStat->success_download_count = buff2long( \
			pStatBuff->sz_success_download_count);
		pStorageStat->total_get_meta_count = buff2long( \
			pStatBuff->sz_total_get_meta_count);
		pStorageStat->success_get_meta_count = buff2long( \
			pStatBuff->sz_success_get_meta_count);
		pStorageStat->last_source_update = buff2long( \
			pStatBuff->sz_last_source_update);
		pStorageStat->last_sync_update = buff2long( \
			pStatBuff->sz_last_sync_update);
		pStorageStat->last_synced_timestamp = buff2long( \
			pStatBuff->sz_last_synced_timestamp);
		pStorageStat->total_create_link_count = buff2long( \
			pStatBuff->sz_total_create_link_count);
		pStorageStat->success_create_link_count = buff2long( \
			pStatBuff->sz_success_create_link_count);
		pStorageStat->total_delete_link_count = buff2long( \
			pStatBuff->sz_total_delete_link_count);
		pStorageStat->success_delete_link_count = buff2long( \
			pStatBuff->sz_success_delete_link_count);
		pStorageStat->total_upload_bytes = buff2long( \
			pStatBuff->sz_total_upload_bytes);
		pStorageStat->success_upload_bytes = buff2long( \
			pStatBuff->sz_success_upload_bytes);
		pStorageStat->total_append_bytes = buff2long( \
			pStatBuff->sz_total_append_bytes);
		pStorageStat->success_append_bytes = buff2long( \
			pStatBuff->sz_success_append_bytes);
		pStorageStat->total_modify_bytes = buff2long( \
			pStatBuff->sz_total_modify_bytes);
		pStorageStat->success_modify_bytes = buff2long( \
			pStatBuff->sz_success_modify_bytes);
		pStorageStat->total_download_bytes = buff2long( \
			pStatBuff->sz_total_download_bytes);
		pStorageStat->success_download_bytes = buff2long( \
			pStatBuff->sz_success_download_bytes);
		pStorageStat->total_sync_in_bytes = buff2long( \
			pStatBuff->sz_total_sync_in_bytes);
		pStorageStat->success_sync_in_bytes = buff2long( \
			pStatBuff->sz_success_sync_in_bytes);
		pStorageStat->total_sync_out_bytes = buff2long( \
			pStatBuff->sz_total_sync_out_bytes);
		pStorageStat->success_sync_out_bytes = buff2long( \
			pStatBuff->sz_success_sync_out_bytes);
		pStorageStat->total_file_open_count = buff2long( \
			pStatBuff->sz_total_file_open_count);
		pStorageStat->success_file_open_count = buff2long( \
			pStatBuff->sz_success_file_open_count);
		pStorageStat->total_file_read_count = buff2long( \
			pStatBuff->sz_total_file_read_count);
		pStorageStat->success_file_read_count = buff2long( \
			pStatBuff->sz_success_file_read_count);
		pStorageStat->total_file_write_count = buff2long( \
			pStatBuff->sz_total_file_write_count);
		pStorageStat->success_file_write_count = buff2long( \
			pStatBuff->sz_success_file_write_count);
		pStorageStat->last_heart_beat_time = buff2long( \
			pStatBuff->sz_last_heart_beat_time);
		pDest->if_trunk_server = pSrc->if_trunk_server;
		pDest++;
	}

	return 0;
}