Skip to content

Commit

Permalink
mds/client: support discard
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-hanqing authored and ilixiaocui committed May 14, 2021
1 parent 8fb352b commit 5a4889d
Show file tree
Hide file tree
Showing 107 changed files with 3,817 additions and 326 deletions.
8 changes: 8 additions & 0 deletions conf/client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,11 @@ global.turnOffHealthCheck=true
### throttle config
#
throttle.enable=false

##### discard configurations #####
# enable/disable discard
discard.enable=true
# discard granularity
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
8 changes: 8 additions & 0 deletions conf/cs_client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,11 @@ global.metricDummyServerStartPort=9000
# session map文件,存储打开文件的filename到path的映射
#
global.sessionMapPath=./session_map.json

##### discard configurations #####
# enable/disable discard
discard.enable=false
# discard granularity
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
2 changes: 2 additions & 0 deletions conf/mds.conf
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ mds.segment.alloc.periodic.persistInterMs=10000
# 出错情况下的重试间隔,单位ms
mds.segment.alloc.retryInterMs=1000

mds.segment.discard.scanIntevalMs=5000


# leader竞选时会创建session, 单位是秒(go端代码的接口这个值的单位就是s)
# 该值和etcd集群election timeout相关.
Expand Down
8 changes: 8 additions & 0 deletions conf/py_client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,11 @@ global.metricDummyServerStartPort=10000
# session map文件,存储打开文件的filename到path的映射
#
global.sessionMapPath=./session_map.json

##### discard configurations #####
# enable/disable discard
discard.enable=false
# discard granularity
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
8 changes: 8 additions & 0 deletions conf/snap_client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,11 @@ global.metricDummyServerStartPort=9000
# session map文件,存储打开文件的filename到path的映射
#
global.sessionMapPath=./session_map.json

##### discard configurations #####
# enable/disable discard
discard.enable=false
# discard granularity
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
4 changes: 4 additions & 0 deletions curve-ansible/roles/generate_config/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mds_etcd_operation_timeout_ms: 5000
mds_etcd_retry_times: 3
mds_segment_alloc_periodic_persist_inter_ms: 10000
mds_segment_alloc_retry_inter_ms: 1000
mds_segment_discard_scan_interval_ms: 5000
mds_leader_session_inter_sec: 5
mds_leader_election_timeout_ms: 0
mds_enable_copyset_scheduler: true
Expand Down Expand Up @@ -220,6 +221,9 @@ client_session_map_path: ./session_map.json
client_closefd_timeout_sec: 300
client_closefd_time_interval_sec: 600
client_throttle_enable: false
client_discard_enable: true
client_discard_granularity: 4096
client_discard_task_delay_ms: 60000

# nebd默认配置
client_config_path: /etc/curve/client.conf
Expand Down
8 changes: 8 additions & 0 deletions curve-ansible/roles/generate_config/templates/client.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,11 @@ global.sessionMapPath={{ client_session_map_path }}
### throttle config
#
throttle.enable={{ client_throttle_enable }}

##### discard configurations #####
# enable/disable discard
discard.enable={{ client_discard_enable }}
# discard granularity
discard.granularity={{ client_discard_granularity }}
# discard cleanup task delay times in millisecond
discard.taskDelayMs={{ client_discard_task_delay_ms }}
2 changes: 2 additions & 0 deletions curve-ansible/roles/generate_config/templates/mds.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ mds.segment.alloc.periodic.persistInterMs={{ mds_segment_alloc_periodic_persist_
# 出错情况下的重试间隔,单位ms
mds.segment.alloc.retryInterMs={{ mds_segment_alloc_retry_inter_ms }}

mds.segment.discard.scanIntevalMs={{ mds_segment_discard_scan_interval_ms }}


# leader竞选时会创建session, 单位是秒(go端代码的接口这个值的单位就是s)
# 该值和etcd集群election timeout相关.
Expand Down
27 changes: 27 additions & 0 deletions include/client/libcurve.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const char* ErrorNum2ErrorName(LIBCURVE_ERROR err);
typedef enum LIBCURVE_OP {
LIBCURVE_OP_READ,
LIBCURVE_OP_WRITE,
LIBCURVE_OP_DISCARD,
LIBCURVE_OP_MAX,
} LIBCURVE_OP;

Expand Down Expand Up @@ -233,6 +234,16 @@ int Read(int fd, char* buf, off_t offset, size_t length);
*/
int Write(int fd, const char* buf, off_t offset, size_t length);

/**
* @brief Synchronous discard operation
* @param fd file descriptor
* @param offset discard offset
* @param length discard length
* @return On success, return 0.
* On error, returns a negative value.
*/
int Discard(int fd, off_t offset, size_t length);

/**
* 异步模式读
* @param: fd为当前open返回的文件描述符
Expand All @@ -249,6 +260,14 @@ int AioRead(int fd, CurveAioContext* aioctx);
*/
int AioWrite(int fd, CurveAioContext* aioctx);

/**
* @brief Asynchronous discard operation
* @param fd file descriptor
* @param aioctx async request context
* @return 0 means success, otherwise it means failure
*/
int AioDiscard(int fd, CurveAioContext* aioctx);

/**
* 重命名文件
* @param: userinfo是用户信息
Expand Down Expand Up @@ -510,6 +529,14 @@ class CurveClient {
virtual int AioWrite(int fd, CurveAioContext* aioctx,
UserDataType dataType);

/**
* @brief Async Discard
* @param fd file descriptor
* @param aioctx async request context
* @return return error code, 0(LIBCURVE_ERROR::OK) means success
*/
virtual int AioDiscard(int fd, CurveAioContext* aioctx);

/**
* 测试使用,设置fileclient
* @param client 需要设置的fileclient
Expand Down
34 changes: 28 additions & 6 deletions nebd/src/part2/request_executor_curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,33 @@ int CurveRequestExecutor::GetInfo(
return 0;
}

int CurveRequestExecutor::Discard(
NebdFileInstance* fd, NebdServerAioContext* aioctx) {
int CurveRequestExecutor::Discard(NebdFileInstance* fd,
NebdServerAioContext* aioctx) {
int curveFd = GetCurveFdFromNebdFileInstance(fd);
if (curveFd < 0) {
LOG(ERROR) << "Parse curve fd failed";
return -1;
}

aioctx->ret = 0;
aioctx->cb(aioctx);
CurveAioCombineContext* curveCombineCtx = new CurveAioCombineContext();
curveCombineCtx->nebdCtx = aioctx;
int ret = FromNebdCtxToCurveCtx(aioctx, &curveCombineCtx->curveCtx);
if (ret < 0) {
LOG(ERROR) << "Convert nebd aio context to curve aio context failed, "
"curve fd: "
<< curveFd;
delete curveCombineCtx;
return -1;
}

return 0;
ret = client_->AioDiscard(curveFd, &curveCombineCtx->curveCtx);
if (ret == LIBCURVE_ERROR::OK) {
return 0;
}

LOG(ERROR) << "Curve client return failed, curve fd: " << curveFd;
delete curveCombineCtx;
return -1;
}

int CurveRequestExecutor::AioRead(
Expand Down Expand Up @@ -271,7 +291,9 @@ int CurveRequestExecutor::FromNebdOpToCurveOp(LIBAIO_OP op, LIBCURVE_OP *out) {
case LIBAIO_OP::LIBAIO_OP_WRITE:
*out = LIBCURVE_OP_WRITE;
return 0;

case LIBAIO_OP::LIBAIO_OP_DISCARD:
*out = LIBCURVE_OP_DISCARD;
return 0;
default:
return -1;
}
Expand Down
1 change: 1 addition & 0 deletions nebd/test/part2/mock_curve_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MockCurveClient : public ::curve::client::CurveClient {
int(int, CurveAioContext*, curve::client::UserDataType));
MOCK_METHOD3(AioWrite,
int(int, CurveAioContext*, curve::client::UserDataType));
MOCK_METHOD2(AioDiscard, int(int, CurveAioContext*));
};

} // namespace server
Expand Down
60 changes: 49 additions & 11 deletions nebd/test/part2/test_request_executor_curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,20 +358,58 @@ TEST_F(TestReuqestExecutorCurve, test_AioWrite) {

TEST_F(TestReuqestExecutorCurve, test_Discard) {
auto executor = CurveRequestExecutor::GetInstance();
NebdServerAioContext aioctx;
aioctx.cb = NebdUnitTestCallback;
std::string curveFilename("/cinder/volume-1234_cinder_");
std::unique_ptr<CurveFileInstance> curveFileIns(new CurveFileInstance());
NebdServerAioContext* aioctx = new NebdServerAioContext();
nebd::client::DiscardResponse response;
TestReuqestExecutorCurveClosure done;

aioctx->op = LIBAIO_OP::LIBAIO_OP_DISCARD;
aioctx->cb = NebdFileServiceCallback;
aioctx->response = &response;
aioctx->done = &done;
// 1. not an curve volume
{
std::unique_ptr<NebdFileInstance> nebdFileIns(new NebdFileInstance());
EXPECT_CALL(*curveClient_, AioDiscard(_, _))
.Times(0);
ASSERT_EQ(-1, executor.Discard(nebdFileIns.get(), &aioctx));
}

ASSERT_EQ(0, executor.Discard(curveFileIns.get(), aioctx));
ASSERT_TRUE(done.IsRunned());
ASSERT_EQ(response.retcode(), nebd::client::RetCode::kOK);
// 2. fd is invalid
{
std::unique_ptr<CurveFileInstance> curveFileIns(
new CurveFileInstance());
curveFileIns->fd = -1;
EXPECT_CALL(*curveClient_, AioDiscard(_, _))
.Times(0);
ASSERT_EQ(-1, executor.Discard(curveFileIns.get(), &aioctx));
}

// 3. curve client return failed
{
std::unique_ptr<CurveFileInstance> curveFileIns(
new CurveFileInstance());
aioctx.size = 1;
aioctx.offset = 0;
aioctx.op = LIBAIO_OP::LIBAIO_OP_DISCARD;
curveFileIns->fd = 1;
curveFileIns->fileName = curveFilename;
EXPECT_CALL(*curveClient_, AioDiscard(_, _))
.WillOnce(Return(LIBCURVE_ERROR::FAILED));
ASSERT_EQ(-1, executor.Discard(curveFileIns.get(), &aioctx));
}

// 4. ok
{
std::unique_ptr<CurveFileInstance> curveFileIns(
new CurveFileInstance());
aioctx.size = 1;
aioctx.offset = 0;
aioctx.op = LIBAIO_OP::LIBAIO_OP_DISCARD;
curveFileIns->fd = 1;
curveFileIns->fileName = curveFilename;
CurveAioContext* curveCtx;
EXPECT_CALL(*curveClient_, AioDiscard(_, _))
.WillOnce(DoAll(SaveArg<1>(&curveCtx),
Return(LIBCURVE_ERROR::OK)));
ASSERT_EQ(0, executor.Discard(curveFileIns.get(), &aioctx));
curveCtx->cb(curveCtx);
}
}

TEST_F(TestReuqestExecutorCurve, test_Flush) {
Expand Down
18 changes: 18 additions & 0 deletions proto/nameserver2.proto
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ message PageFileSegment {
repeated PageFileChunkInfo chunks = 5;
}

message DiscardSegmentInfo {
required FileInfo fileInfo = 1;
required PageFileSegment pageFileSegment = 2;
}

message CreateFileRequest {
required string fileName = 1;
required FileType fileType = 3;
Expand Down Expand Up @@ -254,6 +259,18 @@ message GetOrAllocateSegmentResponse {
optional PageFileSegment pageFileSegment = 2;
}

message DeAllocateSegmentRequest {
required string fileName = 1;
required string owner = 2;
required uint64 offset = 3;
optional string signature = 4;
required uint64 date = 5;
}

message DeAllocateSegmentResponse {
required StatusCode statusCode = 1;
}

message RenameFileRequest {
required string oldFileName = 1;
required string newFileName = 2;
Expand Down Expand Up @@ -569,6 +586,7 @@ service CurveFSService {
rpc GetFileInfo(GetFileInfoRequest) returns (GetFileInfoResponse);
rpc GetOrAllocateSegment(GetOrAllocateSegmentRequest)
returns (GetOrAllocateSegmentResponse);
rpc DeAllocateSegment(DeAllocateSegmentRequest) returns (DeAllocateSegmentResponse);
rpc RenameFile(RenameFileRequest) returns (RenameFileResponse);
rpc ExtendFile(ExtendFileRequest) returns (ExtendFileResponse);
rpc ChangeOwner(ChangeOwnerRequest) returns (ChangeOwnerResponse);
Expand Down
8 changes: 8 additions & 0 deletions src/client/client_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,17 @@ using CopysetID = uint32_t;
using LogicPoolID = uint32_t;
using ChunkServerID = uint32_t;
using ChunkIndex = uint32_t;
using SegmentIndex = uint32_t;

using EndPoint = butil::EndPoint;
using Status = butil::Status;

using IOManagerID = uint64_t;

constexpr uint64_t KiB = 1024;
constexpr uint64_t MiB = 1024 * KiB;
constexpr uint64_t GiB = 1024 * MiB;

// 操作类型
enum class OpType {
READ = 0,
Expand All @@ -58,6 +63,7 @@ enum class OpType {
CREATE_CLONE,
RECOVER_CHUNK,
GET_CHUNK_INFO,
DISCARD,
UNKNOWN
};

Expand Down Expand Up @@ -245,6 +251,8 @@ inline const char* OpTypeToString(OpType optype) {
return "RecoverChunk";
case OpType::GET_CHUNK_INFO:
return "GetChunkInfo";
case OpType::DISCARD:
return "Discard";
case OpType::UNKNOWN:
default:
return "Unknown";
Expand Down
20 changes: 20 additions & 0 deletions src/client/client_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ namespace curve {
namespace client {
int ClientConfig::Init(const char* configpath) {
conf_.SetConfigPath(configpath);

LOG(INFO) << "Init config from " << configpath;

if (!conf_.LoadConfig()) {
LOG(ERROR) << "Load config failed, config path = " << configpath;
return -1;
Expand Down Expand Up @@ -251,6 +254,23 @@ int ClientConfig::Init(const char* configpath) {
<< "config no throttle.enable info, using default value "
<< fileServiceOption_.ioOpt.throttleOption.enable;

ret = conf_.GetBoolValue("discard.enable",
&fileServiceOption_.ioOpt.discardOption.enable);
LOG_IF(ERROR, ret == false) << "config no discard.enable info";
RETURN_IF_FALSE(ret);

ret = conf_.GetUInt32Value(
"discard.granularity",
&fileServiceOption_.ioOpt.metaCacheOpt.discardGranularity);
LOG_IF(ERROR, ret == false) << "config no discard.granularity info";
RETURN_IF_FALSE(ret);

ret = conf_.GetUInt32Value(
"discard.taskDelayMs",
&fileServiceOption_.ioOpt.discardOption.taskDelayMs);
LOG_IF(ERROR, ret == false) << "config no discard.taskDelayMs info";
RETURN_IF_FALSE(ret);

return 0;
}

Expand Down
Loading

0 comments on commit 5a4889d

Please sign in to comment.