1658 lines
45 KiB
C
Executable File
1658 lines
45 KiB
C
Executable File
/**
|
|
* Copyright (C) 2008 Happy Fish / YuQing
|
|
*
|
|
* FastDFS may be copied only under the terms of the GNU General
|
|
* Public License V3, which may be found in the FastDFS source kit.
|
|
* Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
|
|
**/
|
|
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include "fdfs_define.h"
|
|
#include "fastcommon/logger.h"
|
|
#include "fastcommon/shared_func.h"
|
|
#include "fdfs_global.h"
|
|
#include "fastcommon/sockopt.h"
|
|
#include "tracker_types.h"
|
|
#include "tracker_proto.h"
|
|
#include "tracker_client.h"
|
|
#include "client_global.h"
|
|
|
|
int tracker_get_all_connections_ex(TrackerServerGroup *pTrackerGroup)
|
|
{
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
ConnectionInfo *conn;
|
|
int result;
|
|
int success_count;
|
|
|
|
success_count = 0;
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
if ((conn=tracker_connect_server_no_pool(pServer, &result)) != NULL)
|
|
{
|
|
fdfs_active_test(conn);
|
|
success_count++;
|
|
}
|
|
}
|
|
|
|
return success_count > 0 ? 0 : ENOTCONN;
|
|
}
|
|
|
|
void tracker_close_all_connections_ex(TrackerServerGroup *pTrackerGroup)
|
|
{
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
tracker_disconnect_server_no_pool(pServer);
|
|
}
|
|
}
|
|
|
|
ConnectionInfo *tracker_get_connection_ex(TrackerServerGroup *pTrackerGroup)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo *pCurrentServer;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
int server_index;
|
|
int result;
|
|
|
|
server_index = pTrackerGroup->server_index;
|
|
if (server_index >= pTrackerGroup->server_count)
|
|
{
|
|
server_index = 0;
|
|
}
|
|
|
|
do
|
|
{
|
|
pCurrentServer = pTrackerGroup->servers + server_index;
|
|
if ((conn=tracker_connect_server(pCurrentServer, &result)) != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pCurrentServer+1; pServer<pEnd; pServer++)
|
|
{
|
|
if ((conn=tracker_connect_server(pServer, &result)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer -
|
|
pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (conn != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for (pServer=pTrackerGroup->servers; pServer<pCurrentServer; pServer++)
|
|
{
|
|
if ((conn=tracker_connect_server(pServer, &result)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer -
|
|
pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
} while (0);
|
|
|
|
pTrackerGroup->server_index++;
|
|
if (pTrackerGroup->server_index >= pTrackerGroup->server_count)
|
|
{
|
|
pTrackerGroup->server_index = 0;
|
|
}
|
|
|
|
return conn;
|
|
}
|
|
|
|
ConnectionInfo *tracker_get_connection_no_pool(TrackerServerGroup *pTrackerGroup)
|
|
{
|
|
TrackerServerInfo *pCurrentServer;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
ConnectionInfo *conn;
|
|
int server_index;
|
|
int result;
|
|
|
|
server_index = pTrackerGroup->server_index;
|
|
if (server_index >= pTrackerGroup->server_count)
|
|
{
|
|
server_index = 0;
|
|
}
|
|
|
|
conn = NULL;
|
|
do
|
|
{
|
|
pCurrentServer = pTrackerGroup->servers + server_index;
|
|
if ((conn=tracker_connect_server_no_pool(pCurrentServer, &result)) != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pCurrentServer+1; pServer<pEnd; pServer++)
|
|
{
|
|
if ((conn=tracker_connect_server_no_pool(pServer, &result)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer - pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (conn != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for (pServer=pTrackerGroup->servers; pServer<pCurrentServer; pServer++)
|
|
{
|
|
if ((conn=tracker_connect_server_no_pool(pServer, &result)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer - pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
} while (0);
|
|
|
|
pTrackerGroup->server_index++;
|
|
if (pTrackerGroup->server_index >= pTrackerGroup->server_count)
|
|
{
|
|
pTrackerGroup->server_index = 0;
|
|
}
|
|
|
|
return conn;
|
|
}
|
|
|
|
ConnectionInfo *tracker_get_connection_r_ex(TrackerServerGroup *pTrackerGroup,
|
|
TrackerServerInfo *pTrackerServer, int *err_no)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo *pCurrentServer;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
int server_index;
|
|
|
|
server_index = pTrackerGroup->server_index;
|
|
if (server_index >= pTrackerGroup->server_count)
|
|
{
|
|
server_index = 0;
|
|
}
|
|
|
|
do
|
|
{
|
|
pCurrentServer = pTrackerGroup->servers + server_index;
|
|
memcpy(pTrackerServer, pCurrentServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(pTrackerServer);
|
|
if ((conn=tracker_connect_server(pTrackerServer, err_no)) != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pCurrentServer+1; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(pTrackerServer, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(pTrackerServer);
|
|
if ((conn=tracker_connect_server(pTrackerServer, err_no)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer -
|
|
pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (conn != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for (pServer=pTrackerGroup->servers; pServer<pCurrentServer; pServer++)
|
|
{
|
|
memcpy(pTrackerServer, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(pTrackerServer);
|
|
if ((conn=tracker_connect_server(pTrackerServer, err_no)) != NULL)
|
|
{
|
|
pTrackerGroup->server_index = pServer -
|
|
pTrackerGroup->servers;
|
|
break;
|
|
}
|
|
}
|
|
} while (0);
|
|
|
|
pTrackerGroup->server_index++;
|
|
if (pTrackerGroup->server_index >= pTrackerGroup->server_count)
|
|
{
|
|
pTrackerGroup->server_index = 0;
|
|
}
|
|
|
|
return conn;
|
|
}
|
|
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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->connection.alloc_count = buff2int( \
|
|
pStatBuff->connection.sz_alloc_count);
|
|
pStorageStat->connection.current_count = buff2int( \
|
|
pStatBuff->connection.sz_current_count);
|
|
pStorageStat->connection.max_count = buff2int( \
|
|
pStatBuff->connection.sz_max_count);
|
|
|
|
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;
|
|
}
|
|
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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;
|
|
}
|
|
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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;
|
|
}
|
|
|
|
int tracker_do_query_storage(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const byte cmd, \
|
|
const char *group_name, const char *filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
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];
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
int result;
|
|
int filename_len;
|
|
|
|
CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);
|
|
|
|
memset(pStorageServer, 0, sizeof(ConnectionInfo));
|
|
pStorageServer->sock = -1;
|
|
|
|
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 = cmd;
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(conn, result != 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (in_bytes != TRACKER_QUERY_STORAGE_FETCH_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_FETCH_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);
|
|
return 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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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;
|
|
}
|
|
|
|
int tracker_query_storage_store_without_group(ConnectionInfo *pTrackerServer,
|
|
ConnectionInfo *pStorageServer, char *group_name,
|
|
int *store_path_index)
|
|
{
|
|
TrackerHeader header;
|
|
char in_buff[sizeof(TrackerHeader) + \
|
|
TRACKER_QUERY_STORAGE_STORE_BODY_LEN];
|
|
bool new_connection;
|
|
ConnectionInfo *conn;
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
int result;
|
|
|
|
CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);
|
|
|
|
memset(pStorageServer, 0, sizeof(ConnectionInfo));
|
|
pStorageServer->sock = -1;
|
|
|
|
memset(&header, 0, sizeof(header));
|
|
header.cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE;
|
|
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 = in_buff;
|
|
result = fdfs_recv_response(conn, \
|
|
&pInBuff, sizeof(in_buff), &in_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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(group_name, in_buff, FDFS_GROUP_NAME_MAX_LEN);
|
|
*(group_name + FDFS_GROUP_NAME_MAX_LEN) = '\0';
|
|
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;
|
|
}
|
|
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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;
|
|
}
|
|
|
|
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 (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_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;
|
|
}
|
|
|
|
int tracker_delete_storage(TrackerServerGroup *pTrackerGroup, \
|
|
const char *group_name, const char *storage_id)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerHeader *pHeader;
|
|
TrackerServerInfo tracker_server;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
FDFSStorageInfo storage_infos[1];
|
|
char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \
|
|
FDFS_STORAGE_ID_MAX_SIZE];
|
|
char in_buff[1];
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
int result;
|
|
int storage_id_len;
|
|
int storage_count;
|
|
int enoent_count;
|
|
|
|
enoent_count = 0;
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(&tracker_server, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(&tracker_server);
|
|
if ((conn=tracker_connect_server(&tracker_server, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = tracker_list_servers(conn, group_name, storage_id, \
|
|
storage_infos, 1, &storage_count);
|
|
tracker_close_connection_ex(conn, result != 0 && result != ENOENT);
|
|
if (result != 0 && result != ENOENT)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (result == ENOENT || storage_count == 0)
|
|
{
|
|
enoent_count++;
|
|
continue;
|
|
}
|
|
|
|
if (storage_infos[0].status == FDFS_STORAGE_STATUS_ONLINE
|
|
|| storage_infos[0].status == FDFS_STORAGE_STATUS_ACTIVE)
|
|
{
|
|
return EBUSY;
|
|
}
|
|
}
|
|
if (enoent_count == pTrackerGroup->server_count)
|
|
{
|
|
return ENOENT;
|
|
}
|
|
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
|
|
sizeof(TrackerHeader), "%s", group_name);
|
|
storage_id_len = snprintf(out_buff + sizeof(TrackerHeader) + \
|
|
FDFS_GROUP_NAME_MAX_LEN, \
|
|
sizeof(out_buff) - sizeof(TrackerHeader) - \
|
|
FDFS_GROUP_NAME_MAX_LEN, "%s", storage_id);
|
|
|
|
long2buff(FDFS_GROUP_NAME_MAX_LEN + storage_id_len, pHeader->pkg_len);
|
|
pHeader->cmd = TRACKER_PROTO_CMD_SERVER_DELETE_STORAGE;
|
|
|
|
enoent_count = 0;
|
|
result = 0;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(&tracker_server, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(&tracker_server);
|
|
if ((conn=tracker_connect_server(&tracker_server, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if ((result=tcpsenddata_nb(conn->sock, out_buff, \
|
|
sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN +
|
|
storage_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__,
|
|
conn->ip_addr, conn->port,
|
|
result, STRERROR(result));
|
|
}
|
|
else
|
|
{
|
|
pInBuff = in_buff;
|
|
result = fdfs_recv_response(conn, &pInBuff, 0, &in_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
tracker_close_connection_ex(conn, result != 0 && result != ENOENT);
|
|
if (result != 0)
|
|
{
|
|
if (result == ENOENT)
|
|
{
|
|
enoent_count++;
|
|
}
|
|
else if (result == EALREADY)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (enoent_count == pTrackerGroup->server_count)
|
|
{
|
|
return ENOENT;
|
|
}
|
|
|
|
return result == ENOENT ? 0 : result;
|
|
}
|
|
|
|
int tracker_delete_group(TrackerServerGroup *pTrackerGroup, \
|
|
const char *group_name)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerHeader *pHeader;
|
|
TrackerServerInfo tracker_server;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN];
|
|
char in_buff[1];
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
int result;
|
|
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
pHeader = (TrackerHeader *)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_SERVER_DELETE_GROUP;
|
|
|
|
result = 0;
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(&tracker_server, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(&tracker_server);
|
|
if ((conn=tracker_connect_server(&tracker_server, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
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__,
|
|
conn->ip_addr, conn->port,
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
result = fdfs_recv_response(conn, &pInBuff, 0, &in_bytes);
|
|
tracker_close_connection_ex(conn, result != 0 && result != ENOENT);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int tracker_set_trunk_server(TrackerServerGroup *pTrackerGroup, \
|
|
const char *group_name, const char *storage_id, \
|
|
char *new_trunk_server_id)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
TrackerServerInfo tracker_server;
|
|
char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \
|
|
FDFS_STORAGE_ID_MAX_SIZE];
|
|
char in_buff[FDFS_STORAGE_ID_MAX_SIZE];
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
int result;
|
|
int storage_id_len;
|
|
|
|
*new_trunk_server_id = '\0';
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
memset(in_buff, 0, sizeof(in_buff));
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \
|
|
sizeof(TrackerHeader), "%s", group_name);
|
|
if (storage_id == NULL)
|
|
{
|
|
storage_id_len = 0;
|
|
}
|
|
else
|
|
{
|
|
storage_id_len = snprintf(out_buff + sizeof(TrackerHeader) + \
|
|
FDFS_GROUP_NAME_MAX_LEN, \
|
|
sizeof(out_buff) - sizeof(TrackerHeader) - \
|
|
FDFS_GROUP_NAME_MAX_LEN, "%s", storage_id);
|
|
}
|
|
|
|
long2buff(FDFS_GROUP_NAME_MAX_LEN + storage_id_len, pHeader->pkg_len);
|
|
pHeader->cmd = TRACKER_PROTO_CMD_SERVER_SET_TRUNK_SERVER;
|
|
|
|
result = 0;
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(&tracker_server, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(&tracker_server);
|
|
if ((conn=tracker_connect_server(&tracker_server, &result)) == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ((result=tcpsenddata_nb(conn->sock, out_buff, \
|
|
sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN +
|
|
storage_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__,
|
|
conn->ip_addr, conn->port,
|
|
result, STRERROR(result));
|
|
|
|
tracker_close_connection_ex(conn, true);
|
|
continue;
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
result = fdfs_recv_response(conn, &pInBuff,
|
|
sizeof(in_buff) - 1, &in_bytes);
|
|
|
|
tracker_close_connection_ex(conn, result != 0);
|
|
if (result == 0)
|
|
{
|
|
strcpy(new_trunk_server_id, in_buff);
|
|
return 0;
|
|
}
|
|
|
|
if (result == EOPNOTSUPP)
|
|
{
|
|
continue;
|
|
}
|
|
if (result == EALREADY)
|
|
{
|
|
if (storage_id_len > 0)
|
|
{
|
|
strcpy(new_trunk_server_id, storage_id);
|
|
}
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int tracker_get_storage_status(ConnectionInfo *pTrackerServer,
|
|
const char *group_name, const char *ip_addr,
|
|
FDFSStorageBrief *pDestBuff)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
ConnectionInfo *conn;
|
|
bool new_connection;
|
|
char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \
|
|
IP_ADDRESS_SIZE];
|
|
char *pInBuff;
|
|
char *p;
|
|
int result;
|
|
int ip_len;
|
|
int64_t in_bytes;
|
|
|
|
CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);
|
|
|
|
if (ip_addr == NULL)
|
|
{
|
|
ip_len = 0;
|
|
}
|
|
else
|
|
{
|
|
ip_len = strlen(ip_addr);
|
|
}
|
|
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
snprintf(p, sizeof(out_buff) - sizeof(TrackerHeader), "%s", group_name);
|
|
p += FDFS_GROUP_NAME_MAX_LEN;
|
|
if (ip_len > 0)
|
|
{
|
|
memcpy(p, ip_addr, ip_len);
|
|
p += ip_len;
|
|
}
|
|
pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_GET_STATUS;
|
|
long2buff(FDFS_GROUP_NAME_MAX_LEN + ip_len, pHeader->pkg_len);
|
|
if ((result=tcpsenddata_nb(conn->sock, out_buff, \
|
|
p - 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 *)pDestBuff;
|
|
result = fdfs_recv_response(conn, \
|
|
&pInBuff, sizeof(FDFSStorageBrief), &in_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(conn, result != 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (in_bytes != sizeof(FDFSStorageBrief))
|
|
{
|
|
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;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int tracker_get_storage_id(ConnectionInfo *pTrackerServer, \
|
|
const char *group_name, const char *ip_addr, \
|
|
char *storage_id)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
ConnectionInfo *conn;
|
|
bool new_connection;
|
|
char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \
|
|
IP_ADDRESS_SIZE];
|
|
char *p;
|
|
int result;
|
|
int ip_len;
|
|
int64_t in_bytes;
|
|
|
|
if (storage_id == NULL)
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
CHECK_CONNECTION(pTrackerServer, conn, result, new_connection);
|
|
|
|
if (ip_addr == NULL)
|
|
{
|
|
ip_len = 0;
|
|
}
|
|
else
|
|
{
|
|
ip_len = strlen(ip_addr);
|
|
}
|
|
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
snprintf(p, sizeof(out_buff) - sizeof(TrackerHeader), "%s", group_name);
|
|
p += FDFS_GROUP_NAME_MAX_LEN;
|
|
if (ip_len > 0)
|
|
{
|
|
memcpy(p, ip_addr, ip_len);
|
|
p += ip_len;
|
|
}
|
|
pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_GET_SERVER_ID;
|
|
long2buff(FDFS_GROUP_NAME_MAX_LEN + ip_len, pHeader->pkg_len);
|
|
if ((result=tcpsenddata_nb(conn->sock, out_buff, \
|
|
p - 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
|
|
{
|
|
result = fdfs_recv_response(conn, \
|
|
&storage_id, FDFS_STORAGE_ID_MAX_SIZE, &in_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(conn, result != 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (in_bytes == 0 || in_bytes >= FDFS_STORAGE_ID_MAX_SIZE)
|
|
{
|
|
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_id + in_bytes) = '\0';
|
|
return 0;
|
|
}
|
|
|
|
int tracker_get_storage_max_status(TrackerServerGroup *pTrackerGroup, \
|
|
const char *group_name, const char *ip_addr, \
|
|
char *storage_id, int *status)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo tracker_server;
|
|
TrackerServerInfo *pServer;
|
|
TrackerServerInfo *pEnd;
|
|
FDFSStorageBrief storage_brief;
|
|
int result;
|
|
|
|
memset(&storage_brief, 0, sizeof(FDFSStorageBrief));
|
|
storage_brief.status = -1;
|
|
|
|
*storage_id = '\0';
|
|
*status = -1;
|
|
pEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
|
for (pServer=pTrackerGroup->servers; pServer<pEnd; pServer++)
|
|
{
|
|
memcpy(&tracker_server, pServer, sizeof(TrackerServerInfo));
|
|
fdfs_server_sock_reset(&tracker_server);
|
|
if ((conn=tracker_connect_server(&tracker_server, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = tracker_get_storage_status(conn, group_name, \
|
|
ip_addr, &storage_brief);
|
|
tracker_close_connection_ex(conn, result != 0);
|
|
|
|
if (result != 0)
|
|
{
|
|
if (result == ENOENT)
|
|
{
|
|
continue;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
strcpy(storage_id, storage_brief.id);
|
|
if (storage_brief.status > *status)
|
|
{
|
|
*status = storage_brief.status;
|
|
}
|
|
}
|
|
|
|
if (*status == -1)
|
|
{
|
|
return ENOENT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|