From 82e95ccee7917f61c52c250e662d05b82c3b705d Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Wed, 9 Oct 2019 21:26:56 +0800 Subject: [PATCH] tracker support multi ip for storage server --- client/Makefile.in | 6 +- client/client_func.c | 2 +- client/storage_client.c | 6 +- storage/Makefile.in | 4 +- storage/storage_service.c | 4 +- tracker/Makefile.in | 2 +- tracker/fdfs_server_id_func.c | 803 ++++++++++++++++++++++++++++++ tracker/fdfs_server_id_func.h | 82 ++++ tracker/fdfs_shared_func.c | 885 +++++----------------------------- tracker/fdfs_shared_func.h | 61 +-- tracker/tracker_mem.c | 39 +- tracker/tracker_types.h | 16 +- 12 files changed, 1090 insertions(+), 820 deletions(-) create mode 100644 tracker/fdfs_server_id_func.c create mode 100644 tracker/fdfs_server_id_func.h diff --git a/client/Makefile.in b/client/Makefile.in index 7d702ee..859b8b8 100644 --- a/client/Makefile.in +++ b/client/Makefile.in @@ -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 diff --git a/client/client_func.c b/client/client_func.c index 0343d89..1b8fe05 100644 --- a/client/client_func.c +++ b/client/client_func.c @@ -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; diff --git a/client/storage_client.c b/client/storage_client.c index 5ae5ef9..ce7912a 100644 --- a/client/storage_client.c +++ b/client/storage_client.c @@ -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 { diff --git a/storage/Makefile.in b/storage/Makefile.in index 95f8e09..7815196 100644 --- a/storage/Makefile.in +++ b/storage/Makefile.in @@ -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 \ diff --git a/storage/storage_service.c b/storage/storage_service.c index da52e18..f69582f 100644 --- a/storage/storage_service.c +++ b/storage/storage_service.c @@ -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)); } } } diff --git a/tracker/Makefile.in b/tracker/Makefile.in index acb6f54..b4e5a22 100644 --- a/tracker/Makefile.in +++ b/tracker/Makefile.in @@ -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) diff --git a/tracker/fdfs_server_id_func.c b/tracker/fdfs_server_id_func.c new file mode 100644 index 0000000..91404bf --- /dev/null +++ b/tracker/fdfs_server_id_func.c @@ -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 +#include +#include +#include +#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; idInfoip_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; idInfoip_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 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; currentport > 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; iport = 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; iport > 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; iservers + 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; pGServerservers) + { + 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; +} + diff --git a/tracker/fdfs_server_id_func.h b/tracker/fdfs_server_id_func.h new file mode 100644 index 0000000..624ee0b --- /dev/null +++ b/tracker/fdfs_server_id_func.h @@ -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 + diff --git a/tracker/fdfs_shared_func.c b/tracker/fdfs_shared_func.c index 44b0be2..1dfcdf8 100644 --- a/tracker/fdfs_shared_func.c +++ b/tracker/fdfs_shared_func.c @@ -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; iport > 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; iport > 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; iport = 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; iport > 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; iservers + 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; pGServerservers) - { - 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; icount; 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; icount; 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; +} diff --git a/tracker/fdfs_shared_func.h b/tracker/fdfs_shared_func.h index 76544e1..9367d8f 100644 --- a/tracker/fdfs_shared_func.h +++ b/tracker/fdfs_shared_func.h @@ -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 diff --git a/tracker/tracker_mem.c b/tracker/tracker_mem.c index cdd0fcb..0d44233 100644 --- a/tracker/tracker_mem.c +++ b/tracker/tracker_mem.c @@ -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; diff --git a/tracker/tracker_types.h b/tracker/tracker_types.h index ba6ebe2..4a06c6f 100644 --- a/tracker/tracker_types.h +++ b/tracker/tracker_types.h @@ -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];