/** * Copyright (C) 2008 Happy Fish / YuQing * * FastDFS may be copied only under the terms of the GNU General * Public License V3, which may be found in the FastDFS source kit. * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail. **/ #include #include #include #include #include #include #include #include #include #include #include "fdfs_define.h" #include "fastcommon/logger.h" #include "fdfs_global.h" #include "fastcommon/sockopt.h" #include "fastcommon/shared_func.h" #include "tracker_types.h" #include "tracker_proto.h" #include "storage_global.h" #include "storage_func.h" #include "storage_ip_changed_dealer.h" static int storage_do_changelog_req(ConnectionInfo *pTrackerServer) { char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \ FDFS_STORAGE_ID_MAX_SIZE]; TrackerHeader *pHeader; int result; memset(out_buff, 0, sizeof(out_buff)); pHeader = (TrackerHeader *)out_buff; long2buff(FDFS_GROUP_NAME_MAX_LEN + FDFS_STORAGE_ID_MAX_SIZE, \ pHeader->pkg_len); pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_CHANGELOG_REQ; strcpy(out_buff + sizeof(TrackerHeader), g_group_name); strcpy(out_buff + sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, g_my_server_id_str); if((result=tcpsenddata_nb(pTrackerServer->sock, out_buff, \ sizeof(out_buff), SF_G_NETWORK_TIMEOUT)) != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d, send data fail, " \ "errno: %d, error info: %s.", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); return result; } return tracker_deal_changelog_response(pTrackerServer); } static int storage_report_ip_changed(ConnectionInfo *pTrackerServer) { char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \ 2 * IP_ADDRESS_SIZE]; char in_buff[1]; char *pInBuff; TrackerHeader *pHeader; int result; int64_t in_bytes; memset(out_buff, 0, sizeof(out_buff)); pHeader = (TrackerHeader *)out_buff; long2buff(FDFS_GROUP_NAME_MAX_LEN+2*IP_ADDRESS_SIZE, pHeader->pkg_len); pHeader->cmd = TRACKER_PROTO_CMD_STORAGE_REPORT_IP_CHANGED; strcpy(out_buff + sizeof(TrackerHeader), g_group_name); strcpy(out_buff + sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, \ g_last_storage_ip.ips[0].address); strcpy(out_buff + sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \ IP_ADDRESS_SIZE, g_tracker_client_ip.ips[0].address); if((result=tcpsenddata_nb(pTrackerServer->sock, out_buff, \ sizeof(out_buff), SF_G_NETWORK_TIMEOUT)) != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d, send data fail, " \ "errno: %d, error info: %s", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, result, STRERROR(result)); return result; } pInBuff = in_buff; result = fdfs_recv_response(pTrackerServer, &pInBuff, 0, &in_bytes); if (result == 0 || result == EALREADY || result == ENOENT || result == EEXIST) { if (result != 0) { logWarning("file: "__FILE__", line: %d, " "fdfs_recv_response fail, result: %d", __LINE__, result); } return 0; } else { logError("file: "__FILE__", line: %d, " "tracker server %s:%d, recv data fail or " "response status != 0, " "errno: %d, error info: %s", __LINE__, pTrackerServer->ip_addr, pTrackerServer->port, result, STRERROR(result)); return result == EBUSY ? 0 : result; } } int storage_get_my_tracker_client_ip() { TrackerServerInfo *pGlobalServer; TrackerServerInfo *pTServer; TrackerServerInfo *pTServerEnd; TrackerServerInfo trackerServer; ConnectionInfo *conn; char tracker_client_ip[IP_ADDRESS_SIZE]; int success_count; int result; int i; conn = NULL; result = 0; success_count = 0; pTServer = &trackerServer; pTServerEnd = g_tracker_group.servers + g_tracker_group.server_count; while (success_count == 0 && SF_G_CONTINUE_FLAG) { for (pGlobalServer=g_tracker_group.servers; pGlobalServerconnections[0].ip_addr, pTServer->connections[0].port, result, STRERROR(result)); continue; } if ((result=storage_set_tracker_client_ips(conn, pGlobalServer - g_tracker_group.servers)) != 0) { close(conn->sock); return result; } getSockIpaddr(conn->sock, tracker_client_ip, IP_ADDRESS_SIZE); insert_into_local_host_ip(tracker_client_ip); fdfs_quit(conn); close(conn->sock); success_count++; } } if (!SF_G_CONTINUE_FLAG) { return EINTR; } return 0; } static int storage_report_storage_ip_addr() { TrackerServerInfo *pGlobalServer; TrackerServerInfo *pTServer; TrackerServerInfo *pTServerEnd; TrackerServerInfo trackerServer; ConnectionInfo *conn; int success_count; int result; int i; result = 0; success_count = 0; pTServer = &trackerServer; pTServerEnd = g_tracker_group.servers + g_tracker_group.server_count; logDebug("file: "__FILE__", line: %d, " "last my ip is %s, current my ip is %s", __LINE__, g_last_storage_ip.ips[0].address, g_tracker_client_ip.ips[0].address); if (g_last_storage_ip.count == 0) { return storage_write_to_sync_ini_file(); } else if (strcmp(g_tracker_client_ip.ips[0].address, g_last_storage_ip.ips[0].address) == 0) { return 0; } success_count = 0; while (success_count == 0 && SF_G_CONTINUE_FLAG) { for (pGlobalServer=g_tracker_group.servers; pGlobalServerconnections[0].ip_addr, pTServer->connections[0].port, result, STRERROR(result)); continue; } if ((result=storage_report_ip_changed(conn)) == 0) { success_count++; } else { sleep(1); } fdfs_quit(conn); close(conn->sock); } } if (!SF_G_CONTINUE_FLAG) { return EINTR; } return storage_write_to_sync_ini_file(); } int storage_changelog_req() { TrackerServerInfo *pGlobalServer; TrackerServerInfo *pTServer; TrackerServerInfo *pTServerEnd; TrackerServerInfo trackerServer; ConnectionInfo *conn; int success_count; int result; int i; result = 0; success_count = 0; pTServer = &trackerServer; pTServerEnd = g_tracker_group.servers + g_tracker_group.server_count; while (success_count == 0 && SF_G_CONTINUE_FLAG) { for (pGlobalServer=g_tracker_group.servers; pGlobalServerconnections[0].ip_addr, pTServer->connections[0].port, result, STRERROR(result)); continue; } result = storage_do_changelog_req(conn); if (result == 0 || result == ENOENT) { success_count++; } else { sleep(1); } fdfs_quit(conn); close(conn->sock); } } if (!SF_G_CONTINUE_FLAG) { return EINTR; } return 0; } int storage_check_ip_changed() { int result; if ((!g_storage_ip_changed_auto_adjust) || g_use_storage_id) { return 0; } if ((result=storage_report_storage_ip_addr()) != 0) { return result; } if (g_last_storage_ip.count == 0) //first run { return 0; } return storage_changelog_req(); }