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(¤t_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