提交 cde33ee2 编写于 作者: S Shengliang Guan

io and band

上级 09be95e4
...@@ -86,21 +86,21 @@ typedef struct { ...@@ -86,21 +86,21 @@ typedef struct {
typedef struct { typedef struct {
float uptime; // day float uptime; // day
float cpu_engine; double cpu_engine;
float cpu_system; double cpu_system;
float cpu_cores; float cpu_cores;
int64_t mem_engine; // KB int64_t mem_engine; // KB
int64_t mem_system; // KB int64_t mem_system; // KB
int64_t mem_total; // KB int64_t mem_total; // KB
int64_t disk_engine; // Byte int64_t disk_engine; // Byte
int64_t disk_used; // Byte int64_t disk_used; // Byte
int64_t disk_total; // Byte int64_t disk_total; // Byte
int64_t net_in; // Byte double net_in; // bytes per second
int64_t net_out; // Byte double net_out; // bytes per second
float io_read; double io_read;
float io_write; double io_write;
float io_read_disk; double io_read_disk;
float io_write_disk; double io_write_disk;
int32_t req_select; int32_t req_select;
float req_select_rate; float req_select_rate;
int32_t req_insert; int32_t req_insert;
......
...@@ -38,15 +38,15 @@ int32_t taosGetEmail(char *email, int32_t maxLen); ...@@ -38,15 +38,15 @@ int32_t taosGetEmail(char *email, int32_t maxLen);
int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen); int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen);
int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores); int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores);
int32_t taosGetCpuCores(float *numOfCores); int32_t taosGetCpuCores(float *numOfCores);
int32_t taosGetCpuUsage(float *cpu_system, float *cpu_engine); int32_t taosGetCpuUsage(double *cpu_system, double *cpu_engine);
int32_t taosGetTotalMemory(int64_t *totalKB); int32_t taosGetTotalMemory(int64_t *totalKB);
int32_t taosGetProcMemory(int64_t *usedKB); int32_t taosGetProcMemory(int64_t *usedKB);
int32_t taosGetSysMemory(int64_t *usedKB); int32_t taosGetSysMemory(int64_t *usedKB);
int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize); int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize);
int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes); int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes);
int32_t taosGetProcIOSpeed(float *readKB, float *writeKB, float *readDiskKB, float *writeDiskKB); int32_t taosGetIOSpeed(double *readKB, double *writeKB, double *readDiskKB, double *writeDiskKB);
int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes); int32_t taosGetCardInfo(int64_t *receive_bytes, int64_t *transmit_bytes);
int32_t taosGetBandSpeed(float *bandSpeedKb); int32_t taosGetBandSpeed(double *receive_bytes_per_sec, double *transmit_bytes_per_sec);
int32_t taosSystem(const char *cmd); int32_t taosSystem(const char *cmd);
void taosKillSystem(); void taosKillSystem();
......
...@@ -488,9 +488,9 @@ static void dndGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) { ...@@ -488,9 +488,9 @@ static void dndGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) {
pInfo->mem_total = tsTotalMemoryKB; pInfo->mem_total = tsTotalMemoryKB;
pInfo->disk_engine = 0; pInfo->disk_engine = 0;
pInfo->disk_used = tsDataSpace.size.used; pInfo->disk_used = tsDataSpace.size.used;
pInfo->disk_total = tsDataSpace.size.avail; pInfo->disk_total = tsDataSpace.size.total;
taosGetCardInfo(NULL, &pInfo->net_in, &pInfo->net_out); taosGetBandSpeed(&pInfo->net_in, &pInfo->net_out);
taosGetProcIOSpeed(&pInfo->io_read, &pInfo->io_write, &pInfo->io_read_disk, &pInfo->io_write_disk); taosGetIOSpeed(&pInfo->io_read, &pInfo->io_write, &pInfo->io_read_disk, &pInfo->io_write_disk);
pInfo->req_select = 0; pInfo->req_select = 0;
pInfo->req_select_rate = 0; pInfo->req_select_rate = 0;
pInfo->req_insert = 0; pInfo->req_insert = 0;
......
...@@ -87,7 +87,7 @@ int32_t taosGetCpuCores(float *numOfCores) { ...@@ -87,7 +87,7 @@ int32_t taosGetCpuCores(float *numOfCores) {
return 0; return 0;
} }
int32_t taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) { int32_t taosGetCpuUsage(double *sysCpuUsage, double *procCpuUsage) {
*sysCpuUsage = 0; *sysCpuUsage = 0;
*procCpuUsage = 0; *procCpuUsage = 0;
return 0; return 0;
...@@ -112,15 +112,9 @@ int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize) { ...@@ -112,15 +112,9 @@ int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize) {
} }
} }
int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) { int32_t taosGetCardInfo(int64_t *receive_bytes, int64_t *transmit_bytes) {
if (bytes) *bytes = 0; *receive_bytes = 0;
if (rbytes) *rbytes = 0; *transmit_bytes = 0;
if (tbytes) *tbytes = 0;
return 0;
}
int32_t taosGetBandSpeed(float *bandSpeedKb) {
*bandSpeedKb = 0;
return 0; return 0;
} }
...@@ -140,10 +134,10 @@ void taosGetSystemInfo() { ...@@ -140,10 +134,10 @@ void taosGetSystemInfo() {
taosGetCpuCores(&tsNumOfCores); taosGetCpuCores(&tsNumOfCores);
taosGetTotalMemory(&tsTotalMemoryKB); taosGetTotalMemory(&tsTotalMemoryKB);
float tmp1, tmp2, tmp3, tmp4; double tmp1, tmp2, tmp3, tmp4;
taosGetBandSpeed(&tmp1); taosGetBandSpeed(&tmp1, &tmp2);
taosGetCpuUsage(&tmp1, &tmp2); taosGetCpuUsage(&tmp1, &tmp2);
taosGetProcIOSpeed(&tmp1, &tmp2, &tmp3, &tmp4); taosGetIOSpeed(&tmp1, &tmp2, &tmp3, &tmp4);
} }
void taosKillSystem() { void taosKillSystem() {
...@@ -241,19 +235,13 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in ...@@ -241,19 +235,13 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in
return 0; return 0;
} }
int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) { int32_t taosGetCardInfo(int64_t *receive_bytes, int64_t *transmit_bytes) {
if (bytes) *bytes = 0; *receive_bytes = 0;
if (rbytes) *rbytes = 0; *transmit_bytes = 0;
if (tbytes) *tbytes = 0;
return 0; return 0;
} }
int32_t taosGetBandSpeed(float *bandSpeedKb) { int32_t taosGetCpuUsage(double *sysCpuUsage, double *procCpuUsage) {
*bandSpeedKb = 0;
return 0;
}
int32_t taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
*sysCpuUsage = 0; *sysCpuUsage = 0;
*procCpuUsage = 0; *procCpuUsage = 0;
return 0; return 0;
...@@ -370,7 +358,6 @@ int32_t taosGetSysMemory(int64_t *usedKB) { ...@@ -370,7 +358,6 @@ int32_t taosGetSysMemory(int64_t *usedKB) {
} }
int32_t taosGetProcMemory(int64_t *usedKB) { int32_t taosGetProcMemory(int64_t *usedKB) {
// FILE *fp = fopen(tsProcMemFile, "r");
TdFilePtr pFile = taosOpenFile(tsProcMemFile, TD_FILE_READ | TD_FILE_STREAM); TdFilePtr pFile = taosOpenFile(tsProcMemFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) { if (pFile == NULL) {
// printf("open file:%s failed", tsProcMemFile); // printf("open file:%s failed", tsProcMemFile);
...@@ -404,7 +391,6 @@ int32_t taosGetProcMemory(int64_t *usedKB) { ...@@ -404,7 +391,6 @@ int32_t taosGetProcMemory(int64_t *usedKB) {
} }
static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) { static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) {
// FILE *fp = fopen(tsSysCpuFile, "r");
TdFilePtr pFile = taosOpenFile(tsSysCpuFile, TD_FILE_READ | TD_FILE_STREAM); TdFilePtr pFile = taosOpenFile(tsSysCpuFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) { if (pFile == NULL) {
// printf("open file:%s failed", tsSysCpuFile); // printf("open file:%s failed", tsSysCpuFile);
...@@ -429,7 +415,6 @@ static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) { ...@@ -429,7 +415,6 @@ static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) {
} }
static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) { static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) {
// FILE *fp = fopen(tsProcCpuFile, "r");
TdFilePtr pFile = taosOpenFile(tsProcCpuFile, TD_FILE_READ | TD_FILE_STREAM); TdFilePtr pFile = taosOpenFile(tsProcCpuFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) { if (pFile == NULL) {
// printf("open file:%s failed", tsProcCpuFile); // printf("open file:%s failed", tsProcCpuFile);
...@@ -463,7 +448,7 @@ int32_t taosGetCpuCores(float *numOfCores) { ...@@ -463,7 +448,7 @@ int32_t taosGetCpuCores(float *numOfCores) {
return 0; return 0;
} }
int32_t taosGetCpuUsage(float *cpu_system, float *cpu_engine) { int32_t taosGetCpuUsage(double *cpu_system, double *cpu_engine) {
static uint64_t lastSysUsed = 0; static uint64_t lastSysUsed = 0;
static uint64_t lastSysTotal = 0; static uint64_t lastSysTotal = 0;
static uint64_t lastProcTotal = 0; static uint64_t lastProcTotal = 0;
...@@ -492,8 +477,8 @@ int32_t taosGetCpuUsage(float *cpu_system, float *cpu_engine) { ...@@ -492,8 +477,8 @@ int32_t taosGetCpuUsage(float *cpu_system, float *cpu_engine) {
return -1; return -1;
} }
*cpu_engine = (float)((double)(curSysUsed - lastSysUsed) / (double)(curSysTotal - lastSysTotal) * 100); *cpu_engine = (curSysUsed - lastSysUsed) / (double)(curSysTotal - lastSysTotal) * 100;
*cpu_system = (float)((double)(curProcTotal - lastProcTotal) / (double)(curSysTotal - lastSysTotal) * 100); *cpu_system = (curProcTotal - lastProcTotal) / (double)(curSysTotal - lastSysTotal) * 100;
lastSysUsed = curSysUsed; lastSysUsed = curSysUsed;
lastSysTotal = curSysTotal; lastSysTotal = curSysTotal;
...@@ -514,14 +499,9 @@ int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize) { ...@@ -514,14 +499,9 @@ int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize) {
} }
} }
int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) { int32_t taosGetCardInfo(int64_t *receive_bytes, int64_t *transmit_bytes) {
if (bytes) *bytes = 0;
// FILE *fp = fopen(tsSysNetFile, "r");
TdFilePtr pFile = taosOpenFile(tsSysNetFile, TD_FILE_READ | TD_FILE_STREAM); TdFilePtr pFile = taosOpenFile(tsSysNetFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) { if (pFile == NULL) return -1;
// printf("open file:%s failed", tsSysNetFile);
return -1;
}
ssize_t _bytes = 0; ssize_t _bytes = 0;
char *line = NULL; char *line = NULL;
...@@ -554,9 +534,8 @@ int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) { ...@@ -554,9 +534,8 @@ int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) {
"%s %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 "%s %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64
" %" PRId64, " %" PRId64,
nouse0, &o_rbytes, &rpackts, &nouse1, &nouse2, &nouse3, &nouse4, &nouse5, &nouse6, &o_tbytes, &tpackets); nouse0, &o_rbytes, &rpackts, &nouse1, &nouse2, &nouse3, &nouse4, &nouse5, &nouse6, &o_tbytes, &tpackets);
if (rbytes) *rbytes = o_rbytes; *receive_bytes = o_rbytes;
if (tbytes) *tbytes = o_tbytes; *transmit_bytes = o_tbytes;
if (bytes) *bytes += (o_rbytes + o_tbytes);
} }
if (line != NULL) tfree(line); if (line != NULL) tfree(line);
...@@ -565,57 +544,52 @@ int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) { ...@@ -565,57 +544,52 @@ int32_t taosGetCardInfo(int64_t *bytes, int64_t *rbytes, int64_t *tbytes) {
return 0; return 0;
} }
int32_t taosGetBandSpeed(float *bandSpeedKb) { int32_t taosGetBandSpeed(double *receive_bytes_per_sec, double *transmit_bytes_per_sec) {
static int64_t lastBytes = 0; static int64_t last_receive_bytes = 0;
static time_t lastTime = 0; static int64_t last_transmit_bytes = 0;
int64_t curBytes = 0; static int64_t last_time = 0;
time_t curTime = time(NULL); int64_t cur_receive_bytes = 0;
int64_t cur_transmit_bytes = 0;
int64_t cur_time = taosGetTimestampMs();
if (taosGetCardInfo(&curBytes, NULL, NULL) != 0) { if (taosGetCardInfo(&cur_receive_bytes, &cur_transmit_bytes) != 0) {
return -1; return -1;
} }
if (lastTime == 0 || lastBytes == 0) { if (last_time == 0 || last_time >= cur_time) {
lastTime = curTime; last_time = cur_time;
lastBytes = curBytes; last_receive_bytes = cur_receive_bytes;
*bandSpeedKb = 0; last_transmit_bytes = cur_transmit_bytes;
*receive_bytes_per_sec = 0;
*transmit_bytes_per_sec = 0;
return 0; return 0;
} }
if (lastTime >= curTime || lastBytes > curBytes) { *receive_bytes_per_sec = (cur_receive_bytes - last_receive_bytes) / (double)(cur_time - last_time) * 1000;
lastTime = curTime; *transmit_bytes_per_sec = (cur_transmit_bytes - last_transmit_bytes) / (double)(cur_time - last_time) * 1000;
lastBytes = curBytes;
*bandSpeedKb = 0;
return 0;
}
double totalBytes = (double)(curBytes - lastBytes) / 1024 * 8; // Kb last_time = cur_time;
*bandSpeedKb = (float)(totalBytes / (double)(curTime - lastTime)); last_transmit_bytes = cur_transmit_bytes;
last_receive_bytes = cur_receive_bytes;
// //printf("bandwidth lastBytes:%ld, lastTime:%ld, curBytes:%ld, curTime:%ld, if (*receive_bytes_per_sec < 0) *receive_bytes_per_sec = 0;
// speed:%f", lastBytes, lastTime, curBytes, curTime, *bandSpeed); if (*transmit_bytes_per_sec < 0) *transmit_bytes_per_sec = 0;
lastTime = curTime;
lastBytes = curBytes;
return 0; return 0;
} }
int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes) { int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes) {
TdFilePtr pFile = taosOpenFile(tsProcIOFile, TD_FILE_READ | TD_FILE_STREAM); TdFilePtr pFile = taosOpenFile(tsProcIOFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) { if (pFile == NULL) return -1;
// printf("open file:%s failed", tsProcIOFile);
return -1;
}
ssize_t _bytes = 0; ssize_t _bytes = 0;
char *line = NULL; char *line = NULL;
char tmp[10]; char tmp[24];
int readIndex = 0; int readIndex = 0;
while (!taosEOFFile(pFile)) { while (!taosEOFFile(pFile)) {
_bytes = taosGetLineFile(pFile, &line); _bytes = taosGetLineFile(pFile, &line);
if ((_bytes < 0) || (line == NULL)) { if (_bytes < 10 || line == NULL) {
break; break;
} }
if (strstr(line, "rchar:") != NULL) { if (strstr(line, "rchar:") != NULL) {
...@@ -624,13 +598,13 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in ...@@ -624,13 +598,13 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in
} else if (strstr(line, "wchar:") != NULL) { } else if (strstr(line, "wchar:") != NULL) {
sscanf(line, "%s %" PRId64, tmp, wchars); sscanf(line, "%s %" PRId64, tmp, wchars);
readIndex++; readIndex++;
} if (strstr(line, "read_bytes:") != NULL) { } else if (strstr(line, "read_bytes:") != NULL) { // read_bytes
sscanf(line, "%s %" PRId64, tmp, read_bytes); sscanf(line, "%s %" PRId64, tmp, read_bytes);
readIndex++; readIndex++;
} else if (strstr(line, "write_bytes::") != NULL) { } else if (strstr(line, "write_bytes:") != NULL) { // write_bytes
sscanf(line, "%s %" PRId64, tmp, write_bytes); sscanf(line, "%s %" PRId64, tmp, write_bytes);
readIndex++; readIndex++;
}else { } else {
} }
if (readIndex >= 4) break; if (readIndex >= 4) break;
...@@ -640,50 +614,54 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in ...@@ -640,50 +614,54 @@ int32_t taosReadProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, in
taosCloseFile(&pFile); taosCloseFile(&pFile);
if (readIndex < 4) { if (readIndex < 4) {
// printf("read file:%s failed", tsProcIOFile);
return -1; return -1;
} }
return 0; return 0;
} }
int32_t taosGetProcIOSpeed(float *readKB, float *writeKB, float *readDiskKB, float *writeDiskKB) { int32_t taosGetIOSpeed(double *rchar_per_sec, double *wchar_per_sec, double *read_bytes_per_sec,
static int64_t lastRchar = -1; double *write_bytes_per_sec) {
static int64_t lastWchar = -1; static int64_t last_rchar = -1;
static int64_t lastRbyte = -1; static int64_t last_wchar = -1;
static int64_t lastWbyte = -1; static int64_t last_read_bytes = -1;
static int64_t last_write_bytes = -1;
static int64_t last_time = 0;
int64_t curRchar = 0; int64_t cur_rchar = 0;
int64_t curWchar = 0; int64_t cur_wchar = 0;
int64_t curRbyte = 0; int64_t cur_read_bytes = 0;
int64_t curWbyte = 0; int64_t cur_write_bytes = 0;
int64_t cur_time = taosGetTimestampMs();
if (taosReadProcIO(&curRchar, &curWchar, &curRbyte, &curWbyte) != 0) { if (taosReadProcIO(&cur_rchar, &cur_wchar, &cur_read_bytes, &cur_write_bytes) != 0) {
return -1; return -1;
} }
if (lastRchar == -1 || lastWchar == -1 || lastRbyte == -1 || lastWbyte == -1) { if (last_time == 0 || last_time >= cur_time) {
lastRchar = curRchar; last_time = cur_time;
lastWchar = curWchar; last_rchar = cur_rchar;
lastRbyte = curRbyte; last_wchar = cur_wchar;
lastWbyte = curWbyte; last_read_bytes = cur_read_bytes;
last_write_bytes = cur_write_bytes;
return -1; return -1;
} }
*readKB = (curRchar - lastRchar) / 1024.0f; *rchar_per_sec = (cur_rchar - last_rchar) / (double)(cur_time - last_time) * 1000;
*writeKB = (curWchar - lastWchar) / 1024.0f; *wchar_per_sec = (cur_wchar - last_wchar) / (double)(cur_time - last_time) * 1000;
*readDiskKB = (curRbyte - lastRbyte) / 1024.0f; *read_bytes_per_sec = (cur_read_bytes - last_read_bytes) / (double)(cur_time - last_time) * 1000;
*writeDiskKB = (curWbyte - lastWbyte) / 1024.0f; *write_bytes_per_sec = (cur_write_bytes - last_write_bytes) / (double)(cur_time - last_time) * 1000;
if (*readKB < 0) *readKB = 0; last_time = cur_time;
if (*writeKB < 0) *writeKB = 0; last_rchar = cur_rchar;
if (*readDiskKB < 0) *readDiskKB = 0; last_wchar = cur_wchar;
if (*writeDiskKB < 0) *writeDiskKB = 0; last_read_bytes = cur_read_bytes;
last_write_bytes = cur_write_bytes;
lastRchar = curRchar; if (*rchar_per_sec < 0) *rchar_per_sec = 0;
lastWchar = curWchar; if (*wchar_per_sec < 0) *wchar_per_sec = 0;
lastRbyte = curRbyte; if (*read_bytes_per_sec < 0) *read_bytes_per_sec = 0;
lastWbyte = curWbyte; if (*write_bytes_per_sec < 0) *write_bytes_per_sec = 0;
return 0; return 0;
} }
...@@ -693,10 +671,10 @@ void taosGetSystemInfo() { ...@@ -693,10 +671,10 @@ void taosGetSystemInfo() {
taosGetCpuCores(&tsNumOfCores); taosGetCpuCores(&tsNumOfCores);
taosGetTotalMemory(&tsTotalMemoryKB); taosGetTotalMemory(&tsTotalMemoryKB);
float tmp1, tmp2, tmp3, tmp4; double tmp1, tmp2, tmp3, tmp4;
taosGetBandSpeed(&tmp1); taosGetBandSpeed(&tmp1, &tmp2);
taosGetCpuUsage(&tmp1, &tmp2); taosGetCpuUsage(&tmp1, &tmp2);
taosGetProcIOSpeed(&tmp1, &tmp2, &tmp3, &tmp4); taosGetIOSpeed(&tmp1, &tmp2, &tmp3, &tmp4);
} }
void taosKillSystem() { void taosKillSystem() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册