源码路径curve-release2.2\src\chunkserver
1. `trash.cpp`
2. `op_request.cpp`
3. `register.cpp`
4. `passive_getfn.cpp`
5. `scan_service.cpp`
在trash.cpp
文件中,定义了Trash
类,该类负责管理块服务器中的回收站功能,包括删除文件和目录、移动文件到回收站等。以下是对Trash
类中函数的代码注释分析:
// trash.cpp 文件包含了块服务器回收站功能的实现
// Trash 类定义,用于管理块服务器的回收站
namespace curve {
namespace chunkserver {
// Trash::Init 方法,用于初始化回收站
int Trash::Init(TrashOptions options) {
// 设置回收站路径
isStop_ = true; // 初始化时停止状态
if (curve::common::UriParser::ParseUri(options.trashPath, &trashPath_).empty()) {
// 解析回收站路径失败
LOG(ERROR) << "not support trash uri's protocol" << options.trashPath;
return -1; // 返回错误代码
}
if (trashPath_.empty()) {
LOG(ERROR) << "trash path is empty, please check!"; // 回收站路径为空
return -1; // 返回错误代码
}
expiredAfterSec_ = options.expiredAfterSec; // 设置文件过期时间
scanPeriodSec_ = options.scanPeriodSec; // 设置扫描周期
localFileSystem_ = options.localFileSystem; // 设置本地文件系统接口
chunkFilePool_ = options.chunkFilePool; // 设置块文件池接口
walPool_ = options.walPool; // 设置 WAL 文件池接口
chunkNum_.store(0); // 初始化块数量计数器
// 读取回收站目录下的所有目录
std::vector<std::string> files;
localFileSystem_->List(trashPath_, &files);
for (auto &file : files) {
// 遍历目录
if (!IsCopysetInTrash(file)) {
// 如果不是副本集目录,跳过
continue;
}
std::string copysetDir = trashPath_ + "/" + file; // 构建副本集目录路径
uint32_t chunkNum = CountChunkNumInCopyset(copysetDir); // 计算副本集中的块数量
chunkNum_.fetch_add(chunkNum); // 更新块数量计数器
}
LOG(INFO) << "Init trash success. Current num of chunks in trash: " << chunkNum_.load(); // 记录初始化成功的日志
return 0; // 初始化成功,返回 0
}
// Trash::Run 方法,用于启动回收站线程
int Trash::Run() {
if (isStop_.exchange(false)) {
// 如果回收站已经停止,则返回
return -1; // 返回错误代码
}
// 创建并启动回收站线程
recycleThread_ = Thread(&Trash::DeleteEligibleFileInTrashInterval, this);
LOG(INFO) << "Start trash thread ok."; // 记录启动成功的日志
return 0; // 启动成功,返回 0
}
// Trash::Fini 方法,用于停止回收站并清理资源
int Trash::Fini() {
if (!isStop_.exchange(true)) {
// 如果回收站正在运行,则停止
LOG(INFO) << "stop Trash..."; // 记录停止日志
sleeper_.interrupt(); // 打断等待
recycleThread_.join(); // 等待线程结束
}
LOG(INFO) << "stop trash ok."; // 记录停止成功的日志
return 0; // 清理成功,返回 0
}
// Trash::RecycleCopySet 方法,用于将副本集移动到回收站
int Trash::RecycleCopySet(const std::string &dirPath) {
// 检查回收站目录是否存在,如果不存在则创建
if (!localFileSystem_->DirExists(trashPath_)) {
LOG(INFO) << "Copyset recyler directory " << trashPath_
<< " does not exist, creating it"; // 记录创建目录的日志
if (0 != localFileSystem_->Mkdir(trashPath_)) {
// 创建目录
LOG(ERROR) << "Failed to create copyset recyler directory: " << trashPath_;
return -1; // 创建失败,返回错误代码
}
}
// 如果回收站已存在该目录,本次删除失败
std::string dst = trashPath_ + "/" + dirPath.substr(dirPath.find_last_of('/') + 1) + "."
+ std::to_string(std::time(nullptr)); // 构建目标路径
if (localFileSystem_->DirExists(dst)) {
// 检查目标路径是否存在
LOG(WARNING) << "recycle error: " << dst << " already exist in " << trashPath_;
return -1; // 已存在,返回错误代码
}
{
LockGuard lg(mtx_); // 加锁
if (0 != localFileSystem_->Rename(dirPath, dst)) {
// 重命名目录到回收站
LOG(ERROR) << "rename " << dirPath << " to " << dst << " error"; // 记录错误日志
return -1; // 重命名失败,返回错误代码
}
uint32_t chunkNum = CountChunkNumInCopyset(dst); // 计算副本集中的块数量
chunkNum_.fetch_add(chunkNum); // 更新块数量计数器
}
LOG(INFO) << "Recycle copyset success. Copyset path: " << dst << ", current num of chunks in trash: "
<< chunkNum_.load(); // 记录成功日志
return 0; // 移动成功,返回 0
}
// Trash::DeleteEligibleFileInTrashInterval 方法,用于定期扫描并删除过期文件
void Trash::DeleteEligibleFileInTrashInterval() {
while (sleeper_.wait_for(std::chrono::seconds(scanPeriodSec_))) {
// 等待扫描周期
DeleteEligibleFileInTrash(); // 删除过期文件
}
}
// Trash::DeleteEligibleFileInTrash 方法,用于扫描并删除过期文件
void Trash::DeleteEligibleFileInTrash() {
if (!localFileSystem_->DirExists(trashPath_)) {
// 如果回收站目录不存在,则返回
return;
}
// 读取回收站目录下的所有目录
std::vector<std::string> files;
if (0 != localFileSystem_->List(trashPath_, &files)) {
// 列出目录
LOG(ERROR) << "Trash failed list files in " << trashPath_; // 记录错误日志
return;
}
for (auto &file : files) {
// 遍历目录
if (!IsCopysetInTrash(file)) {
// 如果不是副本集目录,跳过
continue;
}
std::string copysetDir = trashPath_ + "/" + file; // 构建副本集目录路径
if (!NeedDelete(copysetDir)) {
// 如果不需要删除,跳过
continue;
}
if (!RecycleChunksAndWALInDir(copysetDir, file)) {
// 回收块文件和 WAL 文件
continue; // 回收失败,跳过
}
// 删除副本集目录
if (0 != localFileSystem_->Delete(copysetDir)) {
// 删除目录
LOG(ERROR) << "Trash fail to delete " << copysetDir; // 记录错误日志
return; // 删除失败,返回
}
}
}
// Trash::IsCopysetInTrash 方法,用于判断目录是否是副本集目录
bool Trash::IsCopysetInTrash(const std::string &dirName) {
// 合法的副本集目录格式为:池 ID.副本集 ID,例如:2860448220024
uint64_t groupId;
int n = dirName.