From 89ca60c73391f53d3b4e6c5246993794536d7a83 Mon Sep 17 00:00:00 2001 From: Hanqing Wu Date: Wed, 23 Feb 2022 19:18:10 +0800 Subject: [PATCH] curvebs: support 512 aligned IO Signed-off-by: Hanqing Wu --- conf/chunkserver.conf | 7 +- conf/chunkserver.conf.example | 5 + conf/mds.conf | 2 + .../templates/chunkserver.conf.j2 | 8 +- .../generate_config/templates/mds.conf.j2 | 2 + .../generate_config/templates/s3.conf.j2 | 1 + .../templates/chunkserver_deploy.sh.j2 | 12 +- curve-ansible/server.ini | 2 + curvefs/src/client/fuse_client.h | 4 +- .../local/chunkserver/conf/chunkserver.conf.0 | 1 + .../local/chunkserver/conf/chunkserver.conf.1 | 1 + .../local/chunkserver/conf/chunkserver.conf.2 | 1 + include/chunkserver/chunkserver_common.h | 3 - include/client/libcurve.h | 3 + nbd/src/ImageInstance.cpp | 6 +- nbd/src/ImageInstance.h | 9 +- nbd/src/NBDController.cpp | 52 +- nbd/src/NBDController.h | 34 +- nbd/src/NBDTool.cpp | 22 +- nbd/src/define.h | 1 - nbd/src/util.cpp | 23 +- nbd/test/mock_nbd_controller.h | 2 +- nebd/proto/client.proto | 1 + nebd/src/part1/libnebd.cpp | 4 + nebd/src/part1/libnebd.h | 2 + nebd/src/part1/libnebd_file.cpp | 4 + nebd/src/part1/libnebd_file.h | 3 + nebd/src/part1/nebd_client.cpp | 40 + nebd/src/part1/nebd_client.h | 2 + nebd/src/part2/define.h | 2 + nebd/src/part2/file_service.cpp | 1 + nebd/src/part2/request_executor_curve.cpp | 8 +- nebd/test/part1/fake_file_service.cpp | 1 + nebd/test/part1/fake_file_service.h | 4 +- nebd/test/part1/nebd_lib_unittest.cpp | 4 +- nebd/test/part2/mock_curve_client.h | 1 + .../part2/test_request_executor_curve.cpp | 20 +- proto/nameserver2.proto | 1 + proto/topology.proto | 1 + src/chunkserver/chunk_service.cpp | 25 +- src/chunkserver/chunk_service.h | 3 +- src/chunkserver/chunkserver.cpp | 21 +- src/chunkserver/clone_core.cpp | 26 +- src/chunkserver/config_info.cpp | 54 - src/chunkserver/config_info.h | 25 +- src/chunkserver/copyset_node.cpp | 3 +- .../datastore/chunkserver_chunkfile.cpp | 89 +- .../datastore/chunkserver_chunkfile.h | 45 +- .../datastore/chunkserver_datastore.cpp | 12 +- .../datastore/chunkserver_datastore.h | 11 +- .../datastore/chunkserver_snapshot.cpp | 21 +- .../datastore/chunkserver_snapshot.h | 15 +- src/chunkserver/datastore/define.h | 9 +- src/chunkserver/datastore/file_pool.cpp | 161 ++- src/chunkserver/datastore/file_pool.h | 67 +- src/chunkserver/op_request.cpp | 6 +- src/chunkserver/register.cpp | 4 +- src/chunkserver/register.h | 1 + src/client/client_common.h | 1 + src/client/file_instance.cpp | 101 +- src/client/file_instance.h | 36 +- src/client/libcurve_client.cpp | 9 +- src/client/libcurve_file.cpp | 28 +- src/client/libcurve_file.h | 5 - src/client/mds_client.cpp | 4 +- src/client/metacache.cpp | 3 +- src/client/service_helper.cpp | 6 + src/client/splitor.cpp | 3 - src/client/splitor.h | 9 +- src/common/authenticator.cpp | 6 + src/common/authenticator.h | 8 - src/common/configuration.cpp | 5 + src/common/configuration.h | 1 + src/common/curve_define.h | 2 +- {curvefs/src => src}/common/fast_align.h | 36 +- src/common/namespace_define.h | 2 + .../mds/common/mds_define.cpp | 26 +- src/mds/common/mds_define.h | 4 + src/mds/main/main.cpp | 7 +- src/mds/nameserver2/curvefs.cpp | 11 +- src/mds/nameserver2/curvefs.h | 6 + src/mds/nameserver2/namespace_service.cpp | 5 +- src/mds/server/mds.cpp | 55 + src/mds/server/mds.h | 2 + src/mds/topology/topology_service_manager.cpp | 12 + src/mds/topology/topology_service_manager.h | 1 - src/tools/curve_format_main.cpp | 126 +- test/chunkserver/chunk_service_test.cpp | 2 + test/chunkserver/chunk_service_test2.cpp | 2 + .../chunkserver/chunkserver_snapshot_test.cpp | 2 + test/chunkserver/chunkserver_test_util.cpp | 17 +- test/chunkserver/client.cpp | 2 +- test/chunkserver/clone/BUILD | 4 +- test/chunkserver/clone/clone_core_test.cpp | 120 +- test/chunkserver/clone/clone_test_util.h | 2 - test/chunkserver/clone/op_request_test.cpp | 50 +- test/chunkserver/copyset_node_test.cpp | 6 +- .../datastore/datastore_mock_unittest.cpp | 1019 +++++++++-------- .../datastore/filepool_mock_unittest.cpp | 170 ++- .../datastore/filepool_unittest.cpp | 58 +- test/chunkserver/heartbeat_test_main.cpp | 1 + test/chunkserver/metrics_test.cpp | 9 +- test/chunkserver/op_request_test.cpp | 9 +- ...curve_filesystem_adaptor_mock_unittest.cpp | 44 +- .../curve_filesystem_adaptor_unittest.cpp | 43 +- ...raftsnapshot_chunkfilepool_integration.cpp | 2 + test/chunkserver/server.cpp | 20 +- test/client/BUILD | 1 + .../client_mdsclient_metacache_unittest.cpp | 84 +- test/client/client_metric_test.cpp | 24 + test/client/client_session_unittest.cpp | 2 +- test/client/client_userinfo_unittest.cpp | 28 +- test/client/copyset_client_test.cpp | 57 +- test/client/fake/fakeMDS.cpp | 2 +- test/client/fake/mockMDS.h | 19 +- test/client/file_instance_test.cpp | 13 + test/client/iotracker_splitor_unittest.cpp | 39 +- test/client/iotracker_test.cpp | 2 +- test/client/libcurve_interface_unittest.cpp | 16 +- .../chunkserver/chunkserver_basic_test.cpp | 9 +- .../chunkserver/chunkserver_clone_recover.cpp | 2 + .../chunkserver_concurrent_test.cpp | 11 +- .../datastore/datastore_basic_test.cpp | 3 +- .../datastore/datastore_clone_case_test.cpp | 15 +- .../datastore/datastore_exception_test.cpp | 37 +- .../datastore/datastore_integration_base.h | 15 +- test/integration/common/chunkservice_op.cpp | 1 + .../raft/raft_config_change_test.cpp | 1 + .../raft/raft_log_replication_test.cpp | 1 + test/integration/raft/raft_snapshot_test.cpp | 1 + test/integration/raft/raft_vote_test.cpp | 1 + .../snapshotcloneserver_common_test.cpp | 4 +- .../snapshotcloneserver_concurrent_test.cpp | 4 +- .../snapshotcloneserver_recover_test.cpp | 4 +- test/mds/server/BUILD | 1 + test/mds/server/mds_test.cpp | 45 + .../test_topology_service_manager.cpp | 21 +- 137 files changed, 2077 insertions(+), 1386 deletions(-) delete mode 100644 src/chunkserver/config_info.cpp rename {curvefs/src => src}/common/fast_align.h (61%) rename test/chunkserver/clone/clone_unittest_main.cpp => src/mds/common/mds_define.cpp (57%) diff --git a/conf/chunkserver.conf b/conf/chunkserver.conf index 2c10a5286a..20f8f35229 100644 --- a/conf/chunkserver.conf +++ b/conf/chunkserver.conf @@ -12,10 +12,13 @@ global.external_subnet=127.0.0.0/24 global.chunk_size=16777216 # chunk 元数据页大小,一般4KB global.meta_page_size=4096 +# chunk's block size, IO requests must align with it, supported value is |512| and |4096| +# it should consist with `block_size` in chunkfilepool.meta_path and `mds.volume.blockSize` in MDS's configurations +# for clone chunk and snapshot chunk, it's also the minimum granularity that each bit represents +# if set to |512|, we need 4096 bytes bitmap for each chunk, so meta_page_size should be 8192 or larger. +global.block_size=4096 # clone chunk允许的最长location长度 global.location_limit=3000 -# minimum alignment for io request -global.min_io_alignment=512 # # MDS settings diff --git a/conf/chunkserver.conf.example b/conf/chunkserver.conf.example index c2ae75226c..f3b2ef7851 100644 --- a/conf/chunkserver.conf.example +++ b/conf/chunkserver.conf.example @@ -13,6 +13,11 @@ global.chunk_size=16777216 # chunk 元数据页大小,一般4KB global.meta_page_size=4096 # clone chunk允许的最长location长度 +# chunk's block size, IO requests must align with it, supported value is |512| and |4096| +# it should consist with `block_size` in chunkfilepool.meta_path and `mds.volume.blockSize` in MDS's configurations +# for clone chunk and snapshot chunk, it's also the minimum granularity that each bit represents +# if set to |512|, we need 4096 bytes bitmap for each chunk, so meta_page_size should be 8192 or larger. +global.block_size=4096 global.location_limit=3000 # diff --git a/conf/mds.conf b/conf/mds.conf index 8dde5ab24b..bcfb152815 100644 --- a/conf/mds.conf +++ b/conf/mds.conf @@ -195,6 +195,8 @@ mds.curvefs.defaultSegmentSize=1073741824 mds.curvefs.minFileLength=10737418240 # curvefs的默认最大文件大小,20TB = 20*1024*1024*1024*1024 = 21990232555520 mds.curvefs.maxFileLength=21990232555520 +# smallest read/write unit for volume, support |512| and |4096| +mds.curvefs.blockSize=4096 # # chunkseverclient config diff --git a/curve-ansible/roles/generate_config/templates/chunkserver.conf.j2 b/curve-ansible/roles/generate_config/templates/chunkserver.conf.j2 index 59888a6704..595f19ea60 100644 --- a/curve-ansible/roles/generate_config/templates/chunkserver.conf.j2 +++ b/curve-ansible/roles/generate_config/templates/chunkserver.conf.j2 @@ -12,6 +12,8 @@ global.external_subnet={{ chunkserver_external_subnet }} global.chunk_size={{ chunk_size }} # chunk 元数据页大小,一般4KB global.meta_page_size={{ chunkserver_meta_page_size }} +# chunk block size,一般4KB +global.block_size={{ chunkserver_block_size }} # clone chunk允许的最长location长度 global.location_limit={{ chunkserver_location_limit }} @@ -108,9 +110,9 @@ copyset.scan_rpc_timeout_ms={{ chunkserver_copyset_scan_rpc_timeout_ms }} copyset.scan_rpc_retry_times={{ chunkserver_copyset_scan_rpc_retry_times }} # the follower send scanmap to leader rpc retry interval copyset.scan_rpc_retry_interval_us={{ chunkserver_copyset_scan_rpc_retry_interval_us }} -copyset.copyset_enable_odsync_when_open_chunkfile={{ chunkserver_copyset_enable_odsync_when_open_chunkfile }} -copyset.copyset_synctimer_interval_ms={{ chunkserver_copyset_synctimer_interval_ms }} -copyset.copyset_check_syncing_interval_ms={{ chunkserver_copyset_check_syncing_interval_ms }} +copyset.enable_odsync_when_open_chunkfile={{ chunkserver_copyset_enable_odsync_when_open_chunkfile }} +copyset.synctimer_interval_ms={{ chunkserver_copyset_synctimer_interval_ms }} +copyset.check_syncing_interval_ms={{ chunkserver_copyset_check_syncing_interval_ms }} # # Clone settings diff --git a/curve-ansible/roles/generate_config/templates/mds.conf.j2 b/curve-ansible/roles/generate_config/templates/mds.conf.j2 index 13040fa9ea..f64f844839 100644 --- a/curve-ansible/roles/generate_config/templates/mds.conf.j2 +++ b/curve-ansible/roles/generate_config/templates/mds.conf.j2 @@ -203,6 +203,8 @@ mds.curvefs.defaultSegmentSize={{ segment_size }} mds.curvefs.minFileLength={{ min_file_length }} # curvefs的默认最大文件大小,20TB = 20*1024*1024*1024*1024 = 21990232555520 mds.curvefs.maxFileLength={{ max_file_length }} +# smallest read/write unit for volume, support |512| and |4096| +mds.curvefs.blockSize={{ chunkserver_block_size }} # # chunkseverclient config diff --git a/curve-ansible/roles/generate_config/templates/s3.conf.j2 b/curve-ansible/roles/generate_config/templates/s3.conf.j2 index 810b70cfab..3842765ce1 100644 --- a/curve-ansible/roles/generate_config/templates/s3.conf.j2 +++ b/curve-ansible/roles/generate_config/templates/s3.conf.j2 @@ -25,3 +25,4 @@ s3.throttle.iopsWriteLimit={{ s3_throttle_iopsWriteLimit }} s3.throttle.bpsTotalMB= {{ s3_throttle_bpsTotalLimit }} s3.throttle.bpsReadMB= {{ s3_throttle_bpsReadLimit }} s3.throttle.bpsWriteMB= {{ s3_throttle_bpsWriteLimit }} +s3.useVirtualAddressing=False diff --git a/curve-ansible/roles/install_package/templates/chunkserver_deploy.sh.j2 b/curve-ansible/roles/install_package/templates/chunkserver_deploy.sh.j2 index db8566728a..f2e44b6177 100644 --- a/curve-ansible/roles/install_package/templates/chunkserver_deploy.sh.j2 +++ b/curve-ansible/roles/install_package/templates/chunkserver_deploy.sh.j2 @@ -167,7 +167,9 @@ do -filePoolDir=$dataDir/chunkserver$i/chunkfilepool \ -filePoolMetaPath=$dataDir/chunkserver$i/chunkfilepool.meta \ -fileSize={{ chunk_size }} \ - -fileSystemPath=$dataDir/chunkserver$i/chunkfilepool & + -fileSystemPath=$dataDir/chunkserver$i/chunkfilepool \ + -metaPageSize={{ chunkserver_meta_page_size }} \ + -blockSize={{ chunkserver_block_size }} & done wait } @@ -185,7 +187,9 @@ function deploy_one_walfile_pool { -filePoolDir=$dataDir/chunkserver$1/walfilepool \ -filePoolMetaPath=$dataDir/chunkserver$1/walfilepool.meta \ -fileSize={{ chunkserver_walfilepool_segment_size }} \ - -fileSystemPath=$dataDir/chunkserver$1/walfilepool & + -fileSystemPath=$dataDir/chunkserver$1/walfilepool \ + -metaPageSize={{ chunkserver_meta_page_size }} \ + -blockSize={{ chunkserver_block_size }} & } @@ -286,7 +290,9 @@ function deploy_one { -filePoolDir=$dirname/chunkfilepool \ -filePoolMetaPath=$dirname/chunkfilepool.meta \ -fileSize={{ chunk_size }} \ - -fileSystemPath=$dirname/chunkfilepool & + -fileSystemPath=$dirname/chunkfilepool \ + -metaPageSize={{ chunkserver_meta_page_size }} \ + -blockSize={{ chunkserver_block_size }} & wait # release disk reserved space sudo tune2fs -m 0 $diskname diff --git a/curve-ansible/server.ini b/curve-ansible/server.ini index eaca5a4515..23fdb8b16e 100644 --- a/curve-ansible/server.ini +++ b/curve-ansible/server.ini @@ -101,6 +101,8 @@ chunk_size=16777216 chunkserver_walfilepool_segment_size=8388608 retain_pool=False walfilepool_use_chunk_file_pool=True +chunkserver_meta_page_size=4096 +chunkserver_block_size=4096 [snapshotclone_nginx:vars] snapshot_nginx_package_version="0.0.6.1.1+7af4d6a4" diff --git a/curvefs/src/client/fuse_client.h b/curvefs/src/client/fuse_client.h index 1312a5790f..4381fde72e 100644 --- a/curvefs/src/client/fuse_client.h +++ b/curvefs/src/client/fuse_client.h @@ -41,7 +41,7 @@ #include "curvefs/src/client/rpcclient/mds_client.h" #include "curvefs/src/client/rpcclient/metaserver_client.h" #include "curvefs/src/client/s3/client_s3_adaptor.h" -#include "curvefs/src/common/fast_align.h" +#include "src/common/fast_align.h" #include "curvefs/src/client/metric/client_metric.h" #include "src/common/concurrent/concurrent.h" #include "curvefs/src/common/define.h" @@ -69,7 +69,7 @@ using rpcclient::MdsClientImpl; using rpcclient::MetaServerClient; using rpcclient::MetaServerClientImpl; -using curvefs::common::is_aligned; +using curve::common::is_aligned; const uint32_t kMaxHostNameLength = 255u; diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.0 b/deploy/local/chunkserver/conf/chunkserver.conf.0 index da6dd8441b..3bed94777c 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.0 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.0 @@ -26,6 +26,7 @@ global.external_ip=127.0.0.1 global.external_subnet=127.0.0.0/24 global.chunk_size=16777216 global.meta_page_size=4096 +global.block_size=4096 global.location_limit=3000 # diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.1 b/deploy/local/chunkserver/conf/chunkserver.conf.1 index b3c1b2ff6d..b7ab698916 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.1 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.1 @@ -26,6 +26,7 @@ global.external_ip=127.0.0.1 global.external_subnet=127.0.0.0/24 global.chunk_size=16777216 global.meta_page_size=4096 +global.block_size=4096 global.location_limit=3000 # diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.2 b/deploy/local/chunkserver/conf/chunkserver.conf.2 index b3c8b0a2c7..6ac9f0a0f5 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.2 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.2 @@ -26,6 +26,7 @@ global.external_ip=127.0.0.1 global.external_subnet=127.0.0.0/24 global.chunk_size=16777216 global.meta_page_size=4096 +global.block_size=4096 global.location_limit=3000 # diff --git a/include/chunkserver/chunkserver_common.h b/include/chunkserver/chunkserver_common.h index aaa05c2333..4a03a89ee6 100644 --- a/include/chunkserver/chunkserver_common.h +++ b/include/chunkserver/chunkserver_common.h @@ -123,9 +123,6 @@ inline std::string ToGroupIdString(const LogicPoolID &logicPoolId, } #define ToGroupIdStr ToGroupIdString -// TODO(wudmeiao): 是否需要考虑可配置 -const uint32_t kOpRequestAlignSize = 4096; - } // namespace chunkserver } // namespace curve diff --git a/include/client/libcurve.h b/include/client/libcurve.h index 3b50ee97d0..775a513d51 100644 --- a/include/client/libcurve.h +++ b/include/client/libcurve.h @@ -56,6 +56,7 @@ typedef struct FileStatInfo { int fileStatus; uint64_t stripeUnit; uint64_t stripeCount; + uint32_t blocksize; } FileStatInfo_t; // 存储用户信息 @@ -436,6 +437,8 @@ class CurveClient { */ virtual int64_t StatFile(const std::string& filename); + virtual int64_t StatFile(const std::string& filename, + FileStatInfo* fileStat); /** * 异步读 * @param fd 文件fd diff --git a/nbd/src/ImageInstance.cpp b/nbd/src/ImageInstance.cpp index b60eed16e7..d03e7a62d7 100644 --- a/nbd/src/ImageInstance.cpp +++ b/nbd/src/ImageInstance.cpp @@ -77,10 +77,14 @@ void ImageInstance::Flush(NebdClientAioContext* context) { nebd_lib_flush(fd_, context); } -int64_t ImageInstance::GetImageSize() { +int64_t ImageInstance::GetImageSize() const { return nebd_lib_filesize(fd_); } +int64_t ImageInstance::GetBlockSize() const { + return nebd_lib_blocksize(fd_); +} + ImageInstance::~ImageInstance() { if (fd_ != -1) { Close(); diff --git a/nbd/src/ImageInstance.h b/nbd/src/ImageInstance.h index 2594ebc68b..6f94ef7d59 100644 --- a/nbd/src/ImageInstance.h +++ b/nbd/src/ImageInstance.h @@ -83,7 +83,14 @@ class ImageInstance { * @return 获取成功返回文件大小(正值) * 获取失败返回错误码(负值) */ - virtual int64_t GetImageSize(); + virtual int64_t GetImageSize() const; + + /** + * @brief Get image's block size + * @return return block size when success, + * otherwise return negative error code + */ + virtual int64_t GetBlockSize() const; private: // nebd返回的文件描述符 diff --git a/nbd/src/NBDController.cpp b/nbd/src/NBDController.cpp index 42d8dad525..674dd442d2 100644 --- a/nbd/src/NBDController.cpp +++ b/nbd/src/NBDController.cpp @@ -42,12 +42,16 @@ namespace curve { namespace nbd { -int IOController::InitDevAttr(NBDConfig* config, uint64_t size, +int g_nbd_index; + +int IOController::InitDevAttr(NBDConfig* config, + uint64_t size, + uint32_t blocksize, uint64_t flags) { int ret = -1; do { - ret = ioctl(nbdFd_, NBD_SET_BLKSIZE, CURVE_NBD_BLKSIZE); + ret = ioctl(nbdFd_, NBD_SET_BLKSIZE, blocksize); if (ret < 0) { break; } @@ -133,11 +137,15 @@ int IOController::MapOnNbdDeviceByDevPath(int sockfd, nbdFd_ = devfd; nbdIndex_ = index; + g_nbd_index = nbdIndex_; return 0; } -int IOController::SetUp(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) { +int IOController::SetUp(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) { int ret = -1; if (config->devpath.empty()) { @@ -150,10 +158,20 @@ int IOController::SetUp(NBDConfig* config, int sockfd, return -1; } - ret = InitDevAttr(config, size, flags); - if (ret == 0) { + do { + ret = InitDevAttr(config, size, blocksize, flags); + if (ret < 0) { + break; + } + ret = check_device_size(nbdIndex_, size); - } + if (ret < 0) { + break; + } + + ret = check_block_size(nbdIndex_, blocksize); + } while (0); + if (ret < 0) { dout << "curve-nbd: failed to map, status: " << cpp_strerror(ret) << std::endl; @@ -240,8 +258,11 @@ void NetLinkController::Uninit() { nlId_ = -1; } -int NetLinkController::SetUp(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) { +int NetLinkController::SetUp(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) { int ret = Init(); if (ret < 0) { dout << "curve-nbd: Netlink interface not supported." @@ -249,7 +270,7 @@ int NetLinkController::SetUp(NBDConfig* config, int sockfd, return ret; } - ret = ConnectInternal(config, sockfd, size, flags); + ret = ConnectInternal(config, sockfd, size, blocksize, flags); Uninit(); if (ret < 0) { return ret; @@ -259,7 +280,7 @@ int NetLinkController::SetUp(NBDConfig* config, int sockfd, if (index < 0) { return index; } - ret = check_block_size(index, CURVE_NBD_BLKSIZE); + ret = check_block_size(index, blocksize); if (ret < 0) { return ret; } @@ -360,8 +381,11 @@ static int netlink_connect_cb(struct nl_msg *msg, void *arg) { return NL_OK; } -int NetLinkController::ConnectInternal(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) { +int NetLinkController::ConnectInternal(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) { struct nlattr *sock_attr = nullptr; struct nlattr *sock_opt = nullptr; struct nl_msg *msg = nullptr; @@ -393,7 +417,7 @@ int NetLinkController::ConnectInternal(NBDConfig* config, int sockfd, NLA_PUT_U64(msg, NBD_ATTR_TIMEOUT, config->timeout); } NLA_PUT_U64(msg, NBD_ATTR_SIZE_BYTES, size); - NLA_PUT_U64(msg, NBD_ATTR_BLOCK_SIZE_BYTES, CURVE_NBD_BLKSIZE); + NLA_PUT_U64(msg, NBD_ATTR_BLOCK_SIZE_BYTES, blocksize); NLA_PUT_U64(msg, NBD_ATTR_SERVER_FLAGS, flags); sock_attr = nla_nest_start(msg, NBD_ATTR_SOCKETS); diff --git a/nbd/src/NBDController.h b/nbd/src/NBDController.h index 204e7b1dbb..8cae896479 100644 --- a/nbd/src/NBDController.h +++ b/nbd/src/NBDController.h @@ -71,11 +71,15 @@ class NBDController { * @param config: 启动NBD设备相关的配置参数 * @param sockfd: socketpair其中一端的fd,传给NBD设备用于跟NBDServer间的数据传输 * @param size: 设置NBD设备的大小 + * @param blocksize: device's block size * @param flags: 设置加载NBD设备的flags * @return: 成功返回0,失败返回负值 */ - virtual int SetUp(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) = 0; + virtual int SetUp(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) = 0; /** * @brief: 根据设备名来卸载已经映射的NBD设备 * @param devpath: 设备路径,例如/dev/nbd0 @@ -141,13 +145,19 @@ class IOController : public NBDController { IOController() {} ~IOController() {} - int SetUp(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) override; + int SetUp(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) override; int DisconnectByPath(const std::string& devpath) override; int Resize(uint64_t size) override; private: - int InitDevAttr(NBDConfig* config, uint64_t size, uint64_t flags); + int InitDevAttr(NBDConfig* config, + uint64_t size, + uint32_t blocksize, + uint64_t flags); int MapOnUnusedNbdDevice(int sockfd, std::string* devpath); int MapOnNbdDeviceByDevPath(int sockfd, const std::string& devpath, bool logWhenError = true); @@ -158,8 +168,11 @@ class NetLinkController : public NBDController { NetLinkController() : nlId_(-1), sock_(nullptr) {} ~NetLinkController() {} - int SetUp(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags) override; + int SetUp(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags) override; int DisconnectByPath(const std::string& devpath) override; int Resize(uint64_t size) override; bool Support(); @@ -171,8 +184,11 @@ class NetLinkController : public NBDController { private: int Init(); void Uninit(); - int ConnectInternal(NBDConfig* config, int sockfd, - uint64_t size, uint64_t flags); + int ConnectInternal(NBDConfig* config, + int sockfd, + uint64_t size, + uint32_t blocksize, + uint64_t flags); int DisconnectInternal(int index); int ResizeInternal(int nbdIndex, uint64_t size); diff --git a/nbd/src/NBDTool.cpp b/nbd/src/NBDTool.cpp index 7a63a8940b..4f10e40668 100644 --- a/nbd/src/NBDTool.cpp +++ b/nbd/src/NBDTool.cpp @@ -34,6 +34,8 @@ namespace curve { namespace nbd { +extern int g_nbd_index; + std::ostream& operator<<(std::ostream& os, const DeviceInfo& info) { TextTable tbl; tbl.define_column("pid", TextTable::LEFT, TextTable::LEFT); @@ -89,6 +91,14 @@ int NBDTool::Connect(NBDConfig *cfg) { return -1; } + int64_t blockSize = imageInstance->GetBlockSize(); + dout << "curve-nbd: block size is " << blockSize << std::endl; + if (blockSize <= 0) { + dout << "curve-nbd: Get block size failed, image block size: " + << blockSize << std::endl; + return -1; + } + // load nbd module ret = load_module(cfg); if (ret < 0) { @@ -106,16 +116,26 @@ int NBDTool::Connect(NBDConfig *cfg) { if (cfg->readonly) { flags |= NBD_FLAG_READ_ONLY; } - ret = nbdCtrl->SetUp(cfg, socketPair_.First(), fileSize, flags); + ret = nbdCtrl->SetUp(cfg, socketPair_.First(), fileSize, blockSize, flags); if (ret < 0) { dout << "nbd controller setup failed, imgname = " << cfg->imgname << std::endl; return -1; } + ret = check_block_size(g_nbd_index, blockSize); + if (ret < 0) { + dout << "check_block_size error" << std::endl; + } + nbdWatchCtx_ = std::make_shared(nbdCtrl, imageInstance, fileSize); + ret = check_block_size(g_nbd_index, blockSize); + if (ret < 0) { + dout << "check_block_size error" << std::endl; + } + return 0; } diff --git a/nbd/src/define.h b/nbd/src/define.h index ed6f443ba9..0be70b1519 100644 --- a/nbd/src/define.h +++ b/nbd/src/define.h @@ -55,7 +55,6 @@ namespace nbd { #define HELP_INFO 1 #define VERSION_INFO 2 -#define CURVE_NBD_BLKSIZE 4096UL // CURVE后端当前支持4096大小对齐的IO #define NBD_MAX_PATH "/sys/module/nbd/parameters/nbds_max" #define PROCESS_NAME "curve-nbd" diff --git a/nbd/src/util.cpp b/nbd/src/util.cpp index 4670a65184..9cb84df458 100644 --- a/nbd/src/util.cpp +++ b/nbd/src/util.cpp @@ -257,7 +257,7 @@ int get_mapped_info(int pid, NBDConfig *cfg) { } ifs >> cmdline; - for (int i = 0; i < cmdline.size(); i++) { + for (size_t i = 0; i < cmdline.size(); i++) { char *arg = &cmdline[i]; if (i == 0) { if (strcmp(basename(arg) , PROCESS_NAME) != 0) { @@ -320,8 +320,7 @@ int check_dev_can_unmap(const NBDConfig *cfg) { int check_size_from_file(const std::string &path, uint64_t expected_size, bool sizeInSector = false) { - std::ifstream ifs; - ifs.open(path.c_str(), std::ifstream::in); + std::ifstream ifs(path, std::ifstream::in); if (!ifs.is_open()) { dout << "curve-nbd: failed to open " << path << std::endl; return -EINVAL; @@ -329,7 +328,6 @@ int check_size_from_file(const std::string &path, uint64_t expected_size, uint64_t size = 0; ifs >> size; - size *= CURVE_NBD_BLKSIZE; if (size == 0) { // Newer kernel versions will report real size only after nbd @@ -343,22 +341,27 @@ int check_size_from_file(const std::string &path, uint64_t expected_size, if (size != expected_size) { dout << "curve-nbd: kernel reported invalid size (" << size - << ", expected " << expected_size << ")" << std::endl; + << ", expected " << expected_size << ")" + << ", from: " << path << std::endl; return -EINVAL; } return 0; } +static std::string sys_block_path(int nbd_index) { + return "/sys/block/nbd" + std::to_string(nbd_index); +} + int check_block_size(int nbd_index, uint64_t expected_size) { - std::string path = "/sys/block/nbd" + std::to_string(nbd_index) - + "/queue/hw_sector_size"; + std::string path = + sys_block_path(nbd_index) + "/queue/logical_block_size"; int ret = check_size_from_file(path, expected_size); if (ret < 0) { return ret; } - path = "/sys/block/nbd" + std::to_string(nbd_index) - + "/queue/minimum_io_size"; + + path = sys_block_path(nbd_index) + "/queue/physical_block_size"; ret = check_size_from_file(path, expected_size); if (ret < 0) { return ret; @@ -371,7 +374,7 @@ int check_device_size(int nbd_index, uint64_t expected_size) { // overflow for large image sizes. This check is to ensure we are // not affected. - std::string path = "/sys/block/nbd" + std::to_string(nbd_index) + "/size"; + std::string path = sys_block_path(nbd_index) + "/size"; return check_size_from_file(path, expected_size, true); } diff --git a/nbd/test/mock_nbd_controller.h b/nbd/test/mock_nbd_controller.h index 4a743fc199..15dd2023a1 100644 --- a/nbd/test/mock_nbd_controller.h +++ b/nbd/test/mock_nbd_controller.h @@ -38,7 +38,7 @@ class MockNBDController : public NBDController { ~MockNBDController() = default; MOCK_METHOD1(Resize, int(uint64_t)); - MOCK_METHOD4(SetUp, int(NBDConfig*, int, uint64_t, uint64_t)); + MOCK_METHOD5(SetUp, int(NBDConfig*, int, uint64_t, uint32_t, uint64_t)); MOCK_METHOD1(DisconnectByPath, int(const std::string&)); }; diff --git a/nebd/proto/client.proto b/nebd/proto/client.proto index 022aaf0ed5..bc084b3af4 100644 --- a/nebd/proto/client.proto +++ b/nebd/proto/client.proto @@ -98,6 +98,7 @@ message FileInfo { required uint64 size = 1; required uint64 objSize = 2; required uint64 objNums = 3; + optional uint32 blocksize = 4; } message GetInfoRequest { diff --git a/nebd/src/part1/libnebd.cpp b/nebd/src/part1/libnebd.cpp index 06898883cc..ab9373de52 100644 --- a/nebd/src/part1/libnebd.cpp +++ b/nebd/src/part1/libnebd.cpp @@ -109,6 +109,10 @@ int64_t nebd_lib_filesize(int fd) { return GetFileSize4Nebd(fd); } +int64_t nebd_lib_blocksize(int fd) { + return GetBlockSize4Nebd(fd); +} + int nebd_lib_resize(int fd, int64_t size) { return Extend4Nebd(fd, size); } diff --git a/nebd/src/part1/libnebd.h b/nebd/src/part1/libnebd.h index 4d3400ba64..380776d71b 100644 --- a/nebd/src/part1/libnebd.h +++ b/nebd/src/part1/libnebd.h @@ -159,6 +159,8 @@ int nebd_lib_sync(int fd); */ int64_t nebd_lib_filesize(int fd); +int64_t nebd_lib_blocksize(int fd); + /** * @brief resize文件 * @param fd:文件的fd diff --git a/nebd/src/part1/libnebd_file.cpp b/nebd/src/part1/libnebd_file.cpp index 8023558175..e41b50a35e 100644 --- a/nebd/src/part1/libnebd_file.cpp +++ b/nebd/src/part1/libnebd_file.cpp @@ -51,6 +51,10 @@ int64_t GetFileSize4Nebd(int fd) { return nebd::client::nebdClient.GetFileSize(fd); } +int64_t GetBlockSize4Nebd(int fd) { + return nebd::client::nebdClient.GetBlockSize(fd); +} + int Discard4Nebd(int fd, NebdClientAioContext* aioctx) { return nebd::client::nebdClient.Discard(fd, aioctx); } diff --git a/nebd/src/part1/libnebd_file.h b/nebd/src/part1/libnebd_file.h index 9cc5868ef2..6361094ab2 100644 --- a/nebd/src/part1/libnebd_file.h +++ b/nebd/src/part1/libnebd_file.h @@ -62,6 +62,9 @@ int Extend4Nebd(int fd, int64_t newsize); * @return 成功返回文件size,失败返回错误码 */ int64_t GetFileSize4Nebd(int fd); + +int64_t GetBlockSize4Nebd(int fd); + /** * @brief discard文件,异步函数 * @param fd:文件的fd diff --git a/nebd/src/part1/nebd_client.cpp b/nebd/src/part1/nebd_client.cpp index 734fee9480..cd67636d4f 100644 --- a/nebd/src/part1/nebd_client.cpp +++ b/nebd/src/part1/nebd_client.cpp @@ -57,6 +57,8 @@ NebdClient &nebdClient = NebdClient::GetInstance(); constexpr int32_t kBufSize = 128; +constexpr uint32_t kDefaultBlockSize = 4096; + ProtoOpenFlags ConverToProtoOpenFlags(const NebdOpenFlags* flags) { ProtoOpenFlags protoFlags; protoFlags.set_exclusive(flags->exclusive); @@ -319,6 +321,44 @@ int64_t NebdClient::GetFileSize(int fd) { return ret; } +int64_t NebdClient::GetBlockSize(int fd) { + auto task = [&](brpc::Controller* cntl, brpc::Channel* channel, + bool* rpcFailed) -> int64_t { + nebd::client::NebdFileService_Stub stub(channel); + nebd::client::GetInfoRequest request; + nebd::client::GetInfoResponse response; + + request.set_fd(fd); + stub.GetInfo(cntl, &request, &response, nullptr); + + *rpcFailed = cntl->Failed(); + if (*rpcFailed) { + LOG(WARNING) << "GetBlockSize failed, error = " << cntl->ErrorText() + << ", log id = " << cntl->log_id(); + return -1; + } else { + if (response.retcode() != nebd::client::RetCode::kOK) { + LOG(ERROR) << "GetBlockSize failed, " + << "retcode = " << response.retcode() + << ", retmsg = " << response.retmsg() + << ", fd = " << fd + << ", log id = " << cntl->log_id(); + return -1; + } else { + return response.info().has_blocksize() + ? response.info().blocksize() + : kDefaultBlockSize; + } + } + }; + + int64_t ret = ExecuteSyncRpc(task); + if (ret < 0) { + LOG(ERROR) << "GetBlockSize failed, fd = " << fd; + } + return ret; +} + int NebdClient::Discard(int fd, NebdClientAioContext* aioctx) { auto task = [this, fd, aioctx]() { nebd::client::NebdFileService_Stub stub(&channel_); diff --git a/nebd/src/part1/nebd_client.h b/nebd/src/part1/nebd_client.h index f30a786009..c814f9f711 100644 --- a/nebd/src/part1/nebd_client.h +++ b/nebd/src/part1/nebd_client.h @@ -100,6 +100,8 @@ class NebdClient { */ int64_t GetFileSize(int fd); + int64_t GetBlockSize(int fd); + /** * @brief discard文件,异步函数 * @param fd:文件的fd diff --git a/nebd/src/part2/define.h b/nebd/src/part2/define.h index 49ec2afe15..4c2fc54022 100644 --- a/nebd/src/part2/define.h +++ b/nebd/src/part2/define.h @@ -105,6 +105,8 @@ struct NebdFileInfo { uint64_t obj_size; // object数量 uint64_t num_objs; + // block size + uint32_t block_size; }; using ExtendAttribute = std::map; diff --git a/nebd/src/part2/file_service.cpp b/nebd/src/part2/file_service.cpp index 5a7f24bee1..8a7af09fb7 100644 --- a/nebd/src/part2/file_service.cpp +++ b/nebd/src/part2/file_service.cpp @@ -296,6 +296,7 @@ void NebdFileServiceImpl::GetInfo( info->set_size(fileInfo.size); info->set_objsize(fileInfo.obj_size); info->set_objnums(fileInfo.num_objs); + info->set_blocksize(fileInfo.block_size); response->set_retcode(RetCode::kOK); response->set_allocated_info(info); } diff --git a/nebd/src/part2/request_executor_curve.cpp b/nebd/src/part2/request_executor_curve.cpp index 37f1afae37..b983f35812 100644 --- a/nebd/src/part2/request_executor_curve.cpp +++ b/nebd/src/part2/request_executor_curve.cpp @@ -180,12 +180,14 @@ int CurveRequestExecutor::GetInfo( return -1; } - int64_t size = client_->StatFile(fileName); - if (size < 0) { + FileStatInfo statInfo; + int64_t rc = client_->StatFile(fileName, &statInfo); + if (rc < 0) { return -1; } - fileInfo->size = size; + fileInfo->size = statInfo.length; + fileInfo->block_size = statInfo.blocksize; return 0; } diff --git a/nebd/test/part1/fake_file_service.cpp b/nebd/test/part1/fake_file_service.cpp index b172da765b..d48c043864 100644 --- a/nebd/test/part1/fake_file_service.cpp +++ b/nebd/test/part1/fake_file_service.cpp @@ -157,6 +157,7 @@ void FakeNebdFileService::GetInfo(::google::protobuf::RpcController* controller, info->set_size(fileSize_); info->set_objsize(fileSize_); info->set_objnums(1); + info->set_blocksize(blockSize_); response->set_retcode(RetCode::kOK); response->set_retmsg("GetInfo OK"); response->set_allocated_info(info); diff --git a/nebd/test/part1/fake_file_service.h b/nebd/test/part1/fake_file_service.h index dd635e3cfb..a11a602f8f 100644 --- a/nebd/test/part1/fake_file_service.h +++ b/nebd/test/part1/fake_file_service.h @@ -33,7 +33,8 @@ namespace client { class FakeNebdFileService: public NebdFileService { public: - FakeNebdFileService() {} + explicit FakeNebdFileService(uint32_t blockSize = 4096) + : fileSize_(0), blockSize_(blockSize) {} virtual ~FakeNebdFileService() {} @@ -84,6 +85,7 @@ class FakeNebdFileService: public NebdFileService { private: int64_t fileSize_; + uint32_t blockSize_; }; } // namespace client } // namespace nebd diff --git a/nebd/test/part1/nebd_lib_unittest.cpp b/nebd/test/part1/nebd_lib_unittest.cpp index 1d7cdf3291..658ebd20ce 100644 --- a/nebd/test/part1/nebd_lib_unittest.cpp +++ b/nebd/test/part1/nebd_lib_unittest.cpp @@ -41,6 +41,7 @@ const char* kFileName = "nebd-lib-test-filename"; const char* kNebdServerTestAddress = "./nebd-lib-unittest.sock"; const char* kNebdClientConf = "./nebd/test/part1/nebd-lib-test.conf"; const int64_t kFileSize = 10LL * 1024 * 1024 * 1024; +const uint32_t kBlockSize = 4096; const int64_t kBufSize = 1024; namespace nebd { @@ -89,7 +90,7 @@ class NebdLibTest : public ::testing::Test { } brpc::Server server; - FakeNebdFileService fakeService; + FakeNebdFileService fakeService{kBlockSize}; MockNebdFileService mockService; }; @@ -106,6 +107,7 @@ TEST_F(NebdLibTest, CommonTest) { ASSERT_EQ(0, nebd_lib_resize(fd, kFileSize)); ASSERT_EQ(kFileSize, nebd_lib_filesize(fd)); ASSERT_EQ(kFileSize, nebd_lib_getinfo(fd)); + ASSERT_EQ(kBlockSize, nebd_lib_blocksize(fd)); ASSERT_EQ(0, nebd_lib_invalidcache(fd)); ASSERT_EQ(-1, nebd_lib_pread(fd, 0, 0, 0)); diff --git a/nebd/test/part2/mock_curve_client.h b/nebd/test/part2/mock_curve_client.h index 6b94c21b9f..23c9854051 100644 --- a/nebd/test/part2/mock_curve_client.h +++ b/nebd/test/part2/mock_curve_client.h @@ -42,6 +42,7 @@ class MockCurveClient : public ::curve::client::CurveClient { MOCK_METHOD1(Close, int(int)); MOCK_METHOD2(Extend, int(const std::string&, int64_t)); MOCK_METHOD1(StatFile, int64_t(const std::string&)); + MOCK_METHOD2(StatFile, int64_t(const std::string&, FileStatInfo*)); MOCK_METHOD3(AioRead, int(int, CurveAioContext*, curve::client::UserDataType)); MOCK_METHOD3(AioWrite, diff --git a/nebd/test/part2/test_request_executor_curve.cpp b/nebd/test/part2/test_request_executor_curve.cpp index 131e92d3a4..8541e41979 100644 --- a/nebd/test/part2/test_request_executor_curve.cpp +++ b/nebd/test/part2/test_request_executor_curve.cpp @@ -36,6 +36,7 @@ using ::testing::_; using ::testing::SetArgPointee; using ::testing::DoAll; using ::testing::SaveArg; +using ::testing::Invoke; class TestReuqestExecutorCurveClosure : public google::protobuf::Closure { public: @@ -231,14 +232,14 @@ TEST_F(TestReuqestExecutorCurve, test_GetInfo) { // 1. nebdFileIns不是CurveFileInstance类型, stat失败 { auto nebdFileIns = new NebdFileInstance(); - EXPECT_CALL(*curveClient_, StatFile(_)).Times(0); + EXPECT_CALL(*curveClient_, StatFile(_, _)).Times(0); ASSERT_EQ(-1, executor.GetInfo(nebdFileIns, &fileInfo)); } // 2. nebdFileIns中的fileName为空, extend失败 { auto curveFileIns = new CurveFileInstance(); - EXPECT_CALL(*curveClient_, StatFile(_)).Times(0); + EXPECT_CALL(*curveClient_, StatFile(_, _)).Times(0); ASSERT_EQ(-1, executor.GetInfo(curveFileIns, &fileInfo)); } @@ -246,18 +247,27 @@ TEST_F(TestReuqestExecutorCurve, test_GetInfo) { { auto curveFileIns = new CurveFileInstance(); curveFileIns->fileName = curveFilename; - EXPECT_CALL(*curveClient_, StatFile(curveFilename)) + EXPECT_CALL(*curveClient_, StatFile(curveFilename, _)) .WillOnce(Return(-1)); ASSERT_EQ(-1, executor.GetInfo(curveFileIns, &fileInfo)); } // 4. extend成功 { + const uint64_t size = 10ull * 1024 * 1024 * 1024; + const uint32_t blocksize = 4096; auto curveFileIns = new CurveFileInstance(); curveFileIns->fileName = curveFilename; - EXPECT_CALL(*curveClient_, StatFile(curveFilename)).WillOnce(Return(1)); + EXPECT_CALL(*curveClient_, StatFile(curveFilename, _)) + .WillOnce(Invoke( + [size, blocksize](const std::string&, FileStatInfo* info) { + info->length = size; + info->blocksize = blocksize; + return 0; + })); ASSERT_EQ(0, executor.GetInfo(curveFileIns, &fileInfo)); - ASSERT_EQ(1, fileInfo.size); + ASSERT_EQ(size, fileInfo.size); + ASSERT_EQ(blocksize, fileInfo.block_size); } } diff --git a/proto/nameserver2.proto b/proto/nameserver2.proto index 14fb04628c..21d27a3e40 100644 --- a/proto/nameserver2.proto +++ b/proto/nameserver2.proto @@ -92,6 +92,7 @@ message FileInfo { optional uint64 stripeCount = 16; optional FileThrottleParams throttleParams = 17; + optional uint32 blocksize = 18; } // status code diff --git a/proto/topology.proto b/proto/topology.proto index 678a209aa1..18666e6d51 100644 --- a/proto/topology.proto +++ b/proto/topology.proto @@ -149,6 +149,7 @@ message ChunkServerRegistRequest { required string hostIp = 3; required uint32 port = 4; optional string externalIp = 5; + optional uint32 blockSize = 6; }; message ChunkServerRegistResponse { diff --git a/src/chunkserver/chunk_service.cpp b/src/chunkserver/chunk_service.cpp index d70138b7b4..1c90cacaad 100755 --- a/src/chunkserver/chunk_service.cpp +++ b/src/chunkserver/chunk_service.cpp @@ -35,14 +35,19 @@ #include "src/chunkserver/chunkserver_metrics.h" #include "src/chunkserver/op_request.h" #include "src/chunkserver/chunk_service_closure.h" +#include "src/common/fast_align.h" namespace curve { namespace chunkserver { -ChunkServiceImpl::ChunkServiceImpl(ChunkServiceOptions chunkServiceOptions) : - chunkServiceOptions_(chunkServiceOptions), - copysetNodeManager_(chunkServiceOptions.copysetNodeManager), - inflightThrottle_(chunkServiceOptions.inflightThrottle) { +using curve::common::is_aligned; + +ChunkServiceImpl::ChunkServiceImpl( + const ChunkServiceOptions &chunkServiceOptions) + : chunkServiceOptions_(chunkServiceOptions), + copysetNodeManager_(chunkServiceOptions.copysetNodeManager), + inflightThrottle_(chunkServiceOptions.inflightThrottle), + ioAlignment_(copysetNodeManager_->GetCopysetNodeOptions().blockSize) { maxChunkSize_ = copysetNodeManager_->GetCopysetNodeOptions().maxChunkSize; } @@ -541,17 +546,7 @@ bool ChunkServiceImpl::CheckRequestOffsetAndLength(uint32_t offset, return false; } - // 检查offset是否对齐 - if (offset % kOpRequestAlignSize != 0) { - return false; - } - - // 检查len是否对齐 - if (len % kOpRequestAlignSize != 0) { - return false; - } - - return true; + return is_aligned(offset, ioAlignment_) && is_aligned(len, ioAlignment_); } } // namespace chunkserver diff --git a/src/chunkserver/chunk_service.h b/src/chunkserver/chunk_service.h index 0d419f1015..00b0cd0fdf 100755 --- a/src/chunkserver/chunk_service.h +++ b/src/chunkserver/chunk_service.h @@ -40,7 +40,7 @@ class CopysetNodeManager; class ChunkServiceImpl : public ChunkService { public: - explicit ChunkServiceImpl(ChunkServiceOptions chunkServiceOptions); + explicit ChunkServiceImpl(const ChunkServiceOptions& chunkServiceOptions); ~ChunkServiceImpl() {} void DeleteChunk(RpcController *controller, @@ -105,6 +105,7 @@ class ChunkServiceImpl : public ChunkService { CopysetNodeManager *copysetNodeManager_; std::shared_ptr inflightThrottle_; uint32_t maxChunkSize_; + uint32_t ioAlignment_; }; } // namespace chunkserver diff --git a/src/chunkserver/chunkserver.cpp b/src/chunkserver/chunkserver.cpp index b6b31c275f..4d389deec8 100644 --- a/src/chunkserver/chunkserver.cpp +++ b/src/chunkserver/chunkserver.cpp @@ -58,7 +58,7 @@ DEFINE_string(chunkServerExternalIp, "127.0.0.1", "chunkserver external ip"); DEFINE_int32(chunkServerPort, 8200, "chunkserver port"); DEFINE_string(chunkServerStoreUri, "local://./0/", "chunkserver store uri"); DEFINE_string(chunkServerMetaUri, - "local://./0/chunkserver.dat", "chunnkserver meata uri"); + "local://./0/chunkserver.dat", "chunkserver meta uri"); DEFINE_string(copySetUri, "local://./0/copysets", "copyset data uri"); DEFINE_string(raftSnapshotUri, "curve://./0/copysets", "raft snapshot uri"); DEFINE_string(raftLogUri, "curve://./0/copysets", "raft log uri"); @@ -135,6 +135,7 @@ int ChunkServer::Run(int argc, char** argv) { InitChunkFilePoolOptions(&conf, &chunkFilePoolOptions); std::shared_ptr chunkfilePool = std::make_shared(fs); + LOG_IF(FATAL, false == chunkfilePool->Initialize(chunkFilePoolOptions)) << "Failed to init chunk file pool"; @@ -185,11 +186,12 @@ int ChunkServer::Run(int argc, char** argv) { RegisterOptions registerOptions; InitRegisterOptions(&conf, ®isterOptions); registerOptions.fs = fs; + registerOptions.blockSize = chunkfilePool->GetFilePoolOpt().blockSize; Register registerMDS(registerOptions); ChunkServerMetadata metadata; // 从本地获取meta - std::string metaPath = UriParser::GetPathFromUri( - registerOptions.chunkserverMetaUri).c_str(); + std::string metaPath = + UriParser::GetPathFromUri(registerOptions.chunkserverMetaUri); if (fs->FileExists(metaPath)) { LOG_IF(FATAL, GetChunkServerMetaFromLocal( registerOptions.chunserverStoreUri, @@ -455,8 +457,15 @@ void ChunkServer::InitChunkFilePoolOptions( common::Configuration *conf, FilePoolOptions *chunkFilePoolOptions) { LOG_IF(FATAL, !conf->GetUInt32Value("global.chunk_size", &chunkFilePoolOptions->fileSize)); + LOG_IF(FATAL, !conf->GetUInt32Value("global.meta_page_size", - &chunkFilePoolOptions->metaPageSize)); + &chunkFilePoolOptions->metaPageSize)) + << "Not found `global.meta_page_size` in config file"; + + LOG_IF(FATAL, !conf->GetUInt32Value("global.block_size", + &chunkFilePoolOptions->blockSize)) + << "Not found `global.block_size` in config file"; + LOG_IF(FATAL, !conf->GetUInt32Value("chunkfilepool.cpmeta_file_size", &chunkFilePoolOptions->metaFileSize)); LOG_IF(FATAL, !conf->GetBoolValue( @@ -561,6 +570,10 @@ void ChunkServer::InitCopysetNodeOptions( ©setNodeOptions->recyclerUri)); LOG_IF(FATAL, !conf->GetUInt32Value("global.chunk_size", ©setNodeOptions->maxChunkSize)); + LOG_IF(FATAL, !conf->GetUInt32Value("global.meta_page_size", + ©setNodeOptions->metaPageSize)); + LOG_IF(FATAL, !conf->GetUInt32Value("global.block_size", + ©setNodeOptions->blockSize)); LOG_IF(FATAL, !conf->GetUInt32Value("global.location_limit", ©setNodeOptions->locationLimit)); LOG_IF(FATAL, !conf->GetUInt32Value("copyset.load_concurrency", diff --git a/src/chunkserver/clone_core.cpp b/src/chunkserver/clone_core.cpp index 0058f449a6..a4e58c5630 100644 --- a/src/chunkserver/clone_core.cpp +++ b/src/chunkserver/clone_core.cpp @@ -140,24 +140,24 @@ int CloneCore::CloneReadByLocalInfo( const ChunkRequest* request = readRequest->request_; off_t offset = request->offset(); size_t length = request->size(); - uint32_t pageSize = chunkInfo.pageSize; + const uint32_t blockSize = chunkInfo.blockSize; - // offset 和 length 必须与 pageSize 对齐 - if (offset % pageSize != 0 || length % pageSize != 0) { + // offset 和 length 必须与 blockSize 对齐 + if (offset % blockSize != 0 || length % blockSize != 0) { LOG(ERROR) << "Invalid offset or length: " << " logic pool id: " << request->logicpoolid() << " copyset id: " << request->copysetid() << " chunkid: " << request->chunkid() << " offset: " << offset << " length: " << length - << " page size: " << pageSize; + << " block size: " << blockSize; SetResponse(readRequest, CHUNK_OP_STATUS::CHUNK_OP_STATUS_INVALID_REQUEST); return -1; } - uint32_t beginIndex = offset / pageSize; - uint32_t endIndex = (offset + length - 1) / pageSize; + uint32_t beginIndex = offset / blockSize; + uint32_t endIndex = (offset + length - 1) / blockSize; // 请求提交到CloneManager的时候,chunk一定是clone chunk // 但是由于有其他请求操作相同的chunk,此时chunk有可能已经被遍写过了 @@ -359,9 +359,9 @@ int CloneCore::ReadThenMerge(std::shared_ptr readRequest, off_t offset = request->offset(); size_t length = request->size(); - uint32_t pageSize = chunkInfo.pageSize; - uint32_t beginIndex = offset / pageSize; - uint32_t endIndex = (offset + length - 1) / pageSize; + uint32_t blockSize = chunkInfo.blockSize; + uint32_t beginIndex = offset / blockSize; + uint32_t endIndex = (offset + length - 1) / blockSize; // 获取chunk文件已经写过和未被写过的区域 std::vector copiedRanges; std::vector uncopiedRanges; @@ -386,8 +386,8 @@ int CloneCore::ReadThenMerge(std::shared_ptr readRequest, // 1.Read 对于已写过的区域,从chunk文件中读取 CSErrorCode errorCode; for (auto& range : copiedRanges) { - readOff = range.beginIndex * pageSize; - readSize = (range.endIndex - range.beginIndex + 1) * pageSize; + readOff = range.beginIndex * blockSize; + readSize = (range.endIndex - range.beginIndex + 1) * blockSize; relativeOff = readOff - offset; errorCode = dataStore->ReadChunk(request->chunkid(), request->sn(), @@ -408,8 +408,8 @@ int CloneCore::ReadThenMerge(std::shared_ptr readRequest, // 2.Merge 对于未写过的区域,从源端下载的区域中拷贝出来进行merge for (auto& range : uncopiedRanges) { - readOff = range.beginIndex * pageSize; - readSize = (range.endIndex - range.beginIndex + 1) * pageSize; + readOff = range.beginIndex * blockSize; + readSize = (range.endIndex - range.beginIndex + 1) * blockSize; relativeOff = readOff - offset; cloneData->copy_to(chunkData + relativeOff, readSize, relativeOff); } diff --git a/src/chunkserver/config_info.cpp b/src/chunkserver/config_info.cpp deleted file mode 100644 index 63d9b9205d..0000000000 --- a/src/chunkserver/config_info.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: curve - * Created Date: 19-2-28 - * Author: wudemiao - */ - -#include "src/chunkserver/config_info.h" - -#include "src/chunkserver/copyset_node_manager.h" -#include "src/chunkserver/concurrent_apply/concurrent_apply.h" -#include "src/chunkserver/datastore/file_pool.h" - -namespace curve { -namespace chunkserver { - -CopysetNodeOptions::CopysetNodeOptions() - : electionTimeoutMs(1000), - snapshotIntervalS(3600), - catchupMargin(1000), - usercodeInPthread(false), - logUri("/log"), - raftMetaUri("/raft_meta"), - raftSnapshotUri("/raft_snapshot"), - chunkDataUri("/data"), - chunkSnapshotUri("/snapshot"), - recyclerUri("/recycler"), - port(8200), - maxChunkSize(16 * 1024 * 1024), - pageSize(4096), - concurrentapply(nullptr), - chunkFilePool(nullptr), - walFilePool(nullptr), - localFileSystem(nullptr), - snapshotThrottle(nullptr) { -} - -} // namespace chunkserver -} // namespace curve diff --git a/src/chunkserver/config_info.h b/src/chunkserver/config_info.h index b5938d9e73..945eabbc75 100644 --- a/src/chunkserver/config_info.h +++ b/src/chunkserver/config_info.h @@ -89,7 +89,9 @@ struct CopysetNodeOptions { // WAL segment file size uint32_t maxWalSegmentSize; // chunk文件的page大小 - uint32_t pageSize; + uint32_t metaPageSize; + // alignment for I/O request + uint32_t blockSize; // clone chunk的location长度限制 uint32_t locationLimit; @@ -140,6 +142,27 @@ struct ChunkServiceOptions { std::shared_ptr inflightThrottle; }; +inline CopysetNodeOptions::CopysetNodeOptions() + : electionTimeoutMs(1000), + snapshotIntervalS(3600), + catchupMargin(1000), + usercodeInPthread(false), + logUri("/log"), + raftMetaUri("/raft_meta"), + raftSnapshotUri("/raft_snapshot"), + chunkDataUri("/data"), + chunkSnapshotUri("/snapshot"), + recyclerUri("/recycler"), + port(8200), + maxChunkSize(16 * 1024 * 1024), + metaPageSize(4096), + blockSize(4096), + concurrentapply(nullptr), + chunkFilePool(nullptr), + walFilePool(nullptr), + localFileSystem(nullptr), + snapshotThrottle(nullptr) {} + } // namespace chunkserver } // namespace curve diff --git a/src/chunkserver/copyset_node.cpp b/src/chunkserver/copyset_node.cpp index 57a2b65030..eec9f51ab8 100755 --- a/src/chunkserver/copyset_node.cpp +++ b/src/chunkserver/copyset_node.cpp @@ -120,7 +120,8 @@ int CopysetNode::Init(const CopysetNodeOptions &options) { DataStoreOptions dsOptions; dsOptions.baseDir = chunkDataApath_; dsOptions.chunkSize = options.maxChunkSize; - dsOptions.pageSize = options.pageSize; + dsOptions.metaPageSize = options.metaPageSize; + dsOptions.blockSize = options.blockSize; dsOptions.locationLimit = options.locationLimit; dsOptions.enableOdsyncWhenOpenChunkFile = options.enableOdsyncWhenOpenChunkFile; diff --git a/src/chunkserver/datastore/chunkserver_chunkfile.cpp b/src/chunkserver/datastore/chunkserver_chunkfile.cpp index c59941a63c..076e362927 100644 --- a/src/chunkserver/datastore/chunkserver_chunkfile.cpp +++ b/src/chunkserver/datastore/chunkserver_chunkfile.cpp @@ -134,7 +134,8 @@ CSChunkFile::CSChunkFile(std::shared_ptr lfs, const ChunkOptions& options) : fd_(-1), size_(options.chunkSize), - pageSize_(options.pageSize), + blockSize_(options.blockSize), + metaPageSize_(options.metaPageSize), chunkId_(options.id), baseDir_(options.baseDir), isCloneChunk_(false), @@ -151,7 +152,7 @@ CSChunkFile::CSChunkFile(std::shared_ptr lfs, // If location is not empty, it is CloneChunk, // and Bitmap needs to be initialized if (!metaPage_.location.empty()) { - uint32_t bits = size_ / pageSize_; + uint32_t bits = size_ / blockSize_; metaPage_.bitmap = std::make_shared(bits); } if (metric_ != nullptr) { @@ -187,8 +188,8 @@ CSErrorCode CSChunkFile::Open(bool createFile) { if (createFile && !lfs_->FileExists(chunkFilePath) && metaPage_.sn > 0) { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); metaPage_.version = FORMAT_VERSION_V2; metaPage_.encode(buf.get()); @@ -258,7 +259,8 @@ CSErrorCode CSChunkFile::LoadSnapshot(SequenceNum sn) { options.sn = sn; options.baseDir = baseDir_; options.chunkSize = size_; - options.pageSize = pageSize_; + options.blockSize = blockSize_; + options.metaPageSize = metaPageSize_; options.metric = metric_; snapshot_ = new(std::nothrow) CSSnapshot(lfs_, chunkFilePool_, @@ -288,8 +290,9 @@ CSErrorCode CSChunkFile::Write(SequenceNum sn, << "ChunkID: " << chunkId_ << ", offset: " << offset << ", length: " << length - << ", page size: " << pageSize_ - << ", chunk size: " << size_; + << ", page size: " << metaPageSize_ + << ", chunk size: " << size_ + << ", block size: " << blockSize_; return CSErrorCode::InvalidArgError; } // Curve will ensure that all previous requests arrive or time out @@ -332,7 +335,8 @@ CSErrorCode CSChunkFile::Write(SequenceNum sn, options.sn = metaPage_.sn; options.baseDir = baseDir_; options.chunkSize = size_; - options.pageSize = pageSize_; + options.blockSize = blockSize_; + options.metaPageSize = metaPageSize_; options.metric = metric_; snapshot_ = new(std::nothrow) CSSnapshot(lfs_, chunkFilePool_, @@ -422,8 +426,9 @@ CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) { << "ChunkID: " << chunkId_ << ", offset: " << offset << ", length: " << length - << ", page size: " << pageSize_ - << ", chunk size: " << size_; + << ", page size: " << metaPageSize_ + << ", chunk size: " << size_ + << ", block size: " << blockSize_; return CSErrorCode::InvalidArgError; } // If it is not a clone chunk, return success directly @@ -431,11 +436,11 @@ CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) { return CSErrorCode::Success; } - // The request above must be pagesize aligned + // The request above must be blocksize aligned // the starting page index number of the paste area - uint32_t beginIndex = offset / pageSize_; + uint32_t beginIndex = offset / blockSize_; // the last page index number of the paste area - uint32_t endIndex = (offset + length - 1) / pageSize_; + uint32_t endIndex = (offset + length - 1) / blockSize_; // Get the unwritten range of the current file std::vector uncopiedRange; metaPage_.bitmap->Divide(beginIndex, @@ -447,8 +452,8 @@ CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) { off_t pasteOff; size_t pasteSize; for (auto& range : uncopiedRange) { - pasteOff = range.beginIndex * pageSize_; - pasteSize = (range.endIndex - range.beginIndex + 1) * pageSize_; + pasteOff = range.beginIndex * blockSize_; + pasteSize = (range.endIndex - range.beginIndex + 1) * blockSize_; int rc = writeData(buf + (pasteOff - offset), pasteOff, pasteSize); if (rc < 0) { LOG(ERROR) << "Paste data to chunk failed." @@ -478,19 +483,20 @@ CSErrorCode CSChunkFile::Read(char * buf, off_t offset, size_t length) { << "ChunkID: " << chunkId_ << ", offset: " << offset << ", length: " << length - << ", page size: " << pageSize_ - << ", chunk size: " << size_; + << ", page size: " << metaPageSize_ + << ", chunk size: " << size_ + << ", block size: " << blockSize_; return CSErrorCode::InvalidArgError; } // If it is clonechunk, ensure that the read area has been written, // otherwise an error is returned if (isCloneChunk_) { - // The request above must be pagesize aligned + // The request above must be blocksize aligned // the starting page index number of the paste area - uint32_t beginIndex = offset / pageSize_; + uint32_t beginIndex = offset / blockSize_; // the last page index number of the paste area - uint32_t endIndex = (offset + length - 1) / pageSize_; + uint32_t endIndex = (offset + length - 1) / blockSize_; if (metaPage_.bitmap->NextClearBit(beginIndex, endIndex) != Bitmap::NO_POS) { LOG(ERROR) << "Read chunk file failed, has page never written." @@ -533,8 +539,9 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn, << "ChunkID: " << chunkId_ << ", offset: " << offset << ", length: " << length - << ", page size: " << pageSize_ - << ", chunk size: " << size_; + << ", page size: " << metaPageSize_ + << ", chunk size: " << size_ + << ", block size: " << blockSize_; return CSErrorCode::InvalidArgError; } // If the sequence equals the sequence of the current chunk, @@ -556,13 +563,13 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn, } // Get the copied areas and uncopied areas in the snapshot file - uint32_t pageBeginIndex = offset / pageSize_; - uint32_t pageEndIndex = (offset + length - 1) / pageSize_; + uint32_t blockBeginIndex = offset / blockSize_; + uint32_t blockEndIndex = (offset + length - 1) / blockSize_; std::vector copiedRange; std::vector uncopiedRange; std::shared_ptr snapBitmap = snapshot_->GetPageStatus(); - snapBitmap->Divide(pageBeginIndex, - pageEndIndex, + snapBitmap->Divide(blockBeginIndex, + blockEndIndex, &uncopiedRange, &copiedRange); @@ -581,8 +588,8 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn, size_t readSize; // For uncopied extents, read chunk data for (auto& range : uncopiedRange) { - readOff = range.beginIndex * pageSize_; - readSize = (range.endIndex - range.beginIndex + 1) * pageSize_; + readOff = range.beginIndex * blockSize_; + readSize = (range.endIndex - range.beginIndex + 1) * blockSize_; int rc = readData(buf + (readOff - offset), readOff, readSize); @@ -595,8 +602,8 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn, } // For the copied range, read the snapshot data for (auto& range : copiedRange) { - readOff = range.beginIndex * pageSize_; - readSize = (range.endIndex - range.beginIndex + 1) * pageSize_; + readOff = range.beginIndex * blockSize_; + readSize = (range.endIndex - range.beginIndex + 1) * blockSize_; errorCode = snapshot_->Read(buf + (readOff - offset), readOff, readSize); @@ -736,8 +743,9 @@ CSErrorCode CSChunkFile::DeleteSnapshotOrCorrectSn(SequenceNum correctedSn) { void CSChunkFile::GetInfo(CSChunkInfo* info) { ReadLockGuard readGuard(rwLock_); info->chunkId = chunkId_; - info->pageSize = pageSize_; + info->metaPageSize = metaPageSize_; info->chunkSize = size_; + info->blockSize = blockSize_; info->curSn = metaPage_.sn; info->correctedSn = metaPage_.correctedSn; info->snapSn = (snapshot_ == nullptr @@ -858,8 +866,8 @@ bool CSChunkFile::needCow(SequenceNum sn) { } CSErrorCode CSChunkFile::updateMetaPage(ChunkFileMetaPage* metaPage) { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); metaPage->encode(buf.get()); int rc = writeMetaPage(buf.get()); if (rc < 0) { @@ -872,8 +880,8 @@ CSErrorCode CSChunkFile::updateMetaPage(ChunkFileMetaPage* metaPage) { } CSErrorCode CSChunkFile::loadMetaPage() { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); int rc = readMetaPage(buf.get()); if (rc < 0) { LOG(ERROR) << "Error occured when reading metaPage_." @@ -885,8 +893,8 @@ CSErrorCode CSChunkFile::loadMetaPage() { CSErrorCode CSChunkFile::copy2Snapshot(off_t offset, size_t length) { // Get the uncopied area in the snapshot file - uint32_t pageBeginIndex = offset / pageSize_; - uint32_t pageEndIndex = (offset + length - 1) / pageSize_; + uint32_t pageBeginIndex = offset / blockSize_; + uint32_t pageEndIndex = (offset + length - 1) / blockSize_; std::vector uncopiedRange; std::shared_ptr snapBitmap = snapshot_->GetPageStatus(); snapBitmap->Divide(pageBeginIndex, @@ -900,10 +908,9 @@ CSErrorCode CSChunkFile::copy2Snapshot(off_t offset, size_t length) { // Read the uncopied area from the chunk file // and write it to the snapshot file for (auto& range : uncopiedRange) { - copyOff = range.beginIndex * pageSize_; - copySize = (range.endIndex - range.beginIndex + 1) * pageSize_; - std::shared_ptr buf(new char[copySize], - std::default_delete()); + copyOff = range.beginIndex * blockSize_; + copySize = (range.endIndex - range.beginIndex + 1) * blockSize_; + std::unique_ptr buf(new char[copySize]); int rc = readData(buf.get(), copyOff, copySize); diff --git a/src/chunkserver/datastore/chunkserver_chunkfile.h b/src/chunkserver/datastore/chunkserver_chunkfile.h index eac696174f..3decddeaa8 100644 --- a/src/chunkserver/datastore/chunkserver_chunkfile.h +++ b/src/chunkserver/datastore/chunkserver_chunkfile.h @@ -40,6 +40,7 @@ #include "src/chunkserver/datastore/chunkserver_snapshot.h" #include "src/chunkserver/datastore/define.h" #include "src/chunkserver/datastore/file_pool.h" +#include "src/common/fast_align.h" namespace curve { namespace chunkserver { @@ -105,8 +106,11 @@ struct ChunkOptions { // The size of the page, each bit in the bitmap represents 1 page, // and the size of the metapage is also 1 page PageSizeType pageSize; + ChunkSizeType blockSize; // enable O_DSYNC When Open ChunkFile bool enableOdsyncWhenOpenChunkFile; + // The size of the meta page, each bit in the bitmap represents 1 block + PageSizeType metaPageSize; // datastore internal statistical metric std::shared_ptr metric; @@ -116,7 +120,8 @@ struct ChunkOptions { , baseDir("") , location("") , chunkSize(0) - , pageSize(0) + , blockSize(0) + , metaPageSize(0) , metric(nullptr) {} }; @@ -306,31 +311,31 @@ class CSChunkFile { } inline uint32_t fileSize() { - return pageSize_ + size_; + return metaPageSize_ + size_; } inline int readMetaPage(char* buf) { - return lfs_->Read(fd_, buf, 0, pageSize_); + return lfs_->Read(fd_, buf, 0, metaPageSize_); } inline int writeMetaPage(const char* buf) { - return lfs_->Write(fd_, buf, 0, pageSize_); + return lfs_->Write(fd_, buf, 0, metaPageSize_); } inline int readData(char* buf, off_t offset, size_t length) { - return lfs_->Read(fd_, buf, offset + pageSize_, length); + return lfs_->Read(fd_, buf, offset + metaPageSize_, length); } inline int writeData(const char* buf, off_t offset, size_t length) { - int rc = lfs_->Write(fd_, buf, offset + pageSize_, length); + int rc = lfs_->Write(fd_, buf, offset + metaPageSize_, length); if (rc < 0) { return rc; } // If it is a clone chunk, you need to determine whether you need to // change the bitmap and update the metapage if (isCloneChunk_) { - uint32_t beginIndex = offset / pageSize_; - uint32_t endIndex = (offset + length - 1) / pageSize_; + uint32_t beginIndex = offset / blockSize_; + uint32_t endIndex = (offset + length - 1) / blockSize_; for (uint32_t i = beginIndex; i <= endIndex; ++i) { // record dirty page if (!metaPage_.bitmap->Test(i)) { @@ -342,15 +347,16 @@ class CSChunkFile { } inline int writeData(const butil::IOBuf& buf, off_t offset, size_t length) { - int rc = lfs_->Write(fd_, buf, offset + pageSize_, length); + int rc = lfs_->Write(fd_, buf, offset + metaPageSize_, length); if (rc < 0) { return rc; } // If it is a clone chunk, you need to determine whether you need to // change the bitmap and update the metapage + // page size to alignment if (isCloneChunk_) { - uint32_t beginIndex = offset / pageSize_; - uint32_t endIndex = (offset + length - 1) / pageSize_; + uint32_t beginIndex = offset / blockSize_; + uint32_t endIndex = (offset + length - 1) / blockSize_; for (uint32_t i = beginIndex; i <= endIndex; ++i) { // record dirty page if (!metaPage_.bitmap->Test(i)) { @@ -371,17 +377,8 @@ class CSChunkFile { return false; } - // Check if the offset is aligned - if (offset % pageSize_ != 0) { - return false; - } - - // Check if len is aligned - if (len % pageSize_ != 0) { - return false; - } - - return true; + return common::is_aligned(offset, blockSize_) && + common::is_aligned(len, blockSize_); } private: @@ -389,8 +386,8 @@ class CSChunkFile { int fd_; // The logical size of the chunk, not including metapage ChunkSizeType size_; - // The smallest atomic read and write unit - PageSizeType pageSize_; + ChunkSizeType blockSize_; + PageSizeType metaPageSize_; // chunk id ChunkID chunkId_; // The directory where the chunk is located diff --git a/src/chunkserver/datastore/chunkserver_datastore.cpp b/src/chunkserver/datastore/chunkserver_datastore.cpp index 3eed89d747..db720e3d87 100644 --- a/src/chunkserver/datastore/chunkserver_datastore.cpp +++ b/src/chunkserver/datastore/chunkserver_datastore.cpp @@ -38,7 +38,8 @@ CSDataStore::CSDataStore(std::shared_ptr lfs, std::shared_ptr chunkFilePool, const DataStoreOptions& options) : chunkSize_(options.chunkSize), - pageSize_(options.pageSize), + blockSize_(options.blockSize), + metaPageSize_(options.metaPageSize), baseDir_(options.baseDir), locationLimit_(options.locationLimit), chunkFilePool_(chunkFilePool), @@ -248,7 +249,8 @@ CSErrorCode CSDataStore::WriteChunk(ChunkID id, options.baseDir = baseDir_; options.chunkSize = chunkSize_; options.location = cloneSourceLocation; - options.pageSize = pageSize_; + options.blockSize = blockSize_; + options.metaPageSize = metaPageSize_; options.metric = metric_; options.enableOdsyncWhenOpenChunkFile = enableOdsyncWhenOpenChunkFile_; CSErrorCode errorCode = CreateChunkFile(options, &chunkFile); @@ -312,7 +314,8 @@ CSErrorCode CSDataStore::CreateCloneChunk(ChunkID id, options.location = location; options.baseDir = baseDir_; options.chunkSize = chunkSize_; - options.pageSize = pageSize_; + options.blockSize = blockSize_; + options.metaPageSize = metaPageSize_; options.metric = metric_; CSErrorCode errorCode = CreateChunkFile(options, &chunkFile); if (errorCode != CSErrorCode::Success) { @@ -404,7 +407,8 @@ CSErrorCode CSDataStore::loadChunkFile(ChunkID id) { options.sn = 0; options.baseDir = baseDir_; options.chunkSize = chunkSize_; - options.pageSize = pageSize_; + options.blockSize = blockSize_; + options.metaPageSize = metaPageSize_; options.metric = metric_; CSChunkFilePtr chunkFilePtr = std::make_shared(lfs_, diff --git a/src/chunkserver/datastore/chunkserver_datastore.h b/src/chunkserver/datastore/chunkserver_datastore.h index abc343ad9a..81fae05d39 100644 --- a/src/chunkserver/datastore/chunkserver_datastore.h +++ b/src/chunkserver/datastore/chunkserver_datastore.h @@ -46,18 +46,20 @@ using curve::fs::LocalFileSystem; using ::curve::common::Atomic; using CSChunkFilePtr = std::shared_ptr; -inline void TrivialDeleter(void* ptr) {} +inline void TrivialDeleter(void* /*ptr*/) {} /** * DataStore configuration parameters * baseDir: Directory path managed by DataStore * chunkSize: The size of the chunk file or snapshot file in the DataStore - * pageSize: the size of the smallest read-write unit + * blockSize: the size of the smallest read-write unit + * metaPageSize: meta page size for chunk */ struct DataStoreOptions { std::string baseDir; ChunkSizeType chunkSize; - PageSizeType pageSize; + ChunkSizeType blockSize; + PageSizeType metaPageSize; uint32_t locationLimit; bool enableOdsyncWhenOpenChunkFile; }; @@ -320,7 +322,8 @@ class CSDataStore { // The size of each chunk ChunkSizeType chunkSize_; // page size, which is the smallest atomic read and write unit - PageSizeType pageSize_; + ChunkSizeType blockSize_; + PageSizeType metaPageSize_; // clone chunk location length limit uint32_t locationLimit_; // datastore management directory diff --git a/src/chunkserver/datastore/chunkserver_snapshot.cpp b/src/chunkserver/datastore/chunkserver_snapshot.cpp index fb0af1d6ed..f1e398e8c6 100644 --- a/src/chunkserver/datastore/chunkserver_snapshot.cpp +++ b/src/chunkserver/datastore/chunkserver_snapshot.cpp @@ -111,14 +111,15 @@ CSSnapshot::CSSnapshot(std::shared_ptr lfs, : fd_(-1), chunkId_(options.id), size_(options.chunkSize), - pageSize_(options.pageSize), + blockSize_(options.blockSize), + metaPageSize_(options.metaPageSize), baseDir_(options.baseDir), lfs_(lfs), chunkFilePool_(chunkFilePool), metric_(options.metric) { CHECK(!baseDir_.empty()) << "Create snapshot failed"; CHECK(lfs_ != nullptr) << "Create snapshot failed"; - uint32_t bits = size_ / pageSize_; + uint32_t bits = size_ / blockSize_; metaPage_.bitmap = std::make_shared(bits); metaPage_.sn = options.sn; if (metric_ != nullptr) { @@ -146,8 +147,8 @@ CSErrorCode CSSnapshot::Open(bool createFile) { if (createFile && !lfs_->FileExists(snapshotPath) && metaPage_.sn > 0) { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); metaPage_.encode(buf.get()); int ret = chunkFilePool_->GetFile(snapshotPath, buf.get()); if (ret != 0) { @@ -217,8 +218,8 @@ CSErrorCode CSSnapshot::Write(const char * buf, off_t offset, size_t length) { << ",snapshot sn: " << metaPage_.sn; return CSErrorCode::InternalError; } - uint32_t pageBeginIndex = offset / pageSize_; - uint32_t pageEndIndex = (offset + length - 1) / pageSize_; + uint32_t pageBeginIndex = offset / blockSize_; + uint32_t pageEndIndex = (offset + length - 1) / blockSize_; for (uint32_t i = pageBeginIndex; i <= pageEndIndex; ++i) { dirtyPages_.insert(i); } @@ -238,8 +239,8 @@ CSErrorCode CSSnapshot::Flush() { } CSErrorCode CSSnapshot::updateMetaPage(SnapshotMetaPage* metaPage) { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); metaPage->encode(buf.get()); int rc = writeMetaPage(buf.get()); if (rc < 0) { @@ -252,8 +253,8 @@ CSErrorCode CSSnapshot::updateMetaPage(SnapshotMetaPage* metaPage) { } CSErrorCode CSSnapshot::loadMetaPage() { - std::unique_ptr buf(new char[pageSize_]); - memset(buf.get(), 0, pageSize_); + std::unique_ptr buf(new char[metaPageSize_]); + memset(buf.get(), 0, metaPageSize_); int rc = readMetaPage(buf.get()); if (rc < 0) { LOG(ERROR) << "Error occured when reading metaPage_." diff --git a/src/chunkserver/datastore/chunkserver_snapshot.h b/src/chunkserver/datastore/chunkserver_snapshot.h index 6ca304d3cf..a9ba82387b 100644 --- a/src/chunkserver/datastore/chunkserver_snapshot.h +++ b/src/chunkserver/datastore/chunkserver_snapshot.h @@ -150,24 +150,24 @@ class CSSnapshot { FileNameOperator::GenerateSnapshotName(chunkId_, metaPage_.sn); } - inline uint32_t fileSize() { - return pageSize_ + size_; + uint32_t fileSize() const { + return metaPageSize_ + size_; } inline int readMetaPage(char* buf) { - return lfs_->Read(fd_, buf, 0, pageSize_); + return lfs_->Read(fd_, buf, 0, metaPageSize_); } inline int writeMetaPage(const char* buf) { - return lfs_->Write(fd_, buf, 0, pageSize_); + return lfs_->Write(fd_, buf, 0, metaPageSize_); } inline int readData(char* buf, off_t offset, size_t length) { - return lfs_->Read(fd_, buf, offset + pageSize_, length); + return lfs_->Read(fd_, buf, offset + metaPageSize_, length); } inline int writeData(const char* buf, off_t offset, size_t length) { - return lfs_->Write(fd_, buf, offset + pageSize_, length); + return lfs_->Write(fd_, buf, offset + metaPageSize_, length); } private: @@ -177,9 +177,10 @@ class CSSnapshot { ChunkID chunkId_; // Logical size of the snapshot file, excluding metapage ChunkSizeType size_; + ChunkSizeType blockSize_; // The smallest atomic read and write unit, which is also the size of // the metapage - PageSizeType pageSize_; + PageSizeType metaPageSize_; // The directory where the snapshot file is located std::string baseDir_; // The metapage of the snapshot file diff --git a/src/chunkserver/datastore/define.h b/src/chunkserver/datastore/define.h index 6cf1255bdf..7e6a92f928 100644 --- a/src/chunkserver/datastore/define.h +++ b/src/chunkserver/datastore/define.h @@ -80,9 +80,10 @@ struct CSChunkInfo { // the id of the chunk ChunkID chunkId; // page size - uint32_t pageSize; + uint32_t metaPageSize; // The size of the chunk uint32_t chunkSize; + uint32_t blockSize; // The sequence number of the chunk file SequenceNum curSn; // The sequence number of the chunk snapshot, @@ -99,8 +100,9 @@ struct CSChunkInfo { // otherwise it is nullptr std::shared_ptr bitmap; CSChunkInfo() : chunkId(0) - , pageSize(4096) + , metaPageSize(4096) , chunkSize(16 * 4096 * 4096) + , blockSize(4096) , curSn(0) , snapSn(0) , correctedSn(0) @@ -110,8 +112,9 @@ struct CSChunkInfo { bool operator== (const CSChunkInfo& rhs) const { if (chunkId != rhs.chunkId || - pageSize != rhs.pageSize || + metaPageSize != rhs.metaPageSize || chunkSize != rhs.chunkSize || + blockSize != rhs.blockSize || curSn != rhs.curSn || snapSn != rhs.snapSn || correctedSn != rhs.correctedSn || diff --git a/src/chunkserver/datastore/file_pool.cpp b/src/chunkserver/datastore/file_pool.cpp index 83696fc963..cc5b491a05 100644 --- a/src/chunkserver/datastore/file_pool.cpp +++ b/src/chunkserver/datastore/file_pool.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "src/common/string_util.h" #include "src/common/throttle.h" @@ -40,7 +41,7 @@ #include "src/common/crc32.h" #include "src/common/curve_define.h" -using curve::common::kFilePoolMaigic; +using curve::common::kFilePoolMagic; namespace curve { namespace chunkserver { @@ -48,34 +49,45 @@ const char* FilePoolHelper::kFileSize = "chunkSize"; const char* FilePoolHelper::kMetaPageSize = "metaPageSize"; const char* FilePoolHelper::kFilePoolPath = "chunkfilepool_path"; const char* FilePoolHelper::kCRC = "crc"; +const char* FilePoolHelper::kBlockSize = "blockSize"; const uint32_t FilePoolHelper::kPersistSize = 4096; const std::string FilePool::kCleanChunkSuffix_ = ".clean"; // NOLINT const std::chrono::milliseconds FilePool::kSuccessSleepMsec_(10); const std::chrono::milliseconds FilePool::kFailSleepMsec_(500); -int FilePoolHelper::PersistEnCodeMetaInfo( - std::shared_ptr fsptr, uint32_t chunkSize, - uint32_t metaPageSize, const std::string& filePoolPath, - const std::string& persistPath) { - Json::Value root; - root[kFileSize] = chunkSize; - root[kMetaPageSize] = metaPageSize; - root[kFilePoolPath] = filePoolPath; +namespace { + +std::ostream& operator<<(std::ostream& os, const FilePoolMeta& meta) { + os << "chunksize: " << meta.chunkSize + << ", metapagesize: " << meta.metaPageSize + << ", hasblocksize: " << meta.hasBlockSize + << ", blocksize: " << meta.blockSize + << ", filepoolpath: " << meta.filePoolPath; - uint32_t crcsize = sizeof(kFilePoolMaigic) + sizeof(chunkSize) + - sizeof(metaPageSize) + filePoolPath.size(); - char* crcbuf = new char[crcsize]; + return os; +} + +bool CheckFilePoolMetaWithOptions(const FilePoolOptions& options, + const FilePoolMeta& meta) { + return options.fileSize == meta.chunkSize && + options.metaPageSize == meta.metaPageSize && + (meta.hasBlockSize ? options.blockSize == meta.blockSize : true); +} - ::memcpy(crcbuf, kFilePoolMaigic, sizeof(kFilePoolMaigic)); - ::memcpy(crcbuf + sizeof(kFilePoolMaigic), &chunkSize, sizeof(uint32_t)); - ::memcpy(crcbuf + sizeof(uint32_t) + sizeof(kFilePoolMaigic), &metaPageSize, - sizeof(uint32_t)); - ::memcpy(crcbuf + 2 * sizeof(uint32_t) + sizeof(kFilePoolMaigic), - filePoolPath.c_str(), filePoolPath.size()); - uint32_t crc = ::curve::common::CRC32(crcbuf, crcsize); - delete[] crcbuf; +} // namespace - root[kCRC] = crc; +int FilePoolHelper::PersistEnCodeMetaInfo( + std::shared_ptr fsptr, + const FilePoolMeta& meta, + const std::string& persistPath) { + Json::Value root; + root[kFileSize] = meta.chunkSize; + root[kMetaPageSize] = meta.metaPageSize; + if (meta.hasBlockSize) { + root[kBlockSize] = meta.blockSize; + } + root[kFilePoolPath] = meta.filePoolPath; + root[kCRC] = meta.Crc32(); int fd = fsptr->Open(persistPath.c_str(), O_RDWR | O_CREAT | O_SYNC); if (fd < 0) { @@ -83,7 +95,7 @@ int FilePoolHelper::PersistEnCodeMetaInfo( return -1; } - LOG(INFO) << root.toStyledString().c_str(); + LOG(INFO) << root.toStyledString(); char* writeBuffer = new char[kPersistSize]; memset(writeBuffer, 0, kPersistSize); @@ -105,10 +117,11 @@ int FilePoolHelper::PersistEnCodeMetaInfo( } int FilePoolHelper::DecodeMetaInfoFromMetaFile( - std::shared_ptr fsptr, const std::string& metaFilePath, - uint32_t metaFileSize, uint32_t* chunksize, uint32_t* metapagesize, - std::string* chunkfilePath) { - int fd = fsptr->Open(metaFilePath, O_RDWR); + std::shared_ptr fsptr, + const std::string& metaFilePath, + uint32_t metaFileSize, + FilePoolMeta* meta) { + int fd = fsptr->Open(metaFilePath, O_RDONLY); if (fd < 0) { LOG(ERROR) << "meta file open failed, " << metaFilePath; return -1; @@ -136,7 +149,7 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile( } if (!value[kFileSize].isNull()) { - *chunksize = value[kFileSize].asUInt(); + meta->chunkSize = value[kFileSize].asUInt(); } else { LOG(ERROR) << "chunkfile meta file got error!" << " no chunksize!"; @@ -144,15 +157,24 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile( } if (!value[kMetaPageSize].isNull()) { - *metapagesize = value[kMetaPageSize].asUInt(); + meta->metaPageSize = value[kMetaPageSize].asUInt(); } else { LOG(ERROR) << "chunkfile meta file got error!" << " no metaPageSize!"; break; } + if (!value[kBlockSize].isNull()) { + meta->hasBlockSize = true; + meta->blockSize = value[kBlockSize].asUInt(); + } else { + meta->hasBlockSize = false; + LOG(WARNING) << "chunkfile meta file doesn't has `" << kBlockSize + << "`, use default value 4096"; + } + if (!value[kFilePoolPath].isNull()) { - *chunkfilePath = value[kFilePoolPath].asString(); + meta->filePoolPath = value[kFilePoolPath].asString(); } else { LOG(ERROR) << "chunkfile meta file got error!" << " no FilePool path!"; @@ -175,25 +197,10 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile( return -1; } - uint32_t crcCheckSize = - 2 * sizeof(uint32_t) + sizeof(kFilePoolMaigic) + chunkfilePath->size(); - - std::unique_ptr crcCheckBuf(new char[crcCheckSize]); - - ::memcpy(crcCheckBuf.get(), kFilePoolMaigic, - sizeof(kFilePoolMaigic)); // NOLINT - ::memcpy(crcCheckBuf.get() + sizeof(kFilePoolMaigic), chunksize, - sizeof(uint32_t)); - ::memcpy(crcCheckBuf.get() + sizeof(uint32_t) + - sizeof(kFilePoolMaigic), // NOLINT - metapagesize, sizeof(uint32_t)); - ::memcpy(crcCheckBuf.get() + 2 * sizeof(uint32_t) + - sizeof(kFilePoolMaigic), // NOLINT - chunkfilePath->c_str(), chunkfilePath->size()); - uint32_t crcCalc = ::curve::common::CRC32(crcCheckBuf.get(), crcCheckSize); - + auto crcCalc = meta->Crc32(); if (crcvalue != crcCalc) { - LOG(ERROR) << "crc check failed!"; + LOG(ERROR) << "crc check failed, calculate crc: " << crcCalc + << ", record: " << crcvalue << ", decoded meta: " << *meta; return -1; } @@ -217,7 +224,7 @@ bool FilePool::Initialize(const FilePoolOptions& cfopt) { LOG(ERROR) << "check valid failed!"; return false; } - if (fsptr_->DirExists(currentdir_.c_str())) { + if (fsptr_->DirExists(currentdir_)) { return ScanInternal(); } else { LOG(ERROR) << "chunkfile pool not exists, inited failed!" @@ -234,21 +241,30 @@ bool FilePool::Initialize(const FilePoolOptions& cfopt) { } bool FilePool::CheckValid() { - uint32_t chunksize = 0; - uint32_t metapagesize = 0; - std::string filePath; - + FilePoolMeta meta; int ret = FilePoolHelper::DecodeMetaInfoFromMetaFile( - fsptr_, poolOpt_.metaPath, poolOpt_.metaFileSize, &chunksize, - &metapagesize, &filePath); + fsptr_, poolOpt_.metaPath, poolOpt_.metaFileSize, &meta); if (ret == -1) { LOG(ERROR) << "Decode meta info from meta file failed!"; return false; } - currentdir_ = filePath; - currentState_.chunkSize = chunksize; - currentState_.metaPageSize = metapagesize; + if (!CheckFilePoolMetaWithOptions(poolOpt_, meta)) { + LOG(ERROR) << "Check file pool meta with options failed, " + << "file pool meta: [" << meta + << "], options [file size: " << poolOpt_.fileSize + << ", meta file size: " << poolOpt_.metaFileSize + << ", block size: " << poolOpt_.blockSize + << ", file pool path: " << poolOpt_.filePoolDir << ']'; + return false; + } + + currentdir_ = std::move(meta.filePoolPath); + currentState_.chunkSize = meta.chunkSize; + currentState_.metaPageSize = meta.metaPageSize; + + // for backward compatibility, the default is 4096 + currentState_.blockSize = meta.hasBlockSize ? meta.blockSize : 4096; return true; } @@ -703,9 +719,38 @@ size_t FilePool::Size() { return currentState_.preallocatedChunksLeft; } -FilePoolState_t FilePool::GetState() { +FilePoolState FilePool::GetState() { return currentState_; } +uint32_t FilePoolMeta::Crc32() const { + const size_t size = sizeof(kFilePoolMagic) + sizeof(chunkSize) + + sizeof(metaPageSize) + filePoolPath.size() + + (hasBlockSize ? sizeof(blockSize) : 0); + + std::unique_ptr crc(new char[size]); + size_t off = 0; + + memcpy(crc.get(), kFilePoolMagic, sizeof(kFilePoolMagic)); + off += sizeof(kFilePoolMagic); + + memcpy(crc.get() + off, &chunkSize, sizeof(chunkSize)); + off += sizeof(chunkSize); + + memcpy(crc.get() + off, &metaPageSize, sizeof(metaPageSize)); + off += sizeof(metaPageSize); + + if (hasBlockSize) { + memcpy(crc.get() + off, &blockSize, sizeof(blockSize)); + off += sizeof(blockSize); + } + + memcpy(crc.get() + off, filePoolPath.c_str(), filePoolPath.size()); + off += filePoolPath.size(); + + assert(off == size); + return curve::common::CRC32(crc.get(), off); +} + } // namespace chunkserver } // namespace curve diff --git a/src/chunkserver/datastore/file_pool.h b/src/chunkserver/datastore/file_pool.h index 8a2d1a0b0c..bab7d9fbc0 100644 --- a/src/chunkserver/datastore/file_pool.h +++ b/src/chunkserver/datastore/file_pool.h @@ -59,6 +59,7 @@ struct FilePoolOptions { char filePoolDir[256]; uint32_t fileSize; uint32_t metaPageSize; + uint32_t blockSize; char metaPath[256]; uint32_t metaFileSize; // retry times for get file @@ -73,12 +74,13 @@ struct FilePoolOptions { fileSize = 0; metaPageSize = 0; retryTimes = 5; + blockSize = 0; ::memset(metaPath, 0, 256); ::memset(filePoolDir, 0, 256); } }; -typedef struct FilePoolState { +struct FilePoolState { // How many dirty chunks are not used by the datastore uint64_t dirtyChunksLeft; // How many clean chunks are not used by the datastore @@ -90,7 +92,47 @@ typedef struct FilePoolState { uint32_t chunkSize; // metapage size uint32_t metaPageSize; -} FilePoolState_t; + // io alignment + uint32_t blockSize; + + FilePoolState() + : dirtyChunksLeft(0), + cleanChunksLeft(0), + preallocatedChunksLeft(0), + chunkSize(0), + metaPageSize(0), + blockSize(0) {} +}; + +struct FilePoolMeta { + uint32_t chunkSize = 0; + uint32_t metaPageSize = 0; + bool hasBlockSize = false; + uint32_t blockSize = 0; + std::string filePoolPath; + + FilePoolMeta() = default; + + FilePoolMeta(uint32_t chunksize, + uint32_t metapagesize, + uint32_t blocksize, + const std::string& filepool) + : chunkSize(chunksize), + metaPageSize(metapagesize), + hasBlockSize(true), + blockSize(blocksize), + filePoolPath(filepool) {} + + FilePoolMeta(uint32_t chunksize, + uint32_t metapagesize, + const std::string& filepool) + : chunkSize(chunksize), + metaPageSize(metapagesize), + hasBlockSize(false), + filePoolPath(filepool) {} + + uint32_t Crc32() const; +}; class FilePoolHelper { public: @@ -98,6 +140,7 @@ class FilePoolHelper { static const char* kMetaPageSize; static const char* kFilePoolPath; static const char* kCRC; + static const char* kBlockSize; static const uint32_t kPersistSize; /** @@ -110,10 +153,8 @@ class FilePoolHelper { * @return: success 0, otherwise -1 */ static int PersistEnCodeMetaInfo(std::shared_ptr fsptr, - uint32_t fileSize, - uint32_t metaPageSize, - const std::string& filepoolPath, - const std::string& persistPath); + const FilePoolMeta& meta, + const std::string& persistPath); /** * Parse the current chunk pool information from the persistent meta data @@ -126,12 +167,10 @@ class FilePoolHelper { * @return: success 0, otherwise -1 */ static int DecodeMetaInfoFromMetaFile( - std::shared_ptr fsptr, - const std::string& metaFilePath, - uint32_t metaFileSize, - uint32_t* fileSize, - uint32_t* metaPageSize, - std::string* filepoolPath); + std::shared_ptr fsptr, + const std::string& metaFilePath, + uint32_t metaFileSize, + FilePoolMeta* meta); }; class CURVE_CACHELINE_ALIGNMENT FilePool { @@ -165,7 +204,7 @@ class CURVE_CACHELINE_ALIGNMENT FilePool { /** * Get the allocation status of FilePool */ - virtual FilePoolState_t GetState(); + virtual FilePoolState GetState(); /** * Get the option configuration information of the current FilePool */ @@ -288,7 +327,7 @@ class CURVE_CACHELINE_ALIGNMENT FilePool { FilePoolOptions poolOpt_; // FilePool allocation status - FilePoolState_t currentState_; + FilePoolState currentState_; // Whether the clean thread is alive Atomic cleanAlived_; diff --git a/src/chunkserver/op_request.cpp b/src/chunkserver/op_request.cpp index e13efd6dde..451c2236fe 100755 --- a/src/chunkserver/op_request.cpp +++ b/src/chunkserver/op_request.cpp @@ -378,9 +378,9 @@ bool ReadChunkRequest::NeedClone(const CSChunkInfo& chunkInfo) { if (chunkInfo.isClone) { off_t offset = request_->offset(); size_t length = request_->size(); - uint32_t pageSize = chunkInfo.pageSize; - uint32_t beginIndex = offset / pageSize; - uint32_t endIndex = (offset + length - 1) / pageSize; + uint32_t blockSize = chunkInfo.blockSize; + uint32_t beginIndex = offset / blockSize; + uint32_t endIndex = (offset + length - 1) / blockSize; // 如果是clone chunk,且存在未被写过的page,就需要拷贝 if (chunkInfo.bitmap->NextClearBit(beginIndex, endIndex) != Bitmap::NO_POS) { diff --git a/src/chunkserver/register.cpp b/src/chunkserver/register.cpp index 04bdec6844..85a12ad8b2 100644 --- a/src/chunkserver/register.cpp +++ b/src/chunkserver/register.cpp @@ -63,12 +63,14 @@ int Register::RegisterToMDS(ChunkServerMetadata *metadata) { req.set_externalip(ops_.chunkserverExternalIp); } req.set_port(ops_.chunkserverPort); + req.set_blocksize(ops_.blockSize); LOG(INFO) << " Registering to MDS " << mdsEps_[inServiceIndex_] << ". internal ip: " << ops_.chunkserverInternalIp << ", port: " << ops_.chunkserverPort << ", enable external server: " << ops_.enableExternalServer - << ", external ip: " << ops_.chunkserverExternalIp; + << ", external ip: " << ops_.chunkserverExternalIp + << ", block size: " << ops_.blockSize; int retries = ops_.registerRetries; while (retries >= 0) { diff --git a/src/chunkserver/register.h b/src/chunkserver/register.h index 652ad6865e..635fd8f27e 100644 --- a/src/chunkserver/register.h +++ b/src/chunkserver/register.h @@ -47,6 +47,7 @@ struct RegisterOptions { std::string chunkserverDiskType; int registerRetries; int registerTimeout; + uint32_t blockSize; std::shared_ptr fs; }; diff --git a/src/client/client_common.h b/src/client/client_common.h index b22ce1c292..d2e2b54ccd 100644 --- a/src/client/client_common.h +++ b/src/client/client_common.h @@ -142,6 +142,7 @@ typedef struct FInfo { uint64_t parentid; FileType filetype; uint32_t chunksize; + uint32_t blocksize; uint32_t segmentsize; uint64_t length; uint64_t ctime; diff --git a/src/client/file_instance.cpp b/src/client/file_instance.cpp index 955fefd1de..0254b51038 100644 --- a/src/client/file_instance.cpp +++ b/src/client/file_instance.cpp @@ -30,6 +30,7 @@ #include "src/client/mds_client.h" #include "src/common/timeutility.h" #include "src/common/curve_define.h" +#include "src/common/fast_align.h" namespace curve { namespace client { @@ -37,18 +38,23 @@ namespace client { using curve::client::ClientConfig; using curve::common::TimeUtility; using curve::mds::SessionStatus; +using curve::common::is_aligned; + +bool CheckIoAligned(off_t off, size_t length, size_t blocksize) { + return is_aligned(off, blocksize) && is_aligned(length, blocksize); +} FileInstance::FileInstance() : finfo_(), fileopt_(), - mdsclient_(nullptr), + mdsclient_(), leaseExecutor_(), iomanager4file_(), readonly_(false) {} bool FileInstance::Initialize(const std::string& filename, - std::shared_ptr mdsclient, - const UserInfo_t& userinfo, + const std::shared_ptr& mdsclient, + const UserInfo& userinfo, const OpenFlags& openflags, const FileServiceOption& fileservicopt, bool readonly) { @@ -66,10 +72,9 @@ bool FileInstance::Initialize(const std::string& filename, break; } + mdsclient_ = mdsclient; finfo_.openflags = openflags; finfo_.userinfo = userinfo; - mdsclient_ = std::move(mdsclient); - finfo_.fullPathName = filename; if (!iomanager4file_.Initialize(filename, fileopt_.ioOpt, @@ -84,14 +89,14 @@ bool FileInstance::Initialize(const std::string& filename, leaseExecutor_.reset(new (std::nothrow) LeaseExecutor( fileopt_.leaseOpt, finfo_.userinfo, mdsclient_.get(), &iomanager4file_)); - if (CURVE_UNLIKELY(leaseExecutor_ == nullptr)) { + if (leaseExecutor_ == nullptr) { LOG(ERROR) << "Allocate LeaseExecutor failed, filename = " << filename; break; } ret = true; - } while (0); + } while (false); return ret; } @@ -106,6 +111,13 @@ void FileInstance::UnInitialize() { } int FileInstance::Read(char* buf, off_t offset, size_t length) { + if (!CheckIoAligned(offset, length, finfo_.blocksize)) { + LOG(ERROR) << "IO not aligned, off: " << offset + << ", length: " << length + << ", block size: " << finfo_.blocksize; + return -LIBCURVE_ERROR::NOT_ALIGNED; + } + DLOG_EVERY_SECOND(INFO) << "begin Read "<< finfo_.fullPathName << ", offset = " << offset << ", len = " << length; @@ -117,6 +129,13 @@ int FileInstance::Write(const char* buf, off_t offset, size_t len) { DVLOG(9) << "open with read only, do not support write!"; return -1; } + + if (!CheckIoAligned(offset, len, finfo_.blocksize)) { + LOG(ERROR) << "IO not aligned, off: " << offset << ", length: " << len + << ", block size: " << finfo_.blocksize; + return -LIBCURVE_ERROR::NOT_ALIGNED; + } + DLOG_EVERY_SECOND(INFO) << "begin write " << finfo_.fullPathName << ", offset = " << offset << ", len = " << len; @@ -124,6 +143,15 @@ int FileInstance::Write(const char* buf, off_t offset, size_t len) { } int FileInstance::AioRead(CurveAioContext* aioctx, UserDataType dataType) { + if (!CheckIoAligned(aioctx->offset, aioctx->length, finfo_.blocksize)) { + LOG(ERROR) << "IO not aligned, off: " << aioctx->offset + << ", length: " << aioctx->length + << ", block size: " << finfo_.blocksize; + aioctx->ret = -LIBCURVE_ERROR::NOT_ALIGNED; + aioctx->cb(aioctx); + return -LIBCURVE_ERROR::NOT_ALIGNED; + } + DLOG_EVERY_SECOND(INFO) << "begin AioRead " << finfo_.fullPathName << ", offset = " << aioctx->offset << ", len = " << aioctx->length; @@ -135,6 +163,16 @@ int FileInstance::AioWrite(CurveAioContext* aioctx, UserDataType dataType) { DVLOG(9) << "open with read only, do not support write!"; return -1; } + + if (!CheckIoAligned(aioctx->offset, aioctx->length, finfo_.blocksize)) { + LOG(ERROR) << "IO not aligned, off: " << aioctx->offset + << ", length: " << aioctx->length + << ", block size: " << finfo_.blocksize; + aioctx->ret = -LIBCURVE_ERROR::NOT_ALIGNED; + aioctx->cb(aioctx); + return -LIBCURVE_ERROR::NOT_ALIGNED; + } + DLOG_EVERY_SECOND(INFO) << "begin AioWrite " << finfo_.fullPathName << ", offset = " << aioctx->offset << ", len = " << aioctx->length; @@ -167,13 +205,12 @@ int FileInstance::AioDiscard(CurveAioContext* aioctx) { // 这时候当前还没有成功打开,所以还没有存储该session信息,所以无法通过refresh // 再去打开,所以这时候需要获取mds一侧session lease时长,然后在client这一侧 // 等待一段时间再去Open,如果依然失败,就向上层返回失败。 -int FileInstance::Open(const std::string& filename, - const UserInfo& userinfo, - std::string* sessionId) { +int FileInstance::Open(std::string* sessionId) { LeaseSession_t lease; int ret = LIBCURVE_ERROR::FAILED; - ret = mdsclient_->OpenFile(filename, finfo_.userinfo, &finfo_, &lease); + ret = mdsclient_->OpenFile(finfo_.fullPathName, finfo_.userinfo, &finfo_, + &lease); if (ret == LIBCURVE_ERROR::OK) { iomanager4file_.UpdateFileThrottleParams(finfo_.throttleParams); ret = leaseExecutor_->Start(finfo_, lease) ? LIBCURVE_ERROR::OK @@ -185,18 +222,6 @@ int FileInstance::Open(const std::string& filename, return -ret; } -int FileInstance::ReOpen(const std::string& filename, - const std::string& sessionId, - const UserInfo& userInfo, - std::string* newSessionId) { - return Open(filename, userInfo, newSessionId); -} - -int FileInstance::GetFileInfo(const std::string& filename, FInfo_t* fi) { - LIBCURVE_ERROR ret = mdsclient_->GetFileInfo(filename, finfo_.userinfo, fi); - return -ret; -} - int FileInstance::Close() { if (readonly_) { LOG(INFO) << "close read only file!" << finfo_.fullPathName; @@ -212,7 +237,7 @@ int FileInstance::Close() { FileInstance* FileInstance::NewInitedFileInstance( const FileServiceOption& fileServiceOption, - std::shared_ptr mdsClient, + const std::shared_ptr& mdsClient, const std::string& filename, const UserInfo& userInfo, const OpenFlags& openflags, // TODO(all): maybe we can put userinfo and readonly into openflags // NOLINT @@ -223,8 +248,8 @@ FileInstance* FileInstance::NewInitedFileInstance( return nullptr; } - bool ret = instance->Initialize(filename, std::move(mdsClient), userInfo, - openflags, fileServiceOption, readonly); + bool ret = instance->Initialize(filename, mdsClient, userInfo, openflags, + fileServiceOption, readonly); if (!ret) { LOG(ERROR) << "FileInstance initialize failed" << ", filename = " << filename @@ -237,20 +262,20 @@ FileInstance* FileInstance::NewInitedFileInstance( return instance; } -FileInstance* FileInstance::Open4Readonly(const FileServiceOption& opt, - std::shared_ptr mdsclient, - const std::string& filename, - const UserInfo& userInfo, - const OpenFlags& openflags) { +FileInstance* FileInstance::Open4Readonly( + const FileServiceOption& opt, + const std::shared_ptr& mdsclient, + const std::string& filename, + const UserInfo& userInfo, + const OpenFlags& openflags) { FileInstance* instance = FileInstance::NewInitedFileInstance( - opt, std::move(mdsclient), filename, userInfo, openflags, true); + opt, mdsclient, filename, userInfo, openflags, true); if (instance == nullptr) { LOG(ERROR) << "NewInitedFileInstance failed, filename = " << filename; return nullptr; } - FInfo fileInfo; - int ret = instance->GetFileInfo(filename, &fileInfo); + int ret = mdsclient->GetFileInfo(filename, userInfo, &instance->finfo_); if (ret != 0) { LOG(ERROR) << "Get file info failed!"; instance->UnInitialize(); @@ -258,10 +283,10 @@ FileInstance* FileInstance::Open4Readonly(const FileServiceOption& opt, return nullptr; } - fileInfo.openflags = openflags; - fileInfo.userinfo = userInfo; - fileInfo.fullPathName = filename; - instance->GetIOManager4File()->UpdateFileInfo(fileInfo); + instance->finfo_.openflags = openflags; + instance->finfo_.userinfo = userInfo; + instance->finfo_.fullPathName = filename; + instance->GetIOManager4File()->UpdateFileInfo(instance->finfo_); return instance; } diff --git a/src/client/file_instance.h b/src/client/file_instance.h index cd5b1ae299..a951a4580a 100644 --- a/src/client/file_instance.h +++ b/src/client/file_instance.h @@ -52,33 +52,17 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance { * @return: 成功返回true、否则返回false */ bool Initialize(const std::string& filename, - std::shared_ptr mdsclient, - const UserInfo_t& userinfo, + const std::shared_ptr& mdsclient, + const UserInfo& userinfo, const OpenFlags& openflags, const FileServiceOption& fileservicopt, bool readonly = false); /** * 打开文件 - * @param: filename为文件名 - * @param: userinfo为user信息 * @return: 成功返回LIBCURVE_ERROR::OK,否则LIBCURVE_ERROR::FAILED */ - int Open(const std::string& filename, - const UserInfo& userinfo, - std::string* sessionId = nullptr); + int Open(std::string* sessionId = nullptr); - /** - * 重新打开文件 - * @param filename为文件名 - * @param sessionId为上次打开文件时返回的sessionid - * @param userInfo为user信息 - * @param[out] newSessionId为ReOpen成功时返回的新sessionid - * @return 成功返回LIBCURVE_ERROR::OK, 否则LIBCURVE_ERROR::FAILED - */ - int ReOpen(const std::string& filenam, - const std::string& sessionId, - const UserInfo& userInfo, - std::string* newSessionId); /** * 同步模式读 * @param: buf为当前待读取的缓冲区 @@ -140,8 +124,6 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance { return leaseExecutor_.get(); } - int GetFileInfo(const std::string& filename, FInfo_t* fi); - /** * @brief 获取当前instance对应的文件信息 * @@ -153,15 +135,17 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance { static FileInstance* NewInitedFileInstance( const FileServiceOption& fileServiceOption, - std::shared_ptr mdsClient, + const std::shared_ptr& mdsclient, const std::string& filename, const UserInfo& userInfo, const OpenFlags& openflags, bool readonly); static FileInstance* Open4Readonly( - const FileServiceOption& opt, std::shared_ptr mdsclient, - const std::string& filename, const UserInfo& userInfo, + const FileServiceOption& opt, + const std::shared_ptr& mdsclient, + const std::string& filename, + const UserInfo& userInfo, const OpenFlags& openflags = DefaultReadonlyOpenFlags()); private: @@ -169,7 +153,7 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance { private: // 保存当前file的文件信息 - FInfo_t finfo_; + FInfo finfo_; // 当前FileInstance的初始化配置信息 FileServiceOption fileopt_; @@ -187,6 +171,8 @@ class CURVE_CACHELINE_ALIGNMENT FileInstance { bool readonly_; }; +bool CheckIoAligned(off_t off, size_t length, size_t blocksize); + } // namespace client } // namespace curve diff --git a/src/client/libcurve_client.cpp b/src/client/libcurve_client.cpp index 40e7f5cfd9..1be5093372 100644 --- a/src/client/libcurve_client.cpp +++ b/src/client/libcurve_client.cpp @@ -83,6 +83,12 @@ int CurveClient::Extend(const std::string& filename, int64_t CurveClient::StatFile(const std::string& filename) { FileStatInfo fileStatInfo; + auto rc = StatFile(filename, &fileStatInfo); + return rc == LIBCURVE_ERROR::OK ? fileStatInfo.length : rc; +} + +int64_t CurveClient::StatFile(const std::string& filename, + FileStatInfo* statInfo) { curve::client::UserInfo userInfo; std::string realFileName; bool ret = curve::client::ServiceHelper::GetUserInfoFromFilename( @@ -93,8 +99,7 @@ int64_t CurveClient::StatFile(const std::string& filename) { return -LIBCURVE_ERROR::FAILED; } - int rc = fileClient_->StatFile(realFileName, userInfo, &fileStatInfo); - return rc == LIBCURVE_ERROR::OK ? fileStatInfo.length : rc; + return fileClient_->StatFile(realFileName, userInfo, statInfo); } int CurveClient::AioRead(int fd, CurveAioContext* aioctx, diff --git a/src/client/libcurve_file.cpp b/src/client/libcurve_file.cpp index 0b3b65c47b..dd679408f4 100644 --- a/src/client/libcurve_file.cpp +++ b/src/client/libcurve_file.cpp @@ -208,7 +208,7 @@ int FileClient::Open(const std::string& filename, return -1; } - int ret = fileserv->Open(filename, userinfo); + int ret = fileserv->Open(); if (ret != LIBCURVE_ERROR::OK) { LOG(ERROR) << "Open file failed, filename: " << filename << ", retCode: " << ret; @@ -292,12 +292,6 @@ int FileClient::Read(int fd, char* buf, off_t offset, size_t len) { return -LIBCURVE_ERROR::OK; } - if (CheckAligned(offset, len) == false) { - LOG(ERROR) << "Read request not aligned, length = " << len - << ", offset = " << offset << ", fd = " << fd; - return -LIBCURVE_ERROR::NOT_ALIGNED; - } - ReadLockGuard lk(rwlock_); if (CURVE_UNLIKELY(fileserviceMap_.find(fd) == fileserviceMap_.end())) { LOG(ERROR) << "invalid fd!"; @@ -313,12 +307,6 @@ int FileClient::Write(int fd, const char* buf, off_t offset, size_t len) { return -LIBCURVE_ERROR::OK; } - if (CheckAligned(offset, len) == false) { - LOG(ERROR) << "Write request not aligned, length = " << len - << ", offset = " << offset << ", fd = " << fd; - return -LIBCURVE_ERROR::NOT_ALIGNED; - } - ReadLockGuard lk(rwlock_); if (CURVE_UNLIKELY(fileserviceMap_.find(fd) == fileserviceMap_.end())) { LOG(ERROR) << "invalid fd!"; @@ -346,12 +334,6 @@ int FileClient::AioRead(int fd, CurveAioContext* aioctx, return -LIBCURVE_ERROR::OK; } - if (CheckAligned(aioctx->offset, aioctx->length) == false) { - LOG(ERROR) << "AioRead request not aligned, length = " << aioctx->length - << ", offset = " << aioctx->offset << ", fd = " << fd; - return -LIBCURVE_ERROR::NOT_ALIGNED; - } - int ret = -LIBCURVE_ERROR::FAILED; ReadLockGuard lk(rwlock_); if (CURVE_UNLIKELY(fileserviceMap_.find(fd) == fileserviceMap_.end())) { @@ -371,13 +353,6 @@ int FileClient::AioWrite(int fd, CurveAioContext* aioctx, return -LIBCURVE_ERROR::OK; } - if (CheckAligned(aioctx->offset, aioctx->length) == false) { - LOG(ERROR) << "AioWrite request not aligned, length = " - << aioctx->length << ", offset = " << aioctx->offset - << ", fd = " << fd; - return -LIBCURVE_ERROR::NOT_ALIGNED; - } - int ret = -LIBCURVE_ERROR::FAILED; ReadLockGuard lk(rwlock_); if (CURVE_UNLIKELY(fileserviceMap_.find(fd) == fileserviceMap_.end())) { @@ -482,6 +457,7 @@ int FileClient::StatFile(const std::string& filename, finfo->parentid = fi.parentid; finfo->ctime = fi.ctime; finfo->length = fi.length; + finfo->blocksize = fi.blocksize; finfo->filetype = fi.filetype; finfo->stripeUnit = fi.stripeUnit; finfo->stripeCount = fi.stripeCount; diff --git a/src/client/libcurve_file.h b/src/client/libcurve_file.h index d2bc29d9c2..17be889de0 100644 --- a/src/client/libcurve_file.h +++ b/src/client/libcurve_file.h @@ -290,11 +290,6 @@ class FileClient { private: bool StartDummyServer(); - bool CheckAligned(off_t offset, size_t length) const { - return (offset % IO_ALIGNED_BLOCK_SIZE == 0) && - (length % IO_ALIGNED_BLOCK_SIZE == 0); - } - private: BthreadRWLock rwlock_; diff --git a/src/client/mds_client.cpp b/src/client/mds_client.cpp index c87578ac1a..ad1f0e4f37 100644 --- a/src/client/mds_client.cpp +++ b/src/client/mds_client.cpp @@ -275,12 +275,14 @@ LIBCURVE_ERROR MDSClient::OpenFile(const std::string &filename, bool flag = response.has_protosession() && response.has_fileinfo(); if (flag) { - ProtoSession leasesession = response.protosession(); + const ProtoSession &leasesession = response.protosession(); lease->sessionID = leasesession.sessionid(); lease->leaseTime = leasesession.leasetime(); lease->createTime = leasesession.createtime(); const curve::mds::FileInfo &protoFileInfo = response.fileinfo(); + LOG(INFO) << "OpenFile succeeded, filename: " << filename + << ", file info " << protoFileInfo.DebugString(); ServiceHelper::ProtoFileInfo2Local(protoFileInfo, fi); if (protoFileInfo.has_clonesource() && diff --git a/src/client/metacache.cpp b/src/client/metacache.cpp index 289a1eb1aa..deb78144ff 100644 --- a/src/client/metacache.cpp +++ b/src/client/metacache.cpp @@ -214,8 +214,7 @@ void MetaCache::UpdateCopysetInfoIfMatchCurrentLeader( CopysetID copysetId, const PeerAddr& leaderAddr) { std::vector> copysetInfos; - int ret = - mdsclient_->GetServerList(logicPoolId, {copysetId}, ©setInfos); + mdsclient_->GetServerList(logicPoolId, {copysetId}, ©setInfos); bool needUpdate = (!copysetInfos.empty()) && (copysetInfos[0].HasPeerInCopyset(leaderAddr)); diff --git a/src/client/service_helper.cpp b/src/client/service_helper.cpp index 1e1696f4b2..4d4794fc7d 100644 --- a/src/client/service_helper.cpp +++ b/src/client/service_helper.cpp @@ -120,6 +120,12 @@ void ServiceHelper::ProtoFileInfo2Local(const curve::mds::FileInfo& finfo, if (finfo.has_stripecount()) { fi->stripeCount = finfo.stripecount(); } + if (finfo.has_blocksize()) { + fi->blocksize = finfo.blocksize(); + } else { + // for backward compatibility + fi->blocksize = 4096; + } if (finfo.has_throttleparams()) { fi->throttleParams = diff --git a/src/client/splitor.cpp b/src/client/splitor.cpp index f0ea0859ef..c979a84ad9 100644 --- a/src/client/splitor.cpp +++ b/src/client/splitor.cpp @@ -133,8 +133,6 @@ bool Splitor::AssignInternal(IOTracker* iotracker, MetaCache* metaCache, butil::IOBuf* data, off_t off, size_t len, MDSClient* mdsclient, const FInfo_t* fileInfo, ChunkIndex chunkidx) { - const auto maxSplitSizeBytes = 1024 * iosplitopt_.fileIOSplitMaxSizeKB; - lldiv_t res = std::div( static_cast(chunkidx) * fileInfo->chunksize, // NOLINT static_cast(fileInfo->segmentsize)); // NOLINT @@ -343,7 +341,6 @@ int Splitor::SplitForStripe(IOTracker* iotracker, MetaCache* metaCache, uint64_t cur = offset; uint64_t left = length; - uint64_t curChunkIndex = 0; while (left > 0) { uint64_t blockIndex = cur / stripeUnit; diff --git a/src/client/splitor.h b/src/client/splitor.h index f6753ff22f..442d571d68 100644 --- a/src/client/splitor.h +++ b/src/client/splitor.h @@ -24,16 +24,15 @@ #include -#include #include +#include -#include "src/client/metacache.h" -#include "src/client/io_tracker.h" +#include "src/client/client_common.h" +#include "src/client/client_config.h" #include "src/client/config_info.h" +#include "src/client/io_tracker.h" #include "src/client/metacache.h" #include "src/client/request_context.h" -#include "src/client/client_common.h" -#include "src/client/client_config.h" namespace curve { namespace client { diff --git a/src/common/authenticator.cpp b/src/common/authenticator.cpp index 7b2819facc..154e1fe41f 100644 --- a/src/common/authenticator.cpp +++ b/src/common/authenticator.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -61,6 +62,11 @@ const EVP_MD* __attribute__((weak)) EVP_sha256(void); namespace curve { namespace common { +static char b[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +/* 0000000000111111111122222222223333333333444444444455555555556666 */ +/* 0123456789012345678901234567890123456789012345678901234567890123 */ + std::string Authenticator::CalcString2Signature(const std::string& in, const std::string& secretKey) { std::string signature; diff --git a/src/common/authenticator.h b/src/common/authenticator.h index 7da49e3810..7d9ba319c3 100644 --- a/src/common/authenticator.h +++ b/src/common/authenticator.h @@ -22,19 +22,11 @@ #ifndef SRC_COMMON_AUTHENTICATOR_H_ #define SRC_COMMON_AUTHENTICATOR_H_ -#include -#include - #include namespace curve { namespace common { -static char b[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -/* 0000000000111111111122222222223333333333444444444455555555556666 */ -/* 0123456789012345678901234567890123456789012345678901234567890123 */ - class Authenticator { public: /** diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp index 78bdc397fb..4496045be6 100644 --- a/src/common/configuration.cpp +++ b/src/common/configuration.cpp @@ -183,6 +183,11 @@ void Configuration::SetUInt64Value( SetValue(key, std::to_string(value)); } +void Configuration::SetUInt32Value(const std::string &key, + const uint32_t value) { + SetValue(key, std::to_string(value)); +} + bool Configuration::GetInt64Value(const std::string& key, int64_t* out) { std::string res; if (GetValue(key, &res)) { diff --git a/src/common/configuration.h b/src/common/configuration.h index d7ce0e5cb1..d546995ade 100644 --- a/src/common/configuration.h +++ b/src/common/configuration.h @@ -79,6 +79,7 @@ class Configuration { bool GetUInt32Value(const std::string &key, uint32_t *out); bool GetUInt64Value(const std::string &key, uint64_t *out); void SetIntValue(const std::string &key, const int value); + void SetUInt32Value(const std::string &key, const uint32_t value); void SetUInt64Value(const std::string &key, const uint64_t value); bool GetInt64Value(const std::string& key, int64_t* out); diff --git a/src/common/curve_define.h b/src/common/curve_define.h index 9ef818267f..63d4501213 100644 --- a/src/common/curve_define.h +++ b/src/common/curve_define.h @@ -56,7 +56,7 @@ const uint32_t kMB = 1024*kKB; const uint32_t kGB = 1024*kMB; // maigic number用于FilePool_meta file计算crc -const char kFilePoolMaigic[3] = "01"; +const char kFilePoolMagic[3] = "01"; } // namespace common } // namespace curve diff --git a/curvefs/src/common/fast_align.h b/src/common/fast_align.h similarity index 61% rename from curvefs/src/common/fast_align.h rename to src/common/fast_align.h index 7ec1e300c1..c2091b8676 100644 --- a/curvefs/src/common/fast_align.h +++ b/src/common/fast_align.h @@ -5,34 +5,12 @@ Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ -/* - * Copyright (c) 2021 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Project: curve - * File Created: Fri Jul 16 21:22:40 CST 2021 - * Author: wuhanqing - */ - -#ifndef CURVEFS_SRC_COMMON_FAST_ALIGN_H_ -#define CURVEFS_SRC_COMMON_FAST_ALIGN_H_ +#ifndef SRC_COMMON_FAST_ALIGN_H_ +#define SRC_COMMON_FAST_ALIGN_H_ #include -namespace curvefs { +namespace curve { namespace common { namespace detail { @@ -77,7 +55,11 @@ inline bool is_aligned(const void* ptr, std::size_t alignment) noexcept { return is_aligned((std::size_t)ptr, alignment); // NOLINT } +constexpr inline bool is_alignment(std::size_t value) noexcept { + return (value > 0) && ((value & (value - 1)) == 0); +} + } // namespace common -} // namespace curvefs +} // namespace curve -#endif // CURVEFS_SRC_COMMON_FAST_ALIGN_H_ +#endif // SRC_COMMON_FAST_ALIGN_H_ diff --git a/src/common/namespace_define.h b/src/common/namespace_define.h index 442b7e36c4..fe4ca3b7a9 100644 --- a/src/common/namespace_define.h +++ b/src/common/namespace_define.h @@ -62,6 +62,8 @@ const char CLONEINFOKEYEND[] = "13"; const char DISCARDSEGMENTKEYPREFIX[] = "13"; const char DISCARDSEGMENTKEYEND[] = "14"; +const char BLOCKSIZEKEY[] = "15blocksize"; + // TODO(hzsunjianliang): if use single prefix for snapshot file? const int COMMON_PREFIX_LENGTH = 2; const int LEADER_PREFIX_LENGTH = 8; diff --git a/test/chunkserver/clone/clone_unittest_main.cpp b/src/mds/common/mds_define.cpp similarity index 57% rename from test/chunkserver/clone/clone_unittest_main.cpp rename to src/mds/common/mds_define.cpp index f497b57f6f..983b754f63 100644 --- a/test/chunkserver/clone/clone_unittest_main.cpp +++ b/src/mds/common/mds_define.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 NetEase Inc. + * Copyright (c) 2022 NetEase Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,17 @@ /* * Project: curve - * Created Date: Friday March 29th 2019 - * Author: yangyaokai + * Date: Wednesday Mar 30 11:04:35 CST 2022 + * Author: wuhanqing */ -#include -#include -#include -#include -#include +#include "src/mds/common/mds_define.h" -int main(int argc, char ** argv) { - ::testing::InitGoogleTest(&argc, argv); - ::testing::InitGoogleMock(&argc, argv); - google::ParseCommandLineFlags(&argc, &argv, false); - int ret = RUN_ALL_TESTS(); +namespace curve { +namespace mds { - return ret; -} +// io block size +uint32_t g_block_size; + +} // namespace mds +} // namespace curve diff --git a/src/mds/common/mds_define.h b/src/mds/common/mds_define.h index e64115ea98..c4b50ec061 100644 --- a/src/mds/common/mds_define.h +++ b/src/mds/common/mds_define.h @@ -51,6 +51,9 @@ const int kCsClientCSOffline = -6; // to prevent the request from being intercepted and played back const uint64_t kStaledRequestTimeIntervalUs = 15 * 1000 * 1000u; +// io block size +extern uint32_t g_block_size; + } // namespace mds } // namespace curve @@ -93,6 +96,7 @@ const int kTopoErrCodeNameDuplicated = -16; const int kTopoErrCodeCreateCopysetNodeOnChunkServerFail = -17; const int kTopoErrCodeCannotRemoveNotRetired = -18; const int kTopoErrCodeLogicalPoolExist = -19; +const int kTopoErrCodeConflictBlockSize = -20; } // namespace topology } // namespace mds diff --git a/src/mds/main/main.cpp b/src/mds/main/main.cpp index c7349fa91e..4c9b9bbe37 100644 --- a/src/mds/main/main.cpp +++ b/src/mds/main/main.cpp @@ -93,16 +93,15 @@ void LoadConfigFromCmdline(Configuration *conf) { int main(int argc, char **argv) { // config initialization google::ParseCommandLineFlags(&argc, &argv, false); - std::string confPath = FLAGS_confPath.c_str(); auto conf = std::make_shared(); - conf->SetConfigPath(confPath); + conf->SetConfigPath(FLAGS_confPath); LOG_IF(FATAL, !conf->LoadConfig()) - << "load mds configuration fail, conf path = " << confPath; + << "load mds configuration fail, conf path = " << FLAGS_confPath; LoadConfigFromCmdline(conf.get()); conf->PrintConfig(); if (FLAGS_log_dir.empty()) { if (!conf->GetStringValue("mds.common.logDir", &FLAGS_log_dir)) { - LOG(WARNING) << "no mds.common.logDir in " << confPath + LOG(WARNING) << "no mds.common.logDir in " << FLAGS_confPath << ", will log to /tmp"; } } diff --git a/src/mds/nameserver2/curvefs.cpp b/src/mds/nameserver2/curvefs.cpp index 188cfb5507..0d68e56a6d 100644 --- a/src/mds/nameserver2/curvefs.cpp +++ b/src/mds/nameserver2/curvefs.cpp @@ -317,6 +317,7 @@ StatusCode CurveFS::CreateFile(const std::string & fileName, fileInfo.set_filestatus(FileStatus::kFileCreated); fileInfo.set_stripeunit(stripeUnit); fileInfo.set_stripecount(stripeCount); + fileInfo.set_blocksize(g_block_size); if (filetype == FileType::INODE_PAGEFILE) { fileInfo.set_allocated_throttleparams( @@ -1609,8 +1610,6 @@ StatusCode CurveFS::OpenFile(const std::string &fileName, return ret; } - LOG(INFO) << "FileInfo, " << fileInfo->DebugString(); - if (fileInfo->filetype() != FileType::INODE_PAGEFILE) { LOG(ERROR) << "OpenFile file type not support, fileName = " << fileName << ", clientIP = " << clientIP @@ -1625,6 +1624,10 @@ StatusCode CurveFS::OpenFile(const std::string &fileName, return ListCloneSourceFileSegments(fileInfo, cloneSourceSegment); } + if (!fileInfo->blocksize()) { + fileInfo->set_blocksize(g_block_size); + } + return StatusCode::kOK; } @@ -2404,6 +2407,10 @@ uint64_t CurveFS::GetMaxFileLength() { return maxFileLength_; } +uint32_t CurveFS::GetBlockSize() const { + return g_block_size; +} + StatusCode CurveFS::CheckStripeParam(uint64_t stripeUnit, uint64_t stripeCount) { if ((stripeUnit == 0) && (stripeCount == 0 )) { diff --git a/src/mds/nameserver2/curvefs.h b/src/mds/nameserver2/curvefs.h index 189306a70f..c7fad6b3f7 100644 --- a/src/mds/nameserver2/curvefs.h +++ b/src/mds/nameserver2/curvefs.h @@ -583,6 +583,12 @@ class CurveFS { */ uint64_t GetMaxFileLength(); + /** + * @brief get the block size of curve volume + * @return block size + */ + uint32_t GetBlockSize() const; + private: CurveFS() = default; diff --git a/src/mds/nameserver2/namespace_service.cpp b/src/mds/nameserver2/namespace_service.cpp index 3d21b88f45..ca339516b9 100644 --- a/src/mds/nameserver2/namespace_service.cpp +++ b/src/mds/nameserver2/namespace_service.cpp @@ -343,8 +343,9 @@ void NameSpaceService::GetFileInfo( return; } - LOG(INFO) << "logid = " << cntl->log_id() - << ", GetFileInfo request, filename = " << request->filename(); + LOG_EVERY_SECOND(INFO) << "logid = " << cntl->log_id() + << ", GetFileInfo request, filename = " + << request->filename(); FileReadLockGuard guard(fileLockManager_, request->filename()); diff --git a/src/mds/server/mds.cpp b/src/mds/server/mds.cpp index 24e5735968..1184510bc2 100644 --- a/src/mds/server/mds.cpp +++ b/src/mds/server/mds.cpp @@ -25,6 +25,9 @@ #include "src/mds/nameserver2/helper/namespace_helper.h" #include "src/mds/topology/topology_storge_etcd.h" #include "src/common/lru_cache.h" +#include "src/common/namespace_define.h" +#include "src/common/string_util.h" +#include "src/common/fast_align.h" using ::curve::mds::topology::TopologyStorageEtcd; using ::curve::mds::topology::TopologyStorageCodec; @@ -34,6 +37,7 @@ namespace mds { using LRUCache = ::curve::common::LRUCache; using CacheMetrics = ::curve::common::CacheMetrics; +using ::curve::common::BLOCKSIZEKEY; MDS::~MDS() { if (etcdEndpoints_) { @@ -118,6 +122,9 @@ void MDS::StartCompaginLeader() { } void MDS::Init() { + LOG_IF(FATAL, !CheckOrInsertBlockSize(etcdClient_.get())) + << "Check or insert block size failed"; + InitSegmentAllocStatistic(options_.retryInterTimes, options_.periodicPersistInterMs); InitNameServerStorage(options_.mdsCacheCount); @@ -500,6 +507,12 @@ void MDS::InitCurveFSOptions(CurveFSOption *curveFSOptions) { "mds.curvefs.minFileLength", &curveFSOptions->minFileLength); conf_->GetValueFatalIfFail( "mds.curvefs.maxFileLength", &curveFSOptions->maxFileLength); + conf_->GetValueFatalIfFail("mds.curvefs.blockSize", &g_block_size); + + if (g_block_size != 4096 && g_block_size != 512) { + LOG(FATAL) << "mds.curvefs.blockSize only supports 512 and 4096"; + } + FileRecordOptions fileRecordOptions; InitFileRecordOptions(&curveFSOptions->fileRecordOptions); @@ -647,5 +660,47 @@ void MDS::InitHeartbeatOption(HeartbeatOption* heartbeatOption) { conf_->GetValueFatalIfFail("mds.heartbeat.clean_follower_afterMs", &heartbeatOption->cleanFollowerAfterMs); } + +bool CheckOrInsertBlockSize(EtcdClientImp* etcdclient) { + std::string value; + auto err = etcdclient->Get(BLOCKSIZEKEY, &value); + + switch (err) { + case EtcdErrCode::EtcdOK: { + uint32_t blocksize = 0; + if (!curve::common::StringToUl(value, &blocksize)) { + LOG(WARNING) << "Convert block size to value failed, raw value " + "from etcd is: " + << value; + return false; + } + + if (blocksize != g_block_size) { + LOG(WARNING) << "Block size `" << blocksize + << "` in etcd is not identical with " + "block size `" + << g_block_size << "` in configurations"; + return false; + } + + return true; + } + case EtcdErrCode::EtcdKeyNotExist: { + std::string value = std::to_string(g_block_size); + err = etcdclient->Put(BLOCKSIZEKEY, value); + if (err != EtcdErrCode::EtcdOK) { + LOG(WARNING) << "Put block size `" << g_block_size + << "` to etcd failed, error: " << err; + return false; + } + + return true; + } + default: + LOG(WARNING) << "Get block size from etcd failed"; + return false; + } +} + } // namespace mds } // namespace curve diff --git a/src/mds/server/mds.h b/src/mds/server/mds.h index 89f752d883..676ac0dd6f 100644 --- a/src/mds/server/mds.h +++ b/src/mds/server/mds.h @@ -238,6 +238,8 @@ class MDS { std::shared_ptr snapshotCloneClient_; }; +bool CheckOrInsertBlockSize(EtcdClientImp* etcdclient); + } // namespace mds } // namespace curve diff --git a/src/mds/topology/topology_service_manager.cpp b/src/mds/topology/topology_service_manager.cpp index e71953c80d..4b661ad9cc 100644 --- a/src/mds/topology/topology_service_manager.cpp +++ b/src/mds/topology/topology_service_manager.cpp @@ -55,9 +55,21 @@ using ::curve::mds::copyset::Copyset; using ::curve::mds::copyset::CopysetConstrait; using ::curve::common::CopysetInfo; + void TopologyServiceManager::RegistChunkServer( const ChunkServerRegistRequest *request, ChunkServerRegistResponse *response) { + if (request->has_blocksize()) { + if (request->blocksize() != mds::g_block_size) { + response->set_statuscode(kTopoErrCodeConflictBlockSize); + LOG(WARNING) + << "chunk's block size is not identical with MDS, block size: " + << mds::g_block_size + << ", request block size: " << request->blocksize(); + return; + } + } + std::string hostIp = request->hostip(); uint32_t port = request->port(); ::curve::common::NameLockGuard lock(registCsMutex, diff --git a/src/mds/topology/topology_service_manager.h b/src/mds/topology/topology_service_manager.h index 2ee4c5e628..f53b000a6d 100644 --- a/src/mds/topology/topology_service_manager.h +++ b/src/mds/topology/topology_service_manager.h @@ -38,7 +38,6 @@ namespace curve { namespace mds { namespace topology { - class TopologyServiceManager { public: TopologyServiceManager( diff --git a/src/tools/curve_format_main.cpp b/src/tools/curve_format_main.cpp index f929fd8280..5ea5d91b20 100644 --- a/src/tools/curve_format_main.cpp +++ b/src/tools/curve_format_main.cpp @@ -35,8 +35,12 @@ #include "src/fs/fs_common.h" #include "src/fs/local_filesystem.h" #include "src/common/crc32.h" +#include "src/common/bitmap.h" #include "src/common/curve_define.h" #include "src/chunkserver/datastore/file_pool.h" +#include "src/common/fast_align.h" + +using ::curve::common::is_aligned; /** * chunkfile pool预分配工具,提供两种分配方式 @@ -53,10 +57,18 @@ DEFINE_uint32(fileSize, 16 * 1024 * 1024, "chunk size"); -DEFINE_uint32(metaPagSize, +DEFINE_uint32(metaPageSize, 4 * 1024, "metapage size for every chunk"); +static bool ValidateMetaPageSize(const char* /*name*/, uint32_t metaPageSize) { + return is_aligned(metaPageSize, 4096); +} + +DEFINE_validator(metaPageSize, &ValidateMetaPageSize); + +DEFINE_uint32(blockSize, 4096, "minimum io alignment supported"); + DEFINE_string(fileSystemPath, "./", "chunkserver disk path"); @@ -90,7 +102,8 @@ using curve::fs::FileSystemType; using curve::fs::LocalFsFactory; using curve::fs::FileSystemInfo; using curve::fs::LocalFileSystem; -using curve::common::kFilePoolMaigic; +using curve::common::kFilePoolMagic; +using curve::chunkserver::FilePoolMeta; class CompareInternal { public: @@ -111,8 +124,8 @@ struct AllocateStruct { }; int AllocateFiles(AllocateStruct* allocatestruct) { - char* data = new(std::nothrow)char[FLAGS_fileSize + FLAGS_metaPagSize]; - memset(data, 0, FLAGS_fileSize + FLAGS_metaPagSize); + char* data = new(std::nothrow)char[FLAGS_fileSize + FLAGS_metaPageSize]; + memset(data, 0, FLAGS_fileSize + FLAGS_metaPageSize); uint64_t count = 0; while (count < allocatestruct->chunknum) { @@ -126,31 +139,31 @@ int AllocateFiles(AllocateStruct* allocatestruct) { std::string tmpchunkfilepath = FLAGS_filePoolDir + "/" + filename + allocatestruct->cleanChunkSuffix; - int ret = allocatestruct->fsptr->Open(tmpchunkfilepath.c_str(), + int ret = allocatestruct->fsptr->Open(tmpchunkfilepath, O_RDWR | O_CREAT); if (ret < 0) { *allocatestruct->checkwrong = true; - LOG(ERROR) << "file open failed, " << tmpchunkfilepath.c_str(); + LOG(ERROR) << "file open failed, " << tmpchunkfilepath; break; } int fd = ret; ret = allocatestruct->fsptr->Fallocate(fd, 0, 0, - FLAGS_fileSize + FLAGS_metaPagSize); + FLAGS_fileSize + FLAGS_metaPageSize); if (ret < 0) { allocatestruct->fsptr->Close(fd); *allocatestruct->checkwrong = true; - LOG(ERROR) << "Fallocate failed, " << tmpchunkfilepath.c_str(); + LOG(ERROR) << "Fallocate failed, " << tmpchunkfilepath; break; } if (FLAGS_needWriteZero) { ret = allocatestruct->fsptr->Write(fd, data, 0, - FLAGS_fileSize + FLAGS_metaPagSize); + FLAGS_fileSize + FLAGS_metaPageSize); if (ret < 0) { allocatestruct->fsptr->Close(fd); *allocatestruct->checkwrong = true; - LOG(ERROR) << "write failed, " << tmpchunkfilepath.c_str(); + LOG(ERROR) << "write failed, " << tmpchunkfilepath; break; } } @@ -159,14 +172,14 @@ int AllocateFiles(AllocateStruct* allocatestruct) { if (ret < 0) { allocatestruct->fsptr->Close(fd); *allocatestruct->checkwrong = true; - LOG(ERROR) << "fsync failed, " << tmpchunkfilepath.c_str(); + LOG(ERROR) << "fsync failed, " << tmpchunkfilepath; break; } allocatestruct->fsptr->Close(fd); if (ret < 0) { *allocatestruct->checkwrong = true; - LOG(ERROR) << "close failed, " << tmpchunkfilepath.c_str(); + LOG(ERROR) << "close failed, " << tmpchunkfilepath; break; } count++; @@ -175,6 +188,35 @@ int AllocateFiles(AllocateStruct* allocatestruct) { return *allocatestruct->checkwrong == true ? 0 : -1; } +// Minimum extra meta size except bitmap. +// See src/chunkserver/datastore/chunkserver_chunkfile.h, for normal/clone chunk +// metapage usage. +// See src/chunkserver/datastore/chunkserver_snapshot.h, for snapshot chunk +// metapage usage. We hard code it for compatibility. +// TODO(all): remove this hard code value, it's should calculated by actual +// usage. +static constexpr uint32_t kMinimumExtraMetaSize = 4096 - 512; + +// for clone chunk and snapshot chunk, we have bitmap to identify whether +// corresponding block is written or not, +// so, check whether meta page size is enough for store bitmap +// and other metadata +static bool CheckChunkAndMetaPageSize() { + if (!is_aligned(FLAGS_fileSize, FLAGS_blockSize)) { + LOG(ERROR) << "io alignment or file size is wrong"; + return false; + } + + auto bitmapBytes = + FLAGS_fileSize / FLAGS_blockSize / curve::common::BITMAP_UNIT_SIZE; + if (bitmapBytes + kMinimumExtraMetaSize > FLAGS_metaPageSize) { + LOG(ERROR) << "meta page size is too small"; + return false; + } + + return true; +} + // TODO(tongguangxun) :添加单元测试 int main(int argc, char** argv) { google::ParseCommandLineFlags(&argc, &argv, false); @@ -187,12 +229,16 @@ int main(int argc, char** argv) { std::atomic allocateChunknum_(0); std::vector tmpvec; - if (fsptr->Mkdir(FLAGS_filePoolDir.c_str()) < 0) { - LOG(ERROR) << "mkdir failed!, " << FLAGS_filePoolDir.c_str(); + if (!CheckChunkAndMetaPageSize()) { + return -1; + } + + if (fsptr->Mkdir(FLAGS_filePoolDir) < 0) { + LOG(ERROR) << "mkdir failed!, " << FLAGS_filePoolDir; return -1; } - if (fsptr->List(FLAGS_filePoolDir.c_str(), &tmpvec) < 0) { - LOG(ERROR) << "list dir failed!, " << FLAGS_filePoolDir.c_str(); + if (fsptr->List(FLAGS_filePoolDir, &tmpvec) < 0) { + LOG(ERROR) << "list dir failed!, " << FLAGS_filePoolDir; return -1; } @@ -222,7 +268,7 @@ int main(int argc, char** argv) { if (FLAGS_allocateByPercent) { preAllocateChunkNum = preAllocateSize - / (FLAGS_fileSize + FLAGS_metaPagSize); + / (FLAGS_fileSize + FLAGS_metaPageSize); } else { preAllocateChunkNum = FLAGS_preAllocateNum; } @@ -240,8 +286,8 @@ int main(int argc, char** argv) { allocateStruct.cleanChunkSuffix = curve::chunkserver::FilePool::GetCleanChunkSuffix(); - thvec.push_back(std::move(std::thread(AllocateFiles, &allocateStruct))); - thvec.push_back(std::move(std::thread(AllocateFiles, &allocateStruct))); + thvec.push_back(std::thread(AllocateFiles, &allocateStruct)); + thvec.push_back(std::thread(AllocateFiles, &allocateStruct)); for (auto& iter : thvec) { iter.join(); @@ -252,12 +298,14 @@ int main(int argc, char** argv) { return -1; } + FilePoolMeta meta; + meta.chunkSize = FLAGS_fileSize; + meta.metaPageSize = FLAGS_metaPageSize; + meta.hasBlockSize = true; + meta.blockSize = FLAGS_blockSize; + meta.filePoolPath = FLAGS_filePoolDir; int ret = curve::chunkserver::FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, - FLAGS_fileSize, - FLAGS_metaPagSize, - FLAGS_filePoolDir, - FLAGS_filePoolMetaPath); + fsptr, meta, FLAGS_filePoolMetaPath); if (ret == -1) { LOG(ERROR) << "persist chunkfile pool meta info failed!"; @@ -265,40 +313,36 @@ int main(int argc, char** argv) { } // 读取meta文件,检查是否写入正确 - uint32_t chunksize = 0; - uint32_t metapagesize = 0; - std::string chunkfilePath; - + FilePoolMeta recordMeta; ret = curve::chunkserver::FilePoolHelper::DecodeMetaInfoFromMetaFile( - fsptr, - FLAGS_filePoolMetaPath, - 4096, - &chunksize, - &metapagesize, - &chunkfilePath); + fsptr, FLAGS_filePoolMetaPath, 4096, &recordMeta); if (ret == -1) { LOG(ERROR) << "chunkfile pool meta info file got something wrong!"; - fsptr->Delete(FLAGS_filePoolMetaPath.c_str()); + fsptr->Delete(FLAGS_filePoolMetaPath); return -1; } bool valid = false; do { - if (chunksize != FLAGS_fileSize) { + if (recordMeta.chunkSize != FLAGS_fileSize) { LOG(ERROR) << "chunksize meta info persistency wrong!"; break; } - if (metapagesize != FLAGS_metaPagSize) { + if (recordMeta.metaPageSize != FLAGS_metaPageSize) { LOG(ERROR) << "metapagesize meta info persistency wrong!"; break; } - if (strcmp(chunkfilePath.c_str(), - FLAGS_filePoolDir.c_str()) != 0) { + if (recordMeta.blockSize != FLAGS_blockSize) { + LOG(ERROR) << "block size meta info persistency wrong!"; + break; + } + + if (recordMeta.filePoolPath != FLAGS_filePoolDir) { LOG(ERROR) << "meta info persistency failed!" - << ", read chunkpath = " << chunkfilePath.c_str() - << ", real chunkpath = " << FLAGS_filePoolDir.c_str(); + << ", read chunkpath = " << recordMeta.filePoolPath + << ", real chunkpath = " << FLAGS_filePoolDir; break; } diff --git a/test/chunkserver/chunk_service_test.cpp b/test/chunkserver/chunk_service_test.cpp index b00107fb02..93e0be55ec 100644 --- a/test/chunkserver/chunk_service_test.cpp +++ b/test/chunkserver/chunk_service_test.cpp @@ -42,6 +42,8 @@ namespace curve { namespace chunkserver { +static constexpr uint32_t kOpRequestAlignSize = 4096; + using curve::common::UUIDGenerator; class ChunkserverTest : public testing::Test { diff --git a/test/chunkserver/chunk_service_test2.cpp b/test/chunkserver/chunk_service_test2.cpp index 7fcf4fbd07..6c606bf91d 100644 --- a/test/chunkserver/chunk_service_test2.cpp +++ b/test/chunkserver/chunk_service_test2.cpp @@ -44,6 +44,8 @@ namespace chunkserver { using curve::common::UUIDGenerator; +static constexpr uint32_t kOpRequestAlignSize = 4096; + class ChunkService2Test : public testing::Test { protected: virtual void SetUp() { diff --git a/test/chunkserver/chunkserver_snapshot_test.cpp b/test/chunkserver/chunkserver_snapshot_test.cpp index 43e29743c4..f1654aa50a 100644 --- a/test/chunkserver/chunkserver_snapshot_test.cpp +++ b/test/chunkserver/chunkserver_snapshot_test.cpp @@ -41,6 +41,8 @@ using curve::fs::LocalFileSystem; using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; +static constexpr uint32_t kOpRequestAlignSize = 4096; + class ChunkServerSnapshotTest : public testing::Test { protected: virtual void SetUp() { diff --git a/test/chunkserver/chunkserver_test_util.cpp b/test/chunkserver/chunkserver_test_util.cpp index d3bcc0934b..5a56ee8d73 100644 --- a/test/chunkserver/chunkserver_test_util.cpp +++ b/test/chunkserver/chunkserver_test_util.cpp @@ -88,12 +88,16 @@ std::shared_ptr InitFilePool(std::shared_ptr fsptr, /** * 持久化FilePool meta file */ + + FilePoolMeta meta; + meta.chunkSize = chunkfileSize; + meta.metaPageSize = metaPageSize; + meta.hasBlockSize = true; + meta.blockSize = 4096; + meta.filePoolPath = dirname; + int ret = curve::chunkserver::FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, - chunkfileSize, - metaPageSize, - dirname, - metaPath); + fsptr, meta, metaPath); if (ret == -1) { LOG(ERROR) << "persist chunkfile pool meta info failed!"; @@ -192,7 +196,8 @@ int StartChunkserver(const char *ip, DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); copysetNode->SetCSDateStore(dataStore); diff --git a/test/chunkserver/client.cpp b/test/chunkserver/client.cpp index e66bc9b5e5..7f8c2e6243 100644 --- a/test/chunkserver/client.cpp +++ b/test/chunkserver/client.cpp @@ -37,7 +37,7 @@ DEFINE_int32(timeout_ms, 500, "Timeout for each request"); DEFINE_int32(election_timeout_ms, 3000, "election timeout ms"); DEFINE_int32(write_percentage, 100, "Percentage of fetch_add"); DEFINE_string(confs, - "127.0.0.1:8200:0,127.0.0.1:8201:0,127.0.0.1:8202:0", + "127.0.0.1:18200:0,127.0.0.1:18201:0,127.0.0.1:18202:0", "Configuration of the raft group"); using curve::chunkserver::CopysetRequest; diff --git a/test/chunkserver/clone/BUILD b/test/chunkserver/clone/BUILD index 5e342358c4..b9720f4167 100644 --- a/test/chunkserver/clone/BUILD +++ b/test/chunkserver/clone/BUILD @@ -20,10 +20,12 @@ cc_test( name = "clone_test", srcs = glob([ "*.cpp", + ]) + [ "clone_test_util.h", - ]), + ], deps = [ "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", "//external:gflags", "//external:glog", "//external:braft", diff --git a/test/chunkserver/clone/clone_core_test.cpp b/test/chunkserver/clone/clone_core_test.cpp index b245b11eb9..78366277aa 100644 --- a/test/chunkserver/clone/clone_core_test.cpp +++ b/test/chunkserver/clone/clone_core_test.cpp @@ -25,6 +25,8 @@ #include #include +#include + #include "src/chunkserver/clone_core.h" #include "src/chunkserver/copyset_node.h" #include "src/chunkserver/op_request.h" @@ -54,9 +56,15 @@ const LogicPoolID LOGICPOOL_ID = 1; const CopysetID COPYSET_ID = 1; const ChunkID CHUNK_ID = 1; -class CloneCoreTest : public testing::Test { +class CloneCoreTest + : public testing::TestWithParam< + std::tuple> { public: void SetUp() { + chunksize_ = std::get<0>(GetParam()); + blocksize_ = std::get<1>(GetParam()); + pagesize_ = std::get<1>(GetParam()); + datastore_ = std::make_shared(); copyer_ = std::make_shared(); node_ = std::make_shared(); @@ -131,6 +139,10 @@ class CloneCoreTest : public testing::Test { } protected: + ChunkSizeType chunksize_; + ChunkSizeType blocksize_; + PageSizeType pagesize_; + std::shared_ptr datastore_; std::shared_ptr node_; std::shared_ptr copyer_; @@ -140,9 +152,9 @@ class CloneCoreTest : public testing::Test { * 测试CHUNK_OP_READ类型请求,请求读取的chunk不是clone chunk * result:不会从远端拷贝数据,直接从本地读取数据,结果返回成功 */ -TEST_F(CloneCoreTest, ReadChunkTest1) { +TEST_P(CloneCoreTest, ReadChunkTest1) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; std::shared_ptr core = std::make_shared(SLICE_SIZE, true, copyer_); std::shared_ptr readRequest @@ -153,7 +165,9 @@ TEST_F(CloneCoreTest, ReadChunkTest1) { // 获取chunk信息 CSChunkInfo info; info.isClone = false; - info.pageSize = PAGE_SIZE; + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; EXPECT_CALL(*datastore_, GetChunkInfo(_, _)) .WillOnce(DoAll(SetArgPointee<1>(info), Return(CSErrorCode::Success))); @@ -188,14 +202,15 @@ TEST_F(CloneCoreTest, ReadChunkTest1) { * case4:请求读取的区域部分被写过,请求的偏移未与pagesize对齐 * result4:返回错误 */ -TEST_F(CloneCoreTest, ReadChunkTest2) { +TEST_P(CloneCoreTest, ReadChunkTest2) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); std::shared_ptr core = std::make_shared(SLICE_SIZE, true, copyer_); // case1 @@ -305,12 +320,14 @@ TEST_F(CloneCoreTest, ReadChunkTest2) { .WillRepeatedly(DoAll(SetArgPointee<1>(info), Return(CSErrorCode::Success))); // 读chunk文件 - char chunkData[3 * PAGE_SIZE]; - memset(chunkData, 'a', 3 * PAGE_SIZE); - EXPECT_CALL(*datastore_, ReadChunk(_, _, _, 0, 3 * PAGE_SIZE)) - .WillOnce(DoAll(SetArrayArgument<2>(chunkData, - chunkData + 3 * PAGE_SIZE), - Return(CSErrorCode::Success))); + char chunkData[pagesize_ + 2 * blocksize_]; // NOLINT(runtime/arrays) + memset(chunkData, 'a', pagesize_ + 2 * blocksize_); + EXPECT_CALL(*datastore_, + ReadChunk(_, _, _, 0, pagesize_ + 2 * blocksize_)) + .WillOnce( + DoAll(SetArrayArgument<2>( + chunkData, chunkData + pagesize_ + 2 * blocksize_), + Return(CSErrorCode::Success))); // 更新 applied index EXPECT_CALL(*node_, UpdateAppliedIndex(_)) .Times(1); @@ -337,15 +354,16 @@ TEST_F(CloneCoreTest, ReadChunkTest2) { task.done->Run(); ASSERT_EQ(memcmp(chunkData, closure->resContent_.attachment.to_string().c_str(), //NOLINT - 3 * PAGE_SIZE), 0); + 3 * blocksize_), 0); ASSERT_EQ(memcmp(cloneData, - closure->resContent_.attachment.to_string().c_str() + 3 * PAGE_SIZE, //NOLINT - 2 * PAGE_SIZE), 0); + closure->resContent_.attachment.to_string().c_str() + 3 * blocksize_, //NOLINT + 2 * blocksize_), 0); } // case4 { - offset = 1024; - length = 4 * PAGE_SIZE; + static unsigned int seed = time(nullptr); + offset = blocksize_ + (rand_r(&seed) & 1 ? 1 : -1); + length = 4 * blocksize_; info.bitmap->Clear(); info.bitmap->Set(0, 2); // 每次调HandleReadRequest后会被closure释放 @@ -383,14 +401,15 @@ TEST_F(CloneCoreTest, ReadChunkTest2) { * 测试CHUNK_OP_READ类型请求,请求读取的chunk不存在,但是请求中包含源端数据地址 * 预期结果:从源端下载数据,产生paste请求 */ -TEST_F(CloneCoreTest, ReadChunkTest3) { +TEST_P(CloneCoreTest, ReadChunkTest3) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / pagesize_); std::shared_ptr core = std::make_shared(SLICE_SIZE, true, copyer_); @@ -454,14 +473,15 @@ TEST_F(CloneCoreTest, ReadChunkTest3) { * case3:ReadChunk时出错 * result3:返回-1,response状态改为CHUNK_OP_STATUS_FAILURE_UNKNOWN */ -TEST_F(CloneCoreTest, ReadChunkErrorTest) { +TEST_P(CloneCoreTest, ReadChunkErrorTest) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); info.bitmap->Clear(); info.bitmap->Set(0, 2); std::shared_ptr core @@ -563,9 +583,9 @@ TEST_F(CloneCoreTest, ReadChunkErrorTest) { * 测试CHUNK_OP_RECOVER类型请求,请求的chunk不是clone chunk * result:不会从远端拷贝数据,也不会从本地读取数据,直接返回成功 */ -TEST_F(CloneCoreTest, RecoverChunkTest1) { +TEST_P(CloneCoreTest, RecoverChunkTest1) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * pagesize_; std::shared_ptr core = std::make_shared(SLICE_SIZE, true, copyer_); std::shared_ptr readRequest @@ -576,7 +596,9 @@ TEST_F(CloneCoreTest, RecoverChunkTest1) { // 获取chunk信息 CSChunkInfo info; info.isClone = false; - info.pageSize = PAGE_SIZE; + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; EXPECT_CALL(*datastore_, GetChunkInfo(_, _)) .WillOnce(DoAll(SetArgPointee<1>(info), Return(CSErrorCode::Success))); @@ -604,14 +626,15 @@ TEST_F(CloneCoreTest, RecoverChunkTest1) { * case2:请求恢复的区域全部或部分未被写过 * result2:从远端拷贝数据,并产生paste请求 */ -TEST_F(CloneCoreTest, RecoverChunkTest2) { +TEST_P(CloneCoreTest, RecoverChunkTest2) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); std::shared_ptr core = std::make_shared(SLICE_SIZE, true, copyer_); // case1 @@ -689,14 +712,15 @@ TEST_F(CloneCoreTest, RecoverChunkTest2) { // case1: read chunk时,从远端拷贝数据,但是不会产生paste请求 // case2: recover chunk时,从远端拷贝数据,会产生paste请求 -TEST_F(CloneCoreTest, DisablePasteTest) { +TEST_P(CloneCoreTest, DisablePasteTest) { off_t offset = 0; - size_t length = 5 * PAGE_SIZE; + size_t length = 5 * blocksize_; CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = pagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); std::shared_ptr core = std::make_shared(SLICE_SIZE, false, copyer_); @@ -785,5 +809,15 @@ TEST_F(CloneCoreTest, DisablePasteTest) { } } +INSTANTIATE_TEST_CASE_P( + CloneCoreTest, + CloneCoreTest, + ::testing::Values( + // chunk size block size, metapagesize + std::make_tuple(16U * 1024 * 1024, 4096U, 4096U), + std::make_tuple(16U * 1024 * 1024, 4096U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 4096U * 4))); + } // namespace chunkserver } // namespace curve diff --git a/test/chunkserver/clone/clone_test_util.h b/test/chunkserver/clone/clone_test_util.h index bf3ab51788..55b04f986b 100644 --- a/test/chunkserver/clone/clone_test_util.h +++ b/test/chunkserver/clone/clone_test_util.h @@ -59,8 +59,6 @@ using ::google::protobuf::Message; using ::google::protobuf::Closure; const uint32_t SLICE_SIZE = 1024 * 1024; -const uint32_t PAGE_SIZE = 4 * 1024; -const uint32_t CHUNK_SIZE = 16 * 1024 * 1024; const uint32_t LAST_INDEX = 5; class FakeChunkClosure : public ::google::protobuf::Closure { diff --git a/test/chunkserver/clone/op_request_test.cpp b/test/chunkserver/clone/op_request_test.cpp index 20e821132f..e078950c0e 100644 --- a/test/chunkserver/clone/op_request_test.cpp +++ b/test/chunkserver/clone/op_request_test.cpp @@ -50,9 +50,15 @@ class FakeConcurrentApplyModule : public ConcurrentApplyModule { } }; -class OpRequestTest : public testing::Test { +class OpRequestTest + : public testing::TestWithParam< + std::tuple> { public: void SetUp() { + chunksize_ = std::get<0>(GetParam()); + blocksize_ = std::get<1>(GetParam()); + metapagesize_ = std::get<2>(GetParam()); + node_ = std::make_shared(); datastore_ = std::make_shared(); cloneMgr_ = std::make_shared(); @@ -86,18 +92,22 @@ class OpRequestTest : public testing::Test { } protected: + ChunkSizeType chunksize_; + ChunkSizeType blocksize_; + PageSizeType metapagesize_; + std::shared_ptr node_; std::shared_ptr datastore_; std::shared_ptr cloneMgr_; std::shared_ptr concurrentApplyModule_; }; -TEST_F(OpRequestTest, CreateCloneTest) { +TEST_P(OpRequestTest, CreateCloneTest) { // 创建CreateCloneChunkRequest LogicPoolID logicPoolId = 1; CopysetID copysetId = 10001; uint64_t chunkId = 12345; - uint32_t size = CHUNK_SIZE; + uint32_t size = chunksize_; uint64_t sn = 1; string location("test@cs"); ChunkRequest* request = new ChunkRequest(); @@ -309,7 +319,7 @@ TEST_F(OpRequestTest, CreateCloneTest) { closure->Release(); } -TEST_F(OpRequestTest, PasteChunkTest) { +TEST_P(OpRequestTest, PasteChunkTest) { // 生成临时的readrequest ChunkResponse *response = new ChunkResponse(); std::shared_ptr readChunkRequest = @@ -537,13 +547,13 @@ TEST_F(OpRequestTest, PasteChunkTest) { closure->Release(); } -TEST_F(OpRequestTest, ReadChunkTest) { +TEST_P(OpRequestTest, ReadChunkTest) { // 创建CreateCloneChunkRequest LogicPoolID logicPoolId = 1; CopysetID copysetId = 10001; uint64_t chunkId = 12345; uint32_t offset = 0; - uint32_t length = 5 * PAGE_SIZE; + uint32_t length = 5 * blocksize_; ChunkRequest* request = new ChunkRequest(); request->set_logicpoolid(logicPoolId); request->set_copysetid(copysetId); @@ -641,9 +651,10 @@ TEST_F(OpRequestTest, ReadChunkTest) { CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = metapagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); /** * 测试Process @@ -997,13 +1008,13 @@ TEST_F(OpRequestTest, ReadChunkTest) { closure->Release(); } -TEST_F(OpRequestTest, RecoverChunkTest) { +TEST_P(OpRequestTest, RecoverChunkTest) { // 创建CreateCloneChunkRequest LogicPoolID logicPoolId = 1; CopysetID copysetId = 10001; uint64_t chunkId = 12345; uint32_t offset = 0; - uint32_t length = 5 * PAGE_SIZE; + uint32_t length = 5 * blocksize_; ChunkRequest* request = new ChunkRequest(); request->set_logicpoolid(logicPoolId); request->set_copysetid(copysetId); @@ -1071,9 +1082,10 @@ TEST_F(OpRequestTest, RecoverChunkTest) { CSChunkInfo info; info.isClone = true; - info.pageSize = PAGE_SIZE; - info.chunkSize = CHUNK_SIZE; - info.bitmap = std::make_shared(CHUNK_SIZE / PAGE_SIZE); + info.metaPageSize = metapagesize_; + info.chunkSize = chunksize_; + info.blockSize = blocksize_; + info.bitmap = std::make_shared(chunksize_ / blocksize_); /** * 测试Process @@ -1354,5 +1366,15 @@ TEST_F(OpRequestTest, RecoverChunkTest) { closure->Release(); } +INSTANTIATE_TEST_CASE_P( + OpRequestTest, + OpRequestTest, + ::testing::Values( + // chunk size block size, metapagesize + std::make_tuple(16U * 1024 * 1024, 4096U, 4096U), + std::make_tuple(16U * 1024 * 1024, 4096U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 4096U * 4))); + } // namespace chunkserver } // namespace curve diff --git a/test/chunkserver/copyset_node_test.cpp b/test/chunkserver/copyset_node_test.cpp index 6d34509d1e..f4e72fea61 100644 --- a/test/chunkserver/copyset_node_test.cpp +++ b/test/chunkserver/copyset_node_test.cpp @@ -333,7 +333,8 @@ TEST_F(CopysetNodeTest, error_test) { DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); copysetNode.SetCSDateStore(dataStore); @@ -361,7 +362,8 @@ TEST_F(CopysetNodeTest, error_test) { DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); copysetNode.SetCSDateStore(dataStore); diff --git a/test/chunkserver/datastore/datastore_mock_unittest.cpp b/test/chunkserver/datastore/datastore_mock_unittest.cpp index 363fd0e852..fb0885c9a7 100644 --- a/test/chunkserver/datastore/datastore_mock_unittest.cpp +++ b/test/chunkserver/datastore/datastore_mock_unittest.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "include/chunkserver/chunkserver_common.h" #include "src/common/bitmap.h" @@ -47,6 +48,7 @@ using ::testing::NotNull; using ::testing::Matcher; using ::testing::Mock; using ::testing::Truly; +using ::testing::Invoke; using ::testing::DoAll; using ::testing::ReturnArg; using ::testing::ElementsAre; @@ -60,8 +62,6 @@ using std::string; namespace curve { namespace chunkserver { -const ChunkSizeType CHUNK_SIZE = 16 * 1024 * 1024; -const PageSizeType PAGE_SIZE = 4096; const uint32_t kLocationLimit = 3000; const char baseDir[] = "/home/chunkserver/copyset/data"; const char chunk1[] = "chunk_1"; @@ -96,27 +96,42 @@ ACTION_TEMPLATE(SetVoidArrayArgument, } } -class CSDataStore_test : public testing::Test { +class CSDataStore_test + : public testing::TestWithParam< + std::tuple> { public: void SetUp() { + chunksize_ = std::get<0>(GetParam()); + blocksize_ = std::get<1>(GetParam()); + metapagesize_ = std::get<2>(GetParam()); + + chunk1MetaPage = new char[metapagesize_]; + chunk2MetaPage = new char[metapagesize_]; + chunk1SnapMetaPage = new char[metapagesize_]; + lfs_ = std::make_shared(); fpool_ = std::make_shared(lfs_); DataStoreOptions options; options.baseDir = baseDir; - options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.chunkSize = chunksize_; + options.blockSize = blocksize_; + options.metaPageSize = metapagesize_; options.locationLimit = kLocationLimit; options.enableOdsyncWhenOpenChunkFile = true; dataStore = std::make_shared(lfs_, fpool_, options); fdMock = 100; - memset(chunk1MetaPage, 0, PAGE_SIZE); - memset(chunk2MetaPage, 0, PAGE_SIZE); - memset(chunk1SnapMetaPage, 0, PAGE_SIZE); + memset(chunk1MetaPage, 0, metapagesize_); + memset(chunk2MetaPage, 0, metapagesize_); + memset(chunk1SnapMetaPage, 0, metapagesize_); } - void TearDown() {} + void TearDown() override { + delete[] chunk1MetaPage; + delete[] chunk2MetaPage; + delete[] chunk1SnapMetaPage; + } inline void FakeEncodeChunk(char* buf, SequenceNum correctedSn, @@ -134,7 +149,7 @@ class CSDataStore_test : public testing::Test { inline void FakeEncodeSnapshot(char* buf, SequenceNum sn) { - uint32_t bits = CHUNK_SIZE / PAGE_SIZE; + uint32_t bits = chunksize_ / blocksize_; SnapshotMetaPage metaPage; metaPage.version = FORMAT_VERSION; metaPage.sn = sn; @@ -201,7 +216,7 @@ class CSDataStore_test : public testing::Test { .WillByDefault(Return(0)); // fake Fstat struct stat fileInfo; - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(_, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -216,25 +231,25 @@ class CSDataStore_test : public testing::Test { .WillByDefault(ReturnArg<3>()); // fake read chunk1 metapage FakeEncodeChunk(chunk1MetaPage, 0, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) - .WillRepeatedly(DoAll( - SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) + .WillRepeatedly( + DoAll(SetArrayArgument<1>(chunk1MetaPage, + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk1's snapshot1 metapage FakeEncodeSnapshot(chunk1SnapMetaPage, 1); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( - SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + SetArrayArgument<1>(chunk1SnapMetaPage, + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk2 metapage FakeEncodeChunk(chunk2MetaPage, 0, 2); - EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, PAGE_SIZE)) - .WillRepeatedly(DoAll( - SetArrayArgument<1>(chunk2MetaPage, - chunk2MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, metapagesize_)) + .WillRepeatedly( + DoAll(SetArrayArgument<1>(chunk2MetaPage, + chunk2MetaPage + metapagesize_), + Return(metapagesize_))); } protected: @@ -242,21 +257,26 @@ class CSDataStore_test : public testing::Test { std::shared_ptr lfs_; std::shared_ptr fpool_; std::shared_ptr dataStore; - char chunk1MetaPage[PAGE_SIZE]; - char chunk2MetaPage[PAGE_SIZE]; - char chunk1SnapMetaPage[PAGE_SIZE]; + char* chunk1MetaPage; + char* chunk2MetaPage; + char* chunk1SnapMetaPage; + + ChunkSizeType chunksize_; + ChunkSizeType blocksize_; + PageSizeType metapagesize_; }; /** * ConstructorTest * case:测试构造参数为空的情况 * 预期结果:进程退出 */ -TEST_F(CSDataStore_test, ConstructorTest) { +TEST_P(CSDataStore_test, ConstructorTest) { // null param test DataStoreOptions options; options.baseDir = baseDir; - options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.chunkSize = chunksize_; + options.blockSize = blocksize_; + options.metaPageSize = metapagesize_; ASSERT_DEATH(std::make_shared(nullptr, fpool_, options), @@ -277,7 +297,7 @@ TEST_F(CSDataStore_test, ConstructorTest) { * case:存在未知类型的文件 * 预期结果:删除该文件,返回true */ -TEST_F(CSDataStore_test, InitializeTest1) { +TEST_P(CSDataStore_test, InitializeTest1) { // test unknown file EXPECT_CALL(*lfs_, DirExists(baseDir)) .Times(1) @@ -299,7 +319,7 @@ TEST_F(CSDataStore_test, InitializeTest1) { * case:存在快照文件,但是快照文件没有对应的chunk * 预期结果:删除快照文件,返回true */ -TEST_F(CSDataStore_test, InitializeTest2) { +TEST_P(CSDataStore_test, InitializeTest2) { // test snapshot without chunk EXPECT_CALL(*lfs_, DirExists(baseDir)) .Times(1) @@ -320,7 +340,7 @@ TEST_F(CSDataStore_test, InitializeTest2) { * case:存在chunk文件,chunk文件存在快照文件 * 预期结果:正常加载文件,返回true */ -TEST_F(CSDataStore_test, InitializeTest3) { +TEST_P(CSDataStore_test, InitializeTest3) { // test chunk with snapshot FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -338,7 +358,7 @@ TEST_F(CSDataStore_test, InitializeTest3) { * List的时候snapshot先于chunk文件被list * 预期结果:返回true */ -TEST_F(CSDataStore_test, InitializeTest4) { +TEST_P(CSDataStore_test, InitializeTest4) { // test snapshot founded before chunk file , // but open chunk file failed FakeEnv(); @@ -362,7 +382,7 @@ TEST_F(CSDataStore_test, InitializeTest4) { * case:存在chunk文件,chunk文件存在两个冲突的快照文件 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeTest5) { +TEST_P(CSDataStore_test, InitializeTest5) { // test snapshot conflict FakeEnv(); vector fileNames; @@ -385,7 +405,7 @@ TEST_F(CSDataStore_test, InitializeTest5) { * case:data目录不存在,创建目录时失败 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeErrorTest1) { +TEST_P(CSDataStore_test, InitializeErrorTest1) { // dir not exist and mkdir failed EXPECT_CALL(*lfs_, DirExists(baseDir)) .Times(1) @@ -404,7 +424,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest1) { * case:List目录时失败 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeErrorTest2) { +TEST_P(CSDataStore_test, InitializeErrorTest2) { // List dir failed EXPECT_CALL(*lfs_, DirExists(baseDir)) .Times(1) @@ -424,7 +444,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest2) { * case:open chunk文件的时候出错 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeErrorTest3) { +TEST_P(CSDataStore_test, InitializeErrorTest3) { // test chunk open failed FakeEnv(); // set open chunk file failed @@ -449,9 +469,9 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { // expect call close EXPECT_CALL(*lfs_, Close(1)) .Times(1); - // stat success but file size not equal CHUNK_SIZE + PAGE_SIZE + // stat success but file size not equal chunksize_ + metapagesize_ struct stat fileInfo; - fileInfo.st_size = CHUNK_SIZE; + fileInfo.st_size = chunksize_; EXPECT_CALL(*lfs_, Fstat(1, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -464,12 +484,12 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { EXPECT_CALL(*lfs_, Close(1)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(1, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); // read metapage failed - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_FALSE(dataStore->Initialize()); @@ -480,17 +500,17 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { EXPECT_CALL(*lfs_, Close(1)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(1, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); // read metapage success, but version incompatible uint8_t version = FORMAT_VERSION + 1; memcpy(chunk1MetaPage, &version, sizeof(uint8_t)); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_FALSE(dataStore->Initialize()); // open success @@ -500,7 +520,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { EXPECT_CALL(*lfs_, Close(1)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(1, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -508,10 +528,10 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { version = FORMAT_VERSION; chunk1MetaPage[1] += 1; // change the page data memcpy(chunk1MetaPage, &version, sizeof(uint8_t)); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_FALSE(dataStore->Initialize()); } @@ -520,7 +540,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest3) { * case:open 快照文件的时候出错 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeErrorTest4) { +TEST_P(CSDataStore_test, InitializeErrorTest4) { // test chunk open failed FakeEnv(); // set open snapshot file failed @@ -551,9 +571,9 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { // expect call close EXPECT_CALL(*lfs_, Close(2)) .Times(1); - // stat success but file size not equal CHUNK_SIZE + PAGE_SIZE + // stat success but file size not equal chunksize_ + metapagesize_ struct stat fileInfo; - fileInfo.st_size = CHUNK_SIZE; + fileInfo.st_size = chunksize_; EXPECT_CALL(*lfs_, Fstat(2, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -569,12 +589,12 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { EXPECT_CALL(*lfs_, Close(2)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(2, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); // read metapage failed - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_FALSE(dataStore->Initialize()); @@ -588,17 +608,17 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { EXPECT_CALL(*lfs_, Close(2)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(2, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); // read metapage success, but version incompatible uint8_t version = FORMAT_VERSION + 1; memcpy(chunk1SnapMetaPage, &version, sizeof(uint8_t)); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_FALSE(dataStore->Initialize()); // 每次重新初始化都会释放原先的资源,重新加载 @@ -611,7 +631,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { EXPECT_CALL(*lfs_, Close(2)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(2, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -619,10 +639,10 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { version = FORMAT_VERSION; chunk1SnapMetaPage[1] += 1; // change the page data memcpy(chunk1SnapMetaPage, &version, sizeof(uint8_t)); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_FALSE(dataStore->Initialize()); EXPECT_CALL(*lfs_, Close(1)) @@ -636,7 +656,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest4) { * open chunk文件的时候出错 * 预期结果:返回false */ -TEST_F(CSDataStore_test, InitializeErrorTest5) { +TEST_P(CSDataStore_test, InitializeErrorTest5) { // test snapshot founded before chunk file , // but open chunk file failed FakeEnv(); @@ -659,7 +679,7 @@ TEST_F(CSDataStore_test, InitializeErrorTest5) { * case:chunk 不存在 * 预期结果:创建chunk文件,并成功写入数据 */ -TEST_F(CSDataStore_test, WriteChunkTest1) { +TEST_P(CSDataStore_test, WriteChunkTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -667,7 +687,7 @@ TEST_F(CSDataStore_test, WriteChunkTest1) { ChunkID id = 3; SequenceNum sn = 1; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = metapagesize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // create new chunk and open it @@ -690,16 +710,16 @@ TEST_F(CSDataStore_test, WriteChunkTest1) { .Times(1) .WillOnce(Return(4)); // will read metapage - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); FakeEncodeChunk(chunk3MetaPage, 0, 1); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); // will write data - EXPECT_CALL(*lfs_, - Write(4, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(4, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->WriteChunk(id, @@ -739,7 +759,7 @@ TEST_F(CSDataStore_test, WriteChunkTest1) { * case:chunk存在,请求sn小于chunk的sn * 预期结果:拒绝写入,返回BackwardRequestError */ -TEST_F(CSDataStore_test, WriteChunkTest2) { +TEST_P(CSDataStore_test, WriteChunkTest2) { // initialize FakeEnv(); // set chunk2's correctedSn as 3 @@ -749,7 +769,7 @@ TEST_F(CSDataStore_test, WriteChunkTest2) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = metapagesize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); @@ -795,22 +815,22 @@ TEST_F(CSDataStore_test, WriteChunkTest2) { * case:chunk存在,请求sn小于chunk的correctedSn * 预期结果:拒绝写入,返回BackwardRequestError */ -TEST_F(CSDataStore_test, WriteChunkTest3) { +TEST_P(CSDataStore_test, WriteChunkTest3) { // initialize FakeEnv(); // set chunk2's correctedSn as 3 FakeEncodeChunk(chunk2MetaPage, 4, 2); - EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk2MetaPage, - chunk2MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk2MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = metapagesize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); @@ -857,7 +877,7 @@ TEST_F(CSDataStore_test, WriteChunkTest3) { * chunk不存在快照 * 预期结果:直接写数据到chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest4) { +TEST_P(CSDataStore_test, WriteChunkTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -865,13 +885,13 @@ TEST_F(CSDataStore_test, WriteChunkTest4) { ChunkID id = 2; SequenceNum sn = 2; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = metapagesize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will write data - EXPECT_CALL(*lfs_, - Write(3, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(3, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -886,8 +906,8 @@ TEST_F(CSDataStore_test, WriteChunkTest4) { ASSERT_EQ(2, info.curSn); ASSERT_EQ(0, info.snapSn); - // return InvalidArgError if offset+length > CHUNK_SIZE - offset = CHUNK_SIZE; + // return InvalidArgError if offset+length > chunksize_ + offset = chunksize_; EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), _, __amd64)) .Times(0); EXPECT_EQ(CSErrorCode::InvalidArgError, @@ -898,8 +918,8 @@ TEST_F(CSDataStore_test, WriteChunkTest4) { length, nullptr)); // return InvalidArgError if length not aligned - offset = PAGE_SIZE; - length = PAGE_SIZE - 1; + offset = blocksize_; + length = blocksize_ - 1; EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), _, _)) .Times(0); EXPECT_EQ(CSErrorCode::InvalidArgError, @@ -910,8 +930,8 @@ TEST_F(CSDataStore_test, WriteChunkTest4) { length, nullptr)); // return InvalidArgError if offset not aligned - offset = PAGE_SIZE + 1; - length = PAGE_SIZE; + offset = blocksize_ + 1; + length = blocksize_; EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), _, _)) .Times(0); EXPECT_EQ(CSErrorCode::InvalidArgError, @@ -937,30 +957,31 @@ TEST_F(CSDataStore_test, WriteChunkTest4) { * chunk不存在快照 * 预期结果:会更新metapage,然后写数据到chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest6) { +TEST_P(CSDataStore_test, WriteChunkTest6) { // initialize FakeEnv(); // set chunk2's correctedSn as 3 FakeEncodeChunk(chunk2MetaPage, 3, 2); - EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk2MetaPage, - chunk2MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk2MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will update metapage - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data EXPECT_CALL(*lfs_, Write(3, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -990,7 +1011,7 @@ TEST_F(CSDataStore_test, WriteChunkTest6) { * 预期结果:会创建快照文件,更新metapage, * 写数据时先cow到snapshot,再写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest7) { +TEST_P(CSDataStore_test, WriteChunkTest7) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -998,7 +1019,7 @@ TEST_F(CSDataStore_test, WriteChunkTest7) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will Open snapshot file, snap sn equals 2 @@ -1013,28 +1034,30 @@ TEST_F(CSDataStore_test, WriteChunkTest7) { EXPECT_CALL(*lfs_, Open(snapPath, _)) .WillOnce(Return(4)); // will read snapshot metapage - char metapage[PAGE_SIZE]; + char metapage[metapagesize_]; // NOLINT(runtime/arrays) memset(metapage, 0, sizeof(metapage)); FakeEncodeSnapshot(metapage, 2); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(metapage, - metapage + PAGE_SIZE), - Return(PAGE_SIZE))); + metapage + metapagesize_), + Return(metapagesize_))); // will update metapage - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will copy on write - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .Times(1); EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data EXPECT_CALL(*lfs_, Write(3, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -1049,9 +1072,9 @@ TEST_F(CSDataStore_test, WriteChunkTest7) { ASSERT_EQ(3, info.curSn); ASSERT_EQ(2, info.snapSn); - // 再次写同一个page的数据,不再进行cow,而是直接写入数据 + // 再次写同一个block的数据,不再进行cow,而是直接写入数据 EXPECT_CALL(*lfs_, Write(3, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->WriteChunk(id, @@ -1086,7 +1109,7 @@ TEST_F(CSDataStore_test, WriteChunkTest7) { * chunk存在快照 * 预期结果:先cow到snapshot,再写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest9) { +TEST_P(CSDataStore_test, WriteChunkTest9) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1094,22 +1117,23 @@ TEST_F(CSDataStore_test, WriteChunkTest9) { ChunkID id = 1; SequenceNum sn = 2; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will not create snapshot // will copy on write - EXPECT_CALL(*lfs_, Read(1, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), metapagesize_ + offset, length)) .Times(1); EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(2, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -1138,31 +1162,32 @@ TEST_F(CSDataStore_test, WriteChunkTest9) { * chunk存在快照 * 预期结果:更新metapage,然后写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest10) { +TEST_P(CSDataStore_test, WriteChunkTest10) { // initialize FakeEnv(); // set chunk1's correctedSn as 3 FakeEncodeChunk(chunk1MetaPage, 3, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will update metapage - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will not cow // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -1191,22 +1216,22 @@ TEST_F(CSDataStore_test, WriteChunkTest10) { * chunk存在快照,snapsn(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 4; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); @@ -1244,7 +1269,7 @@ TEST_F(CSDataStore_test, WriteChunkTest11) { * case4:遍写整个chunk * 预期结果4:写入数据,然后clone chunk会被转为普通chunk */ -TEST_F(CSDataStore_test, WriteChunkTest13) { +TEST_P(CSDataStore_test, WriteChunkTest13) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1253,17 +1278,17 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { SequenceNum sn = 1; SequenceNum correctedSn = 0; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); CSChunkInfo info; // 创建 clone chunk { LOG(INFO) << "case 1"; - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); shared_ptr bitmap = - make_shared(CHUNK_SIZE / PAGE_SIZE); + make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it string chunk3Path = string(baseDir) + "/" + @@ -1277,15 +1302,15 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); } @@ -1293,14 +1318,14 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { { LOG(INFO) << "case 2"; id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, @@ -1322,13 +1347,13 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { { LOG(INFO) << "case 3"; id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(0); ASSERT_EQ(CSErrorCode::Success, @@ -1351,16 +1376,17 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { LOG(INFO) << "case 4"; id = 3; // not exist offset = 0; - length = 4 * PAGE_SIZE; + length = 4 * blocksize_; std::unique_ptr buf(new char[length]); - // [2 * PAGE_SIZE, 4 * PAGE_SIZE)区域已写过,[0, PAGE_SIZE)为metapage + // [2 * blocksize_, 4 * blocksize_)区域已写过 + // [0, metapagesize_)为metapage EXPECT_CALL(*lfs_, Write(4, Matcher(_), - offset + PAGE_SIZE, length)) + offset + metapagesize_, length)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, @@ -1383,16 +1409,17 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { LOG(INFO) << "case 5"; id = 3; // not exist offset = 0; - length = CHUNK_SIZE; + length = chunksize_; std::unique_ptr buf(new char[length]); - // [PAGE_SIZE, 4 * PAGE_SIZE)区域已写过,[0, PAGE_SIZE)为metapage + // [blocksize_, 4 * blocksize_)区域已写过 + // [0, metapagesize_)为metapage EXPECT_CALL(*lfs_, Write(4, Matcher(_), - offset + PAGE_SIZE, length)) + offset + metapagesize_, length)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, @@ -1430,7 +1457,7 @@ TEST_F(CSDataStore_test, WriteChunkTest13) { * case4:clone chunk 存在,sn>chunk.sn, sn>chunk.correctedsn * 预期结果4:返回StatusConflictError */ -TEST_F(CSDataStore_test, WriteChunkTest14) { +TEST_P(CSDataStore_test, WriteChunkTest14) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1439,16 +1466,16 @@ TEST_F(CSDataStore_test, WriteChunkTest14) { SequenceNum sn = 2; SequenceNum correctedSn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); CSChunkInfo info; // 创建 clone chunk { - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); shared_ptr bitmap = - make_shared(CHUNK_SIZE / PAGE_SIZE); + make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it string chunk3Path = string(baseDir) + "/" + @@ -1462,15 +1489,15 @@ TEST_F(CSDataStore_test, WriteChunkTest14) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); ASSERT_EQ(2, info.curSn); @@ -1510,15 +1537,15 @@ TEST_F(CSDataStore_test, WriteChunkTest14) { { LOG(INFO) << "case 2"; id = 3; - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; sn = 3; // sn > chunk.sn;sn == correctedsn EXPECT_CALL(*lfs_, Write(4, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(2); ASSERT_EQ(CSErrorCode::Success, @@ -1544,16 +1571,17 @@ TEST_F(CSDataStore_test, WriteChunkTest14) { { LOG(INFO) << "case 3"; offset = 0; - length = 4 * PAGE_SIZE; + length = 4 * blocksize_; std::unique_ptr buf(new char[length]); - // [2 * PAGE_SIZE, 4 * PAGE_SIZE)区域已写过,[0, PAGE_SIZE)为metapage + // [2 * blocksize_, 4 * blocksize_)区域已写过 + // [0, blocksize_)为metapage EXPECT_CALL(*lfs_, Write(4, Matcher(_), - offset + PAGE_SIZE, length)) + offset + metapagesize_, length)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, @@ -1622,29 +1650,29 @@ TEST_F(CSDataStore_test, WriteChunkTest14) { * chunk存在快照 * 预期结果:先cow到snapshot,再写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest15) { +TEST_P(CSDataStore_test, WriteChunkTest15) { // initialize FakeEnv(); // fake read chunk1 metapage FakeEncodeChunk(chunk1MetaPage, 0, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk1's snapshot1 metapage,chunk.sn(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will not create snapshot @@ -1652,8 +1680,8 @@ TEST_F(CSDataStore_test, WriteChunkTest15) { EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), _, _)) .Times(0); // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -1681,29 +1709,29 @@ TEST_F(CSDataStore_test, WriteChunkTest15) { * chunk存在快照 * 预期结果:先cow到snapshot,再写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkTest16) { +TEST_P(CSDataStore_test, WriteChunkTest16) { // initialize FakeEnv(); // fake read chunk1 metapage FakeEncodeChunk(chunk1MetaPage, 0, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk1's snapshot1 metapage FakeEncodeSnapshot(chunk1SnapMetaPage, 3); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will not create snapshot @@ -1711,11 +1739,12 @@ TEST_F(CSDataStore_test, WriteChunkTest16) { EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), _, _)) .Times(0); // will update sn - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -1739,7 +1768,7 @@ TEST_F(CSDataStore_test, WriteChunkTest16) { * case:创建快照文件时出错 * 预期结果:写失败,不会改变当前chunk状态 */ -TEST_F(CSDataStore_test, WriteChunkErrorTest1) { +TEST_P(CSDataStore_test, WriteChunkErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1747,7 +1776,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest1) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); string snapPath = string(baseDir) + "/" + @@ -1795,7 +1824,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest1) { .WillOnce(Return(true)); EXPECT_CALL(*lfs_, Open(snapPath, _)) .WillOnce(Return(4)); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_CALL(*lfs_, Close(4)) .Times(1); @@ -1824,7 +1853,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest1) { * 预期结果:写失败,产生快照文件,但是chunk版本号不会改变 * 再次写入,不会生成新的快照文件 */ -TEST_F(CSDataStore_test, WriteChunkErrorTest2) { +TEST_P(CSDataStore_test, WriteChunkErrorTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1832,7 +1861,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest2) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will Open snapshot file, snap sn equals 2 @@ -1846,15 +1875,16 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest2) { EXPECT_CALL(*lfs_, Open(snapPath, _)) .WillOnce(Return(4)); // will read snapshot metapage - char metapage[PAGE_SIZE]; + char metapage[metapagesize_]; // NOLINT(runtime/arrays) memset(metapage, 0, sizeof(metapage)); FakeEncodeSnapshot(metapage, 2); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(metapage, - metapage + PAGE_SIZE), - Return(PAGE_SIZE))); + metapage + metapagesize_), + Return(metapagesize_))); // write chunk metapage failed - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, @@ -1886,7 +1916,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest2) { * 预期结果:写失败,产生快照文件,chunk版本号发生变更, * 快照的bitmap未发生变化,再次写入,仍会进行cow */ -TEST_F(CSDataStore_test, WriteChunkErrorTest3) { +TEST_P(CSDataStore_test, WriteChunkErrorTest3) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -1894,7 +1924,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will Open snapshot file, snap sn equals 2 @@ -1908,20 +1938,21 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { EXPECT_CALL(*lfs_, Open(snapPath, _)) .WillOnce(Return(4)); // will read snapshot metapage - char metapage[PAGE_SIZE]; + char metapage[metapagesize_]; // NOLINT(runtime/arrays) memset(metapage, 0, sizeof(metapage)); FakeEncodeSnapshot(metapage, 2); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(metapage, - metapage + PAGE_SIZE), - Return(PAGE_SIZE))); + metapage + metapagesize_), + Return(metapagesize_))); // will update metapage - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); LOG(INFO) << "case 1"; // copy data failed - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, @@ -1938,11 +1969,11 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { LOG(INFO) << "case 2"; // copy data success - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .Times(1); // write data to snapshot failed EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->WriteChunk(id, @@ -1957,14 +1988,15 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { LOG(INFO) << "case 3"; // copy data success - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .Times(1); // write data to snapshot success - EXPECT_CALL(*lfs_, - Write(4, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(4, Matcher(_), metapagesize_ + offset, + length)) .Times(1); // update snapshot metapage failed - EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(4, Matcher(NotNull()), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->WriteChunk(id, @@ -1980,17 +2012,18 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { // 再次写入仍会cow // will copy on write LOG(INFO) << "case 4"; - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .Times(1); EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data - EXPECT_CALL(*lfs_, - Write(3, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(3, Matcher(_), + metapagesize_ + offset, length)) .Times(1); LOG(INFO) << "case 5"; @@ -2018,7 +2051,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest3) { * 预期结果:写失败,产生快照文件,chunk版本号发生变更, * 快照的bitmap发生变化,再次写入,直接写chunk文件 */ -TEST_F(CSDataStore_test, WriteChunkErrorTest4) { +TEST_P(CSDataStore_test, WriteChunkErrorTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -2026,7 +2059,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest4) { ChunkID id = 2; SequenceNum sn = 3; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // will Open snapshot file, snap sn equals 2 @@ -2040,28 +2073,30 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest4) { EXPECT_CALL(*lfs_, Open(snapPath, _)) .WillOnce(Return(4)); // will read snapshot metapage - char metapage[PAGE_SIZE]; + char metapage[metapagesize_]; // NOLINT(runtime/arrays) memset(metapage, 0, sizeof(metapage)); FakeEncodeSnapshot(metapage, 2); - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(metapage, - metapage + PAGE_SIZE), - Return(PAGE_SIZE))); + metapage + metapagesize_), + Return(metapagesize_))); // will update metapage - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will copy on write - EXPECT_CALL(*lfs_, Read(3, NotNull(), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Read(3, NotNull(), metapagesize_ + offset, length)) .Times(1); EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // write chunk failed - EXPECT_CALL(*lfs_, - Write(3, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(3, Matcher(_), + metapagesize_ + offset, length)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, @@ -2073,8 +2108,8 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest4) { nullptr)); // 再次写入直接写chunk文件 // will write data - EXPECT_CALL(*lfs_, - Write(3, Matcher(_), PAGE_SIZE + offset, length)) + EXPECT_CALL(*lfs_, Write(3, Matcher(_), + metapagesize_ + offset, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, @@ -2099,7 +2134,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest4) { * case:chunk 不存在 * 预期结果:创建chunk文件的时候失败 */ -TEST_F(CSDataStore_test, WriteChunkErrorTest5) { +TEST_P(CSDataStore_test, WriteChunkErrorTest5) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -2107,7 +2142,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest5) { ChunkID id = 3; SequenceNum sn = 1; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // create new chunk and open it @@ -2168,9 +2203,9 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest5) { // expect call close EXPECT_CALL(*lfs_, Close(4)) .Times(1); - // stat success but file size not equal CHUNK_SIZE + PAGE_SIZE + // stat success but file size not equal chunksize_ + metapagesize_ struct stat fileInfo; - fileInfo.st_size = CHUNK_SIZE; + fileInfo.st_size = chunksize_; EXPECT_CALL(*lfs_, Fstat(4, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); @@ -2190,12 +2225,12 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest5) { EXPECT_CALL(*lfs_, Close(4)) .Times(1); // stat success - fileInfo.st_size = CHUNK_SIZE + PAGE_SIZE; + fileInfo.st_size = chunksize_ + metapagesize_; EXPECT_CALL(*lfs_, Fstat(4, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(fileInfo), Return(0))); // read metapage failed - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->WriteChunk(id, sn, @@ -2222,7 +2257,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest5) { * case3:更新metapage时失败 * 预期结果3:返回InternalError,chunk状态不变 */ -TEST_F(CSDataStore_test, WriteChunkErrorTest6) { +TEST_P(CSDataStore_test, WriteChunkErrorTest6) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -2231,7 +2266,7 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest6) { SequenceNum sn = 1; SequenceNum correctedSn = 0; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); CSChunkInfo info; @@ -2242,15 +2277,15 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest6) { dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, longLocation)); } // 创建 clone chunk { - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); shared_ptr bitmap = - make_shared(CHUNK_SIZE / PAGE_SIZE); + make_shared(chunksize_ / metapagesize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it string chunk3Path = string(baseDir) + "/" + @@ -2264,28 +2299,28 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest6) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); } // case1:写数据时失败 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .WillOnce(Return(-UT_ERRNO)); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(0); ASSERT_EQ(CSErrorCode::InternalError, dataStore->WriteChunk(id, @@ -2302,14 +2337,14 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest6) { // case2:更新metapage时失败 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(_), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); ASSERT_EQ(CSErrorCode::InternalError, dataStore->WriteChunk(id, @@ -2339,15 +2374,15 @@ TEST_F(CSDataStore_test, WriteChunkErrorTest6) { * case:chunk不存在 * 预期结果:返回ChunkNotExistError错误码 */ -TEST_F(CSDataStore_test, ReadChunkTest1) { +TEST_P(CSDataStore_test, ReadChunkTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 3; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = blocksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test chunk not exists @@ -2371,15 +2406,15 @@ TEST_F(CSDataStore_test, ReadChunkTest1) { * case:chunk存在,读取区域超过chunk大小或者offset和length未对齐 * 预期结果:返回InvalidArgError错误码 */ -TEST_F(CSDataStore_test, ReadChunkTest2) { +TEST_P(CSDataStore_test, ReadChunkTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - off_t offset = CHUNK_SIZE; - size_t length = PAGE_SIZE; + off_t offset = chunksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test read out of range @@ -2390,8 +2425,8 @@ TEST_F(CSDataStore_test, ReadChunkTest2) { offset, length)); // return InvalidArgError if length not aligned - offset = PAGE_SIZE; - length = PAGE_SIZE - 1; + offset = blocksize_; + length = blocksize_ - 1; EXPECT_EQ(CSErrorCode::InvalidArgError, dataStore->ReadChunk(id, sn, @@ -2399,8 +2434,8 @@ TEST_F(CSDataStore_test, ReadChunkTest2) { offset, length)); // return InvalidArgError if offset not aligned - offset = PAGE_SIZE + 1; - length = PAGE_SIZE; + offset = blocksize_ + 1; + length = blocksize_; EXPECT_EQ(CSErrorCode::InvalidArgError, dataStore->ReadChunk(id, sn, @@ -2421,19 +2456,19 @@ TEST_F(CSDataStore_test, ReadChunkTest2) { * case:正常读取存在的chunk * 预期结果:读取成功 */ -TEST_F(CSDataStore_test, ReadChunkTest3) { +TEST_P(CSDataStore_test, ReadChunkTest3) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = blocksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test chunk exists - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->ReadChunk(id, @@ -2460,7 +2495,7 @@ TEST_F(CSDataStore_test, ReadChunkTest3) { * case3:读取区域已被写过 * 预期结果:返回Success,数据成功写入 */ -TEST_F(CSDataStore_test, ReadChunkTest4) { +TEST_P(CSDataStore_test, ReadChunkTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -2469,9 +2504,9 @@ TEST_F(CSDataStore_test, ReadChunkTest4) { SequenceNum sn = 1; SequenceNum correctedSn = 2; CSChunkInfo info; - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); - shared_ptr bitmap = make_shared(CHUNK_SIZE / PAGE_SIZE); + shared_ptr bitmap = make_shared(chunksize_ / metapagesize_); bitmap->Set(0); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); @@ -2487,20 +2522,20 @@ TEST_F(CSDataStore_test, ReadChunkTest4) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // case1: 读取未写过区域 - off_t offset = 1 * PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = 1 * blocksize_; + size_t length = blocksize_; char buf[2 * length]; // NOLINT memset(buf, 0, sizeof(buf)); EXPECT_CALL(*lfs_, Read(_, _, _, _)) @@ -2514,7 +2549,7 @@ TEST_F(CSDataStore_test, ReadChunkTest4) { // case2: 读取区域部分被写过 offset = 0; - length = 2 * PAGE_SIZE; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Read(_, _, _, _)) .Times(0); EXPECT_EQ(CSErrorCode::PageNerverWrittenError, @@ -2526,8 +2561,8 @@ TEST_F(CSDataStore_test, ReadChunkTest4) { // case3: 读取区域已写过 offset = 0; - length = PAGE_SIZE; - EXPECT_CALL(*lfs_, Read(4, NotNull(), offset + PAGE_SIZE, length)) + length = blocksize_; + EXPECT_CALL(*lfs_, Read(4, NotNull(), offset + metapagesize_, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->ReadChunk(id, @@ -2551,19 +2586,19 @@ TEST_F(CSDataStore_test, ReadChunkTest4) { * case:读chunk文件时出错 * 预期结果:读取失败,返回InternalError */ -TEST_F(CSDataStore_test, ReadChunkErrorTest1) { +TEST_P(CSDataStore_test, ReadChunkErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = blocksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test read chunk failed - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->ReadChunk(id, @@ -2585,15 +2620,15 @@ TEST_F(CSDataStore_test, ReadChunkErrorTest1) { * case:chunk不存在 * 预期结果:返回ChunkNotExistError错误码 */ -TEST_F(CSDataStore_test, ReadSnapshotChunkTest1) { +TEST_P(CSDataStore_test, ReadSnapshotChunkTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 3; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = blocksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test chunk not exists @@ -2617,15 +2652,15 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest1) { * case:chunk存在,请求版本号等于chunk版本号 * 预期结果:读chunk的数据 */ -TEST_F(CSDataStore_test, ReadSnapshotChunkTest2) { +TEST_P(CSDataStore_test, ReadSnapshotChunkTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - off_t offset = CHUNK_SIZE; - size_t length = 2 * PAGE_SIZE; + off_t offset = chunksize_; + size_t length = 2 * blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test out of range @@ -2636,8 +2671,8 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest2) { offset, length)); // test offset not aligned - offset = CHUNK_SIZE - 1; - length = CHUNK_SIZE; + offset = chunksize_ - 1; + length = chunksize_; EXPECT_EQ(CSErrorCode::InvalidArgError, dataStore->ReadSnapshotChunk(id, sn, @@ -2645,8 +2680,8 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest2) { offset, length)); // test length not aligned - offset = CHUNK_SIZE; - length = CHUNK_SIZE + 1; + offset = chunksize_; + length = chunksize_ + 1; EXPECT_EQ(CSErrorCode::InvalidArgError, dataStore->ReadSnapshotChunk(id, sn, @@ -2654,9 +2689,9 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest2) { offset, length)); // test in range - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + offset = blocksize_; + length = 2 * blocksize_; + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->ReadSnapshotChunk(id, @@ -2678,29 +2713,30 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest2) { * case:chunk存在,请求版本号等于snapshot版本号 * 预期结果:读快照的数据 */ -TEST_F(CSDataStore_test, ReadSnapshotChunkTest3) { +TEST_P(CSDataStore_test, ReadSnapshotChunkTest3) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); // fake data ChunkID id = 1; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE * 2; + off_t offset = blocksize_; + size_t length = blocksize_ * 2; char writeBuf[length]; // NOLINT memset(writeBuf, 0, sizeof(writeBuf)); - // data in [PAGE_SIZE, 2*PAGE_SIZE) will be cow - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + // data in [blocksize_, 2*blocksize_) will be cow + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .Times(1); EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), - offset + PAGE_SIZE, length)) + offset + metapagesize_, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(2, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), offset + PAGE_SIZE, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + offset + metapagesize_, length)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->WriteChunk(id, @@ -2712,8 +2748,8 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest3) { // test out of range sn = 1; - offset = CHUNK_SIZE; - length = PAGE_SIZE * 4; + offset = chunksize_; + length = blocksize_ * 4; char readBuf[length]; // NOLINT memset(readBuf, 0, sizeof(readBuf)); EXPECT_EQ(CSErrorCode::InvalidArgError, @@ -2722,15 +2758,17 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest3) { readBuf, offset, length)); - // test in range, read [0, 4*PAGE_SIZE) + // test in range, read [0, 4*blocksize_) offset = 0; - // read chunk in[0, PAGE_SIZE) and [3*PAGE_SIZE, 4*PAGE_SIZE) - EXPECT_CALL(*lfs_, Read(1, NotNull(), PAGE_SIZE, PAGE_SIZE)) + // read chunk in[0, blocksize_) and [3*blocksize_, 4*blocksize_) + EXPECT_CALL(*lfs_, Read(1, NotNull(), metapagesize_, blocksize_)) .Times(1); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 4 * PAGE_SIZE, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Read(1, NotNull(), metapagesize_ + 3 * blocksize_, blocksize_)) .Times(1); - // read snapshot in[PAGE_SIZE, 3*PAGE_SIZE) - EXPECT_CALL(*lfs_, Read(2, NotNull(), 2 * PAGE_SIZE, 2 * PAGE_SIZE)) + // read snapshot in[blocksize_, 3*blocksize_) + EXPECT_CALL(*lfs_, Read(2, NotNull(), metapagesize_ + 1 * blocksize_, + 2 * blocksize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->ReadSnapshotChunk(id, @@ -2752,15 +2790,15 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest3) { * case:chunk存在,但是请求的版本号不存在 * 预期结果:返回ChunkNotExistError错误码 */ -TEST_F(CSDataStore_test, ReadSnapshotChunkTest4) { +TEST_P(CSDataStore_test, ReadSnapshotChunkTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 3; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE; + off_t offset = blocksize_; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test sn not exists @@ -2784,31 +2822,32 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkTest4) { * case:读快照时失败 * 预期结果:返回InternalError */ -TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest1) { +TEST_P(CSDataStore_test, ReadSnapshotChunkErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); // fake data ChunkID id = 1; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = PAGE_SIZE * 2; + off_t offset = blocksize_; + size_t length = blocksize_ * 2; char writeBuf[length]; // NOLINT memset(writeBuf, 0, sizeof(writeBuf)); - // data in [PAGE_SIZE, 2*PAGE_SIZE) will be cow - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + // data in [blocksize_, 2*blocksize_) will be cow + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .Times(1); EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), - offset + PAGE_SIZE, length)) + offset + metapagesize_, length)) .Times(1); // will update snapshot metapage - EXPECT_CALL(*lfs_, Write(2, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(2, Matcher(NotNull()), 0, metapagesize_)) .Times(1); // will write data - EXPECT_CALL(*lfs_, - Write(1, Matcher(_), offset + PAGE_SIZE, length)) + EXPECT_CALL(*lfs_, Write(1, Matcher(_), + offset + metapagesize_, length)) .Times(1); - EXPECT_EQ(CSErrorCode::Success, + ASSERT_EQ(CSErrorCode::Success, dataStore->WriteChunk(id, sn, writeBuf, @@ -2816,16 +2855,16 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest1) { length, nullptr)); - // test in range, read [0, 4*PAGE_SIZE) + // test in range, read [0, 4*blocksize_) sn = 1; offset = 0; - length = PAGE_SIZE * 4; + length = blocksize_ * 4; char readBuf[length]; // NOLINT memset(readBuf, 0, sizeof(readBuf)); // read chunk failed - EXPECT_CALL(*lfs_, Read(1, NotNull(), PAGE_SIZE, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), metapagesize_, blocksize_)) .WillOnce(Return(-UT_ERRNO)); - EXPECT_EQ(CSErrorCode::InternalError, + ASSERT_EQ(CSErrorCode::InternalError, dataStore->ReadSnapshotChunk(id, sn, readBuf, @@ -2833,18 +2872,16 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest1) { length)); // read snapshot failed - EXPECT_CALL(*lfs_, Read(1, NotNull(), PAGE_SIZE, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), metapagesize_, blocksize_)) .Times(1); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 4 * PAGE_SIZE, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Read(1, NotNull(), metapagesize_ + 3 * blocksize_, blocksize_)) .Times(1); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 2 * PAGE_SIZE, 2 * PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), metapagesize_ + 1 * blocksize_, + 2 * blocksize_)) .WillOnce(Return(-UT_ERRNO)); - EXPECT_EQ(CSErrorCode::InternalError, - dataStore->ReadSnapshotChunk(id, - sn, - readBuf, - offset, - length)); + ASSERT_EQ(CSErrorCode::InternalError, + dataStore->ReadSnapshotChunk(id, sn, readBuf, offset, length)); EXPECT_CALL(*lfs_, Close(1)) .Times(1); @@ -2859,20 +2896,20 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest1) { * case:chunk存在,请求版本号等于chunk版本号,读数据时失败 * 预期结果:返回InternalError */ -TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest2) { +TEST_P(CSDataStore_test, ReadSnapshotChunkErrorTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - off_t offset = PAGE_SIZE; - size_t length = 2 * PAGE_SIZE; + off_t offset = blocksize_; + size_t length = 2 * blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); // test in range - offset = PAGE_SIZE; - EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + PAGE_SIZE, length)) + offset = blocksize_; + EXPECT_CALL(*lfs_, Read(1, NotNull(), offset + metapagesize_, length)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->ReadSnapshotChunk(id, @@ -2894,15 +2931,15 @@ TEST_F(CSDataStore_test, ReadSnapshotChunkErrorTest2) { * case: read normal chunk * expect: read successfully */ -TEST_F(CSDataStore_test, ReadChunkMetaDataTest1) { +TEST_P(CSDataStore_test, ReadChunkMetaDataTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 3; SequenceNum sn = 2; - char buf[PAGE_SIZE]; - memset(buf, 0, PAGE_SIZE); + char buf[blocksize_]; // NOLINT(runtime/arrays) + memset(buf, 0, blocksize_); // test chunk not exists EXPECT_EQ(CSErrorCode::ChunkNotExistError, dataStore->ReadChunkMetaPage(id, sn, buf)); @@ -2920,17 +2957,17 @@ TEST_F(CSDataStore_test, ReadChunkMetaDataTest1) { * case: read normal chunk * expect: read successfully */ -TEST_F(CSDataStore_test, ReadChunkMetaDataTest2) { +TEST_P(CSDataStore_test, ReadChunkMetaDataTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; SequenceNum sn = 2; - char buf[PAGE_SIZE]; - memset(buf, 0, PAGE_SIZE); + char buf[blocksize_]; // NOLINT(runtime/arrays) + memset(buf, 0, blocksize_); // test chunk exists - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->ReadChunkMetaPage(id, sn, buf)); @@ -2949,7 +2986,7 @@ TEST_F(CSDataStore_test, ReadChunkMetaDataTest2) { * case:chunk不存在 * 预期结果:返回成功 */ -TEST_F(CSDataStore_test, DeleteChunkTest1) { +TEST_P(CSDataStore_test, DeleteChunkTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -2974,7 +3011,7 @@ TEST_F(CSDataStore_test, DeleteChunkTest1) { * case:chunk存在快照文件 * 预期结果:返回Success, chunk被删除,快照被删除 */ -TEST_F(CSDataStore_test, DeleteChunkTest2) { +TEST_P(CSDataStore_test, DeleteChunkTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3002,7 +3039,7 @@ TEST_F(CSDataStore_test, DeleteChunkTest2) { * case:chunk存在,快照文件不存在 * 预期结果:返回成功 */ -TEST_F(CSDataStore_test, DeleteChunkTest3) { +TEST_P(CSDataStore_test, DeleteChunkTest3) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3033,7 +3070,7 @@ TEST_F(CSDataStore_test, DeleteChunkTest3) { * case2: sn>chunkinfo.sn * 预期结果2:返回成功 */ -TEST_F(CSDataStore_test, DeleteChunkTest4) { +TEST_P(CSDataStore_test, DeleteChunkTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3076,7 +3113,7 @@ TEST_F(CSDataStore_test, DeleteChunkTest4) { * case:chunk存在,快照文件不存在,recyclechunk时出错 * 预期结果:返回成功 */ -TEST_F(CSDataStore_test, DeleteChunkErrorTest1) { +TEST_P(CSDataStore_test, DeleteChunkErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3103,7 +3140,7 @@ TEST_F(CSDataStore_test, DeleteChunkErrorTest1) { * case:chunk不存在 * 预期结果:返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest1) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3136,16 +3173,16 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest1) { * chunk.sn>snap.sn * 预期结果:删除快照,不会修改correctedSn,返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest2) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest2) { // initialize FakeEnv(); // set chunk1's correctedSn as 3 FakeEncodeChunk(chunk1MetaPage, 3, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; @@ -3159,7 +3196,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest2) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .Times(1); // chunk's metapage should not be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3177,16 +3215,16 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest2) { * 此时无论correctSn为何值都不会修改correctedSn * 预期结果:返回成功,不会删除快照,不会修改correctedSn */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest3) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest3) { // initialize FakeEnv(); // set chunk1's correctedSn as 0, sn as 3 FakeEncodeChunk(chunk1MetaPage, 0, 3); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; @@ -3197,7 +3235,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest3) { EXPECT_CALL(*lfs_, Close(2)) .Times(0); // chunk's metapage should not be updated - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::BackwardRequestError, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3214,7 +3253,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest3) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .Times(1); // chunk's metapage should not be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3231,7 +3271,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest3) { * fileSn > chunk的sn以及correctedSn * 预期结果:删除快照,并修改correctedSn,返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest4) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest4) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3247,7 +3287,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest4) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .Times(1); // chunk's metapage will be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3264,7 +3305,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest4) { * fileSn <= chunk的sn或correctedSn * 预期结果:不会修改correctedSn,返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest5) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest5) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3274,7 +3315,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest5) { // fileSn > correctedSn SequenceNum fileSn = 2; // chunk's metapage should not be updated - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3293,7 +3335,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest5) { * fileSn > chunk的sn及correctedSn * 预期结果:修改correctedSn,返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest6) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest6) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3303,7 +3345,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest6) { // fileSn > correctedSn SequenceNum fileSn = 4; // chunk's metapage will be updated - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3321,7 +3364,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest6) { * case:chunk存在,snapshot不存在,chunk为clone chunk * 预期结果:返回StatusConflictError */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest7) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest7) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3330,9 +3373,9 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest7) { SequenceNum sn = 2; SequenceNum correctedSn = 4; CSChunkInfo info; - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); - shared_ptr bitmap = make_shared(CHUNK_SIZE / PAGE_SIZE); + shared_ptr bitmap = make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it @@ -3347,15 +3390,15 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest7) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // 无论correctedSn为多少,都返回StatusConflictError @@ -3388,23 +3431,23 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest7) { * chunk.sn==snap.sn * 预期结果:删除快照,不会修改correctedSn,返回成功 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest8) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest8) { // initialize FakeEnv(); // fake read chunk1 metapage FakeEncodeChunk(chunk1MetaPage, 0, 2); - EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk1's snapshot1 metapage,chunk.sn==snap.sn FakeEncodeSnapshot(chunk1SnapMetaPage, 2); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; @@ -3418,7 +3461,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest8) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .Times(0); // chunk's metapage should be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3439,23 +3483,23 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest8) { * chunk.sn(chunk1MetaPage, - chunk1MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1MetaPage + metapagesize_), + Return(metapagesize_))); // fake read chunk1's snapshot1 metapage,chunk.sn==snap.sn FakeEncodeSnapshot(chunk1SnapMetaPage, 3); - EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(2, NotNull(), 0, metapagesize_)) .WillRepeatedly(DoAll( SetArrayArgument<1>(chunk1SnapMetaPage, - chunk1SnapMetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk1SnapMetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_TRUE(dataStore->Initialize()); ChunkID id = 1; @@ -3469,7 +3513,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest9) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .Times(0); // chunk's metapage should not be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3487,7 +3532,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnTest9) { * case:修改correctedSn时失败 * 预期结果:返回失败,correctedSn的值未改变 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest1) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3498,13 +3543,15 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest1) { SequenceNum fileSn = 3; // write chunk metapage failed - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); EXPECT_EQ(CSErrorCode::InternalError, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); // chunk's metapage will be updated - EXPECT_CALL(*lfs_, Write(3, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(3, Matcher(NotNull()), 0, metapagesize_)) .Times(1); EXPECT_EQ(CSErrorCode::Success, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3522,7 +3569,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest1) { * case:回收snapshot的chunk的时候失败 * 预期结果:返回失败 */ -TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest2) { +TEST_P(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3538,7 +3585,8 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest2) { EXPECT_CALL(*fpool_, RecycleFile(chunk1snap1Path)) .WillOnce(Return(-1)); // chunk's metapage will be updated - EXPECT_CALL(*lfs_, Write(1, Matcher(NotNull()), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, + Write(1, Matcher(NotNull()), 0, metapagesize_)) .Times(0); EXPECT_EQ(CSErrorCode::InternalError, dataStore->DeleteSnapshotChunkOrCorrectSn(id, fileSn)); @@ -3564,7 +3612,7 @@ TEST_F(CSDataStore_test, DeleteSnapshotChunkOrCorrectSnErrorTest2) { * case6:指定的chunk存在,chunk不是clone chunk,参数与chunk信息一致 * 预期结果:返回ChunkConflictError,不改变原chunk信息 */ -TEST_F(CSDataStore_test, CreateCloneChunkTest) { +TEST_P(CSDataStore_test, CreateCloneChunkTest) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3573,9 +3621,9 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { SequenceNum sn = 1; SequenceNum correctedSn = 2; CSChunkInfo info; - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); - shared_ptr bitmap = make_shared(CHUNK_SIZE / PAGE_SIZE); + shared_ptr bitmap = make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // case1:输入错误的参数 @@ -3585,7 +3633,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, sn, correctedSn, - PAGE_SIZE, + blocksize_, location)); // sn == 0 @@ -3593,7 +3641,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, 0, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // location is empty @@ -3601,7 +3649,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, "")); } @@ -3619,15 +3667,15 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // 检查生成的clone chunk信息 ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); @@ -3646,7 +3694,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // 检查生成的clone chunk信息 ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); @@ -3667,21 +3715,21 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, sn + 1, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // correctedSn不一致 EXPECT_EQ(CSErrorCode::ChunkConflictError, dataStore->CreateCloneChunk(id, sn, correctedSn + 1, - CHUNK_SIZE, + chunksize_, location)); // location不一致 EXPECT_EQ(CSErrorCode::ChunkConflictError, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, "temp")); // 检查生成的clone chunk信息 ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); @@ -3701,7 +3749,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE + PAGE_SIZE, + chunksize_ + metapagesize_, location)); // 检查生成的clone chunk信息 ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); @@ -3721,7 +3769,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(1, // id 2, // sn 0, // correctedSn - CHUNK_SIZE, + chunksize_, "")); // location 不为空 @@ -3729,7 +3777,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { dataStore->CreateCloneChunk(1, // id 2, // sn 0, // correctedSn - CHUNK_SIZE, + chunksize_, location)); } @@ -3748,7 +3796,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkTest) { * case:chunk不存在,调chunkFile->Open的时候失败 * 预期结果:创建clone chunk失败 */ -TEST_F(CSDataStore_test, CreateCloneChunkErrorTest) { +TEST_P(CSDataStore_test, CreateCloneChunkErrorTest) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3769,7 +3817,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkErrorTest) { dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); // 检查生成的clone chunk信息 ASSERT_EQ(CSErrorCode::ChunkNotExistError, @@ -3800,7 +3848,7 @@ TEST_F(CSDataStore_test, CreateCloneChunkErrorTest) { * case7:遍写整个chunk * 预期结果7:数据写入未写过区域,然后clone chunk会被转为普通chunk */ -TEST_F(CSDataStore_test, PasteChunkTest1) { +TEST_P(CSDataStore_test, PasteChunkTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -3809,16 +3857,16 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { SequenceNum sn = 1; SequenceNum correctedSn = 2; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); CSChunkInfo info; // 创建 clone chunk { - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); shared_ptr bitmap = - make_shared(CHUNK_SIZE / PAGE_SIZE); + make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it string chunk3Path = string(baseDir) + "/" + @@ -3832,15 +3880,15 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); } @@ -3857,21 +3905,21 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { // case2:chunk存在,请求偏移超过chunk文件大小或偏移长度未对齐 { id = 3; // not exist - offset = CHUNK_SIZE; + offset = chunksize_; ASSERT_EQ(CSErrorCode::InvalidArgError, dataStore->PasteChunk(id, buf, offset, length)); - offset = PAGE_SIZE - 1; - length = PAGE_SIZE; + offset = blocksize_ - 1; + length = blocksize_; ASSERT_EQ(CSErrorCode::InvalidArgError, dataStore->PasteChunk(id, buf, offset, length)); - offset = PAGE_SIZE; - length = PAGE_SIZE + 1; + offset = blocksize_; + length = blocksize_ + 1; ASSERT_EQ(CSErrorCode::InvalidArgError, dataStore->PasteChunk(id, buf, @@ -3887,7 +3935,7 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { // 快照不存在 id = 2; offset = 0; - length = PAGE_SIZE; + length = blocksize_; ASSERT_EQ(CSErrorCode::Success, dataStore->PasteChunk(id, buf, @@ -3907,14 +3955,14 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { // case4:chunk存在,且是clone chunk,写入区域之前未写过 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, dataStore->PasteChunk(id, @@ -3932,13 +3980,13 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { // case5:chunk存在,且是clone chunk,写入区域之前已写过 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(0); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(0); ASSERT_EQ(CSErrorCode::Success, dataStore->PasteChunk(id, @@ -3956,22 +4004,19 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { { id = 3; // not exist offset = 0; - length = 4 * PAGE_SIZE; - // [2 * PAGE_SIZE, 4 * PAGE_SIZE)区域已写过,[0, PAGE_SIZE)为metapage - EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), PAGE_SIZE, - PAGE_SIZE)) + length = 4 * blocksize_; + // [2 * blocksize_, 4 * blocksize_)区域已写过,[0, blocksize_)为metapage + EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), + metapagesize_, blocksize_)) .Times(1); EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - 4 * PAGE_SIZE, PAGE_SIZE)) + metapagesize_ + 3 * blocksize_, blocksize_)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, - dataStore->PasteChunk(id, - buf, - offset, - length)); + dataStore->PasteChunk(id, buf, offset, length)); // paste后,chunk的状态不变 ASSERT_EQ(CSErrorCode::Success, dataStore->GetChunkInfo(id, &info)); ASSERT_EQ(true, info.isClone); @@ -3983,15 +4028,15 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { { id = 3; // not exist offset = 0; - length = CHUNK_SIZE; - // [PAGE_SIZE, 4 * PAGE_SIZE)区域已写过,[0, PAGE_SIZE)为metapage + length = chunksize_; + // [blocksize_, 4 * blocksize_)区域已写过,[0, blocksize_)为metapage EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - 5 * PAGE_SIZE, - CHUNK_SIZE - 4 * PAGE_SIZE)) + metapagesize_ + 4 * blocksize_, + chunksize_ - 4 * blocksize_)) .Times(1); EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(1); ASSERT_EQ(CSErrorCode::Success, dataStore->PasteChunk(id, @@ -4021,7 +4066,7 @@ TEST_F(CSDataStore_test, PasteChunkTest1) { * case2:更新metapage时失败 * 预期结果2:返回InternalError,chunk状态不变 */ -TEST_F(CSDataStore_test, PasteChunkErrorTest1) { +TEST_P(CSDataStore_test, PasteChunkErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -4030,16 +4075,16 @@ TEST_F(CSDataStore_test, PasteChunkErrorTest1) { SequenceNum sn = 1; SequenceNum correctedSn = 2; off_t offset = 0; - size_t length = PAGE_SIZE; + size_t length = blocksize_; char buf[length]; // NOLINT memset(buf, 0, sizeof(buf)); CSChunkInfo info; // 创建 clone chunk { - char chunk3MetaPage[PAGE_SIZE]; + char chunk3MetaPage[metapagesize_]; // NOLINT(runtime/arrays) memset(chunk3MetaPage, 0, sizeof(chunk3MetaPage)); shared_ptr bitmap = - make_shared(CHUNK_SIZE / PAGE_SIZE); + make_shared(chunksize_ / blocksize_); FakeEncodeChunk(chunk3MetaPage, correctedSn, sn, bitmap, location); // create new chunk and open it string chunk3Path = string(baseDir) + "/" + @@ -4053,28 +4098,28 @@ TEST_F(CSDataStore_test, PasteChunkErrorTest1) { .Times(1) .WillOnce(Return(4)); // will read metapage - EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, PAGE_SIZE)) + EXPECT_CALL(*lfs_, Read(4, NotNull(), 0, metapagesize_)) .WillOnce(DoAll(SetArrayArgument<1>(chunk3MetaPage, - chunk3MetaPage + PAGE_SIZE), - Return(PAGE_SIZE))); + chunk3MetaPage + metapagesize_), + Return(metapagesize_))); EXPECT_EQ(CSErrorCode::Success, dataStore->CreateCloneChunk(id, sn, correctedSn, - CHUNK_SIZE, + chunksize_, location)); } // case1:写数据时失败 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .WillOnce(Return(-UT_ERRNO)); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .Times(0); ASSERT_EQ(CSErrorCode::InternalError, dataStore->PasteChunk(id, @@ -4089,14 +4134,14 @@ TEST_F(CSDataStore_test, PasteChunkErrorTest1) { // case2:更新metapage时失败 { id = 3; // not exist - offset = PAGE_SIZE; - length = 2 * PAGE_SIZE; + offset = blocksize_; + length = 2 * blocksize_; EXPECT_CALL(*lfs_, Write(4, Matcher(NotNull()), - PAGE_SIZE + offset, length)) + metapagesize_ + offset, length)) .Times(1); // update metapage EXPECT_CALL(*lfs_, - Write(4, Matcher(NotNull()), 0, PAGE_SIZE)) + Write(4, Matcher(NotNull()), 0, metapagesize_)) .WillOnce(Return(-UT_ERRNO)); ASSERT_EQ(CSErrorCode::InternalError, dataStore->PasteChunk(id, @@ -4122,7 +4167,7 @@ TEST_F(CSDataStore_test, PasteChunkErrorTest1) { /* * chunk不存在 */ -TEST_F(CSDataStore_test, GetHashErrorTest1) { +TEST_P(CSDataStore_test, GetHashErrorTest1) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -4148,7 +4193,7 @@ TEST_F(CSDataStore_test, GetHashErrorTest1) { /* * read报错 */ -TEST_F(CSDataStore_test, GetHashErrorTest2) { +TEST_P(CSDataStore_test, GetHashErrorTest2) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -4156,7 +4201,7 @@ TEST_F(CSDataStore_test, GetHashErrorTest2) { ChunkID id = 1; std::string hash; off_t offset = 0; - size_t length = PAGE_SIZE + CHUNK_SIZE; + size_t length = metapagesize_ + chunksize_; // test read chunk failed EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, 4096)) .WillOnce(Return(-UT_ERRNO)); @@ -4176,7 +4221,7 @@ TEST_F(CSDataStore_test, GetHashErrorTest2) { /* * 获取datastore状态测试 */ -TEST_F(CSDataStore_test, GetStatusTest) { +TEST_P(CSDataStore_test, GetStatusTest) { // initialize FakeEnv(); EXPECT_TRUE(dataStore->Initialize()); @@ -4194,5 +4239,15 @@ TEST_F(CSDataStore_test, GetStatusTest) { .Times(1); } +INSTANTIATE_TEST_CASE_P( + CSDataStoreTest, + CSDataStore_test, + ::testing::Values( + // chunk size block size, metapagesize + std::make_tuple(16U * 1024 * 1024, 4096U, 4096U), + std::make_tuple(16U * 1024 * 1024, 4096U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 8192U), + std::make_tuple(16U * 1024 * 1024, 512U, 4096U * 4))); + } // namespace chunkserver } // namespace curve diff --git a/test/chunkserver/datastore/filepool_mock_unittest.cpp b/test/chunkserver/datastore/filepool_mock_unittest.cpp index 95f6691083..af46a4ce39 100644 --- a/test/chunkserver/datastore/filepool_mock_unittest.cpp +++ b/test/chunkserver/datastore/filepool_mock_unittest.cpp @@ -48,7 +48,7 @@ using ::testing::SetArgPointee; using ::testing::SetArrayArgument; using curve::fs::MockLocalFileSystem; -using curve::common::kFilePoolMaigic; +using curve::common::kFilePoolMagic; namespace curve { namespace chunkserver { @@ -56,6 +56,7 @@ namespace chunkserver { const ChunkSizeType CHUNK_SIZE = 16 * 1024 * 1024; const PageSizeType PAGE_SIZE = 4096; const uint32_t metaFileSize = 4096; +const uint32_t blockSize = 4096; const uint32_t fileSize = CHUNK_SIZE + PAGE_SIZE; const std::string poolDir = "./chunkfilepool_dat"; // NOLINT const std::string poolMetaPath = "./chunkfilepool_dat.meta"; // NOLINT @@ -65,6 +66,7 @@ const char* kChunkSize = "chunkSize"; const char* kMetaPageSize = "metaPageSize"; const char* kChunkFilePoolPath = "chunkfilepool_path"; const char* kCRC = "crc"; +const char* kBlockSize = "blockSize"; class CSChunkfilePoolMockTest : public testing::Test { public: @@ -74,29 +76,27 @@ class CSChunkfilePoolMockTest : public testing::Test { void TearDown() {} - Json::Value GenerateMetaJson() { + static Json::Value GenerateMetaJson(bool hasBlockSize = false) { // 正常的meta文件的json格式 - uint32_t crcsize = sizeof(kFilePoolMaigic) + - sizeof(CHUNK_SIZE) + - sizeof(PAGE_SIZE) + - poolDir.size(); - char* crcbuf = new char[crcsize]; - ::memcpy(crcbuf, kFilePoolMaigic, - sizeof(kFilePoolMaigic)); - ::memcpy(crcbuf + sizeof(kFilePoolMaigic), - &CHUNK_SIZE, sizeof(uint32_t)); - ::memcpy(crcbuf + sizeof(uint32_t) + sizeof(kFilePoolMaigic), - &PAGE_SIZE, sizeof(uint32_t)); - ::memcpy(crcbuf + 2 * sizeof(uint32_t) + sizeof(kFilePoolMaigic), - poolDir.c_str(), poolDir.size()); - uint32_t crc = ::curve::common::CRC32(crcbuf, crcsize); - delete[] crcbuf; + FilePoolMeta meta; + meta.chunkSize = CHUNK_SIZE; + meta.metaPageSize = PAGE_SIZE; + meta.hasBlockSize = hasBlockSize; + if (hasBlockSize) { + meta.blockSize = blockSize; + } + meta.filePoolPath = poolDir; Json::Value jsonContent; jsonContent[kChunkSize] = CHUNK_SIZE; jsonContent[kMetaPageSize] = PAGE_SIZE; + + if (hasBlockSize) { + jsonContent[kBlockSize] = blockSize; + } + jsonContent[kChunkFilePoolPath] = poolDir; - jsonContent[kCRC] = crc; + jsonContent[kCRC] = meta.Crc32(); return jsonContent; } @@ -158,6 +158,12 @@ class CSChunkfilePoolMockTest : public testing::Test { // PersistEnCodeMetaInfo接口的异常测试 TEST_F(CSChunkfilePoolMockTest, PersistEnCodeMetaInfoTest) { + FilePoolMeta meta; + meta.chunkSize = CHUNK_SIZE; + meta.metaPageSize = PAGE_SIZE; + meta.hasBlockSize = false; + meta.filePoolPath = poolDir; + // open失败 { EXPECT_CALL(*lfs_, Open(poolMetaPath, _)) @@ -166,12 +172,8 @@ TEST_F(CSChunkfilePoolMockTest, PersistEnCodeMetaInfoTest) { .Times(0); EXPECT_CALL(*lfs_, Close(_)) .Times(0); - ASSERT_EQ(-1, - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, - CHUNK_SIZE, - PAGE_SIZE, - poolDir, - poolMetaPath)); + ASSERT_EQ(-1, FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, + poolMetaPath)); } // open成功,write失败 { @@ -181,12 +183,8 @@ TEST_F(CSChunkfilePoolMockTest, PersistEnCodeMetaInfoTest) { .WillOnce(Return(-1)); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, - CHUNK_SIZE, - PAGE_SIZE, - poolDir, - poolMetaPath)); + ASSERT_EQ(-1, FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, + poolMetaPath)); } // open成功,write成功 { @@ -196,20 +194,15 @@ TEST_F(CSChunkfilePoolMockTest, PersistEnCodeMetaInfoTest) { .WillOnce(Return(4096)); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(0, - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, - CHUNK_SIZE, - PAGE_SIZE, - poolDir, - poolMetaPath)); + ASSERT_EQ( + 0, FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, poolMetaPath)); } } // DecodeMetaInfoFromMetaFile接口的异常测试 TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { - uint32_t chunksize; - uint32_t metapagesize; - std::string chunkfilePath; + FilePoolMeta meta; + // open失败 { EXPECT_CALL(*lfs_, Open(poolMetaPath, _)) @@ -218,13 +211,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { .Times(0); EXPECT_CALL(*lfs_, Close(_)) .Times(0); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // read失败 { @@ -234,13 +222,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { .WillOnce(Return(-1)); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // read成功,解析Json格式失败 { @@ -252,13 +235,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 解析Json格式成功,chunksize为空 { @@ -275,13 +253,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 解析Json格式成功,metapagesize为空 { @@ -298,13 +271,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 解析Json格式成功,kFilePoolPath为空 { @@ -321,13 +289,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 解析Json格式成功,kCRC为空 { @@ -344,13 +307,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 解析Json格式成功,crc不匹配 { @@ -367,13 +325,8 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(-1, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(-1, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } // 正常流程 { @@ -389,13 +342,26 @@ TEST_F(CSChunkfilePoolMockTest, DecodeMetaInfoFromMetaFileTest) { Return(metaFileSize))); EXPECT_CALL(*lfs_, Close(1)) .Times(1); - ASSERT_EQ(0, - FilePoolHelper::DecodeMetaInfoFromMetaFile(lfs_, - poolMetaPath, - metaFileSize, - &chunksize, - &metapagesize, - &chunkfilePath)); + ASSERT_EQ(0, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); + } + + // 正常流程 + { + char buf[metaFileSize] = {0}; + Json::Value root = GenerateMetaJson(true); + memcpy(buf, root.toStyledString().c_str(), + root.toStyledString().size()); + + EXPECT_CALL(*lfs_, Open(poolMetaPath, _)) + .WillOnce(Return(1)); + EXPECT_CALL(*lfs_, Read(1, NotNull(), 0, metaFileSize)) + .WillOnce(DoAll(SetArrayArgument<1>(buf, buf + metaFileSize), + Return(metaFileSize))); + EXPECT_CALL(*lfs_, Close(1)) + .Times(1); + ASSERT_EQ(0, FilePoolHelper::DecodeMetaInfoFromMetaFile( + lfs_, poolMetaPath, metaFileSize, &meta)); } } diff --git a/test/chunkserver/datastore/filepool_unittest.cpp b/test/chunkserver/datastore/filepool_unittest.cpp index fd173d1569..6614da320a 100644 --- a/test/chunkserver/datastore/filepool_unittest.cpp +++ b/test/chunkserver/datastore/filepool_unittest.cpp @@ -52,8 +52,9 @@ using ::testing::StrEq; using curve::chunkserver::FilePool; using curve::chunkserver::FilePoolHelper; using curve::chunkserver::FilePoolOptions; -using curve::chunkserver::FilePoolState_t; -using curve::common::kFilePoolMaigic; +using curve::chunkserver::FilePoolState; +using curve::chunkserver::FilePoolMeta; +using curve::common::kFilePoolMagic; using curve::fs::FileSystemType; using curve::fs::LocalFileSystem; using curve::fs::LocalFsFactory; @@ -66,7 +67,7 @@ const char POOL1_DIR[] = "./cspooltest/pool1/"; const char POOL2_DIR[] = "./cspooltest/pool2/"; const char FILEPOOL_DIR[] = "./cspooltest/filePool/"; -class CSFilePool_test : public testing::Test { +class CSFilePool_test : public testing::TestWithParam { public: void SetUp() { fsptr = LocalFsFactory::CreateFs(FileSystemType::EXT4, ""); @@ -110,10 +111,18 @@ class CSFilePool_test : public testing::Test { uint32_t chunksize = 4096; uint32_t metapagesize = 4096; + uint32_t blockSize = 4096; + + FilePoolMeta meta; + if (GetParam()) { + meta = + FilePoolMeta{chunksize, metapagesize, blockSize, FILEPOOL_DIR}; + } else { + meta = FilePoolMeta{chunksize, metapagesize, FILEPOOL_DIR}; + } int ret = FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, chunksize, metapagesize, FILEPOOL_DIR, - "./cspooltest/filePool.meta"); + fsptr, meta, "./cspooltest/filePool.meta"); if (ret == -1) { LOG(ERROR) << "persist chunkfile pool meta info failed!"; @@ -160,14 +169,16 @@ bool CheckFileOpenOrNot(const std::string& filename) { return out.find("No such file or directory") != out.npos; } -TEST_F(CSFilePool_test, InitializeTest) { +TEST_P(CSFilePool_test, InitializeTest) { std::string filePool = "./cspooltest/filePool.meta"; const std::string filePoolPath = FILEPOOL_DIR; FilePoolOptions cfop; cfop.fileSize = 4096; cfop.metaPageSize = 4096; + cfop.blockSize = 4096; memcpy(cfop.metaPath, filePool.c_str(), filePool.size()); + memcpy(cfop.filePoolDir, filePoolPath.c_str(), filePoolPath.size()); // initialize ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cfop)); @@ -213,12 +224,14 @@ TEST_F(CSFilePool_test, InitializeTest) { fsptr->Delete("./cspooltest/filePool.meta3"); } -TEST_F(CSFilePool_test, GetFileTest) { +TEST_P(CSFilePool_test, GetFileTest) { std::string filePool = "./cspooltest/filePool.meta"; FilePoolOptions cfop; cfop.fileSize = 4096; cfop.metaPageSize = 4096; + cfop.blockSize = 4096; memcpy(cfop.metaPath, filePool.c_str(), filePool.size()); + strncpy(cfop.filePoolDir, FILEPOOL_DIR, strlen(FILEPOOL_DIR) + 1); char metapage[4096]; memset(metapage, '1', 4096); @@ -253,7 +266,7 @@ TEST_F(CSFilePool_test, GetFileTest) { ASSERT_EQ(0, fsptr->Delete(filename)); }; - chunkFilePoolPtr_->Initialize(cfop); + ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cfop)); auto currentStat = chunkFilePoolPtr_->GetState(); ASSERT_EQ(50, currentStat.dirtyChunksLeft); ASSERT_EQ(50, currentStat.cleanChunksLeft); @@ -277,16 +290,18 @@ TEST_F(CSFilePool_test, GetFileTest) { checkBytes("test2", '2'); } -TEST_F(CSFilePool_test, RecycleFileTest) { +TEST_P(CSFilePool_test, RecycleFileTest) { std::string filePool = "./cspooltest/filePool.meta"; const std::string filePoolPath = FILEPOOL_DIR; FilePoolOptions cfop; cfop.fileSize = 4096; cfop.metaPageSize = 4096; + cfop.blockSize = 4096; memcpy(cfop.metaPath, filePool.c_str(), filePool.size()); + strncpy(cfop.filePoolDir, FILEPOOL_DIR, strlen(FILEPOOL_DIR) + 1); - chunkFilePoolPtr_->Initialize(cfop); - FilePoolState_t currentStat = chunkFilePoolPtr_->GetState(); + ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cfop)); + FilePoolState currentStat = chunkFilePoolPtr_->GetState(); ASSERT_EQ(50, currentStat.dirtyChunksLeft); ASSERT_EQ(50, currentStat.cleanChunksLeft); ASSERT_EQ(100, chunkFilePoolPtr_->Size()); @@ -311,17 +326,18 @@ TEST_F(CSFilePool_test, RecycleFileTest) { ASSERT_EQ(0, fsptr->Delete(filePoolPath + "4")); } -TEST_F(CSFilePool_test, UsePoolConcurrentGetAndRecycle) { +TEST_P(CSFilePool_test, UsePoolConcurrentGetAndRecycle) { std::string filePool = "./cspooltest/filePool.meta"; const std::string filePoolPath = FILEPOOL_DIR; FilePoolOptions cfop; memcpy(cfop.filePoolDir, filePoolPath.c_str(), filePoolPath.size()); cfop.fileSize = 4096; cfop.metaPageSize = 4096; + cfop.blockSize = 4096; cfop.getFileFromPool = true; cfop.retryTimes = 1; memcpy(cfop.metaPath, filePool.c_str(), filePool.size()); - + strncpy(cfop.filePoolDir, FILEPOOL_DIR, strlen(FILEPOOL_DIR) + 1); /* step 1. prepare file for filePool and pool2 */ int count = 1; @@ -350,7 +366,7 @@ TEST_F(CSFilePool_test, UsePoolConcurrentGetAndRecycle) { } /* step 2. init filepool */ - chunkFilePoolPtr_->Initialize(cfop); + ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cfop)); /* step 3. start multiple threads, get files from filePool to pool1 */ std::vector threads; @@ -411,7 +427,7 @@ TEST_F(CSFilePool_test, UsePoolConcurrentGetAndRecycle) { } } -TEST_F(CSFilePool_test, WithoutPoolConcurrentGetAndRecycle) { +TEST_P(CSFilePool_test, WithoutPoolConcurrentGetAndRecycle) { std::string filePool = "./cspooltest/filePool.meta"; const std::string filePoolPath = FILEPOOL_DIR; FilePoolOptions cfop; @@ -500,14 +516,16 @@ TEST_F(CSFilePool_test, WithoutPoolConcurrentGetAndRecycle) { } } -TEST_F(CSFilePool_test, CleanChunkTest) { +TEST_P(CSFilePool_test, CleanChunkTest) { std::string filePool = "./cspooltest/filePool.meta"; const std::string filePoolPath = FILEPOOL_DIR; FilePoolOptions cfop; cfop.fileSize = 4096; cfop.metaPageSize = 4096; + cfop.blockSize = 4096; memcpy(cfop.metaPath, filePool.c_str(), filePool.size()); + strncpy(cfop.filePoolDir, FILEPOOL_DIR, strlen(FILEPOOL_DIR) + 1); // CASE 1: initialize ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cfop)); @@ -563,6 +581,10 @@ TEST_F(CSFilePool_test, CleanChunkTest) { } } +INSTANTIATE_TEST_CASE_P(CSFilePoolTest, + CSFilePool_test, + ::testing::Values(false, true)); + TEST(CSFilePool, GetFileDirectlyTest) { std::shared_ptr chunkFilePoolPtr_; std::shared_ptr fsptr; @@ -590,9 +612,7 @@ TEST(CSFilePool, GetFileDirectlyTest) { strcpy(cspopt.filePoolDir, filePoolPath.c_str()); // NOLINT chunkFilePoolPtr_ = std::make_shared(fsptr); - if (chunkFilePoolPtr_ == nullptr) { - LOG(FATAL) << "allocate chunkfile pool failed!"; - } + ASSERT_TRUE(chunkFilePoolPtr_); ASSERT_TRUE(chunkFilePoolPtr_->Initialize(cspopt)); ASSERT_EQ(0, chunkFilePoolPtr_->Size()); diff --git a/test/chunkserver/heartbeat_test_main.cpp b/test/chunkserver/heartbeat_test_main.cpp index d25cc3c518..60ceabcc25 100644 --- a/test/chunkserver/heartbeat_test_main.cpp +++ b/test/chunkserver/heartbeat_test_main.cpp @@ -120,6 +120,7 @@ int main(int argc, char *argv[]) { cg.SetKV("mds.listen.addr", "127.0.0.1:7777,127.0.0.1:9300"); cg.SetKV("mds.heartbeat_interval", "1"); cg.SetKV("copyset.snapshot_interval_s", "30"); + cg.SetKV("global.block_size", "4096"); CHECK(cg.Generate()) << "Generate config file fail"; } diff --git a/test/chunkserver/metrics_test.cpp b/test/chunkserver/metrics_test.cpp index 27ad1f7c66..26d0e007f4 100644 --- a/test/chunkserver/metrics_test.cpp +++ b/test/chunkserver/metrics_test.cpp @@ -50,6 +50,7 @@ butil::AtExitManager atExitManager; const uint64_t kMB = 1024 * 1024; const ChunkSizeType CHUNK_SIZE = 4 * kMB; +const ChunkSizeType BLOCK_SIZE = 4096; const PageSizeType PAGE_SIZE = 4 * 1024; const int chunkNum = 10; const LogicPoolID logicId = 1; @@ -81,14 +82,12 @@ class CSMetricTest : public ::testing::Test { void InitFilePool(std::shared_ptr filePool, const std::string& poolDir, const std::string& poolMetaPath) { - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, - CHUNK_SIZE, - PAGE_SIZE, - poolDir, - poolMetaPath); + FilePoolMeta meta(CHUNK_SIZE, PAGE_SIZE, BLOCK_SIZE, poolDir); + FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, poolMetaPath); FilePoolOptions cfop; cfop.fileSize = CHUNK_SIZE; cfop.metaPageSize = PAGE_SIZE; + cfop.blockSize = BLOCK_SIZE; memcpy(cfop.metaPath, poolMetaPath.c_str(), poolMetaPath.size()); if (lfs_->DirExists(poolDir)) diff --git a/test/chunkserver/op_request_test.cpp b/test/chunkserver/op_request_test.cpp index 6fecb3535c..eff2e5b241 100644 --- a/test/chunkserver/op_request_test.cpp +++ b/test/chunkserver/op_request_test.cpp @@ -73,7 +73,8 @@ TEST(ChunkOpRequestTest, encode) { DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); nodePtr->SetCSDateStore(dataStore); @@ -385,7 +386,8 @@ TEST(ChunkOpRequestTest, OnApplyErrorTest) { DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); nodePtr->SetCSDateStore(dataStore); @@ -749,7 +751,8 @@ TEST(ChunkOpRequestTest, OnApplyFromLogTest) { DataStoreOptions options; options.baseDir = "./test-temp"; options.chunkSize = 16 * 1024 * 1024; - options.pageSize = 4 * 1024; + options.metaPageSize = 4 * 1024; + options.blockSize = 4 * 1024; std::shared_ptr dataStore = std::make_shared(options, fs); nodePtr->SetCSDateStore(dataStore); diff --git a/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_mock_unittest.cpp b/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_mock_unittest.cpp index bfe820d258..b33d196d95 100644 --- a/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_mock_unittest.cpp +++ b/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_mock_unittest.cpp @@ -55,23 +55,25 @@ using curve::chunkserver::FilePool; using curve::fs::MockLocalFileSystem; namespace curve { namespace chunkserver { + +static const char* kFilePool = "./raftsnap/chunkfilepool/"; +static const char* kFilePoolMeta = "./raftsnap/chunkfilepool.meta"; + class RaftSnapshotFilesystemAdaptorMockTest : public testing::Test { public: void SetUp() { fsptr = curve::fs::LocalFsFactory::CreateFs( curve::fs::FileSystemType::EXT4, "/dev/sda"); FilePoolPtr_ = std::make_shared(fsptr); - if (FilePoolPtr_ == nullptr) { - LOG(FATAL) << "allocate chunkfile pool failed!"; - } + ASSERT_TRUE(FilePoolPtr_); + int count = 1; fsptr->Mkdir("./raftsnap"); fsptr->Mkdir("./raftsnap/chunkfilepool"); - std::string dirname = "./raftsnap/chunkfilepool"; while (count < 4) { - std::string filename = "./raftsnap/chunkfilepool/" - + std::to_string(count); - int fd = fsptr->Open(filename.c_str(), O_RDWR | O_CREAT); + std::string filename = kFilePool + std::to_string(count); + int fd = fsptr->Open(filename, O_RDWR | O_CREAT); + ASSERT_GE(fd, 0); char data[8192]; memset(data, 'a', 8192); fsptr->Write(fd, data, 0, 8192); @@ -87,20 +89,20 @@ class RaftSnapshotFilesystemAdaptorMockTest : public testing::Test { cpopt.fileSize = chunksize; cpopt.metaPageSize = metapagesize; cpopt.metaFileSize = 4096; - memcpy(cpopt.filePoolDir, "./raftsnap/chunkfilepool", 17); - memcpy(cpopt.metaPath, "./raftsnap/chunkfilepool.meta", 30); - - int ret = FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, - chunksize, - metapagesize, - dirname, - "./raftsnap/chunkfilepool.meta"); - - if (ret == -1) { - LOG(ERROR) << "persist chunkfile pool meta info failed!"; - return; - } + cpopt.blockSize = 4096; + strcpy(cpopt.filePoolDir, kFilePool); // NOLINT(runtime/printf) + strcpy(cpopt.metaPath, kFilePoolMeta); // NOLINT(runtime/printf) + + FilePoolMeta meta; + meta.chunkSize = chunksize; + meta.metaPageSize = metapagesize; + meta.hasBlockSize = true; + meta.blockSize = 4096; + meta.filePoolPath = kFilePool; + + ASSERT_EQ(0, FilePoolHelper::PersistEnCodeMetaInfo(fsptr, meta, + kFilePoolMeta)) + << "Persist chunkfile pool meta info failed"; lfs = std::make_shared(); diff --git a/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_unittest.cpp b/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_unittest.cpp index 4c9384fe0b..926ccc76c5 100644 --- a/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_unittest.cpp +++ b/test/chunkserver/raftsnapshot/curve_filesystem_adaptor_unittest.cpp @@ -36,23 +36,25 @@ using curve::fs::LocalFileSystem; using curve::chunkserver::FilePool; namespace curve { namespace chunkserver { + +static const char* kFilePool = "./raftsnap/chunkfilepool/"; +static const char* kFilePoolMeta = "./raftsnap/chunkfilepool.meta"; + class CurveFilesystemAdaptorTest : public testing::Test { public: void SetUp() { fsptr = curve::fs::LocalFsFactory::CreateFs( curve::fs::FileSystemType::EXT4, "/dev/sda"); chunkFilePoolPtr_ = std::make_shared(fsptr); - if (chunkFilePoolPtr_ == nullptr) { - LOG(FATAL) << "allocate chunkfile pool failed!"; - } + ASSERT_TRUE(chunkFilePoolPtr_); + int count = 1; fsptr->Mkdir("./raftsnap"); fsptr->Mkdir("./raftsnap/chunkfilepool"); - std::string dirname = "./raftsnap/chunkfilepool"; while (count < 4) { - std::string filename = "./raftsnap/chunkfilepool/" - + std::to_string(count); + std::string filename = kFilePool + std::to_string(count); int fd = fsptr->Open(filename.c_str(), O_RDWR | O_CREAT); + ASSERT_GE(fd, 0); char data[8192]; memset(data, 'a', 8192); fsptr->Write(fd, data, 0, 8192); @@ -62,26 +64,25 @@ class CurveFilesystemAdaptorTest : public testing::Test { uint32_t chunksize = 4096; uint32_t metapagesize = 4096; + uint32_t blockSize = 4096; + + FilePoolMeta meta; + meta.chunkSize = chunksize; + meta.metaPageSize = metapagesize; + meta.hasBlockSize = true; + meta.blockSize = blockSize; + meta.filePoolPath = kFilePool; FilePoolOptions cpopt; cpopt.getFileFromPool = true; cpopt.fileSize = chunksize; cpopt.metaPageSize = metapagesize; - cpopt.metaFileSize = 4096; - memcpy(cpopt.filePoolDir, "./raftsnap/chunkfilepool", 17); - memcpy(cpopt.metaPath, "./raftsnap/chunkfilepool.meta", 30); - - int ret = FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, - chunksize, - metapagesize, - dirname, - "./raftsnap/chunkfilepool.meta"); - - if (ret == -1) { - LOG(ERROR) << "persist chunkfile pool meta info failed!"; - return; - } + cpopt.blockSize = blockSize; + strcpy(cpopt.filePoolDir, kFilePool); // NOLINT(runtime/printf) + strcpy(cpopt.metaPath, kFilePoolMeta); // NOLINT(runtime/printf) + + ASSERT_EQ(0, FilePoolHelper::PersistEnCodeMetaInfo(fsptr, meta, + kFilePoolMeta)); rfa = new CurveFilesystemAdaptor(chunkFilePoolPtr_, fsptr); std::vector filterList; diff --git a/test/chunkserver/raftsnapshot/raftsnapshot_chunkfilepool_integration.cpp b/test/chunkserver/raftsnapshot/raftsnapshot_chunkfilepool_integration.cpp index 6c5b8c0ee9..94bcc4d5a8 100644 --- a/test/chunkserver/raftsnapshot/raftsnapshot_chunkfilepool_integration.cpp +++ b/test/chunkserver/raftsnapshot/raftsnapshot_chunkfilepool_integration.cpp @@ -39,6 +39,8 @@ using curve::fs::LocalFileSystem; using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; +static constexpr uint32_t kOpRequestAlignSize = 4096; + class RaftSnapFilePoolTest : public testing::Test { protected: virtual void SetUp() { diff --git a/test/chunkserver/server.cpp b/test/chunkserver/server.cpp index d0bebeec1f..d90dfb724c 100644 --- a/test/chunkserver/server.cpp +++ b/test/chunkserver/server.cpp @@ -52,6 +52,7 @@ using curve::fs::LocalFileSystem; using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; using curve::chunkserver::FilePoolHelper; +using curve::chunkserver::FilePoolMeta; DEFINE_string(ip, "127.0.0.1", @@ -105,16 +106,19 @@ void CreateChunkFilePool(const std::string& dirname, cpopt.fileSize = chunksize; cpopt.metaPageSize = 4096; cpopt.metaFileSize = 4096; + cpopt.blockSize = 4096; memcpy(cpopt.filePoolDir, datadir.c_str(), datadir.size()); memcpy(cpopt.metaPath, metapath.c_str(), metapath.size()); - int ret = FilePoolHelper::PersistEnCodeMetaInfo( - fsptr, - chunksize, - 4096, - datadir, - metapath); + FilePoolMeta meta; + meta.chunkSize = cpopt.fileSize; + meta.metaPageSize = cpopt.metaFileSize; + meta.hasBlockSize = true; + meta.blockSize = cpopt.blockSize; + meta.filePoolPath = datadir; + + FilePoolHelper::PersistEnCodeMetaInfo(fsptr, meta, metapath); } int main(int argc, char *argv[]) { @@ -154,7 +158,8 @@ int main(int argc, char *argv[]) { std::string raftSnapshotUri = copysetUri; raftSnapshotUri.replace(raftSnapshotUri.find("local"), 5, "curve"); copysetNodeOptions.raftSnapshotUri = raftSnapshotUri; - copysetNodeOptions.pageSize = 4 * 1024; + copysetNodeOptions.metaPageSize = 4 * 1024; + copysetNodeOptions.blockSize = 4 * 1024; copysetNodeOptions.maxChunkSize = kMaxChunkSize; copysetNodeOptions.concurrentapply = new ConcurrentApplyModule(); @@ -180,6 +185,7 @@ int main(int argc, char *argv[]) { cfop.fileSize = kMaxChunkSize; if (cfop.getFileFromPool) { cfop.metaFileSize = 4096; + cfop.blockSize = 4096; if (FLAGS_create_chunkfilepool) { CreateChunkFilePool(chunkDataDir, kMaxChunkSize, fs); } diff --git a/test/client/BUILD b/test/client/BUILD index 7a1b8aa3dc..d70b9727df 100644 --- a/test/client/BUILD +++ b/test/client/BUILD @@ -343,5 +343,6 @@ cc_test( "//test/client/fake:fake_lib", "//test/integration/cluster_common:integration_cluster_common", "//test/client/mock:client_mock_lib", + "@com_google_absl//absl/memory", ] ) diff --git a/test/client/client_mdsclient_metacache_unittest.cpp b/test/client/client_mdsclient_metacache_unittest.cpp index 40e318c3fe..90575b7681 100644 --- a/test/client/client_mdsclient_metacache_unittest.cpp +++ b/test/client/client_mdsclient_metacache_unittest.cpp @@ -53,6 +53,8 @@ #include "test/util/config_generator.h" #include "test/client/mock/mock_namespace_service.h" +#include "absl/memory/memory.h" + uint32_t chunk_size = 4 * 1024 * 1024; uint32_t segment_size = 1 * 1024 * 1024 * 1024; std::string mdsMetaServerAddr = "127.0.0.1:29104"; // NOLINT @@ -852,54 +854,58 @@ TEST_F(MDSClientTest, StatFile) { } TEST_F(MDSClientTest, GetFileInfo) { - std::string filename = "/1_userinfo_"; - curve::mds::FileInfo *info = new curve::mds::FileInfo; - ::curve::mds::GetFileInfoResponse response; - info->set_filename("_filename_"); - info->set_id(1); - info->set_parentid(0); - info->set_filetype(curve::mds::FileType::INODE_PAGEFILE); - info->set_chunksize(4 * 1024 * 1024); - info->set_length(4 * 1024 * 1024 * 1024ul); - info->set_ctime(12345678); - info->set_segmentsize(1 * 1024 * 1024 * 1024ul); + uint32_t blocksize = 512; + for (auto hasBlockSize : {true, false}) { + std::string filename = "/1_userinfo_"; + auto info = absl::make_unique(); + ::curve::mds::GetFileInfoResponse response; + info->set_filename("_filename_"); + info->set_id(1); + info->set_parentid(0); + info->set_filetype(curve::mds::FileType::INODE_PAGEFILE); + info->set_chunksize(4 * 1024 * 1024); + info->set_length(4 * 1024 * 1024 * 1024ul); + info->set_ctime(12345678); + info->set_segmentsize(1 * 1024 * 1024 * 1024ul); - response.set_allocated_fileinfo(info); - response.set_statuscode(::curve::mds::StatusCode::kOK); + if (hasBlockSize) { + info->set_blocksize(blocksize); + } - FakeReturn *fakeret = - new FakeReturn(nullptr, static_cast(&response)); - curvefsservice.SetGetFileInfoFakeReturn(fakeret); + response.set_allocated_fileinfo(info.release()); + response.set_statuscode(::curve::mds::StatusCode::kOK); - curve::client::FInfo_t *finfo = new curve::client::FInfo_t; - mdsclient_.GetFileInfo(filename, userinfo, finfo); + auto fakeret = absl::make_unique( + nullptr, static_cast(&response)); + curvefsservice.SetGetFileInfoFakeReturn(fakeret.get()); - ASSERT_EQ(finfo->filename, "_filename_"); - ASSERT_EQ(finfo->id, 1); - ASSERT_EQ(finfo->parentid, 0); - ASSERT_EQ(static_cast(finfo->filetype), - curve::mds::FileType::INODE_PAGEFILE); - ASSERT_EQ(finfo->chunksize, 4 * 1024 * 1024); - ASSERT_EQ(finfo->length, 4 * 1024 * 1024 * 1024ul); - ASSERT_EQ(finfo->ctime, 12345678); - ASSERT_EQ(finfo->segmentsize, 1 * 1024 * 1024 * 1024ul); + auto finfo = absl::make_unique(); + mdsclient_.GetFileInfo(filename, userinfo, finfo.get()); - // 设置rpc失败,触发重试 - brpc::Controller cntl; - cntl.SetFailed(-1, "failed"); + ASSERT_EQ(finfo->filename, "_filename_"); + ASSERT_EQ(finfo->id, 1); + ASSERT_EQ(finfo->parentid, 0); + ASSERT_EQ(static_cast(finfo->filetype), + curve::mds::FileType::INODE_PAGEFILE); + ASSERT_EQ(finfo->chunksize, 4 * 1024 * 1024); + ASSERT_EQ(finfo->length, 4 * 1024 * 1024 * 1024ul); + ASSERT_EQ(finfo->ctime, 12345678); + ASSERT_EQ(finfo->segmentsize, 1 * 1024 * 1024 * 1024ul); + ASSERT_EQ(finfo->blocksize, hasBlockSize ? blocksize : 4096); - FakeReturn *fakeret2 = - new FakeReturn(&cntl, static_cast(&response)); + // 设置rpc失败,触发重试 + brpc::Controller cntl; + cntl.SetFailed(-1, "failed"); - curvefsservice.SetGetFileInfoFakeReturn(fakeret2); - curvefsservice.CleanRetryTimes(); + auto fakeret2 = absl::make_unique( + &cntl, static_cast(&response)); - ASSERT_EQ(LIBCURVE_ERROR::FAILED, - mdsclient_.GetFileInfo(filename.c_str(), userinfo, finfo)); + curvefsservice.SetGetFileInfoFakeReturn(fakeret2.get()); + curvefsservice.CleanRetryTimes(); - delete fakeret; - delete fakeret2; - delete finfo; + ASSERT_EQ(LIBCURVE_ERROR::FAILED, + mdsclient_.GetFileInfo(filename, userinfo, finfo.get())); + } } TEST_F(MDSClientTest, GetOrAllocateSegment) { diff --git a/test/client/client_metric_test.cpp b/test/client/client_metric_test.cpp index ffb9690065..a0704c5b58 100644 --- a/test/client/client_metric_test.cpp +++ b/test/client/client_metric_test.cpp @@ -29,6 +29,7 @@ #include // NOLINT #include // NOLINT +#include "proto/nameserver2.pb.h" #include "include/client/libcurve.h" #include "src/client/client_metric.h" #include "src/client/file_instance.h" @@ -96,12 +97,31 @@ TEST(MetricTest, ChunkServer_MetricTest) { mds.StartCliService(pd); mds.CreateCopysetNode(true); + auto nameService = mds.GetMDSService(); + OpenFileResponse resp; + resp.set_statuscode(curve::mds::StatusCode::kOK); + auto* session = resp.mutable_protosession(); + session->set_sessionid("xxx"); + session->set_leasetime(10000); + session->set_createtime(10000); + session->set_sessionstatus(curve::mds::SessionStatus::kSessionOK); + auto* fileinfo = resp.mutable_fileinfo(); + fileinfo->set_id(1); + fileinfo->set_filename(filename); + fileinfo->set_parentid(0); + fileinfo->set_length(10ULL * 1024 * 1024 * 1024); + fileinfo->set_blocksize(4096); + + FakeReturn fakeOpen(nullptr, static_cast(&resp)); + nameService->SetOpenFile(&fakeOpen); + UserInfo_t userinfo; userinfo.owner = "test"; auto opt = cc.GetFileServiceOption(); FileInstance fi; ASSERT_TRUE(fi.Initialize(filename, mdsclient, userinfo, OpenFlags{}, opt)); + ASSERT_EQ(LIBCURVE_ERROR::OK, fi.Open()); FileMetric* fm = fi.GetIOManager4File()->GetMetric(); @@ -170,6 +190,8 @@ TEST(MetricTest, ChunkServer_MetricTest) { mds.UnInitialize(); } +namespace { + bool flag = false; std::mutex mtx; std::condition_variable cv; @@ -179,6 +201,8 @@ void cb(CurveAioContext* ctx) { cv.notify_one(); } +} // namespace + TEST(MetricTest, SuspendRPC_MetricTest) { MetaServerOption metaopt; metaopt.rpcRetryOpt.addrs.push_back(mdsMetaServerAddr); diff --git a/test/client/client_session_unittest.cpp b/test/client/client_session_unittest.cpp index 94e518bd51..d1a10c46ae 100644 --- a/test/client/client_session_unittest.cpp +++ b/test/client/client_session_unittest.cpp @@ -148,7 +148,7 @@ TEST(ClientSession, LeaseTaskTest) { curvefsservice->SetRefreshSession(refreshfakeret, refresht); // 3. open the file - int openret = fileinstance.Open(filename, userinfo); + int openret = fileinstance.Open(); ASSERT_EQ(openret, LIBCURVE_ERROR::OK); // 4. wait for refresh diff --git a/test/client/client_userinfo_unittest.cpp b/test/client/client_userinfo_unittest.cpp index 32b3250589..b9390bde41 100644 --- a/test/client/client_userinfo_unittest.cpp +++ b/test/client/client_userinfo_unittest.cpp @@ -46,30 +46,26 @@ namespace client { class CurveClientUserAuthFail : public ::testing::Test { public: - void SetUp() { + void SetUp() override { metaopt.rpcRetryOpt.addrs.push_back("127.0.0.1:9104"); metaopt.rpcRetryOpt.addrs.push_back("127.0.0.1:9104"); metaopt.rpcRetryOpt.rpcTimeoutMs = 500; metaopt.rpcRetryOpt.rpcRetryIntervalUS = 200; - if (server.AddService(&curvefsservice, - brpc::SERVER_DOESNT_OWN_SERVICE) != 0) { - LOG(FATAL) << "Fail to add service"; - } + ASSERT_EQ(0, server.AddService(&curvefsservice, + brpc::SERVER_DOESNT_OWN_SERVICE)) + << "Fail to add service"; - if (server.AddService(&topologyservice, - brpc::SERVER_DOESNT_OWN_SERVICE) != 0) { - LOG(FATAL) << "Fail to add service"; - } + ASSERT_EQ(0, server.AddService(&topologyservice, + brpc::SERVER_DOESNT_OWN_SERVICE)) + << "Fail to add service"; - brpc::ServerOptions options; - options.idle_timeout_sec = -1; - LOG(INFO) << "meta server addr = " << mdsMetaServerAddr.c_str(); - ASSERT_EQ(server.Start(mdsMetaServerAddr.c_str(), &options), 0); + LOG(INFO) << "meta server addr = " << mdsMetaServerAddr; + ASSERT_EQ(server.Start(mdsMetaServerAddr.c_str(), nullptr), 0); } - void TearDown() { + void TearDown() override { ASSERT_EQ(0, server.Stop(0)); ASSERT_EQ(0, server.Join()); } @@ -160,7 +156,7 @@ TEST_F(CurveClientUserAuthFail, CurveClientUserAuthFailTest) { curvefsservice.SetRefreshSession(refreshfakeret, refresht); // 3. open the file auth failed - int openret = fileinstance.Open(filename, userinfo); + int openret = fileinstance.Open(); ASSERT_EQ(openret, -LIBCURVE_ERROR::AUTHFAIL); // 4. open file success @@ -169,7 +165,7 @@ TEST_F(CurveClientUserAuthFail, CurveClientUserAuthFailTest) { = new FakeReturn(nullptr, static_cast(&openresponse)); curvefsservice.SetOpenFile(openfakeret2); - openret = fileinstance.Open(filename, userinfo); + openret = fileinstance.Open(); ASSERT_EQ(openret, LIBCURVE_ERROR::OK); /* // 5. wait for refresh diff --git a/test/client/copyset_client_test.cpp b/test/client/copyset_client_test.cpp index 89f828309d..bcee09c196 100644 --- a/test/client/copyset_client_test.cpp +++ b/test/client/copyset_client_test.cpp @@ -3537,6 +3537,8 @@ TEST_F(CopysetClientTest, get_chunk_info_test) { } } +namespace { + bool gWriteSuccessFlag = false; void WriteCallBack(CurveAioContext* aioctx) { @@ -3544,7 +3546,32 @@ void WriteCallBack(CurveAioContext* aioctx) { delete aioctx; } +void PrepareOpenFile(FakeCurveFSService *service, + OpenFileResponse *openresp, + FakeReturn *fakeReturn) { + openresp->set_statuscode(curve::mds::StatusCode::kOK); + auto *session = openresp->mutable_protosession(); + session->set_sessionid("xxx"); + session->set_leasetime(10000); + session->set_createtime(10000); + session->set_sessionstatus(curve::mds::SessionStatus::kSessionOK); + auto *fileinfo = openresp->mutable_fileinfo(); + fileinfo->set_id(1); + fileinfo->set_filename("filename"); + fileinfo->set_parentid(0); + fileinfo->set_length(10ULL * 1024 * 1024 * 1024); + fileinfo->set_blocksize(4096); + + *fakeReturn = FakeReturn(nullptr, static_cast(openresp)); + + service->SetOpenFile(fakeReturn); +} + +} // namespace + TEST(ChunkServerBackwardTest, ChunkServerBackwardTest) { + const std::string endpoint = "127.0.0.1:9102"; + ClientConfig cc; const std::string& configPath = "./conf/client.conf"; cc.Init(configPath.c_str()); @@ -3553,8 +3580,13 @@ TEST(ChunkServerBackwardTest, ChunkServerBackwardTest) { userinfo.owner = "userinfo"; std::shared_ptr mdsclient = std::make_shared(); - ASSERT_EQ(LIBCURVE_ERROR::OK, - mdsclient->Initialize(cc.GetFileServiceOption().metaServerOpt)); + + // set mds addr + auto mdsopts = cc.GetFileServiceOption().metaServerOpt; + mdsopts.rpcRetryOpt.addrs.clear(); + mdsopts.rpcRetryOpt.addrs.push_back(endpoint); + + ASSERT_EQ(LIBCURVE_ERROR::OK, mdsclient->Initialize(mdsopts)); ASSERT_TRUE(fileinstance.Initialize( "/test", mdsclient, userinfo, OpenFlags{}, cc.GetFileServiceOption())); @@ -3563,15 +3595,23 @@ TEST(ChunkServerBackwardTest, ChunkServerBackwardTest) { // 设置cli服务 CliServiceFake fakeCliservice; + FakeCurveFSService curvefsService; + OpenFileResponse openresp; + FakeReturn fakeReturn; + + PrepareOpenFile(&curvefsService, &openresp, &fakeReturn); + brpc::Server server; ASSERT_EQ(0, server.AddService(&fakechunkservice, brpc::SERVER_DOESNT_OWN_SERVICE)) << "Fail to add fakechunkservice"; ASSERT_EQ(0, server.AddService(&fakeCliservice, brpc::SERVER_DOESNT_OWN_SERVICE)) << "Fail to add fakecliservice"; - brpc::ServerOptions options; - options.idle_timeout_sec = -1; - ASSERT_EQ(0, server.Start("127.0.0.1:9102", &options)) - << "Fail to start server add 127.0.0.1:9102"; + ASSERT_EQ( + 0, server.AddService(&curvefsService, brpc::SERVER_DOESNT_OWN_SERVICE)) + << "Fail to add curvefsService"; + + ASSERT_EQ(0, server.Start(endpoint.c_str(), nullptr)) + << "Fail to start server at " << endpoint; // fill metacache curve::client::MetaCache* mc = @@ -3600,6 +3640,8 @@ TEST(ChunkServerBackwardTest, ChunkServerBackwardTest) { const int kNewFileSn = 100; const int kOldFileSn = 30; + ASSERT_EQ(LIBCURVE_ERROR::OK, fileinstance.Open()); + // 设置文件版本号 fileinstance.GetIOManager4File()->SetLatestFileSn(kNewFileSn); @@ -3638,6 +3680,9 @@ TEST(ChunkServerBackwardTest, ChunkServerBackwardTest) { // 上次写请求成功 ASSERT_EQ(true, gWriteSuccessFlag); + + server.Stop(0); + server.Join(); } TEST_F(CopysetClientTest, retry_rpc_sleep_test) { diff --git a/test/client/fake/fakeMDS.cpp b/test/client/fake/fakeMDS.cpp index 8ec2ada4d9..eac5bcdb59 100644 --- a/test/client/fake/fakeMDS.cpp +++ b/test/client/fake/fakeMDS.cpp @@ -425,7 +425,7 @@ void FakeMDS::CreateFakeChunkservers(bool enablecli) { } if (chunkservers_[i]->Start(server_addrs_[i], &options) != 0) { - LOG(FATAL) << "Fail to start Server"; + LOG(FATAL) << "Fail to start Server, addr: " << server_addrs_[i]; } LOG(INFO) << "Created chunkserver: " << server_addrs_[i]; diff --git a/test/client/fake/mockMDS.h b/test/client/fake/mockMDS.h index 760e7e4e2d..8e6c8538d2 100644 --- a/test/client/fake/mockMDS.h +++ b/test/client/fake/mockMDS.h @@ -37,13 +37,11 @@ using ::curve::mds::topology::GetChunkServerListInCopySetsRequest; using ::curve::mds::topology::ListChunkServerRequest; using ::curve::mds::topology::ListChunkServerResponse; -class FakeReturn { - public: - FakeReturn(::google::protobuf::RpcController* controller, - void* response) { - response_ = response; - controller_ = controller; - } +struct FakeReturn { + FakeReturn() : FakeReturn(nullptr, nullptr) {} + + FakeReturn(::google::protobuf::RpcController* controller, void* response) + : response_(response), controller_(controller) {} void* response_; ::google::protobuf::RpcController* controller_; @@ -177,6 +175,13 @@ class FakeCurveFSService : public curve::mds::CurveFSService { response->CopyFrom(*resp); } + void RefreshSession(::google::protobuf::RpcController* controller, + const ::curve::mds::ReFreshSessionRequest* request, + ::curve::mds::ReFreshSessionResponse* response, + ::google::protobuf::Closure* done) { + done->Run(); + } + void ExtendFile(::google::protobuf::RpcController* controller, const ::curve::mds::ExtendFileRequest* request, ::curve::mds::ExtendFileResponse* response, diff --git a/test/client/file_instance_test.cpp b/test/client/file_instance_test.cpp index 490b2522f3..e6be791294 100644 --- a/test/client/file_instance_test.cpp +++ b/test/client/file_instance_test.cpp @@ -78,5 +78,18 @@ TEST(FileInstanceTest, OpenReadonlyAndDiscardTest) { ASSERT_EQ(-1, instance.AioDiscard(&aioctx)); } +TEST(FileInstanceTest, IoAlignmentTest) { + ASSERT_TRUE(CheckIoAligned(4096, 4096, 4096)); + + ASSERT_FALSE(CheckIoAligned(512, 4096, 4096)); + ASSERT_FALSE(CheckIoAligned(4096, 512, 4096)); + + ASSERT_TRUE(CheckIoAligned(4096, 4096, 512)); + ASSERT_TRUE(CheckIoAligned(512, 4096, 512)); + ASSERT_TRUE(CheckIoAligned(512, 512, 512)); + + ASSERT_FALSE(CheckIoAligned(511, 511, 512)); +} + } // namespace client } // namespace curve diff --git a/test/client/iotracker_splitor_unittest.cpp b/test/client/iotracker_splitor_unittest.cpp index 34e4a44a88..6158b1edc5 100644 --- a/test/client/iotracker_splitor_unittest.cpp +++ b/test/client/iotracker_splitor_unittest.cpp @@ -173,8 +173,7 @@ class IOTrackerSplitorTest : public ::testing::Test { openresponse->set_allocated_fileinfo(fin); FakeReturn* openfakeret = new FakeReturn(nullptr, static_cast(openresponse)); // NOLINT curvefsservice.SetOpenFile(openfakeret); - // open will set the finfo for file instance - fileinstance_->Open("1_userinfo_.txt", userinfo); + fileinstance_->Open(); /** * 2. set closefile response @@ -321,6 +320,26 @@ class IOTrackerSplitorTest : public ::testing::Test { curvefsservice.SetCloseFile(closeFakeRet); } + void PrepareOpenFile() { + openResp_.set_statuscode(curve::mds::StatusCode::kOK); + auto* session = openResp_.mutable_protosession(); + session->set_sessionid("xxx"); + session->set_leasetime(10000); + session->set_createtime(10000); + session->set_sessionstatus(curve::mds::SessionStatus::kSessionOK); + auto* fileinfo = openResp_.mutable_fileinfo(); + fileinfo->set_id(1); + fileinfo->set_filename("filename"); + fileinfo->set_parentid(0); + fileinfo->set_length(10ULL * 1024 * 1024 * 1024); + fileinfo->set_blocksize(4096); + + fakeOpen_.reset( + new FakeReturn(nullptr, static_cast(&openResp_))); + + curvefsservice.SetOpenFile(fakeOpen_.get()); + } + FileClient *fileClient_; UserInfo_t userinfo; std::shared_ptr mdsclient_; @@ -332,6 +351,9 @@ class IOTrackerSplitorTest : public ::testing::Test { FakeReturn *getsegmentfakeret; FakeReturn *notallocatefakeret; FakeReturn *getsegmentfakeretclone; + + OpenFileResponse openResp_; + std::unique_ptr fakeOpen_; }; TEST_F(IOTrackerSplitorTest, AsyncStartRead) { @@ -735,7 +757,7 @@ TEST_F(IOTrackerSplitorTest, ExceptionTest_TEST) { ASSERT_TRUE(fileserv->Initialize("/test", mdsclient_, rootuserinfo, OpenFlags{}, fopt)); - ASSERT_EQ(LIBCURVE_ERROR::OK, fileserv->Open("1_userinfo_.txt", userinfo)); + ASSERT_EQ(LIBCURVE_ERROR::OK, fileserv->Open()); curve::client::IOManager4File* iomana = fileserv->GetIOManager4File(); MetaCache* mc = fileserv->GetIOManager4File()->GetMetaCache(); @@ -1308,8 +1330,11 @@ TEST_F(IOTrackerSplitorTest, AsyncStartReadNotAllocateSegment2) { // read the chunks some haven't been write from clone volume with clonesource TEST_F(IOTrackerSplitorTest, StartReadNotAllocateSegmentFromOrigin) { curvefsservice.SetGetOrAllocateSegmentFakeReturn(notallocatefakeret); - curvefsservice.SetGetOrAllocateSegmentFakeReturnForClone - (getsegmentfakeretclone); + curvefsservice.SetGetOrAllocateSegmentFakeReturnForClone( + getsegmentfakeretclone); + + PrepareOpenFile(); + MockRequestScheduler* mockschuler = new MockRequestScheduler; mockschuler->DelegateToFake(); @@ -1319,6 +1344,7 @@ TEST_F(IOTrackerSplitorTest, StartReadNotAllocateSegmentFromOrigin) { mdsclient_->Initialize(fopt.metaServerOpt); fileinstance2->Initialize("/clonesource", mdsclient_, userinfo, OpenFlags{}, fopt); + ASSERT_EQ(LIBCURVE_ERROR::OK, fileinstance2->Open()); MockRequestScheduler* mockschuler2 = new MockRequestScheduler; mockschuler2->DelegateToFake(); @@ -1385,6 +1411,8 @@ TEST_F(IOTrackerSplitorTest, AsyncStartReadNotAllocateSegmentFromOrigin) { curvefsservice.SetGetOrAllocateSegmentFakeReturn(notallocatefakeret); curvefsservice.SetGetOrAllocateSegmentFakeReturnForClone (getsegmentfakeretclone); + PrepareOpenFile(); + MockRequestScheduler* mockschuler = new MockRequestScheduler; mockschuler->DelegateToFake(); @@ -1394,6 +1422,7 @@ TEST_F(IOTrackerSplitorTest, AsyncStartReadNotAllocateSegmentFromOrigin) { mdsclient_->Initialize(fopt.metaServerOpt); fileinstance2->Initialize("/clonesource", mdsclient_, userinfo, OpenFlags{}, fopt); + ASSERT_EQ(LIBCURVE_ERROR::OK, fileinstance2->Open()); MockRequestScheduler* mockschuler2 = new MockRequestScheduler; mockschuler2->DelegateToFake(); diff --git a/test/client/iotracker_test.cpp b/test/client/iotracker_test.cpp index 61d8318fbe..f95783e134 100644 --- a/test/client/iotracker_test.cpp +++ b/test/client/iotracker_test.cpp @@ -42,7 +42,7 @@ using ::testing::Return; class IOTrackerTest : public ::testing::Test { public: void SetUp() override { - opt_.taskDelayMs = 10; + opt_.taskDelayMs = 100; IOTracker::InitDiscardOption(opt_); metric.reset(new DiscardMetric("IOTrackerTest")); diff --git a/test/client/libcurve_interface_unittest.cpp b/test/client/libcurve_interface_unittest.cpp index 19edf9dfa4..e27d2efd9a 100644 --- a/test/client/libcurve_interface_unittest.cpp +++ b/test/client/libcurve_interface_unittest.cpp @@ -600,21 +600,9 @@ TEST(TestLibcurveInterface, InterfaceExceptionTest) { ASSERT_EQ(0, Init(configpath.c_str())); - char *buffer = new char[8 * 1024]; memset(buffer, 'a', 8 * 1024); - // not aligned test - CurveAioContext ctx; - ctx.buf = buffer; - ctx.offset = 1; - ctx.length = 7 * 1024; - ctx.cb = writecallbacktest; - ASSERT_EQ(-LIBCURVE_ERROR::NOT_ALIGNED, AioWrite(1234, &ctx)); - ASSERT_EQ(-LIBCURVE_ERROR::NOT_ALIGNED, AioRead(1234, &ctx)); - ASSERT_EQ(-LIBCURVE_ERROR::NOT_ALIGNED, Write(1234, buffer, 1, 4096)); - ASSERT_EQ(-LIBCURVE_ERROR::NOT_ALIGNED, Read(1234, buffer, 4096, 123)); - CurveAioContext writeaioctx; writeaioctx.buf = buffer; writeaioctx.offset = 0; @@ -700,7 +688,7 @@ TEST(TestLibcurveInterface, UnstableChunkserverTest) { mds.CreateCopysetNode(true); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - int fd = fileinstance_.Open(filename.c_str(), userinfo); + int fd = fileinstance_.Open(); MetaCache *mc = fileinstance_.GetIOManager4File()->GetMetaCache(); @@ -889,7 +877,7 @@ TEST(TestLibcurveInterface, ResumeTimeoutBackoff) { mds.CreateCopysetNode(true); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - int fd = fileinstance_.Open(filename.c_str(), userinfo); + int fd = fileinstance_.Open(); MetaCache *mc = fileinstance_.GetIOManager4File()->GetMetaCache(); diff --git a/test/integration/chunkserver/chunkserver_basic_test.cpp b/test/integration/chunkserver/chunkserver_basic_test.cpp index cbf219b027..1caaf006c0 100644 --- a/test/integration/chunkserver/chunkserver_basic_test.cpp +++ b/test/integration/chunkserver/chunkserver_basic_test.cpp @@ -42,7 +42,7 @@ using curve::fs::LocalFsFactory; const uint64_t kMB = 1024 * 1024; const ChunkSizeType CHUNK_SIZE = 16 * kMB; - +static constexpr uint32_t kOpRequestAlignSize = 4096; #define BASIC_TEST_CHUNK_SERVER_PORT "9078" #define KB 1024 @@ -96,6 +96,8 @@ class ChunkServerIoTest : public testing::Test { externalIp_ = butil::my_ip_cstr(); cg1_.SetKV("global.external_ip", externalIp_); cg1_.SetKV("global.enable_external_server", "true"); + cg1_.SetKV("global.meta_page_size", "4096"); + cg1_.SetKV("global.block_size", "4096"); ASSERT_TRUE(cg1_.Generate()); paramsIndexs_[PeerCluster::PeerToId(peer1_)] = 0; @@ -107,8 +109,9 @@ class ChunkServerIoTest : public testing::Test { "/chunkfilepool/"; metaDir_ = "./" + std::to_string(PeerCluster::PeerToId(peer1_)) + "/chunkfilepool.meta"; - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, kChunkSize, kPageSize, - poolDir_, metaDir_); + + FilePoolMeta meta(kChunkSize, kPageSize, poolDir_); + FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, metaDir_); allocateChunk(lfs_, kChunkNum, poolDir_, kChunkSize); } diff --git a/test/integration/chunkserver/chunkserver_clone_recover.cpp b/test/integration/chunkserver/chunkserver_clone_recover.cpp index e3a4808626..e23e0b0968 100644 --- a/test/integration/chunkserver/chunkserver_clone_recover.cpp +++ b/test/integration/chunkserver/chunkserver_clone_recover.cpp @@ -124,6 +124,8 @@ const std::vector csCommonConf{ string("mds.listen.addr=" + ALLMDS_IP_PORT), string("curve.config_path=" + clientConfPath), string("s3.config_path=" + kS3ConfigPath), + string("global.block_size=4096"), + string("global.meta_page_size=4096"), }; const std::vector chunkserverConf1{ diff --git a/test/integration/chunkserver/chunkserver_concurrent_test.cpp b/test/integration/chunkserver/chunkserver_concurrent_test.cpp index 501ded79b4..0f6a749c32 100644 --- a/test/integration/chunkserver/chunkserver_concurrent_test.cpp +++ b/test/integration/chunkserver/chunkserver_concurrent_test.cpp @@ -43,6 +43,8 @@ using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; using curve::common::Thread; +static constexpr uint32_t kOpRequestAlignSize = 4096; + static char *chunkConcurrencyParams1[1][16] = { { "chunkserver", @@ -110,6 +112,8 @@ class ChunkServerConcurrentNotFromFilePoolTest : public testing::Test { ASSERT_TRUE(cg1.Init("9076")); cg1.SetKV("copyset.election_timeout_ms", "3000"); cg1.SetKV("copyset.snapshot_interval_s", "60"); + cg1.SetKV("global.block_size", "4096"); + cg1.SetKV("global.meta_page_size", "4096"); ASSERT_TRUE(cg1.Generate()); logicPoolId = 1; @@ -198,11 +202,8 @@ class ChunkServerConcurrentFromFilePoolTest : public testing::Test { + std::to_string(PeerCluster::PeerToId(peer1)) + "/chunkfilepool.meta"; - FilePoolHelper::PersistEnCodeMetaInfo(lfs, - kChunkSize, - kPageSize, - poolDir, - metaDir); + FilePoolMeta meta(kChunkSize, kPageSize, poolDir); + FilePoolHelper::PersistEnCodeMetaInfo(lfs, meta, metaDir); // There maybe one chunk in cleaning, so you should allocate // (kChunkNum + 1) chunks in start if you want to use kChunkNum chunks. diff --git a/test/integration/chunkserver/datastore/datastore_basic_test.cpp b/test/integration/chunkserver/datastore/datastore_basic_test.cpp index 0f91ad77c6..14fdc3901c 100644 --- a/test/integration/chunkserver/datastore/datastore_basic_test.cpp +++ b/test/integration/chunkserver/datastore/datastore_basic_test.cpp @@ -87,7 +87,8 @@ TEST_F(BasicTestSuit, BasicTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(0, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(false, info.isClone); ASSERT_EQ(nullptr, info.bitmap); diff --git a/test/integration/chunkserver/datastore/datastore_clone_case_test.cpp b/test/integration/chunkserver/datastore/datastore_clone_case_test.cpp index 02600ae0e4..3b0d635652 100644 --- a/test/integration/chunkserver/datastore/datastore_clone_case_test.cpp +++ b/test/integration/chunkserver/datastore/datastore_clone_case_test.cpp @@ -64,7 +64,8 @@ TEST_F(CloneTestSuit, CloneTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); @@ -84,7 +85,8 @@ TEST_F(CloneTestSuit, CloneTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); @@ -104,7 +106,8 @@ TEST_F(CloneTestSuit, CloneTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(2, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); @@ -267,7 +270,8 @@ TEST_F(CloneTestSuit, RecoverTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); @@ -287,7 +291,8 @@ TEST_F(CloneTestSuit, RecoverTest) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(BLOCK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); diff --git a/test/integration/chunkserver/datastore/datastore_exception_test.cpp b/test/integration/chunkserver/datastore/datastore_exception_test.cpp index 190a0b645a..ae5a0e0ce0 100644 --- a/test/integration/chunkserver/datastore/datastore_exception_test.cpp +++ b/test/integration/chunkserver/datastore/datastore_exception_test.cpp @@ -74,7 +74,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest1) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -130,7 +130,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest2) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -186,7 +186,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest3) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -251,7 +251,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest4) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -300,7 +300,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest5) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -383,7 +383,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest6) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -440,7 +440,8 @@ TEST_F(ExceptionTestSuit, ExceptionTest7) { chunkOption.sn = 1; chunkOption.baseDir = baseDir; chunkOption.chunkSize = CHUNK_SIZE; - chunkOption.pageSize = PAGE_SIZE; + chunkOption.blockSize = BLOCK_SIZE; + chunkOption.metaPageSize = PAGE_SIZE; CSSnapshot snapshot(lfs_, filePool_, chunkOption); errorCode = snapshot.Open(true); ASSERT_EQ(errorCode, CSErrorCode::Success); @@ -449,7 +450,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest7) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -553,7 +554,8 @@ TEST_F(ExceptionTestSuit, ExceptionTest8) { chunkOption.sn = 2; chunkOption.baseDir = baseDir; chunkOption.chunkSize = CHUNK_SIZE; - chunkOption.pageSize = PAGE_SIZE; + chunkOption.metaPageSize = PAGE_SIZE; + chunkOption.blockSize = BLOCK_SIZE; CSSnapshot snapshot(lfs_, filePool_, chunkOption); errorCode = snapshot.Open(true); ASSERT_EQ(errorCode, CSErrorCode::Success); @@ -562,7 +564,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest8) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -656,7 +658,8 @@ TEST_F(ExceptionTestSuit, ExceptionTest9) { chunkOption.sn = 1; chunkOption.baseDir = baseDir; chunkOption.chunkSize = CHUNK_SIZE; - chunkOption.pageSize = PAGE_SIZE; + chunkOption.metaPageSize = PAGE_SIZE; + chunkOption.blockSize = BLOCK_SIZE; CSSnapshot snapshot(lfs_, filePool_, chunkOption); errorCode = snapshot.Open(true); ASSERT_EQ(errorCode, CSErrorCode::Success); @@ -684,7 +687,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest9) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -805,7 +808,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest10) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -927,7 +930,7 @@ TEST_F(ExceptionTestSuit, ExceptionTest11) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, @@ -1027,7 +1030,8 @@ TEST_F(ExceptionTestSuit, ExceptionTest12) { ASSERT_EQ(0, info.snapSn); ASSERT_EQ(correctedSn, info.correctedSn); ASSERT_EQ(id, info.chunkId); - ASSERT_EQ(PAGE_SIZE, info.pageSize); + ASSERT_EQ(PAGE_SIZE, info.metaPageSize); + ASSERT_EQ(CHUNK_SIZE, info.blockSize); ASSERT_EQ(CHUNK_SIZE, info.chunkSize); ASSERT_EQ(true, info.isClone); ASSERT_NE(nullptr, info.bitmap); @@ -1051,7 +1055,8 @@ TEST_F(ExceptionTestSuit, ExceptionTest12) { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.blockSize = BLOCK_SIZE; + options.metaPageSize = PAGE_SIZE; // 构造新的dataStore_,并重新初始化,重启失败 dataStore_ = std::make_shared(lfs_, filePool_, diff --git a/test/integration/chunkserver/datastore/datastore_integration_base.h b/test/integration/chunkserver/datastore/datastore_integration_base.h index 1985ef9d57..0731eb39cd 100644 --- a/test/integration/chunkserver/datastore/datastore_integration_base.h +++ b/test/integration/chunkserver/datastore/datastore_integration_base.h @@ -52,6 +52,7 @@ namespace chunkserver { const uint64_t kMB = 1024 * 1024; const ChunkSizeType CHUNK_SIZE = 16 * kMB; +const ChunkSizeType BLOCK_SIZE = 4096; const PageSizeType PAGE_SIZE = 4 * 1024; extern const string baseDir; // NOLINT @@ -76,7 +77,8 @@ class DatastoreIntegrationBase : public testing::Test { DataStoreOptions options; options.baseDir = baseDir; options.chunkSize = CHUNK_SIZE; - options.pageSize = PAGE_SIZE; + options.metaPageSize = PAGE_SIZE; + options.blockSize = BLOCK_SIZE; dataStore_ = std::make_shared(lfs_, filePool_, options); @@ -84,11 +86,12 @@ class DatastoreIntegrationBase : public testing::Test { LOG(FATAL) << "allocate chunkfile pool failed!"; } - FilePoolHelper::PersistEnCodeMetaInfo(lfs_, - CHUNK_SIZE, - PAGE_SIZE, - poolDir, - poolMetaPath); + FilePoolMeta meta; + meta.chunkSize = CHUNK_SIZE; + meta.metaPageSize = PAGE_SIZE; + meta.filePoolPath = poolDir; + + FilePoolHelper::PersistEnCodeMetaInfo(lfs_, meta, poolMetaPath); InitChunkPool(10); ASSERT_TRUE(dataStore_->Initialize()); diff --git a/test/integration/common/chunkservice_op.cpp b/test/integration/common/chunkservice_op.cpp index a52d2d301e..d359d5e294 100644 --- a/test/integration/common/chunkservice_op.cpp +++ b/test/integration/common/chunkservice_op.cpp @@ -28,6 +28,7 @@ namespace curve { namespace chunkserver { +static constexpr uint32_t kOpRequestAlignSize = 4096; const PageSizeType kPageSize = kOpRequestAlignSize; int ChunkServiceOp::WriteChunk(struct ChunkServiceOpConf *opConf, diff --git a/test/integration/raft/raft_config_change_test.cpp b/test/integration/raft/raft_config_change_test.cpp index e207c6ad8b..b64e882e98 100644 --- a/test/integration/raft/raft_config_change_test.cpp +++ b/test/integration/raft/raft_config_change_test.cpp @@ -41,6 +41,7 @@ using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; const char kRaftConfigChangeTestLogDir[] = "./runlog/RaftConfigChange"; +static constexpr uint32_t kOpRequestAlignSize = 4096; static char* raftConfigParam[5][16] = { { diff --git a/test/integration/raft/raft_log_replication_test.cpp b/test/integration/raft/raft_log_replication_test.cpp index dc974e3cd2..3a82459cd7 100644 --- a/test/integration/raft/raft_log_replication_test.cpp +++ b/test/integration/raft/raft_log_replication_test.cpp @@ -42,6 +42,7 @@ using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; const char kRaftLogRepTestLogDir[] = "./runlog/RaftLogRep"; +static constexpr uint32_t kOpRequestAlignSize = 4096; static char* raftLogParam[5][16] = { { diff --git a/test/integration/raft/raft_snapshot_test.cpp b/test/integration/raft/raft_snapshot_test.cpp index 23dbf6d44c..314798f90e 100644 --- a/test/integration/raft/raft_snapshot_test.cpp +++ b/test/integration/raft/raft_snapshot_test.cpp @@ -41,6 +41,7 @@ using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; const char kRaftSnapshotTestLogDir[] = "./runlog/RaftSnapshot"; +static constexpr uint32_t kOpRequestAlignSize = 4096; static char *raftVoteParam[4][16] = { { diff --git a/test/integration/raft/raft_vote_test.cpp b/test/integration/raft/raft_vote_test.cpp index eff9f63a7a..5bf03e9bc1 100644 --- a/test/integration/raft/raft_vote_test.cpp +++ b/test/integration/raft/raft_vote_test.cpp @@ -41,6 +41,7 @@ using curve::fs::LocalFsFactory; using curve::fs::FileSystemType; const char kRaftVoteTestLogDir[] = "./runlog/RaftVote"; +static constexpr uint32_t kOpRequestAlignSize = 4096; static char* raftVoteParam[3][16] = { { diff --git a/test/integration/snapshotcloneserver/snapshotcloneserver_common_test.cpp b/test/integration/snapshotcloneserver/snapshotcloneserver_common_test.cpp index 04605f41b4..65b05af5b1 100644 --- a/test/integration/snapshotcloneserver/snapshotcloneserver_common_test.cpp +++ b/test/integration/snapshotcloneserver/snapshotcloneserver_common_test.cpp @@ -109,7 +109,9 @@ const std::vector chunkserverConfigOptions{ std::string("curve.config_path=") + kCsClientConfigPath, std::string("s3.config_path=") + kS3ConfigPath, "walfilepool.use_chunk_file_pool=false", - "walfilepool.enable_get_segment_from_pool=false" + "walfilepool.enable_get_segment_from_pool=false", + "global.block_size=4096", + "global.meta_page_size=4096", }; const std::vector csClientConfigOptions{ diff --git a/test/integration/snapshotcloneserver/snapshotcloneserver_concurrent_test.cpp b/test/integration/snapshotcloneserver/snapshotcloneserver_concurrent_test.cpp index d112e3d774..cea2ac6ad9 100644 --- a/test/integration/snapshotcloneserver/snapshotcloneserver_concurrent_test.cpp +++ b/test/integration/snapshotcloneserver/snapshotcloneserver_concurrent_test.cpp @@ -108,7 +108,9 @@ const std::vector chunkserverConfigOptions{ std::string("curve.config_path=") + kCsClientConfigPath, std::string("s3.config_path=") + kS3ConfigPath, "walfilepool.use_chunk_file_pool=false", - "walfilepool.enable_get_segment_from_pool=false" + "walfilepool.enable_get_segment_from_pool=false", + "global.block_size=4096", + "global.meta_page_size=4096", }; const std::vector csClientConfigOptions{ diff --git a/test/integration/snapshotcloneserver/snapshotcloneserver_recover_test.cpp b/test/integration/snapshotcloneserver/snapshotcloneserver_recover_test.cpp index 4001b23995..08980afdfc 100644 --- a/test/integration/snapshotcloneserver/snapshotcloneserver_recover_test.cpp +++ b/test/integration/snapshotcloneserver/snapshotcloneserver_recover_test.cpp @@ -132,7 +132,9 @@ const std::vector chunkserverConfigOptions{ std::string("curve.root_username") + mdsRootUser_, std::string("curve.root_password") + mdsRootPassword_, "walfilepool.use_chunk_file_pool=false", - "walfilepool.enable_get_segment_from_pool=false" + "walfilepool.enable_get_segment_from_pool=false", + "global.block_size=4096", + "global.meta_page_size=4096", }; const std::vector csClientConfigOptions{ diff --git a/test/mds/server/BUILD b/test/mds/server/BUILD index 05d2fd70ee..071c3c984d 100644 --- a/test/mds/server/BUILD +++ b/test/mds/server/BUILD @@ -27,6 +27,7 @@ cc_binary( "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", "//src/mds/server:mds_for_test", + "//test/mds/mock:common_mock", ], linkopts = ["-lfiu"], ) diff --git a/test/mds/server/mds_test.cpp b/test/mds/server/mds_test.cpp index 93c2207cfa..438cd9769f 100644 --- a/test/mds/server/mds_test.cpp +++ b/test/mds/server/mds_test.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,8 @@ #include "src/common/timeutility.h" #include "src/common/string_util.h" +#include "test/mds/mock/mock_etcdclient.h" + using ::curve::common::Thread; DECLARE_string(mdsAddr); @@ -39,6 +42,9 @@ DECLARE_string(etcdAddr); namespace curve { namespace mds { + +extern uint32_t g_block_size; + class MDSTest : public ::testing::Test { protected: void SetUp() { @@ -217,5 +223,44 @@ TEST_F(MDSTest, common) { ASSERT_LE(stopTime - startTime, 100); } +TEST_F(MDSTest, TestBlockSize) { + using ::testing::_; + using ::testing::Return; + using ::testing::Invoke; + + auto client = std::make_shared(); + + // etcd doesn't has block size on startup + { + EXPECT_CALL(*client, Get(_, _)) + .WillOnce(Return(EtcdErrCode::EtcdKeyNotExist)); + EXPECT_CALL(*client, Put(_, _)) + .WillOnce(Return(EtcdErrCode::EtcdOK)); + ASSERT_TRUE(CheckOrInsertBlockSize(client.get())); + } + + // etcd has block size but different with `g_block_size` + { + g_block_size = 4096; + EXPECT_CALL(*client, Get(_, _)) + .WillOnce(Invoke([](const std::string&, std::string* value) { + *value = std::to_string(g_block_size / 2); + return EtcdErrCode::EtcdOK; + })); + ASSERT_FALSE(CheckOrInsertBlockSize(client.get())); + } + + // etcd has block size + { + g_block_size = 4096; + EXPECT_CALL(*client, Get(_, _)) + .WillOnce(Invoke([](const std::string&, std::string* value) { + *value = std::to_string(g_block_size); + return EtcdErrCode::EtcdOK; + })); + ASSERT_TRUE(CheckOrInsertBlockSize(client.get())); + } +} + } // namespace mds } // namespace curve diff --git a/test/mds/topology/test_topology_service_manager.cpp b/test/mds/topology/test_topology_service_manager.cpp index 47b2052df7..b59907dbd4 100644 --- a/test/mds/topology/test_topology_service_manager.cpp +++ b/test/mds/topology/test_topology_service_manager.cpp @@ -33,6 +33,9 @@ namespace curve { namespace mds { + +extern uint32_t g_block_size; + namespace topology { using ::testing::Return; @@ -226,7 +229,6 @@ class TestTopologyServiceManager : public ::testing::Test { MockCopysetServiceImpl *mockCopySetService; }; - TEST_F(TestTopologyServiceManager, test_RegistChunkServer_SuccessWithExIp) { ChunkServerIdType csId = 0x41; ServerIdType serverId = 0x31; @@ -404,6 +406,23 @@ TEST_F(TestTopologyServiceManager, test_RegistChunkServer_AddChunkServerFail) { ASSERT_FALSE(response.has_token()); } +TEST_F(TestTopologyServiceManager, test_RegistChunkServer_BlockSizeConflict) { + ChunkServerRegistRequest request; + request.set_disktype("ssd"); + request.set_diskpath("/"); + request.set_hostip("testInternalIp"); + request.set_port(100); + request.set_blocksize(512); + g_block_size = 4096; + + ChunkServerRegistResponse response; + + serviceManager_->RegistChunkServer(&request, &response); + ASSERT_EQ(kTopoErrCodeConflictBlockSize, response.statuscode()); + ASSERT_FALSE(response.has_chunkserverid()); + ASSERT_FALSE(response.has_token()); +} + TEST_F(TestTopologyServiceManager, test_ListChunkServer_ByIdSuccess) { ChunkServerIdType csId1 = 0x41; ChunkServerIdType csId2 = 0x42;