1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8 
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <time.h>
19 #include <fcntl.h>
20 #include <pthread.h>
21 #include "fdfs_define.h"
22 #include "fastcommon/logger.h"
23 #include "fastcommon/sockopt.h"
24 #include "fdfs_global.h"
25 #include "fastcommon/shared_func.h"
26 #include "fastcommon/pthread_func.h"
27 #include "fastcommon/sched_thread.h"
28 #include "fdfs_shared_func.h"
29 #include "tracker_global.h"
30 #include "tracker_proto.h"
31 #include "tracker_func.h"
32 #include "tracker_relationship.h"
33 #include "tracker_mem.h"
34 
35 #define TRACKER_MEM_ALLOC_ONCE	2
36 
37 #define GROUP_SECTION_NAME_GLOBAL            "Global"
38 #define GROUP_SECTION_NAME_PREFIX            "Group"
39 #define GROUP_SECTION_NO_FORMAT              "%03d"
40 #define GROUP_ITEM_GROUP_COUNT               "group_count"
41 #define GROUP_ITEM_GROUP_NAME                "group_name"
42 #define GROUP_ITEM_STORAGE_PORT              "storage_port"
43 #define GROUP_ITEM_STORAGE_HTTP_PORT         "storage_http_port"
44 #define GROUP_ITEM_STORE_PATH_COUNT          "store_path_count"
45 #define GROUP_ITEM_SUBDIR_COUNT_PER_PATH     "subdir_count_per_path"
46 #define GROUP_ITEM_CURRENT_TRUNK_FILE_ID     "current_trunk_file_id"
47 #define GROUP_ITEM_LAST_TRUNK_SERVER         "last_trunk_server"
48 #define GROUP_ITEM_TRUNK_SERVER              "trunk_server"
49 
50 #define STORAGE_SECTION_NAME_GLOBAL            "Global"
51 #define STORAGE_SECTION_NAME_PREFIX            "Storage"
52 #define STORAGE_SECTION_NO_FORMAT              "%03d"
53 #define STORAGE_ITEM_STORAGE_COUNT             "storage_count"
54 
55 #define STORAGE_ITEM_GROUP_NAME                "group_name"
56 #define STORAGE_ITEM_SERVER_ID                 "id"
57 #define STORAGE_ITEM_IP_ADDR                   "ip_addr"
58 #define STORAGE_ITEM_STATUS                    "status"
59 #define STORAGE_ITEM_DOMAIN_NAME               "domain_name"
60 #define STORAGE_ITEM_VERSION                   "version"
61 #define STORAGE_ITEM_SYNC_SRC_SERVER           "sync_src_server"
62 #define STORAGE_ITEM_SYNC_UNTIL_TIMESTAMP      "sync_until_timestamp"
63 #define STORAGE_ITEM_JOIN_TIME                 "join_time"
64 #define STORAGE_ITEM_TOTAL_MB                  "total_mb"
65 #define STORAGE_ITEM_FREE_MB                   "free_mb"
66 #define STORAGE_ITEM_CHANGELOG_OFFSET          "changelog_offset"
67 #define STORAGE_ITEM_STORE_PATH_COUNT          "store_path_count"
68 #define STORAGE_ITEM_SUBDIR_COUNT_PER_PATH     "subdir_count_per_path"
69 #define STORAGE_ITEM_UPLOAD_PRIORITY           "upload_priority"
70 #define STORAGE_ITEM_STORAGE_PORT              "storage_port"
71 #define STORAGE_ITEM_STORAGE_HTTP_PORT         "storage_http_port"
72 #define STORAGE_ITEM_TOTAL_UPLOAD_COUNT        "total_upload_count"
73 #define STORAGE_ITEM_SUCCESS_UPLOAD_COUNT      "success_upload_count"
74 #define STORAGE_ITEM_TOTAL_APPEND_COUNT        "total_append_count"
75 #define STORAGE_ITEM_SUCCESS_APPEND_COUNT      "success_append_count"
76 #define STORAGE_ITEM_TOTAL_SET_META_COUNT      "total_set_meta_count"
77 #define STORAGE_ITEM_SUCCESS_SET_META_COUNT    "success_set_meta_count"
78 #define STORAGE_ITEM_TOTAL_DELETE_COUNT        "total_delete_count"
79 #define STORAGE_ITEM_SUCCESS_DELETE_COUNT      "success_delete_count"
80 #define STORAGE_ITEM_TOTAL_DOWNLOAD_COUNT      "total_download_count"
81 #define STORAGE_ITEM_SUCCESS_DOWNLOAD_COUNT    "success_download_count"
82 #define STORAGE_ITEM_TOTAL_GET_META_COUNT      "total_get_meta_count"
83 #define STORAGE_ITEM_SUCCESS_GET_META_COUNT    "success_get_meta_count"
84 #define STORAGE_ITEM_TOTAL_CREATE_LINK_COUNT   "total_create_link_count"
85 #define STORAGE_ITEM_SUCCESS_CREATE_LINK_COUNT "success_create_link_count"
86 #define STORAGE_ITEM_TOTAL_DELETE_LINK_COUNT   "total_delete_link_count"
87 #define STORAGE_ITEM_SUCCESS_DELETE_LINK_COUNT "success_delete_link_count"
88 #define STORAGE_ITEM_TOTAL_UPLOAD_BYTES        "total_upload_bytes"
89 #define STORAGE_ITEM_SUCCESS_UPLOAD_BYTES      "success_upload_bytes"
90 #define STORAGE_ITEM_TOTAL_APPEND_BYTES        "total_append_bytes"
91 #define STORAGE_ITEM_SUCCESS_APPEND_BYTES      "success_append_bytes"
92 #define STORAGE_ITEM_TOTAL_DOWNLOAD_BYTES      "total_download_bytes"
93 #define STORAGE_ITEM_SUCCESS_DOWNLOAD_BYTES    "success_download_bytes"
94 #define STORAGE_ITEM_TOTAL_SYNC_IN_BYTES       "total_sync_in_bytes"
95 #define STORAGE_ITEM_SUCCESS_SYNC_IN_BYTES     "success_sync_in_bytes"
96 #define STORAGE_ITEM_TOTAL_SYNC_OUT_BYTES      "total_sync_out_bytes"
97 #define STORAGE_ITEM_SUCCESS_SYNC_OUT_BYTES    "success_sync_out_bytes"
98 #define STORAGE_ITEM_TOTAL_FILE_OPEN_COUNT     "total_file_open_count"
99 #define STORAGE_ITEM_SUCCESS_FILE_OPEN_COUNT   "success_file_open_count"
100 #define STORAGE_ITEM_TOTAL_FILE_READ_COUNT     "total_file_read_count"
101 #define STORAGE_ITEM_SUCCESS_FILE_READ_COUNT   "success_file_read_count"
102 #define STORAGE_ITEM_TOTAL_FILE_WRITE_COUNT    "total_file_write_count"
103 #define STORAGE_ITEM_SUCCESS_FILE_WRITE_COUNT  "success_file_write_count"
104 #define STORAGE_ITEM_LAST_SOURCE_UPDATE        "last_source_update"
105 #define STORAGE_ITEM_LAST_SYNC_UPDATE          "last_sync_update"
106 #define STORAGE_ITEM_LAST_SYNCED_TIMESTAMP     "last_synced_timestamp"
107 #define STORAGE_ITEM_LAST_HEART_BEAT_TIME      "last_heart_beat_time"
108 
109 TrackerServerGroup g_tracker_servers = {0, 0, -1, NULL};
110 TrackerServerInfo *g_last_tracker_servers = NULL;  //for delay free
111 int g_next_leader_index = -1;			   //next leader index
112 int g_trunk_server_chg_count = 1;		   //for notify other trackers
113 int g_tracker_leader_chg_count = 0;		   //for notify storage servers
114 
115 int64_t g_changelog_fsize = 0; //storage server change log file size
116 static int changelog_fd = -1;  //storage server change log fd for write
117 static bool need_get_sys_files = true;
118 static bool get_sys_files_done = false;
119 
120 static pthread_mutex_t mem_thread_lock;
121 static pthread_mutex_t mem_file_lock;
122 
123 static void tracker_mem_find_store_server(FDFSGroupInfo *pGroup);
124 static int tracker_mem_find_trunk_server(FDFSGroupInfo *pGroup,
125 		const bool save);
126 
127 static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup,
128 	FDFSStorageDetail **ppStorageServer, const char *id,
129 	const char *ip_addr, const bool bNeedSleep,
130 	const bool bNeedLock, bool *bInserted);
131 
132 static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo,
133 		const char *id, const char *ip_addr,
134 		const bool bNeedSleep, const bool bNeedLock, bool *bInserted);
135 
136 static int tracker_mem_add_storage_from_file(FDFSGroups *pGroups,
137         const char *data_path, TrackerClientInfo *pClientInfo,
138 		const char *group_name, const char *storage_id, char *ip_addr);
139 
140 static int tracker_mem_add_group_ex(FDFSGroups *pGroups,
141 	TrackerClientInfo *pClientInfo, const char *group_name,
142 	const bool bNeedSleep, bool *bInserted);
143 
144 static int tracker_mem_destroy_groups(FDFSGroups *pGroups, const bool saveFiles);
145 
146 char *g_tracker_sys_filenames[TRACKER_SYS_FILE_COUNT] = {
147 	STORAGE_GROUPS_LIST_FILENAME_NEW,
148 	STORAGE_SERVERS_LIST_FILENAME_NEW,
149 	STORAGE_SYNC_TIMESTAMP_FILENAME,
150 	STORAGE_SERVERS_CHANGELOG_FILENAME
151 };
152 
153 #define TRACKER_CHOWN(path, current_uid, current_gid) \
154 	if (!(g_run_by_gid == current_gid && g_run_by_uid == current_uid)) \
155 	{ \
156 		if (chown(path, g_run_by_uid, g_run_by_gid) != 0) \
157 		{ \
158 			logError("file: "__FILE__", line: %d, " \
159 				"chown \"%s\" fail, " \
160 				"errno: %d, error info: %s", \
161 				__LINE__, path, \
162 				errno, STRERROR(errno)); \
163 			return errno != 0 ? errno : EPERM; \
164 		} \
165 	}
166 
167 #define TRACKER_FCHOWN(fd, path, current_uid, current_gid) \
168 	if (!(g_run_by_gid == current_gid && g_run_by_uid == current_uid)) \
169 	{ \
170 		if (fchown(fd, g_run_by_uid, g_run_by_gid) != 0) \
171 		{ \
172 			logError("file: "__FILE__", line: %d, " \
173 				"chown \"%s\" fail, " \
174 				"errno: %d, error info: %s", \
175 				__LINE__, path, \
176 				errno, STRERROR(errno)); \
177 			return errno != 0 ? errno : EPERM; \
178 		} \
179 	}
180 
181 
tracker_mem_pthread_lock()182 int tracker_mem_pthread_lock()
183 {
184 	int result;
185 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
186 	{
187 		logError("file: "__FILE__", line: %d, " \
188 			"call pthread_mutex_lock fail, " \
189 			"errno: %d, error info: %s", \
190 			__LINE__, result, STRERROR(result));
191 		return result;
192 	}
193 
194 	return 0;
195 }
196 
tracker_mem_pthread_unlock()197 int tracker_mem_pthread_unlock()
198 {
199 	int result;
200 	if ((result=pthread_mutex_unlock(&mem_thread_lock)) != 0)
201 	{
202 		logError("file: "__FILE__", line: %d, " \
203 			"call pthread_mutex_unlock fail, " \
204 			"errno: %d, error info: %s", \
205 			__LINE__, result, STRERROR(result));
206 		return result;
207 	}
208 
209 	return 0;
210 }
211 
tracker_mem_file_lock()212 int tracker_mem_file_lock()
213 {
214 	int result;
215 	if ((result=pthread_mutex_lock(&mem_file_lock)) != 0)
216 	{
217 		logError("file: "__FILE__", line: %d, " \
218 			"call pthread_mutex_lock fail, " \
219 			"errno: %d, error info: %s", \
220 			__LINE__, result, STRERROR(result));
221 		return result;
222 	}
223 
224 	return 0;
225 }
226 
tracker_mem_file_unlock()227 int tracker_mem_file_unlock()
228 {
229 	int result;
230 	if ((result=pthread_mutex_unlock(&mem_file_lock)) != 0)
231 	{
232 		logError("file: "__FILE__", line: %d, " \
233 			"call pthread_mutex_unlock fail, " \
234 			"errno: %d, error info: %s", \
235 			__LINE__, result, STRERROR(result));
236 		return result;
237 	}
238 
239 	return 0;
240 }
241 
tracker_write_to_changelog(FDFSGroupInfo * pGroup,FDFSStorageDetail * pStorage,const char * pArg)242 static int tracker_write_to_changelog(FDFSGroupInfo *pGroup, \
243 		FDFSStorageDetail *pStorage, const char *pArg)
244 {
245 	char buff[256];
246 	int len;
247 	int result;
248 
249 	tracker_mem_file_lock();
250 
251 	len = snprintf(buff, sizeof(buff), "%d %s %s %d %s\n", \
252 		(int)g_current_time, pGroup->group_name, pStorage->id, \
253 		pStorage->status, pArg != NULL ? pArg : "");
254 
255 	if (fc_safe_write(changelog_fd, buff, len) != len)
256 	{
257 		tracker_mem_file_unlock();
258 
259 		result = errno != 0 ? errno : EIO;
260 		logError("file: "__FILE__", line: %d, " \
261 			"write to file: %s fail, " \
262 			"errno: %d, error info: %s", \
263 			__LINE__, STORAGE_SERVERS_CHANGELOG_FILENAME, \
264 			result, STRERROR(result));
265 
266 		return result;
267 	}
268 
269 	g_changelog_fsize += len;
270 	result = fsync(changelog_fd);
271 	if (result != 0)
272 	{
273 		result = errno != 0 ? errno : EIO;
274 		logError("file: "__FILE__", line: %d, " \
275 			"call fsync of file: %s fail, " \
276 			"errno: %d, error info: %s", \
277 			__LINE__, STORAGE_SERVERS_CHANGELOG_FILENAME, \
278 			result, STRERROR(result));
279 	}
280 
281 	tracker_mem_file_unlock();
282 
283 	return result;
284 }
285 
tracker_malloc_storage_path_mbs(FDFSStorageDetail * pStorage,const int store_path_count)286 static int tracker_malloc_storage_path_mbs(FDFSStorageDetail *pStorage, \
287 		const int store_path_count)
288 {
289 	int alloc_bytes;
290 
291 	if (store_path_count <= 0)
292 	{
293 		return 0;
294 	}
295 
296 	alloc_bytes = sizeof(int64_t) * store_path_count;
297 	pStorage->path_total_mbs = (int64_t *)malloc(alloc_bytes);
298 	if (pStorage->path_total_mbs == NULL)
299 	{
300 		logError("file: "__FILE__", line: %d, " \
301 			"malloc %d bytes fail, " \
302 			"errno: %d, error info: %s", \
303 			__LINE__, alloc_bytes, errno, STRERROR(errno));
304 		return errno != 0 ? errno : ENOMEM;
305 	}
306 
307 	pStorage->path_free_mbs = (int64_t *)malloc(alloc_bytes);
308 	if (pStorage->path_free_mbs == NULL)
309 	{
310 		free(pStorage->path_total_mbs);
311 		pStorage->path_total_mbs = NULL;
312 
313 		logError("file: "__FILE__", line: %d, " \
314 			"malloc %d bytes fail, " \
315 			"errno: %d, error info: %s", \
316 			__LINE__, alloc_bytes, errno, STRERROR(errno));
317 		return errno != 0 ? errno : ENOMEM;
318 	}
319 
320 	memset(pStorage->path_total_mbs, 0, alloc_bytes);
321 	memset(pStorage->path_free_mbs, 0, alloc_bytes);
322 
323 	return 0;
324 }
325 
tracker_realloc_storage_path_mbs(FDFSStorageDetail * pStorage,const int old_store_path_count,const int new_store_path_count)326 static int tracker_realloc_storage_path_mbs(FDFSStorageDetail *pStorage, \
327 		const int old_store_path_count, const int new_store_path_count)
328 {
329 	int alloc_bytes;
330 	int copy_bytes;
331 	int64_t *new_path_total_mbs;
332 	int64_t *new_path_free_mbs;
333 
334 	if (new_store_path_count <= 0)
335 	{
336 		return EINVAL;
337 	}
338 
339 	alloc_bytes = sizeof(int64_t) * new_store_path_count;
340 
341 	new_path_total_mbs = (int64_t *)malloc(alloc_bytes);
342 	if (new_path_total_mbs == NULL)
343 	{
344 		logError("file: "__FILE__", line: %d, " \
345 			"malloc %d bytes fail, " \
346 			"errno: %d, error info: %s", \
347 			__LINE__, alloc_bytes, errno, STRERROR(errno));
348 		return errno != 0 ? errno : ENOMEM;
349 	}
350 
351 	new_path_free_mbs = (int64_t *)malloc(alloc_bytes);
352 	if (new_path_free_mbs == NULL)
353 	{
354 		free(new_path_total_mbs);
355 
356 		logError("file: "__FILE__", line: %d, " \
357 			"malloc %d bytes fail, " \
358 			"errno: %d, error info: %s", \
359 			__LINE__, alloc_bytes, errno, STRERROR(errno));
360 		return errno != 0 ? errno : ENOMEM;
361 	}
362 
363 	memset(new_path_total_mbs, 0, alloc_bytes);
364 	memset(new_path_free_mbs, 0, alloc_bytes);
365 
366 	if (old_store_path_count == 0)
367 	{
368 		pStorage->path_total_mbs = new_path_total_mbs;
369 		pStorage->path_free_mbs = new_path_free_mbs;
370 
371 		return 0;
372 	}
373 
374 	copy_bytes = (old_store_path_count < new_store_path_count ? \
375 		old_store_path_count : new_store_path_count) * sizeof(int64_t);
376 	memcpy(new_path_total_mbs, pStorage->path_total_mbs, copy_bytes);
377 	memcpy(new_path_free_mbs, pStorage->path_free_mbs, copy_bytes);
378 
379 	free(pStorage->path_total_mbs);
380 	free(pStorage->path_free_mbs);
381 
382 	pStorage->path_total_mbs = new_path_total_mbs;
383 	pStorage->path_free_mbs = new_path_free_mbs;
384 
385 	return 0;
386 }
387 
tracker_realloc_group_path_mbs(FDFSGroupInfo * pGroup,const int new_store_path_count)388 static int tracker_realloc_group_path_mbs(FDFSGroupInfo *pGroup, \
389 		const int new_store_path_count)
390 {
391 	FDFSStorageDetail **ppStorage;
392 	FDFSStorageDetail **ppEnd;
393 	int result;
394 
395 	ppEnd = pGroup->all_servers + pGroup->alloc_size;
396 	for (ppStorage=pGroup->all_servers; ppStorage<ppEnd; ppStorage++)
397 	{
398 		if ((result=tracker_realloc_storage_path_mbs(*ppStorage, \
399 			pGroup->store_path_count, new_store_path_count)) != 0)
400 		{
401 			return result;
402 		}
403 	}
404 
405 	pGroup->store_path_count = new_store_path_count;
406 
407 	return 0;
408 }
409 
tracker_malloc_group_path_mbs(FDFSGroupInfo * pGroup)410 static int tracker_malloc_group_path_mbs(FDFSGroupInfo *pGroup)
411 {
412 	FDFSStorageDetail **ppStorage;
413 	FDFSStorageDetail **ppEnd;
414 	int result;
415 
416 	ppEnd = pGroup->all_servers + pGroup->alloc_size;
417 	for (ppStorage=pGroup->all_servers; ppStorage<ppEnd; ppStorage++)
418 	{
419 		if ((result=tracker_malloc_storage_path_mbs(*ppStorage, \
420 				pGroup->store_path_count)) != 0)
421 		{
422 			return result;
423 		}
424 	}
425 
426 	return 0;
427 }
428 
tracker_malloc_all_group_path_mbs(FDFSGroups * pGroups)429 static int tracker_malloc_all_group_path_mbs(FDFSGroups *pGroups)
430 {
431 	FDFSGroupInfo **ppGroup;
432 	FDFSGroupInfo **ppEnd;
433 	int result;
434 
435 	ppEnd = pGroups->groups + pGroups->alloc_size;
436 	for (ppGroup=pGroups->groups; ppGroup<ppEnd; ppGroup++)
437 	{
438 		if ((*ppGroup)->store_path_count == 0)
439 		{
440 			continue;
441 		}
442 
443 		if ((result=tracker_malloc_group_path_mbs(*ppGroup)) != 0)
444 		{
445 			return result;
446 		}
447 	}
448 
449 	return 0;
450 }
451 
tracker_load_groups_old(FDFSGroups * pGroups,const char * data_path)452 static int tracker_load_groups_old(FDFSGroups *pGroups, const char *data_path)
453 {
454 #define STORAGE_DATA_GROUP_FIELDS	4
455 
456 	FILE *fp;
457 	char szLine[256];
458 	char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
459 	char *fields[STORAGE_DATA_GROUP_FIELDS];
460 	int result;
461 	int col_count;
462 	TrackerClientInfo clientInfo;
463 	bool bInserted;
464 
465 	if ((fp=fopen(STORAGE_GROUPS_LIST_FILENAME_OLD, "r")) == NULL)
466 	{
467 		logError("file: "__FILE__", line: %d, " \
468 			"open file \"%s/%s\" fail, " \
469 			"errno: %d, error info: %s", \
470 			__LINE__, data_path, STORAGE_GROUPS_LIST_FILENAME_OLD, \
471 			errno, STRERROR(errno));
472 		return errno != 0 ? errno : ENOENT;
473 	}
474 
475 	result = 0;
476 	while (fgets(szLine, sizeof(szLine), fp) != NULL)
477 	{
478 		if (*szLine == '\0')
479 		{
480 			continue;
481 		}
482 
483 		col_count = splitEx(szLine, STORAGE_DATA_FIELD_SEPERATOR, \
484 			fields, STORAGE_DATA_GROUP_FIELDS);
485 		if (col_count != STORAGE_DATA_GROUP_FIELDS && \
486 			col_count != STORAGE_DATA_GROUP_FIELDS - 2)
487 		{
488 			logError("file: "__FILE__", line: %d, " \
489 				"the format of the file \"%s/%s\" is invalid", \
490 				__LINE__, data_path, \
491 				STORAGE_GROUPS_LIST_FILENAME_OLD);
492 			result = errno != 0 ? errno : EINVAL;
493 			break;
494 		}
495 
496 		memset(&clientInfo, 0, sizeof(TrackerClientInfo));
497 		snprintf(group_name, sizeof(group_name),\
498 				"%s", trim(fields[0]));
499 		if ((result=tracker_mem_add_group_ex(pGroups, &clientInfo, \
500 				group_name, false, &bInserted)) != 0)
501 		{
502 			break;
503 		}
504 
505 		if (!bInserted)
506 		{
507 			logError("file: "__FILE__", line: %d, " \
508 				"in the file \"%s/%s\", " \
509 				"group \"%s\" is duplicate", \
510 				__LINE__, data_path, \
511 				STORAGE_GROUPS_LIST_FILENAME_OLD, \
512 				group_name);
513 			result = errno != 0 ? errno : EEXIST;
514 			break;
515 		}
516 
517 		clientInfo.pGroup->storage_port = atoi(trim(fields[1]));
518 		if (col_count == STORAGE_DATA_GROUP_FIELDS - 2)
519 		{  //version < V1.12
520 			clientInfo.pGroup->store_path_count = 0;
521 			clientInfo.pGroup->subdir_count_per_path = 0;
522 		}
523 		else
524 		{
525 			clientInfo.pGroup->store_path_count = \
526 				atoi(trim(fields[2]));
527 			clientInfo.pGroup->subdir_count_per_path = \
528 				atoi(trim(fields[3]));
529 		}
530 	}
531 
532 	fclose(fp);
533 	return result;
534 }
535 
tracker_mem_get_storage_id(const char * group_name,const char * pIpAddr,char * storage_id)536 static int tracker_mem_get_storage_id(const char *group_name, \
537 		const char *pIpAddr, char *storage_id)
538 {
539 	FDFSStorageIdInfo *pStorageIdInfo;
540 	pStorageIdInfo = fdfs_get_storage_id_by_ip(group_name, pIpAddr);
541 	if (pStorageIdInfo == NULL)
542 	{
543 		return ENOENT;
544 	}
545 
546 	strcpy(storage_id, pStorageIdInfo->id);
547 	return 0;
548 }
549 
tracker_load_groups_new(FDFSGroups * pGroups,const char * data_path,FDFSStorageSync ** ppTrunkServers,int * nTrunkServerCount)550 static int tracker_load_groups_new(FDFSGroups *pGroups, const char *data_path,
551 		FDFSStorageSync **ppTrunkServers, int *nTrunkServerCount)
552 {
553 	IniContext iniContext;
554 	FDFSGroupInfo *pGroup;
555 	char *group_name;
556 	char *pValue;
557 	int nStorageSyncSize;
558 	int group_count;
559 	int result;
560 	int i;
561 	char section_name[64];
562 	TrackerClientInfo clientInfo;
563 	bool bInserted;
564 
565 	*nTrunkServerCount = 0;
566 	*ppTrunkServers = NULL;
567 	if (!fileExists(STORAGE_GROUPS_LIST_FILENAME_NEW) && \
568 	     fileExists(STORAGE_GROUPS_LIST_FILENAME_OLD))
569 	{
570 		logDebug("file: "__FILE__", line: %d, " \
571 			"convert old data file %s to new data file %s", \
572 			__LINE__, STORAGE_GROUPS_LIST_FILENAME_OLD, \
573 			STORAGE_GROUPS_LIST_FILENAME_NEW);
574 		if ((result=tracker_load_groups_old(pGroups, data_path)) == 0)
575 		{
576 			if ((result=tracker_save_groups()) == 0)
577 			{
578 				unlink(STORAGE_GROUPS_LIST_FILENAME_OLD);
579 			}
580 		}
581 
582 		return result;
583 	}
584 
585 	if ((result=iniLoadFromFile(STORAGE_GROUPS_LIST_FILENAME_NEW, \
586 			&iniContext)) != 0)
587 	{
588 		return result;
589 	}
590 
591 	group_count = iniGetIntValue(GROUP_SECTION_NAME_GLOBAL, \
592 				GROUP_ITEM_GROUP_COUNT, \
593                 		&iniContext, -1);
594 	if (group_count < 0)
595 	{
596 		iniFreeContext(&iniContext);
597 		logError("file: "__FILE__", line: %d, " \
598 			"in the file \"%s/%s\", " \
599 			"item \"%s\" is not found", \
600 			__LINE__, data_path, \
601 			STORAGE_GROUPS_LIST_FILENAME_NEW, \
602 			GROUP_ITEM_GROUP_COUNT);
603 		return ENOENT;
604 	}
605 
606 	nStorageSyncSize = 0;
607 	for (i=1; i<=group_count; i++)
608 	{
609 		sprintf(section_name, "%s"GROUP_SECTION_NO_FORMAT, \
610 			GROUP_SECTION_NAME_PREFIX, i);
611 
612 		group_name = iniGetStrValue(section_name, \
613 				GROUP_ITEM_GROUP_NAME, &iniContext);
614 		if (group_name == NULL)
615 		{
616 			logError("file: "__FILE__", line: %d, " \
617 				"in the file \"%s/%s\", " \
618 				"item \"%s\" is not found", \
619 				__LINE__, data_path, \
620 				STORAGE_GROUPS_LIST_FILENAME_NEW, \
621 				GROUP_ITEM_GROUP_NAME);
622 			result = ENOENT;
623 			break;
624 		}
625 
626 		memset(&clientInfo, 0, sizeof(TrackerClientInfo));
627 		if ((result=tracker_mem_add_group_ex(pGroups, &clientInfo, \
628 				group_name, false, &bInserted)) != 0)
629 		{
630 			break;
631 		}
632 
633 		if (!bInserted)
634 		{
635 			logError("file: "__FILE__", line: %d, " \
636 				"in the file \"%s/%s\", " \
637 				"group \"%s\" is duplicate", \
638 				__LINE__, data_path, \
639 				STORAGE_GROUPS_LIST_FILENAME_NEW, \
640 				group_name);
641 			result = errno != 0 ? errno : EEXIST;
642 			break;
643 		}
644 
645 		pGroup = clientInfo.pGroup;
646 		pGroup->storage_port = iniGetIntValue(section_name, \
647 			GROUP_ITEM_STORAGE_PORT, &iniContext, 0);
648 		pGroup->storage_http_port = iniGetIntValue(section_name, \
649 			GROUP_ITEM_STORAGE_HTTP_PORT, &iniContext, 0);
650 		pGroup->store_path_count = iniGetIntValue(section_name, \
651 			GROUP_ITEM_STORE_PATH_COUNT, &iniContext, 0);
652 		pGroup->subdir_count_per_path = iniGetIntValue(section_name, \
653 			GROUP_ITEM_SUBDIR_COUNT_PER_PATH, &iniContext, 0);
654 		pGroup->current_trunk_file_id = iniGetIntValue(section_name, \
655 			GROUP_ITEM_CURRENT_TRUNK_FILE_ID, &iniContext, 0);
656 		pValue = iniGetStrValue(section_name, \
657 			GROUP_ITEM_LAST_TRUNK_SERVER, &iniContext);
658 		if (pValue != NULL)
659 		{
660 			snprintf(pGroup->last_trunk_server_id,
661 				sizeof(pGroup->last_trunk_server_id), \
662 				"%s", pValue);
663 			if (g_use_storage_id && (*pValue != '\0' && \
664 				!fdfs_is_server_id_valid(pValue)))
665 			{
666 				if (tracker_mem_get_storage_id( \
667 					pGroup->group_name, pValue, \
668 					pGroup->last_trunk_server_id) != 0)
669 				{
670 					logWarning("file: "__FILE__", line: %d,"\
671 						"server id of group name: %s " \
672 						"and last trunk ip address: %s"\
673 						" NOT exist", __LINE__, \
674 						pGroup->group_name, pValue);
675 					*pGroup->last_trunk_server_id = '\0';
676 				}
677 			}
678 		}
679 
680 		pValue = iniGetStrValue(section_name, \
681 			GROUP_ITEM_TRUNK_SERVER, &iniContext);
682 		if (pValue != NULL && *pValue != '\0')
683 		{
684 		if (nStorageSyncSize <= *nTrunkServerCount)
685 		{
686 			nStorageSyncSize += 8;
687 			*ppTrunkServers = (FDFSStorageSync *)realloc( \
688 				*ppTrunkServers, \
689 				sizeof(FDFSStorageSync) * nStorageSyncSize);
690 			if (*ppTrunkServers == NULL)
691 			{
692 				result = errno != 0 ? errno : ENOMEM;
693 				logError("file: "__FILE__", line: %d, " \
694 					"realloc %d bytes fail", __LINE__, \
695 					(int)sizeof(FDFSStorageSync) * \
696 					nStorageSyncSize);
697 				break;
698 			}
699 		}
700 
701 		strcpy((*ppTrunkServers)[*nTrunkServerCount].group_name, \
702 			clientInfo.pGroup->group_name);
703 		snprintf((*ppTrunkServers)[*nTrunkServerCount].id, \
704 			FDFS_STORAGE_ID_MAX_SIZE, "%s", pValue);
705 		if (g_use_storage_id && !fdfs_is_server_id_valid(pValue))
706 		{
707 			if ((result=tracker_mem_get_storage_id( \
708 				clientInfo.pGroup->group_name, pValue, \
709 				(*ppTrunkServers)[*nTrunkServerCount].id)) != 0)
710 			{
711 				logError("file: "__FILE__", line: %d, " \
712 					"server id of group name: %s and " \
713 					"trunk server ip address: %s NOT " \
714 					"exist", __LINE__, \
715 					clientInfo.pGroup->group_name, pValue);
716 				break;
717 			}
718 		}
719 
720 		(*nTrunkServerCount)++;
721 		}
722 	}
723 
724 	iniFreeContext(&iniContext);
725 
726 	return result;
727 }
728 
tracker_locate_group_trunk_servers(FDFSGroups * pGroups,FDFSStorageSync * pTrunkServers,const int nTrunkServerCount,const bool bLoadFromFile)729 static int tracker_locate_group_trunk_servers(FDFSGroups *pGroups, \
730 		FDFSStorageSync *pTrunkServers, \
731 		const int nTrunkServerCount, const bool bLoadFromFile)
732 {
733 	FDFSGroupInfo *pGroup;
734 	FDFSStorageDetail *pStorage;
735 	FDFSStorageSync *pServer;
736 	FDFSStorageSync *pTrunkEnd;
737 
738 	if (nTrunkServerCount == 0)
739 	{
740 		return 0;
741 	}
742 
743 	pTrunkEnd = pTrunkServers + nTrunkServerCount;
744 	for (pServer=pTrunkServers; pServer<pTrunkEnd; pServer++)
745 	{
746 		pGroup = tracker_mem_get_group_ex(pGroups, \
747 				pServer->group_name);
748 		if (pGroup == NULL)
749 		{
750 			continue;
751 		}
752 
753 		pStorage = tracker_mem_get_storage(pGroup, pServer->id);
754 		if (pStorage == NULL)
755 		{
756 			char buff[MAX_PATH_SIZE+64];
757 			if (bLoadFromFile)
758 			{
759 				snprintf(buff, sizeof(buff), \
760 					"in the file \"%s/data/%s\", ", \
761 					g_fdfs_base_path, \
762 					STORAGE_GROUPS_LIST_FILENAME_NEW);
763 			}
764 			else
765 			{
766 				*buff = '\0';
767 			}
768 
769 			logError("file: "__FILE__", line: %d, " \
770 				"%sgroup_name: %s, trunk server \"%s\" " \
771 				"does not exist", __LINE__, buff, \
772 				pServer->group_name, pServer->id);
773 
774 			return ENOENT;
775 		}
776 
777 		pGroup->pTrunkServer = pStorage;
778 		pGroup->trunk_chg_count++;
779 		if (*(pGroup->last_trunk_server_id) == '\0')
780 		{
781 			strcpy(pGroup->last_trunk_server_id, pStorage->id);
782 		}
783 	}
784 
785 	return 0;
786 }
787 
tracker_locate_storage_sync_server(FDFSGroups * pGroups,FDFSStorageSync * pStorageSyncs,const int nStorageSyncCount,const bool bLoadFromFile)788 static int tracker_locate_storage_sync_server(FDFSGroups *pGroups, \
789 		FDFSStorageSync *pStorageSyncs, \
790 		const int nStorageSyncCount, const bool bLoadFromFile)
791 {
792 	FDFSGroupInfo *pGroup;
793 	FDFSStorageDetail *pStorage;
794 	FDFSStorageSync *pSyncServer;
795 	FDFSStorageSync *pSyncEnd;
796 
797 	if (nStorageSyncCount == 0)
798 	{
799 		return 0;
800 	}
801 
802 	pSyncEnd = pStorageSyncs + nStorageSyncCount;
803 	for (pSyncServer=pStorageSyncs; pSyncServer<pSyncEnd; pSyncServer++)
804 	{
805 		pGroup = tracker_mem_get_group_ex(pGroups, \
806 				pSyncServer->group_name);
807 		if (pGroup == NULL)
808 		{
809 			continue;
810 		}
811 
812 		pStorage=tracker_mem_get_storage(pGroup, pSyncServer->id);
813 		if (pStorage == NULL)
814 		{
815 			continue;
816 		}
817 
818 		pStorage->psync_src_server = tracker_mem_get_storage(pGroup, \
819 			pSyncServer->sync_src_id);
820 		if (pStorage->psync_src_server == NULL)
821 		{
822 			char buff[MAX_PATH_SIZE+64];
823 			if (bLoadFromFile)
824 			{
825 				snprintf(buff, sizeof(buff), \
826 					"in the file \"%s/data/%s\", ", \
827 					g_fdfs_base_path, \
828 					STORAGE_SERVERS_LIST_FILENAME_NEW);
829 			}
830 			else
831 			{
832 				*buff = '\0';
833 			}
834 
835 			logError("file: "__FILE__", line: %d, " \
836 				"%sgroup_name: %s, storage server \"%s\" " \
837 				"does not exist", __LINE__, buff, \
838 				pSyncServer->group_name, \
839 				pSyncServer->sync_src_id);
840 
841 			return ENOENT;
842 		}
843 	}
844 
845 	return 0;
846 }
847 
tracker_load_storages_old(FDFSGroups * pGroups,const char * data_path)848 static int tracker_load_storages_old(FDFSGroups *pGroups, const char *data_path)
849 {
850 #define STORAGE_DATA_SERVER_FIELDS	22
851 
852 	FILE *fp;
853 	char szLine[256];
854 	char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
855 	char *fields[STORAGE_DATA_SERVER_FIELDS];
856 	char ip_addr[IP_ADDRESS_SIZE];
857 	char *psync_src_id;
858 	FDFSStorageDetail *pStorage;
859 	FDFSStorageSync *pStorageSyncs;
860 	int nStorageSyncSize;
861 	int nStorageSyncCount;
862 	int cols;
863 	int result;
864 	TrackerClientInfo clientInfo;
865 	bool bInserted;
866 
867 	if ((fp=fopen(STORAGE_SERVERS_LIST_FILENAME_OLD, "r")) == NULL)
868 	{
869 		logError("file: "__FILE__", line: %d, " \
870 			"open file \"%s/%s\" fail, " \
871 			"errno: %d, error info: %s", \
872 			__LINE__, data_path, STORAGE_SERVERS_LIST_FILENAME_OLD, \
873 			errno, STRERROR(errno));
874 		return errno != 0 ? errno : ENOENT;
875 	}
876 
877 	nStorageSyncSize = 0;
878 	nStorageSyncCount = 0;
879 	pStorageSyncs = NULL;
880 	result = 0;
881 	while (fgets(szLine, sizeof(szLine), fp) != NULL)
882 	{
883 		if (*szLine == '\0')
884 		{
885 			continue;
886 		}
887 
888 		cols = splitEx(szLine, STORAGE_DATA_FIELD_SEPERATOR, \
889 				fields, STORAGE_DATA_SERVER_FIELDS);
890 		if (cols != STORAGE_DATA_SERVER_FIELDS && \
891 		    cols != STORAGE_DATA_SERVER_FIELDS - 2 && \
892 		    cols != STORAGE_DATA_SERVER_FIELDS - 4 && \
893 		    cols != STORAGE_DATA_SERVER_FIELDS - 5)
894 		{
895 			logError("file: "__FILE__", line: %d, " \
896 				"the format of the file \"%s/%s\" is invalid" \
897 				", colums: %d != expect colums: " \
898 				"%d or %d or %d or %d", \
899 				__LINE__, data_path, \
900 				STORAGE_SERVERS_LIST_FILENAME_OLD, \
901 				cols, STORAGE_DATA_SERVER_FIELDS, \
902 				STORAGE_DATA_SERVER_FIELDS - 2, \
903 				STORAGE_DATA_SERVER_FIELDS - 4, \
904 				STORAGE_DATA_SERVER_FIELDS - 5);
905 			result = EINVAL;
906 			break;
907 		}
908 
909 		memset(&clientInfo, 0, sizeof(TrackerClientInfo));
910 		snprintf(group_name, sizeof(group_name), "%s", trim(fields[0]));
911 		snprintf(ip_addr, sizeof(ip_addr), "%s", trim(fields[1]));
912 		if ((clientInfo.pGroup=tracker_mem_get_group_ex(pGroups, \
913 						group_name)) == NULL)
914 		{
915 			logError("file: "__FILE__", line: %d, " \
916 				"in the file \"%s/%s\", " \
917 				"group \"%s\" is not found", \
918 				__LINE__, data_path, \
919 				STORAGE_SERVERS_LIST_FILENAME_OLD, \
920 				group_name);
921 			result = errno != 0 ? errno : ENOENT;
922 			break;
923 		}
924 
925 		if ((result=tracker_mem_add_storage(&clientInfo, NULL, ip_addr,
926 				false, false, &bInserted)) != 0)
927 		{
928 			break;
929 		}
930 
931 		if (!bInserted)
932 		{
933 			logError("file: "__FILE__", line: %d, " \
934 				"in the file \"%s/%s\", " \
935 				"storage \"%s\" is duplicate", \
936 				__LINE__, data_path, \
937 				STORAGE_SERVERS_LIST_FILENAME_OLD, ip_addr);
938 			result = errno != 0 ? errno : EEXIST;
939 			break;
940 		}
941 
942 		pStorage = clientInfo.pStorage;
943 		pStorage->status = atoi(trim_left(fields[2]));
944 		if (!((pStorage->status == \
945 				FDFS_STORAGE_STATUS_WAIT_SYNC) || \
946 			(pStorage->status == \
947 				FDFS_STORAGE_STATUS_SYNCING) || \
948 			(pStorage->status == \
949 				FDFS_STORAGE_STATUS_INIT)))
950 		{
951 			pStorage->status = \
952 				FDFS_STORAGE_STATUS_OFFLINE;
953 		}
954 
955 		psync_src_id = trim(fields[3]);
956 		pStorage->sync_until_timestamp = atoi( \
957 					trim_left(fields[4]));
958 		pStorage->stat.total_upload_count = strtoll( \
959 					trim_left(fields[5]), NULL, 10);
960 		pStorage->stat.success_upload_count = strtoll( \
961 					trim_left(fields[6]), NULL, 10);
962 		pStorage->stat.total_set_meta_count = strtoll( \
963 					trim_left(fields[7]), NULL, 10);
964 		pStorage->stat.success_set_meta_count = strtoll( \
965 					trim_left(fields[8]), NULL, 10);
966 		pStorage->stat.total_delete_count = strtoll( \
967 					trim_left(fields[9]), NULL, 10);
968 		pStorage->stat.success_delete_count = strtoll( \
969 					trim_left(fields[10]), NULL, 10);
970 		pStorage->stat.total_download_count = strtoll( \
971 					trim_left(fields[11]), NULL, 10);
972 		pStorage->stat.success_download_count = strtoll( \
973 					trim_left(fields[12]), NULL, 10);
974 		pStorage->stat.total_get_meta_count = strtoll( \
975 					trim_left(fields[13]), NULL, 10);
976 		pStorage->stat.success_get_meta_count = strtoll( \
977 					trim_left(fields[14]), NULL, 10);
978 		pStorage->stat.last_source_update = atoi( \
979 					trim_left(fields[15]));
980 		pStorage->stat.last_sync_update = atoi( \
981 					trim_left(fields[16]));
982 		if (cols > STORAGE_DATA_SERVER_FIELDS - 5)
983 		{
984 			pStorage->changelog_offset = strtoll( \
985 					trim_left(fields[17]), NULL, 10);
986 			if (pStorage->changelog_offset < 0)
987 			{
988 				pStorage->changelog_offset = 0;
989 			}
990 			if (pStorage->changelog_offset > \
991 				g_changelog_fsize)
992 			{
993 				pStorage->changelog_offset = \
994 					g_changelog_fsize;
995 			}
996 
997 			if (cols > STORAGE_DATA_SERVER_FIELDS - 4)
998 			{
999 				pStorage->storage_port = \
1000 					atoi(trim_left(fields[18]));
1001 				pStorage->storage_http_port = \
1002 					atoi(trim_left(fields[19]));
1003 				if (cols > STORAGE_DATA_SERVER_FIELDS - 2)
1004 				{
1005 					pStorage->join_time = \
1006 					(time_t)atoi(trim_left(fields[20]));
1007 
1008 					snprintf(pStorage->version, \
1009 					sizeof(pStorage->version),
1010 					 "%s", trim(fields[21]));
1011 				}
1012 			}
1013 		}
1014 
1015 		if (*psync_src_id == '\0')
1016 		{
1017 			continue;
1018 		}
1019 
1020 		if (nStorageSyncSize <= nStorageSyncCount)
1021 		{
1022 			nStorageSyncSize += 8;
1023 			pStorageSyncs = (FDFSStorageSync *)realloc( \
1024 				pStorageSyncs, \
1025 				sizeof(FDFSStorageSync) * nStorageSyncSize);
1026 			if (pStorageSyncs == NULL)
1027 			{
1028 				result = errno != 0 ? errno : ENOMEM;
1029 				logError("file: "__FILE__", line: %d, " \
1030 					"realloc %d bytes fail", __LINE__, \
1031 					(int)sizeof(FDFSStorageSync) * \
1032 					nStorageSyncSize);
1033 				break;
1034 			}
1035 		}
1036 
1037 		strcpy(pStorageSyncs[nStorageSyncCount].group_name, \
1038 			clientInfo.pGroup->group_name);
1039 		strcpy(pStorageSyncs[nStorageSyncCount].id, pStorage->id);
1040 		snprintf(pStorageSyncs[nStorageSyncCount].sync_src_id, \
1041 			FDFS_STORAGE_ID_MAX_SIZE, "%s", psync_src_id);
1042 
1043 		nStorageSyncCount++;
1044 
1045 	}
1046 
1047 	fclose(fp);
1048 
1049 	if (pStorageSyncs == NULL)
1050 	{
1051 		return result;
1052 	}
1053 
1054 	if (result != 0)
1055 	{
1056 		free(pStorageSyncs);
1057 		return result;
1058 	}
1059 
1060 	result = tracker_locate_storage_sync_server(pGroups, pStorageSyncs, \
1061 			nStorageSyncCount, true);
1062 	free(pStorageSyncs);
1063 	return result;
1064 }
1065 
tracker_load_storages_new(FDFSGroups * pGroups,const char * data_path)1066 static int tracker_load_storages_new(FDFSGroups *pGroups, const char *data_path)
1067 {
1068 	IniContext iniContext;
1069 	char *group_name;
1070 	char *storage_id;
1071 	char *ip_addr;
1072 	char *psync_src_id;
1073 	char *pValue;
1074 	FDFSStorageDetail *pStorage;
1075 	FDFSStorageStat *pStat;
1076 	FDFSStorageSync *pStorageSyncs;
1077 	int nStorageSyncSize;
1078 	int nStorageSyncCount;
1079 	int storage_count;
1080 	int i;
1081 	int result;
1082 	char section_name[64];
1083 	TrackerClientInfo clientInfo;
1084 
1085 	if (!fileExists(STORAGE_SERVERS_LIST_FILENAME_NEW) && \
1086 	     fileExists(STORAGE_SERVERS_LIST_FILENAME_OLD))
1087 	{
1088 		logDebug("file: "__FILE__", line: %d, " \
1089 			"convert old data file %s to new data file %s", \
1090 			__LINE__, STORAGE_SERVERS_LIST_FILENAME_OLD, \
1091 			STORAGE_SERVERS_LIST_FILENAME_NEW);
1092 		if ((result=tracker_load_storages_old(pGroups, data_path)) == 0)
1093 		{
1094 			if ((result=tracker_save_storages()) == 0)
1095 			{
1096 				unlink(STORAGE_SERVERS_LIST_FILENAME_OLD);
1097 			}
1098 		}
1099 
1100 		return result;
1101 	}
1102 
1103 	if ((result=iniLoadFromFile(STORAGE_SERVERS_LIST_FILENAME_NEW, \
1104 			&iniContext)) != 0)
1105 	{
1106 		return result;
1107 	}
1108 
1109 	storage_count = iniGetIntValue(STORAGE_SECTION_NAME_GLOBAL, \
1110 				STORAGE_ITEM_STORAGE_COUNT, \
1111                 		&iniContext, -1);
1112 	if (storage_count < 0)
1113 	{
1114 		iniFreeContext(&iniContext);
1115 		logError("file: "__FILE__", line: %d, " \
1116 			"in the file \"%s/%s\", " \
1117 			"item \"%s\" is not found", \
1118 			__LINE__, data_path, \
1119 			STORAGE_SERVERS_LIST_FILENAME_NEW, \
1120 			STORAGE_ITEM_STORAGE_COUNT);
1121 		return ENOENT;
1122 	}
1123 
1124 	nStorageSyncSize = 0;
1125 	nStorageSyncCount = 0;
1126 	pStorageSyncs = NULL;
1127 	result = 0;
1128 	for (i=1; i<=storage_count; i++)
1129 	{
1130 		sprintf(section_name, "%s"STORAGE_SECTION_NO_FORMAT, \
1131 			STORAGE_SECTION_NAME_PREFIX, i);
1132 
1133 		group_name = iniGetStrValue(section_name, \
1134 				STORAGE_ITEM_GROUP_NAME, &iniContext);
1135 		if (group_name == NULL)
1136 		{
1137 			logError("file: "__FILE__", line: %d, " \
1138 				"in the file \"%s/%s\", " \
1139 				"item \"%s\" is not found", \
1140 				__LINE__, data_path, \
1141 				STORAGE_SERVERS_LIST_FILENAME_NEW, \
1142 				STORAGE_ITEM_GROUP_NAME);
1143 			result = ENOENT;
1144 			break;
1145 		}
1146 
1147 		storage_id = iniGetStrValue(section_name, \
1148 				STORAGE_ITEM_SERVER_ID, &iniContext);
1149 
1150 		ip_addr = iniGetStrValue(section_name, \
1151 				STORAGE_ITEM_IP_ADDR, &iniContext);
1152 
1153         if ((result=tracker_mem_add_storage_from_file(pGroups,
1154                         data_path, &clientInfo, group_name,
1155                         storage_id, ip_addr)) != 0)
1156         {
1157             break;
1158         }
1159 
1160 		pStorage = clientInfo.pStorage;
1161 		pStat = &(pStorage->stat);
1162 		pStorage->status = iniGetIntValue(section_name, \
1163 				STORAGE_ITEM_STATUS, &iniContext, 0);
1164 
1165 		pValue = iniGetStrValue(section_name, \
1166 				STORAGE_ITEM_DOMAIN_NAME, &iniContext);
1167 		if (pValue != NULL)
1168 		{
1169 			snprintf(pStorage->domain_name, \
1170 				sizeof(pStorage->domain_name), "%s", pValue);
1171 		}
1172 
1173 		pValue = iniGetStrValue(section_name, \
1174 				STORAGE_ITEM_VERSION, &iniContext);
1175 		if (pValue != NULL)
1176 		{
1177 			snprintf(pStorage->version, \
1178 				sizeof(pStorage->version), "%s", pValue);
1179 		}
1180 
1181 		if (!((pStorage->status == \
1182 				FDFS_STORAGE_STATUS_WAIT_SYNC) || \
1183 			(pStorage->status == \
1184 				FDFS_STORAGE_STATUS_SYNCING) || \
1185 			(pStorage->status == \
1186 				FDFS_STORAGE_STATUS_INIT)))
1187 		{
1188 			pStorage->status = FDFS_STORAGE_STATUS_OFFLINE;
1189 		}
1190 
1191 		psync_src_id = iniGetStrValue(section_name, \
1192 				STORAGE_ITEM_SYNC_SRC_SERVER, &iniContext);
1193 		if (psync_src_id == NULL)
1194 		{
1195 			psync_src_id = "";
1196 		}
1197 
1198 		pStorage->sync_until_timestamp = iniGetIntValue(section_name, \
1199 			STORAGE_ITEM_SYNC_UNTIL_TIMESTAMP, &iniContext, 0);
1200 		pStorage->join_time = iniGetIntValue(section_name, \
1201 			STORAGE_ITEM_JOIN_TIME, &iniContext, 0);
1202 		pStorage->total_mb = iniGetInt64Value(section_name, \
1203 			STORAGE_ITEM_TOTAL_MB, &iniContext, 0);
1204 		pStorage->free_mb = iniGetInt64Value(section_name, \
1205 			STORAGE_ITEM_FREE_MB, &iniContext, 0);
1206 		pStorage->store_path_count = iniGetIntValue(section_name, \
1207 			STORAGE_ITEM_STORE_PATH_COUNT, &iniContext, 0);
1208 		pStorage->subdir_count_per_path = iniGetIntValue(section_name, \
1209 			STORAGE_ITEM_SUBDIR_COUNT_PER_PATH, &iniContext, 0);
1210 		pStorage->upload_priority = iniGetIntValue(section_name, \
1211 			STORAGE_ITEM_UPLOAD_PRIORITY, &iniContext, 0);
1212 		pStorage->storage_port = iniGetIntValue(section_name, \
1213 			STORAGE_ITEM_STORAGE_PORT, &iniContext, 0);
1214 		pStorage->storage_http_port = iniGetIntValue(section_name, \
1215 			STORAGE_ITEM_STORAGE_HTTP_PORT, &iniContext, 0);
1216 		pStat->total_upload_count = iniGetInt64Value(section_name, \
1217 			STORAGE_ITEM_TOTAL_UPLOAD_COUNT, &iniContext, 0);
1218 		pStat->success_upload_count = iniGetInt64Value(section_name, \
1219 			STORAGE_ITEM_SUCCESS_UPLOAD_COUNT, &iniContext, 0);
1220 		pStat->total_append_count = iniGetInt64Value(section_name, \
1221 			STORAGE_ITEM_TOTAL_APPEND_COUNT, &iniContext, 0);
1222 		pStat->success_append_count = iniGetInt64Value(section_name, \
1223 			STORAGE_ITEM_SUCCESS_APPEND_COUNT, &iniContext, 0);
1224 		pStat->total_set_meta_count = iniGetInt64Value(section_name, \
1225 			STORAGE_ITEM_TOTAL_SET_META_COUNT, &iniContext, 0);
1226 		pStat->success_set_meta_count = iniGetInt64Value(section_name, \
1227 			STORAGE_ITEM_SUCCESS_SET_META_COUNT, &iniContext, 0);
1228 		pStat->total_delete_count = iniGetInt64Value(section_name, \
1229 			STORAGE_ITEM_TOTAL_DELETE_COUNT, &iniContext, 0);
1230 		pStat->success_delete_count = iniGetInt64Value(section_name, \
1231 			STORAGE_ITEM_SUCCESS_DELETE_COUNT, &iniContext, 0);
1232 		pStat->total_download_count = iniGetInt64Value(section_name, \
1233 			STORAGE_ITEM_TOTAL_DOWNLOAD_COUNT, &iniContext, 0);
1234 		pStat->success_download_count = iniGetInt64Value(section_name, \
1235 			STORAGE_ITEM_SUCCESS_DOWNLOAD_COUNT, &iniContext, 0);
1236 		pStat->total_get_meta_count = iniGetInt64Value(section_name, \
1237 			STORAGE_ITEM_TOTAL_GET_META_COUNT, &iniContext, 0);
1238 		pStat->success_get_meta_count = iniGetInt64Value(section_name, \
1239 			STORAGE_ITEM_SUCCESS_GET_META_COUNT, &iniContext, 0);
1240 		pStat->total_create_link_count = iniGetInt64Value(section_name, \
1241 			STORAGE_ITEM_TOTAL_CREATE_LINK_COUNT, &iniContext, 0);
1242 		pStat->success_create_link_count = iniGetInt64Value(section_name, \
1243 			STORAGE_ITEM_SUCCESS_CREATE_LINK_COUNT, &iniContext, 0);
1244 		pStat->total_delete_link_count = iniGetInt64Value(section_name, \
1245 			STORAGE_ITEM_TOTAL_DELETE_LINK_COUNT, &iniContext, 0);
1246 		pStat->success_delete_link_count = iniGetInt64Value(section_name, \
1247 			STORAGE_ITEM_SUCCESS_DELETE_LINK_COUNT, &iniContext, 0);
1248 		pStat->total_upload_bytes = iniGetInt64Value(section_name, \
1249 			STORAGE_ITEM_TOTAL_UPLOAD_BYTES, &iniContext, 0);
1250 		pStat->success_upload_bytes = iniGetInt64Value(section_name, \
1251 			STORAGE_ITEM_SUCCESS_UPLOAD_BYTES, &iniContext, 0);
1252 		pStat->total_append_bytes = iniGetInt64Value(section_name, \
1253 			STORAGE_ITEM_TOTAL_APPEND_BYTES, &iniContext, 0);
1254 		pStat->success_append_bytes = iniGetInt64Value(section_name, \
1255 			STORAGE_ITEM_SUCCESS_APPEND_BYTES, &iniContext, 0);
1256 		pStat->total_download_bytes = iniGetInt64Value(section_name, \
1257 			STORAGE_ITEM_TOTAL_DOWNLOAD_BYTES, &iniContext, 0);
1258 		pStat->success_download_bytes = iniGetInt64Value(section_name, \
1259 			STORAGE_ITEM_SUCCESS_DOWNLOAD_BYTES, &iniContext, 0);
1260 		pStat->total_sync_in_bytes = iniGetInt64Value(section_name, \
1261 			STORAGE_ITEM_TOTAL_SYNC_IN_BYTES, &iniContext, 0);
1262 		pStat->success_sync_in_bytes = iniGetInt64Value(section_name, \
1263 			STORAGE_ITEM_SUCCESS_SYNC_IN_BYTES, &iniContext, 0);
1264 		pStat->total_sync_out_bytes = iniGetInt64Value(section_name, \
1265 			STORAGE_ITEM_TOTAL_SYNC_OUT_BYTES, &iniContext, 0);
1266 		pStat->success_sync_out_bytes = iniGetInt64Value(section_name, \
1267 			STORAGE_ITEM_SUCCESS_SYNC_OUT_BYTES, &iniContext, 0);
1268 		pStat->total_file_open_count = iniGetInt64Value(section_name, \
1269 			STORAGE_ITEM_TOTAL_FILE_OPEN_COUNT, &iniContext, 0);
1270 		pStat->success_file_open_count = iniGetInt64Value(section_name, \
1271 			STORAGE_ITEM_SUCCESS_FILE_OPEN_COUNT, &iniContext, 0);
1272 		pStat->total_file_read_count = iniGetInt64Value(section_name, \
1273 			STORAGE_ITEM_TOTAL_FILE_READ_COUNT, &iniContext, 0);
1274 		pStat->success_file_read_count = iniGetInt64Value(section_name, \
1275 			STORAGE_ITEM_SUCCESS_FILE_READ_COUNT, &iniContext, 0);
1276 		pStat->total_file_write_count = iniGetInt64Value(section_name, \
1277 			STORAGE_ITEM_TOTAL_FILE_WRITE_COUNT, &iniContext, 0);
1278 		pStat->success_file_write_count = iniGetInt64Value(section_name, \
1279 			STORAGE_ITEM_SUCCESS_FILE_WRITE_COUNT, &iniContext, 0);
1280 		pStat->last_source_update = iniGetIntValue(section_name, \
1281 			STORAGE_ITEM_LAST_SOURCE_UPDATE, &iniContext, 0);
1282 		pStat->last_sync_update = iniGetIntValue(section_name, \
1283 			STORAGE_ITEM_LAST_SYNC_UPDATE, &iniContext, 0);
1284 		pStat->last_synced_timestamp = iniGetIntValue(section_name, \
1285 			STORAGE_ITEM_LAST_SYNCED_TIMESTAMP, &iniContext, 0);
1286 		pStat->last_heart_beat_time = iniGetIntValue(section_name, \
1287 			STORAGE_ITEM_LAST_HEART_BEAT_TIME, &iniContext, 0);
1288 		pStorage->changelog_offset = iniGetInt64Value(section_name, \
1289 			STORAGE_ITEM_CHANGELOG_OFFSET, &iniContext, 0);
1290 
1291 		if (*psync_src_id == '\0')
1292 		{
1293 			continue;
1294 		}
1295 
1296 		if (nStorageSyncSize <= nStorageSyncCount)
1297 		{
1298 			if (nStorageSyncSize == 0)
1299 			{
1300 				nStorageSyncSize = 8;
1301 			}
1302 			else
1303 			{
1304 				nStorageSyncSize *= 2;
1305 			}
1306 			pStorageSyncs = (FDFSStorageSync *)realloc( \
1307 				pStorageSyncs, \
1308 				sizeof(FDFSStorageSync) * nStorageSyncSize);
1309 			if (pStorageSyncs == NULL)
1310 			{
1311 				result = errno != 0 ? errno : ENOMEM;
1312 				logError("file: "__FILE__", line: %d, " \
1313 					"realloc %d bytes fail", __LINE__, \
1314 					(int)sizeof(FDFSStorageSync) * \
1315 					nStorageSyncSize);
1316 				break;
1317 			}
1318 		}
1319 
1320 		strcpy(pStorageSyncs[nStorageSyncCount].group_name, \
1321 			clientInfo.pGroup->group_name);
1322 		strcpy(pStorageSyncs[nStorageSyncCount].id, pStorage->id);
1323 		snprintf(pStorageSyncs[nStorageSyncCount].sync_src_id, \
1324 			FDFS_STORAGE_ID_MAX_SIZE, "%s", psync_src_id);
1325 		if (g_use_storage_id && !fdfs_is_server_id_valid( \
1326 						psync_src_id))
1327 		{
1328 			if ((result=tracker_mem_get_storage_id( \
1329 				clientInfo.pGroup->group_name, psync_src_id, \
1330 				pStorageSyncs[nStorageSyncCount].sync_src_id))\
1331 				 != 0)
1332 			{
1333 				logError("file: "__FILE__", line: %d, " \
1334 					"server id of group name: %s and " \
1335 					"src storage ip address: %s NOT " \
1336 					"exist", __LINE__, \
1337 					clientInfo.pGroup->group_name, \
1338 					psync_src_id);
1339 				break;
1340 			}
1341 		}
1342 
1343 		nStorageSyncCount++;
1344 	}
1345 
1346 	iniFreeContext(&iniContext);
1347 
1348 	if (pStorageSyncs == NULL)
1349 	{
1350 		return result;
1351 	}
1352 
1353 	if (result != 0)
1354 	{
1355 		free(pStorageSyncs);
1356 		return result;
1357 	}
1358 
1359 	result = tracker_locate_storage_sync_server(pGroups, pStorageSyncs, \
1360 			nStorageSyncCount, true);
1361 	free(pStorageSyncs);
1362 	return result;
1363 }
1364 
tracker_load_sync_timestamps(FDFSGroups * pGroups,const char * data_path)1365 static int tracker_load_sync_timestamps(FDFSGroups *pGroups, const char *data_path)
1366 {
1367 #define STORAGE_SYNC_TIME_MAX_FIELDS	2 + FDFS_MAX_SERVERS_EACH_GROUP
1368 
1369 	FILE *fp;
1370 	char szLine[512];
1371 	char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
1372 	char previous_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
1373 	char src_storage_id[FDFS_STORAGE_ID_MAX_SIZE];
1374 	char *fields[STORAGE_SYNC_TIME_MAX_FIELDS];
1375 	FDFSGroupInfo **ppGroup;
1376 	FDFSGroupInfo **ppEnd;
1377 	FDFSGroupInfo *pGroup;
1378 	int cols;
1379 	int src_index;
1380 	int dest_index;
1381 	int curr_synced_timestamp;
1382 	int result;
1383 
1384 	if (!fileExists(STORAGE_SYNC_TIMESTAMP_FILENAME))
1385 	{
1386 		return 0;
1387 	}
1388 
1389 	if ((fp=fopen(STORAGE_SYNC_TIMESTAMP_FILENAME, "r")) == NULL)
1390 	{
1391 		logError("file: "__FILE__", line: %d, " \
1392 			"open file \"%s/%s\" fail, " \
1393 			"errno: %d, error info: %s", \
1394 			__LINE__, data_path, STORAGE_SYNC_TIMESTAMP_FILENAME, \
1395 			errno, STRERROR(errno));
1396 		return errno != 0 ? errno : ENOENT;
1397 	}
1398 
1399 	pGroup = NULL;
1400 	src_index = 0;
1401 	*previous_group_name = '\0';
1402 	result = 0;
1403 	while (fgets(szLine, sizeof(szLine), fp) != NULL)
1404 	{
1405 		if (*szLine == '\0' || *szLine == '\n')
1406 		{
1407 			continue;
1408 		}
1409 
1410 		if ((cols=splitEx(szLine, STORAGE_DATA_FIELD_SEPERATOR, \
1411 			fields, STORAGE_SYNC_TIME_MAX_FIELDS)) <= 2)
1412 		{
1413 			logError("file: "__FILE__", line: %d, " \
1414 				"the format of the file \"%s/%s\" is invalid" \
1415 				", colums: %d <= 2", \
1416 				__LINE__, data_path, \
1417 				STORAGE_SYNC_TIMESTAMP_FILENAME, cols);
1418 			result = errno != 0 ? errno : EINVAL;
1419 			break;
1420 		}
1421 
1422 		snprintf(group_name, sizeof(group_name), \
1423 				"%s", trim(fields[0]));
1424 		snprintf(src_storage_id, sizeof(src_storage_id), \
1425 				"%s", trim(fields[1]));
1426 		if (strcmp(group_name, previous_group_name) != 0 || \
1427 			pGroup == NULL)
1428 		{
1429 			if ((pGroup=tracker_mem_get_group_ex(pGroups, \
1430 						group_name)) == NULL)
1431 			{
1432 				logError("file: "__FILE__", line: %d, " \
1433 					"in the file \"%s/%s\", " \
1434 					"group \"%s\" is not found", \
1435 					__LINE__, data_path, \
1436 					STORAGE_SYNC_TIMESTAMP_FILENAME, \
1437 					group_name);
1438 				result = errno != 0 ? errno : ENOENT;
1439 				break;
1440 			}
1441 
1442 			strcpy(previous_group_name, group_name);
1443 			src_index = 0;
1444 		}
1445 
1446 		if (src_index >= pGroup->count)
1447 		{
1448 			logError("file: "__FILE__", line: %d, " \
1449 				"the format of the file \"%s/%s\" is invalid" \
1450 				", group: %s, row count:%d > server count:%d",\
1451 				__LINE__, data_path, \
1452 				STORAGE_SYNC_TIMESTAMP_FILENAME, \
1453 				group_name, src_index+1, pGroup->count);
1454 			result = errno != 0 ? errno : EINVAL;
1455 			break;
1456 		}
1457 
1458 		if (g_use_storage_id && !fdfs_is_server_id_valid( \
1459 						src_storage_id))
1460 		{
1461 			if ((result=tracker_mem_get_storage_id( \
1462 				group_name, src_storage_id, \
1463 				src_storage_id)) != 0)
1464 			{
1465 				logError("file: "__FILE__", line: %d, " \
1466 					"server id of group name: %s and " \
1467 					"storage ip address: %s NOT " \
1468 					"exist", __LINE__, \
1469 					group_name, src_storage_id);
1470 				break;
1471 			}
1472 		}
1473 
1474 		if (strcmp(pGroup->all_servers[src_index]->id, \
1475 			src_storage_id) != 0)
1476 		{
1477 			logError("file: "__FILE__", line: %d, " \
1478 				"in data file: \"%s/%s\", " \
1479 				"group: %s, src server id: %s != %s",\
1480 				__LINE__, data_path, \
1481 				STORAGE_SYNC_TIMESTAMP_FILENAME, \
1482 				group_name, src_storage_id, \
1483 				pGroup->all_servers[src_index]->id);
1484 			result = errno != 0 ? errno : EINVAL;
1485 			break;
1486 		}
1487 
1488 		if (cols > pGroup->count + 2)
1489 		{
1490 			logError("file: "__FILE__", line: %d, " \
1491 				"the format of the file \"%s/%s\" is invalid" \
1492 				", group_name: %s, colums: %d > %d", \
1493 				__LINE__, data_path, \
1494 				STORAGE_SYNC_TIMESTAMP_FILENAME, \
1495 				group_name, cols, pGroup->count + 2);
1496 			result = errno != 0 ? errno : EINVAL;
1497 			break;
1498 		}
1499 
1500 		for (dest_index=0; dest_index<cols-2; dest_index++)
1501 		{
1502 			pGroup->last_sync_timestamps[src_index][dest_index] = \
1503 				atoi(trim_left(fields[2 + dest_index]));
1504 		}
1505 
1506 		src_index++;
1507 	}
1508 
1509 	fclose(fp);
1510 
1511 	if (result != 0)
1512 	{
1513 		return result;
1514 	}
1515 
1516 	ppEnd = pGroups->groups + pGroups->count;
1517 	for (ppGroup=pGroups->groups; ppGroup<ppEnd; ppGroup++)
1518 	{
1519 		if ((*ppGroup)->count <= 1)
1520 		{
1521 			continue;
1522 		}
1523 
1524 		for (dest_index=0; dest_index<(*ppGroup)->count; dest_index++)
1525 		{
1526 			if (pGroups->store_server == FDFS_STORE_SERVER_ROUND_ROBIN)
1527 			{
1528 				int min_synced_timestamp;
1529 
1530 				min_synced_timestamp = 0;
1531 				for (src_index=0; src_index<(*ppGroup)->count; \
1532 					src_index++)
1533 				{
1534 					if (src_index == dest_index)
1535 					{
1536 						continue;
1537 					}
1538 
1539 					curr_synced_timestamp = \
1540 						(*ppGroup)->last_sync_timestamps \
1541 							[src_index][dest_index];
1542 					if (curr_synced_timestamp == 0)
1543 					{
1544 						continue;
1545 					}
1546 
1547 					if (min_synced_timestamp == 0)
1548 					{
1549 						min_synced_timestamp = \
1550 							curr_synced_timestamp;
1551 					}
1552 					else if (curr_synced_timestamp < \
1553 						min_synced_timestamp)
1554 					{
1555 						min_synced_timestamp = \
1556 							curr_synced_timestamp;
1557 					}
1558 				}
1559 
1560 				(*ppGroup)->all_servers[dest_index]->stat. \
1561 					last_synced_timestamp = min_synced_timestamp;
1562 			}
1563 			else
1564 			{
1565 				int max_synced_timestamp;
1566 
1567 				max_synced_timestamp = 0;
1568 				for (src_index=0; src_index<(*ppGroup)->count; \
1569 					src_index++)
1570 				{
1571 					if (src_index == dest_index)
1572 					{
1573 						continue;
1574 					}
1575 
1576 					curr_synced_timestamp = \
1577 						(*ppGroup)->last_sync_timestamps \
1578 							[src_index][dest_index];
1579 					if (curr_synced_timestamp > \
1580 						max_synced_timestamp)
1581 					{
1582 						max_synced_timestamp = \
1583 							curr_synced_timestamp;
1584 					}
1585 				}
1586 
1587 				(*ppGroup)->all_servers[dest_index]->stat. \
1588 					last_synced_timestamp = max_synced_timestamp;
1589 			}
1590 		}
1591 	}
1592 
1593 	return result;
1594 }
1595 
tracker_load_data(FDFSGroups * pGroups)1596 static int tracker_load_data(FDFSGroups *pGroups)
1597 {
1598 	char data_path[MAX_PATH_SIZE];
1599 	int result;
1600 	FDFSStorageSync *pTrunkServers;
1601 	int nTrunkServerCount;
1602 
1603 	snprintf(data_path, sizeof(data_path), "%s/data", g_fdfs_base_path);
1604 	if (!fileExists(data_path))
1605 	{
1606 		if (mkdir(data_path, 0755) != 0)
1607 		{
1608 			logError("file: "__FILE__", line: %d, " \
1609 				"mkdir \"%s\" fail, " \
1610 				"errno: %d, error info: %s", \
1611 				__LINE__, data_path, errno, STRERROR(errno));
1612 			return errno != 0 ? errno : ENOENT;
1613 		}
1614 		TRACKER_CHOWN(data_path, geteuid(), getegid())
1615 	}
1616 
1617 	if (chdir(data_path) != 0)
1618 	{
1619 		logError("file: "__FILE__", line: %d, " \
1620 			"chdir \"%s\" fail, " \
1621 			"errno: %d, error info: %s", \
1622 			__LINE__, data_path, errno, STRERROR(errno));
1623 		return errno != 0 ? errno : ENOENT;
1624 	}
1625 
1626 	if (!fileExists(STORAGE_GROUPS_LIST_FILENAME_OLD) && \
1627 	    !fileExists(STORAGE_GROUPS_LIST_FILENAME_NEW))
1628 	{
1629 		return 0;
1630 	}
1631 
1632 	if ((result=tracker_load_groups_new(pGroups, data_path, \
1633 		&pTrunkServers, &nTrunkServerCount)) != 0)
1634 	{
1635 		return result;
1636 	}
1637 
1638 	if ((result=tracker_load_storages_new(pGroups, data_path)) != 0)
1639 	{
1640 		return result;
1641 	}
1642 
1643 	if ((result=tracker_malloc_all_group_path_mbs(pGroups)) != 0)
1644 	{
1645 		return result;
1646 	}
1647 
1648 	if ((result=tracker_load_sync_timestamps(pGroups, data_path)) != 0)
1649 	{
1650 		return result;
1651 	}
1652 
1653 	if (g_if_use_trunk_file)
1654 	{
1655 	if ((result=tracker_locate_group_trunk_servers(pGroups, \
1656 		pTrunkServers, nTrunkServerCount, true)) != 0)
1657 	{
1658 		return result;
1659 	}
1660 	}
1661 
1662 	if (pTrunkServers != NULL)
1663 	{
1664 		free(pTrunkServers);
1665 	}
1666 
1667 	return 0;
1668 }
1669 
tracker_save_groups()1670 int tracker_save_groups()
1671 {
1672 	char tmpFilename[MAX_PATH_SIZE];
1673 	char trueFilename[MAX_PATH_SIZE];
1674 	char buff[FDFS_GROUP_NAME_MAX_LEN + 256];
1675 	int fd;
1676 	FDFSGroupInfo **ppGroup;
1677 	FDFSGroupInfo **ppEnd;
1678 	int result;
1679 	int len;
1680 
1681 	tracker_mem_file_lock();
1682 
1683 	snprintf(trueFilename, sizeof(trueFilename), "%s/data/%s", \
1684 		g_fdfs_base_path, STORAGE_GROUPS_LIST_FILENAME_NEW);
1685 	snprintf(tmpFilename, sizeof(tmpFilename), "%s.tmp", trueFilename);
1686 	if ((fd=open(tmpFilename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
1687 	{
1688 		tracker_mem_file_unlock();
1689 
1690 		logError("file: "__FILE__", line: %d, " \
1691 			"open \"%s\" fail, " \
1692 			"errno: %d, error info: %s", \
1693 			__LINE__, tmpFilename, errno, STRERROR(errno));
1694 		return errno != 0 ? errno : ENOENT;
1695 	}
1696 
1697 	len = sprintf(buff, \
1698 			"# global section\n" \
1699 			"[%s]\n" \
1700 			"\t%s=%d\n\n", \
1701 			GROUP_SECTION_NAME_GLOBAL, \
1702 			GROUP_ITEM_GROUP_COUNT, g_groups.count);
1703 	if (fc_safe_write(fd, buff, len) != len)
1704 	{
1705 		logError("file: "__FILE__", line: %d, " \
1706 			"write to file \"%s\" fail, " \
1707 			"errno: %d, error info: %s", \
1708 			__LINE__, tmpFilename, \
1709 			errno, STRERROR(errno));
1710 		result = errno != 0 ? errno : EIO;
1711 	}
1712 	else
1713 	{
1714 	result = 0;
1715 
1716 	ppEnd = g_groups.sorted_groups + g_groups.count;
1717 	for (ppGroup=g_groups.sorted_groups; ppGroup<ppEnd; ppGroup++)
1718 	{
1719 		len = sprintf(buff, \
1720 				"# group: %s\n" \
1721 				"[%s"GROUP_SECTION_NO_FORMAT"]\n" \
1722 				"\t%s=%s\n" \
1723 				"\t%s=%d\n" \
1724 				"\t%s=%d\n" \
1725 				"\t%s=%d\n" \
1726 				"\t%s=%d\n" \
1727 				"\t%s=%d\n" \
1728 				"\t%s=%s\n" \
1729 				"\t%s=%s\n\n", \
1730 				(*ppGroup)->group_name, \
1731 				GROUP_SECTION_NAME_PREFIX, \
1732 				(int)(ppGroup - g_groups.sorted_groups) + 1, \
1733 				GROUP_ITEM_GROUP_NAME, \
1734 				(*ppGroup)->group_name, \
1735 				GROUP_ITEM_STORAGE_PORT, \
1736 				(*ppGroup)->storage_port, \
1737 				GROUP_ITEM_STORAGE_HTTP_PORT, \
1738 				(*ppGroup)->storage_http_port, \
1739 				GROUP_ITEM_STORE_PATH_COUNT, \
1740 				(*ppGroup)->store_path_count, \
1741 				GROUP_ITEM_SUBDIR_COUNT_PER_PATH, \
1742 				(*ppGroup)->subdir_count_per_path, \
1743 				GROUP_ITEM_CURRENT_TRUNK_FILE_ID, \
1744 				(*ppGroup)->current_trunk_file_id, \
1745 				GROUP_ITEM_TRUNK_SERVER, \
1746 				(*ppGroup)->pTrunkServer != NULL ? \
1747 					(*ppGroup)->pTrunkServer->id : "",
1748 				GROUP_ITEM_LAST_TRUNK_SERVER, \
1749 				(*ppGroup)->last_trunk_server_id
1750 			);
1751 
1752 		if (fc_safe_write(fd, buff, len) != len)
1753 		{
1754 			logError("file: "__FILE__", line: %d, " \
1755 				"write to file \"%s\" fail, " \
1756 				"errno: %d, error info: %s", \
1757 				__LINE__, tmpFilename, errno, STRERROR(errno));
1758 			result = errno != 0 ? errno : EIO;
1759 			break;
1760 		}
1761 	}
1762 	}
1763 
1764 	if (result == 0)
1765 	{
1766 		if (fsync(fd) != 0)
1767 		{
1768 			logError("file: "__FILE__", line: %d, " \
1769 				"fsync file \"%s\" fail, " \
1770 				"errno: %d, error info: %s", \
1771 				__LINE__, tmpFilename, \
1772 				errno, STRERROR(errno));
1773 			result = errno != 0 ? errno : EIO;
1774 		}
1775 	}
1776 
1777 	close(fd);
1778 
1779 	if (result == 0)
1780 	{
1781 		if (rename(tmpFilename, trueFilename) != 0)
1782 		{
1783 			logError("file: "__FILE__", line: %d, " \
1784 				"rename file \"%s\" to \"%s\" fail, " \
1785 				"errno: %d, error info: %s", \
1786 				__LINE__, tmpFilename, trueFilename, \
1787 				errno, STRERROR(errno));
1788 			result = errno != 0 ? errno : EIO;
1789 		}
1790 
1791 		TRACKER_CHOWN(trueFilename, geteuid(), getegid())
1792 	}
1793 
1794 	if (result != 0)
1795 	{
1796 		unlink(tmpFilename);
1797 	}
1798 
1799 	tracker_mem_file_unlock();
1800 
1801 	return result;
1802 }
1803 
tracker_save_storages()1804 int tracker_save_storages()
1805 {
1806 	char tmpFilename[MAX_PATH_SIZE];
1807 	char trueFilename[MAX_PATH_SIZE];
1808 	char buff[4096];
1809 	char id_buff[128];
1810 	int fd;
1811 	int len;
1812 	FDFSGroupInfo **ppGroup;
1813 	FDFSGroupInfo **ppGroupEnd;
1814 	FDFSStorageDetail **ppStorage;
1815 	FDFSStorageDetail **ppStorageEnd;
1816 	FDFSStorageDetail *pStorage;
1817 	int result;
1818 	int count;
1819 
1820 	tracker_mem_file_lock();
1821 
1822 	snprintf(trueFilename, sizeof(trueFilename), "%s/data/%s", \
1823 		g_fdfs_base_path, STORAGE_SERVERS_LIST_FILENAME_NEW);
1824 	snprintf(tmpFilename, sizeof(tmpFilename), "%s.tmp", trueFilename);
1825 	if ((fd=open(tmpFilename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
1826 	{
1827 		tracker_mem_file_unlock();
1828 
1829 		logError("file: "__FILE__", line: %d, " \
1830 			"open \"%s\" fail, " \
1831 			"errno: %d, error info: %s", \
1832 			__LINE__, tmpFilename, errno, STRERROR(errno));
1833 		return errno != 0 ? errno : ENOENT;
1834 	}
1835 
1836 	*id_buff = '\0';
1837 	count = 0;
1838 	result = 0;
1839 	ppGroupEnd = g_groups.sorted_groups + g_groups.count;
1840 	for (ppGroup=g_groups.sorted_groups; \
1841 		(ppGroup < ppGroupEnd) && (result == 0); ppGroup++)
1842 	{
1843 		ppStorageEnd = (*ppGroup)->all_servers + (*ppGroup)->count;
1844 		for (ppStorage=(*ppGroup)->all_servers; \
1845 			ppStorage<ppStorageEnd; ppStorage++)
1846 		{
1847 			pStorage = *ppStorage;
1848 			if (pStorage->status == FDFS_STORAGE_STATUS_DELETED
1849 			 || pStorage->status == FDFS_STORAGE_STATUS_IP_CHANGED)
1850 			{
1851 				continue;
1852 			}
1853 
1854 			if (g_use_storage_id)
1855 			{
1856 				sprintf(id_buff, "\t%s=%s\n",
1857 					STORAGE_ITEM_SERVER_ID, pStorage->id);
1858 			}
1859 
1860 			count++;
1861 			len = sprintf(buff, \
1862 				"# storage %s:%d\n" \
1863 				"[%s"STORAGE_SECTION_NO_FORMAT"]\n" \
1864 				"%s" \
1865 				"\t%s=%s\n" \
1866 				"\t%s=%s\n" \
1867 				"\t%s=%d\n" \
1868 				"\t%s=%s\n" \
1869 				"\t%s=%d\n" \
1870 				"\t%s=%d\n" \
1871 				"\t%s=%d\n" \
1872 				"\t%s=%s\n" \
1873 				"\t%s=%s\n" \
1874 				"\t%s=%d\n" \
1875 				"\t%s=%d\n" \
1876 				"\t%s=%d\n" \
1877 				"\t%s=%d\n" \
1878 				"\t%s=%"PRId64"\n" \
1879 				"\t%s=%"PRId64"\n" \
1880 				"\t%s=%"PRId64"\n" \
1881 				"\t%s=%"PRId64"\n" \
1882 				"\t%s=%"PRId64"\n" \
1883 				"\t%s=%"PRId64"\n" \
1884 				"\t%s=%"PRId64"\n" \
1885 				"\t%s=%"PRId64"\n" \
1886 				"\t%s=%"PRId64"\n" \
1887 				"\t%s=%"PRId64"\n" \
1888 				"\t%s=%"PRId64"\n" \
1889 				"\t%s=%"PRId64"\n" \
1890 				"\t%s=%"PRId64"\n" \
1891 				"\t%s=%"PRId64"\n" \
1892 				"\t%s=%"PRId64"\n" \
1893 				"\t%s=%"PRId64"\n" \
1894 				"\t%s=%"PRId64"\n" \
1895 				"\t%s=%"PRId64"\n" \
1896 				"\t%s=%"PRId64"\n" \
1897 				"\t%s=%"PRId64"\n" \
1898 				"\t%s=%"PRId64"\n" \
1899 				"\t%s=%"PRId64"\n" \
1900 				"\t%s=%"PRId64"\n" \
1901 				"\t%s=%"PRId64"\n" \
1902 				"\t%s=%"PRId64"\n" \
1903 				"\t%s=%"PRId64"\n" \
1904 				"\t%s=%"PRId64"\n" \
1905 				"\t%s=%"PRId64"\n" \
1906 				"\t%s=%"PRId64"\n" \
1907 				"\t%s=%"PRId64"\n" \
1908 				"\t%s=%"PRId64"\n" \
1909 				"\t%s=%"PRId64"\n" \
1910 				"\t%s=%"PRId64"\n" \
1911 				"\t%s=%"PRId64"\n" \
1912 				"\t%s=%d\n" \
1913 				"\t%s=%d\n" \
1914 				"\t%s=%d\n" \
1915 				"\t%s=%d\n" \
1916 				"\t%s=%"PRId64"\n\n", \
1917                 FDFS_CURRENT_IP_ADDR(pStorage), \
1918 				pStorage->storage_port, \
1919 				STORAGE_SECTION_NAME_PREFIX, count, id_buff, \
1920 				STORAGE_ITEM_GROUP_NAME, \
1921 				(*ppGroup)->group_name, \
1922 				STORAGE_ITEM_IP_ADDR, FDFS_CURRENT_IP_ADDR(pStorage), \
1923 				STORAGE_ITEM_STATUS, pStorage->status, \
1924 				STORAGE_ITEM_VERSION, pStorage->version, \
1925 				STORAGE_ITEM_JOIN_TIME, \
1926 				(int)pStorage->join_time, \
1927 				STORAGE_ITEM_STORAGE_PORT, \
1928 				pStorage->storage_port, \
1929 				STORAGE_ITEM_STORAGE_HTTP_PORT, \
1930 				pStorage->storage_http_port,  \
1931 				STORAGE_ITEM_DOMAIN_NAME, \
1932 				pStorage->domain_name, \
1933 				STORAGE_ITEM_SYNC_SRC_SERVER, \
1934 				(pStorage->psync_src_server != NULL ? \
1935 				pStorage->psync_src_server->id: ""), \
1936 				STORAGE_ITEM_SYNC_UNTIL_TIMESTAMP, \
1937 				(int)pStorage->sync_until_timestamp, \
1938 				STORAGE_ITEM_STORE_PATH_COUNT, \
1939 				pStorage->store_path_count, \
1940 				STORAGE_ITEM_SUBDIR_COUNT_PER_PATH, \
1941 				pStorage->subdir_count_per_path, \
1942 				STORAGE_ITEM_UPLOAD_PRIORITY, \
1943 				pStorage->upload_priority, \
1944 				STORAGE_ITEM_TOTAL_MB, pStorage->total_mb, \
1945 				STORAGE_ITEM_FREE_MB, pStorage->free_mb, \
1946 				STORAGE_ITEM_TOTAL_UPLOAD_COUNT, \
1947 				pStorage->stat.total_upload_count, \
1948 				STORAGE_ITEM_SUCCESS_UPLOAD_COUNT, \
1949 				pStorage->stat.success_upload_count, \
1950 				STORAGE_ITEM_TOTAL_APPEND_COUNT, \
1951 				pStorage->stat.total_append_count, \
1952 				STORAGE_ITEM_SUCCESS_APPEND_COUNT, \
1953 				pStorage->stat.success_append_count, \
1954 				STORAGE_ITEM_TOTAL_SET_META_COUNT, \
1955 				pStorage->stat.total_set_meta_count, \
1956 				STORAGE_ITEM_SUCCESS_SET_META_COUNT, \
1957 				pStorage->stat.success_set_meta_count, \
1958 				STORAGE_ITEM_TOTAL_DELETE_COUNT, \
1959 				pStorage->stat.total_delete_count, \
1960 				STORAGE_ITEM_SUCCESS_DELETE_COUNT, \
1961 				pStorage->stat.success_delete_count, \
1962 				STORAGE_ITEM_TOTAL_DOWNLOAD_COUNT, \
1963 				pStorage->stat.total_download_count, \
1964 				STORAGE_ITEM_SUCCESS_DOWNLOAD_COUNT, \
1965 				pStorage->stat.success_download_count, \
1966 				STORAGE_ITEM_TOTAL_GET_META_COUNT, \
1967 				pStorage->stat.total_get_meta_count, \
1968 				STORAGE_ITEM_SUCCESS_GET_META_COUNT, \
1969 				pStorage->stat.success_get_meta_count, \
1970 				STORAGE_ITEM_TOTAL_CREATE_LINK_COUNT, \
1971 				pStorage->stat.total_create_link_count, \
1972 				STORAGE_ITEM_SUCCESS_CREATE_LINK_COUNT, \
1973 				pStorage->stat.success_create_link_count, \
1974 				STORAGE_ITEM_TOTAL_DELETE_LINK_COUNT, \
1975 				pStorage->stat.total_delete_link_count, \
1976 				STORAGE_ITEM_SUCCESS_DELETE_LINK_COUNT, \
1977 				pStorage->stat.success_delete_link_count, \
1978 				STORAGE_ITEM_TOTAL_UPLOAD_BYTES, \
1979 				pStorage->stat.total_upload_bytes, \
1980 				STORAGE_ITEM_SUCCESS_UPLOAD_BYTES, \
1981 				pStorage->stat.success_upload_bytes, \
1982 				STORAGE_ITEM_TOTAL_APPEND_BYTES, \
1983 				pStorage->stat.total_append_bytes, \
1984 				STORAGE_ITEM_SUCCESS_APPEND_BYTES, \
1985 				pStorage->stat.success_append_bytes, \
1986 				STORAGE_ITEM_TOTAL_DOWNLOAD_BYTES, \
1987 				pStorage->stat.total_download_bytes, \
1988 				STORAGE_ITEM_SUCCESS_DOWNLOAD_BYTES, \
1989 				pStorage->stat.success_download_bytes, \
1990 				STORAGE_ITEM_TOTAL_SYNC_IN_BYTES, \
1991 				pStorage->stat.total_sync_in_bytes, \
1992 				STORAGE_ITEM_SUCCESS_SYNC_IN_BYTES, \
1993 				pStorage->stat.success_sync_in_bytes, \
1994 				STORAGE_ITEM_TOTAL_SYNC_OUT_BYTES, \
1995 				pStorage->stat.total_sync_out_bytes, \
1996 				STORAGE_ITEM_SUCCESS_SYNC_OUT_BYTES, \
1997 				pStorage->stat.success_sync_out_bytes, \
1998 				STORAGE_ITEM_TOTAL_FILE_OPEN_COUNT, \
1999 				pStorage->stat.total_file_open_count, \
2000 				STORAGE_ITEM_SUCCESS_FILE_OPEN_COUNT, \
2001 				pStorage->stat.success_file_open_count, \
2002 				STORAGE_ITEM_TOTAL_FILE_READ_COUNT, \
2003 				pStorage->stat.total_file_read_count, \
2004 				STORAGE_ITEM_SUCCESS_FILE_READ_COUNT, \
2005 				pStorage->stat.success_file_read_count, \
2006 				STORAGE_ITEM_TOTAL_FILE_WRITE_COUNT, \
2007 				pStorage->stat.total_file_write_count, \
2008 				STORAGE_ITEM_SUCCESS_FILE_WRITE_COUNT, \
2009 				pStorage->stat.success_file_write_count, \
2010 				STORAGE_ITEM_LAST_SOURCE_UPDATE, \
2011 				(int)(pStorage->stat.last_source_update), \
2012 				STORAGE_ITEM_LAST_SYNC_UPDATE, \
2013 				(int)(pStorage->stat.last_sync_update), \
2014 				STORAGE_ITEM_LAST_SYNCED_TIMESTAMP, \
2015 				(int)pStorage->stat.last_synced_timestamp, \
2016 				STORAGE_ITEM_LAST_HEART_BEAT_TIME, \
2017 				(int)pStorage->stat.last_heart_beat_time, \
2018 				STORAGE_ITEM_CHANGELOG_OFFSET, \
2019 				pStorage->changelog_offset \
2020 	 		     );
2021 
2022 			if (fc_safe_write(fd, buff, len) != len)
2023 			{
2024 				logError("file: "__FILE__", line: %d, " \
2025 					"write to file \"%s\" fail, " \
2026 					"errno: %d, error info: %s", \
2027 					__LINE__, tmpFilename, \
2028 					errno, STRERROR(errno));
2029 				result = errno != 0 ? errno : EIO;
2030 				break;
2031 			}
2032 		}
2033 	}
2034 
2035 	if (result == 0)
2036 	{
2037 		len = sprintf(buff, \
2038 			"\n# global section\n" \
2039 			"[%s]\n" \
2040 			"\t%s=%d\n", \
2041 			STORAGE_SECTION_NAME_GLOBAL, \
2042 			STORAGE_ITEM_STORAGE_COUNT, count);
2043 		if (fc_safe_write(fd, buff, len) != len)
2044 		{
2045 			logError("file: "__FILE__", line: %d, " \
2046 				"write to file \"%s\" fail, " \
2047 				"errno: %d, error info: %s", \
2048 				__LINE__, tmpFilename, \
2049 				errno, STRERROR(errno));
2050 			result = errno != 0 ? errno : EIO;
2051 		}
2052 	}
2053 
2054 	if (result == 0)
2055 	{
2056 		if (fsync(fd) != 0)
2057 		{
2058 			logError("file: "__FILE__", line: %d, " \
2059 				"fsync file \"%s\" fail, " \
2060 				"errno: %d, error info: %s", \
2061 				__LINE__, tmpFilename, \
2062 				errno, STRERROR(errno));
2063 			result = errno != 0 ? errno : EIO;
2064 		}
2065 	}
2066 
2067 	close(fd);
2068 
2069 	if (result == 0)
2070 	{
2071 		if (rename(tmpFilename, trueFilename) != 0)
2072 		{
2073 			logError("file: "__FILE__", line: %d, " \
2074 				"rename file \"%s\" to \"%s\" fail, " \
2075 				"errno: %d, error info: %s", \
2076 				__LINE__, tmpFilename, trueFilename, \
2077 				errno, STRERROR(errno));
2078 			result = errno != 0 ? errno : EIO;
2079 		}
2080 
2081 		TRACKER_CHOWN(trueFilename, geteuid(), getegid())
2082 	}
2083 
2084 	if (result != 0)
2085 	{
2086 		unlink(tmpFilename);
2087 	}
2088 
2089 	tracker_mem_file_unlock();
2090 
2091 	return result;
2092 }
2093 
tracker_save_sync_timestamps()2094 int tracker_save_sync_timestamps()
2095 {
2096 	char tmpFilename[MAX_PATH_SIZE];
2097 	char trueFilename[MAX_PATH_SIZE];
2098 	char buff[512];
2099 	int fd;
2100 	int len;
2101 	FDFSGroupInfo **ppGroup;
2102 	FDFSGroupInfo **ppGroupEnd;
2103 	int **last_sync_timestamps;
2104 	int i;
2105 	int k;
2106 	int result;
2107 
2108 	tracker_mem_file_lock();
2109 
2110 	snprintf(trueFilename, sizeof(trueFilename), "%s/data/%s", \
2111 		g_fdfs_base_path, STORAGE_SYNC_TIMESTAMP_FILENAME);
2112 	snprintf(tmpFilename, sizeof(tmpFilename), "%s.tmp", trueFilename);
2113 	if ((fd=open(tmpFilename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
2114 	{
2115 		tracker_mem_file_unlock();
2116 
2117 		logError("file: "__FILE__", line: %d, " \
2118 			"open \"%s\" fail, " \
2119 			"errno: %d, error info: %s", \
2120 			__LINE__, tmpFilename, errno, STRERROR(errno));
2121 		return errno != 0 ? errno : ENOENT;
2122 	}
2123 
2124 	result = 0;
2125 	ppGroupEnd = g_groups.sorted_groups + g_groups.count;
2126 	for (ppGroup=g_groups.sorted_groups; \
2127 		(ppGroup < ppGroupEnd) && (result == 0); ppGroup++)
2128 	{
2129 		last_sync_timestamps = (*ppGroup)->last_sync_timestamps;
2130 		for (i=0; i<(*ppGroup)->count; i++)
2131 		{
2132 			if ((*ppGroup)->all_servers[i]->status == \
2133 				FDFS_STORAGE_STATUS_DELETED \
2134 			 || (*ppGroup)->all_servers[i]->status == \
2135 				FDFS_STORAGE_STATUS_IP_CHANGED)
2136 			{
2137 				continue;
2138 			}
2139 
2140 			len = sprintf(buff, "%s%c%s", (*ppGroup)->group_name, \
2141 				STORAGE_DATA_FIELD_SEPERATOR, \
2142 				(*ppGroup)->all_servers[i]->id);
2143 			for (k=0; k<(*ppGroup)->count; k++)
2144 			{
2145 				if ((*ppGroup)->all_servers[k]->status == \
2146 					FDFS_STORAGE_STATUS_DELETED \
2147 				 || (*ppGroup)->all_servers[k]->status == \
2148 					FDFS_STORAGE_STATUS_IP_CHANGED)
2149 				{
2150 					continue;
2151 				}
2152 
2153 				len += sprintf(buff + len, "%c%d", \
2154 					STORAGE_DATA_FIELD_SEPERATOR, \
2155 					last_sync_timestamps[i][k]);
2156 			}
2157 			*(buff + len) = '\n';
2158 			len++;
2159 
2160 			if (fc_safe_write(fd, buff, len) != len)
2161 			{
2162 				logError("file: "__FILE__", line: %d, " \
2163 					"write to file \"%s\" fail, " \
2164 					"errno: %d, error info: %s", \
2165 					__LINE__, tmpFilename, \
2166 					errno, STRERROR(errno));
2167 				result = errno != 0 ? errno : EIO;
2168 				break;
2169 			}
2170 		}
2171 	}
2172 
2173 	if (result == 0)
2174 	{
2175 		if (fsync(fd) != 0)
2176 		{
2177 			logError("file: "__FILE__", line: %d, " \
2178 				"fsync file \"%s\" fail, " \
2179 				"errno: %d, error info: %s", \
2180 				__LINE__, tmpFilename, \
2181 				errno, STRERROR(errno));
2182 			result = errno != 0 ? errno : EIO;
2183 		}
2184 	}
2185 
2186 	close(fd);
2187 
2188 	if (result == 0)
2189 	{
2190 		if (rename(tmpFilename, trueFilename) != 0)
2191 		{
2192 			logError("file: "__FILE__", line: %d, " \
2193 				"rename file \"%s\" to \"%s\" fail, " \
2194 				"errno: %d, error info: %s", \
2195 				__LINE__, tmpFilename, trueFilename, \
2196 				errno, STRERROR(errno));
2197 			result = errno != 0 ? errno : EIO;
2198 		}
2199 
2200 		TRACKER_CHOWN(trueFilename, geteuid(), getegid())
2201 	}
2202 
2203 	if (result != 0)
2204 	{
2205 		unlink(tmpFilename);
2206 	}
2207 
2208 	tracker_mem_file_unlock();
2209 
2210 	return result;
2211 }
2212 
tracker_save_sys_files()2213 int tracker_save_sys_files()
2214 {
2215 	int result;
2216 
2217 	if ((result=tracker_save_groups()) != 0)
2218 	{
2219 		return result;
2220 	}
2221 
2222 	if ((result=tracker_save_storages()) != 0)
2223 	{
2224 		return result;
2225 	}
2226 
2227 	return tracker_save_sync_timestamps();
2228 }
2229 
tracker_open_changlog_file()2230 static int tracker_open_changlog_file()
2231 {
2232 	char data_path[MAX_PATH_SIZE];
2233 	char filename[MAX_PATH_SIZE];
2234 
2235 	snprintf(data_path, sizeof(data_path), "%s/data", g_fdfs_base_path);
2236 	if (!fileExists(data_path))
2237 	{
2238 		if (mkdir(data_path, 0755) != 0)
2239 		{
2240 			logError("file: "__FILE__", line: %d, " \
2241 				"mkdir \"%s\" fail, " \
2242 				"errno: %d, error info: %s", \
2243 				__LINE__, data_path, errno, STRERROR(errno));
2244 			return errno != 0 ? errno : ENOENT;
2245 		}
2246 		TRACKER_CHOWN(data_path, geteuid(), getegid())
2247 	}
2248 
2249 	snprintf(filename, sizeof(filename), "%s/data/%s", \
2250 		g_fdfs_base_path, STORAGE_SERVERS_CHANGELOG_FILENAME);
2251 	changelog_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
2252 	if (changelog_fd < 0)
2253 	{
2254 		logError("file: "__FILE__", line: %d, " \
2255 			"open \"%s\" fail, " \
2256 			"errno: %d, error info: %s", \
2257 			__LINE__, filename, errno, STRERROR(errno));
2258 		return errno != 0 ? errno : ENOENT;
2259 	}
2260 
2261 	g_changelog_fsize = lseek(changelog_fd, 0, SEEK_END);
2262         if (g_changelog_fsize < 0)
2263 	{
2264 		logError("file: "__FILE__", line: %d, " \
2265 			"lseek file \"%s\" fail, " \
2266 			"errno: %d, error info: %s", \
2267 			__LINE__, filename, errno, STRERROR(errno));
2268 		return errno != 0 ? errno : EIO;
2269 	}
2270 
2271 	TRACKER_FCHOWN(changelog_fd, filename, geteuid(), getegid())
2272 
2273 	return 0;
2274 }
2275 
tracker_mem_init_groups(FDFSGroups * pGroups)2276 static int tracker_mem_init_groups(FDFSGroups *pGroups)
2277 {
2278 	int result;
2279 	FDFSGroupInfo **ppGroup;
2280 	FDFSGroupInfo **ppGroupEnd;
2281 
2282 	pGroups->alloc_size = TRACKER_MEM_ALLOC_ONCE;
2283 	pGroups->count = 0;
2284 	pGroups->current_write_group = 0;
2285 	pGroups->pStoreGroup = NULL;
2286 	pGroups->groups = (FDFSGroupInfo **)malloc( \
2287 			sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2288 	if (pGroups->groups == NULL)
2289 	{
2290 		logCrit("file: "__FILE__", line: %d, " \
2291 			"malloc %d bytes fail!", __LINE__, \
2292 			(int)sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2293 		return errno != 0 ? errno : ENOMEM;
2294 	}
2295 
2296 	memset(pGroups->groups, 0, \
2297 		sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2298 
2299 	ppGroupEnd = pGroups->groups + pGroups->alloc_size;
2300 	for (ppGroup=pGroups->groups; ppGroup<ppGroupEnd; ppGroup++)
2301 	{
2302 		*ppGroup = (FDFSGroupInfo *)malloc(sizeof(FDFSGroupInfo));
2303 		if (*ppGroup == NULL)
2304 		{
2305 			logCrit("file: "__FILE__", line: %d, " \
2306 				"malloc %d bytes fail!", \
2307 				__LINE__, (int)sizeof(FDFSGroupInfo));
2308 			return errno != 0 ? errno : ENOMEM;
2309 		}
2310 
2311 		memset(*ppGroup, 0, sizeof(FDFSGroupInfo));
2312 	}
2313 
2314 	pGroups->sorted_groups = (FDFSGroupInfo **) \
2315 			malloc(sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2316 	if (pGroups->sorted_groups == NULL)
2317 	{
2318 		free(pGroups->groups);
2319 		pGroups->groups = NULL;
2320 
2321 		logCrit("file: "__FILE__", line: %d, " \
2322 			"malloc %d bytes fail!", __LINE__, \
2323 			(int)sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2324 		return errno != 0 ? errno : ENOMEM;
2325 	}
2326 
2327 	memset(pGroups->sorted_groups, 0, \
2328 		sizeof(FDFSGroupInfo *) * pGroups->alloc_size);
2329 
2330 	if ((result=tracker_load_data(pGroups)) != 0)
2331 	{
2332 		return result;
2333 	}
2334 
2335 	return 0;
2336 }
2337 
tracker_mem_init()2338 int tracker_mem_init()
2339 {
2340 	int result;
2341 
2342 	if ((result=init_pthread_lock(&mem_thread_lock)) != 0)
2343 	{
2344 		return result;
2345 	}
2346 
2347 	if ((result=init_pthread_lock(&mem_file_lock)) != 0)
2348 	{
2349 		return result;
2350 	}
2351 
2352 	if ((result=tracker_open_changlog_file()) != 0)
2353 	{
2354 		return result;
2355 	}
2356 
2357 	return tracker_mem_init_groups(&g_groups);
2358 }
2359 
tracker_free_last_sync_timestamps(int ** last_sync_timestamps,const int alloc_size)2360 static void tracker_free_last_sync_timestamps(int **last_sync_timestamps, \
2361 		const int alloc_size)
2362 {
2363 	int i;
2364 
2365 	if (last_sync_timestamps != NULL)
2366 	{
2367 		for (i=0; i<alloc_size; i++)
2368 		{
2369 			if (last_sync_timestamps[i] != NULL)
2370 			{
2371 				free(last_sync_timestamps[i]);
2372 				last_sync_timestamps[i] = NULL;
2373 			}
2374 		}
2375 
2376 		free(last_sync_timestamps);
2377 	}
2378 }
2379 
tracker_malloc_last_sync_timestamps(const int alloc_size,int * err_no)2380 static int **tracker_malloc_last_sync_timestamps(const int alloc_size, \
2381 		int *err_no)
2382 {
2383 	int **results;
2384 	int i;
2385 
2386 	results = (int **)malloc(sizeof(int *) * alloc_size);
2387 	if (results == NULL)
2388 	{
2389 		*err_no = errno != 0 ? errno : ENOMEM;
2390 		logError("file: "__FILE__", line: %d, " \
2391 			"malloc %d bytes fail", __LINE__, \
2392 			(int)sizeof(int *) * alloc_size);
2393 		return NULL;
2394 	}
2395 
2396 	memset(results, 0, sizeof(int *) * alloc_size);
2397 	for (i=0; i<alloc_size; i++)
2398 	{
2399 		results[i] = (int *)malloc(sizeof(int) * alloc_size);
2400 		if (results[i] == NULL)
2401 		{
2402 			*err_no = errno != 0 ? errno : ENOMEM;
2403 			logError("file: "__FILE__", line: %d, " \
2404 				"malloc %d bytes fail", __LINE__, \
2405 				(int)sizeof(int) * alloc_size);
2406 
2407 			tracker_free_last_sync_timestamps(results, alloc_size);
2408 			return NULL;
2409 		}
2410 
2411 		memset(results[i], 0, sizeof(int) * alloc_size);
2412 	}
2413 
2414 	*err_no = 0;
2415 	return results;
2416 }
2417 
tracker_mem_free_storages(FDFSStorageDetail ** servers,const int count)2418 static void tracker_mem_free_storages(FDFSStorageDetail **servers, const int count)
2419 {
2420 	FDFSStorageDetail **ppServer;
2421 	FDFSStorageDetail **ppServerEnd;
2422 
2423 	ppServerEnd = servers + count;
2424 	for (ppServer=servers; ppServer<ppServerEnd; ppServer++)
2425 	{
2426 		if (*ppServer != NULL)
2427 		{
2428 			free(*ppServer);
2429 		}
2430 	}
2431 
2432 	free(servers);
2433 }
2434 
tracker_mem_free_group(FDFSGroupInfo * pGroup)2435 static void tracker_mem_free_group(FDFSGroupInfo *pGroup)
2436 {
2437 	if (pGroup->sorted_servers != NULL)
2438 	{
2439 		free(pGroup->sorted_servers);
2440 		pGroup->sorted_servers = NULL;
2441 	}
2442 
2443 	if (pGroup->active_servers != NULL)
2444 	{
2445 		free(pGroup->active_servers);
2446 		pGroup->active_servers = NULL;
2447 	}
2448 
2449 	if (pGroup->all_servers != NULL)
2450 	{
2451 		tracker_mem_free_storages(pGroup->all_servers, \
2452 				pGroup->alloc_size);
2453 		pGroup->all_servers = NULL;
2454 	}
2455 
2456 #ifdef WITH_HTTPD
2457 	if (g_http_check_interval > 0)
2458 	{
2459 		if (pGroup->http_servers != NULL)
2460 		{
2461 			free(pGroup->http_servers);
2462 			pGroup->http_servers = NULL;
2463 		}
2464 	}
2465 #endif
2466 
2467 	tracker_free_last_sync_timestamps(pGroup->last_sync_timestamps, \
2468 				pGroup->alloc_size);
2469 	pGroup->last_sync_timestamps = NULL;
2470 }
2471 
tracker_mem_init_group(FDFSGroupInfo * pGroup)2472 static int tracker_mem_init_group(FDFSGroupInfo *pGroup)
2473 {
2474 	FDFSStorageDetail **ppServer;
2475 	FDFSStorageDetail **ppServerEnd;
2476 	int err_no;
2477 
2478 	pGroup->alloc_size = TRACKER_MEM_ALLOC_ONCE;
2479 	pGroup->count = 0;
2480 	pGroup->all_servers = (FDFSStorageDetail **) \
2481 			malloc(sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2482 	if (pGroup->all_servers == NULL)
2483 	{
2484 		logError("file: "__FILE__", line: %d, " \
2485 			"malloc %d bytes fail", __LINE__, \
2486 			(int)sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2487 		return errno != 0 ? errno : ENOMEM;
2488 	}
2489 
2490 	memset(pGroup->all_servers, 0, \
2491 		sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2492 	ppServerEnd = pGroup->all_servers + pGroup->alloc_size;
2493 	for (ppServer=pGroup->all_servers; ppServer<ppServerEnd; ppServer++)
2494 	{
2495 		*ppServer = (FDFSStorageDetail *)malloc( \
2496 					sizeof(FDFSStorageDetail));
2497 		if (*ppServer == NULL)
2498 		{
2499 			tracker_mem_free_group(pGroup);
2500 
2501 			logError("file: "__FILE__", line: %d, " \
2502 				"malloc %d bytes fail", __LINE__, \
2503 				(int)sizeof(FDFSStorageDetail));
2504 			return errno != 0 ? errno : ENOMEM;
2505 		}
2506 
2507 		memset(*ppServer, 0, sizeof(FDFSStorageDetail));
2508 	}
2509 
2510 	pGroup->sorted_servers = (FDFSStorageDetail **) \
2511 		malloc(sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2512 	if (pGroup->sorted_servers == NULL)
2513 	{
2514 		tracker_mem_free_group(pGroup);
2515 
2516 		logError("file: "__FILE__", line: %d, " \
2517 			"malloc %d bytes fail", __LINE__, \
2518 			(int)sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2519 		return errno != 0 ? errno : ENOMEM;
2520 	}
2521 	memset(pGroup->sorted_servers, 0, \
2522 		sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2523 
2524 	pGroup->active_servers = (FDFSStorageDetail **) \
2525 		malloc(sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2526 	if (pGroup->active_servers == NULL)
2527 	{
2528 		tracker_mem_free_group(pGroup);
2529 
2530 		logError("file: "__FILE__", line: %d, " \
2531 			"malloc %d bytes fail", __LINE__, \
2532 			(int)sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2533 		return errno != 0 ? errno : ENOMEM;
2534 	}
2535 	memset(pGroup->active_servers, 0, \
2536 		sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2537 
2538 #ifdef WITH_HTTPD
2539 	if (g_http_check_interval <= 0)
2540 	{
2541 		pGroup->http_servers = pGroup->active_servers;
2542 	}
2543 	else
2544 	{
2545 		pGroup->http_servers = (FDFSStorageDetail **) \
2546 			malloc(sizeof(FDFSStorageDetail *)*pGroup->alloc_size);
2547 		if (pGroup->http_servers == NULL)
2548 		{
2549 			tracker_mem_free_group(pGroup);
2550 
2551 			logError("file: "__FILE__", line: %d, " \
2552 				"malloc %d bytes fail", __LINE__, \
2553 				(int)sizeof(FDFSStorageDetail *) * \
2554 				pGroup->alloc_size);
2555 			return errno != 0 ? errno : ENOMEM;
2556 		}
2557 		memset(pGroup->http_servers, 0, \
2558 			sizeof(FDFSStorageDetail *) * pGroup->alloc_size);
2559 		g_http_servers_dirty = true;
2560 	}
2561 #endif
2562 
2563 	pGroup->last_sync_timestamps = tracker_malloc_last_sync_timestamps( \
2564 			pGroup->alloc_size, &err_no);
2565 	return err_no;
2566 }
2567 
tracker_mem_destroy_groups(FDFSGroups * pGroups,const bool saveFiles)2568 static int tracker_mem_destroy_groups(FDFSGroups *pGroups, const bool saveFiles)
2569 {
2570 	FDFSGroupInfo **ppGroup;
2571 	FDFSGroupInfo **ppEnd;
2572 	int result;
2573 
2574 	if (pGroups->groups == NULL)
2575 	{
2576 		result = 0;
2577 	}
2578 	else
2579 	{
2580 		if (saveFiles)
2581 		{
2582 			result = tracker_save_sys_files();
2583 		}
2584 		else
2585 		{
2586 			result = 0;
2587 		}
2588 
2589 		ppEnd = pGroups->groups + pGroups->count;
2590 		for (ppGroup=pGroups->groups; ppGroup<ppEnd; ppGroup++)
2591 		{
2592 			tracker_mem_free_group(*ppGroup);
2593 		}
2594 
2595 		if (pGroups->sorted_groups != NULL)
2596 		{
2597 			free(pGroups->sorted_groups);
2598 			pGroups->sorted_groups = NULL;
2599 		}
2600 
2601 		free(pGroups->groups);
2602 		pGroups->groups = NULL;
2603 	}
2604 
2605 	return result;
2606 }
2607 
tracker_mem_destroy()2608 int tracker_mem_destroy()
2609 {
2610 	int result;
2611 
2612 	result = tracker_mem_destroy_groups(&g_groups, true);
2613 
2614 	if (changelog_fd >= 0)
2615 	{
2616 		close(changelog_fd);
2617 		changelog_fd = -1;
2618 	}
2619 
2620 	if (pthread_mutex_destroy(&mem_thread_lock) != 0)
2621 	{
2622 		logError("file: "__FILE__", line: %d, " \
2623 			"call pthread_mutex_destroy fail", \
2624 			__LINE__);
2625 	}
2626 
2627 	if (pthread_mutex_destroy(&mem_file_lock) != 0)
2628 	{
2629 		logError("file: "__FILE__", line: %d, " \
2630 			"call pthread_mutex_destroy fail", \
2631 			__LINE__);
2632 	}
2633 
2634 	return result;
2635 }
2636 
tracker_mem_free_groups(FDFSGroupInfo ** groups,const int count)2637 static void tracker_mem_free_groups(FDFSGroupInfo **groups, const int count)
2638 {
2639 	FDFSGroupInfo **ppGroup;
2640 	FDFSGroupInfo **ppGroupEnd;
2641 
2642 	ppGroupEnd = groups + count;
2643 	for (ppGroup=groups; ppGroup<ppGroupEnd; ppGroup++)
2644 	{
2645 		if (*ppGroup != NULL)
2646 		{
2647 			free(*ppGroup);
2648 		}
2649 	}
2650 
2651 	free(groups);
2652 }
2653 
tracker_mem_realloc_groups(FDFSGroups * pGroups,const bool bNeedSleep)2654 static int tracker_mem_realloc_groups(FDFSGroups *pGroups, const bool bNeedSleep)
2655 {
2656 	FDFSGroupInfo **old_groups;
2657 	FDFSGroupInfo **old_sorted_groups;
2658 	FDFSGroupInfo **new_groups;
2659 	FDFSGroupInfo **new_sorted_groups;
2660 	FDFSGroupInfo **ppGroup;
2661 	FDFSGroupInfo **ppGroupEnd;
2662 	int new_size;
2663 
2664 	new_size = pGroups->alloc_size + TRACKER_MEM_ALLOC_ONCE;
2665 	new_groups = (FDFSGroupInfo **)malloc(sizeof(FDFSGroupInfo *) * new_size);
2666 	if (new_groups == NULL)
2667 	{
2668 		logError("file: "__FILE__", line: %d, " \
2669 			"malloc %d bytes fail", \
2670 			__LINE__, (int)sizeof(FDFSGroupInfo *) * new_size);
2671 		return errno != 0 ? errno : ENOMEM;
2672 	}
2673 	memset(new_groups, 0, sizeof(FDFSGroupInfo *) * new_size);
2674 
2675 	ppGroupEnd = new_groups + new_size;
2676 	for (ppGroup=new_groups+pGroups->count; ppGroup<ppGroupEnd; ppGroup++)
2677 	{
2678 		*ppGroup = (FDFSGroupInfo *)malloc(sizeof(FDFSGroupInfo));
2679 		if (*ppGroup == NULL)
2680 		{
2681 			tracker_mem_free_groups(new_groups, new_size);
2682 
2683 			logCrit("file: "__FILE__", line: %d, " \
2684 				"malloc %d bytes fail", \
2685 				__LINE__, (int)sizeof(FDFSGroupInfo));
2686 			return errno != 0 ? errno : ENOMEM;
2687 		}
2688 
2689 		memset(*ppGroup, 0, sizeof(FDFSGroupInfo));
2690 	}
2691 
2692 	memcpy(new_groups, pGroups->groups, \
2693 		sizeof(FDFSGroupInfo *) * pGroups->count);
2694 
2695 	new_sorted_groups = (FDFSGroupInfo **)malloc( \
2696 			sizeof(FDFSGroupInfo *) * new_size);
2697 	if (new_sorted_groups == NULL)
2698 	{
2699 		tracker_mem_free_groups(new_groups, new_size);
2700 
2701 		logError("file: "__FILE__", line: %d, " \
2702 			"malloc %d bytes fail", \
2703 			__LINE__, (int)sizeof(FDFSGroupInfo *) * new_size);
2704 		return errno != 0 ? errno : ENOMEM;
2705 	}
2706 
2707 	memset(new_sorted_groups, 0, sizeof(FDFSGroupInfo *) * new_size);
2708 	memcpy(new_sorted_groups, pGroups->sorted_groups, \
2709 		sizeof(FDFSGroupInfo *) * pGroups->count);
2710 
2711 	old_groups = pGroups->groups;
2712 	old_sorted_groups = pGroups->sorted_groups;
2713 	pGroups->alloc_size = new_size;
2714 	pGroups->groups = new_groups;
2715 	pGroups->sorted_groups = new_sorted_groups;
2716 
2717 	if (bNeedSleep)
2718 	{
2719 		sleep(1);
2720 	}
2721 
2722 	free(old_groups);
2723 	free(old_sorted_groups);
2724 
2725 	return 0;
2726 }
2727 
tracker_get_group_file_count(FDFSGroupInfo * pGroup)2728 int tracker_get_group_file_count(FDFSGroupInfo *pGroup)
2729 {
2730 	int count;
2731 	FDFSStorageDetail **ppServer;
2732 	FDFSStorageDetail **ppServerEnd;
2733 
2734 	count = 0;
2735 	ppServerEnd = pGroup->all_servers + pGroup->count;
2736 	for (ppServer=pGroup->all_servers; ppServer<ppServerEnd; ppServer++)
2737 	{
2738 		count += (*ppServer)->stat.success_upload_count - \
2739 				(*ppServer)->stat.success_delete_count;
2740 	}
2741 
2742 	return count;
2743 }
2744 
tracker_get_group_success_upload_count(FDFSGroupInfo * pGroup)2745 int tracker_get_group_success_upload_count(FDFSGroupInfo *pGroup)
2746 {
2747 	int count;
2748 	FDFSStorageDetail **ppServer;
2749 	FDFSStorageDetail **ppServerEnd;
2750 
2751 	count = 0;
2752 	ppServerEnd = pGroup->all_servers + pGroup->count;
2753 	for (ppServer=pGroup->all_servers; ppServer<ppServerEnd; ppServer++)
2754 	{
2755 		count += (*ppServer)->stat.success_upload_count;
2756 	}
2757 
2758 	return count;
2759 }
2760 
tracker_get_group_sync_src_server(FDFSGroupInfo * pGroup,FDFSStorageDetail * pDestServer)2761 FDFSStorageDetail *tracker_get_group_sync_src_server(FDFSGroupInfo *pGroup, \
2762 			FDFSStorageDetail *pDestServer)
2763 {
2764 	FDFSStorageDetail **ppServer;
2765 	FDFSStorageDetail **ppServerEnd;
2766 
2767 	ppServerEnd = pGroup->active_servers + pGroup->active_count;
2768 	for (ppServer=pGroup->active_servers; ppServer<ppServerEnd; ppServer++)
2769 	{
2770 		if (strcmp((*ppServer)->id, pDestServer->id) == 0)
2771 		{
2772 			continue;
2773 		}
2774 
2775 		return *ppServer;
2776 	}
2777 
2778 	return NULL;
2779 }
2780 
tracker_mem_realloc_store_servers(FDFSGroupInfo * pGroup,const int inc_count,const bool bNeedSleep)2781 static int tracker_mem_realloc_store_servers(FDFSGroupInfo *pGroup, \
2782 		const int inc_count, const bool bNeedSleep)
2783 {
2784 	int result;
2785 	FDFSStorageDetail **old_servers;
2786 	FDFSStorageDetail **old_sorted_servers;
2787 	FDFSStorageDetail **old_active_servers;
2788 	int **old_last_sync_timestamps;
2789 	FDFSStorageDetail **new_servers;
2790 	FDFSStorageDetail **new_sorted_servers;
2791 	FDFSStorageDetail **new_active_servers;
2792 	FDFSStorageDetail **ppServer;
2793 	FDFSStorageDetail **ppServerEnd;
2794 #ifdef WITH_HTTPD
2795 	FDFSStorageDetail **old_http_servers;
2796 	FDFSStorageDetail **new_http_servers;
2797 #endif
2798 	int **new_last_sync_timestamps;
2799 	int old_size;
2800 	int new_size;
2801 	int err_no;
2802 	int i;
2803 
2804 	new_size = pGroup->alloc_size + inc_count + TRACKER_MEM_ALLOC_ONCE;
2805 	new_servers = (FDFSStorageDetail **) \
2806 		malloc(sizeof(FDFSStorageDetail *) * new_size);
2807 	if (new_servers == NULL)
2808 	{
2809 		logError("file: "__FILE__", line: %d, " \
2810 			"malloc %d bytes fail", \
2811 			__LINE__, (int)sizeof(FDFSStorageDetail *) * new_size);
2812 		return errno != 0 ? errno : ENOMEM;
2813 	}
2814 	memset(new_servers, 0, sizeof(FDFSStorageDetail *) * new_size);
2815 
2816 	ppServerEnd = new_servers + new_size;
2817 	for (ppServer=new_servers+pGroup->count; ppServer<ppServerEnd; ppServer++)
2818 	{
2819 		*ppServer = (FDFSStorageDetail *)malloc( \
2820 					sizeof(FDFSStorageDetail));
2821 		if (*ppServer == NULL)
2822 		{
2823 			tracker_mem_free_storages(new_servers, new_size);
2824 
2825 			logError("file: "__FILE__", line: %d, " \
2826 				"malloc %d bytes fail", __LINE__, \
2827 				(int)sizeof(FDFSStorageDetail));
2828 			return errno != 0 ? errno : ENOMEM;
2829 		}
2830 
2831 		memset(*ppServer, 0, sizeof(FDFSStorageDetail));
2832 	}
2833 
2834 	memcpy(new_servers, pGroup->all_servers, \
2835 		sizeof(FDFSStorageDetail *) * pGroup->count);
2836 
2837 	new_sorted_servers = (FDFSStorageDetail **) \
2838 		malloc(sizeof(FDFSStorageDetail *) * new_size);
2839 	if (new_sorted_servers == NULL)
2840 	{
2841 		free(new_servers);
2842 		logError("file: "__FILE__", line: %d, " \
2843 			"malloc %d bytes fail", \
2844 			__LINE__, (int)sizeof(FDFSStorageDetail *) * new_size);
2845 		return errno != 0 ? errno : ENOMEM;
2846 	}
2847 
2848 	new_active_servers = (FDFSStorageDetail **) \
2849 		malloc(sizeof(FDFSStorageDetail *) * new_size);
2850 	if (new_active_servers == NULL)
2851 	{
2852 		free(new_servers);
2853 		free(new_sorted_servers);
2854 
2855 		logError("file: "__FILE__", line: %d, " \
2856 			"malloc %d bytes fail", \
2857 			__LINE__, (int)sizeof(FDFSStorageDetail *) * new_size);
2858 		return errno != 0 ? errno : ENOMEM;
2859 	}
2860 
2861 #ifdef WITH_HTTPD
2862 	if (g_http_check_interval > 0)
2863 	{
2864 		new_http_servers = (FDFSStorageDetail **) \
2865 			malloc(sizeof(FDFSStorageDetail *) * new_size);
2866 		if (new_http_servers == NULL)
2867 		{
2868 			free(new_servers);
2869 			free(new_sorted_servers);
2870 			free(new_active_servers);
2871 
2872 			logError("file: "__FILE__", line: %d, " \
2873 				"malloc %d bytes fail", __LINE__, \
2874 				(int)sizeof(FDFSStorageDetail *) * new_size);
2875 			return errno != 0 ? errno : ENOMEM;
2876 		}
2877 
2878 		memset(new_http_servers,0,sizeof(FDFSStorageDetail *)*new_size);
2879 
2880 		memcpy(new_http_servers, pGroup->http_servers, \
2881 			sizeof(FDFSStorageDetail *) * pGroup->count);
2882 
2883 	}
2884 	else
2885 	{
2886 		new_http_servers = NULL;
2887 	}
2888 #endif
2889 
2890 	memset(new_sorted_servers, 0, sizeof(FDFSStorageDetail *) * new_size);
2891 	memset(new_active_servers, 0, sizeof(FDFSStorageDetail *) * new_size);
2892 	if (pGroup->store_path_count > 0)
2893 	{
2894 		for (i=pGroup->count; i<new_size; i++)
2895 		{
2896 			result=tracker_malloc_storage_path_mbs(*(new_servers+i), \
2897 				pGroup->store_path_count);
2898 			if (result != 0)
2899 			{
2900 				free(new_servers);
2901 				free(new_sorted_servers);
2902 		        free(new_active_servers);
2903 
2904 				return result;
2905 			}
2906 		}
2907 	}
2908 
2909 	memcpy(new_sorted_servers, pGroup->sorted_servers, \
2910 		sizeof(FDFSStorageDetail *) * pGroup->count);
2911 
2912 	memcpy(new_active_servers, pGroup->active_servers, \
2913 		sizeof(FDFSStorageDetail *) * pGroup->count);
2914 
2915 	new_last_sync_timestamps = tracker_malloc_last_sync_timestamps( \
2916 		new_size, &err_no);
2917 	if (new_last_sync_timestamps == NULL)
2918 	{
2919 		free(new_servers);
2920 		free(new_sorted_servers);
2921 		free(new_active_servers);
2922 
2923 		return err_no;
2924 	}
2925 	for (i=0; i<pGroup->alloc_size; i++)
2926 	{
2927 		memcpy(new_last_sync_timestamps[i],  \
2928 			pGroup->last_sync_timestamps[i], \
2929 			(int)sizeof(int) *  pGroup->alloc_size);
2930 	}
2931 
2932 	old_size = pGroup->alloc_size;
2933 	old_servers = pGroup->all_servers;
2934 	old_sorted_servers = pGroup->sorted_servers;
2935 	old_active_servers = pGroup->active_servers;
2936 	old_last_sync_timestamps = pGroup->last_sync_timestamps;
2937 
2938 	pGroup->alloc_size = new_size;
2939 	pGroup->all_servers = new_servers;
2940 	pGroup->sorted_servers = new_sorted_servers;
2941 	pGroup->active_servers = new_active_servers;
2942 	pGroup->last_sync_timestamps = new_last_sync_timestamps;
2943 
2944 	tracker_mem_find_store_server(pGroup);
2945 	if (g_if_leader_self && g_if_use_trunk_file)
2946 	{
2947 		tracker_mem_find_trunk_server(pGroup, true);
2948 	}
2949 
2950 #ifdef WITH_HTTPD
2951 	if (g_http_check_interval <= 0)
2952 	{
2953 		old_http_servers = NULL;
2954 		pGroup->http_servers = pGroup->active_servers;
2955 	}
2956 	else
2957 	{
2958 		old_http_servers = pGroup->http_servers;
2959 		pGroup->http_servers = new_http_servers;
2960 		g_http_servers_dirty = true;
2961 	}
2962 #endif
2963 
2964 	if (bNeedSleep)
2965 	{
2966 		sleep(1);
2967 	}
2968 
2969 	free(old_servers);
2970 
2971 	free(old_sorted_servers);
2972 	free(old_active_servers);
2973 
2974 #ifdef WITH_HTTPD
2975 	if (old_http_servers != NULL)
2976 	{
2977 		free(old_http_servers);
2978 	}
2979 #endif
2980 
2981 	tracker_free_last_sync_timestamps(old_last_sync_timestamps, \
2982 				old_size);
2983 
2984 	return 0;
2985 }
2986 
tracker_mem_cmp_by_group_name(const void * p1,const void * p2)2987 static int tracker_mem_cmp_by_group_name(const void *p1, const void *p2)
2988 {
2989 	return strcmp((*((FDFSGroupInfo **)p1))->group_name,
2990 			(*((FDFSGroupInfo **)p2))->group_name);
2991 }
2992 
tracker_mem_cmp_by_storage_id(const void * p1,const void * p2)2993 static int tracker_mem_cmp_by_storage_id(const void *p1, const void *p2)
2994 {
2995 	return strcmp((*((FDFSStorageDetail **)p1))->id,
2996 			(*((FDFSStorageDetail **)p2))->id);
2997 }
2998 
tracker_mem_insert_into_sorted_servers(FDFSStorageDetail * pTargetServer,FDFSStorageDetail ** sorted_servers,const int count)2999 static void tracker_mem_insert_into_sorted_servers( \
3000 		FDFSStorageDetail *pTargetServer,   \
3001 		FDFSStorageDetail **sorted_servers, const int count)
3002 {
3003 	FDFSStorageDetail **ppServer;
3004 	FDFSStorageDetail **ppEnd;
3005 
3006 	ppEnd = sorted_servers + count;
3007 	for (ppServer=ppEnd; ppServer>sorted_servers; ppServer--)
3008 	{
3009 		if (strcmp(pTargetServer->id, (*(ppServer-1))->id) > 0)
3010 		{
3011 			break;
3012 		}
3013 		else
3014 		{
3015 			*ppServer = *(ppServer-1);
3016 		}
3017 	}
3018 
3019 	*ppServer = pTargetServer;
3020 }
3021 
tracker_mem_insert_into_sorted_groups(FDFSGroups * pGroups,FDFSGroupInfo * pTargetGroup)3022 static void tracker_mem_insert_into_sorted_groups(FDFSGroups *pGroups, \
3023 		FDFSGroupInfo *pTargetGroup)
3024 {
3025 	FDFSGroupInfo **ppGroup;
3026 	FDFSGroupInfo **ppEnd;
3027 
3028 	ppEnd = pGroups->sorted_groups + pGroups->count;
3029 	for (ppGroup=ppEnd; ppGroup > pGroups->sorted_groups; ppGroup--)
3030 	{
3031 		if (strcmp(pTargetGroup->group_name, \
3032 			   (*(ppGroup-1))->group_name) > 0)
3033 		{
3034 			*ppGroup = pTargetGroup;
3035 			return;
3036 		}
3037 		else
3038 		{
3039 			*ppGroup = *(ppGroup-1);
3040 		}
3041 	}
3042 
3043 	*ppGroup = pTargetGroup;
3044 }
3045 
tracker_mem_get_group_ex(FDFSGroups * pGroups,const char * group_name)3046 FDFSGroupInfo *tracker_mem_get_group_ex(FDFSGroups *pGroups, \
3047 		const char *group_name)
3048 {
3049 	FDFSGroupInfo target_groups;
3050 	FDFSGroupInfo *pTargetGroups;
3051 	FDFSGroupInfo **ppGroup;
3052 
3053 	memset(&target_groups, 0, sizeof(target_groups));
3054 	strcpy(target_groups.group_name, group_name);
3055 	pTargetGroups = &target_groups;
3056 	ppGroup = (FDFSGroupInfo **)bsearch(&pTargetGroups, \
3057 			pGroups->sorted_groups, \
3058 			pGroups->count, sizeof(FDFSGroupInfo *), \
3059 			tracker_mem_cmp_by_group_name);
3060 
3061 	if (ppGroup != NULL)
3062 	{
3063 		return *ppGroup;
3064 	}
3065 	else
3066 	{
3067 		return NULL;
3068 	}
3069 }
3070 
tracker_mem_add_group_ex(FDFSGroups * pGroups,TrackerClientInfo * pClientInfo,const char * group_name,const bool bNeedSleep,bool * bInserted)3071 static int tracker_mem_add_group_ex(FDFSGroups *pGroups, \
3072 	TrackerClientInfo *pClientInfo, const char *group_name, \
3073 	const bool bNeedSleep, bool *bInserted)
3074 {
3075 	FDFSGroupInfo *pGroup;
3076 	int result;
3077 
3078 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
3079 	{
3080 		logError("file: "__FILE__", line: %d, " \
3081 			"call pthread_mutex_lock fail, " \
3082 			"errno: %d, error info: %s", \
3083 			__LINE__, result, STRERROR(result));
3084 		return result;
3085 	}
3086 
3087 	do
3088 	{
3089 		result = 0;
3090 		*bInserted = false;
3091 		pGroup = tracker_mem_get_group_ex(pGroups, group_name);
3092 		if (pGroup != NULL)
3093 		{
3094 			break;
3095 		}
3096 
3097 		if (pGroups->count >= pGroups->alloc_size)
3098 		{
3099 			result = tracker_mem_realloc_groups(pGroups, bNeedSleep);
3100 			if (result != 0)
3101 			{
3102 				break;
3103 			}
3104 		}
3105 
3106 		pGroup = *(pGroups->groups + pGroups->count);
3107 		result = tracker_mem_init_group(pGroup);
3108 		if (result != 0)
3109 		{
3110 			break;
3111 		}
3112 
3113 		strcpy(pGroup->group_name, group_name);
3114 		tracker_mem_insert_into_sorted_groups(pGroups, pGroup);
3115 		pGroups->count++;
3116 
3117 		if ((pGroups->store_lookup == \
3118 				FDFS_STORE_LOOKUP_SPEC_GROUP) && \
3119 				(pGroups->pStoreGroup == NULL) && \
3120 				(strcmp(pGroups->store_group, \
3121 					pGroup->group_name) == 0))
3122 		{
3123 			pGroups->pStoreGroup = pGroup;
3124 		}
3125 
3126 		*bInserted = true;
3127 	} while (0);
3128 
3129 	if (pthread_mutex_unlock(&mem_thread_lock) != 0)
3130 	{
3131 		logError("file: "__FILE__", line: %d, "   \
3132 			"call pthread_mutex_unlock fail", \
3133 			__LINE__);
3134 	}
3135 
3136 	if (result != 0)
3137 	{
3138 		return result;
3139 	}
3140 
3141 	pClientInfo->pGroup = pGroup;
3142 	return 0;
3143 }
3144 
tracker_mem_get_active_storage_by_id(FDFSGroupInfo * pGroup,const char * id)3145 static FDFSStorageDetail *tracker_mem_get_active_storage_by_id( \
3146 		FDFSGroupInfo *pGroup, const char *id)
3147 {
3148 	FDFSStorageDetail target_storage;
3149 	FDFSStorageDetail *pTargetStorage;
3150 	FDFSStorageDetail **ppStorageServer;
3151 
3152 	if (id == NULL)
3153 	{
3154 		return NULL;
3155 	}
3156 
3157 	memset(&target_storage, 0, sizeof(target_storage));
3158 	strcpy(target_storage.id, id);
3159 	pTargetStorage = &target_storage;
3160 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetStorage, \
3161 			pGroup->active_servers, \
3162 			pGroup->active_count, \
3163 			sizeof(FDFSStorageDetail *), \
3164 			tracker_mem_cmp_by_storage_id);
3165 	if (ppStorageServer != NULL)
3166 	{
3167 		return *ppStorageServer;
3168 	}
3169 	else
3170 	{
3171 		return NULL;
3172 	}
3173 }
3174 
tracker_mem_get_active_storage_by_ip(FDFSGroupInfo * pGroup,const char * ip_addr)3175 static FDFSStorageDetail *tracker_mem_get_active_storage_by_ip( \
3176 		FDFSGroupInfo *pGroup, const char *ip_addr)
3177 {
3178 	FDFSStorageIdInfo *pStorageId;
3179 
3180 	if (!g_use_storage_id)
3181 	{
3182 		return tracker_mem_get_active_storage_by_id(pGroup, ip_addr);
3183 	}
3184 
3185 	pStorageId = fdfs_get_storage_id_by_ip(pGroup->group_name, ip_addr);
3186 	if (pStorageId == NULL)
3187 	{
3188 		return NULL;
3189 	}
3190 	return tracker_mem_get_active_storage_by_id(pGroup, pStorageId->id);
3191 }
3192 
3193 #ifdef WITH_HTTPD
tracker_mem_get_active_http_server_by_ip(FDFSGroupInfo * pGroup,const char * ip_addr)3194 static FDFSStorageDetail *tracker_mem_get_active_http_server_by_ip( \
3195 			FDFSGroupInfo *pGroup, const char *ip_addr)
3196 {
3197 	FDFSStorageDetail target_storage;
3198 	FDFSStorageDetail *pTargetStorage;
3199 	FDFSStorageDetail **ppStorageServer;
3200 
3201 	memset(&target_storage, 0, sizeof(target_storage));
3202 	if (!g_use_storage_id)
3203 	{
3204 		strcpy(target_storage.id, ip_addr);
3205 	}
3206 	else
3207 	{
3208 		FDFSStorageIdInfo *pStorageId;
3209 		pStorageId = fdfs_get_storage_id_by_ip( \
3210 				pGroup->group_name, ip_addr);
3211 		if (pStorageId == NULL)
3212 		{
3213 			return NULL;
3214 		}
3215 		strcpy(target_storage.id, pStorageId->id);
3216 	}
3217 	pTargetStorage = &target_storage;
3218 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetStorage, \
3219 			pGroup->http_servers, \
3220 			pGroup->http_server_count, \
3221 			sizeof(FDFSStorageDetail *), \
3222 			tracker_mem_cmp_by_storage_id);
3223 	if (ppStorageServer != NULL)
3224 	{
3225 		return *ppStorageServer;
3226 	}
3227 	else
3228 	{
3229 		return NULL;
3230 	}
3231 }
3232 
tracker_mem_get_active_http_server_by_id(FDFSGroupInfo * pGroup,const char * storage_id)3233 static FDFSStorageDetail *tracker_mem_get_active_http_server_by_id( \
3234 			FDFSGroupInfo *pGroup, const char *storage_id)
3235 {
3236 	FDFSStorageDetail target_storage;
3237 	FDFSStorageDetail *pTargetStorage;
3238 	FDFSStorageDetail **ppStorageServer;
3239 
3240 	memset(&target_storage, 0, sizeof(target_storage));
3241 	strcpy(target_storage.id, storage_id);
3242 	pTargetStorage = &target_storage;
3243 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetStorage, \
3244 			pGroup->http_servers, \
3245 			pGroup->http_server_count, \
3246 			sizeof(FDFSStorageDetail *), \
3247 			tracker_mem_cmp_by_storage_id);
3248 	if (ppStorageServer != NULL)
3249 	{
3250 		return *ppStorageServer;
3251 	}
3252 	else
3253 	{
3254 		return NULL;
3255 	}
3256 }
3257 #endif
3258 
tracker_mem_get_storage_by_ip(FDFSGroupInfo * pGroup,const char * ip_addr)3259 FDFSStorageDetail *tracker_mem_get_storage_by_ip(FDFSGroupInfo *pGroup, \
3260 				const char *ip_addr)
3261 {
3262 	const char *storage_id;
3263 
3264 	if (g_use_storage_id)
3265 	{
3266 		FDFSStorageIdInfo *pStorageIdInfo;
3267 		pStorageIdInfo = fdfs_get_storage_id_by_ip( \
3268 				pGroup->group_name, ip_addr);
3269 		if (pStorageIdInfo == NULL)
3270 		{
3271 			return NULL;
3272 		}
3273 		storage_id = pStorageIdInfo->id;
3274 	}
3275 	else
3276 	{
3277 		storage_id = ip_addr;
3278 	}
3279 
3280 	return tracker_mem_get_storage(pGroup, storage_id);
3281 }
3282 
tracker_mem_get_storage(FDFSGroupInfo * pGroup,const char * id)3283 FDFSStorageDetail *tracker_mem_get_storage(FDFSGroupInfo *pGroup, \
3284 				const char *id)
3285 {
3286 	FDFSStorageDetail target_storage;
3287 	FDFSStorageDetail *pTargetStorage;
3288 	FDFSStorageDetail **ppStorageServer;
3289 
3290 	memset(&target_storage, 0, sizeof(target_storage));
3291 	strcpy(target_storage.id, id);
3292 	pTargetStorage = &target_storage;
3293 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetStorage, \
3294 			pGroup->sorted_servers, \
3295 			pGroup->count, \
3296 			sizeof(FDFSStorageDetail *), \
3297 			tracker_mem_cmp_by_storage_id);
3298 	if (ppStorageServer != NULL)
3299 	{
3300 		return *ppStorageServer;
3301 	}
3302 	else
3303 	{
3304 		return NULL;
3305 	}
3306 }
3307 
tracker_mem_clear_storage_fields(FDFSStorageDetail * pStorageServer)3308 static void tracker_mem_clear_storage_fields(FDFSStorageDetail *pStorageServer)
3309 {
3310         if (pStorageServer->path_total_mbs != NULL)
3311 	{
3312 		memset(pStorageServer->path_total_mbs, 0, sizeof(int64_t) \
3313 			* pStorageServer->store_path_count);
3314 	}
3315 
3316         if (pStorageServer->path_free_mbs != NULL)
3317 	{
3318 		memset(pStorageServer->path_free_mbs, 0, sizeof(int64_t) \
3319 			* pStorageServer->store_path_count);
3320 	}
3321 
3322 	pStorageServer->psync_src_server = NULL;
3323 	pStorageServer->sync_until_timestamp = 0;
3324 	pStorageServer->total_mb = 0;
3325 	pStorageServer->free_mb = 0;
3326 	pStorageServer->changelog_offset = 0;
3327 	pStorageServer->store_path_count = 0;
3328 	pStorageServer->subdir_count_per_path = 0;
3329 	pStorageServer->upload_priority = 0;
3330 	pStorageServer->current_write_path = 0;
3331 
3332 	memset(&(pStorageServer->stat), 0, sizeof(FDFSStorageStat));
3333 }
3334 
tracker_mem_remove_group(FDFSGroupInfo ** groups,FDFSGroupInfo * pGroup)3335 static int tracker_mem_remove_group(FDFSGroupInfo **groups, FDFSGroupInfo *pGroup)
3336 {
3337 	FDFSGroupInfo **ppGroup;
3338 	FDFSGroupInfo **ppEnd;
3339 	FDFSGroupInfo **pp;
3340 
3341     ppEnd = groups + g_groups.count;
3342     for (ppGroup=groups; ppGroup<ppEnd; ppGroup++)
3343     {
3344         if (*ppGroup == pGroup)
3345         {
3346             break;
3347         }
3348     }
3349 
3350     if (ppGroup == ppEnd)
3351     {
3352         return ENOENT;
3353     }
3354 
3355     for (pp=ppGroup + 1; pp<ppEnd; pp++)
3356     {
3357         *(pp - 1) = *pp;
3358     }
3359 
3360     return 0;
3361 }
3362 
tracker_mem_delete_group(const char * group_name)3363 int tracker_mem_delete_group(const char *group_name)
3364 {
3365     FDFSGroupInfo *pGroup;
3366     int result;
3367 
3368     pGroup = tracker_mem_get_group(group_name);
3369     if (pGroup == NULL)
3370     {
3371         return ENOENT;
3372     }
3373 
3374     if (pGroup->count != 0)
3375     {
3376         return EBUSY;
3377     }
3378 
3379 	pthread_mutex_lock(&mem_thread_lock);
3380     if (pGroup->count != 0)
3381     {
3382         result = EBUSY;
3383     }
3384     else
3385     {
3386     result = tracker_mem_remove_group(g_groups.groups, pGroup);
3387     if (result == 0)
3388     {
3389         result = tracker_mem_remove_group(g_groups.sorted_groups, pGroup);
3390     }
3391     }
3392     if (result == 0)
3393     {
3394         if (g_groups.pStoreGroup == pGroup)
3395         {
3396             g_groups.pStoreGroup = NULL;
3397         }
3398         g_groups.count--;
3399     }
3400 	pthread_mutex_unlock(&mem_thread_lock);
3401 
3402     if (result != 0)
3403     {
3404         return result;
3405     }
3406 
3407     logDebug("file: "__FILE__", line: %d, " \
3408             "delete empty group: %s", \
3409             __LINE__, group_name);
3410     sleep(1);
3411     free(pGroup);
3412 
3413     return tracker_save_groups();
3414 }
3415 
tracker_mem_delete_storage(FDFSGroupInfo * pGroup,const char * id)3416 int tracker_mem_delete_storage(FDFSGroupInfo *pGroup, const char *id)
3417 {
3418 	FDFSStorageDetail *pStorageServer;
3419 	FDFSStorageDetail **ppServer;
3420 	FDFSStorageDetail **ppEnd;
3421 
3422 	pStorageServer = tracker_mem_get_storage(pGroup, id);
3423 	if (pStorageServer == NULL || pStorageServer->status == \
3424 		FDFS_STORAGE_STATUS_IP_CHANGED)
3425 	{
3426 		return ENOENT;
3427 	}
3428 
3429 	if (pStorageServer->status == FDFS_STORAGE_STATUS_ONLINE || \
3430 	    pStorageServer->status == FDFS_STORAGE_STATUS_ACTIVE || \
3431 	    pStorageServer->status == FDFS_STORAGE_STATUS_RECOVERY)
3432 	{
3433 		return EBUSY;
3434 	}
3435 
3436 	if (pStorageServer->status == FDFS_STORAGE_STATUS_DELETED)
3437 	{
3438 		return EALREADY;
3439 	}
3440 
3441 	ppEnd = pGroup->all_servers + pGroup->count;
3442 	for (ppServer=pGroup->all_servers; ppServer<ppEnd; ppServer++)
3443 	{
3444 		if ((*ppServer)->psync_src_server != NULL && \
3445 			strcmp((*ppServer)->psync_src_server->id, id) == 0)
3446 		{
3447 			(*ppServer)->psync_src_server = NULL;
3448 		}
3449 	}
3450 
3451     logDebug("file: "__FILE__", line: %d, "
3452             "delete storage server: %s:%d, group: %s",
3453             __LINE__, pStorageServer->ip_addrs.ips[0].address,
3454             pStorageServer->storage_port, pGroup->group_name);
3455 
3456 	tracker_mem_clear_storage_fields(pStorageServer);
3457 
3458 	pStorageServer->status = FDFS_STORAGE_STATUS_DELETED;
3459 	pGroup->chg_count++;
3460 
3461 	tracker_write_to_changelog(pGroup, pStorageServer, NULL);
3462 	return 0;
3463 }
3464 
tracker_mem_storage_ip_changed(FDFSGroupInfo * pGroup,const char * old_storage_ip,const char * new_storage_ip)3465 int tracker_mem_storage_ip_changed(FDFSGroupInfo *pGroup, \
3466 		const char *old_storage_ip, const char *new_storage_ip)
3467 {
3468 	FDFSStorageDetail *pOldStorageServer;
3469 	FDFSStorageDetail *pNewStorageServer;
3470 	int result;
3471 	bool bInserted;
3472 
3473 	if (g_use_storage_id)
3474 	{
3475 		logError("file: "__FILE__", line: %d, " \
3476 			"client ip: %s, do NOT support ip changed adjust " \
3477 			"because cluster use server ID instead of " \
3478 			"IP address", __LINE__, new_storage_ip);
3479 		return EOPNOTSUPP;
3480 	}
3481 
3482 	pOldStorageServer = tracker_mem_get_storage(pGroup, old_storage_ip);
3483 	if (pOldStorageServer == NULL || pOldStorageServer->status == \
3484 		FDFS_STORAGE_STATUS_DELETED)
3485 	{
3486 		logError("file: "__FILE__", line: %d, " \
3487 			"client ip: %s, old storage server: %s not exists", \
3488 			__LINE__, new_storage_ip, old_storage_ip);
3489 		return ENOENT;
3490 	}
3491 
3492 	if (pOldStorageServer->status == FDFS_STORAGE_STATUS_ONLINE || \
3493 	    pOldStorageServer->status == FDFS_STORAGE_STATUS_ACTIVE || \
3494 	    pOldStorageServer->status == FDFS_STORAGE_STATUS_RECOVERY)
3495 	{
3496 		logError("file: "__FILE__", line: %d, " \
3497 			"client ip: %s, old storage server: %s is online", \
3498 			__LINE__, new_storage_ip, old_storage_ip);
3499 		return EBUSY;
3500 	}
3501 
3502 	if (pOldStorageServer->status == FDFS_STORAGE_STATUS_IP_CHANGED)
3503 	{
3504 		logError("file: "__FILE__", line: %d, " \
3505 			"client ip: %s, old storage server: %s " \
3506 			"'s ip address already changed", \
3507 			__LINE__, new_storage_ip, old_storage_ip);
3508 		return EALREADY;
3509 	}
3510 
3511 	pNewStorageServer = tracker_mem_get_storage(pGroup, new_storage_ip);
3512 	if (!(pNewStorageServer == NULL || pNewStorageServer->status == \
3513 		FDFS_STORAGE_STATUS_DELETED))
3514 	{
3515 		logError("file: "__FILE__", line: %d, " \
3516 			"client ip: %s, new storage server: %s already exists",\
3517 			__LINE__, new_storage_ip, new_storage_ip);
3518 		return EEXIST;
3519 	}
3520 
3521 	result = _tracker_mem_add_storage(pGroup, &pNewStorageServer, \
3522 			new_storage_ip, new_storage_ip, true, true, &bInserted);
3523 	if (result != 0)
3524 	{
3525 		return result;
3526 	}
3527 
3528 	if (!bInserted)
3529 	{
3530 		logError("file: "__FILE__", line: %d, " \
3531 			"client ip: %s, new storage server: %s already exists",\
3532 			__LINE__, new_storage_ip, new_storage_ip);
3533 		return EEXIST;
3534 	}
3535 
3536 	pthread_mutex_lock(&mem_thread_lock);
3537 
3538 	//exchange old and new storage server
3539 	snprintf(pOldStorageServer->id, sizeof(pOldStorageServer->id),
3540 		"%s", new_storage_ip);
3541 	snprintf(pOldStorageServer->ip_addrs.ips[0].address,
3542 		sizeof(pOldStorageServer->ip_addrs.ips[0].address),
3543         "%s", new_storage_ip);
3544 
3545 	snprintf(pNewStorageServer->id, sizeof(pNewStorageServer->id),
3546 		"%s", old_storage_ip);
3547     pNewStorageServer->ip_addrs.count = 1;
3548 	snprintf(pNewStorageServer->ip_addrs.ips[0].address,
3549 		sizeof(pNewStorageServer->ip_addrs.ips[0].address),
3550         "%s", old_storage_ip);
3551 	pNewStorageServer->status = FDFS_STORAGE_STATUS_IP_CHANGED;
3552 
3553 	pGroup->chg_count++;
3554 
3555 	//need re-sort
3556 	qsort(pGroup->sorted_servers, pGroup->count,
3557 		sizeof(FDFSStorageDetail *), tracker_mem_cmp_by_storage_id);
3558 
3559 	pthread_mutex_unlock(&mem_thread_lock);
3560 
3561 	tracker_write_to_changelog(pGroup, pNewStorageServer, new_storage_ip);
3562 
3563 	return tracker_save_sys_files();
3564 }
3565 
tracker_mem_add_storage(TrackerClientInfo * pClientInfo,const char * id,const char * ip_addr,const bool bNeedSleep,const bool bNeedLock,bool * bInserted)3566 static int tracker_mem_add_storage(TrackerClientInfo *pClientInfo,
3567 		const char *id, const char *ip_addr,
3568 		const bool bNeedSleep, const bool bNeedLock, bool *bInserted)
3569 {
3570 	int result;
3571 	FDFSStorageDetail *pStorageServer;
3572 
3573 	pStorageServer = NULL;
3574 	result = _tracker_mem_add_storage(pClientInfo->pGroup, \
3575 			&pStorageServer, id, ip_addr, bNeedSleep, \
3576 			bNeedLock, bInserted);
3577 	if (result == 0)
3578 	{
3579 		pClientInfo->pStorage = pStorageServer;
3580 	}
3581 
3582 	return result;
3583 }
3584 
tracker_mem_add_storage_from_file(FDFSGroups * pGroups,const char * data_path,TrackerClientInfo * pClientInfo,const char * group_name,const char * storage_id,char * ip_addr)3585 static int tracker_mem_add_storage_from_file(FDFSGroups *pGroups,
3586         const char *data_path, TrackerClientInfo *pClientInfo,
3587 		const char *group_name, const char *storage_id, char *ip_addr)
3588 {
3589     int result;
3590     bool bInserted;
3591 
3592     if (g_use_storage_id)
3593     {
3594         if (storage_id == NULL || *storage_id == '\0')
3595         {
3596             FDFSStorageIdInfo *idInfo;
3597             idInfo = fdfs_get_storage_id_by_ip(group_name, ip_addr);
3598             if (idInfo == NULL)
3599             {
3600                 logError("file: "__FILE__", line: %d, "
3601                         "in the file \"%s/%s\", "
3602                         "group: %s, item \"%s\" is not found or empty, "
3603                         "and storage ip %s not configed in storage_ids.conf",
3604                         __LINE__, data_path,
3605                         STORAGE_SERVERS_LIST_FILENAME_NEW,
3606                         group_name, STORAGE_ITEM_SERVER_ID, ip_addr);
3607                 return ENOENT;
3608             }
3609 
3610             storage_id = idInfo->id;
3611         }
3612     }
3613 
3614     if (ip_addr == NULL)
3615     {
3616         logError("file: "__FILE__", line: %d, "
3617                 "in the file \"%s/%s\", "
3618                 "group: %s, item \"%s\" is not found",
3619                 __LINE__, data_path,
3620                 STORAGE_SERVERS_LIST_FILENAME_NEW,
3621                 group_name, STORAGE_ITEM_IP_ADDR);
3622         return ENOENT;
3623     }
3624     if (*ip_addr == '\0')
3625     {
3626         logWarning("file: "__FILE__", line: %d, "
3627                 "in the file \"%s/%s\", "
3628                 "group: %s, item \"%s\" is empty",
3629                 __LINE__, data_path,
3630                 STORAGE_SERVERS_LIST_FILENAME_NEW,
3631                 group_name, STORAGE_ITEM_IP_ADDR);
3632         return ENOENT;
3633     }
3634 
3635     memset(pClientInfo, 0, sizeof(TrackerClientInfo));
3636     if ((pClientInfo->pGroup=tracker_mem_get_group_ex(pGroups,
3637                     group_name)) == NULL)
3638     {
3639         logError("file: "__FILE__", line: %d, "
3640                 "in the file \"%s/%s\", "
3641                 "group \"%s\" is not found",
3642                 __LINE__, data_path,
3643                 STORAGE_SERVERS_LIST_FILENAME_NEW,
3644                 group_name);
3645         return errno != 0 ? errno : ENOENT;
3646     }
3647 
3648     if ((result=tracker_mem_add_storage(pClientInfo, storage_id,
3649                     ip_addr, false, false, &bInserted)) != 0)
3650     {
3651         return result;
3652     }
3653 
3654     if (!bInserted)
3655     {
3656         logError("file: "__FILE__", line: %d, "
3657                 "in the file \"%s/%s\", "
3658                 "storage \"%s\" is duplicate",
3659                 __LINE__, data_path,
3660                 STORAGE_SERVERS_LIST_FILENAME_NEW, ip_addr);
3661         return EEXIST;
3662     }
3663 
3664     return 0;
3665 }
3666 
_tracker_mem_add_storage(FDFSGroupInfo * pGroup,FDFSStorageDetail ** ppStorageServer,const char * id,const char * ip_addr,const bool bNeedSleep,const bool bNeedLock,bool * bInserted)3667 static int _tracker_mem_add_storage(FDFSGroupInfo *pGroup,
3668 	FDFSStorageDetail **ppStorageServer, const char *id,
3669 	const char *ip_addr, const bool bNeedSleep,
3670 	const bool bNeedLock, bool *bInserted)
3671 {
3672 	int result;
3673 	const char *storage_id;
3674     FDFSStorageIdInfo *pStorageIdInfo;
3675     FDFSMultiIP multi_ip;
3676 
3677 	if (*ip_addr == '\0')
3678 	{
3679 		logError("file: "__FILE__", line: %d, " \
3680 			"ip address is empty!", __LINE__);
3681 		return EINVAL;
3682 	}
3683 
3684     memset(&multi_ip, 0, sizeof(multi_ip));
3685     if (!g_use_storage_id)
3686     {
3687         multi_ip.count = 1;
3688         multi_ip.index = 0;
3689         strcpy(multi_ip.ips[0].address, ip_addr);
3690     }
3691 
3692 	if (id != NULL)
3693 	{
3694 		if (g_use_storage_id)
3695 		{
3696             pStorageIdInfo = fdfs_get_storage_by_id(id);
3697             if (pStorageIdInfo == NULL)
3698             {
3699 				logError("file: "__FILE__", line: %d, "
3700 					"storage id: %s not exist in config file, "
3701 					"group_name: %s, storage ip: %s", __LINE__,
3702 					id, pGroup->group_name, ip_addr);
3703 				return ENOENT;
3704             }
3705 
3706 			if (strcmp(pStorageIdInfo->group_name, pGroup->group_name) != 0)
3707 			{
3708 				logError("file: "__FILE__", line: %d, "
3709 					"check storage id fail, inconsistent group names, "
3710 					"id: %s, storage ip: %s, "
3711                     "reported group_name: %s != "
3712                     "group name in config file: %s", __LINE__,
3713 					pGroup->group_name, id, ip_addr,
3714                     pStorageIdInfo->group_name);
3715 				return EINVAL;
3716 			}
3717 
3718              multi_ip = pStorageIdInfo->ip_addrs;
3719 		}
3720 
3721 		storage_id = id;
3722 	}
3723 	else if (g_use_storage_id)
3724 	{
3725 		pStorageIdInfo = fdfs_get_storage_id_by_ip(
3726 				pGroup->group_name, ip_addr);
3727 		if (pStorageIdInfo == NULL)
3728 		{
3729 			logError("file: "__FILE__", line: %d, "
3730 				"get storage id info fail, "
3731 				"group_name: %s, storage ip: %s not exist in config file",
3732 				__LINE__, pGroup->group_name, ip_addr);
3733 			return ENOENT;
3734 		}
3735 
3736         multi_ip = pStorageIdInfo->ip_addrs;
3737 		storage_id = pStorageIdInfo->id;
3738 	}
3739 	else
3740 	{
3741 		storage_id = ip_addr;
3742 	}
3743 
3744 	if (bNeedLock && (result=pthread_mutex_lock(&mem_thread_lock)) != 0)
3745 	{
3746 		logError("file: "__FILE__", line: %d, " \
3747 			"call pthread_mutex_lock fail, " \
3748 			"errno: %d, error info: %s", \
3749 			__LINE__, result, STRERROR(result));
3750 		return result;
3751 	}
3752 
3753 	do
3754 	{
3755 		result = 0;
3756 		*bInserted = false;
3757 		*ppStorageServer = tracker_mem_get_storage(pGroup, storage_id);
3758 		if (*ppStorageServer != NULL)
3759 		{
3760 			if (g_use_storage_id)
3761 			{
3762                 fdfs_set_multi_ip_index(&(*ppStorageServer)->ip_addrs, ip_addr);
3763 			}
3764 
3765 			if ((*ppStorageServer)->status==FDFS_STORAGE_STATUS_DELETED \
3766 			 || (*ppStorageServer)->status==FDFS_STORAGE_STATUS_IP_CHANGED)
3767 			{
3768 			 	(*ppStorageServer)->status = FDFS_STORAGE_STATUS_INIT;
3769 			}
3770 
3771 			break;
3772 		}
3773 
3774 		if (pGroup->count >= pGroup->alloc_size)
3775 		{
3776 			result = tracker_mem_realloc_store_servers(
3777 					pGroup, 1, bNeedSleep);
3778 			if (result != 0)
3779 			{
3780 				break;
3781 			}
3782 		}
3783 
3784 		*ppStorageServer = *(pGroup->all_servers + pGroup->count);
3785 		snprintf((*ppStorageServer)->id, FDFS_STORAGE_ID_MAX_SIZE,
3786 				"%s", storage_id);
3787         (*ppStorageServer)->ip_addrs = multi_ip;
3788         if (g_use_storage_id)
3789         {
3790             fdfs_set_multi_ip_index(&(*ppStorageServer)->ip_addrs, ip_addr);
3791         }
3792 
3793 		tracker_mem_insert_into_sorted_servers(*ppStorageServer,
3794 				pGroup->sorted_servers, pGroup->count);
3795 		pGroup->count++;
3796 		pGroup->chg_count++;
3797 
3798 		*bInserted = true;
3799 	} while (0);
3800 
3801 	if (bNeedLock && pthread_mutex_unlock(&mem_thread_lock) != 0)
3802 	{
3803 		logError("file: "__FILE__", line: %d, "   \
3804 			"call pthread_mutex_unlock fail", \
3805 			__LINE__);
3806 	}
3807 
3808 	return result;
3809 }
3810 
tracker_calc_running_times(TrackerRunningStatus * pStatus)3811 void tracker_calc_running_times(TrackerRunningStatus *pStatus)
3812 {
3813 	pStatus->running_time = g_current_time - g_up_time;
3814 
3815 	if (g_tracker_last_status.last_check_time == 0)
3816 	{
3817 		pStatus->restart_interval = 0;
3818 	}
3819 	else
3820 	{
3821 		pStatus->restart_interval = g_up_time - \
3822 				g_tracker_last_status.last_check_time;
3823 	}
3824 
3825 #define FDFS_TRIM_TIME(t, i) (t / i) * i
3826 
3827 	pStatus->running_time = FDFS_TRIM_TIME(pStatus->running_time, \
3828 					TRACKER_SYNC_STATUS_FILE_INTERVAL);
3829 	pStatus->restart_interval = FDFS_TRIM_TIME(pStatus->restart_interval, \
3830 					TRACKER_SYNC_STATUS_FILE_INTERVAL);
3831 }
3832 
tracker_mem_get_sys_file_piece(ConnectionInfo * pTrackerServer,const int file_index,int fd,int64_t * offset,int64_t * file_size)3833 static int tracker_mem_get_sys_file_piece(ConnectionInfo *pTrackerServer, \
3834 	const int file_index, int fd, int64_t *offset, int64_t *file_size)
3835 {
3836 	char out_buff[sizeof(TrackerHeader) + 1 + FDFS_PROTO_PKG_LEN_SIZE];
3837 	char in_buff[TRACKER_MAX_PACKAGE_SIZE];
3838 	TrackerHeader *pHeader;
3839 	char *p;
3840 	char *pInBuff;
3841 	char *pContent;
3842 	int64_t in_bytes;
3843 	int64_t write_bytes;
3844 	int result;
3845 
3846 	memset(out_buff, 0, sizeof(out_buff));
3847 	pHeader = (TrackerHeader *)out_buff;
3848 	pHeader->cmd = TRACKER_PROTO_CMD_TRACKER_GET_ONE_SYS_FILE;
3849 	long2buff(1 + FDFS_PROTO_PKG_LEN_SIZE, pHeader->pkg_len);
3850 
3851 	p = out_buff + sizeof(TrackerHeader);
3852 	*p++ = file_index;
3853 	long2buff(*offset, p);
3854 	if ((result=tcpsenddata_nb(pTrackerServer->sock, out_buff, \
3855 			sizeof(out_buff), g_fdfs_network_timeout)) != 0)
3856 	{
3857 		logError("file: "__FILE__", line: %d, " \
3858 			"send data to tracker server %s:%d fail, " \
3859 			"errno: %d, error info: %s", __LINE__, \
3860 			pTrackerServer->ip_addr, \
3861 			pTrackerServer->port, \
3862 			result, STRERROR(result));
3863 
3864 		return (result == ENOENT ? EACCES : result);
3865 	}
3866 
3867 	pInBuff = in_buff;
3868 	result = fdfs_recv_response(pTrackerServer, &pInBuff, \
3869 				sizeof(in_buff), &in_bytes);
3870 	if (result != 0)
3871 	{
3872         logError("file: "__FILE__", line: %d, "
3873                 "fdfs_recv_response fail, result: %d",
3874                 __LINE__, result);
3875 		return result;
3876 	}
3877 
3878 	if (in_bytes < FDFS_PROTO_PKG_LEN_SIZE)
3879 	{
3880 		logError("file: "__FILE__", line: %d, " \
3881 			"tracker server %s:%d response data " \
3882 			"length: %"PRId64" is invalid, " \
3883 			"expect length >= %d.", __LINE__, \
3884 			pTrackerServer->ip_addr, pTrackerServer->port, \
3885 			in_bytes, FDFS_PROTO_PKG_LEN_SIZE);
3886 		return EINVAL;
3887 	}
3888 
3889 	*file_size = buff2long(in_buff);
3890 	write_bytes = in_bytes - FDFS_PROTO_PKG_LEN_SIZE;
3891 
3892 	if (*file_size < 0)
3893 	{
3894 		logError("file: "__FILE__", line: %d, " \
3895 			"tracker server %s:%d, file size: %"PRId64\
3896 			" < 0", __LINE__, pTrackerServer->ip_addr, \
3897 			pTrackerServer->port, *file_size);
3898 		return EINVAL;
3899 	}
3900 
3901 	if (*file_size > 0 && write_bytes == 0)
3902 	{
3903 		logError("file: "__FILE__", line: %d, " \
3904 			"tracker server %s:%d, file size: %"PRId64\
3905 			" > 0, but file content is empty", __LINE__, \
3906 			pTrackerServer->ip_addr, pTrackerServer->port, \
3907 			*file_size);
3908 		return EINVAL;
3909 	}
3910 
3911 	pContent = pInBuff + FDFS_PROTO_PKG_LEN_SIZE;
3912 	if (write_bytes > 0 &&
3913             fc_safe_write(fd, pContent, write_bytes) != write_bytes)
3914 	{
3915 		logError("file: "__FILE__", line: %d, " \
3916 			"write to file %s fail, " \
3917 			"errno: %d, error info: %s", \
3918 			__LINE__, g_tracker_sys_filenames[file_index], \
3919 			errno, STRERROR(errno));
3920 		return errno != 0 ? errno : EIO;
3921         }
3922 
3923 	*offset += write_bytes;
3924 	return 0;
3925 }
3926 
tracker_mem_get_one_sys_file(ConnectionInfo * pTrackerServer,const int file_index)3927 static int tracker_mem_get_one_sys_file(ConnectionInfo *pTrackerServer, \
3928 		const int file_index)
3929 {
3930 	char full_filename[MAX_PATH_SIZE];
3931 	int fd;
3932 	int result;
3933 	int64_t offset;
3934 	int64_t file_size;
3935 
3936 	snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \
3937 			g_fdfs_base_path, g_tracker_sys_filenames[file_index]);
3938 	fd = open(full_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
3939 	if (fd < 0)
3940 	{
3941 		logError("file: "__FILE__", line: %d, " \
3942 			"open file %s fail, " \
3943 			"errno: %d, error info: %s", \
3944 			__LINE__, full_filename, \
3945 			errno, STRERROR(errno));
3946 		return errno != 0 ? errno : EACCES;
3947 	}
3948 
3949 	TRACKER_FCHOWN(fd, full_filename, geteuid(), getegid())
3950 
3951 	offset = 0;
3952 	file_size = 0;
3953 	while (1)
3954 	{
3955 		result = tracker_mem_get_sys_file_piece(pTrackerServer, \
3956 			file_index, fd, &offset, &file_size);
3957 		if (result != 0)
3958 		{
3959 			break;
3960 		}
3961 
3962 		if (offset >= file_size)
3963 		{
3964 			break;
3965 		}
3966 	}
3967 
3968 	close(fd);
3969 	return result;
3970 }
3971 
tracker_mem_get_sys_files(TrackerServerInfo * pTrackerServer)3972 static int tracker_mem_get_sys_files(TrackerServerInfo *pTrackerServer)
3973 {
3974 	ConnectionInfo *conn;
3975 	int result;
3976 	int index;
3977 
3978     fdfs_server_sock_reset(pTrackerServer);
3979 	if ((conn=tracker_connect_server(pTrackerServer, &result)) == NULL)
3980 	{
3981 		return result;
3982 	}
3983 
3984 	if ((result=tracker_get_sys_files_start(conn)) != 0)
3985 	{
3986 		tracker_close_connection_ex(conn, true);
3987 		return result;
3988 	}
3989 
3990 	for (index=0; index<TRACKER_SYS_FILE_COUNT; index++)
3991 	{
3992 		result = tracker_mem_get_one_sys_file(conn, index);
3993 		if (result != 0)
3994 		{
3995 			break;
3996 		}
3997 	}
3998 
3999 	result = tracker_get_sys_files_end(conn);
4000 	tracker_close_connection_ex(conn, result != 0);
4001 
4002 	return result;
4003 }
4004 
tracker_mem_cmp_tracker_running_status(const void * p1,const void * p2)4005 static int tracker_mem_cmp_tracker_running_status(const void *p1, const void *p2)
4006 {
4007 	TrackerRunningStatus *pStatus1;
4008 	TrackerRunningStatus *pStatus2;
4009 	int sub;
4010 
4011 	pStatus1 = (TrackerRunningStatus *)p1;
4012 	pStatus2 = (TrackerRunningStatus *)p2;
4013 
4014     if (pStatus1->if_leader)
4015     {
4016         return 1;
4017     }
4018     else if (pStatus2->if_leader)
4019     {
4020         return -1;
4021     }
4022 
4023 	sub = pStatus1->running_time - pStatus2->running_time;
4024 	if (sub != 0)
4025 	{
4026 		return sub;
4027 	}
4028 
4029 	return pStatus2->restart_interval - pStatus1->restart_interval;
4030 }
4031 
find_my_ip_in_tracker_list()4032 static int find_my_ip_in_tracker_list()
4033 {
4034     const char *current_ip;
4035     const char *previous_ip;
4036     TrackerServerInfo *pServer;
4037     char buff[256];
4038 
4039     previous_ip = NULL;
4040     while ((current_ip=get_next_local_ip(previous_ip)) != NULL)
4041     {
4042         pServer = fdfs_tracker_group_get_server(&g_tracker_servers,
4043                 current_ip, g_server_port);
4044         if (pServer != NULL)
4045         {
4046             if (pServer->count > 1)
4047             {
4048                 ConnectionInfo *conn;
4049                 ConnectionInfo *end;
4050 
4051                 end = pServer->connections + pServer->count;
4052                 for (conn=pServer->connections; conn<end; conn++)
4053                 {
4054                     insert_into_local_host_ip(conn->ip_addr);
4055                 }
4056             }
4057             return 0;
4058         }
4059 
4060         previous_ip = current_ip;
4061     }
4062 
4063     logError("file: "__FILE__", line: %d, "
4064             "my ip NOT in tracker server list. %s",
4065             __LINE__, local_host_ip_addrs_to_string(buff, sizeof(buff)));
4066     return ENOENT;
4067 }
4068 
tracker_mem_first_add_tracker_servers(FDFSStorageJoinBody * pJoinBody)4069 static int tracker_mem_first_add_tracker_servers(FDFSStorageJoinBody *pJoinBody)
4070 {
4071 	TrackerServerInfo *pLocalTracker;
4072 	TrackerServerInfo *pLocalEnd;
4073 	TrackerServerInfo *servers;
4074 	int tracker_count;
4075 	int bytes;
4076 
4077 	tracker_count = pJoinBody->tracker_count;
4078 	bytes = sizeof(TrackerServerInfo) * tracker_count;
4079 	servers = (TrackerServerInfo *)malloc(bytes);
4080 	if (servers == NULL)
4081 	{
4082 		logError("file: "__FILE__", line: %d, " \
4083 			"malloc %d bytes fail, " \
4084 			"errno: %d, error info: %s", \
4085 			__LINE__, bytes, errno, STRERROR(errno));
4086 		return errno != 0 ? errno : ENOMEM;
4087 	}
4088 	memcpy(servers, pJoinBody->tracker_servers, bytes);
4089 
4090 	pLocalEnd = servers + tracker_count;
4091        	for (pLocalTracker=servers; pLocalTracker<pLocalEnd; \
4092 		pLocalTracker++)
4093 	{
4094         fdfs_server_sock_reset(pLocalTracker);
4095 	}
4096 
4097 	g_tracker_servers.servers = servers;
4098 	g_tracker_servers.server_count = tracker_count;
4099 	return find_my_ip_in_tracker_list();
4100 }
4101 
tracker_mem_copy_uniq_tracker_servers(TrackerServerInfo * pSrcServer,TrackerServerInfo * pDestServer)4102 static int tracker_mem_copy_uniq_tracker_servers(
4103         TrackerServerInfo *pSrcServer,
4104         TrackerServerInfo *pDestServer)
4105 {
4106 	ConnectionInfo *conn;
4107 	ConnectionInfo *end;
4108 
4109 	end = pSrcServer->connections + pSrcServer->count;
4110 	for (conn=pSrcServer->connections; conn<end; conn++)
4111     {
4112 		if (!fdfs_server_contain1(pDestServer, conn))
4113         {
4114             if (pDestServer->count == FDFS_MULTI_IP_MAX_COUNT)
4115             {
4116                 logError("file: "__FILE__", line: %d, "
4117                         "tracker IPs reach max count: %d",
4118                         __LINE__, FDFS_MULTI_IP_MAX_COUNT);
4119                 return ENOSPC;
4120             }
4121 
4122             pDestServer->connections[pDestServer->count++] = *conn;
4123         }
4124     }
4125     return 0;
4126 }
4127 
tracker_mem_check_add_tracker_servers(FDFSStorageJoinBody * pJoinBody)4128 static int tracker_mem_check_add_tracker_servers(FDFSStorageJoinBody *pJoinBody)
4129 {
4130 	TrackerServerInfo *pJoinTracker;
4131 	TrackerServerInfo *pJoinEnd;
4132 	TrackerServerInfo *pLocalTracker;
4133 	TrackerServerInfo *pLocalEnd;
4134 	TrackerServerInfo *pNewServer;
4135 	TrackerServerInfo *new_servers;
4136     char ip_str_join[256];
4137     char ip_str_before[256];
4138     char ip_str_after[256];
4139 	int add_count;
4140 	int bytes;
4141 
4142 	add_count = 0;
4143 	pLocalEnd = g_tracker_servers.servers + g_tracker_servers.server_count;
4144 	pJoinEnd = pJoinBody->tracker_servers + pJoinBody->tracker_count;
4145         for (pJoinTracker=pJoinBody->tracker_servers;
4146                 pJoinTracker<pJoinEnd; pJoinTracker++)
4147 	{
4148         	for (pLocalTracker=g_tracker_servers.servers;
4149                		pLocalTracker<pLocalEnd; pLocalTracker++)
4150 		{
4151             if (fdfs_server_equal(pJoinTracker, pLocalTracker))
4152             {
4153 				break;
4154             }
4155             if (fdfs_server_contain_ex(pJoinTracker, pLocalTracker))
4156 			{
4157                 fdfs_server_info_to_string(pJoinTracker,
4158                         ip_str_join, sizeof(ip_str_join));
4159                 fdfs_server_info_to_string(pLocalTracker,
4160                         ip_str_before, sizeof(ip_str_before));
4161 
4162                 logWarning("file: "__FILE__", line: %d, "
4163                         "tracker server ips not consistent, "
4164                         "join: %s, local: %s", __LINE__,
4165                         ip_str_join, ip_str_before);
4166 
4167                 if (pJoinTracker->count > pLocalTracker->count)
4168                 {
4169                     if (tracker_mem_copy_uniq_tracker_servers(pJoinTracker,
4170                             pLocalTracker) == 0)
4171                     {
4172                         fdfs_server_info_to_string(pLocalTracker,
4173                                 ip_str_after, sizeof(ip_str_after));
4174                         logInfo("file: "__FILE__", line: %d, "
4175                                 "merge tracker server ips, before: %s, "
4176                                 "after: %s", __LINE__,
4177                                 ip_str_before, ip_str_after);
4178                     }
4179                 }
4180 				break;
4181 			}
4182 		}
4183 
4184 		if (pLocalTracker == pLocalEnd)
4185 		{
4186 			add_count++;
4187 		}
4188 	}
4189 
4190 	if (add_count == 0)
4191 	{
4192 		return 0;
4193 	}
4194 
4195 	if (g_last_tracker_servers != NULL)
4196 	{
4197 		logError("file: "__FILE__", line: %d, " \
4198 			"last tracker servers does not freed, " \
4199 			"should try again!", __LINE__);
4200 		return EAGAIN;
4201 	}
4202 
4203 	if (g_tracker_servers.server_count + add_count > FDFS_MAX_TRACKERS)
4204 	{
4205 		logError("file: "__FILE__", line: %d, "
4206 			"too many tracker servers: %d",
4207 			__LINE__, g_tracker_servers.server_count + add_count);
4208 		return ENOSPC;
4209 	}
4210 
4211 	bytes = sizeof(TrackerServerInfo) * (g_tracker_servers.server_count
4212 						 + add_count);
4213 	new_servers = (TrackerServerInfo *)malloc(bytes);
4214 	if (new_servers == NULL)
4215 	{
4216 		logError("file: "__FILE__", line: %d, "
4217 			"malloc %d bytes fail, "
4218 			"errno: %d, error info: %s",
4219 			__LINE__, bytes, errno, STRERROR(errno));
4220 		return errno != 0 ? errno : ENOMEM;
4221 	}
4222 
4223 	memcpy(new_servers, g_tracker_servers.servers, sizeof(TrackerServerInfo) *
4224 				g_tracker_servers.server_count);
4225 	pNewServer = new_servers + g_tracker_servers.server_count;
4226 	for (pJoinTracker=pJoinBody->tracker_servers;
4227 		pJoinTracker<pJoinEnd; pJoinTracker++)
4228 	{
4229 		for (pLocalTracker=new_servers;
4230 			pLocalTracker<pNewServer; pLocalTracker++)
4231 		{
4232             if (fdfs_server_contain_ex(pJoinTracker, pLocalTracker))
4233 			{
4234 				break;
4235 			}
4236 		}
4237 
4238 		if (pLocalTracker == pNewServer)
4239 		{
4240 			memcpy(pNewServer, pJoinTracker,
4241 				sizeof(TrackerServerInfo));
4242             fdfs_server_sock_reset(pNewServer);
4243 			pNewServer++;
4244 		}
4245 	}
4246 
4247 	add_count = (pNewServer - new_servers) - g_tracker_servers.server_count;
4248 	g_last_tracker_servers = g_tracker_servers.servers;
4249 	g_tracker_servers.servers = new_servers;
4250 	g_tracker_servers.server_count += add_count;
4251 
4252 	logInfo("file: "__FILE__", line: %d, "
4253 		"add %d tracker servers, total tracker servers: %d",
4254 		__LINE__, add_count, g_tracker_servers.server_count);
4255 
4256 	return find_my_ip_in_tracker_list();
4257 }
4258 
tracker_mem_get_tracker_server(FDFSStorageJoinBody * pJoinBody,TrackerRunningStatus * pTrackerStatus)4259 static int tracker_mem_get_tracker_server(FDFSStorageJoinBody *pJoinBody, \
4260 		TrackerRunningStatus *pTrackerStatus)
4261 {
4262 	TrackerServerInfo *pTrackerServer;
4263 	TrackerServerInfo *pTrackerEnd;
4264 	TrackerRunningStatus *pStatus;
4265 	TrackerRunningStatus trackerStatus[FDFS_MAX_TRACKERS];
4266 	int count;
4267 	int result;
4268 	int r;
4269 	int i;
4270 
4271 	memset(pTrackerStatus, 0, sizeof(TrackerRunningStatus));
4272 	pStatus = trackerStatus;
4273 	result = 0;
4274 	pTrackerEnd = pJoinBody->tracker_servers + pJoinBody->tracker_count;
4275     for (pTrackerServer=pJoinBody->tracker_servers;
4276             pTrackerServer<pTrackerEnd; pTrackerServer++)
4277 	{
4278 		if (fdfs_server_contain_local_service(pTrackerServer, g_server_port))
4279 		{
4280 			continue;
4281 		}
4282 
4283 		pStatus->pTrackerServer = pTrackerServer;
4284 		r = fdfs_get_tracker_status(pTrackerServer, pStatus);
4285 		if (r == 0)
4286 		{
4287 			pStatus++;
4288 		}
4289 		else if (r != ENOENT)
4290 		{
4291 			result = r;
4292 		}
4293 	}
4294 
4295 	count = pStatus - trackerStatus;
4296 	if (count == 0)
4297 	{
4298 		return result == 0 ? ENOENT : result;
4299 	}
4300 
4301 	if (count > 1)
4302 	{
4303 		qsort(trackerStatus, count, sizeof(TrackerRunningStatus), \
4304 			tracker_mem_cmp_tracker_running_status);
4305 	}
4306 
4307 	for (i=0; i<count; i++)
4308 	{
4309 		logDebug("file: "__FILE__", line: %d, "
4310 			"%s:%d leader: %d, running time: %d, "
4311 			"restart interval: %d", __LINE__,
4312 			trackerStatus[i].pTrackerServer->connections[0].ip_addr,
4313 			trackerStatus[i].pTrackerServer->connections[0].port,
4314 			trackerStatus[i].if_leader,
4315 			trackerStatus[i].running_time,
4316 			trackerStatus[i].restart_interval);
4317 	}
4318 
4319 	//copy the last
4320 	memcpy(pTrackerStatus, trackerStatus + (count - 1), \
4321 			sizeof(TrackerRunningStatus));
4322 	return 0;
4323 }
4324 
tracker_mem_get_sys_files_from_others(FDFSStorageJoinBody * pJoinBody,TrackerRunningStatus * pRunningStatus)4325 static int tracker_mem_get_sys_files_from_others(FDFSStorageJoinBody *pJoinBody,
4326 		 TrackerRunningStatus *pRunningStatus)
4327 {
4328 	int result;
4329 	TrackerRunningStatus trackerStatus;
4330 	TrackerServerInfo *pTrackerServer;
4331 	FDFSGroups newGroups;
4332 	FDFSGroups tempGroups;
4333 
4334 	if (pJoinBody->tracker_count == 0)
4335 	{
4336 		return 0;
4337 	}
4338 
4339 	result = tracker_mem_get_tracker_server(pJoinBody, &trackerStatus);
4340 	if (result != 0)
4341 	{
4342 		return result == ENOENT ? 0 : result;
4343 	}
4344 
4345 	if (pRunningStatus != NULL)
4346 	{
4347 		if (tracker_mem_cmp_tracker_running_status(pRunningStatus,
4348 							&trackerStatus) >= 0)
4349 		{
4350 			logDebug("file: "__FILE__", line: %d, "
4351 				"%s:%d running time: %d, restart interval: %d, "
4352 				"my running time: %d, restart interval: %d, "
4353 				"do not need sync system files", __LINE__,
4354 				trackerStatus.pTrackerServer->connections[0].ip_addr,
4355 				trackerStatus.pTrackerServer->connections[0].port,
4356 				trackerStatus.running_time,
4357 				trackerStatus.restart_interval,
4358 				pRunningStatus->running_time,
4359 				pRunningStatus->restart_interval);
4360 
4361 			return 0;
4362 		}
4363 	}
4364 
4365 	pTrackerServer = trackerStatus.pTrackerServer;
4366 	result = tracker_mem_get_sys_files(pTrackerServer);
4367 	if (result != 0)
4368 	{
4369 		return result;
4370 	}
4371 
4372 	logInfo("file: "__FILE__", line: %d, "
4373 		"sys files loaded from tracker server %s:%d",
4374 		__LINE__, pTrackerServer->connections[0].ip_addr,
4375 		pTrackerServer->connections[0].port);
4376 
4377 	memset(&newGroups, 0, sizeof(newGroups));
4378 	newGroups.store_lookup = g_groups.store_lookup;
4379 	newGroups.store_server = g_groups.store_server;
4380 	newGroups.download_server = g_groups.download_server;
4381 	newGroups.store_path = g_groups.store_path;
4382 	strcpy(newGroups.store_group, g_groups.store_group);
4383 	if ((result=tracker_mem_init_groups(&newGroups)) != 0)
4384 	{
4385  		tracker_mem_destroy_groups(&newGroups, false);
4386 		return result;
4387 	}
4388 
4389 	memcpy(&tempGroups, &g_groups, sizeof(FDFSGroups));
4390 	memcpy(&g_groups, &newGroups, sizeof(FDFSGroups));
4391 
4392 	usleep(100000);
4393 
4394  	tracker_mem_destroy_groups(&tempGroups, false);
4395 	tracker_write_status_to_file(NULL);
4396 
4397 	if (changelog_fd >= 0)
4398 	{
4399 		close(changelog_fd);
4400 		changelog_fd = -1;
4401 	}
4402 
4403 	return tracker_open_changlog_file();
4404 }
4405 
tracker_mem_add_group_and_storage(TrackerClientInfo * pClientInfo,const char * ip_addr,FDFSStorageJoinBody * pJoinBody,const bool bNeedSleep)4406 int tracker_mem_add_group_and_storage(TrackerClientInfo *pClientInfo, \
4407 		const char *ip_addr, FDFSStorageJoinBody *pJoinBody, \
4408 		const bool bNeedSleep)
4409 {
4410 	int result;
4411 	bool bStorageInserted;
4412 	bool bGroupInserted;
4413 	FDFSStorageDetail *pStorageServer;
4414 	FDFSStorageDetail **ppServer;
4415 	FDFSStorageDetail **ppEnd;
4416 	FDFSStorageIdInfo *pStorageIdInfo;
4417 	const char *storage_id;
4418 
4419 	tracker_mem_file_lock();
4420 
4421 	if (need_get_sys_files)
4422 	{
4423 		if (g_tracker_last_status.last_check_time > 0 && \
4424 			g_up_time - g_tracker_last_status.last_check_time > \
4425 				2 * TRACKER_SYNC_STATUS_FILE_INTERVAL)
4426 		{ /* stop time exceeds 2 * interval */
4427 			TrackerRunningStatus runningStatus;
4428 
4429 			runningStatus.if_leader = false;
4430 			tracker_calc_running_times(&runningStatus);
4431 			result = tracker_mem_get_sys_files_from_others(\
4432 						pJoinBody, &runningStatus);
4433 			if (result != 0)
4434 			{
4435 				tracker_mem_file_unlock();
4436 			    logError("file: "__FILE__", line: %d, "
4437                         "get sys files from other trackers fail, errno: %d",
4438                         __LINE__, result);
4439 				return EAGAIN;
4440 			}
4441 
4442 			get_sys_files_done = true;
4443 		}
4444 
4445 		need_get_sys_files = false;
4446 	}
4447 
4448 	if ((!get_sys_files_done) && (g_groups.count == 0))
4449 	{
4450 		if (g_groups.count == 0)
4451 		{
4452 			if ((result=tracker_mem_get_sys_files_from_others( \
4453 				pJoinBody, NULL)) != 0)
4454 			{
4455 				tracker_mem_file_unlock();
4456 			    logError("file: "__FILE__", line: %d, "
4457                         "get sys files from other trackers fail, errno: %d",
4458                         __LINE__, result);
4459 				return EAGAIN;
4460 			}
4461 
4462 			get_sys_files_done = true;
4463 		}
4464 	}
4465 
4466 	if (g_tracker_servers.servers == NULL)
4467 	{
4468 		result = tracker_mem_first_add_tracker_servers(pJoinBody);
4469 		if (result != 0)
4470 		{
4471 			tracker_mem_file_unlock();
4472 			return result;
4473 		}
4474 	}
4475 	else
4476 	{
4477 		result = tracker_mem_check_add_tracker_servers(pJoinBody);
4478 		if (result != 0)
4479 		{
4480 			tracker_mem_file_unlock();
4481 			return result;
4482 		}
4483 	}
4484 
4485 	tracker_mem_file_unlock();
4486 
4487 	if ((result=tracker_mem_add_group_ex(&g_groups, pClientInfo, \
4488 		pJoinBody->group_name, bNeedSleep, &bGroupInserted)) != 0)
4489 	{
4490 		return result;
4491 	}
4492 
4493 	if (bGroupInserted)
4494 	{
4495 		if ((result=tracker_save_groups()) != 0)
4496 		{
4497 			return result;
4498 		}
4499 	}
4500 
4501 	if (g_use_storage_id)
4502 	{
4503 		pStorageIdInfo = fdfs_get_storage_id_by_ip(
4504 				pClientInfo->pGroup->group_name, ip_addr);
4505 		if (pStorageIdInfo == NULL)
4506 		{
4507 			logError("file: "__FILE__", line: %d, " \
4508 				"get storage id info fail, group_name: %s, " \
4509 				"storage ip: %s", __LINE__, \
4510 				pClientInfo->pGroup->group_name, ip_addr);
4511 			return ENOENT;
4512 		}
4513 		storage_id = pStorageIdInfo->id;
4514 	}
4515 	else
4516 	{
4517 		pStorageIdInfo = NULL;
4518 		storage_id = ip_addr;
4519 	}
4520 
4521 	if (pClientInfo->pGroup->storage_port == 0)
4522 	{
4523 		pClientInfo->pGroup->storage_port = pJoinBody->storage_port;
4524 		if ((result=tracker_save_groups()) != 0)
4525 		{
4526 			return result;
4527 		}
4528 	}
4529 	else
4530 	{
4531 		if (pClientInfo->pGroup->storage_port !=  \
4532 			pJoinBody->storage_port)
4533 		{
4534 			ppEnd = pClientInfo->pGroup->all_servers + \
4535 				pClientInfo->pGroup->count;
4536 			for (ppServer=pClientInfo->pGroup->all_servers; \
4537 				ppServer<ppEnd; ppServer++)
4538 			{
4539 				if (strcmp((*ppServer)->id, storage_id) == 0)
4540 				{
4541 					(*ppServer)->storage_port = \
4542 						pJoinBody->storage_port;
4543 					break;
4544 				}
4545 			}
4546 
4547 			for (ppServer=pClientInfo->pGroup->all_servers; \
4548 				ppServer<ppEnd; ppServer++)
4549 			{
4550 				if ((*ppServer)->storage_port != \
4551 					pJoinBody->storage_port)
4552 				{
4553 					break;
4554 				}
4555 			}
4556 			if (ppServer == ppEnd)  //all servers are same, adjust
4557 			{
4558 				pClientInfo->pGroup->storage_port = \
4559 						pJoinBody->storage_port;
4560 				if ((result=tracker_save_groups()) != 0)
4561 				{
4562 					return result;
4563 				}
4564 			}
4565 			else
4566 			{
4567 			logError("file: "__FILE__", line: %d, " \
4568 				"client ip: %s, port %d is not same " \
4569 				"in the group \"%s\", group port is %d", \
4570 				__LINE__, ip_addr, pJoinBody->storage_port, \
4571 				pJoinBody->group_name, \
4572 				pClientInfo->pGroup->storage_port);
4573 			return EINVAL;
4574 			}
4575 		}
4576 	}
4577 
4578 	if (pClientInfo->pGroup->storage_http_port == 0)
4579 	{
4580 		pClientInfo->pGroup->storage_http_port = \
4581 			pJoinBody->storage_http_port;
4582 		if ((result=tracker_save_groups()) != 0)
4583 		{
4584 			return result;
4585 		}
4586 	}
4587 	else
4588 	{
4589 		if (pClientInfo->pGroup->storage_http_port !=  \
4590 			pJoinBody->storage_http_port)
4591 		{
4592 			ppEnd = pClientInfo->pGroup->all_servers + \
4593 				pClientInfo->pGroup->count;
4594 			for (ppServer=pClientInfo->pGroup->all_servers; \
4595 				ppServer<ppEnd; ppServer++)
4596 			{
4597 				if (strcmp((*ppServer)->id, storage_id) == 0)
4598 				{
4599 					(*ppServer)->storage_http_port = \
4600 						pJoinBody->storage_http_port;
4601 					break;
4602 				}
4603 			}
4604 
4605 			for (ppServer=pClientInfo->pGroup->all_servers; \
4606 				ppServer<ppEnd; ppServer++)
4607 			{
4608 				if ((*ppServer)->storage_http_port != \
4609 					pJoinBody->storage_http_port)
4610 				{
4611 					break;
4612 				}
4613 			}
4614 			if (ppServer == ppEnd)  //all servers are same, adjust
4615 			{
4616 				pClientInfo->pGroup->storage_http_port = \
4617 					pJoinBody->storage_http_port;
4618 				if ((result=tracker_save_groups()) != 0)
4619 				{
4620 					return result;
4621 				}
4622 			}
4623 			else
4624 			{
4625 			logError("file: "__FILE__", line: %d, " \
4626 				"client ip: %s, http port %d is not same " \
4627 				"in the group \"%s\", group http port is %d", \
4628 				__LINE__, ip_addr, \
4629 				pJoinBody->storage_http_port, \
4630 				pJoinBody->group_name, \
4631 				pClientInfo->pGroup->storage_http_port);
4632 #ifdef WITH_HTTPD
4633 			return EINVAL;
4634 #endif
4635 			}
4636 		}
4637 	}
4638 
4639 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
4640 	{
4641 		logError("file: "__FILE__", line: %d, " \
4642 			"call pthread_mutex_lock fail, " \
4643 			"errno: %d, error info: %s", \
4644 			__LINE__, result, STRERROR(result));
4645 		return result;
4646 	}
4647 	pStorageServer = tracker_mem_get_storage(pClientInfo->pGroup, storage_id);
4648 	if (pthread_mutex_unlock(&mem_thread_lock) != 0)
4649 	{
4650 		logError("file: "__FILE__", line: %d, "   \
4651 			"call pthread_mutex_unlock fail", \
4652 			__LINE__);
4653 	}
4654 
4655 	if (pStorageServer == NULL)
4656 	{
4657 		if (!pJoinBody->init_flag)
4658 		{
4659 			if (pJoinBody->status < 0 || \
4660 			pJoinBody->status == FDFS_STORAGE_STATUS_DELETED || \
4661 			pJoinBody->status == FDFS_STORAGE_STATUS_IP_CHANGED || \
4662 			pJoinBody->status == FDFS_STORAGE_STATUS_NONE)
4663 			{
4664 				logError("file: "__FILE__", line: %d, " \
4665 					"client ip: %s:%d, invalid storage " \
4666 					"status %d, in the group \"%s\"", \
4667 					__LINE__, ip_addr, \
4668 					pJoinBody->storage_port, \
4669 					pJoinBody->status, \
4670 					pJoinBody->group_name);
4671 				return EFAULT;
4672 			}
4673 		}
4674 	}
4675 
4676 	if ((result=tracker_mem_add_storage(pClientInfo, storage_id, ip_addr,
4677 			bNeedSleep, true, &bStorageInserted)) != 0)
4678 	{
4679 		return result;
4680 	}
4681 
4682 	pStorageServer = pClientInfo->pStorage;
4683 	pStorageServer->store_path_count = pJoinBody->store_path_count;
4684 	pStorageServer->subdir_count_per_path = pJoinBody->subdir_count_per_path;
4685 	pStorageServer->upload_priority = pJoinBody->upload_priority;
4686 	pStorageServer->join_time = pJoinBody->join_time;
4687 	pStorageServer->up_time = pJoinBody->up_time;
4688 	snprintf(pStorageServer->version, sizeof(pStorageServer->version), \
4689 		"%s", pJoinBody->version);
4690 	snprintf(pStorageServer->domain_name, \
4691 		sizeof(pStorageServer->domain_name), \
4692 		"%s", pJoinBody->domain_name);
4693 	pStorageServer->storage_port = pJoinBody->storage_port;
4694 	pStorageServer->storage_http_port = pJoinBody->storage_http_port;
4695 
4696 	if (pClientInfo->pGroup->store_path_count == 0)
4697 	{
4698 		pClientInfo->pGroup->store_path_count = \
4699 				pJoinBody->store_path_count;
4700 		if ((result=tracker_malloc_group_path_mbs( \
4701 				pClientInfo->pGroup)) != 0)
4702 		{
4703 			return result;
4704 		}
4705 		if ((result=tracker_save_groups()) != 0)
4706 		{
4707 			return result;
4708 		}
4709 	}
4710 	else
4711 	{
4712 		if (pClientInfo->pGroup->store_path_count !=
4713 			pJoinBody->store_path_count)
4714 		{
4715 			ppEnd = pClientInfo->pGroup->all_servers +
4716 				pClientInfo->pGroup->count;
4717 			for (ppServer=pClientInfo->pGroup->all_servers;
4718 				ppServer<ppEnd; ppServer++)
4719 			{
4720 				if ((*ppServer)->status == FDFS_STORAGE_STATUS_DELETED)
4721                 {
4722                     continue;
4723                 }
4724 
4725                 if ((*ppServer)->store_path_count !=
4726                          pJoinBody->store_path_count)
4727 				{
4728 					break;
4729 				}
4730 			}
4731 
4732 			if (ppServer == ppEnd)  //all servers are same, adjust
4733 			{
4734 				if ((result=tracker_realloc_group_path_mbs(
4735                                 pClientInfo->pGroup, pJoinBody->
4736                                 store_path_count)) != 0)
4737 				{
4738 					return result;
4739 				}
4740 
4741 				if ((result=tracker_save_groups()) != 0)
4742 				{
4743 					return result;
4744 				}
4745 
4746 				logDebug("file: "__FILE__", line: %d, " \
4747 				"all storage server's store_path_count " \
4748 				"are same, adjust to %d", \
4749 				__LINE__, pJoinBody->store_path_count);
4750 			}
4751 			else if (pJoinBody->store_path_count < \
4752 				pClientInfo->pGroup->store_path_count)
4753 			{
4754 				logError("file: "__FILE__", line: %d, " \
4755 				"client ip: %s, store_path_count %d less " \
4756 				"than that of the group \"%s\", " \
4757 				"the group store_path_count is %d", \
4758 				__LINE__, ip_addr, \
4759 				pJoinBody->store_path_count, \
4760 				pJoinBody->group_name, \
4761 				pClientInfo->pGroup->store_path_count);
4762 				return EINVAL;
4763 			}
4764 		}
4765 	}
4766 
4767 	if (pClientInfo->pGroup->subdir_count_per_path == 0)
4768 	{
4769 		pClientInfo->pGroup->subdir_count_per_path = \
4770 				pJoinBody->subdir_count_per_path;
4771 		if ((result=tracker_save_groups()) != 0)
4772 		{
4773 			return result;
4774 		}
4775 	}
4776 	else
4777 	{
4778 		if (pClientInfo->pGroup->subdir_count_per_path != \
4779 				pJoinBody->subdir_count_per_path)
4780 		{
4781 			ppEnd = pClientInfo->pGroup->all_servers + \
4782 				pClientInfo->pGroup->count;
4783 			for (ppServer=pClientInfo->pGroup->all_servers; \
4784 				ppServer<ppEnd; ppServer++)
4785 			{
4786 				if ((*ppServer)->subdir_count_per_path != \
4787 					pJoinBody->subdir_count_per_path)
4788 				{
4789 					break;
4790 				}
4791 			}
4792 
4793 			if (ppServer == ppEnd)  //all servers are same, adjust
4794 			{
4795 				pClientInfo->pGroup->subdir_count_per_path = \
4796 					pJoinBody->subdir_count_per_path;
4797 				if ((result=tracker_save_groups()) != 0)
4798 				{
4799 					return result;
4800 				}
4801 			}
4802 			else
4803 			{
4804 				logError("file: "__FILE__", line: %d, " \
4805 				"client ip: %s, subdir_count_per_path %d is " \
4806 				"not same in the group \"%s\", " \
4807 				"group subdir_count_per_path is %d", \
4808 				__LINE__, ip_addr, \
4809 				pJoinBody->subdir_count_per_path, \
4810 				pJoinBody->group_name,\
4811 				pClientInfo->pGroup->subdir_count_per_path);
4812 
4813 				return EINVAL;
4814 			}
4815 		}
4816 	}
4817 
4818 	if (bStorageInserted)
4819 	{
4820 		if ((!pJoinBody->init_flag) && pJoinBody->status > 0)
4821 		{
4822 			if (pJoinBody->status == FDFS_STORAGE_STATUS_ACTIVE)
4823 			{
4824 				pStorageServer->status = FDFS_STORAGE_STATUS_ONLINE;
4825 			}
4826 			else
4827 			{
4828 				pStorageServer->status = pJoinBody->status;
4829 			}
4830 		}
4831 
4832 		if ((result=tracker_save_sys_files()) != 0)
4833 		{
4834 			return result;
4835 		}
4836 	}
4837 
4838 	if (pStorageServer->status == FDFS_STORAGE_STATUS_OFFLINE || \
4839 	    pStorageServer->status == FDFS_STORAGE_STATUS_RECOVERY)
4840 	{
4841 		pStorageServer->status = FDFS_STORAGE_STATUS_ONLINE;
4842 	}
4843 	else if (pStorageServer->status == FDFS_STORAGE_STATUS_INIT)
4844 	{
4845 	 	pStorageServer->changelog_offset = g_changelog_fsize;
4846 	}
4847 
4848 	logDebug("file: "__FILE__", line: %d, " \
4849 		"storage server %s::%s join in, remain changelog bytes: " \
4850 		"%"PRId64, __LINE__, \
4851 		pClientInfo->pGroup->group_name, ip_addr, \
4852 	 	g_changelog_fsize - pStorageServer->changelog_offset);
4853 
4854 	return 0;
4855 }
4856 
tracker_mem_sync_storages(FDFSGroupInfo * pGroup,FDFSStorageBrief * briefServers,const int server_count)4857 int tracker_mem_sync_storages(FDFSGroupInfo *pGroup, \
4858 		FDFSStorageBrief *briefServers, const int server_count)
4859 {
4860 	int result;
4861 	FDFSStorageBrief *pServer;
4862 	FDFSStorageBrief *pEnd;
4863 	FDFSStorageDetail target_storage;
4864 	FDFSStorageDetail *pTargetStorage;
4865 	FDFSStorageDetail **ppFound;
4866 
4867 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
4868 	{
4869 		logError("file: "__FILE__", line: %d, " \
4870 			"call pthread_mutex_lock fail, " \
4871 			"errno: %d, error info: %s", \
4872 			__LINE__, result, STRERROR(result));
4873 		return result;
4874 	}
4875 
4876 	result = 0;
4877 	do
4878 	{
4879 		memset(&target_storage, 0, sizeof(target_storage));
4880 		pEnd = briefServers + server_count;
4881 		for (pServer=briefServers; pServer<pEnd; pServer++)
4882 		{
4883 			pServer->id[FDFS_STORAGE_ID_MAX_SIZE - 1] = '\0';
4884 			pServer->ip_addr[IP_ADDRESS_SIZE - 1] = '\0';
4885 			if (pServer->status == FDFS_STORAGE_STATUS_NONE)
4886 			{
4887 				continue;
4888 			}
4889 
4890 			memcpy(target_storage.id, pServer->id,
4891 				FDFS_STORAGE_ID_MAX_SIZE);
4892 			pTargetStorage = &target_storage;
4893 			if ((ppFound=(FDFSStorageDetail **)bsearch(
4894 				&pTargetStorage,
4895 				pGroup->sorted_servers,
4896 				pGroup->count,
4897 				sizeof(FDFSStorageDetail *),
4898 				tracker_mem_cmp_by_storage_id)) != NULL)
4899 			{
4900 				if ((*ppFound)->status == pServer->status \
4901 				 || (*ppFound)->status == \
4902 					FDFS_STORAGE_STATUS_INIT \
4903 				 || (*ppFound)->status == \
4904 					FDFS_STORAGE_STATUS_ONLINE \
4905 				 || (*ppFound)->status == \
4906 					FDFS_STORAGE_STATUS_ACTIVE
4907 				 || (*ppFound)->status == \
4908 					FDFS_STORAGE_STATUS_RECOVERY)
4909 				{
4910 					continue;
4911 				}
4912 
4913                 logWarning("file: "__FILE__", line: %d, "
4914                         "storage server: %s:%d, dest status: %d, "
4915                         "my status: %d, should change my status!",
4916                         __LINE__, FDFS_CURRENT_IP_ADDR(*ppFound),
4917                         (*ppFound)->storage_port,
4918                         pServer->status, (*ppFound)->status);
4919 
4920 				if (pServer->status == \
4921 					FDFS_STORAGE_STATUS_DELETED
4922 				 || pServer->status == \
4923 					FDFS_STORAGE_STATUS_IP_CHANGED)
4924 				{
4925 					(*ppFound)->status = pServer->status;
4926 					pGroup->chg_count++;
4927 					continue;
4928 				}
4929 
4930 				if (pServer->status > (*ppFound)->status)
4931 				{
4932 					(*ppFound)->status = pServer->status;
4933 					pGroup->chg_count++;
4934 				}
4935 			}
4936 			else if (pServer->status == FDFS_STORAGE_STATUS_DELETED
4937 			   || pServer->status == FDFS_STORAGE_STATUS_IP_CHANGED)
4938 			{
4939 				//ignore deleted storage server
4940 			}
4941             else if (pServer->status == FDFS_STORAGE_STATUS_ACTIVE
4942 			   || pServer->status == FDFS_STORAGE_STATUS_ONLINE)
4943             {
4944 				//ignore online or active storage server
4945             }
4946 			else
4947 			{
4948 				FDFSStorageDetail *pStorageServer;
4949 				bool bInserted;
4950 
4951 				result = _tracker_mem_add_storage(pGroup,
4952 					&pStorageServer, pServer->id,
4953 					pServer->ip_addr, true, false,
4954 					&bInserted);
4955 				if (result == 0 && bInserted)
4956 				{
4957 					pStorageServer->status = pServer->status;
4958 				}
4959 			}
4960 		}
4961 	} while (0);
4962 
4963 	if (pthread_mutex_unlock(&mem_thread_lock) != 0)
4964 	{
4965 		logError("file: "__FILE__", line: %d, "   \
4966 			"call pthread_mutex_unlock fail", \
4967 			__LINE__);
4968 	}
4969 
4970 	return result;
4971 }
4972 
tracker_mem_find_store_server(FDFSGroupInfo * pGroup)4973 static void tracker_mem_find_store_server(FDFSGroupInfo *pGroup)
4974 {
4975 	if (pGroup->active_count == 0)
4976 	{
4977 		pGroup->pStoreServer = NULL;
4978 		return;
4979 	}
4980 
4981 	if (g_groups.store_server == FDFS_STORE_SERVER_FIRST_BY_PRI)
4982 	{
4983 		FDFSStorageDetail **ppEnd;
4984 		FDFSStorageDetail **ppServer;
4985 		FDFSStorageDetail *pMinPriServer;
4986 
4987 		pMinPriServer = *(pGroup->active_servers);
4988 		ppEnd = pGroup->active_servers + pGroup->active_count;
4989 		for (ppServer=pGroup->active_servers+1; ppServer<ppEnd; \
4990 			ppServer++)
4991 		{
4992 			if ((*ppServer)->upload_priority < \
4993 				pMinPriServer->upload_priority)
4994 			{
4995 				pMinPriServer = *ppServer;
4996 			}
4997 		}
4998 
4999 		pGroup->pStoreServer = pMinPriServer;
5000 	}
5001 	else
5002 	{
5003 		pGroup->pStoreServer = *(pGroup->active_servers);
5004 	}
5005 }
5006 
_storage_get_trunk_binlog_size(ConnectionInfo * pStorageServer,int64_t * file_size)5007 static int _storage_get_trunk_binlog_size(
5008 	ConnectionInfo *pStorageServer, int64_t *file_size)
5009 {
5010 	char out_buff[sizeof(TrackerHeader)];
5011 	char in_buff[8];
5012 	TrackerHeader *pHeader;
5013 	char *pInBuff;
5014 	int64_t in_bytes;
5015 	int result;
5016 
5017 	pHeader = (TrackerHeader *)out_buff;
5018 	memset(out_buff, 0, sizeof(out_buff));
5019 	pHeader->cmd = STORAGE_PROTO_CMD_TRUNK_GET_BINLOG_SIZE;
5020 	if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
5021 			sizeof(out_buff), g_fdfs_network_timeout)) != 0)
5022 	{
5023 		logError("file: "__FILE__", line: %d, " \
5024 			"storage server %s:%d, send data fail, " \
5025 			"errno: %d, error info: %s.", \
5026 			__LINE__, pStorageServer->ip_addr, \
5027 			pStorageServer->port, \
5028 			result, STRERROR(result));
5029 		return result;
5030 	}
5031 
5032 	pInBuff = in_buff;
5033 	if ((result=fdfs_recv_response(pStorageServer, \
5034 		&pInBuff, sizeof(in_buff), &in_bytes)) != 0)
5035 	{
5036         logError("file: "__FILE__", line: %d, "
5037                 "fdfs_recv_response fail, result: %d",
5038                 __LINE__, result);
5039 		return result;
5040 	}
5041 
5042 	if (in_bytes != sizeof(in_buff))
5043 	{
5044 		logError("file: "__FILE__", line: %d, " \
5045 			"storage server %s:%d, recv body length: " \
5046 			"%"PRId64" != %d",  \
5047 			__LINE__, pStorageServer->ip_addr, \
5048 			pStorageServer->port, in_bytes, (int)sizeof(in_buff));
5049 		return EINVAL;
5050 	}
5051 
5052 	*file_size = buff2long(in_buff);
5053 	return 0;
5054 }
5055 
tracker_mem_get_trunk_binlog_size(const char * storage_ip,const int port,int64_t * file_size)5056 static int tracker_mem_get_trunk_binlog_size(
5057 	const char *storage_ip, const int port, int64_t *file_size)
5058 {
5059 	ConnectionInfo storage_server;
5060 	ConnectionInfo *conn;
5061 	int result;
5062 
5063 	*file_size = 0;
5064 	strcpy(storage_server.ip_addr, storage_ip);
5065 	storage_server.port = port;
5066 	storage_server.sock = -1;
5067 	if ((conn=tracker_make_connection(&storage_server, &result)) == NULL)
5068 	{
5069 		return result;
5070 	}
5071 
5072 	result = _storage_get_trunk_binlog_size(conn, file_size);
5073 	tracker_close_connection_ex(conn, result != 0);
5074 
5075 
5076 	logDebug("file: "__FILE__", line: %d, " \
5077 		"storage %s:%d, trunk binlog file size: %"PRId64, \
5078 		__LINE__, storage_server.ip_addr, storage_server.port, \
5079 		*file_size);
5080 	return result;
5081 }
5082 
tracker_write_to_trunk_change_log(FDFSGroupInfo * pGroup,FDFSStorageDetail * pLastTrunkServer)5083 static int tracker_write_to_trunk_change_log(FDFSGroupInfo *pGroup, \
5084 		FDFSStorageDetail *pLastTrunkServer)
5085 {
5086 	char full_filename[MAX_PATH_SIZE];
5087 	char buff[256];
5088 	int fd;
5089 	int len;
5090 	struct tm tm;
5091 	time_t current_time;
5092 	FDFSStorageDetail *pLastTrunk;
5093 
5094 	tracker_mem_file_lock();
5095 
5096 	snprintf(full_filename, sizeof(full_filename), "%s/logs/%s", \
5097 		g_fdfs_base_path, TRUNK_SERVER_CHANGELOG_FILENAME);
5098 	if ((fd=open(full_filename, O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0)
5099 	{
5100 		tracker_mem_file_unlock();
5101 		logError("file: "__FILE__", line: %d, " \
5102 			"open \"%s\" fail, errno: %d, error info: %s", \
5103 			__LINE__, full_filename, errno, STRERROR(errno));
5104 		return errno != 0 ? errno : ENOENT;
5105 	}
5106 
5107 	current_time = g_current_time;
5108 	localtime_r(&current_time, &tm);
5109 	len = sprintf(buff, "[%04d-%02d-%02d %02d:%02d:%02d] %s ", \
5110 		tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, \
5111 		tm.tm_hour, tm.tm_min, tm.tm_sec, pGroup->group_name);
5112 
5113 	pLastTrunk = pLastTrunkServer;
5114 	if (pLastTrunk == NULL && *(pGroup->last_trunk_server_id) != '\0')
5115 	{
5116 		pLastTrunk = tracker_mem_get_storage(pGroup, \
5117 				pGroup->last_trunk_server_id);
5118 	}
5119 	if (g_use_storage_id)
5120 	{
5121 		if (pLastTrunk == NULL)
5122 		{
5123 			len += sprintf(buff + len, " %s/%s  => ",
5124 				*(pGroup->last_trunk_server_id) == '\0' ?
5125 				  "-" : pGroup->last_trunk_server_id, "-");
5126 		}
5127 		else
5128 		{
5129 			len += sprintf(buff + len, " %s/%s  => ",
5130 				pLastTrunk->id, FDFS_CURRENT_IP_ADDR(pLastTrunk));
5131 		}
5132 
5133 		if (pGroup->pTrunkServer == NULL)
5134 		{
5135 			len += sprintf(buff + len, " %s/%s\n", "-", "-");
5136 		}
5137 		else
5138 		{
5139 			len += sprintf(buff + len, " %s/%s\n",
5140 				pGroup->pTrunkServer->id,
5141                 FDFS_CURRENT_IP_ADDR(pGroup->pTrunkServer));
5142 		}
5143 	}
5144 	else
5145 	{
5146 		if (pLastTrunk == NULL)
5147 		{
5148 			len += sprintf(buff + len, " %s  => ",
5149 				*(pGroup->last_trunk_server_id) == '\0' ?
5150 				  "-" : pGroup->last_trunk_server_id);
5151 		}
5152 		else
5153 		{
5154 			len += sprintf(buff + len, " %s  => ",
5155                     FDFS_CURRENT_IP_ADDR(pLastTrunk));
5156 		}
5157 
5158 		if (pGroup->pTrunkServer == NULL)
5159 		{
5160 			len += sprintf(buff + len, " %s\n", "-");
5161 		}
5162 		else
5163 		{
5164 			len += sprintf(buff + len, " %s\n",
5165                     FDFS_CURRENT_IP_ADDR(pGroup->pTrunkServer));
5166 		}
5167 	}
5168 
5169 	if (fc_safe_write(fd, buff, len) != len)
5170 	{
5171 		logError("file: "__FILE__", line: %d, " \
5172 			"write to file \"%s\" fail, " \
5173 			"errno: %d, error info: %s", \
5174 			__LINE__, full_filename, \
5175 			errno, STRERROR(errno));
5176 	}
5177 
5178 	close(fd);
5179 	tracker_mem_file_unlock();
5180 
5181 	return 0;
5182 }
5183 
tracker_set_trunk_server_and_log(FDFSGroupInfo * pGroup,FDFSStorageDetail * pNewTrunkServer)5184 static int tracker_set_trunk_server_and_log(FDFSGroupInfo *pGroup, \
5185 		FDFSStorageDetail *pNewTrunkServer)
5186 {
5187 	FDFSStorageDetail *pLastTrunkServer;
5188 
5189 	pLastTrunkServer = pGroup->pTrunkServer;
5190 	pGroup->pTrunkServer = pNewTrunkServer;
5191 	if (pNewTrunkServer == NULL || strcmp(pNewTrunkServer->id, \
5192 					pGroup->last_trunk_server_id) != 0)
5193 	{
5194 		int result;
5195 		result = tracker_write_to_trunk_change_log(pGroup, \
5196 				pLastTrunkServer);
5197 		if (pNewTrunkServer == NULL)
5198 		{
5199 			*(pGroup->last_trunk_server_id) = '\0';
5200 		}
5201 		else
5202 		{
5203 			strcpy(pGroup->last_trunk_server_id, \
5204 				pNewTrunkServer->id);
5205 		}
5206 		return result;
5207 	}
5208 
5209 	return 0;
5210 }
5211 
tracker_mem_do_set_trunk_server(FDFSGroupInfo * pGroup,FDFSStorageDetail * pTrunkServer,const bool save)5212 static int tracker_mem_do_set_trunk_server(FDFSGroupInfo *pGroup,
5213 	FDFSStorageDetail *pTrunkServer, const bool save)
5214 {
5215 	int result;
5216 
5217 	if (*(pGroup->last_trunk_server_id) != '\0' &&
5218 	    strcmp(pTrunkServer->id, pGroup->last_trunk_server_id) != 0)
5219 	{
5220 		if ((result=fdfs_deal_no_body_cmd_ex(
5221                         FDFS_CURRENT_IP_ADDR(pTrunkServer),
5222                         pGroup->storage_port,
5223                         STORAGE_PROTO_CMD_TRUNK_DELETE_BINLOG_MARKS)) != 0)
5224 		{
5225             logError("file: "__FILE__", line: %d, "
5226                     "fdfs_deal_no_body_cmd_ex fail, result: %d",
5227                     __LINE__, result);
5228 			return result;
5229 		}
5230 	}
5231 
5232 	tracker_set_trunk_server_and_log(pGroup, pTrunkServer);
5233 	pGroup->trunk_chg_count++;
5234 	g_trunk_server_chg_count++;
5235 
5236 	logInfo("file: "__FILE__", line: %d, "
5237 		"group: %s, trunk server set to %s(%s:%d)", __LINE__,
5238 		pGroup->group_name, pGroup->pTrunkServer->id,
5239 		FDFS_CURRENT_IP_ADDR(pGroup->pTrunkServer),
5240         pGroup->storage_port);
5241 	if (save)
5242 	{
5243 		return tracker_save_groups();
5244 	}
5245 
5246 	return 0;
5247 }
5248 
tracker_mem_find_trunk_server(FDFSGroupInfo * pGroup,const bool save)5249 static int tracker_mem_find_trunk_server(FDFSGroupInfo *pGroup,
5250 		const bool save)
5251 {
5252 	FDFSStorageDetail *pStoreServer;
5253 	FDFSStorageDetail **ppServer;
5254 	FDFSStorageDetail **ppServerEnd;
5255 	int result;
5256 	int64_t file_size;
5257 	int64_t max_file_size;
5258 
5259 	pStoreServer = pGroup->pStoreServer;
5260 	if (pStoreServer == NULL)
5261 	{
5262 		return ENOENT;
5263 	}
5264 
5265 	result = tracker_mem_get_trunk_binlog_size(
5266             FDFS_CURRENT_IP_ADDR(pStoreServer),
5267             pGroup->storage_port, &max_file_size);
5268 	if (result != 0)
5269 	{
5270 		return result;
5271 	}
5272 
5273 	ppServerEnd = pGroup->active_servers + pGroup->active_count;
5274 	for (ppServer=pGroup->active_servers; ppServer<ppServerEnd; ppServer++)
5275 	{
5276 		if (*ppServer == pStoreServer)
5277 		{
5278 			continue;
5279 		}
5280 
5281 		result = tracker_mem_get_trunk_binlog_size(
5282                 FDFS_CURRENT_IP_ADDR(*ppServer),
5283                 pGroup->storage_port, &file_size);
5284 		if (result != 0)
5285 		{
5286 			continue;
5287 		}
5288 
5289 		if (file_size > max_file_size)
5290 		{
5291 			pStoreServer = *ppServer;
5292 		}
5293 	}
5294 
5295 	return tracker_mem_do_set_trunk_server(pGroup, pStoreServer, save);
5296 }
5297 
tracker_mem_set_trunk_server(FDFSGroupInfo * pGroup,const char * pStroageId,int * result)5298 const FDFSStorageDetail *tracker_mem_set_trunk_server( \
5299 	FDFSGroupInfo *pGroup, const char *pStroageId, int *result)
5300 {
5301 	FDFSStorageDetail *pServer;
5302 	FDFSStorageDetail *pTrunkServer;
5303 
5304 	if (!(g_if_leader_self && g_if_use_trunk_file))
5305 	{
5306 		*result = EOPNOTSUPP;
5307 		return NULL;
5308 	}
5309 
5310 	pTrunkServer = pGroup->pTrunkServer;
5311 	if (pStroageId == NULL || *pStroageId == '\0')
5312 	{
5313 		if (pTrunkServer != NULL && pTrunkServer-> \
5314 			status == FDFS_STORAGE_STATUS_ACTIVE)
5315 		{
5316 			*result = 0;
5317 			return pTrunkServer;
5318 		}
5319 
5320 		*result = tracker_mem_find_trunk_server(pGroup, true);
5321 		if (*result != 0)
5322 		{
5323 			return NULL;
5324 		}
5325 		return pGroup->pTrunkServer;
5326 	}
5327 
5328 	if (pTrunkServer != NULL && pTrunkServer->status == \
5329 			FDFS_STORAGE_STATUS_ACTIVE)
5330 	{
5331 		if (strcmp(pStroageId, pTrunkServer->id) == 0)
5332 		{
5333 			*result = EALREADY;
5334 		}
5335 		else
5336 		{
5337 			*result = EEXIST;
5338 		}
5339 		return pTrunkServer;
5340 	}
5341 
5342 	pServer = tracker_mem_get_storage(pGroup, pStroageId);
5343 	if (pServer == NULL)
5344 	{
5345 		*result = ENOENT;
5346 		return NULL;
5347 	}
5348 
5349 	if (pServer->status != FDFS_STORAGE_STATUS_ACTIVE)
5350 	{
5351 		*result = ENONET;
5352 		return NULL;
5353 	}
5354 
5355 	*result = tracker_mem_do_set_trunk_server(pGroup, \
5356 			pServer, true);
5357 	return *result == 0 ? pGroup->pTrunkServer : NULL;
5358 }
5359 
tracker_mem_deactive_store_server(FDFSGroupInfo * pGroup,FDFSStorageDetail * pTargetServer)5360 int tracker_mem_deactive_store_server(FDFSGroupInfo *pGroup,
5361 			FDFSStorageDetail *pTargetServer)
5362 {
5363 	int result;
5364 	FDFSStorageDetail **ppStorageServer;
5365 	FDFSStorageDetail **ppEnd;
5366 	FDFSStorageDetail **ppServer;
5367 
5368 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
5369 	{
5370 		logError("file: "__FILE__", line: %d, " \
5371 			"call pthread_mutex_lock fail, " \
5372 			"errno: %d, error info: %s", \
5373 			__LINE__, result, STRERROR(result));
5374 		return result;
5375 	}
5376 
5377 	ppStorageServer = (FDFSStorageDetail **)bsearch( \
5378 			&pTargetServer, \
5379 			pGroup->active_servers, \
5380 			pGroup->active_count,   \
5381 			sizeof(FDFSStorageDetail *), \
5382 			tracker_mem_cmp_by_storage_id);
5383 	if (ppStorageServer != NULL)
5384 	{
5385 		(*ppStorageServer)->chg_count = 0;
5386 		(*ppStorageServer)->trunk_chg_count = 0;
5387 
5388 		ppEnd = pGroup->active_servers + pGroup->active_count - 1;
5389 		for (ppServer=ppStorageServer; ppServer<ppEnd; ppServer++)
5390 		{
5391 			*ppServer = *(ppServer+1);
5392 		}
5393 
5394 		pGroup->active_count--;
5395 		pGroup->chg_count++;
5396 
5397 #ifdef WITH_HTTPD
5398 		if (g_http_check_interval <= 0)
5399 		{
5400 			pGroup->http_server_count = pGroup->active_count;
5401 		}
5402 #endif
5403 	}
5404 
5405 	tracker_mem_find_store_server(pGroup);
5406 
5407 	if ((result=pthread_mutex_unlock(&mem_thread_lock)) != 0)
5408 	{
5409 		logError("file: "__FILE__", line: %d, " \
5410 			"call pthread_mutex_unlock fail, " \
5411 			"errno: %d, error info: %s", \
5412 			__LINE__, result, STRERROR(result));
5413 		return result;
5414 	}
5415 
5416 	return 0;
5417 }
5418 
tracker_mem_active_store_server(FDFSGroupInfo * pGroup,FDFSStorageDetail * pTargetServer)5419 int tracker_mem_active_store_server(FDFSGroupInfo *pGroup, \
5420 			FDFSStorageDetail *pTargetServer)
5421 {
5422 	int result;
5423 	FDFSStorageDetail **ppStorageServer;
5424 
5425 	if ((pTargetServer->status == FDFS_STORAGE_STATUS_WAIT_SYNC) || \
5426 		(pTargetServer->status == FDFS_STORAGE_STATUS_SYNCING) || \
5427 		(pTargetServer->status == FDFS_STORAGE_STATUS_IP_CHANGED) || \
5428 		(pTargetServer->status == FDFS_STORAGE_STATUS_INIT))
5429 	{
5430 		return 0;
5431 	}
5432 
5433 	/*
5434 	if (pTargetServer->status == FDFS_STORAGE_STATUS_DELETED)
5435 	{
5436 		logError("file: "__FILE__", line: %d, " \
5437 			"storage ip: %s already deleted, you can " \
5438 			"restart the tracker servers to reset.", \
5439 			__LINE__, pTargetServer->ip_addr);
5440 		return EAGAIN;
5441 	}
5442 	*/
5443 
5444 	pTargetServer->status = FDFS_STORAGE_STATUS_ACTIVE;
5445 
5446 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetServer, \
5447 			pGroup->active_servers, \
5448 			pGroup->active_count,   \
5449 			sizeof(FDFSStorageDetail *), \
5450 			tracker_mem_cmp_by_storage_id);
5451 	if (ppStorageServer != NULL)
5452 	{
5453 		return 0;
5454 	}
5455 
5456 	if ((result=pthread_mutex_lock(&mem_thread_lock)) != 0)
5457 	{
5458 		logError("file: "__FILE__", line: %d, " \
5459 			"call pthread_mutex_lock fail, " \
5460 			"errno: %d, error info: %s", \
5461 			__LINE__, result, STRERROR(result));
5462 		return result;
5463 	}
5464 
5465 	ppStorageServer = (FDFSStorageDetail **)bsearch(&pTargetServer, \
5466 			pGroup->active_servers, \
5467 			pGroup->active_count,   \
5468 			sizeof(FDFSStorageDetail *), \
5469 			tracker_mem_cmp_by_storage_id);
5470 	if (ppStorageServer == NULL)
5471 	{
5472 		tracker_mem_insert_into_sorted_servers( \
5473 			pTargetServer, pGroup->active_servers, \
5474 			pGroup->active_count);
5475 		pGroup->active_count++;
5476 		pGroup->chg_count++;
5477 
5478 #ifdef WITH_HTTPD
5479 		if (g_http_check_interval <= 0)
5480 		{
5481 			pGroup->http_server_count = pGroup->active_count;
5482 		}
5483 #endif
5484 
5485 		if (g_use_storage_id)
5486 		{
5487 			logDebug("file: "__FILE__", line: %d, "
5488 				"storage server %s::%s(%s) now active",
5489 				__LINE__, pGroup->group_name,
5490 				pTargetServer->id, FDFS_CURRENT_IP_ADDR(pTargetServer));
5491 		}
5492 		else
5493 		{
5494 			logDebug("file: "__FILE__", line: %d, "
5495 				"storage server %s::%s now active",
5496 				__LINE__, pGroup->group_name,
5497 				FDFS_CURRENT_IP_ADDR(pTargetServer));
5498 		}
5499 	}
5500 
5501 	tracker_mem_find_store_server(pGroup);
5502 	if (g_if_leader_self && g_if_use_trunk_file && \
5503 		pGroup->pTrunkServer == NULL)
5504 	{
5505 		tracker_mem_find_trunk_server(pGroup, true);
5506 	}
5507 
5508 	if ((result=pthread_mutex_unlock(&mem_thread_lock)) != 0)
5509 	{
5510 		logError("file: "__FILE__", line: %d, " \
5511 			"call pthread_mutex_unlock fail, " \
5512 			"errno: %d, error info: %s", \
5513 			__LINE__, result, STRERROR(result));
5514 		return result;
5515 	}
5516 
5517 	return 0;
5518 }
5519 
tracker_mem_find_trunk_servers()5520 void tracker_mem_find_trunk_servers()
5521 {
5522 	FDFSGroupInfo **ppGroup;
5523 	FDFSGroupInfo **ppGroupEnd;
5524 
5525 	if (!(g_if_leader_self && g_if_use_trunk_file))
5526 	{
5527 		return;
5528 	}
5529 
5530 	pthread_mutex_lock(&mem_thread_lock);
5531 	ppGroupEnd = g_groups.groups + g_groups.count;
5532 	for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
5533 	{
5534 		if ((*ppGroup)->pTrunkServer == NULL)
5535 		{
5536 			tracker_mem_find_trunk_server(*ppGroup, true);
5537 		}
5538 	}
5539 	g_trunk_server_chg_count++;
5540 	pthread_mutex_unlock(&mem_thread_lock);
5541 }
5542 
tracker_mem_offline_store_server(FDFSGroupInfo * pGroup,FDFSStorageDetail * pStorage)5543 int tracker_mem_offline_store_server(FDFSGroupInfo *pGroup, \
5544 			FDFSStorageDetail *pStorage)
5545 {
5546 	pStorage->up_time = 0;
5547 	if ((pStorage->status == FDFS_STORAGE_STATUS_WAIT_SYNC) || \
5548 		(pStorage->status == FDFS_STORAGE_STATUS_SYNCING) || \
5549 		(pStorage->status == FDFS_STORAGE_STATUS_INIT) || \
5550 		(pStorage->status == FDFS_STORAGE_STATUS_DELETED) || \
5551 		(pStorage->status == FDFS_STORAGE_STATUS_IP_CHANGED) || \
5552 		(pStorage->status == FDFS_STORAGE_STATUS_RECOVERY))
5553 	{
5554 		return 0;
5555 	}
5556 
5557 	if (g_use_storage_id)
5558 	{
5559 		logDebug("file: "__FILE__", line: %d, "
5560 			"storage server %s::%s (%s) offline",
5561 			__LINE__, pGroup->group_name,
5562 			pStorage->id, FDFS_CURRENT_IP_ADDR(pStorage));
5563 	}
5564 	else
5565 	{
5566 		logDebug("file: "__FILE__", line: %d, "
5567 			"storage server %s::%s offline",
5568 			__LINE__, pGroup->group_name,
5569 			FDFS_CURRENT_IP_ADDR(pStorage));
5570 	}
5571 
5572 	pStorage->status = FDFS_STORAGE_STATUS_OFFLINE;
5573 	return tracker_mem_deactive_store_server(pGroup, pStorage);
5574 }
5575 
tracker_get_writable_storage(FDFSGroupInfo * pStoreGroup)5576 FDFSStorageDetail *tracker_get_writable_storage(FDFSGroupInfo *pStoreGroup)
5577 {
5578 	int write_server_index;
5579 	if (g_groups.store_server == FDFS_STORE_SERVER_ROUND_ROBIN)
5580 	{
5581 		write_server_index = pStoreGroup->current_write_server++;
5582 		if (pStoreGroup->current_write_server >= \
5583 				pStoreGroup->active_count)
5584 		{
5585 			pStoreGroup->current_write_server = 0;
5586 		}
5587 
5588 		if (write_server_index >= pStoreGroup->active_count)
5589 		{
5590 			write_server_index = 0;
5591 		}
5592 		return  *(pStoreGroup->active_servers + write_server_index);
5593 	}
5594 	else //use the first server
5595 	{
5596 		return pStoreGroup->pStoreServer;
5597 	}
5598 }
5599 
tracker_mem_get_storage_by_filename(const byte cmd,FDFS_DOWNLOAD_TYPE_PARAM const char * group_name,const char * filename,const int filename_len,FDFSGroupInfo ** ppGroup,FDFSStorageDetail ** ppStoreServers,int * server_count)5600 int tracker_mem_get_storage_by_filename(const byte cmd,FDFS_DOWNLOAD_TYPE_PARAM\
5601 	const char *group_name, const char *filename, const int filename_len, \
5602 	FDFSGroupInfo **ppGroup, FDFSStorageDetail **ppStoreServers, \
5603 	int *server_count)
5604 {
5605 	char szIpAddr[IP_ADDRESS_SIZE];
5606 	char storage_id[FDFS_STORAGE_ID_MAX_SIZE];
5607 	FDFSStorageDetail *pStoreSrcServer;
5608 	FDFSStorageDetail **ppServer;
5609 	FDFSStorageDetail **ppServerEnd;
5610 	FDFSStorageDetail *pGroupStoreServer;
5611 	int file_timestamp;
5612 	int storage_ip;
5613 	int read_server_index;
5614 	int cmp_res;
5615 	struct in_addr ip_addr;
5616 	time_t current_time;
5617 	bool bNormalFile;
5618 
5619 	*server_count = 0;
5620 	*ppGroup = tracker_mem_get_group(group_name);
5621 	if (*ppGroup == NULL)
5622 	{
5623 		logError("file: "__FILE__", line: %d, " \
5624 			"invalid group_name: %s", \
5625 			__LINE__, group_name);
5626 		return ENOENT;
5627 	}
5628 
5629 #ifdef WITH_HTTPD
5630 	if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5631 	{
5632 		if ((*ppGroup)->active_count == 0)
5633 		{
5634 			return ENOENT;
5635 		}
5636 	}
5637 	else
5638 	{
5639 		if ((*ppGroup)->http_server_count == 0)
5640 		{
5641 			return ENOENT;
5642 		}
5643 	}
5644 #else
5645 	if ((*ppGroup)->active_count == 0)
5646 	{
5647 		return ENOENT;
5648 	}
5649 #endif
5650 
5651 	pGroupStoreServer = (*ppGroup)->pStoreServer;
5652 	if (pGroupStoreServer == NULL)
5653 	{
5654 		return ENOENT;
5655 	}
5656 
5657 	//file generated by version < v1.12
5658 	if (filename_len < 32 + (FDFS_FILE_EXT_NAME_MAX_LEN + 1))
5659 	{
5660 		storage_ip = INADDR_NONE;
5661 		*storage_id = '\0';
5662 		file_timestamp = 0;
5663 		bNormalFile = true;
5664 	}
5665 	else //file generated by version >= v1.12
5666 	{
5667 		int64_t file_size;
5668 
5669 		char name_buff[64];
5670 		int decoded_len;
5671 
5672 		base64_decode_auto(&g_base64_context, (char *)filename + \
5673 			FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
5674 			name_buff, &decoded_len);
5675 		storage_ip = ntohl(buff2int(name_buff));
5676 		file_timestamp = buff2int(name_buff+sizeof(int));
5677 		file_size = buff2long(name_buff + sizeof (int) * 2);
5678 
5679 		if (fdfs_get_server_id_type(storage_ip) == FDFS_ID_TYPE_SERVER_ID)
5680 		{
5681 			sprintf(storage_id, "%d", storage_ip);
5682 		}
5683 		else
5684 		{
5685 			*storage_id = '\0';
5686 		}
5687 
5688 		bNormalFile = !(IS_SLAVE_FILE(filename_len, file_size) || \
5689 				IS_APPENDER_FILE(file_size));
5690 	}
5691 
5692 	/*
5693 	//logInfo("cmd=%d, bNormalFile=%d, storage_ip=%d, storage_id=%s, "
5694     "file_timestamp=%d\n", cmd, bNormalFile, storage_ip,
5695     storage_id, file_timestamp);
5696 	*/
5697 
5698 	memset(szIpAddr, 0, sizeof(szIpAddr));
5699 	if (cmd == TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE)
5700 	{
5701 		if (g_groups.download_server == \
5702 				FDFS_DOWNLOAD_SERVER_SOURCE_FIRST)
5703 		{
5704 #ifdef WITH_HTTPD
5705 			if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5706 			{
5707 				if (*storage_id != '\0')
5708 				{
5709 					pStoreSrcServer=tracker_mem_get_active_storage_by_id(\
5710 						*ppGroup, storage_id);
5711 				}
5712 				else
5713 				{
5714 					memset(&ip_addr, 0, sizeof(ip_addr));
5715 					ip_addr.s_addr = storage_ip;
5716 					pStoreSrcServer=tracker_mem_get_active_storage_by_ip( \
5717 						*ppGroup, inet_ntop(AF_INET, &ip_addr, \
5718 						szIpAddr, sizeof(szIpAddr)));
5719 				}
5720 			}
5721 			else
5722 			{
5723 				if (*storage_id != '\0')
5724 				{
5725 				pStoreSrcServer=tracker_mem_get_active_http_server_by_id( \
5726 				*ppGroup, storage_id);
5727 				}
5728 				else
5729 				{
5730 				memset(&ip_addr, 0, sizeof(ip_addr));
5731 				ip_addr.s_addr = storage_ip;
5732 				pStoreSrcServer=tracker_mem_get_active_http_server_by_ip( \
5733 				*ppGroup, inet_ntop(AF_INET, &ip_addr, \
5734 				szIpAddr, sizeof(szIpAddr)));
5735 				}
5736 			}
5737 #else
5738 			if (*storage_id != '\0')
5739 			{
5740 			pStoreSrcServer=tracker_mem_get_active_storage_by_id(\
5741 				*ppGroup, storage_id);
5742 			}
5743 			else
5744 			{
5745 			memset(&ip_addr, 0, sizeof(ip_addr));
5746 			ip_addr.s_addr = storage_ip;
5747 			pStoreSrcServer=tracker_mem_get_active_storage_by_ip(\
5748 				*ppGroup, inet_ntop(AF_INET, &ip_addr, \
5749 				szIpAddr, sizeof(szIpAddr)));
5750 			}
5751 #endif
5752 			if (pStoreSrcServer != NULL)
5753 			{
5754 				ppStoreServers[(*server_count)++] = \
5755 						 pStoreSrcServer;
5756 				return 0;
5757 			}
5758 		}
5759 
5760 		//round robin
5761 #ifdef WITH_HTTPD
5762 		if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5763 		{
5764 		read_server_index = (*ppGroup)->current_read_server;
5765 		if (read_server_index >= (*ppGroup)->active_count)
5766 		{
5767 			read_server_index = 0;
5768 		}
5769 		ppStoreServers[(*server_count)++]=*((*ppGroup)->active_servers \
5770 				+ read_server_index);
5771 		}
5772 		else
5773 		{
5774 		read_server_index = (*ppGroup)->current_http_server;
5775 		if (read_server_index >= (*ppGroup)->http_server_count)
5776 		{
5777 			read_server_index = 0;
5778 		}
5779 		ppStoreServers[(*server_count)++]=*((*ppGroup)->http_servers \
5780 				+ read_server_index);
5781 		}
5782 #else
5783 		read_server_index = (*ppGroup)->current_read_server;
5784 		if (read_server_index >= (*ppGroup)->active_count)
5785 		{
5786 			read_server_index = 0;
5787 		}
5788 		ppStoreServers[(*server_count)++]=*((*ppGroup)->active_servers \
5789 				+ read_server_index);
5790 #endif
5791 		/*
5792 		//logInfo("filename=%s, storage server ip=%s, " \
5793 		"file_timestamp=%d, last_synced_timestamp=%d\n",
5794 		filename, ppStoreServers[0]->ip_addr, file_timestamp, \
5795 		(int)ppStoreServers[0]->stat.last_synced_timestamp);
5796 		*/
5797 
5798 		do
5799 		{
5800 			if (bNormalFile)
5801 			{
5802 			current_time = g_current_time;
5803 			if ((file_timestamp < current_time - \
5804 				g_storage_sync_file_max_delay) || \
5805 			(ppStoreServers[0]->stat.last_synced_timestamp > \
5806 				file_timestamp) || \
5807 			(ppStoreServers[0]->stat.last_synced_timestamp + 1 >= \
5808 			 file_timestamp && current_time - file_timestamp > \
5809 				g_storage_sync_file_max_time)\
5810 			|| (storage_ip == INADDR_NONE \
5811 			&& g_groups.store_server == FDFS_STORE_SERVER_ROUND_ROBIN))
5812 			{
5813 				break;
5814 			}
5815 
5816 			if (storage_ip == INADDR_NONE)
5817 			{
5818 #ifdef WITH_HTTPD
5819 				if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5820 				{
5821 				ppStoreServers[0] = pGroupStoreServer;
5822 				break;
5823 				}
5824 				else
5825 				{
5826 				pStoreSrcServer=tracker_mem_get_active_storage_by_id(
5827 					*ppGroup, pGroupStoreServer->id);
5828 				if (pStoreSrcServer != NULL)
5829 				{
5830 					ppStoreServers[0] = pStoreSrcServer;
5831 					break;
5832 				}
5833 				}
5834 #else
5835 				ppStoreServers[0] = pGroupStoreServer;
5836 				break;
5837 #endif
5838 			}
5839 			}
5840 
5841       memset(&ip_addr, 0, sizeof(ip_addr));
5842       if (*storage_id != '\0')
5843       {
5844           cmp_res = strcmp(storage_id, ppStoreServers[0]->id);
5845       }
5846       else
5847       {
5848           ip_addr.s_addr = storage_ip;
5849           inet_ntop(AF_INET, &ip_addr, szIpAddr, sizeof(szIpAddr));
5850           cmp_res = strcmp(szIpAddr, FDFS_CURRENT_IP_ADDR(ppStoreServers[0]));
5851       }
5852       if (cmp_res == 0)
5853 			{
5854 #ifdef WITH_HTTPD
5855 				if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5856 				{
5857 					break;
5858 				}
5859 				else //http
5860 				{
5861           if (*storage_id != '\0')
5862           {
5863             if (tracker_mem_get_active_http_server_by_id(
5864 	  					*ppGroup, storage_id) != NULL)
5865 		  			{
5866 			  			break;
5867 				  	}
5868           }
5869           else if (tracker_mem_get_active_http_server_by_ip(
5870 						*ppGroup, szIpAddr) != NULL)
5871 					{
5872 					  break;
5873 					}
5874 				}
5875 #else
5876 				break;
5877 #endif
5878 			}
5879 
5880 			if (g_groups.download_server == \
5881 					FDFS_DOWNLOAD_SERVER_ROUND_ROBIN)
5882 			{  //avoid search again
5883 #ifdef WITH_HTTPD
5884 				if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5885 				{
5886         if (*storage_id != '\0')
5887         {
5888 				pStoreSrcServer=tracker_mem_get_active_storage_by_id(
5889 					*ppGroup, storage_id);
5890         }
5891         else
5892         {
5893 				pStoreSrcServer=tracker_mem_get_active_storage_by_ip(
5894 					*ppGroup, szIpAddr);
5895         }
5896 				}
5897 				else //http
5898 				{
5899         if (*storage_id != '\0')
5900         {
5901 				pStoreSrcServer=tracker_mem_get_active_http_server_by_id(
5902 					*ppGroup, storage_id);
5903         }
5904         else
5905         {
5906 				pStoreSrcServer=tracker_mem_get_active_http_server_by_ip(
5907 					*ppGroup, szIpAddr);
5908         }
5909 				}
5910 #else
5911         if (*storage_id != '\0')
5912         {
5913 				pStoreSrcServer=tracker_mem_get_active_storage_by_id(
5914 					*ppGroup, storage_id);
5915         }
5916         else
5917         {
5918 				pStoreSrcServer=tracker_mem_get_active_storage_by_ip(
5919 					*ppGroup, szIpAddr);
5920         }
5921 #endif
5922 				if (pStoreSrcServer != NULL)
5923 				{
5924 					ppStoreServers[0] = pStoreSrcServer;
5925 					break;
5926 				}
5927 			}
5928 
5929 			if (g_groups.store_server != \
5930 				FDFS_STORE_SERVER_ROUND_ROBIN)
5931 			{
5932 #ifdef WITH_HTTPD
5933 				if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5934 				{
5935 				ppStoreServers[0] = pGroupStoreServer;
5936 				}
5937 				else  //http
5938 				{
5939 				pStoreSrcServer=tracker_mem_get_active_http_server_by_id(
5940 					*ppGroup, pGroupStoreServer->id);
5941 				if (pStoreSrcServer != NULL)
5942 				{
5943 				ppStoreServers[0] = pStoreSrcServer;
5944 				}
5945 				else
5946 				{
5947 				ppStoreServers[0] = *((*ppGroup)->http_servers);
5948 				}
5949 				}
5950 #else
5951 				ppStoreServers[0] = pGroupStoreServer;
5952 #endif
5953 				break;
5954 			}
5955 		} while (0);
5956 
5957 #ifdef WITH_HTTPD
5958 		if (download_type == FDFS_DOWNLOAD_TYPE_TCP)
5959 		{
5960 		(*ppGroup)->current_read_server++;
5961 		if ((*ppGroup)->current_read_server >= (*ppGroup)->active_count)
5962 		{
5963 			(*ppGroup)->current_read_server = 0;
5964 		}
5965 		}
5966 		else  //http
5967 		{
5968 			(*ppGroup)->current_http_server++;
5969 			if ((*ppGroup)->current_http_server >= \
5970 				(*ppGroup)->http_server_count)
5971 			{
5972 				(*ppGroup)->current_http_server = 0;
5973 			}
5974 		}
5975 #else
5976 		(*ppGroup)->current_read_server++;
5977 		if ((*ppGroup)->current_read_server >= (*ppGroup)->active_count)
5978 		{
5979 			(*ppGroup)->current_read_server = 0;
5980 		}
5981 #endif
5982 	}
5983 	else if (cmd == TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE)
5984 	{
5985 		if (storage_ip != INADDR_NONE)
5986 		{
5987       if (*storage_id != '\0')
5988       {
5989 			pStoreSrcServer=tracker_mem_get_active_storage_by_id(\
5990 					*ppGroup, storage_id);
5991       }
5992       else
5993       {
5994 			memset(&ip_addr, 0, sizeof(ip_addr));
5995 			ip_addr.s_addr = storage_ip;
5996 			pStoreSrcServer=tracker_mem_get_active_storage_by_ip(\
5997 					*ppGroup, inet_ntop(AF_INET, &ip_addr, \
5998 					szIpAddr, sizeof(szIpAddr)));
5999       }
6000 
6001 			if (pStoreSrcServer != NULL)
6002 			{
6003 				ppStoreServers[(*server_count)++] = \
6004 							 pStoreSrcServer;
6005 				return 0;
6006 			}
6007 		}
6008 
6009 		ppStoreServers[0] = tracker_get_writable_storage(*ppGroup);
6010 		*server_count = ppStoreServers[0] != NULL ? 1 : 0;
6011 	}
6012 	else //TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL
6013 	{
6014 		memset(szIpAddr, 0, sizeof(szIpAddr));
6015 		if (storage_ip != INADDR_NONE)
6016 		{
6017 			memset(&ip_addr, 0, sizeof(ip_addr));
6018 			ip_addr.s_addr = storage_ip;
6019 			inet_ntop(AF_INET, &ip_addr,szIpAddr,sizeof(szIpAddr));
6020 		}
6021 
6022 		if (bNormalFile)
6023 		{
6024 		current_time = g_current_time;
6025 		ppServerEnd = (*ppGroup)->active_servers + \
6026 				(*ppGroup)->active_count;
6027 
6028 		for (ppServer=(*ppGroup)->active_servers; \
6029 				ppServer<ppServerEnd; ppServer++)
6030 		{
6031 			if ((file_timestamp < current_time -
6032 				g_storage_sync_file_max_delay) ||
6033 			((*ppServer)->stat.last_synced_timestamp >
6034 				file_timestamp) ||
6035 			((*ppServer)->stat.last_synced_timestamp + 1 >=
6036 			 file_timestamp && current_time - file_timestamp >
6037 				g_storage_sync_file_max_time)
6038 				|| (storage_ip == INADDR_NONE
6039 					&& g_groups.store_server ==
6040 					FDFS_STORE_SERVER_ROUND_ROBIN)
6041 				|| strcmp(FDFS_CURRENT_IP_ADDR(*ppServer), szIpAddr) == 0)
6042 			{
6043 				ppStoreServers[(*server_count)++] = *ppServer;
6044 			}
6045 		}
6046 		}
6047 		else
6048 		{
6049       if (*storage_id != '\0')
6050       {
6051 			pStoreSrcServer = tracker_mem_get_active_storage_by_id( \
6052 						*ppGroup, storage_id);
6053       }
6054       else
6055       {
6056 			pStoreSrcServer = tracker_mem_get_active_storage_by_ip( \
6057 						*ppGroup, szIpAddr);
6058       }
6059 
6060 			if (pStoreSrcServer != NULL)
6061 			{
6062 				ppStoreServers[(*server_count)++] = \
6063 						pStoreSrcServer;
6064 			}
6065 		}
6066 
6067 		if (*server_count == 0)
6068 		{
6069 			ppStoreServers[(*server_count)++] = pGroupStoreServer;
6070 		}
6071 	}
6072 
6073 	return *server_count > 0 ? 0 : ENOENT;
6074 }
6075 
tracker_mem_check_alive(void * arg)6076 int tracker_mem_check_alive(void *arg)
6077 {
6078 	FDFSStorageDetail **ppServer;
6079 	FDFSStorageDetail **ppServerEnd;
6080 	FDFSGroupInfo **ppGroup;
6081 	FDFSGroupInfo **ppGroupEnd;
6082 	FDFSStorageDetail *deactiveServers[FDFS_MAX_SERVERS_EACH_GROUP];
6083 	int deactiveCount;
6084 	time_t current_time;
6085 
6086 	current_time = g_current_time;
6087 	ppGroupEnd = g_groups.groups + g_groups.count;
6088 	for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
6089 	{
6090 	deactiveCount = 0;
6091 	ppServerEnd = (*ppGroup)->active_servers + (*ppGroup)->active_count;
6092 	for (ppServer=(*ppGroup)->active_servers; ppServer<ppServerEnd; ppServer++)
6093 	{
6094 		if (current_time - (*ppServer)->stat.last_heart_beat_time > \
6095 			g_check_active_interval)
6096 		{
6097 			deactiveServers[deactiveCount] = *ppServer;
6098 			deactiveCount++;
6099 			if (deactiveCount >= FDFS_MAX_SERVERS_EACH_GROUP)
6100 			{
6101 				break;
6102 			}
6103 		}
6104 	}
6105 
6106 	if (deactiveCount == 0)
6107 	{
6108 		continue;
6109 	}
6110 
6111 	ppServerEnd = deactiveServers + deactiveCount;
6112 	for (ppServer=deactiveServers; ppServer<ppServerEnd; ppServer++)
6113 	{
6114 		(*ppServer)->status = FDFS_STORAGE_STATUS_OFFLINE;
6115 		tracker_mem_deactive_store_server(*ppGroup, *ppServer);
6116 		if (g_use_storage_id)
6117 		{
6118 			logInfo("file: "__FILE__", line: %d, "
6119 				"storage server %s(%s:%d) idle too long, "
6120 				"status change to offline!", __LINE__,
6121 				(*ppServer)->id, FDFS_CURRENT_IP_ADDR(*ppServer),
6122 				(*ppGroup)->storage_port);
6123 		}
6124 		else
6125 		{
6126 			logInfo("file: "__FILE__", line: %d, "
6127 				"storage server %s:%d idle too long, "
6128 				"status change to offline!", __LINE__,
6129 				FDFS_CURRENT_IP_ADDR(*ppServer),
6130                 (*ppGroup)->storage_port);
6131 		}
6132 	}
6133 	}
6134 
6135 	if ((!g_if_leader_self) || (!g_if_use_trunk_file))
6136 	{
6137 		return 0;
6138 	}
6139 
6140 	for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
6141 	{
6142 	if ((*ppGroup)->pTrunkServer != NULL)
6143 	{
6144 		int check_trunk_times;
6145 		int check_trunk_interval;
6146 		int last_beat_interval;
6147 
6148 		if (current_time - (*ppGroup)->pTrunkServer->up_time <= \
6149 			10 * g_check_active_interval)
6150 		{
6151 			if (g_trunk_init_check_occupying)
6152 			{
6153 				check_trunk_times = 5;
6154 			}
6155 			else
6156 			{
6157 				check_trunk_times = 3;
6158 			}
6159 
6160 			if (g_trunk_init_reload_from_binlog)
6161 			{
6162 				check_trunk_times *= 2;
6163 			}
6164 		}
6165 		else
6166 		{
6167 			check_trunk_times = 2;
6168 		}
6169 
6170 		last_beat_interval = current_time - (*ppGroup)-> \
6171 				pTrunkServer->stat.last_heart_beat_time;
6172 		check_trunk_interval = check_trunk_times * \
6173 					g_check_active_interval;
6174 	    	if (last_beat_interval > check_trunk_interval)
6175 		{
6176 			logInfo("file: "__FILE__", line: %d, "
6177 				"trunk server %s(%s:%d) offline because idle "
6178 				"time: %d s > threshold: %d s, should "
6179 				"re-select trunk server", __LINE__,
6180 				(*ppGroup)->pTrunkServer->id,
6181 				FDFS_CURRENT_IP_ADDR((*ppGroup)->pTrunkServer),
6182 				(*ppGroup)->storage_port, last_beat_interval,
6183 				check_trunk_interval);
6184 
6185 			(*ppGroup)->pTrunkServer = NULL;
6186 			tracker_mem_find_trunk_server(*ppGroup, false);
6187 			if ((*ppGroup)->pTrunkServer == NULL)
6188 			{
6189 				tracker_set_trunk_server_and_log(*ppGroup, NULL);
6190 			}
6191 
6192 			(*ppGroup)->trunk_chg_count++;
6193 			g_trunk_server_chg_count++;
6194 
6195 			tracker_save_groups();
6196 		}
6197 	}
6198 	else
6199 	{
6200 		tracker_mem_find_trunk_server(*ppGroup, true);
6201 	}
6202 	}
6203 
6204 	return 0;
6205 }
6206 
tracker_mem_get_storage_index(FDFSGroupInfo * pGroup,FDFSStorageDetail * pStorage)6207 int tracker_mem_get_storage_index(FDFSGroupInfo *pGroup, \
6208 		FDFSStorageDetail *pStorage)
6209 {
6210 	FDFSStorageDetail **ppStorage;
6211 	FDFSStorageDetail **ppEnd;
6212 
6213 	ppEnd = pGroup->all_servers + pGroup->count;
6214 	for (ppStorage=pGroup->all_servers; ppStorage<ppEnd; ppStorage++)
6215 	{
6216 		if (*ppStorage == pStorage)
6217 		{
6218 			return ppStorage - pGroup->all_servers;
6219 		}
6220 	}
6221 
6222 	logError("file: "__FILE__", line: %d, "
6223 		"get index of storage %s fail!!!",
6224 		__LINE__, FDFS_CURRENT_IP_ADDR(pStorage));
6225 
6226 	return -1;
6227 }
6228 
6229