curve源码分析 chunkserver -----3

源码路径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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值