Commit 54ce570a authored by charisu's avatar charisu Committed by lixiaocui1
Browse files

namespace功能优化及增加查询chunk位置功能,http://jira.netease.com/browse/CLDCFS-1895,http://...

namespace功能优化及增加查询chunk位置功能,http://jira.netease.com/browse/CLDCFS-1895,http://jira.netease.com/browse/CLDCFS-1896

Change-Id: I51196f2f1e9b284ad96693d0dbe4631c839fd31b
parent 7911056e
Showing with 526 additions and 181 deletions
+526 -181
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <stdint.h> #include <stdint.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <string>
#include <vector> #include <vector>
namespace curve { namespace curve {
...@@ -34,6 +35,16 @@ class TimeUtility { ...@@ -34,6 +35,16 @@ class TimeUtility {
gettimeofday(&tm, NULL); gettimeofday(&tm, NULL);
return tm.tv_sec; return tm.tv_sec;
} }
// 时间戳转成标准时间输出在standard里面,时间戳单位为秒
static inline void TimeStampToStandard(time_t timeStamp,
std::string* standard) {
char now[64];
struct tm p;
p = *localtime_r(&timeStamp, &p);
strftime(now, 64, "%Y-%m-%d %H:%M:%S", &p);
*standard = std::string(now);
}
}; };
} // namespace common } // namespace common
......
...@@ -162,6 +162,7 @@ cc_library( ...@@ -162,6 +162,7 @@ cc_library(
"//external:gflags", "//external:gflags",
"//external:protobuf", "//external:protobuf",
"//proto:nameserver2_cc_proto", "//proto:nameserver2_cc_proto",
"//proto:topology_cc_proto",
"//src/common:curve_common", "//src/common:curve_common",
"//src/mds/common:mds_common", "//src/mds/common:mds_common",
"//src/mds/nameserver2:nameserver2", "//src/mds/nameserver2:nameserver2",
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include "src/tools/copyset_check.h" #include "src/tools/copyset_check.h"
DEFINE_string(mdsAddr, "127.0.0.1:6666", "mds addr");
DEFINE_bool(detail, false, "list the copyset detail or not"); DEFINE_bool(detail, false, "list the copyset detail or not");
DEFINE_uint64(margin, 1000, "The threshold of the gap between peers"); DEFINE_uint64(margin, 1000, "The threshold of the gap between peers");
DEFINE_uint32(logicalPoolId, 0, "logical pool id of copyset"); DEFINE_uint32(logicalPoolId, 0, "logical pool id of copyset");
...@@ -21,13 +20,12 @@ DEFINE_uint64(retryTimes, 3, "rpc retry times"); ...@@ -21,13 +20,12 @@ DEFINE_uint64(retryTimes, 3, "rpc retry times");
namespace curve { namespace curve {
namespace tool { namespace tool {
int CopysetCheck::Init() { int CopysetCheck::Init(const std::string& mdsAddr) {
curve::common::SplitString(FLAGS_mdsAddr, ",", &mdsAddrVec_); curve::common::SplitString(mdsAddr, ",", &mdsAddrVec_);
if (mdsAddrVec_.empty()) { if (mdsAddrVec_.empty()) {
std::cout << "Split mds address fail!" << std::endl; std::cout << "Split mds address fail!" << std::endl;
return -1; return -1;
} }
channelToMds_ = new (std::nothrow) brpc::Channel();
for (const auto& mdsAddr : mdsAddrVec_) { for (const auto& mdsAddr : mdsAddrVec_) {
if (channelToMds_->Init(mdsAddr.c_str(), nullptr) != 0) { if (channelToMds_->Init(mdsAddr.c_str(), nullptr) != 0) {
std::cout << "Init channel to " << mdsAddr << "fail!" << std::endl; std::cout << "Init channel to " << mdsAddr << "fail!" << std::endl;
...@@ -48,6 +46,10 @@ int CopysetCheck::Init() { ...@@ -48,6 +46,10 @@ int CopysetCheck::Init() {
return -1; return -1;
} }
CopysetCheck::CopysetCheck() {
channelToMds_ = new (std::nothrow) brpc::Channel();
}
CopysetCheck::~CopysetCheck() { CopysetCheck::~CopysetCheck() {
delete channelToMds_; delete channelToMds_;
channelToMds_ = nullptr; channelToMds_ = nullptr;
......
...@@ -46,7 +46,7 @@ enum class CheckResult { ...@@ -46,7 +46,7 @@ enum class CheckResult {
class CopysetCheck { class CopysetCheck {
public: public:
CopysetCheck() {} CopysetCheck();
~CopysetCheck(); ~CopysetCheck();
/** /**
...@@ -67,10 +67,15 @@ class CopysetCheck { ...@@ -67,10 +67,15 @@ class CopysetCheck {
/** /**
* @brief 初始化channel * @brief 初始化channel
* @param * @param mdsAddr mds的地址,支持多地址,用","分隔
* @return 无 * @return 无
*/ */
int Init(); int Init(const std::string& mdsAddr);
/**
* @brief 释放资源
*/
void UnInit(const std::string& mdsAddr);
private: private:
/** /**
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
DEFINE_string(mds_config_path, "conf/mds.conf", "mds confPath"); DEFINE_string(mds_config_path, "conf/mds.conf", "mds confPath");
DEFINE_bool(example, false, "print the example of usage"); DEFINE_bool(example, false, "print the example of usage");
DEFINE_string(mdsAddr, "127.0.0.1:6666", "mds addr");
int main(int argc, char** argv) { int main(int argc, char** argv) {
std::string help_str = "Usage: curve_ops_tool [Command] [OPTIONS...]\n" std::string help_str = "Usage: curve_ops_tool [Command] [OPTIONS...]\n"
...@@ -27,6 +28,7 @@ int main(int argc, char** argv) { ...@@ -27,6 +28,7 @@ int main(int argc, char** argv) {
"delete : delete the file, to force delete, should specify the --forcedelete=true\n" //NOLINT "delete : delete the file, to force delete, should specify the --forcedelete=true\n" //NOLINT
"clean-recycle : clean the RecycleBin\n" "clean-recycle : clean the RecycleBin\n"
"create : create file\n" "create : create file\n"
"chunk-location : query the location of the chunk corresponding to the offset\n" //NOLINT
"check-consistency : check the consistency of three copies\n" "check-consistency : check the consistency of three copies\n"
"add_peer : add the peer to the copyset\n" "add_peer : add the peer to the copyset\n"
"remove_peer : remove the peer from the copyset\n" "remove_peer : remove the peer from the copyset\n"
...@@ -67,14 +69,15 @@ int main(int argc, char** argv) { ...@@ -67,14 +69,15 @@ int main(int argc, char** argv) {
|| command == "seginfo" || command == "seginfo"
|| command == "delete" || command == "delete"
|| command == "clean-recycle" || command == "clean-recycle"
|| command == "create") { || command == "create"
|| command == "chunk-location") {
// 使用namespaceTool // 使用namespaceTool
curve::tool::NameSpaceTool namespaceTool; curve::tool::NameSpaceTool namespaceTool;
if (FLAGS_example) { if (FLAGS_example) {
namespaceTool.PrintHelp(command); namespaceTool.PrintHelp(command);
return 0; return 0;
} }
if (namespaceTool.Init() != 0) { if (namespaceTool.Init(FLAGS_mdsAddr) != 0) {
std::cout << "Init failed!" << std::endl; std::cout << "Init failed!" << std::endl;
return -1; return -1;
} }
...@@ -116,7 +119,7 @@ int main(int argc, char** argv) { ...@@ -116,7 +119,7 @@ int main(int argc, char** argv) {
copysetCheck.PrintHelp(command); copysetCheck.PrintHelp(command);
return 0; return 0;
} }
if (copysetCheck.Init() != 0) { if (copysetCheck.Init(FLAGS_mdsAddr) != 0) {
std::cout << "Init failed!" << std::endl; std::cout << "Init failed!" << std::endl;
return -1; return -1;
} }
......
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
*/ */
#include "src/tools/namespace_tool.h" #include "src/tools/namespace_tool.h"
DEFINE_string(mds_addr, "127.0.0.1:6666", "mds addr");
DEFINE_string(fileName, "", "file name"); DEFINE_string(fileName, "", "file name");
DEFINE_string(userName, "root", "owner of the file"); DEFINE_string(userName, "root", "owner of the file");
DEFINE_string(password, "root_password", "password of administrator"); DEFINE_string(password, "root_password", "password of administrator");
DEFINE_bool(forcedelete, false, "force delete file or not"); DEFINE_bool(forcedelete, false, "force delete file or not");
DEFINE_uint64(fileLength, 20*1024*1024*1024ull, "file length"); DEFINE_uint64(fileLength, 20*1024*1024*1024ull, "file length");
DEFINE_bool(isTest, false, "is unit test or not"); DEFINE_bool(isTest, false, "is unit test or not");
DEFINE_uint64(offset, 0, "offset to query chunk location");
namespace curve { namespace curve {
namespace tool { namespace tool {
...@@ -56,6 +56,8 @@ int NameSpaceTool::RunCommand(const std::string &cmd) { ...@@ -56,6 +56,8 @@ int NameSpaceTool::RunCommand(const std::string &cmd) {
} }
} else if (cmd == "create") { } else if (cmd == "create") {
return CreateFile(FLAGS_fileName); return CreateFile(FLAGS_fileName);
} else if (cmd == "chunk-location") {
return QueryChunkLocation(FLAGS_fileName, FLAGS_offset);
} else { } else {
std::cout << "Command not support!" << std::endl; std::cout << "Command not support!" << std::endl;
PrintHelp("get"); PrintHelp("get");
...@@ -64,19 +66,20 @@ int NameSpaceTool::RunCommand(const std::string &cmd) { ...@@ -64,19 +66,20 @@ int NameSpaceTool::RunCommand(const std::string &cmd) {
PrintHelp("delete"); PrintHelp("delete");
PrintHelp("clean-recycle"); PrintHelp("clean-recycle");
PrintHelp("create"); PrintHelp("create");
PrintHelp("chunk-location");
return -1; return -1;
} }
} }
int NameSpaceTool::Init() { int NameSpaceTool::Init(const std::string& mdsAddr) {
// 初始化channel // 初始化channel
curve::common::SplitString(FLAGS_mds_addr, ",", &mdsAddrVec_); std::vector<std::string> mdsAddrVec;
if (mdsAddrVec_.empty()) { curve::common::SplitString(mdsAddr, ",", &mdsAddrVec);
if (mdsAddrVec.empty()) {
std::cout << "Split mds address fail!" << std::endl; std::cout << "Split mds address fail!" << std::endl;
return -1; return -1;
} }
channel_ = new (std::nothrow) brpc::Channel(); for (const auto& mdsAddr : mdsAddrVec) {
for (const auto& mdsAddr : mdsAddrVec_) {
if (channel_->Init(mdsAddr.c_str(), nullptr) != 0) { if (channel_->Init(mdsAddr.c_str(), nullptr) != 0) {
continue; continue;
} }
...@@ -100,6 +103,10 @@ int NameSpaceTool::Init() { ...@@ -100,6 +103,10 @@ int NameSpaceTool::Init() {
return -1; return -1;
} }
NameSpaceTool::NameSpaceTool() {
channel_ = new (std::nothrow) brpc::Channel();
}
NameSpaceTool::~NameSpaceTool() { NameSpaceTool::~NameSpaceTool() {
delete channel_; delete channel_;
channel_ = nullptr; channel_ = nullptr;
...@@ -108,13 +115,16 @@ NameSpaceTool::~NameSpaceTool() { ...@@ -108,13 +115,16 @@ NameSpaceTool::~NameSpaceTool() {
void NameSpaceTool::PrintHelp(const std::string &cmd) { void NameSpaceTool::PrintHelp(const std::string &cmd) {
std::cout << "Example: " << std::endl; std::cout << "Example: " << std::endl;
if (cmd == "get" || cmd == "list" || cmd == "seginfo") { if (cmd == "get" || cmd == "list" || cmd == "seginfo") {
std::cout << "curve_ops_tool " << cmd << " -mds_addr=127.0.0.1:6666 -fileName=/test" << std::endl; // NOLINT std::cout << "curve_ops_tool " << cmd << " -mdsAddr=127.0.0.1:6666 -fileName=/test" << std::endl; // NOLINT
} else if (cmd == "clean-recycle") { } else if (cmd == "clean-recycle") {
std::cout << "curve_ops_tool " << cmd << " -mds_addr=127.0.0.1:6666" << std::endl; // NOLINT std::cout << "curve_ops_tool " << cmd << " -mdsAddr=127.0.0.1:6666 [-fileName=/cinder]" << std::endl; // NOLINT
std::cout << "If -fileName is specified, delete the files in recyclebin that the original directory is fileName" << std::endl; // NOLINT
} else if (cmd == "create") { } else if (cmd == "create") {
std::cout << "curve_ops_tool " << cmd << " -mds_addr=127.0.0.1:6666 -fileName=/test -userName=test -password=123 -fileLength=21474836480" << std::endl; // NOLINT std::cout << "curve_ops_tool " << cmd << " -mdsAddr=127.0.0.1:6666 -fileName=/test -userName=test -password=123 -fileLength=21474836480" << std::endl; // NOLINT
} else if (cmd == "delete") { } else if (cmd == "delete") {
std::cout << "curve_ops_tool " << cmd << " -mds_addr=127.0.0.1:6666 -fileName=/test -userName=test -password=123 -forcedelete=true" << std::endl; // NOLINT std::cout << "curve_ops_tool " << cmd << " -mdsAddr=127.0.0.1:6666 -fileName=/test -userName=test -password=123 -forcedelete=true" << std::endl; // NOLINT
} else if (cmd == "chunk-location") {
std::cout << "curve_ops_tool " << cmd << " -mdsAddr=127.0.0.1:6666 -fileName=/test -offset=16777216" << std::endl; // NOLINT
} else { } else {
std::cout << "command not found!" << std::endl; std::cout << "command not found!" << std::endl;
} }
...@@ -131,7 +141,7 @@ int NameSpaceTool::PrintFileInfoAndActualSize(std::string fileName) { ...@@ -131,7 +141,7 @@ int NameSpaceTool::PrintFileInfoAndActualSize(std::string fileName) {
return -1; return -1;
} }
std::cout << "File info:" << std::endl; std::cout << "File info:" << std::endl;
std::cout << fileInfo.DebugString(); PrintFileInfo(fileInfo);
fileInfo.set_originalfullpathname(fileName); fileInfo.set_originalfullpathname(fileName);
int64_t size = GetActualSize(fileInfo); int64_t size = GetActualSize(fileInfo);
if (size < 0) { if (size < 0) {
...@@ -143,6 +153,23 @@ int NameSpaceTool::PrintFileInfoAndActualSize(std::string fileName) { ...@@ -143,6 +153,23 @@ int NameSpaceTool::PrintFileInfoAndActualSize(std::string fileName) {
return 0; return 0;
} }
void NameSpaceTool::PrintFileInfo(const FileInfo& fileInfo) {
std::string fileInfoStr = fileInfo.DebugString();
std::vector<std::string> items;
curve::common::SplitString(fileInfoStr, "\n", &items);
for (const auto& item : items) {
if (item.compare(0, 5, "ctime") == 0) {
// ctime是微妙,打印的时候只打印到秒
time_t ctime = fileInfo.ctime() / 1000000;
std::string standard;
curve::common::TimeUtility::TimeStampToStandard(ctime, &standard);
std::cout << "ctime: " << standard << std::endl;
continue;
}
std::cout << item << std::endl;
}
}
int NameSpaceTool::GetFileInfo(const std::string &fileName, int NameSpaceTool::GetFileInfo(const std::string &fileName,
FileInfo* fileInfo) { FileInfo* fileInfo) {
curve::mds::GetFileInfoRequest request; curve::mds::GetFileInfoRequest request;
...@@ -180,7 +207,7 @@ int64_t NameSpaceTool::GetActualSize(const FileInfo& fileInfo) { ...@@ -180,7 +207,7 @@ int64_t NameSpaceTool::GetActualSize(const FileInfo& fileInfo) {
// 如果是文件的话,直接获取segment信息,然后计算空间即可 // 如果是文件的话,直接获取segment信息,然后计算空间即可
if (fileInfo.filetype() != curve::mds::FileType::INODE_DIRECTORY) { if (fileInfo.filetype() != curve::mds::FileType::INODE_DIRECTORY) {
std::vector<PageFileSegment> segments; std::vector<PageFileSegment> segments;
if (GetSegmentInfo(fileInfo, &segments) != 0) { if (GetFileSegments(fileInfo, &segments) != 0) {
std::cout << "Get segment info fail, parent id: " std::cout << "Get segment info fail, parent id: "
<< fileInfo.parentid() << fileInfo.parentid()
<< " filename: " << fileInfo.filename() << " filename: " << fileInfo.filename()
...@@ -234,7 +261,7 @@ int NameSpaceTool::PrintListDir(std::string dirName) { ...@@ -234,7 +261,7 @@ int NameSpaceTool::PrintListDir(std::string dirName) {
if (i != 0) { if (i != 0) {
std::cout << std::endl; std::cout << std::endl;
} }
std::cout << files[i].DebugString(); PrintFileInfo(files[i]);
if (dirName == "/") { if (dirName == "/") {
files[i].set_originalfullpathname(dirName + files[i].filename()); files[i].set_originalfullpathname(dirName + files[i].filename());
} else { } else {
...@@ -296,21 +323,49 @@ int NameSpaceTool::PrintSegmentInfo(const std::string &fileName) { ...@@ -296,21 +323,49 @@ int NameSpaceTool::PrintSegmentInfo(const std::string &fileName) {
} }
fileInfo.set_originalfullpathname(fileName); fileInfo.set_originalfullpathname(fileName);
std::vector<PageFileSegment> segments; std::vector<PageFileSegment> segments;
if (GetSegmentInfo(fileInfo, &segments) != 0) { if (GetFileSegments(fileInfo, &segments) != 0) {
std::cout << "Get segment info fail!" << std::endl; std::cout << "Get segment info fail!" << std::endl;
return -1; return -1;
} }
for (auto& segment : segments) { for (auto& segment : segments) {
std::cout << segment.DebugString() << std::endl; PrintSegment(segment);
} }
return 0; return 0;
} }
int NameSpaceTool::GetSegmentInfo(const FileInfo &fileInfo, void NameSpaceTool::PrintSegment(const PageFileSegment& segment) {
if (segment.has_logicalpoolid()) {
std::cout << "logicalPoolID: " << segment.logicalpoolid() << std::endl;
}
if (segment.has_startoffset()) {
std::cout << "startOffset: " << segment.startoffset() << std::endl;
}
if (segment.has_segmentsize()) {
std::cout << "segmentSize: " << segment.segmentsize() << std::endl;
}
if (segment.has_chunksize()) {
std::cout << "chunkSize: " << segment.chunksize() << std::endl;
}
std::cout << "chunks: " << std::endl;
for (int i = 0; i < segment.chunks_size(); ++i) {
uint64_t chunkId = 0;
uint32_t copysetId = 0;
if (segment.chunks(i).has_chunkid()) {
chunkId = segment.chunks(i).chunkid();
}
if (segment.chunks(i).has_copysetid()) {
copysetId = segment.chunks(i).copysetid();
}
std::cout << "chunkID: " << chunkId << ", copysetID: "
<< copysetId << std::endl;
}
}
int NameSpaceTool::GetFileSegments(const FileInfo &fileInfo,
std::vector<PageFileSegment>* segments) { std::vector<PageFileSegment>* segments) {
// 如果是目录,不能计算segmentsize // 只能获取page file的segment
if (fileInfo.filetype() == curve::mds::FileType::INODE_DIRECTORY) { if (fileInfo.filetype() != curve::mds::FileType::INODE_PAGEFILE) {
std::cout << "It is a directory!" << std::endl; std::cout << "It is not a page file!" << std::endl;
return -1; return -1;
} }
...@@ -318,43 +373,59 @@ int NameSpaceTool::GetSegmentInfo(const FileInfo &fileInfo, ...@@ -318,43 +373,59 @@ int NameSpaceTool::GetSegmentInfo(const FileInfo &fileInfo,
int segmentNum = fileInfo.length() / fileInfo.segmentsize(); int segmentNum = fileInfo.length() / fileInfo.segmentsize();
uint64_t segmentSize = fileInfo.segmentsize(); uint64_t segmentSize = fileInfo.segmentsize();
std::string fileName = fileInfo.originalfullpathname(); std::string fileName = fileInfo.originalfullpathname();
for (int i = 0; i != segmentNum; i++) { for (uint64_t i = 0; i < segmentNum; i++) {
// load segment // load segment
curve::mds::GetOrAllocateSegmentRequest request; PageFileSegment segment;
curve::mds::GetOrAllocateSegmentResponse response; GetSegmentRes res = GetSegmentInfo(fileName,
brpc::Controller cntl; i * segmentSize, &segment);
cntl.set_timeout_ms(3000); if (res == GetSegmentRes::kOK) {
request.set_filename(fileName); segments->emplace_back(segment);
request.set_offset(i*segmentSize); } else if (res == GetSegmentRes::kSegmentNotAllocated) {
request.set_allocateifnotexist(false); continue;
FillUserInfo(&request); } else {
std::cout << "Get segment info from mds fail!" << std::endl;
curve::mds::CurveFSService_Stub stub(channel_);
stub.GetOrAllocateSegment(&cntl, &request, &response, NULL);
if (cntl.Failed()) {
std::cout<< "Get segment info fail, errCde = "
<< response.statuscode()
<< ", error content:"
<< cntl.ErrorText() << std::endl;
return -1; return -1;
} }
}
return 0;
}
if (response.has_statuscode()) { GetSegmentRes NameSpaceTool::GetSegmentInfo(std::string fileName,
if (response.statuscode() == StatusCode::kOK) { uint64_t offset,
segments->push_back(response.pagefilesegment()); PageFileSegment* segment) {
} else if (response.statuscode() == curve::mds::GetOrAllocateSegmentRequest request;
StatusCode::kSegmentNotAllocated) { curve::mds::GetOrAllocateSegmentResponse response;
continue; brpc::Controller cntl;
} else { cntl.set_timeout_ms(3000);
std::cout << "Get segment info fail, offset: " request.set_filename(fileName);
<< i*segmentSize << " errCode:" request.set_offset(offset);
request.set_allocateifnotexist(false);
FillUserInfo(&request);
curve::mds::CurveFSService_Stub stub(channel_);
stub.GetOrAllocateSegment(&cntl, &request, &response, NULL);
if (cntl.Failed()) {
std::cout << "Get segment info fail, errCde = "
<< response.statuscode()
<< ", error content:"
<< cntl.ErrorText() << std::endl;
return GetSegmentRes::kOtherError;
}
if (response.has_statuscode()) {
if (response.statuscode() == StatusCode::kOK) {
*segment = response.pagefilesegment();
} else if (response.statuscode() ==
StatusCode::kSegmentNotAllocated) {
return GetSegmentRes::kSegmentNotAllocated;
} else {
std::cout << "Get segment info fail, offset: "
<< offset << " errCode:"
<< response.statuscode() << std::endl; << response.statuscode() << std::endl;
return -1; return GetSegmentRes::kOtherError;;
}
} }
} }
return 0; return GetSegmentRes::kOK;
} }
int NameSpaceTool::DeleteFile(const std::string& fileName, bool forcedelete) { int NameSpaceTool::DeleteFile(const std::string& fileName, bool forcedelete) {
...@@ -398,6 +469,13 @@ int NameSpaceTool::CleanRecycleBin() { ...@@ -398,6 +469,13 @@ int NameSpaceTool::CleanRecycleBin() {
bool success = true; bool success = true;
for (const auto& fileInfo : files) { for (const auto& fileInfo : files) {
std::string fileName = "/RecycleBin/" + fileInfo.filename(); std::string fileName = "/RecycleBin/" + fileInfo.filename();
// 如果指定了-fileName,就只删除原来在这个目录下的文件
if (!FLAGS_fileName.empty()) {
std::string originPath = fileInfo.originalfullpathname();
if (originPath.find(FLAGS_fileName) != 0) {
continue;
}
}
if (DeleteFile(fileName, true) != 0) { if (DeleteFile(fileName, true) != 0) {
success = false; success = false;
} }
...@@ -442,6 +520,88 @@ int NameSpaceTool::CreateFile(const std::string& fileName) { ...@@ -442,6 +520,88 @@ int NameSpaceTool::CreateFile(const std::string& fileName) {
return -1; return -1;
} }
int NameSpaceTool::QueryChunkLocation(const std::string& fileName,
uint64_t offset) {
FileInfo fileInfo;
int ret = GetFileInfo(fileName, &fileInfo);
if (ret != 0) {
std::cout << "Get file info failed!" << std::endl;
return -1;
}
if (fileInfo.filetype() != curve::mds::FileType::INODE_PAGEFILE) {
std::cout << "It is not a page file!" << std::endl;
return -1;
}
uint64_t segmentSize = fileInfo.segmentsize();
// segment对齐的offset
uint64_t segOffset = (offset / segmentSize) * segmentSize;
PageFileSegment segment;
GetSegmentRes res = GetSegmentInfo(fileName, segOffset, &segment);
if (res != GetSegmentRes::kOK) {
if (res == GetSegmentRes::kSegmentNotAllocated) {
std::cout << "Chunk has not been allocated!" << std::endl;
return -1;
} else {
std::cout << "Get segment info from mds fail!" << std::endl;
return -1;
}
}
// 在segment里面的chunk的索引
uint64_t chunkIndex = (offset - segOffset) / segment.chunksize();
if (chunkIndex >= segment.chunks_size()) {
std::cout << "ChunkIndex exceed chunks num in segment!" << std::endl;
return -1;
}
PageFileChunkInfo chunk = segment.chunks(chunkIndex);
uint64_t chunkId = chunk.chunkid();
uint32_t logicPoolId = segment.logicalpoolid();
uint32_t copysetId = chunk.copysetid();
uint64_t groupId = (static_cast<uint64_t>(logicPoolId) << 32) | copysetId;
std::cout << "chunkId: " << chunkId
<< ", logicalPoolId: " << logicPoolId
<< ", copysetId: " << copysetId
<< ", groupId: " << groupId << std::endl;
return PrintCopysetMembers(segment.logicalpoolid(), copysetId);
}
int NameSpaceTool::PrintCopysetMembers(uint32_t logicalPoolId,
uint32_t copysetId) {
curve::mds::topology::GetChunkServerListInCopySetsRequest request;
curve::mds::topology::GetChunkServerListInCopySetsResponse response;
brpc::Controller cntl;
cntl.set_timeout_ms(3000);
request.set_logicalpoolid(logicalPoolId);
request.add_copysetid(copysetId);
curve::mds::topology::TopologyService_Stub topo_stub(channel_);
topo_stub.GetChunkServerListInCopySets(&cntl,
&request, &response, nullptr);
if (cntl.Failed()) {
std::cout << "GetChunkServerListInCopySets fail, errCode = "
<< response.statuscode()
<< ", error content:"
<< cntl.ErrorText() << std::endl;
return -1;
}
if (response.has_statuscode()) {
if (response.statuscode() != kTopoErrCodeSuccess) {
std::cout << "GetChunkServerListInCopySets fail, errCode: "
<< response.statuscode() << std::endl;
return -1;
}
}
std::cout << "location: {";
for (int i = 0; i < response.csinfo(0).cslocs_size(); ++i) {
if (i != 0) {
std::cout << ", ";
}
auto location = response.csinfo(0).cslocs(i);
std::cout << location.hostip() << ":"
<< std::to_string(location.port());
}
std::cout << "}" << std::endl;
return 0;
}
template <class T> template <class T>
void NameSpaceTool::FillUserInfo(T* request) { void NameSpaceTool::FillUserInfo(T* request) {
uint64_t date = curve::common::TimeUtility::GetTimeofDayUs(); uint64_t date = curve::common::TimeUtility::GetTimeofDayUs();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <brpc/channel.h> #include <brpc/channel.h>
#include <time.h>
#include <vector> #include <vector>
#include <string> #include <string>
...@@ -19,28 +20,39 @@ ...@@ -19,28 +20,39 @@
#include <cstring> #include <cstring>
#include "proto/nameserver2.pb.h" #include "proto/nameserver2.pb.h"
#include "proto/topology.pb.h"
#include "src/common/timeutility.h" #include "src/common/timeutility.h"
#include "src/common/authenticator.h" #include "src/common/authenticator.h"
#include "src/common/string_util.h" #include "src/common/string_util.h"
#include "src/mds/common/mds_define.h"
using curve::mds::FileInfo; using curve::mds::FileInfo;
using curve::mds::PageFileSegment; using curve::mds::PageFileSegment;
using curve::mds::StatusCode; using curve::mds::StatusCode;
using curve::mds::PageFileChunkInfo;
using curve::mds::topology::kTopoErrCodeSuccess;
using curve::common::Authenticator; using curve::common::Authenticator;
namespace curve { namespace curve {
namespace tool { namespace tool {
enum class GetSegmentRes {
kOK = 0, // 获取segment成功
kSegmentNotAllocated = -1, // segment不存在
kOtherError = -2 // 其他错误
};
class NameSpaceTool { class NameSpaceTool {
public: public:
NameSpaceTool() {} NameSpaceTool();
~NameSpaceTool(); ~NameSpaceTool();
/** /**
* @brief 初始化channel * @brief 初始化channel
* @param * @param mdsAddr mds的地址,支持多地址,用","分隔
* @return 无 * @return 无
*/ */
int Init(); int Init(const std::string& mdsAddr);
/** /**
* @brief 打印用法 * @brief 打印用法
...@@ -77,8 +89,13 @@ class NameSpaceTool { ...@@ -77,8 +89,13 @@ class NameSpaceTool {
int PrintSegmentInfo(const std::string &fileName); int PrintSegmentInfo(const std::string &fileName);
// 获取文件的segment信息并输出到segments里面 // 获取文件的segment信息并输出到segments里面
int GetSegmentInfo(const FileInfo &fileInfo, int GetFileSegments(const FileInfo &fileInfo,
std::vector<PageFileSegment>* segments); std::vector<PageFileSegment>* segments);
// 获取指定偏移的segment放到segment里面
GetSegmentRes GetSegmentInfo(std::string fileName,
uint64_t offset,
PageFileSegment* segment);
// 删除文件 // 删除文件
int DeleteFile(const std::string& fileName, bool forcedelete); int DeleteFile(const std::string& fileName, bool forcedelete);
...@@ -89,15 +106,25 @@ class NameSpaceTool { ...@@ -89,15 +106,25 @@ class NameSpaceTool {
// 创建文件 // 创建文件
int CreateFile(const std::string& fileName); int CreateFile(const std::string& fileName);
// 根据文件名和offset查询chunk位置
int QueryChunkLocation(const std::string& fileName, uint64_t offset);
// 填充signature // 填充signature
template <class T> template <class T>
void FillUserInfo(T* request); void FillUserInfo(T* request);
// 打印fileInfo,把时间转化为易读的格式输出
void PrintFileInfo(const FileInfo& fileInfo);
// 打印PageFileSegment,把同一个chunk的信息打在同一行
void PrintSegment(const PageFileSegment& segment);
// 打印copyset里面的chunkserver
int PrintCopysetMembers(uint32_t logicalPoolId,
uint32_t copysetId);
// 向mds发送RPC的channel // 向mds发送RPC的channel
brpc::Channel* channel_; brpc::Channel* channel_;
// mds的地址
std::vector<std::string> mdsAddrVec_;
}; };
} // namespace tool } // namespace tool
} // namespace curve } // namespace curve
......
...@@ -24,9 +24,9 @@ using curve::mds::topology::GetChunkServerInfoResponse; ...@@ -24,9 +24,9 @@ using curve::mds::topology::GetChunkServerInfoResponse;
std::string metaserver_addr = "127.0.0.1:9170"; // NOLINT std::string metaserver_addr = "127.0.0.1:9170"; // NOLINT
uint32_t chunk_size = 4*1024*1024; // NOLINT uint32_t chunk_size = 4*1024*1024; // NOLINT
uint32_t segment_size = 1*1024*1024*1024; // NOLINT uint32_t segment_size = 1*1024*1024*1024; // NOLINT
std::string mdsAddr = "127.0.0.1:9999,127.0.0.1:9170"; // NOLINT
DECLARE_string(chunkserver_list); DECLARE_string(chunkserver_list);
DECLARE_string(mdsAddr);
DECLARE_uint32(logicalPoolId); DECLARE_uint32(logicalPoolId);
DECLARE_uint32(copysetId); DECLARE_uint32(copysetId);
DECLARE_uint32(chunkserverId); DECLARE_uint32(chunkserverId);
...@@ -39,7 +39,6 @@ class CopysetCheckTest : public ::testing::Test { ...@@ -39,7 +39,6 @@ class CopysetCheckTest : public ::testing::Test {
protected: protected:
CopysetCheckTest() : fakemds("test") {} CopysetCheckTest() : fakemds("test") {}
void SetUp() { void SetUp() {
FLAGS_mdsAddr = "127.0.0.1:9999,127.0.0.1:9170";
FLAGS_chunkserver_list = FLAGS_chunkserver_list =
"127.0.0.1:9191:0,127.0.0.1:9192:0,127.0.0.1:9193:0"; "127.0.0.1:9191:0,127.0.0.1:9192:0,127.0.0.1:9193:0";
FLAGS_detail = true; FLAGS_detail = true;
...@@ -167,7 +166,9 @@ TEST_F(CopysetCheckTest, testCheckOneCopyset) { ...@@ -167,7 +166,9 @@ TEST_F(CopysetCheckTest, testCheckOneCopyset) {
std::unique_ptr<FakeReturn> fakelistpoolret( std::unique_ptr<FakeReturn> fakelistpoolret(
new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get()))); new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get())));
topology->fakelistpoolret_ = fakelistpoolret.get(); topology->fakelistpoolret_ = fakelistpoolret.get();
ASSERT_EQ(0, copysetCheck.Init()); ASSERT_EQ(-1, copysetCheck.Init(""));
ASSERT_EQ(-1, copysetCheck.Init("127.0.0.1:9999"));
ASSERT_EQ(0, copysetCheck.Init(mdsAddr));
// 没有指定逻辑池和copyset的话返回失败 // 没有指定逻辑池和copyset的话返回失败
ASSERT_EQ(-1, copysetCheck.RunCommand("check-copyset")); ASSERT_EQ(-1, copysetCheck.RunCommand("check-copyset"));
FLAGS_logicalPoolId = 2; FLAGS_logicalPoolId = 2;
...@@ -262,7 +263,7 @@ TEST_F(CopysetCheckTest, testCheckChunkserver) { ...@@ -262,7 +263,7 @@ TEST_F(CopysetCheckTest, testCheckChunkserver) {
new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get()))); new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get())));
topology->fakelistpoolret_ = fakelistpoolret.get(); topology->fakelistpoolret_ = fakelistpoolret.get();
curve::tool::CopysetCheck copysetCheck; curve::tool::CopysetCheck copysetCheck;
ASSERT_EQ(0, copysetCheck.Init()); ASSERT_EQ(0, copysetCheck.Init(mdsAddr));
// 没有指定chunkserver的话报错 // 没有指定chunkserver的话报错
ASSERT_EQ(-1, copysetCheck.RunCommand("check-chunkserver")); ASSERT_EQ(-1, copysetCheck.RunCommand("check-chunkserver"));
FLAGS_chunkserverId = 1; FLAGS_chunkserverId = 1;
...@@ -368,7 +369,7 @@ TEST_F(CopysetCheckTest, testCheckServer) { ...@@ -368,7 +369,7 @@ TEST_F(CopysetCheckTest, testCheckServer) {
new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get()))); new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get())));
topology->fakelistpoolret_ = fakelistpoolret.get(); topology->fakelistpoolret_ = fakelistpoolret.get();
curve::tool::CopysetCheck copysetCheck; curve::tool::CopysetCheck copysetCheck;
ASSERT_EQ(0, copysetCheck.Init()); ASSERT_EQ(0, copysetCheck.Init(mdsAddr));
ASSERT_EQ(-1, copysetCheck.RunCommand("check-chunkserver")); ASSERT_EQ(-1, copysetCheck.RunCommand("check-chunkserver"));
FLAGS_serverId = 1; FLAGS_serverId = 1;
copysetCheck.PrintHelp("check-chunkserver"); copysetCheck.PrintHelp("check-chunkserver");
...@@ -426,7 +427,7 @@ TEST_F(CopysetCheckTest, testCheckCluster) { ...@@ -426,7 +427,7 @@ TEST_F(CopysetCheckTest, testCheckCluster) {
new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get()))); new FakeReturn(nullptr, static_cast<void*>(listPoolResp.get())));
topology->fakelistpoolret_ = fakelistpoolret.get(); topology->fakelistpoolret_ = fakelistpoolret.get();
curve::tool::CopysetCheck copysetCheck; curve::tool::CopysetCheck copysetCheck;
ASSERT_EQ(0, copysetCheck.Init()); ASSERT_EQ(0, copysetCheck.Init(mdsAddr));
copysetCheck.PrintHelp("check-cluster"); copysetCheck.PrintHelp("check-cluster");
std::unique_ptr<brpc::Controller> cntl(new brpc::Controller()); std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
// 设置好IOBuf // 设置好IOBuf
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment