storage can fetch it's group_name from tracker server

pull/48/head V5.05
yuqing 2014-11-22 12:01:22 +08:00
parent 119ff3ca5a
commit 9a47139321
8 changed files with 381 additions and 47 deletions

View File

@ -2,6 +2,7 @@
Version 5.05 2014-11-22 Version 5.05 2014-11-22
* tracker_mem.c log more info * tracker_mem.c log more info
* remove useless global variable: g_network_tv * remove useless global variable: g_network_tv
* storage can fetch it's group_name from tracker server
Version 5.04 2014-09-16 Version 5.04 2014-09-16
* add fastdfs.spec for build RPM on Linux * add fastdfs.spec for build RPM on Linux

View File

@ -4,6 +4,10 @@
disabled=false disabled=false
# the name of the group this storage server belongs to # 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 group_name=group1
# bind an address of this host # bind an address of this host

View File

@ -198,6 +198,7 @@ if [ "$1" = "install" ]; then
cp -f conf/tracker.conf $TARGET_CONF_PATH/tracker.conf.sample 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/storage.conf $TARGET_CONF_PATH/storage.conf.sample
cp -f conf/client.conf $TARGET_CONF_PATH/client.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 fi
mkdir -p $TARGET_INIT_PATH mkdir -p $TARGET_INIT_PATH
cp -f init.d/fdfs_trackerd $TARGET_INIT_PATH cp -f init.d/fdfs_trackerd $TARGET_INIT_PATH

View File

@ -124,6 +124,85 @@ static int storage_close_stat_file();
static int storage_make_data_dirs(const char *pBasePath, bool *pathCreated); static int storage_make_data_dirs(const char *pBasePath, bool *pathCreated);
static int storage_check_and_make_data_dirs(); 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; \
pTrackerServer<pServerEnd; pTrackerServer++)
{
memcpy(&tracker_server, pTrackerServer, \
sizeof(ConnectionInfo));
tracker_server.sock = -1;
if ((pTrackerConn=tracker_connect_server(&tracker_server, \
&result)) == NULL)
{
continue;
}
result = storage_do_get_group_name(pTrackerConn);
tracker_disconnect_server_ex(pTrackerConn, \
result != 0 && result != ENOENT);
if (result == 0)
{
return 0;
}
}
return result;
}
static int tracker_get_my_server_id() static int tracker_get_my_server_id()
{ {
struct in_addr ip_addr; struct in_addr ip_addr;
@ -1084,37 +1163,6 @@ int storage_func_init(const char *filename, \
g_client_bind_addr = iniGetBoolValue(NULL, "client_bind", \ g_client_bind_addr = iniGetBoolValue(NULL, "client_bind", \
&iniContext, true); &iniContext, true);
pGroupName = iniGetStrValue(NULL, "group_name", &iniContext);
if (pGroupName == NULL)
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\" must have item " \
"\"group_name\"!", \
__LINE__, filename);
result = ENOENT;
break;
}
if (pGroupName[0] == '\0')
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\", " \
"group_name is empty!", \
__LINE__, filename);
result = EINVAL;
break;
}
snprintf(g_group_name, sizeof(g_group_name), "%s", pGroupName);
if ((result=fdfs_validate_group_name(g_group_name)) != 0) \
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\", " \
"the group name \"%s\" is invalid!", \
__LINE__, filename, g_group_name);
result = EINVAL;
break;
}
result = fdfs_load_tracker_group_ex(&g_tracker_group, \ result = fdfs_load_tracker_group_ex(&g_tracker_group, \
filename, &iniContext); filename, &iniContext);
if (result != 0) if (result != 0)
@ -1143,6 +1191,50 @@ int storage_func_init(const char *filename, \
break; break;
} }
pGroupName = iniGetStrValue(NULL, "group_name", &iniContext);
if (pGroupName == NULL)
{
result = storage_get_group_name_from_tracker();
if (result == 0)
{
logInfo("file: "__FILE__", line: %d, " \
"get group name from tracker server, group_name: %s",
__LINE__, g_group_name);
}
else
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\" must have item " \
"\"group_name\"!", \
__LINE__, filename);
result = ENOENT;
break;
}
}
else if (pGroupName[0] == '\0')
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\", " \
"group_name is empty!", \
__LINE__, filename);
result = EINVAL;
break;
}
else
{
snprintf(g_group_name, sizeof(g_group_name), "%s", pGroupName);
}
if ((result=fdfs_validate_group_name(g_group_name)) != 0) \
{
logError("file: "__FILE__", line: %d, " \
"conf file \"%s\", " \
"the group name \"%s\" is invalid!", \
__LINE__, filename, g_group_name);
result = EINVAL;
break;
}
g_sync_wait_usec = iniGetIntValue(NULL, "sync_wait_msec",\ g_sync_wait_usec = iniGetIntValue(NULL, "sync_wait_msec",\
&iniContext, STORAGE_DEF_SYNC_WAIT_MSEC); &iniContext, STORAGE_DEF_SYNC_WAIT_MSEC);
if (g_sync_wait_usec <= 0) if (g_sync_wait_usec <= 0)

View File

@ -18,6 +18,8 @@
FDFSStorageIdInfo *g_storage_ids_by_ip = NULL; //sorted by group name and storage IP 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 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; int g_storage_id_count = 0;
int fdfs_get_tracker_leader_index_ex(TrackerServerGroup *pServerGroup, \ int fdfs_get_tracker_leader_index_ex(TrackerServerGroup *pServerGroup, \
@ -301,6 +303,20 @@ static int fdfs_cmp_server_id(const void *p1, const void *p2)
(*((FDFSStorageIdInfo **)p2))->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, \ FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \
const char *pIpAddr) 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; 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 = &target;
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) int fdfs_check_storage_id(const char *group_name, const char *id)
{ {
FDFSStorageIdInfo *pFound; FDFSStorageIdInfo *pFound;
@ -354,7 +481,9 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
char *line; char *line;
char *id; char *id;
char *group_name; char *group_name;
char *pHost;
char *pIpAddr; char *pIpAddr;
char *pPort;
FDFSStorageIdInfo *pStorageIdInfo; FDFSStorageIdInfo *pStorageIdInfo;
FDFSStorageIdInfo **ppStorageIdInfo; FDFSStorageIdInfo **ppStorageIdInfo;
FDFSStorageIdInfo **ppStorageIdEnd; FDFSStorageIdInfo **ppStorageIdEnd;
@ -455,14 +584,14 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
group_name++; group_name++;
} }
pIpAddr = group_name; pHost = group_name;
while (!(*pIpAddr == ' ' || *pIpAddr == '\t' \ while (!(*pHost == ' ' || *pHost == '\t' \
|| *pIpAddr == '\0')) || *pHost == '\0'))
{ {
pIpAddr++; pHost++;
} }
if (*pIpAddr == '\0') if (*pHost == '\0')
{ {
logError("file: "__FILE__", line: %d, " \ logError("file: "__FILE__", line: %d, " \
"config file: %s, line no: %d, " \ "config file: %s, line no: %d, " \
@ -473,19 +602,29 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
break; break;
} }
*pIpAddr = '\0'; *pHost = '\0';
pIpAddr++; //skip space char pHost++; //skip space char
while (*pIpAddr == ' ' || *pIpAddr == '\t') 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, \ if (getIpaddrByName(pIpAddr, pStorageIdInfo->ip_addr, \
sizeof(pStorageIdInfo->ip_addr)) == INADDR_NONE) sizeof(pStorageIdInfo->ip_addr)) == INADDR_NONE)
{ {
logError("file: "__FILE__", line: %d, " \ logError("file: "__FILE__", line: %d, " \
"invalid host name: %s", \ "invalid host name: %s", __LINE__, pIpAddr);
__LINE__, pIpAddr);
result = EINVAL; result = EINVAL;
break; break;
} }
@ -520,9 +659,18 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
pStorageIdInfo = g_storage_ids_by_ip; pStorageIdInfo = g_storage_ids_by_ip;
for (i=0; i<g_storage_id_count; i++) for (i=0; i<g_storage_id_count; i++)
{ {
logDebug("%s %s %s", pStorageIdInfo->id, \ char szPortPart[16];
pStorageIdInfo->group_name, if (pStorageIdInfo->port > 0)
pStorageIdInfo->ip_addr); {
sprintf(szPortPart, ":%d", pStorageIdInfo->port);
}
else
{
*szPortPart = '\0';
}
logDebug("%s %s %s%s", pStorageIdInfo->id,
pStorageIdInfo->group_name,
pStorageIdInfo->ip_addr, szPortPart);
pStorageIdInfo++; pStorageIdInfo++;
} }
@ -539,6 +687,7 @@ int fdfs_load_storage_ids(char *content, const char *pStorageIdsFilename)
sizeof(FDFSStorageIdInfo), fdfs_cmp_group_name_and_ip); sizeof(FDFSStorageIdInfo), fdfs_cmp_group_name_and_ip);
qsort(g_storage_ids_by_id, g_storage_id_count, \ qsort(g_storage_ids_by_id, g_storage_id_count, \
sizeof(FDFSStorageIdInfo *), fdfs_cmp_server_id); sizeof(FDFSStorageIdInfo *), fdfs_cmp_server_id);
return result; return result;
} }

View File

@ -60,6 +60,9 @@ FDFSStorageIdInfo *fdfs_get_storage_by_id(const char *id);
FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \ FDFSStorageIdInfo *fdfs_get_storage_id_by_ip(const char *group_name, \
const char *pIpAddr); 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_check_storage_id(const char *group_name, const char *id);
int fdfs_get_storage_ids_from_tracker_server(ConnectionInfo *pTrackerServer); int fdfs_get_storage_ids_from_tracker_server(ConnectionInfo *pTrackerServer);

View File

@ -1120,6 +1120,77 @@ static int tracker_deal_get_storage_id(struct fast_task_info *pTask)
return 0; 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) static int tracker_deal_fetch_storage_ids(struct fast_task_info *pTask)
{ {
FDFSStorageIdInfo *pIdsStart; 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; pIdsEnd = g_storage_ids_by_ip + g_storage_id_count;
for (pIdInfo = pIdsStart; pIdInfo < pIdsEnd; pIdInfo++) for (pIdInfo = pIdsStart; pIdInfo < pIdsEnd; pIdInfo++)
{ {
char szPortPart[16];
if ((int)(p - pTask->data) > pTask->size - 64) if ((int)(p - pTask->data) > pTask->size - 64)
{ {
break; break;
} }
p += sprintf(p, "%s %s %s\n", pIdInfo->id, \ if (pIdInfo->port > 0)
pIdInfo->group_name, pIdInfo->ip_addr); {
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); 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: case TRACKER_PROTO_CMD_STORAGE_GET_SERVER_ID:
result = tracker_deal_get_storage_id(pTask); result = tracker_deal_get_storage_id(pTask);
break; 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: case TRACKER_PROTO_CMD_STORAGE_FETCH_STORAGE_IDS:
result = tracker_deal_fetch_storage_ids(pTask); result = tracker_deal_fetch_storage_ids(pTask);
break; break;

View File

@ -423,6 +423,7 @@ typedef struct
char id[FDFS_STORAGE_ID_MAX_SIZE]; char id[FDFS_STORAGE_ID_MAX_SIZE];
char group_name[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes alignment char group_name[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes alignment
char ip_addr[IP_ADDRESS_SIZE]; char ip_addr[IP_ADDRESS_SIZE];
int port; //since v5.05
} FDFSStorageIdInfo; } FDFSStorageIdInfo;
typedef struct typedef struct