602 lines
15 KiB
C
602 lines
15 KiB
C
/**
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <netdb.h>
|
|
#include <sys/types.h>
|
|
#include "fastcommon/sockopt.h"
|
|
#include "fastcommon/logger.h"
|
|
#include "client_global.h"
|
|
#include "fdfs_global.h"
|
|
#include "fdfs_client.h"
|
|
|
|
static ConnectionInfo *pTrackerServer;
|
|
|
|
static int list_all_groups(const char *group_name);
|
|
|
|
static void usage(char *argv[])
|
|
{
|
|
printf("Usage: %s <config_file> [-h <tracker_server>] "
|
|
"[list|delete|set_trunk_server <group_name> [storage_id]]\n"
|
|
"\tthe tracker server format: host[:port], "
|
|
"the tracker default port is %d\n\n",
|
|
argv[0], FDFS_TRACKER_SERVER_DEF_PORT);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *conf_filename;
|
|
int result;
|
|
char *op_type;
|
|
char *tracker_server;
|
|
int arg_index;
|
|
char *group_name;
|
|
|
|
if (argc < 2)
|
|
{
|
|
usage(argv);
|
|
return 1;
|
|
}
|
|
|
|
tracker_server = NULL;
|
|
conf_filename = argv[1];
|
|
arg_index = 2;
|
|
|
|
if (arg_index >= argc)
|
|
{
|
|
op_type = "list";
|
|
}
|
|
else
|
|
{
|
|
int len;
|
|
|
|
len = strlen(argv[arg_index]);
|
|
if (len >= 2 && strncmp(argv[arg_index], "-h", 2) == 0)
|
|
{
|
|
if (len == 2)
|
|
{
|
|
arg_index++;
|
|
if (arg_index >= argc)
|
|
{
|
|
usage(argv);
|
|
return 1;
|
|
}
|
|
|
|
tracker_server = argv[arg_index++];
|
|
}
|
|
else
|
|
{
|
|
tracker_server = argv[arg_index] + 2;
|
|
arg_index++;
|
|
}
|
|
|
|
if (arg_index < argc)
|
|
{
|
|
op_type = argv[arg_index++];
|
|
}
|
|
else
|
|
{
|
|
op_type = "list";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
op_type = argv[arg_index++];
|
|
}
|
|
}
|
|
|
|
log_init();
|
|
g_log_context.log_level = LOG_DEBUG;
|
|
ignore_signal_pipe();
|
|
|
|
if ((result=fdfs_client_init(conf_filename)) != 0)
|
|
{
|
|
return result;
|
|
}
|
|
load_log_level_ex(conf_filename);
|
|
|
|
if (tracker_server == NULL)
|
|
{
|
|
if (g_tracker_group.server_count > 1)
|
|
{
|
|
srand(time(NULL));
|
|
rand(); //discard the first
|
|
g_tracker_group.server_index = (int)( \
|
|
(g_tracker_group.server_count * (double)rand()) \
|
|
/ (double)RAND_MAX);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
ConnectionInfo conn;
|
|
|
|
if ((result=conn_pool_parse_server_info(tracker_server, &conn,
|
|
FDFS_TRACKER_SERVER_DEF_PORT)) != 0)
|
|
{
|
|
printf("resolve ip address of tracker server: %s "
|
|
"fail!, error info: %s\n", tracker_server, hstrerror(h_errno));
|
|
return result;
|
|
}
|
|
|
|
for (i=0; i<g_tracker_group.server_count; i++)
|
|
{
|
|
if (fdfs_server_contain1(g_tracker_group.servers + i, &conn))
|
|
{
|
|
fdfs_set_server_info_index1(g_tracker_group.servers + i, &conn);
|
|
g_tracker_group.server_index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == g_tracker_group.server_count)
|
|
{
|
|
printf("tracker server: %s not exists!\n", tracker_server);
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
printf("server_count=%d, server_index=%d\n",
|
|
g_tracker_group.server_count, g_tracker_group.server_index);
|
|
|
|
pTrackerServer = tracker_get_connection();
|
|
if (pTrackerServer == NULL)
|
|
{
|
|
fdfs_client_destroy();
|
|
return errno != 0 ? errno : ECONNREFUSED;
|
|
}
|
|
printf("\ntracker server is %s:%u\n\n", pTrackerServer->ip_addr, pTrackerServer->port);
|
|
|
|
if (arg_index < argc)
|
|
{
|
|
group_name = argv[arg_index++];
|
|
}
|
|
else
|
|
{
|
|
group_name = NULL;
|
|
}
|
|
|
|
if (strcmp(op_type, "list") == 0)
|
|
{
|
|
if (group_name == NULL)
|
|
{
|
|
result = list_all_groups(NULL);
|
|
}
|
|
else
|
|
{
|
|
result = list_all_groups(group_name);
|
|
}
|
|
}
|
|
else if (strcmp(op_type, "delete") == 0)
|
|
{
|
|
if (arg_index >= argc)
|
|
{
|
|
if ((result=tracker_delete_group(&g_tracker_group, \
|
|
group_name)) == 0)
|
|
{
|
|
printf("delete group: %s success\n", \
|
|
group_name);
|
|
}
|
|
else
|
|
{
|
|
printf("delete group: %s fail, " \
|
|
"error no: %d, error info: %s\n", \
|
|
group_name, result, STRERROR(result));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char *storage_id;
|
|
|
|
storage_id = argv[arg_index++];
|
|
if ((result=tracker_delete_storage(&g_tracker_group, \
|
|
group_name, storage_id)) == 0)
|
|
{
|
|
printf("delete storage server %s::%s success\n", \
|
|
group_name, storage_id);
|
|
}
|
|
else
|
|
{
|
|
printf("delete storage server %s::%s fail, " \
|
|
"error no: %d, error info: %s\n", \
|
|
group_name, storage_id, \
|
|
result, STRERROR(result));
|
|
}
|
|
}
|
|
}
|
|
else if (strcmp(op_type, "set_trunk_server") == 0)
|
|
{
|
|
char *storage_id;
|
|
char new_trunk_server_id[FDFS_STORAGE_ID_MAX_SIZE];
|
|
|
|
if (group_name == NULL)
|
|
{
|
|
usage(argv);
|
|
return 1;
|
|
}
|
|
if (arg_index >= argc)
|
|
{
|
|
storage_id = "";
|
|
}
|
|
else
|
|
{
|
|
storage_id = argv[arg_index++];
|
|
}
|
|
|
|
if ((result=tracker_set_trunk_server(&g_tracker_group, \
|
|
group_name, storage_id, new_trunk_server_id)) == 0)
|
|
{
|
|
printf("set trunk server %s::%s success, " \
|
|
"new trunk server: %s\n", group_name, \
|
|
storage_id, new_trunk_server_id);
|
|
}
|
|
else
|
|
{
|
|
printf("set trunk server %s::%s fail, " \
|
|
"error no: %d, error info: %s\n", \
|
|
group_name, storage_id, \
|
|
result, STRERROR(result));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("Invalid command %s\n\n", op_type);
|
|
usage(argv);
|
|
}
|
|
|
|
tracker_close_connection_ex(pTrackerServer, true);
|
|
fdfs_client_destroy();
|
|
return 0;
|
|
}
|
|
|
|
static int list_storages(FDFSGroupStat *pGroupStat)
|
|
{
|
|
int result;
|
|
int storage_count;
|
|
FDFSStorageInfo storage_infos[FDFS_MAX_SERVERS_EACH_GROUP];
|
|
FDFSStorageInfo *p;
|
|
FDFSStorageInfo *pStorage;
|
|
FDFSStorageInfo *pStorageEnd;
|
|
FDFSStorageStat *pStorageStat;
|
|
char szJoinTime[32];
|
|
char szUpTime[32];
|
|
char szLastHeartBeatTime[32];
|
|
char szSrcUpdTime[32];
|
|
char szSyncUpdTime[32];
|
|
char szSyncedTimestamp[32];
|
|
char szSyncedDelaySeconds[128];
|
|
char szHostname[128];
|
|
char szHostnamePrompt[128+8];
|
|
char szDiskTotalSpace[32];
|
|
char szDiskFreeSpace[32];
|
|
char szTrunkSpace[32];
|
|
int k;
|
|
int max_last_source_update;
|
|
|
|
printf( "group name = %s\n"
|
|
"disk total space = %s MB\n"
|
|
"disk free space = %s MB\n"
|
|
"trunk free space = %s MB\n"
|
|
"storage server count = %d\n"
|
|
"active server count = %d\n"
|
|
"storage server port = %d\n"
|
|
"storage HTTP port = %d\n"
|
|
"store path count = %d\n"
|
|
"subdir count per path = %d\n"
|
|
"current write server index = %d\n"
|
|
"current trunk file id = %d\n\n",
|
|
pGroupStat->group_name,
|
|
long_to_comma_str(pGroupStat->total_mb, szDiskTotalSpace),
|
|
long_to_comma_str(pGroupStat->free_mb, szDiskFreeSpace),
|
|
long_to_comma_str(pGroupStat->trunk_free_mb, szTrunkSpace),
|
|
pGroupStat->count,
|
|
pGroupStat->active_count,
|
|
pGroupStat->storage_port,
|
|
pGroupStat->storage_http_port,
|
|
pGroupStat->store_path_count,
|
|
pGroupStat->subdir_count_per_path,
|
|
pGroupStat->current_write_server,
|
|
pGroupStat->current_trunk_file_id
|
|
);
|
|
|
|
result = tracker_list_servers(pTrackerServer, \
|
|
pGroupStat->group_name, NULL, \
|
|
storage_infos, FDFS_MAX_SERVERS_EACH_GROUP, \
|
|
&storage_count);
|
|
if (result != 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
k = 0;
|
|
pStorageEnd = storage_infos + storage_count;
|
|
for (pStorage=storage_infos; pStorage<pStorageEnd; \
|
|
pStorage++)
|
|
{
|
|
max_last_source_update = 0;
|
|
for (p=storage_infos; p<pStorageEnd; p++)
|
|
{
|
|
if (p != pStorage && p->stat.last_source_update
|
|
> max_last_source_update)
|
|
{
|
|
max_last_source_update = \
|
|
p->stat.last_source_update;
|
|
}
|
|
}
|
|
|
|
pStorageStat = &(pStorage->stat);
|
|
if (max_last_source_update == 0)
|
|
{
|
|
*szSyncedDelaySeconds = '\0';
|
|
}
|
|
else
|
|
{
|
|
if (pStorageStat->last_synced_timestamp == 0)
|
|
{
|
|
strcpy(szSyncedDelaySeconds, "(never synced)");
|
|
}
|
|
else
|
|
{
|
|
int delay_seconds;
|
|
int remain_seconds;
|
|
int day;
|
|
int hour;
|
|
int minute;
|
|
int second;
|
|
char szDelayTime[64];
|
|
|
|
delay_seconds = (int)(max_last_source_update -
|
|
pStorageStat->last_synced_timestamp);
|
|
if (delay_seconds < 0)
|
|
{
|
|
delay_seconds = 0;
|
|
}
|
|
day = delay_seconds / (24 * 3600);
|
|
remain_seconds = delay_seconds % (24 * 3600);
|
|
hour = remain_seconds / 3600;
|
|
remain_seconds %= 3600;
|
|
minute = remain_seconds / 60;
|
|
second = remain_seconds % 60;
|
|
|
|
if (day != 0)
|
|
{
|
|
sprintf(szDelayTime, "%d days " \
|
|
"%02dh:%02dm:%02ds", \
|
|
day, hour, minute, second);
|
|
}
|
|
else if (hour != 0)
|
|
{
|
|
sprintf(szDelayTime, "%02dh:%02dm:%02ds", \
|
|
hour, minute, second);
|
|
}
|
|
else if (minute != 0)
|
|
{
|
|
sprintf(szDelayTime, "%02dm:%02ds", minute, second);
|
|
}
|
|
else
|
|
{
|
|
sprintf(szDelayTime, "%ds", second);
|
|
}
|
|
|
|
sprintf(szSyncedDelaySeconds, "(%s delay)", szDelayTime);
|
|
}
|
|
}
|
|
|
|
//getHostnameByIp(pStorage->ip_addr, szHostname, sizeof(szHostname));
|
|
*szHostname = '\0';
|
|
if (*szHostname != '\0')
|
|
{
|
|
sprintf(szHostnamePrompt, " (%s)", szHostname);
|
|
}
|
|
else
|
|
{
|
|
*szHostnamePrompt = '\0';
|
|
}
|
|
|
|
if (pStorage->up_time != 0)
|
|
{
|
|
formatDatetime(pStorage->up_time, \
|
|
"%Y-%m-%d %H:%M:%S", \
|
|
szUpTime, sizeof(szUpTime));
|
|
}
|
|
else
|
|
{
|
|
*szUpTime = '\0';
|
|
}
|
|
|
|
printf( "\tStorage %d:\n"
|
|
"\t\tid = %s\n"
|
|
"\t\tip_addr = %s%s %s\n"
|
|
"\t\thttp domain = %s\n"
|
|
"\t\tversion = %s\n"
|
|
"\t\tjoin time = %s\n"
|
|
"\t\tup time = %s\n"
|
|
"\t\ttotal storage = %s MB\n"
|
|
"\t\tfree storage = %s MB\n"
|
|
"\t\tupload priority = %d\n"
|
|
"\t\tstore_path_count = %d\n"
|
|
"\t\tsubdir_count_per_path = %d\n"
|
|
"\t\tstorage_port = %d\n"
|
|
"\t\tstorage_http_port = %d\n"
|
|
"\t\tcurrent_write_path = %d\n"
|
|
"\t\tsource storage id = %s\n"
|
|
"\t\tif_trunk_server = %d\n"
|
|
"\t\tconnection.alloc_count = %d\n"
|
|
"\t\tconnection.current_count = %d\n"
|
|
"\t\tconnection.max_count = %d\n"
|
|
"\t\ttotal_upload_count = %"PRId64"\n"
|
|
"\t\tsuccess_upload_count = %"PRId64"\n"
|
|
"\t\ttotal_append_count = %"PRId64"\n"
|
|
"\t\tsuccess_append_count = %"PRId64"\n"
|
|
"\t\ttotal_modify_count = %"PRId64"\n"
|
|
"\t\tsuccess_modify_count = %"PRId64"\n"
|
|
"\t\ttotal_truncate_count = %"PRId64"\n"
|
|
"\t\tsuccess_truncate_count = %"PRId64"\n"
|
|
"\t\ttotal_set_meta_count = %"PRId64"\n"
|
|
"\t\tsuccess_set_meta_count = %"PRId64"\n"
|
|
"\t\ttotal_delete_count = %"PRId64"\n"
|
|
"\t\tsuccess_delete_count = %"PRId64"\n"
|
|
"\t\ttotal_download_count = %"PRId64"\n"
|
|
"\t\tsuccess_download_count = %"PRId64"\n"
|
|
"\t\ttotal_get_meta_count = %"PRId64"\n"
|
|
"\t\tsuccess_get_meta_count = %"PRId64"\n"
|
|
"\t\ttotal_create_link_count = %"PRId64"\n"
|
|
"\t\tsuccess_create_link_count = %"PRId64"\n"
|
|
"\t\ttotal_delete_link_count = %"PRId64"\n"
|
|
"\t\tsuccess_delete_link_count = %"PRId64"\n"
|
|
"\t\ttotal_upload_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_upload_bytes = %"PRId64"\n"
|
|
"\t\ttotal_append_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_append_bytes = %"PRId64"\n"
|
|
"\t\ttotal_modify_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_modify_bytes = %"PRId64"\n"
|
|
"\t\tstotal_download_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_download_bytes = %"PRId64"\n"
|
|
"\t\ttotal_sync_in_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_sync_in_bytes = %"PRId64"\n"
|
|
"\t\ttotal_sync_out_bytes = %"PRId64"\n"
|
|
"\t\tsuccess_sync_out_bytes = %"PRId64"\n"
|
|
"\t\ttotal_file_open_count = %"PRId64"\n"
|
|
"\t\tsuccess_file_open_count = %"PRId64"\n"
|
|
"\t\ttotal_file_read_count = %"PRId64"\n"
|
|
"\t\tsuccess_file_read_count = %"PRId64"\n"
|
|
"\t\ttotal_file_write_count = %"PRId64"\n"
|
|
"\t\tsuccess_file_write_count = %"PRId64"\n"
|
|
"\t\tlast_heart_beat_time = %s\n"
|
|
"\t\tlast_source_update = %s\n"
|
|
"\t\tlast_sync_update = %s\n"
|
|
"\t\tlast_synced_timestamp = %s %s\n",
|
|
++k, pStorage->id, pStorage->ip_addr,
|
|
szHostnamePrompt, get_storage_status_caption(
|
|
pStorage->status), pStorage->domain_name,
|
|
pStorage->version,
|
|
formatDatetime(pStorage->join_time,
|
|
"%Y-%m-%d %H:%M:%S",
|
|
szJoinTime, sizeof(szJoinTime)), szUpTime,
|
|
long_to_comma_str(pStorage->total_mb, szDiskTotalSpace),
|
|
long_to_comma_str(pStorage->free_mb, szDiskFreeSpace),
|
|
pStorage->upload_priority,
|
|
pStorage->store_path_count,
|
|
pStorage->subdir_count_per_path,
|
|
pStorage->storage_port,
|
|
pStorage->storage_http_port,
|
|
pStorage->current_write_path,
|
|
pStorage->src_id,
|
|
pStorage->if_trunk_server,
|
|
pStorageStat->connection.alloc_count,
|
|
pStorageStat->connection.current_count,
|
|
pStorageStat->connection.max_count,
|
|
pStorageStat->total_upload_count,
|
|
pStorageStat->success_upload_count,
|
|
pStorageStat->total_append_count,
|
|
pStorageStat->success_append_count,
|
|
pStorageStat->total_modify_count,
|
|
pStorageStat->success_modify_count,
|
|
pStorageStat->total_truncate_count,
|
|
pStorageStat->success_truncate_count,
|
|
pStorageStat->total_set_meta_count,
|
|
pStorageStat->success_set_meta_count,
|
|
pStorageStat->total_delete_count,
|
|
pStorageStat->success_delete_count,
|
|
pStorageStat->total_download_count,
|
|
pStorageStat->success_download_count,
|
|
pStorageStat->total_get_meta_count,
|
|
pStorageStat->success_get_meta_count,
|
|
pStorageStat->total_create_link_count,
|
|
pStorageStat->success_create_link_count,
|
|
pStorageStat->total_delete_link_count,
|
|
pStorageStat->success_delete_link_count,
|
|
pStorageStat->total_upload_bytes,
|
|
pStorageStat->success_upload_bytes,
|
|
pStorageStat->total_append_bytes,
|
|
pStorageStat->success_append_bytes,
|
|
pStorageStat->total_modify_bytes,
|
|
pStorageStat->success_modify_bytes,
|
|
pStorageStat->total_download_bytes,
|
|
pStorageStat->success_download_bytes,
|
|
pStorageStat->total_sync_in_bytes,
|
|
pStorageStat->success_sync_in_bytes,
|
|
pStorageStat->total_sync_out_bytes,
|
|
pStorageStat->success_sync_out_bytes,
|
|
pStorageStat->total_file_open_count,
|
|
pStorageStat->success_file_open_count,
|
|
pStorageStat->total_file_read_count,
|
|
pStorageStat->success_file_read_count,
|
|
pStorageStat->total_file_write_count,
|
|
pStorageStat->success_file_write_count,
|
|
formatDatetime(pStorageStat->last_heart_beat_time,
|
|
"%Y-%m-%d %H:%M:%S",
|
|
szLastHeartBeatTime, sizeof(szLastHeartBeatTime)),
|
|
formatDatetime(pStorageStat->last_source_update,
|
|
"%Y-%m-%d %H:%M:%S",
|
|
szSrcUpdTime, sizeof(szSrcUpdTime)),
|
|
formatDatetime(pStorageStat->last_sync_update,
|
|
"%Y-%m-%d %H:%M:%S",
|
|
szSyncUpdTime, sizeof(szSyncUpdTime)),
|
|
formatDatetime(pStorageStat->last_synced_timestamp,
|
|
"%Y-%m-%d %H:%M:%S",
|
|
szSyncedTimestamp, sizeof(szSyncedTimestamp)),
|
|
szSyncedDelaySeconds);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int list_all_groups(const char *group_name)
|
|
{
|
|
int result;
|
|
int group_count;
|
|
FDFSGroupStat group_stats[FDFS_MAX_GROUPS];
|
|
FDFSGroupStat *pGroupStat;
|
|
FDFSGroupStat *pGroupEnd;
|
|
int i;
|
|
|
|
result = tracker_list_groups(pTrackerServer, \
|
|
group_stats, FDFS_MAX_GROUPS, \
|
|
&group_count);
|
|
if (result != 0)
|
|
{
|
|
tracker_close_all_connections();
|
|
fdfs_client_destroy();
|
|
return result;
|
|
}
|
|
|
|
pGroupEnd = group_stats + group_count;
|
|
if (group_name == NULL)
|
|
{
|
|
printf("group count: %d\n", group_count);
|
|
i = 0;
|
|
for (pGroupStat=group_stats; pGroupStat<pGroupEnd; \
|
|
pGroupStat++)
|
|
{
|
|
printf( "\nGroup %d:\n", ++i);
|
|
list_storages(pGroupStat);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (pGroupStat=group_stats; pGroupStat<pGroupEnd; \
|
|
pGroupStat++)
|
|
{
|
|
if (strcmp(pGroupStat->group_name, group_name) == 0)
|
|
{
|
|
list_storages(pGroupStat);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|