2644 lines
67 KiB
C
Executable File
2644 lines
67 KiB
C
Executable File
/**
|
|
* 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 <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#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 "client_func.h"
|
|
#include "tracker_client.h"
|
|
#include "storage_client.h"
|
|
#include "storage_client1.h"
|
|
#include "client_global.h"
|
|
#include "fastcommon/base64.h"
|
|
|
|
static struct base64_context the_base64_context;
|
|
static int the_base64_context_inited = 0;
|
|
|
|
#define FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id) \
|
|
char in_file_id[FDFS_GROUP_NAME_MAX_LEN + 128]; \
|
|
char *group_name; \
|
|
char *filename; \
|
|
char *pSeperator; \
|
|
\
|
|
snprintf(in_file_id, sizeof(in_file_id), "%s", file_id); \
|
|
pSeperator = strchr(in_file_id, FDFS_FILE_ID_SEPERATOR); \
|
|
if (pSeperator == NULL) \
|
|
{ \
|
|
return EINVAL; \
|
|
} \
|
|
\
|
|
*pSeperator = '\0'; \
|
|
group_name = in_file_id; \
|
|
filename = pSeperator + 1; \
|
|
|
|
#define storage_get_read_connection(pTrackerServer, \
|
|
ppStorageServer, group_name, filename, \
|
|
pNewStorage, new_connection) \
|
|
storage_get_connection(pTrackerServer, \
|
|
ppStorageServer, TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE, \
|
|
group_name, filename, pNewStorage, new_connection)
|
|
|
|
#define storage_get_update_connection(pTrackerServer, \
|
|
ppStorageServer, group_name, filename, \
|
|
pNewStorage, new_connection) \
|
|
storage_get_connection(pTrackerServer, \
|
|
ppStorageServer, TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE, \
|
|
group_name, filename, pNewStorage, new_connection)
|
|
|
|
static int storage_get_connection(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo **ppStorageServer, const byte cmd, \
|
|
const char *group_name, const char *filename, \
|
|
ConnectionInfo *pNewStorage, bool *new_connection)
|
|
{
|
|
int result;
|
|
bool new_tracker_connection;
|
|
ConnectionInfo *pNewTracker;
|
|
if (*ppStorageServer == NULL)
|
|
{
|
|
CHECK_CONNECTION(pTrackerServer, pNewTracker, result, \
|
|
new_tracker_connection);
|
|
if (cmd == TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE)
|
|
{
|
|
result = tracker_query_storage_fetch(pNewTracker, \
|
|
pNewStorage, group_name, filename);
|
|
}
|
|
else
|
|
{
|
|
result = tracker_query_storage_update(pNewTracker, \
|
|
pNewStorage, group_name, filename);
|
|
}
|
|
|
|
if (new_tracker_connection)
|
|
{
|
|
tracker_close_connection_ex(pNewTracker, result != 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if ((*ppStorageServer=tracker_make_connection(pNewStorage,
|
|
&result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
*new_connection = true;
|
|
}
|
|
else
|
|
{
|
|
if ((*ppStorageServer)->sock >= 0)
|
|
{
|
|
*new_connection = false;
|
|
}
|
|
else
|
|
{
|
|
if ((*ppStorageServer=tracker_make_connection(
|
|
*ppStorageServer, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
*new_connection = true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int storage_get_upload_connection(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo **ppStorageServer, char *group_name, \
|
|
ConnectionInfo *pNewStorage, int *store_path_index, \
|
|
bool *new_connection)
|
|
{
|
|
int result;
|
|
bool new_tracker_connection;
|
|
ConnectionInfo *pNewTracker;
|
|
|
|
if (*ppStorageServer == NULL)
|
|
{
|
|
CHECK_CONNECTION(pTrackerServer, pNewTracker, result, \
|
|
new_tracker_connection);
|
|
if (*group_name == '\0')
|
|
{
|
|
result = tracker_query_storage_store_without_group( \
|
|
pNewTracker, pNewStorage, group_name, \
|
|
store_path_index);
|
|
}
|
|
else
|
|
{
|
|
result = tracker_query_storage_store_with_group( \
|
|
pNewTracker, group_name, pNewStorage, \
|
|
store_path_index);
|
|
}
|
|
|
|
if (new_tracker_connection)
|
|
{
|
|
tracker_close_connection_ex(pNewTracker, result != 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if ((*ppStorageServer=tracker_make_connection(pNewStorage,
|
|
&result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
*new_connection = true;
|
|
}
|
|
else
|
|
{
|
|
if ((*ppStorageServer)->sock >= 0)
|
|
{
|
|
*new_connection = false;
|
|
}
|
|
else
|
|
{
|
|
if ((*ppStorageServer=tracker_make_connection(
|
|
*ppStorageServer, &result)) == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
*new_connection = true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int storage_get_metadata1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id, \
|
|
FDFSMetaData **meta_list, int *meta_count)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_get_metadata(pTrackerServer, pStorageServer, \
|
|
group_name, filename, meta_list, meta_count);
|
|
}
|
|
|
|
int storage_get_metadata(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *filename, \
|
|
FDFSMetaData **meta_list, \
|
|
int *meta_count)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
ConnectionInfo storageServer;
|
|
char out_buff[sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN+128];
|
|
int64_t in_bytes;
|
|
int filename_len;
|
|
char *file_buff;
|
|
int64_t file_size;
|
|
bool new_connection;
|
|
|
|
file_buff = NULL;
|
|
*meta_list = NULL;
|
|
*meta_count = 0;
|
|
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
/**
|
|
send pkg format:
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
remain bytes: filename
|
|
**/
|
|
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
memset(out_buff, 0, sizeof(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 = STORAGE_PROTO_CMD_GET_METADATA;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->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 storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
|
|
break;
|
|
}
|
|
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
&file_buff, 0, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
file_size = in_bytes;
|
|
if (file_size == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
file_buff[in_bytes] = '\0';
|
|
*meta_list = fdfs_split_metadata(file_buff, meta_count, &result);
|
|
} while (0);
|
|
|
|
if (file_buff != NULL)
|
|
{
|
|
free(file_buff);
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_query_file_info_ex1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_id, \
|
|
FDFSFileInfo *pFileInfo, const bool bSilence)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
return storage_query_file_info_ex(pTrackerServer, pStorageServer, \
|
|
group_name, filename, pFileInfo, bSilence);
|
|
}
|
|
|
|
int storage_query_file_info_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *filename, \
|
|
FDFSFileInfo *pFileInfo, const bool bSilence)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
ConnectionInfo storageServer;
|
|
char out_buff[sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN+128];
|
|
char in_buff[3 * FDFS_PROTO_PKG_LEN_SIZE + IP_ADDRESS_SIZE];
|
|
char buff[64];
|
|
int64_t in_bytes;
|
|
int filename_len;
|
|
int buff_len;
|
|
char *pInBuff;
|
|
char *p;
|
|
bool new_connection;
|
|
|
|
if ((result=storage_get_read_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
/**
|
|
send pkg format:
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
remain bytes: filename
|
|
**/
|
|
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
memset(out_buff, 0, sizeof(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 = STORAGE_PROTO_CMD_QUERY_FILE_INFO;
|
|
pHeader->status = bSilence ? ENOENT : 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->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 storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
|
|
break;
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
&pInBuff, sizeof(in_buff), &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes != sizeof(in_buff))
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"recv data from storage server %s:%d fail, " \
|
|
"recv bytes: %"PRId64" != %d", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
in_bytes, (int)sizeof(in_buff));
|
|
result = EINVAL;
|
|
}
|
|
|
|
if (!the_base64_context_inited)
|
|
{
|
|
the_base64_context_inited = 1;
|
|
base64_init_ex(&the_base64_context, 0, '-', '_', '.');
|
|
}
|
|
|
|
memset(buff, 0, sizeof(buff));
|
|
if (filename_len >= FDFS_LOGIC_FILE_PATH_LEN \
|
|
+ FDFS_FILENAME_BASE64_LENGTH + FDFS_FILE_EXT_NAME_MAX_LEN + 1)
|
|
{
|
|
base64_decode_auto(&the_base64_context, (char *)filename + \
|
|
FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
|
|
buff, &buff_len);
|
|
}
|
|
|
|
p = in_buff;
|
|
pFileInfo->file_size = buff2long(p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
pFileInfo->create_timestamp = buff2long(p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
pFileInfo->crc32 = buff2long(p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
memcpy(pFileInfo->source_ip_addr, p, IP_ADDRESS_SIZE);
|
|
*(pFileInfo->source_ip_addr + IP_ADDRESS_SIZE - 1) = '\0';
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_delete_file1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_delete_file(pTrackerServer, \
|
|
pStorageServer, group_name, filename);
|
|
}
|
|
|
|
int storage_truncate_file1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer,
|
|
const char *appender_file_id, \
|
|
const int64_t truncated_file_size)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_truncate_file(pTrackerServer, \
|
|
pStorageServer, group_name, filename, \
|
|
truncated_file_size);
|
|
}
|
|
|
|
int storage_delete_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
ConnectionInfo storageServer;
|
|
char out_buff[sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN+128];
|
|
char in_buff[1];
|
|
char *pBuff;
|
|
int64_t in_bytes;
|
|
int filename_len;
|
|
bool new_connection;
|
|
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
/**
|
|
send pkg format:
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
remain bytes: filename
|
|
**/
|
|
|
|
memset(out_buff, 0, sizeof(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);
|
|
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
long2buff(FDFS_GROUP_NAME_MAX_LEN + filename_len, pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_DELETE_FILE;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->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 storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
pBuff = in_buff;
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
&pBuff, 0, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_do_download_file1_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const int download_type, const char *file_id, \
|
|
const int64_t file_offset, const int64_t download_bytes, \
|
|
char **file_buff, void *arg, int64_t *file_size)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_do_download_file_ex(pTrackerServer, pStorageServer, \
|
|
download_type, group_name, filename, \
|
|
file_offset, download_bytes, file_buff, arg, file_size);
|
|
}
|
|
|
|
int storage_do_download_file_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const int download_type, \
|
|
const char *group_name, const char *remote_filename, \
|
|
const int64_t file_offset, const int64_t download_bytes, \
|
|
char **file_buff, void *arg, int64_t *file_size)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
ConnectionInfo storageServer;
|
|
char out_buff[sizeof(TrackerHeader)+FDFS_GROUP_NAME_MAX_LEN+128];
|
|
char *p;
|
|
int out_bytes;
|
|
int64_t in_bytes;
|
|
int64_t total_recv_bytes;
|
|
int filename_len;
|
|
bool new_connection;
|
|
|
|
*file_size = 0;
|
|
if ((result=storage_get_read_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, remote_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
/**
|
|
send pkg format:
|
|
8 bytes: file offset
|
|
8 bytes: download file bytes
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
remain bytes: filename
|
|
**/
|
|
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
long2buff(file_offset, p);
|
|
p += 8;
|
|
long2buff(download_bytes, p);
|
|
p += 8;
|
|
snprintf(p, sizeof(out_buff) - (p - out_buff), "%s", group_name);
|
|
p += FDFS_GROUP_NAME_MAX_LEN;
|
|
filename_len = snprintf(p, sizeof(out_buff) - (p - out_buff), \
|
|
"%s", remote_filename);
|
|
p += filename_len;
|
|
out_bytes = p - out_buff;
|
|
long2buff(out_bytes - sizeof(TrackerHeader), pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_DOWNLOAD_FILE;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
out_bytes, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
if (download_type == FDFS_DOWNLOAD_TO_FILE)
|
|
{
|
|
if ((result=fdfs_recv_header(pStorageServer, \
|
|
&in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_header fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if ((result=tcprecvfile(pStorageServer->sock, \
|
|
*file_buff, in_bytes, 0, \
|
|
g_fdfs_network_timeout, \
|
|
&total_recv_bytes)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if (download_type == FDFS_DOWNLOAD_TO_BUFF)
|
|
{
|
|
*file_buff = NULL;
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
file_buff, 0, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DownloadCallback callback;
|
|
char buff[2048];
|
|
int recv_bytes;
|
|
int64_t remain_bytes;
|
|
|
|
if ((result=fdfs_recv_header(pStorageServer, \
|
|
&in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_header fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
callback = (DownloadCallback)*file_buff;
|
|
remain_bytes = in_bytes;
|
|
while (remain_bytes > 0)
|
|
{
|
|
if (remain_bytes > sizeof(buff))
|
|
{
|
|
recv_bytes = sizeof(buff);
|
|
}
|
|
else
|
|
{
|
|
recv_bytes = remain_bytes;
|
|
}
|
|
|
|
if ((result=tcprecvdata_nb(pStorageServer->sock, buff, \
|
|
recv_bytes, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"recv data from storage server " \
|
|
"%s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, \
|
|
pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
result = callback(arg, in_bytes, buff, recv_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"call callback function fail, " \
|
|
"error code: %d", __LINE__, result);
|
|
break;
|
|
}
|
|
|
|
remain_bytes -= recv_bytes;
|
|
}
|
|
|
|
if (remain_bytes != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
*file_size = in_bytes;
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_download_file_to_file1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id, \
|
|
const char *local_filename, int64_t *file_size)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_download_file_to_file(pTrackerServer, \
|
|
pStorageServer, group_name, filename, \
|
|
local_filename, file_size);
|
|
}
|
|
|
|
int storage_download_file_to_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *remote_filename, \
|
|
const char *local_filename, int64_t *file_size)
|
|
{
|
|
char *pLocalFilename;
|
|
pLocalFilename = (char *)local_filename;
|
|
return storage_do_download_file(pTrackerServer, pStorageServer, \
|
|
FDFS_DOWNLOAD_TO_FILE, group_name, remote_filename, \
|
|
&pLocalFilename, NULL, file_size);
|
|
}
|
|
|
|
int storage_upload_by_filename1_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, const char *local_filename, \
|
|
const char *file_ext_name, const FDFSMetaData *meta_list, \
|
|
const int meta_count, const char *group_name, char *file_id)
|
|
{
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
int result;
|
|
|
|
if (group_name == NULL)
|
|
{
|
|
*new_group_name = '\0';
|
|
}
|
|
else
|
|
{
|
|
snprintf(new_group_name, sizeof(new_group_name), \
|
|
"%s", group_name);
|
|
}
|
|
|
|
result = storage_upload_by_filename_ex(pTrackerServer, \
|
|
pStorageServer, store_path_index, cmd, \
|
|
local_filename, file_ext_name, \
|
|
meta_list, meta_count, \
|
|
new_group_name, remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
file_id[0] = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_do_upload_file1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, const int upload_type, \
|
|
const char *file_buff, void *arg, const int64_t file_size, \
|
|
const char *file_ext_name, const FDFSMetaData *meta_list, \
|
|
const int meta_count, const char *group_name, char *file_id)
|
|
{
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
int result;
|
|
|
|
if (group_name == NULL)
|
|
{
|
|
*new_group_name = '\0';
|
|
}
|
|
else
|
|
{
|
|
snprintf(new_group_name, sizeof(new_group_name), \
|
|
"%s", group_name);
|
|
}
|
|
|
|
result = storage_do_upload_file(pTrackerServer, \
|
|
pStorageServer, store_path_index, cmd, upload_type, \
|
|
file_buff, arg, file_size, NULL, NULL, file_ext_name, \
|
|
meta_list, meta_count, new_group_name, remote_filename);//上传文件并得到new_group_name和remote_filename
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
file_id[0] = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
STORAGE_PROTO_CMD_UPLOAD_FILE and
|
|
STORAGE_PROTO_CMD_UPLOAD_APPENDER_FILE:
|
|
1 byte: store path index
|
|
8 bytes: meta data bytes
|
|
8 bytes: file size
|
|
FDFS_FILE_EXT_NAME_MAX_LEN bytes: file ext name
|
|
meta data bytes: each meta data seperated by \x01,
|
|
name and value seperated by \x02
|
|
file size bytes: file content
|
|
|
|
STORAGE_PROTO_CMD_UPLOAD_SLAVE_FILE:
|
|
8 bytes: master filename length
|
|
8 bytes: meta data bytes
|
|
8 bytes: file size
|
|
FDFS_FILE_PREFIX_MAX_LEN bytes : filename prefix
|
|
FDFS_FILE_EXT_NAME_MAX_LEN bytes: file ext name, do not include dot (.)
|
|
master filename bytes: master filename
|
|
meta data bytes: each meta data seperated by \x01,
|
|
name and value seperated by \x02
|
|
file size bytes: file content
|
|
**/
|
|
int storage_do_upload_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, const int upload_type, const char *file_buff, \
|
|
void *arg, const int64_t file_size, const char *master_filename, \
|
|
const char *prefix_name, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *group_name, char *remote_filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[512];
|
|
char *p;
|
|
int64_t in_bytes;
|
|
int64_t total_send_bytes;
|
|
char in_buff[128];
|
|
char *pInBuff;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
bool bUploadSlave;
|
|
int new_store_path;
|
|
int master_filename_len;
|
|
int prefix_len;
|
|
|
|
*remote_filename = '\0';
|
|
new_store_path = store_path_index;
|
|
if (master_filename != NULL)
|
|
{
|
|
master_filename_len = strlen(master_filename);
|
|
}
|
|
else
|
|
{
|
|
master_filename_len = 0;
|
|
}
|
|
|
|
if (prefix_name != NULL)
|
|
{
|
|
prefix_len = strlen(prefix_name);
|
|
}
|
|
else
|
|
{
|
|
prefix_len = 0;
|
|
}
|
|
|
|
bUploadSlave = (strlen(group_name) > 0 && master_filename_len > 0);//false
|
|
if (bUploadSlave)
|
|
{
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, master_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
else if ((result=storage_get_upload_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, &storageServer, \
|
|
&new_store_path, &new_connection)) != 0)
|
|
{
|
|
*group_name = '\0';
|
|
return result;
|
|
}
|
|
|
|
*group_name = '\0';
|
|
|
|
/*
|
|
//logInfo("upload to storage %s:%d\n", \
|
|
pStorageServer->ip_addr, pStorageServer->port);
|
|
*/
|
|
|
|
do
|
|
{
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
if (bUploadSlave)
|
|
{
|
|
long2buff(master_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
}
|
|
else
|
|
{
|
|
*p++ = (char)new_store_path;
|
|
}
|
|
|
|
long2buff(file_size, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
if (bUploadSlave)
|
|
{
|
|
memset(p, 0, FDFS_FILE_PREFIX_MAX_LEN + \
|
|
FDFS_FILE_EXT_NAME_MAX_LEN);
|
|
if (prefix_len > FDFS_FILE_PREFIX_MAX_LEN)
|
|
{
|
|
prefix_len = FDFS_FILE_PREFIX_MAX_LEN;
|
|
}
|
|
if (prefix_len > 0)
|
|
{
|
|
memcpy(p, prefix_name, prefix_len);
|
|
}
|
|
p += FDFS_FILE_PREFIX_MAX_LEN;
|
|
}
|
|
else
|
|
{
|
|
memset(p, 0, FDFS_FILE_EXT_NAME_MAX_LEN);
|
|
}
|
|
|
|
if (file_ext_name != NULL)
|
|
{
|
|
int file_ext_len;
|
|
|
|
file_ext_len = strlen(file_ext_name);
|
|
if (file_ext_len > FDFS_FILE_EXT_NAME_MAX_LEN)
|
|
{
|
|
file_ext_len = FDFS_FILE_EXT_NAME_MAX_LEN;
|
|
}
|
|
if (file_ext_len > 0)
|
|
{
|
|
memcpy(p, file_ext_name, file_ext_len);
|
|
}
|
|
}
|
|
p += FDFS_FILE_EXT_NAME_MAX_LEN;
|
|
|
|
if (bUploadSlave)
|
|
{
|
|
memcpy(p, master_filename, master_filename_len);
|
|
p += master_filename_len;
|
|
}
|
|
|
|
long2buff((p - out_buff) + file_size - sizeof(TrackerHeader), \
|
|
pHeader->pkg_len);
|
|
pHeader->cmd = cmd;
|
|
pHeader->status = 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
if (upload_type == FDFS_UPLOAD_BY_FILE)
|
|
{
|
|
if ((result=tcpsendfile(pStorageServer->sock, file_buff, \
|
|
file_size, g_fdfs_network_timeout, \
|
|
&total_send_bytes)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if (upload_type == FDFS_UPLOAD_BY_BUFF)
|
|
{
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, \
|
|
(char *)file_buff, file_size, \
|
|
g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
}
|
|
else //FDFS_UPLOAD_BY_CALLBACK
|
|
{
|
|
UploadCallback callback;
|
|
callback = (UploadCallback)file_buff;
|
|
if ((result=callback(arg, file_size, pStorageServer->sock))!=0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
&pInBuff, sizeof(in_buff), &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes <= FDFS_GROUP_NAME_MAX_LEN)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"storage server %s:%d response data " \
|
|
"length: %"PRId64" is invalid, " \
|
|
"should > %d", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
in_bytes, FDFS_GROUP_NAME_MAX_LEN);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
in_buff[in_bytes] = '\0';
|
|
memcpy(group_name, in_buff, FDFS_GROUP_NAME_MAX_LEN);
|
|
group_name[FDFS_GROUP_NAME_MAX_LEN] = '\0';
|
|
|
|
memcpy(remote_filename, in_buff + FDFS_GROUP_NAME_MAX_LEN, \
|
|
in_bytes - FDFS_GROUP_NAME_MAX_LEN + 1);
|
|
|
|
} while (0);
|
|
|
|
if (result == 0 && meta_count > 0)
|
|
{
|
|
result = storage_set_metadata(pTrackerServer, \
|
|
pStorageServer, group_name, remote_filename, \
|
|
meta_list, meta_count, \
|
|
STORAGE_SET_METADATA_FLAG_OVERWRITE);
|
|
if (result != 0) //rollback
|
|
{
|
|
storage_delete_file(pTrackerServer, pStorageServer, \
|
|
group_name, remote_filename);
|
|
*group_name = '\0';
|
|
*remote_filename = '\0';
|
|
}
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_upload_by_callback_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, UploadCallback callback, void *arg, \
|
|
const int64_t file_size, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *group_name, char *remote_filename)
|
|
{
|
|
return storage_do_upload_file(pTrackerServer, pStorageServer, \
|
|
store_path_index, cmd, FDFS_UPLOAD_BY_CALLBACK, \
|
|
(char *)callback, arg, file_size, NULL, NULL, \
|
|
file_ext_name, meta_list, meta_count, \
|
|
group_name, remote_filename);
|
|
}
|
|
|
|
int storage_upload_by_callback1_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, UploadCallback callback, void *arg, \
|
|
const int64_t file_size, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
const char *group_name, char *file_id)
|
|
{
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
int result;
|
|
|
|
if (group_name == NULL)
|
|
{
|
|
*new_group_name = '\0';
|
|
}
|
|
else
|
|
{
|
|
snprintf(new_group_name, sizeof(new_group_name), \
|
|
"%s", group_name);
|
|
}
|
|
|
|
result = storage_do_upload_file(pTrackerServer, \
|
|
pStorageServer, store_path_index, \
|
|
cmd, FDFS_UPLOAD_BY_CALLBACK, (char *)callback, arg, \
|
|
file_size, NULL, NULL, file_ext_name, \
|
|
meta_list, meta_count, \
|
|
new_group_name, remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
file_id[0] = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_upload_by_filename_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int store_path_index, \
|
|
const char cmd, const char *local_filename, \
|
|
const char *file_ext_name, const FDFSMetaData *meta_list, \
|
|
const int meta_count, char *group_name, char *remote_filename)
|
|
{
|
|
struct stat stat_buf;
|
|
|
|
if (stat(local_filename, &stat_buf) != 0)
|
|
{
|
|
group_name[0] = '\0';
|
|
remote_filename[0] = '\0';
|
|
return errno;
|
|
}
|
|
|
|
if (!S_ISREG(stat_buf.st_mode))
|
|
{
|
|
group_name[0] = '\0';
|
|
remote_filename[0] = '\0';
|
|
return EINVAL;
|
|
}
|
|
|
|
if (file_ext_name == NULL)
|
|
{
|
|
file_ext_name = fdfs_get_file_ext_name(local_filename);
|
|
}
|
|
|
|
return storage_do_upload_file(pTrackerServer, pStorageServer, \
|
|
store_path_index, cmd, \
|
|
FDFS_UPLOAD_BY_FILE, local_filename, \
|
|
NULL, stat_buf.st_size, NULL, NULL, file_ext_name, \
|
|
meta_list, meta_count, group_name, remote_filename);
|
|
}
|
|
|
|
int storage_set_metadata1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
const char op_flag)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_set_metadata(pTrackerServer, pStorageServer, \
|
|
group_name, filename, \
|
|
meta_list, meta_count, op_flag);
|
|
}
|
|
|
|
/**
|
|
8 bytes: filename length
|
|
8 bytes: meta data size
|
|
1 bytes: operation flag,
|
|
'O' for overwrite all old metadata
|
|
'M' for merge, insert when the meta item not exist, otherwise update it
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
filename
|
|
meta data bytes: each meta data seperated by \x01,
|
|
name and value seperated by \x02
|
|
**/
|
|
int storage_set_metadata(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *filename, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
const char op_flag)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
ConnectionInfo storageServer;
|
|
char out_buff[sizeof(TrackerHeader)+2*FDFS_PROTO_PKG_LEN_SIZE+\
|
|
FDFS_GROUP_NAME_MAX_LEN+128];
|
|
char in_buff[1];
|
|
int64_t in_bytes;
|
|
char *pBuff;
|
|
int filename_len;
|
|
char *meta_buff;
|
|
int meta_bytes;
|
|
char *p;
|
|
char *pEnd;
|
|
bool new_connection;
|
|
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
meta_buff = NULL;
|
|
do
|
|
{
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
filename_len = strlen(filename);
|
|
|
|
if (meta_count > 0)
|
|
{
|
|
meta_buff = fdfs_pack_metadata(meta_list, meta_count, \
|
|
NULL, &meta_bytes);
|
|
if (meta_buff == NULL)
|
|
{
|
|
result = ENOMEM;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
meta_bytes = 0;
|
|
}
|
|
|
|
pEnd = out_buff + sizeof(out_buff);
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
|
|
long2buff(filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
long2buff(meta_bytes, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
*p++ = op_flag;
|
|
|
|
snprintf(p, pEnd - p, "%s", group_name);
|
|
p += FDFS_GROUP_NAME_MAX_LEN;
|
|
|
|
filename_len = snprintf(p, pEnd - p, "%s", filename);
|
|
p += filename_len;
|
|
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
long2buff((int)(p - (out_buff + sizeof(TrackerHeader))) + \
|
|
meta_bytes, pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_SET_METADATA;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
|
|
break;
|
|
}
|
|
|
|
if (meta_bytes > 0 && (result=tcpsenddata_nb(pStorageServer->sock, \
|
|
meta_buff, meta_bytes, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
pBuff = in_buff;
|
|
result = fdfs_recv_response(pStorageServer, \
|
|
&pBuff, 0, &in_bytes);
|
|
if (result != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
}
|
|
} while (0);
|
|
|
|
if (meta_buff != NULL)
|
|
{
|
|
free(meta_buff);
|
|
}
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_download_file_ex1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id, \
|
|
const int64_t file_offset, const int64_t download_bytes, \
|
|
DownloadCallback callback, void *arg, int64_t *file_size)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return storage_download_file_ex(pTrackerServer, pStorageServer, \
|
|
group_name, filename, file_offset, download_bytes, \
|
|
callback, arg, file_size);
|
|
}
|
|
|
|
int storage_download_file_ex(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *remote_filename, \
|
|
const int64_t file_offset, const int64_t download_bytes, \
|
|
DownloadCallback callback, void *arg, int64_t *file_size)
|
|
{
|
|
char *pCallback;
|
|
pCallback = (char *)callback;
|
|
return storage_do_download_file_ex(pTrackerServer, pStorageServer, \
|
|
FDFS_DOWNLOAD_TO_CALLBACK, group_name, remote_filename, \
|
|
file_offset, download_bytes, &pCallback, arg, file_size);
|
|
}
|
|
|
|
int tracker_query_storage_fetch1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return tracker_query_storage_fetch(pTrackerServer, \
|
|
pStorageServer, group_name, filename);
|
|
}
|
|
|
|
int tracker_query_storage_update1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return tracker_query_storage_update(pTrackerServer, \
|
|
pStorageServer, group_name, filename);
|
|
}
|
|
|
|
/**
|
|
pkg format:
|
|
Header
|
|
8 bytes: master filename len
|
|
8 bytes: source filename len
|
|
8 bytes: source file signature len
|
|
FDFS_GROUP_NAME_MAX_LEN bytes: group_name
|
|
FDFS_FILE_PREFIX_MAX_LEN bytes : filename prefix, can be empty
|
|
FDFS_FILE_EXT_NAME_MAX_LEN bytes: file ext name, do not include dot (.)
|
|
master filename len: master filename
|
|
source filename len: source filename without group name
|
|
source file signature len: source file signature
|
|
**/
|
|
int storage_client_create_link(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *master_filename,\
|
|
const char *src_filename, const int src_filename_len, \
|
|
const char *src_file_sig, const int src_file_sig_len, \
|
|
const char *group_name, const char *prefix_name, \
|
|
const char *file_ext_name, \
|
|
char *remote_filename, int *filename_len)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[sizeof(TrackerHeader) + 4 * FDFS_PROTO_PKG_LEN_SIZE + \
|
|
FDFS_GROUP_NAME_MAX_LEN + FDFS_FILE_PREFIX_MAX_LEN + \
|
|
FDFS_FILE_EXT_NAME_MAX_LEN + 256];
|
|
char in_buff[128];
|
|
char *p;
|
|
int group_name_len;
|
|
int master_filename_len;
|
|
int64_t in_bytes;
|
|
char *pInBuff;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
|
|
*remote_filename = '\0';
|
|
if (master_filename != NULL)
|
|
{
|
|
master_filename_len = strlen(master_filename);
|
|
}
|
|
else
|
|
{
|
|
master_filename_len = 0;
|
|
}
|
|
if (src_filename_len >= 128 || src_file_sig_len > 64 || \
|
|
master_filename_len >= 128)
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, src_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
memset(out_buff, 0, sizeof(out_buff));
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
long2buff(master_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
long2buff(src_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
long2buff(src_file_sig_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
group_name_len = strlen(group_name);
|
|
if (group_name_len > FDFS_GROUP_NAME_MAX_LEN)
|
|
{
|
|
group_name_len = FDFS_GROUP_NAME_MAX_LEN;
|
|
}
|
|
memcpy(p, group_name, group_name_len);
|
|
p += FDFS_GROUP_NAME_MAX_LEN;
|
|
|
|
if (prefix_name != NULL)
|
|
{
|
|
int prefix_len;
|
|
|
|
prefix_len = strlen(prefix_name);
|
|
if (prefix_len > FDFS_FILE_PREFIX_MAX_LEN)
|
|
{
|
|
prefix_len = FDFS_FILE_PREFIX_MAX_LEN;
|
|
}
|
|
if (prefix_len > 0)
|
|
{
|
|
memcpy(p, prefix_name, prefix_len);
|
|
}
|
|
}
|
|
p += FDFS_FILE_PREFIX_MAX_LEN;
|
|
|
|
if (file_ext_name != NULL)
|
|
{
|
|
int file_ext_len;
|
|
|
|
file_ext_len = strlen(file_ext_name);
|
|
if (file_ext_len > FDFS_FILE_EXT_NAME_MAX_LEN)
|
|
{
|
|
file_ext_len = FDFS_FILE_EXT_NAME_MAX_LEN;
|
|
}
|
|
if (file_ext_len > 0)
|
|
{
|
|
memcpy(p, file_ext_name, file_ext_len);
|
|
}
|
|
}
|
|
p += FDFS_FILE_EXT_NAME_MAX_LEN;
|
|
|
|
if (master_filename_len > 0)
|
|
{
|
|
memcpy(p, master_filename, master_filename_len);
|
|
p += master_filename_len;
|
|
}
|
|
memcpy(p, src_filename, src_filename_len);
|
|
p += src_filename_len;
|
|
memcpy(p, src_file_sig, src_file_sig_len);
|
|
p += src_file_sig_len;
|
|
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
long2buff(p - out_buff - sizeof(TrackerHeader), pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_CREATE_LINK;
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
if ((result=fdfs_recv_response(pStorageServer, \
|
|
&pInBuff, sizeof(in_buff), &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes <= FDFS_GROUP_NAME_MAX_LEN)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"storage server %s:%d response data " \
|
|
"length: %"PRId64" is invalid, " \
|
|
"should > %d", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
in_bytes, FDFS_GROUP_NAME_MAX_LEN);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
*(in_buff + in_bytes) = '\0';
|
|
*filename_len = in_bytes - FDFS_GROUP_NAME_MAX_LEN;
|
|
memcpy(remote_filename, in_buff + FDFS_GROUP_NAME_MAX_LEN, \
|
|
(*filename_len) + 1);
|
|
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int tracker_query_storage_list1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int nMaxServerCount, \
|
|
int *server_count, const char *file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
return tracker_query_storage_list(pTrackerServer, \
|
|
pStorageServer, nMaxServerCount, \
|
|
server_count, group_name, filename);
|
|
}
|
|
|
|
int storage_upload_slave_by_filename(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const char *master_filename, const char *prefix_name, \
|
|
const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *group_name, char *remote_filename)
|
|
{
|
|
struct stat stat_buf;
|
|
|
|
if (master_filename == NULL || *master_filename == '\0' || \
|
|
prefix_name == NULL || group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
if (stat(local_filename, &stat_buf) != 0)
|
|
{
|
|
*group_name = '\0';
|
|
*remote_filename = '\0';
|
|
return errno != 0 ? errno : EPERM;
|
|
}
|
|
|
|
if (!S_ISREG(stat_buf.st_mode))
|
|
{
|
|
*group_name = '\0';
|
|
*remote_filename = '\0';
|
|
return EINVAL;
|
|
}
|
|
|
|
if (file_ext_name == NULL)
|
|
{
|
|
file_ext_name = fdfs_get_file_ext_name(local_filename);
|
|
}
|
|
|
|
return storage_do_upload_file(pTrackerServer, pStorageServer, \
|
|
0, STORAGE_PROTO_CMD_UPLOAD_SLAVE_FILE, \
|
|
FDFS_UPLOAD_BY_FILE, local_filename, \
|
|
NULL, stat_buf.st_size, master_filename, prefix_name, \
|
|
file_ext_name, meta_list, meta_count, \
|
|
group_name, remote_filename);
|
|
}
|
|
|
|
int storage_upload_slave_by_callback(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, \
|
|
const int64_t file_size, const char *master_filename, \
|
|
const char *prefix_name, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *group_name, char *remote_filename)
|
|
{
|
|
if (master_filename == NULL || *master_filename == '\0' || \
|
|
prefix_name == NULL || *prefix_name == '\0' || \
|
|
group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_upload_file(pTrackerServer, pStorageServer, \
|
|
0, STORAGE_PROTO_CMD_UPLOAD_SLAVE_FILE, \
|
|
FDFS_UPLOAD_BY_CALLBACK, (char *)callback, arg, \
|
|
file_size, master_filename, prefix_name, \
|
|
file_ext_name, meta_list, meta_count, \
|
|
group_name, remote_filename);
|
|
}
|
|
|
|
int storage_upload_slave_by_filebuff(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_size, const char *master_filename, \
|
|
const char *prefix_name, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *group_name, char *remote_filename)
|
|
{
|
|
if (master_filename == NULL || *master_filename == '\0' || \
|
|
prefix_name == NULL || *prefix_name == '\0' || \
|
|
group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_upload_file(pTrackerServer, pStorageServer, \
|
|
0, STORAGE_PROTO_CMD_UPLOAD_SLAVE_FILE, \
|
|
FDFS_UPLOAD_BY_BUFF, file_buff, NULL, \
|
|
file_size, master_filename, prefix_name, \
|
|
file_ext_name, meta_list, meta_count, \
|
|
group_name, remote_filename);
|
|
}
|
|
|
|
int storage_upload_slave_by_filename1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const char *master_file_id, const char *prefix_name, \
|
|
const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *file_id)
|
|
{
|
|
int result;
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(master_file_id)
|
|
|
|
strcpy(new_group_name, group_name);
|
|
result = storage_upload_slave_by_filename(pTrackerServer, \
|
|
pStorageServer, local_filename, filename, \
|
|
prefix_name, file_ext_name, \
|
|
meta_list, meta_count, \
|
|
new_group_name, remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
*file_id = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_upload_slave_by_filebuff1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_size, const char *master_file_id, \
|
|
const char *prefix_name, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *file_id)
|
|
{
|
|
int result;
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(master_file_id)
|
|
|
|
strcpy(new_group_name, group_name);
|
|
result = storage_upload_slave_by_filebuff(pTrackerServer, \
|
|
pStorageServer, file_buff, file_size, \
|
|
filename, prefix_name, file_ext_name, \
|
|
meta_list, meta_count, \
|
|
new_group_name, remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
*file_id = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_upload_slave_by_callback1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, \
|
|
const int64_t file_size, const char *master_file_id, \
|
|
const char *prefix_name, const char *file_ext_name, \
|
|
const FDFSMetaData *meta_list, const int meta_count, \
|
|
char *file_id)
|
|
{
|
|
int result;
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char remote_filename[128];
|
|
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(master_file_id)
|
|
|
|
strcpy(new_group_name, group_name);
|
|
result = storage_upload_slave_by_callback(pTrackerServer, \
|
|
pStorageServer, callback, arg, file_size, \
|
|
filename, prefix_name, file_ext_name, \
|
|
meta_list, meta_count, \
|
|
new_group_name, remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(file_id, "%s%c%s", new_group_name, \
|
|
FDFS_FILE_ID_SEPERATOR, remote_filename);
|
|
}
|
|
else
|
|
{
|
|
*file_id = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
STORAGE_PROTO_CMD_APPEND_FILE:
|
|
8 bytes: appender filename length
|
|
8 bytes: file size
|
|
master filename bytes: appender filename
|
|
file size bytes: file content
|
|
**/
|
|
int storage_do_append_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int upload_type, \
|
|
const char *file_buff, void *arg, const int64_t file_size, \
|
|
const char *group_name, const char *appender_filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[512];
|
|
char *p;
|
|
int64_t in_bytes;
|
|
int64_t total_send_bytes;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
int appender_filename_len;
|
|
|
|
appender_filename_len = strlen(appender_filename);
|
|
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, appender_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
//printf("upload to storage %s:%d\n", \
|
|
pStorageServer->ip_addr, pStorageServer->port);
|
|
*/
|
|
|
|
do
|
|
{
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
long2buff(appender_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
long2buff(file_size, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
memcpy(p, appender_filename, appender_filename_len);
|
|
p += appender_filename_len;
|
|
|
|
long2buff((p - out_buff) + file_size - sizeof(TrackerHeader), \
|
|
pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_APPEND_FILE;
|
|
pHeader->status = 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
if (upload_type == FDFS_UPLOAD_BY_FILE)
|
|
{
|
|
if ((result=tcpsendfile(pStorageServer->sock, file_buff, \
|
|
file_size, g_fdfs_network_timeout, \
|
|
&total_send_bytes)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if (upload_type == FDFS_UPLOAD_BY_BUFF)
|
|
{
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, \
|
|
(char *)file_buff, file_size, \
|
|
g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
}
|
|
else //FDFS_UPLOAD_BY_CALLBACK
|
|
{
|
|
UploadCallback callback;
|
|
callback = (UploadCallback)file_buff;
|
|
if ((result=callback(arg, file_size, pStorageServer->sock))!=0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((result=fdfs_recv_header(pStorageServer, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_header fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"storage server %s:%d response data " \
|
|
"length: %"PRId64" is invalid, " \
|
|
"should == 0", __LINE__, pStorageServer->ip_addr, \
|
|
pStorageServer->port, in_bytes);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
STORAGE_PROTO_CMD_MODIFY_FILE:
|
|
8 bytes: appender filename length
|
|
8 bytes: file offset
|
|
8 bytes: file size
|
|
master filename bytes: appender filename
|
|
file size bytes: file content
|
|
**/
|
|
int storage_do_modify_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const int upload_type, \
|
|
const char *file_buff, void *arg, const int64_t file_offset, \
|
|
const int64_t file_size, const char *group_name, \
|
|
const char *appender_filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[512];
|
|
char *p;
|
|
int64_t in_bytes;
|
|
int64_t total_send_bytes;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
int appender_filename_len;
|
|
|
|
appender_filename_len = strlen(appender_filename);
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, appender_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
//printf("upload to storage %s:%d\n", \
|
|
pStorageServer->ip_addr, pStorageServer->port);
|
|
*/
|
|
|
|
do
|
|
{
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
long2buff(appender_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
long2buff(file_offset, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
long2buff(file_size, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
memcpy(p, appender_filename, appender_filename_len);
|
|
p += appender_filename_len;
|
|
|
|
long2buff((p - out_buff) + file_size - sizeof(TrackerHeader), \
|
|
pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_MODIFY_FILE;
|
|
pHeader->status = 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
if (upload_type == FDFS_UPLOAD_BY_FILE)
|
|
{
|
|
if ((result=tcpsendfile(pStorageServer->sock, file_buff, \
|
|
file_size, g_fdfs_network_timeout, \
|
|
&total_send_bytes)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if (upload_type == FDFS_UPLOAD_BY_BUFF)
|
|
{
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, \
|
|
(char *)file_buff, file_size, \
|
|
g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
}
|
|
else //FDFS_UPLOAD_BY_CALLBACK
|
|
{
|
|
UploadCallback callback;
|
|
callback = (UploadCallback)file_buff;
|
|
if ((result=callback(arg, file_size, pStorageServer->sock))!=0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((result=fdfs_recv_header(pStorageServer, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_header fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"storage server %s:%d response data " \
|
|
"length: %"PRId64" is invalid, " \
|
|
"should == 0", __LINE__, pStorageServer->ip_addr, \
|
|
pStorageServer->port, in_bytes);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_append_by_filename(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const char *group_name, const char *appender_filename)
|
|
{
|
|
struct stat stat_buf;
|
|
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
if (stat(local_filename, &stat_buf) != 0)
|
|
{
|
|
return errno != 0 ? errno : EPERM;
|
|
}
|
|
|
|
if (!S_ISREG(stat_buf.st_mode))
|
|
{
|
|
return EINVAL;
|
|
}
|
|
return storage_do_append_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_FILE, local_filename, \
|
|
NULL, stat_buf.st_size, group_name, appender_filename);
|
|
}
|
|
|
|
int storage_append_by_callback(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, const int64_t file_size, \
|
|
const char *group_name, const char *appender_filename)
|
|
{
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_append_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_CALLBACK, (char *)callback, arg, \
|
|
file_size, group_name, appender_filename);
|
|
}
|
|
|
|
int storage_append_by_filebuff(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_size, const char *group_name, \
|
|
const char *appender_filename)
|
|
{
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_append_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_BUFF, file_buff, NULL, \
|
|
file_size, group_name, appender_filename);
|
|
}
|
|
|
|
int storage_append_by_filename1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_append_by_filename(pTrackerServer, \
|
|
pStorageServer, local_filename, group_name, filename);
|
|
}
|
|
|
|
int storage_append_by_filebuff1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_size, const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_append_by_filebuff(pTrackerServer, \
|
|
pStorageServer, file_buff, file_size, \
|
|
group_name, filename);
|
|
}
|
|
|
|
int storage_append_by_callback1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, \
|
|
const int64_t file_size, const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_append_by_callback(pTrackerServer, \
|
|
pStorageServer, callback, arg, file_size, \
|
|
group_name, filename);
|
|
}
|
|
|
|
int storage_modify_by_filename(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const int64_t file_offset, const char *group_name, \
|
|
const char *appender_filename)
|
|
{
|
|
struct stat stat_buf;
|
|
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
if (stat(local_filename, &stat_buf) != 0)
|
|
{
|
|
return errno != 0 ? errno : EPERM;
|
|
}
|
|
|
|
if (!S_ISREG(stat_buf.st_mode))
|
|
{
|
|
return EINVAL;
|
|
}
|
|
return storage_do_modify_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_FILE, local_filename, \
|
|
NULL, file_offset, stat_buf.st_size, \
|
|
group_name, appender_filename);
|
|
}
|
|
|
|
int storage_modify_by_callback(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, const int64_t file_offset,\
|
|
const int64_t file_size, const char *group_name, \
|
|
const char *appender_filename)
|
|
{
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_modify_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_CALLBACK, (char *)callback, arg, \
|
|
file_offset, file_size, group_name, appender_filename);
|
|
}
|
|
|
|
int storage_modify_by_filebuff(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_offset, const int64_t file_size, \
|
|
const char *group_name, const char *appender_filename)
|
|
{
|
|
if (appender_filename == NULL || *appender_filename == '\0' \
|
|
|| group_name == NULL || *group_name == '\0')
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
return storage_do_modify_file(pTrackerServer, pStorageServer, \
|
|
FDFS_UPLOAD_BY_BUFF, file_buff, NULL, \
|
|
file_offset, file_size, group_name, appender_filename);
|
|
}
|
|
|
|
int storage_modify_by_filename1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *local_filename,\
|
|
const int64_t file_offset, const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_modify_by_filename(pTrackerServer, \
|
|
pStorageServer, local_filename, file_offset, \
|
|
group_name, filename);
|
|
}
|
|
|
|
int storage_modify_by_filebuff1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, const char *file_buff, \
|
|
const int64_t file_offset, const int64_t file_size, \
|
|
const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_modify_by_filebuff(pTrackerServer, \
|
|
pStorageServer, file_buff, file_offset, file_size, \
|
|
group_name, filename);
|
|
}
|
|
|
|
int storage_modify_by_callback1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
UploadCallback callback, void *arg, \
|
|
const int64_t file_offset, const int64_t file_size, \
|
|
const char *appender_file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
return storage_modify_by_callback(pTrackerServer, \
|
|
pStorageServer, callback, arg, file_offset, file_size, \
|
|
group_name, filename);
|
|
}
|
|
//bh edit start
|
|
int fdfs_get_allonline_file_info_ex1(const char *file_id, const bool get_from_server, \
|
|
FDFSFileInfo *pFileInfo)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return fdfs_get_allonline_file_info_ex(group_name, filename, get_from_server, \
|
|
pFileInfo);
|
|
}
|
|
|
|
int fdfs_get_allonline_file_info_ex(const char *group_name, const char *remote_filename, \
|
|
const bool get_from_server, FDFSFileInfo *pFileInfo)
|
|
{
|
|
struct in_addr ip_addr;
|
|
int filename_len;
|
|
int buff_len;
|
|
int result;
|
|
char buff[64];
|
|
|
|
memset(pFileInfo, 0, sizeof(FDFSFileInfo));
|
|
if (!the_base64_context_inited)
|
|
{
|
|
the_base64_context_inited = 1;
|
|
base64_init_ex(&the_base64_context, 0, '-', '_', '.');
|
|
}
|
|
|
|
filename_len = strlen(remote_filename);
|
|
if (filename_len < FDFS_NORMAL_LOGIC_FILENAME_LENGTH)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"filename is too short, length: %d < %d", \
|
|
__LINE__, filename_len, \
|
|
FDFS_NORMAL_LOGIC_FILENAME_LENGTH);
|
|
return EINVAL;
|
|
}
|
|
|
|
memset(buff, 0, sizeof(buff));
|
|
base64_decode_auto(&the_base64_context, (char *)remote_filename + \
|
|
FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
|
|
buff, &buff_len);
|
|
|
|
memset(&ip_addr, 0, sizeof(ip_addr));
|
|
ip_addr.s_addr = ntohl(buff2int(buff));
|
|
if (fdfs_get_server_id_type(ip_addr.s_addr) == FDFS_ID_TYPE_SERVER_ID)
|
|
{
|
|
pFileInfo->source_id = ip_addr.s_addr;
|
|
if (g_storage_ids_by_id.count > 0)
|
|
{
|
|
char id[16];
|
|
FDFSStorageIdInfo *pStorageId;
|
|
|
|
sprintf(id, "%d", pFileInfo->source_id);
|
|
pStorageId = fdfs_get_storage_by_id(id);
|
|
if (pStorageId != NULL)
|
|
{
|
|
strcpy(pFileInfo->source_ip_addr,
|
|
pStorageId->ip_addrs.ips[0].address);
|
|
}
|
|
else
|
|
{
|
|
*(pFileInfo->source_ip_addr) = '\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*(pFileInfo->source_ip_addr) = '\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->source_id = 0;
|
|
inet_ntop(AF_INET, &ip_addr, pFileInfo->source_ip_addr, \
|
|
IP_ADDRESS_SIZE);
|
|
}
|
|
|
|
pFileInfo->create_timestamp = buff2int(buff + sizeof(int));
|
|
pFileInfo->file_size = buff2long(buff + sizeof(int) * 2);
|
|
|
|
if (IS_APPENDER_FILE(pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_APPENDER;
|
|
}
|
|
else if (IS_SLAVE_FILE(filename_len, pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_SLAVE;
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_NORMAL;
|
|
}
|
|
|
|
if (pFileInfo->file_type == FDFS_FILE_TYPE_SLAVE ||
|
|
pFileInfo->file_type == FDFS_FILE_TYPE_APPENDER ||
|
|
(*(pFileInfo->source_ip_addr) == '\0' && get_from_server))
|
|
{ //slave file or appender file
|
|
if (get_from_server)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo trackerServer;
|
|
|
|
conn = tracker_get_connection_r(&trackerServer, &result);
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = storage_query_file_info(conn,
|
|
NULL, group_name, remote_filename, pFileInfo);
|
|
tracker_close_connection_ex(conn, result != 0 &&
|
|
result != ENOENT);
|
|
|
|
pFileInfo->get_from_server = true;
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->get_from_server = false;
|
|
pFileInfo->file_size = -1;
|
|
return 0;
|
|
}
|
|
}
|
|
else //master file (normal file)
|
|
{
|
|
if (get_from_server){
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo trackerServer;
|
|
|
|
conn = tracker_get_connection_r(&trackerServer, &result);
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = storage_query_file_info(conn,
|
|
NULL, group_name, remote_filename, pFileInfo);
|
|
tracker_close_connection_ex(conn, result != 0 &&
|
|
result != ENOENT);
|
|
|
|
pFileInfo->get_from_server = true;
|
|
return result;
|
|
} else {
|
|
pFileInfo->get_from_server = false;
|
|
if ((pFileInfo->file_size >> 63) != 0)
|
|
{
|
|
pFileInfo->file_size &= 0xFFFFFFFF; //low 32 bits is file size
|
|
}
|
|
else if (IS_TRUNK_FILE(pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_size = FDFS_TRUNK_FILE_TRUE_SIZE( \
|
|
pFileInfo->file_size);
|
|
}
|
|
|
|
pFileInfo->crc32 = buff2int(buff+sizeof(int)*4);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//bh edit end
|
|
|
|
int fdfs_get_file_info_ex1(const char *file_id, const bool get_from_server, \
|
|
FDFSFileInfo *pFileInfo)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
|
|
return fdfs_get_file_info_ex(group_name, filename, get_from_server, \
|
|
pFileInfo);
|
|
}
|
|
|
|
|
|
|
|
int fdfs_get_file_info_ex(const char *group_name, const char *remote_filename, \
|
|
const bool get_from_server, FDFSFileInfo *pFileInfo)
|
|
{
|
|
struct in_addr ip_addr;
|
|
int filename_len;
|
|
int buff_len;
|
|
int result;
|
|
char buff[64];
|
|
|
|
memset(pFileInfo, 0, sizeof(FDFSFileInfo));
|
|
if (!the_base64_context_inited)
|
|
{
|
|
the_base64_context_inited = 1;
|
|
base64_init_ex(&the_base64_context, 0, '-', '_', '.');
|
|
}
|
|
|
|
filename_len = strlen(remote_filename);
|
|
if (filename_len < FDFS_NORMAL_LOGIC_FILENAME_LENGTH)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"filename is too short, length: %d < %d", \
|
|
__LINE__, filename_len, \
|
|
FDFS_NORMAL_LOGIC_FILENAME_LENGTH);
|
|
return EINVAL;
|
|
}
|
|
|
|
memset(buff, 0, sizeof(buff));
|
|
base64_decode_auto(&the_base64_context, (char *)remote_filename + \
|
|
FDFS_LOGIC_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \
|
|
buff, &buff_len);
|
|
|
|
memset(&ip_addr, 0, sizeof(ip_addr));
|
|
ip_addr.s_addr = ntohl(buff2int(buff));
|
|
if (fdfs_get_server_id_type(ip_addr.s_addr) == FDFS_ID_TYPE_SERVER_ID)
|
|
{
|
|
pFileInfo->source_id = ip_addr.s_addr;
|
|
if (g_storage_ids_by_id.count > 0)
|
|
{
|
|
char id[16];
|
|
FDFSStorageIdInfo *pStorageId;
|
|
|
|
sprintf(id, "%d", pFileInfo->source_id);
|
|
pStorageId = fdfs_get_storage_by_id(id);
|
|
if (pStorageId != NULL)
|
|
{
|
|
strcpy(pFileInfo->source_ip_addr,
|
|
pStorageId->ip_addrs.ips[0].address);
|
|
}
|
|
else
|
|
{
|
|
*(pFileInfo->source_ip_addr) = '\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*(pFileInfo->source_ip_addr) = '\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->source_id = 0;
|
|
inet_ntop(AF_INET, &ip_addr, pFileInfo->source_ip_addr, \
|
|
IP_ADDRESS_SIZE);
|
|
}
|
|
|
|
pFileInfo->create_timestamp = buff2int(buff + sizeof(int));
|
|
pFileInfo->file_size = buff2long(buff + sizeof(int) * 2);
|
|
|
|
if (IS_APPENDER_FILE(pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_APPENDER;
|
|
}
|
|
else if (IS_SLAVE_FILE(filename_len, pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_SLAVE;
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->file_type = FDFS_FILE_TYPE_NORMAL;
|
|
}
|
|
|
|
if (pFileInfo->file_type == FDFS_FILE_TYPE_SLAVE ||
|
|
pFileInfo->file_type == FDFS_FILE_TYPE_APPENDER ||
|
|
(*(pFileInfo->source_ip_addr) == '\0' && get_from_server))
|
|
{ //slave file or appender file
|
|
if (get_from_server)
|
|
{
|
|
ConnectionInfo *conn;
|
|
TrackerServerInfo trackerServer;
|
|
|
|
conn = tracker_get_connection_r(&trackerServer, &result);
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = storage_query_file_info(conn,
|
|
NULL, group_name, remote_filename, pFileInfo);
|
|
tracker_close_connection_ex(conn, result != 0 &&
|
|
result != ENOENT);
|
|
|
|
pFileInfo->get_from_server = true;
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
pFileInfo->get_from_server = false;
|
|
pFileInfo->file_size = -1;
|
|
return 0;
|
|
}
|
|
}
|
|
else //master file (normal file)
|
|
{
|
|
pFileInfo->get_from_server = false;
|
|
if ((pFileInfo->file_size >> 63) != 0)
|
|
{
|
|
pFileInfo->file_size &= 0xFFFFFFFF; //low 32 bits is file size
|
|
}
|
|
else if (IS_TRUNK_FILE(pFileInfo->file_size))
|
|
{
|
|
pFileInfo->file_size = FDFS_TRUNK_FILE_TRUE_SIZE( \
|
|
pFileInfo->file_size);
|
|
}
|
|
pFileInfo->crc32 = buff2int(buff+sizeof(int)*4);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int storage_file_exist(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *group_name, const char *remote_filename)
|
|
{
|
|
FDFSFileInfo file_info;
|
|
return storage_query_file_info_ex(pTrackerServer, \
|
|
pStorageServer, group_name, remote_filename, \
|
|
&file_info, true);
|
|
}
|
|
|
|
int storage_file_exist1(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer, \
|
|
const char *file_id)
|
|
{
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id)
|
|
return storage_file_exist(pTrackerServer, pStorageServer, \
|
|
group_name, filename);
|
|
}
|
|
|
|
int storage_truncate_file(ConnectionInfo *pTrackerServer, \
|
|
ConnectionInfo *pStorageServer,
|
|
const char *group_name, const char *appender_filename, \
|
|
const int64_t truncated_file_size)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[512];
|
|
char *p;
|
|
int64_t in_bytes;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
int appender_filename_len;
|
|
|
|
appender_filename_len = strlen(appender_filename);
|
|
if ((result=storage_get_update_connection(pTrackerServer, \
|
|
&pStorageServer, group_name, appender_filename, \
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
//printf("upload to storage %s:%d\n", \
|
|
pStorageServer->ip_addr, pStorageServer->port);
|
|
*/
|
|
|
|
do
|
|
{
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
long2buff(appender_filename_len, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
long2buff(truncated_file_size, p);
|
|
p += FDFS_PROTO_PKG_LEN_SIZE;
|
|
|
|
memcpy(p, appender_filename, appender_filename_len);
|
|
p += appender_filename_len;
|
|
|
|
long2buff((p - out_buff) - sizeof(TrackerHeader), \
|
|
pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_TRUNCATE_FILE;
|
|
pHeader->status = 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff, \
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"send data to storage server %s:%d fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
pStorageServer->ip_addr, pStorageServer->port, \
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
if ((result=fdfs_recv_header(pStorageServer, &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_header fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"storage server %s:%d response data " \
|
|
"length: %"PRId64" is invalid, " \
|
|
"should == 0", __LINE__, pStorageServer->ip_addr, \
|
|
pStorageServer->port, in_bytes);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_regenerate_appender_filename(ConnectionInfo *pTrackerServer,
|
|
ConnectionInfo *pStorageServer, const char *group_name,
|
|
const char *appender_filename, char *new_group_name,
|
|
char *new_remote_filename)
|
|
{
|
|
TrackerHeader *pHeader;
|
|
int result;
|
|
char out_buff[512];
|
|
char in_buff[256];
|
|
char *p;
|
|
char *pInBuff;
|
|
int64_t in_bytes;
|
|
ConnectionInfo storageServer;
|
|
bool new_connection;
|
|
int appender_filename_len;
|
|
|
|
appender_filename_len = strlen(appender_filename);
|
|
if ((result=storage_get_update_connection(pTrackerServer,
|
|
&pStorageServer, group_name, appender_filename,
|
|
&storageServer, &new_connection)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
do
|
|
{
|
|
pHeader = (TrackerHeader *)out_buff;
|
|
p = out_buff + sizeof(TrackerHeader);
|
|
|
|
memcpy(p, appender_filename, appender_filename_len);
|
|
p += appender_filename_len;
|
|
|
|
long2buff((p - out_buff) - sizeof(TrackerHeader),
|
|
pHeader->pkg_len);
|
|
pHeader->cmd = STORAGE_PROTO_CMD_REGENERATE_APPENDER_FILENAME;
|
|
pHeader->status = 0;
|
|
|
|
if ((result=tcpsenddata_nb(pStorageServer->sock, out_buff,
|
|
p - out_buff, g_fdfs_network_timeout)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"send data to storage server %s:%d fail, "
|
|
"errno: %d, error info: %s", __LINE__,
|
|
pStorageServer->ip_addr, pStorageServer->port,
|
|
result, STRERROR(result));
|
|
break;
|
|
}
|
|
|
|
pInBuff = in_buff;
|
|
if ((result=fdfs_recv_response(pStorageServer,
|
|
&pInBuff, sizeof(in_buff), &in_bytes)) != 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"fdfs_recv_response fail, result: %d",
|
|
__LINE__, result);
|
|
break;
|
|
}
|
|
|
|
if (in_bytes <= FDFS_GROUP_NAME_MAX_LEN)
|
|
{
|
|
logError("file: "__FILE__", line: %d, "
|
|
"storage server %s:%d response data "
|
|
"length: %"PRId64" is invalid, "
|
|
"should > %d", __LINE__,
|
|
pStorageServer->ip_addr, pStorageServer->port,
|
|
in_bytes, FDFS_GROUP_NAME_MAX_LEN);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
in_buff[in_bytes] = '\0';
|
|
memcpy(new_group_name, in_buff, FDFS_GROUP_NAME_MAX_LEN);
|
|
new_group_name[FDFS_GROUP_NAME_MAX_LEN] = '\0';
|
|
|
|
memcpy(new_remote_filename, in_buff + FDFS_GROUP_NAME_MAX_LEN,
|
|
in_bytes - FDFS_GROUP_NAME_MAX_LEN + 1);
|
|
|
|
} while (0);
|
|
|
|
if (new_connection)
|
|
{
|
|
tracker_close_connection_ex(pStorageServer, result != 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int storage_regenerate_appender_filename1(ConnectionInfo *pTrackerServer,
|
|
ConnectionInfo *pStorageServer, const char *appender_file_id,
|
|
char *new_file_id)
|
|
{
|
|
int result;
|
|
char new_group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
|
|
char new_remote_filename[128];
|
|
|
|
FDFS_SPLIT_GROUP_NAME_AND_FILENAME(appender_file_id)
|
|
|
|
result = storage_regenerate_appender_filename(pTrackerServer,
|
|
pStorageServer, group_name, filename,
|
|
new_group_name, new_remote_filename);
|
|
if (result == 0)
|
|
{
|
|
sprintf(new_file_id, "%s%c%s", new_group_name,
|
|
FDFS_FILE_ID_SEPERATOR, new_remote_filename);
|
|
}
|
|
else
|
|
{
|
|
new_file_id[0] = '\0';
|
|
}
|
|
|
|
return result;
|
|
}
|