int fdfs_recv_header(ConnectionInfo *pTrackerServer, int64_t *in_bytes) { TrackerHeader resp; int result; if ((result=tcprecvdata_nb(pTrackerServer->sock, &resp, \ sizeof(resp), g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "server: %s:%d, recv data fail, " \ "errno: %d, error info: %s", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); *in_bytes = 0; return result; } if (resp.status != 0) { logError("file: "__FILE__", line: %d, " \ "server: %s:%d, response status %d != 0", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, resp.status); *in_bytes = 0; return resp.status; } *in_bytes = buff2long(resp.pkg_len); if (*in_bytes < 0) { logError("file: "__FILE__", line: %d, " \ "server: %s:%d, recv package size " \ INT64_PRINTF_FORMAT" is not correct", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, *in_bytes); *in_bytes = 0; return EINVAL; } return resp.status; }
bool fdfs_is_trunk_file(const char *remote_filename, const int filename_len) { int buff_len; char buff[64]; int64_t file_size; if (filename_len != FDFS_TRUNK_LOGIC_FILENAME_LENGTH) //not trunk file { return false; } memset(buff, 0, sizeof(buff)); base64_decode_auto(&g_fdfs_base64_context, (char *)remote_filename + \ FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \ buff, &buff_len); file_size = buff2long(buff + sizeof(int) * 2); return IS_TRUNK_FILE(file_size); }
int tcprecvfile(int sock, const char *filename, const int64_t file_bytes, \ const int fsync_after_written_bytes, const int timeout, \ int64_t *true_file_bytes) { int write_fd; char buff[FDFS_WRITE_BUFF_SIZE]; int64_t remain_bytes; int recv_bytes; int written_bytes; int result; int flags; int count; tcprecvdata_exfunc recv_func; *true_file_bytes = 0; flags = fcntl(sock, F_GETFL, 0); if (flags < 0) { return errno != 0 ? errno : EACCES; } if (flags & O_NONBLOCK) { recv_func = tcprecvdata_nb_ex; } else { recv_func = tcprecvdata_ex; } write_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (write_fd < 0) { return errno != 0 ? errno : EACCES; } written_bytes = 0; remain_bytes = file_bytes; while (remain_bytes > 0) { if (remain_bytes > sizeof(buff)) { recv_bytes = sizeof(buff); } else { recv_bytes = remain_bytes; } result = recv_func(sock, buff, recv_bytes, \ timeout, &count); if (result != 0) { if (file_bytes != INFINITE_FILE_SIZE) { close(write_fd); unlink(filename); return result; } } if (count > 0 && write(write_fd, buff, count) != count) { result = errno != 0 ? errno: EIO; close(write_fd); unlink(filename); return result; } *true_file_bytes += count; if (fsync_after_written_bytes > 0) { written_bytes += count; if (written_bytes >= fsync_after_written_bytes) { written_bytes = 0; if (fsync(write_fd) != 0) { result = errno != 0 ? errno: EIO; close(write_fd); unlink(filename); return result; } } } if (result != 0) //recv infinite file, does not delete the file { int read_fd; read_fd = -1; do { if (*true_file_bytes < 8) { break; } read_fd = open(filename, O_RDONLY); if (read_fd < 0) { return errno != 0 ? errno : EACCES; } if (lseek(read_fd, -8, SEEK_END) < 0) { result = errno != 0 ? errno : EIO; break; } if (read(read_fd, buff, 8) != 8) { result = errno != 0 ? errno : EIO; break; } *true_file_bytes -= 8; if (buff2long(buff) != *true_file_bytes) { result = EINVAL; break; } if (ftruncate(write_fd, *true_file_bytes) != 0) { result = errno != 0 ? errno : EIO; break; } result = 0; } while (0); close(write_fd); if (read_fd >= 0) { close(read_fd); } if (result != 0) { unlink(filename); } return result; } remain_bytes -= count; } close(write_fd); return 0; }
int trunk_file_do_lstat_func_ex(const FDFSStorePaths *pStorePaths, \ const int store_path_index, const char *true_filename, \ const int filename_len, const int stat_func, \ struct stat *pStat, FDFSTrunkFullInfo *pTrunkInfo, \ FDFSTrunkHeader *pTrunkHeader, int *pfd) { char full_filename[MAX_PATH_SIZE]; char buff[128]; char pack_buff[FDFS_TRUNK_FILE_HEADER_SIZE]; int64_t file_size; int buff_len; int fd; int read_bytes; int result; pTrunkInfo->file.id = 0; if (filename_len != FDFS_TRUNK_FILENAME_LENGTH) //not trunk file { snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \ pStorePaths->paths[store_path_index], true_filename); if (stat_func == FDFS_STAT_FUNC_STAT) { result = stat(full_filename, pStat); } else { result = lstat(full_filename, pStat); } if (result == 0) { return 0; } else { return errno != 0 ? errno : ENOENT; } } memset(buff, 0, sizeof(buff)); base64_decode_auto(&g_fdfs_base64_context, (char *)true_filename + \ FDFS_TRUE_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \ buff, &buff_len); file_size = buff2long(buff + sizeof(int) * 2); if (!IS_TRUNK_FILE(file_size)) //slave file { snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \ pStorePaths->paths[store_path_index], true_filename); if (stat_func == FDFS_STAT_FUNC_STAT) { result = stat(full_filename, pStat); } else { result = lstat(full_filename, pStat); } if (result == 0) { return 0; } else { return errno != 0 ? errno : ENOENT; } } trunk_file_info_decode(true_filename + FDFS_TRUE_FILE_PATH_LEN + \ FDFS_FILENAME_BASE64_LENGTH, &pTrunkInfo->file); pTrunkHeader->file_size = FDFS_TRUNK_FILE_TRUE_SIZE(file_size); pTrunkHeader->mtime = buff2int(buff + sizeof(int)); pTrunkHeader->crc32 = buff2int(buff + sizeof(int) * 4); memcpy(pTrunkHeader->formatted_ext_name, true_filename + \ (filename_len - (FDFS_FILE_EXT_NAME_MAX_LEN + 1)), \ FDFS_FILE_EXT_NAME_MAX_LEN + 2); //include tailing '\0' pTrunkHeader->alloc_size = pTrunkInfo->file.size; pTrunkInfo->path.store_path_index = store_path_index; pTrunkInfo->path.sub_path_high = strtol(true_filename, NULL, 16); pTrunkInfo->path.sub_path_low = strtol(true_filename + 3, NULL, 16); trunk_get_full_filename_ex(pStorePaths, pTrunkInfo, full_filename, \ sizeof(full_filename)); fd = open(full_filename, O_RDONLY); if (fd < 0) { return errno != 0 ? errno : EIO; } if (lseek(fd, pTrunkInfo->file.offset, SEEK_SET) < 0) { result = errno != 0 ? errno : EIO; close(fd); return result; } read_bytes = read(fd, buff, FDFS_TRUNK_FILE_HEADER_SIZE); if (read_bytes == FDFS_TRUNK_FILE_HEADER_SIZE) { result = 0; } else { result = errno; close(fd); return result != 0 ? result : EINVAL; } memset(pStat, 0, sizeof(struct stat)); pTrunkHeader->file_type = *(buff + FDFS_TRUNK_FILE_FILE_TYPE_OFFSET); if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_REGULAR) { pStat->st_mode = S_IFREG; } else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_LINK) { pStat->st_mode = S_IFLNK; } else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_NONE) { close(fd); return ENOENT; } else { close(fd); logError("file: "__FILE__", line: %d, " \ "Invalid file type: %d", __LINE__, \ pTrunkHeader->file_type); return ENOENT; } trunk_pack_header(pTrunkHeader, pack_buff); /* { char temp[265]; char szHexBuff[2 * FDFS_TRUNK_FILE_HEADER_SIZE + 1]; FDFSTrunkHeader trueTrunkHeader; fprintf(stderr, "file: "__FILE__", line: %d, true buff=%s\n", __LINE__, \ bin2hex(buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff)); trunk_unpack_header(buff, &trueTrunkHeader); fprintf(stderr, "file: "__FILE__", line: %d, true fields=%s\n", __LINE__, \ trunk_header_dump(&trueTrunkHeader, full_filename, sizeof(full_filename))); fprintf(stderr, "file: "__FILE__", line: %d, my buff=%s\n", __LINE__, \ bin2hex(pack_buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff)); fprintf(stderr, "file: "__FILE__", line: %d, my trunk=%s, my fields=%s\n", __LINE__, \ trunk_info_dump(pTrunkInfo, temp, sizeof(temp)), \ trunk_header_dump(pTrunkHeader, full_filename, sizeof(full_filename))); } */ if (memcmp(pack_buff, buff, FDFS_TRUNK_FILE_HEADER_SIZE) != 0) { close(fd); return ENOENT; } pStat->st_size = pTrunkHeader->file_size; pStat->st_mtime = pTrunkHeader->mtime; if (pfd != NULL) { *pfd = fd; } else { close(fd); } return 0; }
static void client_sock_read(int sock, short event, void *arg) { int bytes; int recv_bytes; struct fast_task_info *pTask; StorageClientInfo *pClientInfo; pTask = (struct fast_task_info *)arg; pClientInfo = (StorageClientInfo *)pTask->arg; if (pClientInfo->canceled) { return; } if (pClientInfo->stage != FDFS_STORAGE_STAGE_NIO_RECV) { if (event & IOEVENT_TIMEOUT) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } return; } if (event & IOEVENT_TIMEOUT) { if (pClientInfo->total_offset == 0 && pTask->req_count > 0) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv timeout, " \ "recv offset: %d, expect length: %d", \ __LINE__, pTask->client_ip, \ pTask->offset, pTask->length); task_finish_clean_up(pTask); } return; } if (event & IOEVENT_ERROR) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv error event: %d, " "close connection", __LINE__, pTask->client_ip, event); task_finish_clean_up(pTask); return; } fast_timer_modify(&pTask->thread_data->timer, &pTask->event.timer, g_current_time + g_fdfs_network_timeout); while (1) { if (pClientInfo->total_length == 0) //recv header { recv_bytes = sizeof(TrackerHeader) - pTask->offset; } else { recv_bytes = pTask->length - pTask->offset; } /* logInfo("total_length=%"PRId64", recv_bytes=%d, " "pTask->length=%d, pTask->offset=%d", pClientInfo->total_length, recv_bytes, pTask->length, pTask->offset); */ bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { } else if (errno == EINTR) { continue; } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "errno: %d, error info: %s", \ __LINE__, pTask->client_ip, \ errno, STRERROR(errno)); task_finish_clean_up(pTask); } return; } else if (bytes == 0) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "connection disconnected.", \ __LINE__, pTask->client_ip); task_finish_clean_up(pTask); return; } if (pClientInfo->total_length == 0) //header { if (pTask->offset + bytes < sizeof(TrackerHeader)) { pTask->offset += bytes; return; } pClientInfo->total_length=buff2long(((TrackerHeader *) \ pTask->data)->pkg_len); if (pClientInfo->total_length < 0) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: " \ "%"PRId64" < 0", \ __LINE__, pTask->client_ip, \ pClientInfo->total_length); task_finish_clean_up(pTask); return; } pClientInfo->total_length += sizeof(TrackerHeader); if (pClientInfo->total_length > pTask->size) { pTask->length = pTask->size; } else { pTask->length = pClientInfo->total_length; } } pTask->offset += bytes; if (pTask->offset >= pTask->length) //recv current pkg done { if (pClientInfo->total_offset + pTask->length >= \ pClientInfo->total_length) { /* current req recv done */ pClientInfo->stage = FDFS_STORAGE_STAGE_NIO_SEND; pTask->req_count++; } if (pClientInfo->total_offset == 0) { pClientInfo->total_offset = pTask->length; storage_deal_task(pTask); } else { pClientInfo->total_offset += pTask->length; /* continue write to file */ storage_dio_queue_push(pTask); } return; } } return; }
static void client_sock_read(int sock, short event, void *arg) { int bytes; int recv_bytes; struct fast_task_info *pTask; pTask = (struct fast_task_info *)arg; if (event & IOEVENT_TIMEOUT) { if (pTask->offset == 0 && pTask->req_count > 0) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv timeout, " \ "recv offset: %d, expect length: %d", \ __LINE__, pTask->client_ip, \ pTask->offset, pTask->length); task_finish_clean_up(pTask); } return; } if (event & IOEVENT_ERROR) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv error event: %d, " "close connection", __LINE__, pTask->client_ip, event); task_finish_clean_up(pTask); return; } while (1) { fast_timer_modify(&pTask->thread_data->timer, &pTask->event.timer, g_current_time + g_fdfs_network_timeout); if (pTask->length == 0) //recv header { recv_bytes = sizeof(TrackerHeader) - pTask->offset; } else { recv_bytes = pTask->length - pTask->offset; } bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { } else if (errno == EINTR) { continue; } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "errno: %d, error info: %s", \ __LINE__, pTask->client_ip, \ errno, STRERROR(errno)); task_finish_clean_up(pTask); } return; } else if (bytes == 0) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "connection disconnected.", \ __LINE__, pTask->client_ip); task_finish_clean_up(pTask); return; } if (pTask->length == 0) //header { if (pTask->offset + bytes < sizeof(TrackerHeader)) { pTask->offset += bytes; return; } pTask->length = buff2long(((TrackerHeader *) \ pTask->data)->pkg_len); if (pTask->length < 0) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: %d < 0", \ __LINE__, pTask->client_ip, \ pTask->length); task_finish_clean_up(pTask); return; } pTask->length += sizeof(TrackerHeader); if (pTask->length > TRACKER_MAX_PACKAGE_SIZE) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: %d > " \ "max pkg size: %d", __LINE__, \ pTask->client_ip, pTask->length, \ TRACKER_MAX_PACKAGE_SIZE); task_finish_clean_up(pTask); return; } } pTask->offset += bytes; if (pTask->offset >= pTask->length) //recv done { pTask->req_count++; tracker_deal_task(pTask); return; } } return; }
int tracker_query_storage_store_list_with_group( \ ConnectionInfo *pTrackerServer, const char *group_name, \ ConnectionInfo *storageServers, const int nMaxServerCount, \ int *storage_count, int *store_path_index) { ConnectionInfo *pStorageServer; ConnectionInfo *pServerEnd; TrackerHeader *pHeader; ConnectionInfo *conn; bool new_connection; char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN]; char in_buff[sizeof(TrackerHeader) + FDFS_MAX_SERVERS_EACH_GROUP * \ TRACKER_QUERY_STORAGE_STORE_BODY_LEN]; char returned_group_name[FDFS_GROUP_NAME_MAX_LEN + 1]; char *pInBuff; char *p; int64_t in_bytes; int out_len; int ipPortsLen; int result; *storage_count = 0; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); pHeader = (TrackerHeader *)out_buff; memset(out_buff, 0, sizeof(out_buff)); if (group_name == NULL || *group_name == '\0') { pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ALL; out_len = 0; } else { pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ALL; snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \ sizeof(TrackerHeader), "%s", group_name); out_len = FDFS_GROUP_NAME_MAX_LEN; } long2buff(out_len, pHeader->pkg_len); if ((result=tcpsenddata_nb(conn->sock, out_buff, \ sizeof(TrackerHeader) + out_len, g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = in_buff; result = fdfs_recv_response(conn, \ &pInBuff, sizeof(in_buff), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { return result; } if (in_bytes < TRACKER_QUERY_STORAGE_STORE_BODY_LEN) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid, " \ "expect length >= %d", __LINE__, \ pTrackerServer->ip_addr, pTrackerServer->port, \ in_bytes, TRACKER_QUERY_STORAGE_STORE_BODY_LEN); return EINVAL; } #define RECORD_LENGTH (IP_ADDRESS_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE) ipPortsLen = in_bytes - (FDFS_GROUP_NAME_MAX_LEN + 1); if (ipPortsLen % RECORD_LENGTH != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, in_bytes); return EINVAL; } *storage_count = ipPortsLen / RECORD_LENGTH; if (nMaxServerCount < *storage_count) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response storage server " \ "count: %d, exceeds max server count: %d!", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, *storage_count, nMaxServerCount); return ENOSPC; } memset(storageServers, 0, sizeof(ConnectionInfo) * nMaxServerCount); memcpy(returned_group_name, in_buff, FDFS_GROUP_NAME_MAX_LEN); p = in_buff + FDFS_GROUP_NAME_MAX_LEN; *(returned_group_name + FDFS_GROUP_NAME_MAX_LEN) = '\0'; pServerEnd = storageServers + (*storage_count); for (pStorageServer=storageServers; pStorageServer<pServerEnd; \ pStorageServer++) { pStorageServer->sock = -1; memcpy(pStorageServer->ip_addr, p, IP_ADDRESS_SIZE - 1); p += IP_ADDRESS_SIZE - 1; pStorageServer->port = (int)buff2long(p); p += FDFS_PROTO_PKG_LEN_SIZE; } *store_path_index = *p; return 0; }
int tracker_query_storage_store_with_group(ConnectionInfo *pTrackerServer, \ const char *group_name, ConnectionInfo *pStorageServer, \ int *store_path_index) { TrackerHeader *pHeader; ConnectionInfo *conn; bool new_connection; char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN]; char in_buff[sizeof(TrackerHeader) + \ TRACKER_QUERY_STORAGE_STORE_BODY_LEN]; char *pInBuff; int64_t in_bytes; int result; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); memset(pStorageServer, 0, sizeof(ConnectionInfo)); pStorageServer->sock = -1; pHeader = (TrackerHeader *)out_buff; memset(out_buff, 0, sizeof(out_buff)); snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \ sizeof(TrackerHeader), "%s", group_name); long2buff(FDFS_GROUP_NAME_MAX_LEN, pHeader->pkg_len); pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE; if ((result=tcpsenddata_nb(conn->sock, out_buff, \ sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, \ g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = in_buff; result = fdfs_recv_response(conn, \ &pInBuff, sizeof(in_buff), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { return result; } if (in_bytes != TRACKER_QUERY_STORAGE_STORE_BODY_LEN) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid, " \ "expect length: %d", __LINE__, \ pTrackerServer->ip_addr, pTrackerServer->port, \ in_bytes, TRACKER_QUERY_STORAGE_STORE_BODY_LEN); return EINVAL; } memcpy(pStorageServer->ip_addr, in_buff + \ FDFS_GROUP_NAME_MAX_LEN, IP_ADDRESS_SIZE-1); pStorageServer->port = (int)buff2long(in_buff + \ FDFS_GROUP_NAME_MAX_LEN + IP_ADDRESS_SIZE - 1); *store_path_index = *(in_buff + FDFS_GROUP_NAME_MAX_LEN + \ IP_ADDRESS_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE); return 0; }
int tracker_query_storage_list(ConnectionInfo *pTrackerServer, \ ConnectionInfo *pStorageServer, const int nMaxServerCount, \ int *server_count, char *group_name, const char *filename) { TrackerHeader *pHeader; ConnectionInfo *pServer; ConnectionInfo *pServerEnd; ConnectionInfo *conn; bool new_connection; char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + 128]; char in_buff[sizeof(TrackerHeader) + \ TRACKER_QUERY_STORAGE_FETCH_BODY_LEN + \ FDFS_MAX_SERVERS_EACH_GROUP * IP_ADDRESS_SIZE]; char *pInBuff; int64_t in_bytes; int result; int filename_len; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); memset(out_buff, 0, sizeof(out_buff)); pHeader = (TrackerHeader *)out_buff; snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \ sizeof(TrackerHeader), "%s", group_name); filename_len = snprintf(out_buff + sizeof(TrackerHeader) + \ FDFS_GROUP_NAME_MAX_LEN, \ sizeof(out_buff) - sizeof(TrackerHeader) - \ FDFS_GROUP_NAME_MAX_LEN, "%s", filename); long2buff(FDFS_GROUP_NAME_MAX_LEN + filename_len, pHeader->pkg_len); pHeader->cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL; if ((result=tcpsenddata_nb(conn->sock, out_buff, \ sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + filename_len, g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = in_buff; result = fdfs_recv_response(conn, \ &pInBuff, sizeof(in_buff), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { return result; } if ((in_bytes - TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) % \ (IP_ADDRESS_SIZE - 1) != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, in_bytes); return EINVAL; } *server_count = 1 + (in_bytes - TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) / (IP_ADDRESS_SIZE - 1); if (nMaxServerCount < *server_count) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response storage server " \ "count: %d, exceeds max server count: %d!", __LINE__, \ pTrackerServer->ip_addr, pTrackerServer->port, \ *server_count, nMaxServerCount); return ENOSPC; } memset(pStorageServer, 0, nMaxServerCount * sizeof(ConnectionInfo)); pStorageServer->sock = -1; memcpy(group_name, pInBuff, FDFS_GROUP_NAME_MAX_LEN); *(group_name + FDFS_GROUP_NAME_MAX_LEN) = '\0'; pInBuff += FDFS_GROUP_NAME_MAX_LEN; memcpy(pStorageServer->ip_addr, pInBuff, IP_ADDRESS_SIZE - 1); pInBuff += IP_ADDRESS_SIZE - 1; pStorageServer->port = (int)buff2long(pInBuff); pInBuff += FDFS_PROTO_PKG_LEN_SIZE; pServerEnd = pStorageServer + (*server_count); for (pServer=pStorageServer+1; pServer<pServerEnd; pServer++) { pServer->sock = -1; pServer->port = pStorageServer->port; memcpy(pServer->ip_addr, pInBuff, IP_ADDRESS_SIZE - 1); pInBuff += IP_ADDRESS_SIZE - 1; } return 0; }
int tracker_list_groups(ConnectionInfo *pTrackerServer, \ FDFSGroupStat *group_stats, const int max_groups, \ int *group_count) { bool new_connection; TrackerHeader header; TrackerGroupStat stats[FDFS_MAX_GROUPS]; char *pInBuff; ConnectionInfo *conn; TrackerGroupStat *pSrc; TrackerGroupStat *pEnd; FDFSGroupStat *pDest; int result; int64_t in_bytes; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); memset(&header, 0, sizeof(header)); header.cmd = TRACKER_PROTO_CMD_SERVER_LIST_ALL_GROUPS; header.status = 0; if ((result=tcpsenddata_nb(conn->sock, &header, \ sizeof(header), g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = (char *)stats; result = fdfs_recv_response(conn, \ &pInBuff, sizeof(stats), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { *group_count = 0; return result; } if (in_bytes % sizeof(TrackerGroupStat) != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, in_bytes); *group_count = 0; return EINVAL; } *group_count = in_bytes / sizeof(TrackerGroupStat); if (*group_count > max_groups) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d insufficent space, " \ "max group count: %d, expect count: %d", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, max_groups, *group_count); *group_count = 0; return ENOSPC; } memset(group_stats, 0, sizeof(FDFSGroupStat) * max_groups); pDest = group_stats; pEnd = stats + (*group_count); for (pSrc=stats; pSrc<pEnd; pSrc++) { memcpy(pDest->group_name, pSrc->group_name, \ FDFS_GROUP_NAME_MAX_LEN); pDest->total_mb = buff2long(pSrc->sz_total_mb); pDest->free_mb = buff2long(pSrc->sz_free_mb); pDest->trunk_free_mb = buff2long(pSrc->sz_trunk_free_mb); pDest->count= buff2long(pSrc->sz_count); pDest->storage_port= buff2long(pSrc->sz_storage_port); pDest->storage_http_port= buff2long(pSrc->sz_storage_http_port); pDest->active_count = buff2long(pSrc->sz_active_count); pDest->current_write_server = buff2long( \ pSrc->sz_current_write_server); pDest->store_path_count = buff2long( \ pSrc->sz_store_path_count); pDest->subdir_count_per_path = buff2long( \ pSrc->sz_subdir_count_per_path); pDest->current_trunk_file_id = buff2long( \ pSrc->sz_current_trunk_file_id); pDest++; } return 0; }
int tracker_list_one_group(ConnectionInfo *pTrackerServer, \ const char *group_name, FDFSGroupStat *pDest) { TrackerHeader *pHeader; ConnectionInfo *conn; bool new_connection; char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN]; TrackerGroupStat src; char *pInBuff; int result; int64_t in_bytes; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); memset(out_buff, 0, sizeof(out_buff)); pHeader = (TrackerHeader *)out_buff; snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - \ sizeof(TrackerHeader), "%s", group_name); pHeader->cmd = TRACKER_PROTO_CMD_SERVER_LIST_ONE_GROUP; long2buff(FDFS_GROUP_NAME_MAX_LEN, pHeader->pkg_len); if ((result=tcpsenddata_nb(conn->sock, out_buff, \ sizeof(out_buff), g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = (char *)&src; result = fdfs_recv_response(conn, \ &pInBuff, sizeof(TrackerGroupStat), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { return result; } if (in_bytes != sizeof(TrackerGroupStat)) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, in_bytes); return EINVAL; } memset(pDest, 0, sizeof(FDFSGroupStat)); memcpy(pDest->group_name, src.group_name, FDFS_GROUP_NAME_MAX_LEN); pDest->total_mb = buff2long(src.sz_total_mb); pDest->free_mb = buff2long(src.sz_free_mb); pDest->trunk_free_mb = buff2long(src.sz_trunk_free_mb); pDest->count= buff2long(src.sz_count); pDest->storage_port= buff2long(src.sz_storage_port); pDest->storage_http_port= buff2long(src.sz_storage_http_port); pDest->active_count = buff2long(src.sz_active_count); pDest->current_write_server = buff2long(src.sz_current_write_server); pDest->store_path_count = buff2long(src.sz_store_path_count); pDest->subdir_count_per_path = buff2long(src.sz_subdir_count_per_path); pDest->current_trunk_file_id = buff2long(src.sz_current_trunk_file_id); return 0; }
int tracker_list_servers(ConnectionInfo *pTrackerServer, \ const char *szGroupName, const char *szStorageId, \ FDFSStorageInfo *storage_infos, const int max_storages, \ int *storage_count) { char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + \ IP_ADDRESS_SIZE]; bool new_connection; TrackerHeader *pHeader; ConnectionInfo *conn; int result; int name_len; int id_len; TrackerStorageStat stats[FDFS_MAX_GROUPS]; char *pInBuff; TrackerStorageStat *pSrc; TrackerStorageStat *pEnd; FDFSStorageStat *pStorageStat; FDFSStorageInfo *pDest; FDFSStorageStatBuff *pStatBuff; int64_t in_bytes; CHECK_CONNECTION(pTrackerServer, conn, result, new_connection); memset(out_buff, 0, sizeof(out_buff)); pHeader = (TrackerHeader *)out_buff; name_len = strlen(szGroupName); if (name_len > FDFS_GROUP_NAME_MAX_LEN) { name_len = FDFS_GROUP_NAME_MAX_LEN; } memcpy(out_buff + sizeof(TrackerHeader), szGroupName, name_len); if (szStorageId == NULL) { id_len = 0; } else { id_len = strlen(szStorageId); if (id_len >= FDFS_STORAGE_ID_MAX_SIZE) { id_len = FDFS_STORAGE_ID_MAX_SIZE - 1; } memcpy(out_buff+sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN,\ szStorageId, id_len); } long2buff(FDFS_GROUP_NAME_MAX_LEN + id_len, pHeader->pkg_len); pHeader->cmd = TRACKER_PROTO_CMD_SERVER_LIST_STORAGE; if ((result=tcpsenddata_nb(conn->sock, out_buff, \ sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + id_len, \ g_fdfs_network_timeout)) != 0) { logError("file: "__FILE__", line: %d, " \ "send data to tracker server %s:%d fail, " \ "errno: %d, error info: %s", __LINE__, \ pTrackerServer->ip_addr, \ pTrackerServer->port, \ result, STRERROR(result)); } else { pInBuff = (char *)stats; result = fdfs_recv_response(conn, &pInBuff, \ sizeof(stats), &in_bytes); } if (new_connection) { tracker_disconnect_server_ex(conn, result != 0); } if (result != 0) { *storage_count = 0; return result; } if (in_bytes % sizeof(TrackerStorageStat) != 0) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d response data " \ "length: %"PRId64" is invalid", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, in_bytes); *storage_count = 0; return EINVAL; } *storage_count = in_bytes / sizeof(TrackerStorageStat); if (*storage_count > max_storages) { logError("file: "__FILE__", line: %d, " \ "tracker server %s:%d insufficent space, " \ "max storage count: %d, expect count: %d", \ __LINE__, pTrackerServer->ip_addr, \ pTrackerServer->port, max_storages, *storage_count); *storage_count = 0; return ENOSPC; } memset(storage_infos, 0, sizeof(FDFSStorageInfo) * max_storages); pDest = storage_infos; pEnd = stats + (*storage_count); for (pSrc=stats; pSrc<pEnd; pSrc++) { pStatBuff = &(pSrc->stat_buff); pStorageStat = &(pDest->stat); pDest->status = pSrc->status; memcpy(pDest->id, pSrc->id, FDFS_STORAGE_ID_MAX_SIZE - 1); memcpy(pDest->ip_addr, pSrc->ip_addr, IP_ADDRESS_SIZE - 1); memcpy(pDest->src_id, pSrc->src_id, \ FDFS_STORAGE_ID_MAX_SIZE - 1); strcpy(pDest->domain_name, pSrc->domain_name); strcpy(pDest->version, pSrc->version); pDest->join_time = buff2long(pSrc->sz_join_time); pDest->up_time = buff2long(pSrc->sz_up_time); pDest->total_mb = buff2long(pSrc->sz_total_mb); pDest->free_mb = buff2long(pSrc->sz_free_mb); pDest->upload_priority = buff2long(pSrc->sz_upload_priority); pDest->store_path_count = buff2long(pSrc->sz_store_path_count); pDest->subdir_count_per_path = buff2long( \ pSrc->sz_subdir_count_per_path); pDest->storage_port = buff2long(pSrc->sz_storage_port); pDest->storage_http_port = buff2long(pSrc->sz_storage_http_port); pDest->current_write_path = buff2long( \ pSrc->sz_current_write_path); pStorageStat->total_upload_count = buff2long( \ pStatBuff->sz_total_upload_count); pStorageStat->success_upload_count = buff2long( \ pStatBuff->sz_success_upload_count); pStorageStat->total_append_count = buff2long( \ pStatBuff->sz_total_append_count); pStorageStat->success_append_count = buff2long( \ pStatBuff->sz_success_append_count); pStorageStat->total_modify_count = buff2long( \ pStatBuff->sz_total_modify_count); pStorageStat->success_modify_count = buff2long( \ pStatBuff->sz_success_modify_count); pStorageStat->total_truncate_count = buff2long( \ pStatBuff->sz_total_truncate_count); pStorageStat->success_truncate_count = buff2long( \ pStatBuff->sz_success_truncate_count); pStorageStat->total_set_meta_count = buff2long( \ pStatBuff->sz_total_set_meta_count); pStorageStat->success_set_meta_count = buff2long( \ pStatBuff->sz_success_set_meta_count); pStorageStat->total_delete_count = buff2long( \ pStatBuff->sz_total_delete_count); pStorageStat->success_delete_count = buff2long( \ pStatBuff->sz_success_delete_count); pStorageStat->total_download_count = buff2long( \ pStatBuff->sz_total_download_count); pStorageStat->success_download_count = buff2long( \ pStatBuff->sz_success_download_count); pStorageStat->total_get_meta_count = buff2long( \ pStatBuff->sz_total_get_meta_count); pStorageStat->success_get_meta_count = buff2long( \ pStatBuff->sz_success_get_meta_count); pStorageStat->last_source_update = buff2long( \ pStatBuff->sz_last_source_update); pStorageStat->last_sync_update = buff2long( \ pStatBuff->sz_last_sync_update); pStorageStat->last_synced_timestamp = buff2long( \ pStatBuff->sz_last_synced_timestamp); pStorageStat->total_create_link_count = buff2long( \ pStatBuff->sz_total_create_link_count); pStorageStat->success_create_link_count = buff2long( \ pStatBuff->sz_success_create_link_count); pStorageStat->total_delete_link_count = buff2long( \ pStatBuff->sz_total_delete_link_count); pStorageStat->success_delete_link_count = buff2long( \ pStatBuff->sz_success_delete_link_count); pStorageStat->total_upload_bytes = buff2long( \ pStatBuff->sz_total_upload_bytes); pStorageStat->success_upload_bytes = buff2long( \ pStatBuff->sz_success_upload_bytes); pStorageStat->total_append_bytes = buff2long( \ pStatBuff->sz_total_append_bytes); pStorageStat->success_append_bytes = buff2long( \ pStatBuff->sz_success_append_bytes); pStorageStat->total_modify_bytes = buff2long( \ pStatBuff->sz_total_modify_bytes); pStorageStat->success_modify_bytes = buff2long( \ pStatBuff->sz_success_modify_bytes); pStorageStat->total_download_bytes = buff2long( \ pStatBuff->sz_total_download_bytes); pStorageStat->success_download_bytes = buff2long( \ pStatBuff->sz_success_download_bytes); pStorageStat->total_sync_in_bytes = buff2long( \ pStatBuff->sz_total_sync_in_bytes); pStorageStat->success_sync_in_bytes = buff2long( \ pStatBuff->sz_success_sync_in_bytes); pStorageStat->total_sync_out_bytes = buff2long( \ pStatBuff->sz_total_sync_out_bytes); pStorageStat->success_sync_out_bytes = buff2long( \ pStatBuff->sz_success_sync_out_bytes); pStorageStat->total_file_open_count = buff2long( \ pStatBuff->sz_total_file_open_count); pStorageStat->success_file_open_count = buff2long( \ pStatBuff->sz_success_file_open_count); pStorageStat->total_file_read_count = buff2long( \ pStatBuff->sz_total_file_read_count); pStorageStat->success_file_read_count = buff2long( \ pStatBuff->sz_success_file_read_count); pStorageStat->total_file_write_count = buff2long( \ pStatBuff->sz_total_file_write_count); pStorageStat->success_file_write_count = buff2long( \ pStatBuff->sz_success_file_write_count); pStorageStat->last_heart_beat_time = buff2long( \ pStatBuff->sz_last_heart_beat_time); pDest->if_trunk_server = pSrc->if_trunk_server; pDest++; } return 0; }