diff --git a/HISTORY b/HISTORY index 152488a..907a21a 100644 --- a/HISTORY +++ b/HISTORY @@ -2,6 +2,7 @@ Version 5.05 2014-11-22 * tracker_mem.c log more info * remove useless global variable: g_network_tv + * storage can fetch it's group_name from tracker server Version 5.04 2014-09-16 * add fastdfs.spec for build RPM on Linux diff --git a/conf/storage.conf b/conf/storage.conf index 47fe053..e93a071 100644 --- a/conf/storage.conf +++ b/conf/storage.conf @@ -4,6 +4,10 @@ disabled=false # the name of the group this storage server belongs to +# +# comment or remove this item for fetching from tracker server, +# in this case, use_storage_id must set to true in tracker.conf, +# and storage_ids.conf must be configed correctly. group_name=group1 # bind an address of this host diff --git a/make.sh b/make.sh index 1c47f72..7d3f44d 100755 --- a/make.sh +++ b/make.sh @@ -198,6 +198,7 @@ if [ "$1" = "install" ]; then cp -f conf/tracker.conf $TARGET_CONF_PATH/tracker.conf.sample cp -f conf/storage.conf $TARGET_CONF_PATH/storage.conf.sample cp -f conf/client.conf $TARGET_CONF_PATH/client.conf.sample + cp -f conf/storage_ids.conf $TARGET_CONF_PATH/storage_ids.conf.sample fi mkdir -p $TARGET_INIT_PATH cp -f init.d/fdfs_trackerd $TARGET_INIT_PATH diff --git a/storage/storage_func.c b/storage/storage_func.c index b03e522..bf03bc3 100644 --- a/storage/storage_func.c +++ b/storage/storage_func.c @@ -124,6 +124,85 @@ static int storage_close_stat_file(); static int storage_make_data_dirs(const char *pBasePath, bool *pathCreated); static int storage_check_and_make_data_dirs(); +static int storage_do_get_group_name(ConnectionInfo *pTrackerServer) +{ + char out_buff[sizeof(TrackerHeader) + 4]; + TrackerHeader *pHeader; + char *pInBuff; + int64_t in_bytes; + int result; + + pHeader = (TrackerHeader *)out_buff; + memset(out_buff, 0, sizeof(out_buff)); + long2buff(4, pHeader->pkg_len); + int2buff(g_server_port, out_buff + sizeof(TrackerHeader)); + pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_GET_GROUP_NAME; + if ((result=tcpsenddata_nb(pTrackerServer->sock, out_buff, \ + sizeof(out_buff), g_fdfs_network_timeout)) != 0) + { + logError("file: "__FILE__", line: %d, " \ + "tracker server %s:%d, send data fail, " \ + "errno: %d, error info: %s.", \ + __LINE__, pTrackerServer->ip_addr, \ + pTrackerServer->port, \ + result, STRERROR(result)); + return result; + } + + pInBuff = g_group_name; + if ((result=fdfs_recv_response(pTrackerServer, \ + &pInBuff, FDFS_GROUP_NAME_MAX_LEN, &in_bytes)) != 0) + { + return result; + } + + if (in_bytes != FDFS_GROUP_NAME_MAX_LEN) + { + logError("file: "__FILE__", line: %d, " \ + "tracker server %s:%d, recv body length: " \ + "%"PRId64" != %d", \ + __LINE__, pTrackerServer->ip_addr, \ + pTrackerServer->port, in_bytes, FDFS_GROUP_NAME_MAX_LEN); + return EINVAL; + } + + return 0; +} + +static int storage_get_group_name_from_tracker() +{ + ConnectionInfo *pTrackerServer; + ConnectionInfo *pServerEnd; + ConnectionInfo *pTrackerConn; + ConnectionInfo tracker_server; + int result; + + result = ENOENT; + pServerEnd = g_tracker_group.servers + g_tracker_group.server_count; + for (pTrackerServer=g_tracker_group.servers; \ + pTrackerServerid); } +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) { @@ -335,6 +351,117 @@ FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id) } } +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; @@ -354,7 +481,9 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename) char *line; char *id; char *group_name; + char *pHost; char *pIpAddr; + char *pPort; FDFSStorageIdInfo *pStorageIdInfo; FDFSStorageIdInfo **ppStorageIdInfo; FDFSStorageIdInfo **ppStorageIdEnd; @@ -455,14 +584,14 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename) group_name++; } - pIpAddr = group_name; - while (!(*pIpAddr == ' ' || *pIpAddr == '\t' \ - || *pIpAddr == '\0')) + pHost = group_name; + while (!(*pHost == ' ' || *pHost == '\t' \ + || *pHost == '\0')) { - pIpAddr++; + pHost++; } - if (*pIpAddr == '\0') + if (*pHost == '\0') { logError("file: "__FILE__", line: %d, " \ "config file: %s, line no: %d, " \ @@ -473,19 +602,29 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename) break; } - *pIpAddr = '\0'; - pIpAddr++; //skip space char - while (*pIpAddr == ' ' || *pIpAddr == '\t') + *pHost = '\0'; + pHost++; //skip space char + while (*pHost == ' ' || *pHost == '\t') { - pIpAddr++; + 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); + "invalid host name: %s", __LINE__, pIpAddr); result = EINVAL; break; } @@ -520,9 +659,18 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename) pStorageIdInfo = g_storage_ids_by_ip; for (i=0; iid, \ - pStorageIdInfo->group_name, - pStorageIdInfo->ip_addr); + 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++; } @@ -539,6 +687,7 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename) 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; } diff --git a/tracker/fdfs_shared_func.h b/tracker/fdfs_shared_func.h index 172831f..d40c5f0 100644 --- a/tracker/fdfs_shared_func.h +++ b/tracker/fdfs_shared_func.h @@ -60,6 +60,9 @@ 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(ConnectionInfo *pTrackerServer); diff --git a/tracker/tracker_service.c b/tracker/tracker_service.c index d3c9bd1..f057033 100644 --- a/tracker/tracker_service.c +++ b/tracker/tracker_service.c @@ -1120,6 +1120,77 @@ static int tracker_deal_get_storage_id(struct fast_task_info *pTask) return 0; } +static int tracker_deal_get_storage_group_name(struct fast_task_info *pTask) +{ + char ip_addr[IP_ADDRESS_SIZE]; + FDFSStorageIdInfo *pFDFSStorageIdInfo; + char *pPort; + int port; + int nPkgLen; + + if (!g_use_storage_id) + { + logError("file: "__FILE__", line: %d, " + "use_storage_id is disabled, can't get group name " + "from storage ip and port!", __LINE__); + pTask->length = sizeof(TrackerHeader); + return EOPNOTSUPP; + } + + nPkgLen = pTask->length - sizeof(TrackerHeader); + if (nPkgLen < 4) + { + logError("file: "__FILE__", line: %d, " \ + "cmd=%d, client ip addr: %s, " \ + "package size %d is not correct", __LINE__, \ + TRACKER_PROTO_CMD_STORAGE_GET_GROUP_NAME, \ + pTask->client_ip, nPkgLen); + pTask->length = sizeof(TrackerHeader); + return EINVAL; + } + + if (nPkgLen == 4) //port only + { + strcpy(ip_addr, pTask->client_ip); + pPort = pTask->data + sizeof(TrackerHeader); + } + else //ip_addr and port + { + int ip_len; + + ip_len = nPkgLen - 4; + if (ip_len >= IP_ADDRESS_SIZE) + { + logError("file: "__FILE__", line: %d, " \ + "ip address is too long, length: %d", + __LINE__, ip_len); + pTask->length = sizeof(TrackerHeader); + return ENAMETOOLONG; + } + + memcpy(ip_addr, pTask->data + sizeof(TrackerHeader), ip_len); + *(ip_addr + ip_len) = '\0'; + pPort = pTask->data + sizeof(TrackerHeader) + ip_len; + } + port = buff2int(pPort); + + pFDFSStorageIdInfo = fdfs_get_storage_id_by_ip_port(ip_addr, port); + if (pFDFSStorageIdInfo == NULL) + { + logError("file: "__FILE__", line: %d, " + "client ip: %s, can't get group name for storage %s:%d", + __LINE__, pTask->client_ip, ip_addr, port); + pTask->length = sizeof(TrackerHeader); + return ENOENT; + } + + pTask->length = sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN; + memset(pTask->data + sizeof(TrackerHeader), 0, FDFS_GROUP_NAME_MAX_LEN); + strcpy(pTask->data + sizeof(TrackerHeader), pFDFSStorageIdInfo->group_name); + + return 0; +} + static int tracker_deal_fetch_storage_ids(struct fast_task_info *pTask) { FDFSStorageIdInfo *pIdsStart; @@ -1172,13 +1243,22 @@ static int tracker_deal_fetch_storage_ids(struct fast_task_info *pTask) pIdsEnd = g_storage_ids_by_ip + g_storage_id_count; for (pIdInfo = pIdsStart; pIdInfo < pIdsEnd; pIdInfo++) { + char szPortPart[16]; if ((int)(p - pTask->data) > pTask->size - 64) { break; } - p += sprintf(p, "%s %s %s\n", pIdInfo->id, \ - pIdInfo->group_name, pIdInfo->ip_addr); + if (pIdInfo->port > 0) + { + sprintf(szPortPart, ":%d", pIdInfo->port); + } + else + { + *szPortPart = '\0'; + } + p += sprintf(p, "%s %s %s%s\n", pIdInfo->id, + pIdInfo->group_name, pIdInfo->ip_addr, szPortPart); } int2buff((int)(pIdInfo - pIdsStart), (char *)pCurrentCount); @@ -3683,6 +3763,9 @@ int tracker_deal_task(struct fast_task_info *pTask) case TRACKER_PROTO_CMD_STORAGE_GET_SERVER_ID: result = tracker_deal_get_storage_id(pTask); break; + case TRACKER_PROTO_CMD_STORAGE_GET_GROUP_NAME: + result = tracker_deal_get_storage_group_name(pTask); + break; case TRACKER_PROTO_CMD_STORAGE_FETCH_STORAGE_IDS: result = tracker_deal_fetch_storage_ids(pTask); break; diff --git a/tracker/tracker_types.h b/tracker/tracker_types.h index 2989bde..edff92a 100644 --- a/tracker/tracker_types.h +++ b/tracker/tracker_types.h @@ -423,6 +423,7 @@ 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