tracker support multi ip for storage server
parent
f60d96989a
commit
82e95ccee7
|
|
@ -12,7 +12,7 @@ CONFIG_PATH = $(TARGET_CONF_PATH)
|
|||
|
||||
FDFS_STATIC_OBJS = ../common/fdfs_global.o ../common/fdfs_http_shared.o \
|
||||
../common/mime_file_parser.o ../tracker/tracker_proto.o \
|
||||
../tracker/fdfs_shared_func.o \
|
||||
../tracker/fdfs_shared_func.o ../tracker/fdfs_server_id_func.o \
|
||||
../storage/trunk_mgr/trunk_shared.o \
|
||||
tracker_client.o client_func.o \
|
||||
client_global.o storage_client.o
|
||||
|
|
@ -21,7 +21,7 @@ STATIC_OBJS = $(FDFS_STATIC_OBJS)
|
|||
|
||||
FDFS_SHARED_OBJS = ../common/fdfs_global.lo ../common/fdfs_http_shared.lo \
|
||||
../common/mime_file_parser.lo ../tracker/tracker_proto.lo \
|
||||
../tracker/fdfs_shared_func.lo \
|
||||
../tracker/fdfs_shared_func.lo ../tracker/fdfs_server_id_func.lo \
|
||||
../storage/trunk_mgr/trunk_shared.lo \
|
||||
tracker_client.lo client_func.lo \
|
||||
client_global.lo storage_client.lo
|
||||
|
|
@ -29,7 +29,7 @@ FDFS_SHARED_OBJS = ../common/fdfs_global.lo ../common/fdfs_http_shared.lo \
|
|||
FDFS_HEADER_FILES = ../common/fdfs_define.h ../common/fdfs_global.h \
|
||||
../common/mime_file_parser.h ../common/fdfs_http_shared.h \
|
||||
../tracker/tracker_types.h ../tracker/tracker_proto.h \
|
||||
../tracker/fdfs_shared_func.h \
|
||||
../tracker/fdfs_shared_func.h ../tracker/fdfs_server_id_func.h \
|
||||
../storage/trunk_mgr/trunk_shared.h \
|
||||
tracker_client.h storage_client.h storage_client1.h \
|
||||
client_func.h client_global.h fdfs_client.h
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ static int fdfs_client_do_init_ex(TrackerServerGroup *pTrackerGroup, \
|
|||
g_fdfs_network_timeout, pTrackerGroup->server_count, \
|
||||
g_anti_steal_token, g_anti_steal_secret_key.length, \
|
||||
g_use_connection_pool, g_connection_pool_max_idle_time, \
|
||||
use_storage_id, g_storage_id_count);
|
||||
use_storage_id, g_storage_ids_by_id.count);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2171,7 +2171,7 @@ int fdfs_get_file_info_ex(const char *group_name, const char *remote_filename, \
|
|||
if (fdfs_get_server_id_type(ip_addr.s_addr) == FDFS_ID_TYPE_SERVER_ID)
|
||||
{
|
||||
pFileInfo->source_id = ip_addr.s_addr;
|
||||
if (g_storage_ids_by_id != NULL && g_storage_id_count > 0)
|
||||
if (g_storage_ids_by_id.count > 0)
|
||||
{
|
||||
char id[16];
|
||||
FDFSStorageIdInfo *pStorageId;
|
||||
|
|
@ -2180,8 +2180,8 @@ int fdfs_get_file_info_ex(const char *group_name, const char *remote_filename, \
|
|||
pStorageId = fdfs_get_storage_by_id(id);
|
||||
if (pStorageId != NULL)
|
||||
{
|
||||
strcpy(pFileInfo->source_ip_addr, \
|
||||
pStorageId->ip_addr);
|
||||
strcpy(pFileInfo->source_ip_addr,
|
||||
pStorageId->ip_addrs.ips[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ LIB_PATH = $(LIBS) -lfastcommon
|
|||
TARGET_PATH = $(TARGET_PREFIX)/bin
|
||||
CONFIG_PATH = $(TARGET_CONF_PATH)
|
||||
|
||||
SHARED_OBJS = ../common/fdfs_global.o \
|
||||
../tracker/fdfs_shared_func.o ../tracker/tracker_proto.o \
|
||||
SHARED_OBJS = ../common/fdfs_global.o ../tracker/fdfs_shared_func.o \
|
||||
../tracker/fdfs_server_id_func.o ../tracker/tracker_proto.o \
|
||||
tracker_client_thread.o storage_global.o storage_func.o \
|
||||
storage_service.o storage_sync.o storage_nio.o storage_dio.o \
|
||||
storage_ip_changed_dealer.o storage_param_getter.o \
|
||||
|
|
|
|||
|
|
@ -3668,7 +3668,9 @@ static int storage_server_query_file_info(struct fast_task_info *pTask)
|
|||
pStorageIdInfo = fdfs_get_storage_by_id(id);
|
||||
if (pStorageIdInfo != NULL)
|
||||
{
|
||||
strcpy(p, pStorageIdInfo->ip_addr);
|
||||
strcpy(p, fdfs_get_ipaddr_by_client_ip(
|
||||
&pStorageIdInfo->ip_addrs,
|
||||
pTask->client_ip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ CONFIG_PATH = $(TARGET_CONF_PATH)
|
|||
|
||||
SHARED_OBJS = ../common/fdfs_global.o \
|
||||
tracker_proto.o tracker_mem.o tracker_service.o tracker_status.o \
|
||||
tracker_global.o tracker_func.o \
|
||||
tracker_global.o tracker_func.o fdfs_server_id_func.o \
|
||||
fdfs_shared_func.o tracker_nio.o tracker_relationship.o \
|
||||
$(TRACKER_EXTRA_OBJS)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,803 @@
|
|||
/**
|
||||
* 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.csource.org/ for more detail.
|
||||
**/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include "fastcommon/logger.h"
|
||||
#include "fastcommon/sockopt.h"
|
||||
#include "fastcommon/shared_func.h"
|
||||
#include "tracker_proto.h"
|
||||
#include "fdfs_global.h"
|
||||
#include "fdfs_shared_func.h"
|
||||
#include "fdfs_server_id_func.h"
|
||||
|
||||
FDFSStorageIdInfoArray g_storage_ids_by_id = {0, NULL}; //sorted by storage ID
|
||||
FDFSStorageIdMapArray g_storage_ids_by_ip = {0, NULL}; //sorted by group name and storage IP
|
||||
static FDFSStorageIdMapArray g_storage_ids_by_ip_port = {0, NULL}; //sorted by storage ip and port
|
||||
|
||||
bool fdfs_is_server_id_valid(const char *id)
|
||||
{
|
||||
long n;
|
||||
char *endptr;
|
||||
char buff[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
|
||||
if (*id == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
endptr = NULL;
|
||||
n = strtol(id, &endptr, 10);
|
||||
if (endptr != NULL && *endptr != '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n <= 0 || n > FDFS_MAX_SERVER_ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(buff, sizeof(buff), "%ld", n);
|
||||
return strcmp(buff, id) == 0;
|
||||
}
|
||||
|
||||
int fdfs_get_server_id_type(const int id)
|
||||
{
|
||||
if (id > 0 && id <= FDFS_MAX_SERVER_ID)
|
||||
{
|
||||
return FDFS_ID_TYPE_SERVER_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FDFS_ID_TYPE_IP_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
static int fdfs_cmp_group_name_and_ip(const void *p1, const void *p2)
|
||||
{
|
||||
int result;
|
||||
result = strcmp(((FDFSStorageIdMap *)p1)->group_name,
|
||||
((FDFSStorageIdMap *)p2)->group_name);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return strcmp(((FDFSStorageIdMap *)p1)->ip_addr,
|
||||
((FDFSStorageIdMap *)p2)->ip_addr);
|
||||
}
|
||||
|
||||
static int fdfs_cmp_server_id(const void *p1, const void *p2)
|
||||
{
|
||||
return strcmp((*((FDFSStorageIdInfo **)p1))->id,
|
||||
(*((FDFSStorageIdInfo **)p2))->id);
|
||||
}
|
||||
|
||||
static int fdfs_cmp_ip_and_port(const void *p1, const void *p2)
|
||||
{
|
||||
int result;
|
||||
result = strcmp(((FDFSStorageIdMap *)p1)->ip_addr,
|
||||
((FDFSStorageIdMap *)p2)->ip_addr);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return ((FDFSStorageIdMap *)p1)->port -
|
||||
((FDFSStorageIdMap *)p2)->port;
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name,
|
||||
const char *pIpAddr)
|
||||
{
|
||||
FDFSStorageIdMap target;
|
||||
FDFSStorageIdMap *pFound;
|
||||
|
||||
target.group_name = group_name;
|
||||
target.ip_addr = pIpAddr;
|
||||
target.port = 0;
|
||||
target.idInfo = NULL;
|
||||
pFound = (FDFSStorageIdMap *)bsearch(&target,
|
||||
g_storage_ids_by_ip.maps, g_storage_ids_by_ip.count,
|
||||
sizeof(FDFSStorageIdMap), fdfs_cmp_group_name_and_ip);
|
||||
if (pFound == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pFound->idInfo;
|
||||
}
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id)
|
||||
{
|
||||
FDFSStorageIdInfo target;
|
||||
|
||||
memset(&target, 0, sizeof(FDFSStorageIdInfo));
|
||||
snprintf(target.id, sizeof(target.id), "%s", id);
|
||||
return (FDFSStorageIdInfo *)bsearch(&target,
|
||||
g_storage_ids_by_id.ids, g_storage_ids_by_id.count,
|
||||
sizeof(FDFSStorageIdInfo), fdfs_cmp_server_id);
|
||||
}
|
||||
|
||||
static int fdfs_calc_ip_count()
|
||||
{
|
||||
FDFSStorageIdInfo *idInfo;
|
||||
FDFSStorageIdInfo *idEnd;
|
||||
int ip_count;
|
||||
|
||||
ip_count = 0;
|
||||
idEnd = g_storage_ids_by_id.ids + g_storage_ids_by_id.count;
|
||||
for (idInfo=g_storage_ids_by_id.ids; idInfo<idEnd; idInfo++)
|
||||
{
|
||||
ip_count += idInfo->ip_addrs.count;
|
||||
}
|
||||
|
||||
return ip_count;
|
||||
}
|
||||
|
||||
static int fdfs_init_ip_array(FDFSStorageIdMapArray *mapArray,
|
||||
int (*compare_func)(const void *, const void *))
|
||||
{
|
||||
int result;
|
||||
int i;
|
||||
int alloc_bytes;
|
||||
FDFSStorageIdMap *idMap;
|
||||
FDFSStorageIdInfo *idInfo;
|
||||
FDFSStorageIdInfo *idEnd;
|
||||
|
||||
mapArray->count = fdfs_calc_ip_count();
|
||||
alloc_bytes = sizeof(FDFSStorageIdMap) * mapArray->count;
|
||||
mapArray->maps = (FDFSStorageIdMap *)malloc(alloc_bytes);
|
||||
if (mapArray->maps == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"malloc %d bytes fail, "
|
||||
"errno: %d, error info: %s", __LINE__,
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
return result;
|
||||
}
|
||||
memset(mapArray->maps, 0, alloc_bytes);
|
||||
|
||||
idEnd = g_storage_ids_by_id.ids + g_storage_ids_by_id.count;
|
||||
idMap = mapArray->maps;
|
||||
for (idInfo=g_storage_ids_by_id.ids; idInfo<idEnd; idInfo++)
|
||||
{
|
||||
for (i=0; i<idInfo->ip_addrs.count; i++)
|
||||
{
|
||||
idMap->idInfo = idInfo;
|
||||
idMap->group_name = idInfo->group_name;
|
||||
idMap->ip_addr = idInfo->ip_addrs.ips[i];
|
||||
idMap->port = idInfo->port;
|
||||
idMap++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(mapArray->maps, mapArray->count,
|
||||
sizeof(FDFSStorageIdMap), compare_func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fdfs_check_ip_port()
|
||||
{
|
||||
int i;
|
||||
int port_count;
|
||||
FDFSStorageIdMap *previous;
|
||||
FDFSStorageIdMap *current;
|
||||
FDFSStorageIdMap *end;
|
||||
|
||||
port_count = 0;
|
||||
for (i=0; i<g_storage_ids_by_id.count; i++)
|
||||
{
|
||||
if (g_storage_ids_by_id.ids[i].port > 0)
|
||||
{
|
||||
port_count++;
|
||||
}
|
||||
}
|
||||
if (port_count > 0 && port_count != g_storage_ids_by_id.count)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: storage_ids.conf, "
|
||||
"some storages without port, "
|
||||
"must be the same format as host:port", __LINE__);
|
||||
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
previous = g_storage_ids_by_ip_port.maps + 0;
|
||||
end = g_storage_ids_by_ip_port.maps + g_storage_ids_by_ip_port.count;
|
||||
for (current=g_storage_ids_by_ip_port.maps+1; current<end; current++)
|
||||
{
|
||||
if (fdfs_cmp_ip_and_port(current, previous) == 0)
|
||||
{
|
||||
char szPortPart[16];
|
||||
if (previous->port > 0)
|
||||
{
|
||||
sprintf(szPortPart, ":%d", previous->port);
|
||||
}
|
||||
else
|
||||
{
|
||||
*szPortPart = '\0';
|
||||
}
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: storage_ids.conf, "
|
||||
"duplicate storage: %s%s", __LINE__,
|
||||
previous->ip_addr, szPortPart);
|
||||
|
||||
free(g_storage_ids_by_ip_port.maps);
|
||||
g_storage_ids_by_ip_port.maps = NULL;
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
previous = current;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip_port(const char *pIpAddr,
|
||||
const int port)
|
||||
{
|
||||
FDFSStorageIdMap target;
|
||||
FDFSStorageIdMap *pFound;
|
||||
int ports[2];
|
||||
int i;
|
||||
|
||||
target.ip_addr = pIpAddr;
|
||||
target.group_name = NULL;
|
||||
target.idInfo = NULL;
|
||||
ports[0] = port;
|
||||
ports[1] = 0;
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
target.port = ports[i];
|
||||
pFound = (FDFSStorageIdMap *)bsearch(&target,
|
||||
g_storage_ids_by_ip_port.maps,
|
||||
g_storage_ids_by_ip_port.count,
|
||||
sizeof(FDFSStorageIdMap), fdfs_cmp_ip_and_port);
|
||||
if (pFound != NULL)
|
||||
{
|
||||
return pFound->idInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fdfs_check_storage_id(const char *group_name, const char *id)
|
||||
{
|
||||
FDFSStorageIdInfo *pFound;
|
||||
|
||||
pFound = fdfs_get_storage_by_id(id);
|
||||
if (pFound == NULL)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
return strcmp(pFound->group_name, group_name) == 0 ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
|
||||
{
|
||||
char **lines;
|
||||
char *line;
|
||||
char *id;
|
||||
char *group_name;
|
||||
char *pHost;
|
||||
char *pPort;
|
||||
FDFSStorageIdInfo *pStorageIdInfo;
|
||||
char error_info[256];
|
||||
int alloc_bytes;
|
||||
int result;
|
||||
int line_count;
|
||||
int i;
|
||||
|
||||
lines = split(content, '\n', 0, &line_count);
|
||||
if (lines == NULL)
|
||||
{
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
do
|
||||
{
|
||||
g_storage_ids_by_id.count = 0;
|
||||
for (i=0; i<line_count; i++)
|
||||
{
|
||||
trim(lines[i]);
|
||||
if (*lines[i] == '\0' || *lines[i] == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
g_storage_ids_by_id.count++;
|
||||
}
|
||||
|
||||
if (g_storage_ids_by_id.count == 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, no storage id!", \
|
||||
__LINE__, pStorageIdsFilename);
|
||||
result = ENOENT;
|
||||
break;
|
||||
}
|
||||
|
||||
alloc_bytes = sizeof(FDFSStorageIdInfo) * g_storage_ids_by_id.count;
|
||||
g_storage_ids_by_id.ids = (FDFSStorageIdInfo *)malloc(alloc_bytes);
|
||||
if (g_storage_ids_by_id.ids == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", __LINE__, \
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
break;
|
||||
}
|
||||
memset(g_storage_ids_by_id.ids, 0, alloc_bytes);
|
||||
|
||||
pStorageIdInfo = g_storage_ids_by_id.ids;
|
||||
for (i=0; i<line_count; i++)
|
||||
{
|
||||
line = lines[i];
|
||||
if (*line == '\0' || *line == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
id = line;
|
||||
group_name = line;
|
||||
while (!(*group_name == ' ' || *group_name == '\t' \
|
||||
|| *group_name == '\0'))
|
||||
{
|
||||
group_name++;
|
||||
}
|
||||
|
||||
if (*group_name == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, line no: %d, " \
|
||||
"content: %s, invalid format, " \
|
||||
"expect group name and ip address!", \
|
||||
__LINE__, pStorageIdsFilename, \
|
||||
i + 1, line);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
*group_name = '\0';
|
||||
group_name++; //skip space char
|
||||
while (*group_name == ' ' || *group_name == '\t')
|
||||
{
|
||||
group_name++;
|
||||
}
|
||||
|
||||
pHost = group_name;
|
||||
while (!(*pHost == ' ' || *pHost == '\t' \
|
||||
|| *pHost == '\0'))
|
||||
{
|
||||
pHost++;
|
||||
}
|
||||
|
||||
if (*pHost == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, line no: %d, " \
|
||||
"content: %s, invalid format, " \
|
||||
"expect ip address!", __LINE__, \
|
||||
pStorageIdsFilename, i + 1, line);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
*pHost = '\0';
|
||||
pHost++; //skip space char
|
||||
while (*pHost == ' ' || *pHost == '\t')
|
||||
{
|
||||
pHost++;
|
||||
}
|
||||
|
||||
pPort = strchr(pHost, ':');
|
||||
if (pPort != NULL)
|
||||
{
|
||||
*pPort = '\0';
|
||||
pStorageIdInfo->port = atoi(pPort + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pStorageIdInfo->port = 0;
|
||||
}
|
||||
|
||||
if ((result=fdfs_parse_multi_ips(pHost, &pStorageIdInfo->ip_addrs,
|
||||
error_info, sizeof(error_info))) != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: %s, line no: %d, %s", __LINE__,
|
||||
pStorageIdsFilename, i + 1, error_info);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((result=fdfs_check_and_format_ips(&pStorageIdInfo->ip_addrs,
|
||||
error_info, sizeof(error_info))) != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: %s, line no: %d, %s", __LINE__,
|
||||
pStorageIdsFilename, i + 1, error_info);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fdfs_is_server_id_valid(id))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"invalid server id: \"%s\", " \
|
||||
"which must be a none zero start " \
|
||||
"integer, such as 100001", __LINE__, id);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(pStorageIdInfo->id,
|
||||
sizeof(pStorageIdInfo->id), "%s", id);
|
||||
snprintf(pStorageIdInfo->group_name,
|
||||
sizeof(pStorageIdInfo->group_name),
|
||||
"%s", group_name);
|
||||
pStorageIdInfo++;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
freeSplit(lines);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (g_log_context.log_level >= LOG_DEBUG)
|
||||
{
|
||||
logDebug("file: "__FILE__", line: %d, "
|
||||
"g_storage_ids_by_id.count: %d",
|
||||
__LINE__, g_storage_ids_by_id.count);
|
||||
|
||||
pStorageIdInfo = g_storage_ids_by_id.ids;
|
||||
for (i=0; i<g_storage_ids_by_id.count; i++)
|
||||
{
|
||||
char szPortPart[16];
|
||||
char ip_str[256];
|
||||
if (pStorageIdInfo->port > 0)
|
||||
{
|
||||
sprintf(szPortPart, ":%d", pStorageIdInfo->port);
|
||||
}
|
||||
else
|
||||
{
|
||||
*szPortPart = '\0';
|
||||
}
|
||||
|
||||
fdfs_multi_ips_to_string(&pStorageIdInfo->ip_addrs,
|
||||
ip_str, sizeof(ip_str));
|
||||
logDebug("%s %s %s%s", pStorageIdInfo->id,
|
||||
pStorageIdInfo->group_name, ip_str, szPortPart);
|
||||
|
||||
pStorageIdInfo++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(g_storage_ids_by_id.ids, g_storage_ids_by_id.count,
|
||||
sizeof(FDFSStorageIdInfo), fdfs_cmp_server_id);
|
||||
|
||||
if ((result=fdfs_init_ip_array(&g_storage_ids_by_ip,
|
||||
fdfs_cmp_group_name_and_ip)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if ((result=fdfs_init_ip_array(&g_storage_ids_by_ip_port,
|
||||
fdfs_cmp_ip_and_port)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return fdfs_check_ip_port();
|
||||
}
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_server(TrackerServerInfo *pTrackerServer)
|
||||
{
|
||||
#define MAX_REQUEST_LOOP 32
|
||||
TrackerHeader *pHeader;
|
||||
ConnectionInfo *conn;
|
||||
char out_buff[sizeof(TrackerHeader) + sizeof(int)];
|
||||
char *p;
|
||||
char *response;
|
||||
struct data_info {
|
||||
char *buffer; //for free
|
||||
char *content;
|
||||
int length;
|
||||
} data_list[MAX_REQUEST_LOOP];
|
||||
int list_count;
|
||||
int total_count;
|
||||
int current_count;
|
||||
int result;
|
||||
int i;
|
||||
int start_index;
|
||||
int64_t in_bytes;
|
||||
|
||||
if ((conn=tracker_connect_server(pTrackerServer, &result)) == NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
memset(data_list, 0, sizeof(data_list));
|
||||
memset(out_buff, 0, sizeof(out_buff));
|
||||
pHeader = (TrackerHeader *)out_buff;
|
||||
p = out_buff + sizeof(TrackerHeader);
|
||||
pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_FETCH_STORAGE_IDS;
|
||||
long2buff(sizeof(int), pHeader->pkg_len);
|
||||
|
||||
start_index = 0;
|
||||
list_count = 0;
|
||||
result = 0;
|
||||
while (1)
|
||||
{
|
||||
int2buff(start_index, p);
|
||||
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__,
|
||||
conn->ip_addr, conn->port,
|
||||
result, STRERROR(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
response = NULL;
|
||||
result = fdfs_recv_response(conn, &response, 0, &in_bytes);
|
||||
if (result != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"fdfs_recv_response fail, result: %d",
|
||||
__LINE__, result);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (in_bytes < 2 * sizeof(int))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, recv data length: %d "
|
||||
"is invalid", __LINE__,
|
||||
conn->ip_addr, conn->port, (int)in_bytes);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
total_count = buff2int(response);
|
||||
current_count = buff2int(response + sizeof(int));
|
||||
if (total_count <= start_index)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, total storage "
|
||||
"count: %d is invalid, which <= start "
|
||||
"index: %d", __LINE__, conn->ip_addr,
|
||||
conn->port, total_count, start_index);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_count <= 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, current storage "
|
||||
"count: %d is invalid, which <= 0", __LINE__,
|
||||
conn->ip_addr, conn->port, current_count);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data_list[list_count].buffer = response;
|
||||
data_list[list_count].content = response + 2 * sizeof(int);
|
||||
data_list[list_count].length = in_bytes - 2 * sizeof(int);
|
||||
list_count++;
|
||||
|
||||
/*
|
||||
//logInfo("list_count: %d, total_count: %d, current_count: %d",
|
||||
list_count, total_count, current_count);
|
||||
*/
|
||||
|
||||
start_index += current_count;
|
||||
if (start_index >= total_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (list_count == MAX_REQUEST_LOOP)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"response data from tracker " \
|
||||
"server %s:%d is too large", \
|
||||
__LINE__, conn->ip_addr,\
|
||||
conn->port);
|
||||
result = ENOSPC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tracker_close_connection_ex(conn, result != 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
int total_length;
|
||||
char *content;
|
||||
|
||||
total_length = 0;
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
total_length += data_list[i].length;
|
||||
}
|
||||
|
||||
content = (char *)malloc(total_length + 1);
|
||||
if (content == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, total_length + 1, \
|
||||
result, STRERROR(result));
|
||||
break;
|
||||
}
|
||||
|
||||
p = content;
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
memcpy(p, data_list[i].content, data_list[i].length);
|
||||
p += data_list[i].length;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
//logInfo("list_count: %d, storage ids:\n%s", list_count, content);
|
||||
|
||||
result = fdfs_load_storage_ids(content, \
|
||||
"storage-ids-from-tracker");
|
||||
free(content);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
free(data_list[i].buffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_group(TrackerServerGroup *pTrackerGroup)
|
||||
{
|
||||
TrackerServerInfo *pGServer;
|
||||
TrackerServerInfo *pTServer;
|
||||
TrackerServerInfo *pServerStart;
|
||||
TrackerServerInfo *pServerEnd;
|
||||
TrackerServerInfo trackerServer;
|
||||
int result;
|
||||
int leader_index;
|
||||
int i;
|
||||
|
||||
pTServer = &trackerServer;
|
||||
pServerEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
||||
|
||||
leader_index = pTrackerGroup->leader_index;
|
||||
if (leader_index >= 0)
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers + leader_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers;
|
||||
}
|
||||
|
||||
result = ENOENT;
|
||||
for (i=0; i<5; i++)
|
||||
{
|
||||
for (pGServer=pServerStart; pGServer<pServerEnd; pGServer++)
|
||||
{
|
||||
memcpy(pTServer, pGServer, sizeof(TrackerServerInfo));
|
||||
fdfs_server_sock_reset(pTServer);
|
||||
result = fdfs_get_storage_ids_from_tracker_server(pTServer);
|
||||
if (result == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (pServerStart != pTrackerGroup->servers)
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_load_storage_ids_from_file(const char *config_filename, \
|
||||
IniContext *pItemContext)
|
||||
{
|
||||
char *pStorageIdsFilename;
|
||||
char *content;
|
||||
int64_t file_size;
|
||||
int result;
|
||||
|
||||
pStorageIdsFilename = iniGetStrValue(NULL, "storage_ids_filename", \
|
||||
pItemContext);
|
||||
if (pStorageIdsFilename == NULL)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf file \"%s\" must have item " \
|
||||
"\"storage_ids_filename\"!", __LINE__, config_filename);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (*pStorageIdsFilename == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf file \"%s\", storage_ids_filename is emtpy!", \
|
||||
__LINE__, config_filename);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (*pStorageIdsFilename == '/') //absolute path
|
||||
{
|
||||
result = getFileContent(pStorageIdsFilename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *lastSlash = strrchr(config_filename, '/');
|
||||
if (lastSlash == NULL)
|
||||
{
|
||||
result = getFileContent(pStorageIdsFilename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
char filepath[MAX_PATH_SIZE];
|
||||
char full_filename[MAX_PATH_SIZE];
|
||||
int len;
|
||||
|
||||
len = lastSlash - config_filename;
|
||||
if (len >= sizeof(filepath))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf filename: \"%s\" is too long!", \
|
||||
__LINE__, config_filename);
|
||||
return ENOSPC;
|
||||
}
|
||||
memcpy(filepath, config_filename, len);
|
||||
*(filepath + len) = '\0';
|
||||
snprintf(full_filename, sizeof(full_filename), \
|
||||
"%s/%s", filepath, pStorageIdsFilename);
|
||||
result = getFileContent(full_filename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
}
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fdfs_load_storage_ids(content, pStorageIdsFilename);
|
||||
free(content);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* 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.csource.org/ for more detail.
|
||||
**/
|
||||
|
||||
//fdfs_server_id_func.h
|
||||
|
||||
#ifndef _FDFS_SERVER_ID_FUNC_H
|
||||
#define _FDFS_SERVER_ID_FUNC_H
|
||||
|
||||
#include "fastcommon/common_define.h"
|
||||
#include "fastcommon/ini_file_reader.h"
|
||||
#include "fastcommon/logger.h"
|
||||
#include "tracker_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char id[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
char group_name[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes alignment
|
||||
FDFSMultiIP ip_addrs;
|
||||
int port; //since v5.05
|
||||
} FDFSStorageIdInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *group_name;
|
||||
const char *ip_addr;
|
||||
int port;
|
||||
FDFSStorageIdInfo *idInfo;
|
||||
} FDFSStorageIdMap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
FDFSStorageIdInfo *ids;
|
||||
} FDFSStorageIdInfoArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
FDFSStorageIdMap *maps;
|
||||
} FDFSStorageIdMapArray;
|
||||
|
||||
extern FDFSStorageIdInfoArray g_storage_ids_by_id; //sorted by storage ID
|
||||
extern FDFSStorageIdMapArray g_storage_ids_by_ip; //sorted by group name and storage IP
|
||||
|
||||
bool fdfs_is_server_id_valid(const char *id);
|
||||
|
||||
int fdfs_get_server_id_type(const int id);
|
||||
|
||||
int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \
|
||||
const char *pIpAddr);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip_port(const char *pIpAddr,
|
||||
const int port);
|
||||
|
||||
int fdfs_check_storage_id(const char *group_name, const char *id);
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_server(TrackerServerInfo *pTrackerServer);
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_group(TrackerServerGroup *pTrackerGroup);
|
||||
|
||||
int fdfs_load_storage_ids_from_file(const char *config_filename, \
|
||||
IniContext *pItemContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -17,12 +17,6 @@
|
|||
#include "fdfs_global.h"
|
||||
#include "fdfs_shared_func.h"
|
||||
|
||||
FDFSStorageIdInfo *g_storage_ids_by_ip = NULL; //sorted by group name and storage IP
|
||||
FDFSStorageIdInfo **g_storage_ids_by_id = NULL; //sorted by storage ID
|
||||
static FDFSStorageIdInfo **g_storage_ids_by_ip_port = NULL; //sorted by storage ip and port
|
||||
|
||||
int g_storage_id_count = 0;
|
||||
|
||||
bool fdfs_server_contain(TrackerServerInfo *pServerInfo,
|
||||
const char *target_ip, const int target_port)
|
||||
{
|
||||
|
|
@ -359,749 +353,6 @@ bool fdfs_check_reserved_space_path(const int64_t total_mb, \
|
|||
}
|
||||
}
|
||||
|
||||
bool fdfs_is_server_id_valid(const char *id)
|
||||
{
|
||||
long n;
|
||||
char *endptr;
|
||||
char buff[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
|
||||
if (*id == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
endptr = NULL;
|
||||
n = strtol(id, &endptr, 10);
|
||||
if (endptr != NULL && *endptr != '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n <= 0 || n > FDFS_MAX_SERVER_ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(buff, sizeof(buff), "%ld", n);
|
||||
return strcmp(buff, id) == 0;
|
||||
}
|
||||
|
||||
int fdfs_get_server_id_type(const int id)
|
||||
{
|
||||
if (id > 0 && id <= FDFS_MAX_SERVER_ID)
|
||||
{
|
||||
return FDFS_ID_TYPE_SERVER_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FDFS_ID_TYPE_IP_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
static int fdfs_cmp_group_name_and_ip(const void *p1, const void *p2)
|
||||
{
|
||||
int result;
|
||||
result = strcmp(((FDFSStorageIdInfo *)p1)->group_name,
|
||||
((FDFSStorageIdInfo *)p2)->group_name);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return strcmp(((FDFSStorageIdInfo *)p1)->ip_addr, \
|
||||
((FDFSStorageIdInfo *)p2)->ip_addr);
|
||||
}
|
||||
|
||||
static int fdfs_cmp_server_id(const void *p1, const void *p2)
|
||||
{
|
||||
return strcmp((*((FDFSStorageIdInfo **)p1))->id, \
|
||||
(*((FDFSStorageIdInfo **)p2))->id);
|
||||
}
|
||||
|
||||
static int fdfs_cmp_ip_and_port(const void *p1, const void *p2)
|
||||
{
|
||||
int result;
|
||||
result = strcmp((*((FDFSStorageIdInfo **)p1))->ip_addr,
|
||||
(*((FDFSStorageIdInfo **)p2))->ip_addr);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return (*((FDFSStorageIdInfo **)p1))->port -
|
||||
(*((FDFSStorageIdInfo **)p2))->port;
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \
|
||||
const char *pIpAddr)
|
||||
{
|
||||
FDFSStorageIdInfo target;
|
||||
memset(&target, 0, sizeof(FDFSStorageIdInfo));
|
||||
snprintf(target.group_name, sizeof(target.group_name), "%s", group_name);
|
||||
snprintf(target.ip_addr, sizeof(target.ip_addr), "%s", pIpAddr);
|
||||
return (FDFSStorageIdInfo *)bsearch(&target, g_storage_ids_by_ip, \
|
||||
g_storage_id_count, sizeof(FDFSStorageIdInfo), \
|
||||
fdfs_cmp_group_name_and_ip);
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id)
|
||||
{
|
||||
FDFSStorageIdInfo target;
|
||||
FDFSStorageIdInfo *pTarget;
|
||||
FDFSStorageIdInfo **ppFound;
|
||||
|
||||
memset(&target, 0, sizeof(FDFSStorageIdInfo));
|
||||
snprintf(target.id, sizeof(target.id), "%s", id);
|
||||
pTarget = ⌖
|
||||
ppFound = (FDFSStorageIdInfo **)bsearch(&pTarget, g_storage_ids_by_id, \
|
||||
g_storage_id_count, sizeof(FDFSStorageIdInfo *), \
|
||||
fdfs_cmp_server_id);
|
||||
if (ppFound == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *ppFound;
|
||||
}
|
||||
}
|
||||
|
||||
static int fdfs_init_ip_port_array()
|
||||
{
|
||||
int result;
|
||||
int alloc_bytes;
|
||||
int i;
|
||||
int port_count;
|
||||
FDFSStorageIdInfo *previous;
|
||||
|
||||
alloc_bytes = sizeof(FDFSStorageIdInfo *) * g_storage_id_count;
|
||||
g_storage_ids_by_ip_port = (FDFSStorageIdInfo **)malloc(alloc_bytes);
|
||||
if (g_storage_ids_by_ip_port == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", __LINE__, \
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
port_count = 0;
|
||||
for (i=0; i<g_storage_id_count; i++)
|
||||
{
|
||||
g_storage_ids_by_ip_port[i] = g_storage_ids_by_ip + i;
|
||||
if (g_storage_ids_by_ip_port[i]->port > 0)
|
||||
{
|
||||
port_count++;
|
||||
}
|
||||
}
|
||||
if (port_count > 0 && port_count != g_storage_id_count)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: storage_ids.conf, some storages without port, "
|
||||
"must be the same format as host:port", __LINE__);
|
||||
|
||||
free(g_storage_ids_by_ip_port);
|
||||
g_storage_ids_by_ip_port = NULL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
qsort(g_storage_ids_by_ip_port, g_storage_id_count,
|
||||
sizeof(FDFSStorageIdInfo *), fdfs_cmp_ip_and_port);
|
||||
|
||||
previous = g_storage_ids_by_ip_port[0];
|
||||
for (i=1; i<g_storage_id_count; i++)
|
||||
{
|
||||
if (fdfs_cmp_ip_and_port(&g_storage_ids_by_ip_port[i],
|
||||
&previous) == 0)
|
||||
{
|
||||
char szPortPart[16];
|
||||
if (previous->port > 0)
|
||||
{
|
||||
sprintf(szPortPart, ":%d", previous->port);
|
||||
}
|
||||
else
|
||||
{
|
||||
*szPortPart = '\0';
|
||||
}
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: storage_ids.conf, "
|
||||
"duplicate storage: %s%s", __LINE__,
|
||||
previous->ip_addr, szPortPart);
|
||||
|
||||
free(g_storage_ids_by_ip_port);
|
||||
g_storage_ids_by_ip_port = NULL;
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
previous = g_storage_ids_by_ip_port[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip_port(const char *pIpAddr,
|
||||
const int port)
|
||||
{
|
||||
FDFSStorageIdInfo target;
|
||||
FDFSStorageIdInfo *pTarget;
|
||||
FDFSStorageIdInfo **ppFound;
|
||||
int ports[2];
|
||||
int i;
|
||||
|
||||
if (g_storage_ids_by_ip_port == NULL)
|
||||
{
|
||||
if (fdfs_init_ip_port_array() != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pTarget = ⌖
|
||||
memset(&target, 0, sizeof(FDFSStorageIdInfo));
|
||||
snprintf(target.ip_addr, sizeof(target.ip_addr), "%s", pIpAddr);
|
||||
ports[0] = port;
|
||||
ports[1] = 0;
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
target.port = ports[i];
|
||||
ppFound = (FDFSStorageIdInfo **)bsearch(&pTarget,
|
||||
g_storage_ids_by_ip_port, g_storage_id_count,
|
||||
sizeof(FDFSStorageIdInfo *), fdfs_cmp_ip_and_port);
|
||||
if (ppFound != NULL)
|
||||
{
|
||||
return *ppFound;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fdfs_check_storage_id(const char *group_name, const char *id)
|
||||
{
|
||||
FDFSStorageIdInfo *pFound;
|
||||
|
||||
pFound = fdfs_get_storage_by_id(id);
|
||||
if (pFound == NULL)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
return strcmp(pFound->group_name, group_name) == 0 ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
|
||||
{
|
||||
char **lines;
|
||||
char *line;
|
||||
char *id;
|
||||
char *group_name;
|
||||
char *pHost;
|
||||
char *pIpAddr;
|
||||
char *pPort;
|
||||
FDFSStorageIdInfo *pStorageIdInfo;
|
||||
FDFSStorageIdInfo **ppStorageIdInfo;
|
||||
FDFSStorageIdInfo **ppStorageIdEnd;
|
||||
int alloc_bytes;
|
||||
int result;
|
||||
int line_count;
|
||||
int i;
|
||||
|
||||
lines = split(content, '\n', 0, &line_count);
|
||||
if (lines == NULL)
|
||||
{
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
do
|
||||
{
|
||||
g_storage_id_count = 0;
|
||||
for (i=0; i<line_count; i++)
|
||||
{
|
||||
trim(lines[i]);
|
||||
if (*lines[i] == '\0' || *lines[i] == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
g_storage_id_count++;
|
||||
}
|
||||
|
||||
if (g_storage_id_count == 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, no storage id!", \
|
||||
__LINE__, pStorageIdsFilename);
|
||||
result = ENOENT;
|
||||
break;
|
||||
}
|
||||
|
||||
alloc_bytes = sizeof(FDFSStorageIdInfo) * g_storage_id_count;
|
||||
g_storage_ids_by_ip = (FDFSStorageIdInfo *)malloc(alloc_bytes);
|
||||
if (g_storage_ids_by_ip == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", __LINE__, \
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
break;
|
||||
}
|
||||
memset(g_storage_ids_by_ip, 0, alloc_bytes);
|
||||
|
||||
alloc_bytes = sizeof(FDFSStorageIdInfo *) * g_storage_id_count;
|
||||
g_storage_ids_by_id = (FDFSStorageIdInfo **)malloc(alloc_bytes);
|
||||
if (g_storage_ids_by_id == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", __LINE__, \
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
free(g_storage_ids_by_ip);
|
||||
break;
|
||||
}
|
||||
memset(g_storage_ids_by_id, 0, alloc_bytes);
|
||||
|
||||
pStorageIdInfo = g_storage_ids_by_ip;
|
||||
for (i=0; i<line_count; i++)
|
||||
{
|
||||
line = lines[i];
|
||||
if (*line == '\0' || *line == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
id = line;
|
||||
group_name = line;
|
||||
while (!(*group_name == ' ' || *group_name == '\t' \
|
||||
|| *group_name == '\0'))
|
||||
{
|
||||
group_name++;
|
||||
}
|
||||
|
||||
if (*group_name == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, line no: %d, " \
|
||||
"content: %s, invalid format, " \
|
||||
"expect group name and ip address!", \
|
||||
__LINE__, pStorageIdsFilename, \
|
||||
i + 1, line);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
*group_name = '\0';
|
||||
group_name++; //skip space char
|
||||
while (*group_name == ' ' || *group_name == '\t')
|
||||
{
|
||||
group_name++;
|
||||
}
|
||||
|
||||
pHost = group_name;
|
||||
while (!(*pHost == ' ' || *pHost == '\t' \
|
||||
|| *pHost == '\0'))
|
||||
{
|
||||
pHost++;
|
||||
}
|
||||
|
||||
if (*pHost == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"config file: %s, line no: %d, " \
|
||||
"content: %s, invalid format, " \
|
||||
"expect ip address!", __LINE__, \
|
||||
pStorageIdsFilename, i + 1, line);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
*pHost = '\0';
|
||||
pHost++; //skip space char
|
||||
while (*pHost == ' ' || *pHost == '\t')
|
||||
{
|
||||
pHost++;
|
||||
}
|
||||
|
||||
pIpAddr = pHost;
|
||||
pPort = strchr(pHost, ':');
|
||||
if (pPort != NULL)
|
||||
{
|
||||
*pPort = '\0';
|
||||
pStorageIdInfo->port = atoi(pPort + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pStorageIdInfo->port = 0;
|
||||
}
|
||||
if (getIpaddrByName(pIpAddr, pStorageIdInfo->ip_addr, \
|
||||
sizeof(pStorageIdInfo->ip_addr)) == INADDR_NONE)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"invalid host name: %s", __LINE__, pIpAddr);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fdfs_is_server_id_valid(id))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"invalid server id: \"%s\", " \
|
||||
"which must be a none zero start " \
|
||||
"integer, such as 100001", __LINE__, id);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(pStorageIdInfo->id, \
|
||||
sizeof(pStorageIdInfo->id), "%s", id);
|
||||
snprintf(pStorageIdInfo->group_name, \
|
||||
sizeof(pStorageIdInfo->group_name), \
|
||||
"%s", group_name);
|
||||
pStorageIdInfo++;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
freeSplit(lines);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
logDebug("file: "__FILE__", line: %d, " \
|
||||
"g_storage_id_count: %d", __LINE__, g_storage_id_count);
|
||||
pStorageIdInfo = g_storage_ids_by_ip;
|
||||
for (i=0; i<g_storage_id_count; i++)
|
||||
{
|
||||
char szPortPart[16];
|
||||
if (pStorageIdInfo->port > 0)
|
||||
{
|
||||
sprintf(szPortPart, ":%d", pStorageIdInfo->port);
|
||||
}
|
||||
else
|
||||
{
|
||||
*szPortPart = '\0';
|
||||
}
|
||||
logDebug("%s %s %s%s", pStorageIdInfo->id,
|
||||
pStorageIdInfo->group_name,
|
||||
pStorageIdInfo->ip_addr, szPortPart);
|
||||
|
||||
pStorageIdInfo++;
|
||||
}
|
||||
|
||||
ppStorageIdEnd = g_storage_ids_by_id + g_storage_id_count;
|
||||
pStorageIdInfo = g_storage_ids_by_ip;
|
||||
for (ppStorageIdInfo=g_storage_ids_by_id; ppStorageIdInfo < \
|
||||
ppStorageIdEnd; ppStorageIdInfo++)
|
||||
{
|
||||
*ppStorageIdInfo = pStorageIdInfo++;
|
||||
}
|
||||
|
||||
qsort(g_storage_ids_by_ip, g_storage_id_count, \
|
||||
sizeof(FDFSStorageIdInfo), fdfs_cmp_group_name_and_ip);
|
||||
qsort(g_storage_ids_by_id, g_storage_id_count, \
|
||||
sizeof(FDFSStorageIdInfo *), fdfs_cmp_server_id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_server(TrackerServerInfo *pTrackerServer)
|
||||
{
|
||||
#define MAX_REQUEST_LOOP 32
|
||||
TrackerHeader *pHeader;
|
||||
ConnectionInfo *conn;
|
||||
char out_buff[sizeof(TrackerHeader) + sizeof(int)];
|
||||
char *p;
|
||||
char *response;
|
||||
struct data_info {
|
||||
char *buffer; //for free
|
||||
char *content;
|
||||
int length;
|
||||
} data_list[MAX_REQUEST_LOOP];
|
||||
int list_count;
|
||||
int total_count;
|
||||
int current_count;
|
||||
int result;
|
||||
int i;
|
||||
int start_index;
|
||||
int64_t in_bytes;
|
||||
|
||||
if ((conn=tracker_connect_server(pTrackerServer, &result)) == NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
memset(data_list, 0, sizeof(data_list));
|
||||
memset(out_buff, 0, sizeof(out_buff));
|
||||
pHeader = (TrackerHeader *)out_buff;
|
||||
p = out_buff + sizeof(TrackerHeader);
|
||||
pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_FETCH_STORAGE_IDS;
|
||||
long2buff(sizeof(int), pHeader->pkg_len);
|
||||
|
||||
start_index = 0;
|
||||
list_count = 0;
|
||||
result = 0;
|
||||
while (1)
|
||||
{
|
||||
int2buff(start_index, p);
|
||||
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__,
|
||||
conn->ip_addr, conn->port,
|
||||
result, STRERROR(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
response = NULL;
|
||||
result = fdfs_recv_response(conn, &response, 0, &in_bytes);
|
||||
if (result != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"fdfs_recv_response fail, result: %d",
|
||||
__LINE__, result);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (in_bytes < 2 * sizeof(int))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, recv data length: %d "
|
||||
"is invalid", __LINE__,
|
||||
conn->ip_addr, conn->port, (int)in_bytes);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
total_count = buff2int(response);
|
||||
current_count = buff2int(response + sizeof(int));
|
||||
if (total_count <= start_index)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, total storage "
|
||||
"count: %d is invalid, which <= start "
|
||||
"index: %d", __LINE__, conn->ip_addr,
|
||||
conn->port, total_count, start_index);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_count <= 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"tracker server %s:%d, current storage "
|
||||
"count: %d is invalid, which <= 0", __LINE__,
|
||||
conn->ip_addr, conn->port, current_count);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data_list[list_count].buffer = response;
|
||||
data_list[list_count].content = response + 2 * sizeof(int);
|
||||
data_list[list_count].length = in_bytes - 2 * sizeof(int);
|
||||
list_count++;
|
||||
|
||||
/*
|
||||
//logInfo("list_count: %d, total_count: %d, current_count: %d",
|
||||
list_count, total_count, current_count);
|
||||
*/
|
||||
|
||||
start_index += current_count;
|
||||
if (start_index >= total_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (list_count == MAX_REQUEST_LOOP)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"response data from tracker " \
|
||||
"server %s:%d is too large", \
|
||||
__LINE__, conn->ip_addr,\
|
||||
conn->port);
|
||||
result = ENOSPC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tracker_close_connection_ex(conn, result != 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
int total_length;
|
||||
char *content;
|
||||
|
||||
total_length = 0;
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
total_length += data_list[i].length;
|
||||
}
|
||||
|
||||
content = (char *)malloc(total_length + 1);
|
||||
if (content == NULL)
|
||||
{
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, total_length + 1, \
|
||||
result, STRERROR(result));
|
||||
break;
|
||||
}
|
||||
|
||||
p = content;
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
memcpy(p, data_list[i].content, data_list[i].length);
|
||||
p += data_list[i].length;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
//logInfo("list_count: %d, storage ids:\n%s", list_count, content);
|
||||
|
||||
result = fdfs_load_storage_ids(content, \
|
||||
"storage-ids-from-tracker");
|
||||
free(content);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
for (i=0; i<list_count; i++)
|
||||
{
|
||||
free(data_list[i].buffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_group(TrackerServerGroup *pTrackerGroup)
|
||||
{
|
||||
TrackerServerInfo *pGServer;
|
||||
TrackerServerInfo *pTServer;
|
||||
TrackerServerInfo *pServerStart;
|
||||
TrackerServerInfo *pServerEnd;
|
||||
TrackerServerInfo trackerServer;
|
||||
int result;
|
||||
int leader_index;
|
||||
int i;
|
||||
|
||||
pTServer = &trackerServer;
|
||||
pServerEnd = pTrackerGroup->servers + pTrackerGroup->server_count;
|
||||
|
||||
leader_index = pTrackerGroup->leader_index;
|
||||
if (leader_index >= 0)
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers + leader_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers;
|
||||
}
|
||||
|
||||
result = ENOENT;
|
||||
for (i=0; i<5; i++)
|
||||
{
|
||||
for (pGServer=pServerStart; pGServer<pServerEnd; pGServer++)
|
||||
{
|
||||
memcpy(pTServer, pGServer, sizeof(TrackerServerInfo));
|
||||
fdfs_server_sock_reset(pTServer);
|
||||
result = fdfs_get_storage_ids_from_tracker_server(pTServer);
|
||||
if (result == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (pServerStart != pTrackerGroup->servers)
|
||||
{
|
||||
pServerStart = pTrackerGroup->servers;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_load_storage_ids_from_file(const char *config_filename, \
|
||||
IniContext *pItemContext)
|
||||
{
|
||||
char *pStorageIdsFilename;
|
||||
char *content;
|
||||
int64_t file_size;
|
||||
int result;
|
||||
|
||||
pStorageIdsFilename = iniGetStrValue(NULL, "storage_ids_filename", \
|
||||
pItemContext);
|
||||
if (pStorageIdsFilename == NULL)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf file \"%s\" must have item " \
|
||||
"\"storage_ids_filename\"!", __LINE__, config_filename);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (*pStorageIdsFilename == '\0')
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf file \"%s\", storage_ids_filename is emtpy!", \
|
||||
__LINE__, config_filename);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (*pStorageIdsFilename == '/') //absolute path
|
||||
{
|
||||
result = getFileContent(pStorageIdsFilename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *lastSlash = strrchr(config_filename, '/');
|
||||
if (lastSlash == NULL)
|
||||
{
|
||||
result = getFileContent(pStorageIdsFilename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
char filepath[MAX_PATH_SIZE];
|
||||
char full_filename[MAX_PATH_SIZE];
|
||||
int len;
|
||||
|
||||
len = lastSlash - config_filename;
|
||||
if (len >= sizeof(filepath))
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"conf filename: \"%s\" is too long!", \
|
||||
__LINE__, config_filename);
|
||||
return ENOSPC;
|
||||
}
|
||||
memcpy(filepath, config_filename, len);
|
||||
*(filepath + len) = '\0';
|
||||
snprintf(full_filename, sizeof(full_filename), \
|
||||
"%s/%s", filepath, pStorageIdsFilename);
|
||||
result = getFileContent(full_filename, \
|
||||
&content, &file_size);
|
||||
}
|
||||
}
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fdfs_load_storage_ids(content, pStorageIdsFilename);
|
||||
free(content);
|
||||
return result;
|
||||
}
|
||||
|
||||
int fdfs_connection_pool_init(const char *config_filename, \
|
||||
IniContext *pItemContext)
|
||||
{
|
||||
|
|
@ -1198,13 +449,18 @@ int fdfs_parse_server_info_ex(char *server_str, const int default_port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fdfs_server_info_to_string_ex(TrackerServerInfo *pServer,
|
||||
int fdfs_server_info_to_string_ex(const TrackerServerInfo *pServer,
|
||||
const int port, char *buff, const int buffSize)
|
||||
{
|
||||
ConnectionInfo *conn;
|
||||
ConnectionInfo *end;
|
||||
const ConnectionInfo *conn;
|
||||
const ConnectionInfo *end;
|
||||
int len;
|
||||
|
||||
if (pServer->count <= 0)
|
||||
{
|
||||
*buff = '\0';
|
||||
return 0;
|
||||
}
|
||||
if (pServer->count == 1)
|
||||
{
|
||||
return snprintf(buff, buffSize, "%s:%d",
|
||||
|
|
@ -1221,7 +477,7 @@ int fdfs_server_info_to_string_ex(TrackerServerInfo *pServer,
|
|||
return len;
|
||||
}
|
||||
|
||||
int fdfs_check_server_ips(TrackerServerInfo *pServer,
|
||||
int fdfs_check_server_ips(const TrackerServerInfo *pServer,
|
||||
char *error_info, const int error_size)
|
||||
{
|
||||
int private0;
|
||||
|
|
@ -1262,3 +518,126 @@ int fdfs_check_server_ips(TrackerServerInfo *pServer,
|
|||
*error_info = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdfs_parse_multi_ips_ex(char *ip_str, FDFSMultiIP *ip_addrs,
|
||||
char *error_info, const int error_size, const bool resolve)
|
||||
{
|
||||
char *hosts[FDFS_MULTI_IP_MAX_COUNT];
|
||||
int i;
|
||||
|
||||
ip_addrs->count = splitEx(ip_str, ',', hosts, FDFS_MULTI_IP_MAX_COUNT);
|
||||
for (i=0; i<ip_addrs->count; i++)
|
||||
{
|
||||
if (resolve)
|
||||
{
|
||||
if (getIpaddrByName(hosts[i], ip_addrs->ips[i],
|
||||
sizeof(ip_addrs->ips[i])) == INADDR_NONE)
|
||||
{
|
||||
snprintf(error_info, error_size,
|
||||
"host \"%s\" is invalid, error info: %s",
|
||||
hosts[i], hstrerror(h_errno));
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(ip_addrs->ips[i], sizeof(ip_addrs->ips[i]), "%s", hosts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
*error_info = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdfs_multi_ips_to_string_ex(const FDFSMultiIP *ip_addrs,
|
||||
const char seperator, char *buff, const int buffSize)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
|
||||
if (ip_addrs->count <= 0)
|
||||
{
|
||||
*buff = '\0';
|
||||
return 0;
|
||||
}
|
||||
if (ip_addrs->count == 1)
|
||||
{
|
||||
return snprintf(buff, buffSize, "%s",
|
||||
ip_addrs->ips[0]);
|
||||
}
|
||||
|
||||
len = snprintf(buff, buffSize, "%s", ip_addrs->ips[0]);
|
||||
for (i=1; i<ip_addrs->count; i++)
|
||||
{
|
||||
len += snprintf(buff + len, buffSize - len, "%c%s",
|
||||
seperator, ip_addrs->ips[i]);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *fdfs_get_ipaddr_by_client_ip(const FDFSMultiIP *ip_addrs,
|
||||
const char *client_ip)
|
||||
{
|
||||
int index;
|
||||
if (ip_addrs->count == 1)
|
||||
{
|
||||
return ip_addrs->ips[0];
|
||||
}
|
||||
|
||||
if (ip_addrs->count <= 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
index = is_private_ip(client_ip) ? FDFS_MULTI_IP_INDEX_INNER : FDFS_MULTI_IP_INDEX_OUTER;
|
||||
return ip_addrs->ips[index];
|
||||
}
|
||||
|
||||
int fdfs_check_and_format_ips(FDFSMultiIP *ip_addrs,
|
||||
char *error_info, const int error_size)
|
||||
{
|
||||
int privates[FDFS_MULTI_IP_MAX_COUNT];
|
||||
char swap_ip[IP_ADDRESS_SIZE];
|
||||
if (ip_addrs->count == 1)
|
||||
{
|
||||
*error_info = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ip_addrs->count <= 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"empty server", __LINE__);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (ip_addrs->count > FDFS_MULTI_IP_MAX_COUNT)
|
||||
{
|
||||
snprintf(error_info, error_size,
|
||||
"too many server ip addresses: %d, exceeds %d",
|
||||
ip_addrs->count, FDFS_MULTI_IP_MAX_COUNT);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
privates[0] = is_private_ip(ip_addrs->ips[0]) ? 1 : 0;
|
||||
privates[1] = is_private_ip(ip_addrs->ips[1]) ? 1 : 0;
|
||||
if ((privates[0] ^ privates[1]) == 0)
|
||||
{
|
||||
snprintf(error_info, error_size,
|
||||
"invalid ip addresses %s and %s, "
|
||||
"one MUST be an inner IP and another is a outer IP",
|
||||
ip_addrs->ips[0], ip_addrs->ips[1]);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (!privates[FDFS_MULTI_IP_INDEX_INNER])
|
||||
{
|
||||
strcpy(swap_ip, ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER]);
|
||||
strcpy(ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER],
|
||||
ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER]);
|
||||
strcpy(ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER], swap_ip);
|
||||
}
|
||||
|
||||
*error_info = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,12 @@
|
|||
#include "fastcommon/ini_file_reader.h"
|
||||
#include "fastcommon/logger.h"
|
||||
#include "tracker_types.h"
|
||||
#include "fdfs_server_id_func.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern FDFSStorageIdInfo *g_storage_ids_by_ip; //sorted by group name and storage IP
|
||||
extern FDFSStorageIdInfo **g_storage_ids_by_id; //sorted by storage ID
|
||||
extern int g_storage_id_count; //storage id count
|
||||
|
||||
int fdfs_get_tracker_leader_index_ex(TrackerServerGroup *pServerGroup, \
|
||||
const char *leaderIp, const int leaderPort);
|
||||
|
||||
|
|
@ -50,29 +47,6 @@ bool fdfs_check_reserved_space_path(const int64_t total_mb, \
|
|||
const int64_t free_mb, const int avg_mb, \
|
||||
FDFSStorageReservedSpace *pStorageReservedSpace);
|
||||
|
||||
bool fdfs_is_server_id_valid(const char *id);
|
||||
|
||||
int fdfs_get_server_id_type(const int id);
|
||||
|
||||
int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \
|
||||
const char *pIpAddr);
|
||||
|
||||
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip_port(const char *pIpAddr,
|
||||
const int port);
|
||||
|
||||
int fdfs_check_storage_id(const char *group_name, const char *id);
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_server(TrackerServerInfo *pTrackerServer);
|
||||
|
||||
int fdfs_get_storage_ids_from_tracker_group(TrackerServerGroup *pTrackerGroup);
|
||||
|
||||
int fdfs_load_storage_ids_from_file(const char *config_filename, \
|
||||
IniContext *pItemContext);
|
||||
|
||||
int fdfs_connection_pool_init(const char *config_filename, \
|
||||
IniContext *pItemContext);
|
||||
|
||||
|
|
@ -108,19 +82,46 @@ static inline int fdfs_parse_server_info(char *server_str, const int default_por
|
|||
pServer, resolve);
|
||||
}
|
||||
|
||||
int fdfs_server_info_to_string_ex(TrackerServerInfo *pServer,
|
||||
int fdfs_server_info_to_string_ex(const TrackerServerInfo *pServer,
|
||||
const int port, char *buff, const int buffSize);
|
||||
|
||||
static inline int fdfs_server_info_to_string(TrackerServerInfo *pServer,
|
||||
static inline int fdfs_server_info_to_string(const TrackerServerInfo *pServer,
|
||||
char *buff, const int buffSize)
|
||||
{
|
||||
return fdfs_server_info_to_string_ex(pServer,
|
||||
pServer->connections[0].port, buff, buffSize);
|
||||
}
|
||||
|
||||
int fdfs_check_server_ips(TrackerServerInfo *pServer,
|
||||
int fdfs_multi_ips_to_string_ex(const FDFSMultiIP *ip_addrs,
|
||||
const char seperator, char *buff, const int buffSize);
|
||||
|
||||
static inline int fdfs_multi_ips_to_string(const FDFSMultiIP *ip_addrs,
|
||||
char *buff, const int buffSize)
|
||||
{
|
||||
const char seperator = ',';
|
||||
return fdfs_multi_ips_to_string_ex(ip_addrs, seperator, buff, buffSize);
|
||||
}
|
||||
|
||||
int fdfs_parse_multi_ips_ex(char *ip_str, FDFSMultiIP *ip_addrs,
|
||||
char *error_info, const int error_size, const bool resolve);
|
||||
|
||||
static inline int fdfs_parse_multi_ips(char *ip_str, FDFSMultiIP *ip_addrs,
|
||||
char *error_info, const int error_size)
|
||||
{
|
||||
const bool resolve = true;
|
||||
return fdfs_parse_multi_ips_ex(ip_str, ip_addrs,
|
||||
error_info, error_size, resolve);
|
||||
}
|
||||
|
||||
int fdfs_check_server_ips(const TrackerServerInfo *pServer,
|
||||
char *error_info, const int error_size);
|
||||
|
||||
int fdfs_check_and_format_ips(FDFSMultiIP *ip_addrs,
|
||||
char *error_info, const int error_size);
|
||||
|
||||
const char *fdfs_get_ipaddr_by_client_ip(const FDFSMultiIP *ip_addrs,
|
||||
const char *client_ip);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -124,9 +124,9 @@ static void tracker_mem_find_store_server(FDFSGroupInfo *pGroup);
|
|||
static int tracker_mem_find_trunk_server(FDFSGroupInfo *pGroup,
|
||||
const bool save);
|
||||
|
||||
static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup, \
|
||||
FDFSStorageDetail **ppStorageServer, const char *id, \
|
||||
const char *ip_addr, const bool bNeedSleep, \
|
||||
static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup,
|
||||
FDFSStorageDetail **ppStorageServer, const char *id,
|
||||
const char *ip_addr, const bool bNeedSleep,
|
||||
const bool bNeedLock, bool *bInserted);
|
||||
|
||||
static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo, \
|
||||
|
|
@ -1849,6 +1849,7 @@ int tracker_save_storages()
|
|||
char trueFilename[MAX_PATH_SIZE];
|
||||
char buff[4096];
|
||||
char id_buff[128];
|
||||
char ip_buff[256];
|
||||
int fd;
|
||||
int len;
|
||||
FDFSGroupInfo **ppGroup;
|
||||
|
|
@ -1895,10 +1896,13 @@ int tracker_save_storages()
|
|||
|
||||
if (g_use_storage_id)
|
||||
{
|
||||
sprintf(id_buff, "\t%s=%s\n", \
|
||||
sprintf(id_buff, "\t%s=%s\n",
|
||||
STORAGE_ITEM_SERVER_ID, pStorage->id);
|
||||
}
|
||||
|
||||
fdfs_multi_ips_to_string(&pStorage->ip_addrs,
|
||||
ip_buff, sizeof(ip_buff));
|
||||
|
||||
count++;
|
||||
len = sprintf(buff, \
|
||||
"# storage %s:%d\n" \
|
||||
|
|
@ -1956,11 +1960,11 @@ int tracker_save_storages()
|
|||
"\t%s=%d\n" \
|
||||
"\t%s=%d\n" \
|
||||
"\t%s=%"PRId64"\n\n", \
|
||||
pStorage->ip_addr, pStorage->storage_port, \
|
||||
ip_buff, pStorage->storage_port, \
|
||||
STORAGE_SECTION_NAME_PREFIX, count, id_buff, \
|
||||
STORAGE_ITEM_GROUP_NAME, \
|
||||
(*ppGroup)->group_name, \
|
||||
STORAGE_ITEM_IP_ADDR, pStorage->ip_addr, \
|
||||
STORAGE_ITEM_IP_ADDR, ip_buff, \
|
||||
STORAGE_ITEM_STATUS, pStorage->status, \
|
||||
STORAGE_ITEM_VERSION, pStorage->version, \
|
||||
STORAGE_ITEM_JOIN_TIME, \
|
||||
|
|
@ -3491,7 +3495,7 @@ int tracker_mem_delete_storage(FDFSGroupInfo *pGroup, const char *id)
|
|||
|
||||
logDebug("file: "__FILE__", line: %d, " \
|
||||
"delete storage server: %s:%d, group: %s", \
|
||||
__LINE__, pStorageServer->ip_addr,
|
||||
__LINE__, pStorageServer->ip_addrs.ips[0],
|
||||
pStorageServer->storage_port, pGroup->group_name);
|
||||
|
||||
tracker_mem_clear_storage_fields(pStorageServer);
|
||||
|
|
@ -3579,19 +3583,20 @@ int tracker_mem_storage_ip_changed(FDFSGroupInfo *pGroup, \
|
|||
//exchange old and new storage server
|
||||
snprintf(pOldStorageServer->id, sizeof(pOldStorageServer->id), \
|
||||
"%s", new_storage_ip);
|
||||
snprintf(pOldStorageServer->ip_addr, \
|
||||
sizeof(pOldStorageServer->ip_addr), "%s", new_storage_ip);
|
||||
snprintf(pOldStorageServer->ip_addrs.ips[0],
|
||||
sizeof(pOldStorageServer->ip_addrs.ips[0]), "%s", new_storage_ip);
|
||||
|
||||
snprintf(pNewStorageServer->id, sizeof(pNewStorageServer->id), \
|
||||
"%s", old_storage_ip);
|
||||
snprintf(pNewStorageServer->ip_addr, \
|
||||
sizeof(pNewStorageServer->ip_addr), "%s", old_storage_ip);
|
||||
pNewStorageServer->ip_addrs.count = 1;
|
||||
snprintf(pNewStorageServer->ip_addrs.ips[0],
|
||||
sizeof(pNewStorageServer->ip_addrs.ips[0]), "%s", old_storage_ip);
|
||||
pNewStorageServer->status = FDFS_STORAGE_STATUS_IP_CHANGED;
|
||||
|
||||
pGroup->chg_count++;
|
||||
|
||||
//need re-sort
|
||||
qsort(pGroup->sorted_servers, pGroup->count, \
|
||||
qsort(pGroup->sorted_servers, pGroup->count,
|
||||
sizeof(FDFSStorageDetail *), tracker_mem_cmp_by_storage_id);
|
||||
|
||||
pthread_mutex_unlock(&mem_thread_lock);
|
||||
|
|
@ -3601,8 +3606,8 @@ int tracker_mem_storage_ip_changed(FDFSGroupInfo *pGroup, \
|
|||
return tracker_save_sys_files();
|
||||
}
|
||||
|
||||
static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo, \
|
||||
const char *id, const char *ip_addr, \
|
||||
static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo,
|
||||
const char *id, const char *ip_addr,
|
||||
const bool bNeedSleep, const bool bNeedLock, bool *bInserted)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -3620,9 +3625,9 @@ static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo, \
|
|||
return result;
|
||||
}
|
||||
|
||||
static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup, \
|
||||
FDFSStorageDetail **ppStorageServer, const char *id, \
|
||||
const char *ip_addr, const bool bNeedSleep, \
|
||||
static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup,
|
||||
FDFSStorageDetail **ppStorageServer, const char *id,
|
||||
const char *ip_addr, const bool bNeedSleep,
|
||||
const bool bNeedLock, bool *bInserted)
|
||||
{
|
||||
int result;
|
||||
|
|
|
|||
|
|
@ -272,12 +272,18 @@ typedef struct
|
|||
char sz_last_heart_beat_time[8];
|
||||
} FDFSStorageStatBuff;
|
||||
|
||||
typedef struct StructFDFSMultiIP
|
||||
{
|
||||
int count;
|
||||
char ips[FDFS_MULTI_IP_MAX_COUNT][IP_ADDRESS_SIZE];
|
||||
} FDFSMultiIP;
|
||||
|
||||
typedef struct StructFDFSStorageDetail
|
||||
{
|
||||
char status;
|
||||
char padding; //just for padding
|
||||
char id[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
char ip_addr[IP_ADDRESS_SIZE];
|
||||
FDFSMultiIP ip_addrs;
|
||||
char version[FDFS_VERSION_SIZE];
|
||||
char domain_name[FDFS_DOMAIN_NAME_MAX_SIZE];
|
||||
|
||||
|
|
@ -429,14 +435,6 @@ typedef struct
|
|||
int version; //for binlog pre-read, compare with binlog_write_version
|
||||
} BinLogBuffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char id[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
char group_name[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes alignment
|
||||
char ip_addr[IP_ADDRESS_SIZE];
|
||||
int port; //since v5.05
|
||||
} FDFSStorageIdInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char id[FDFS_STORAGE_ID_MAX_SIZE];
|
||||
|
|
|
|||
Loading…
Reference in New Issue