Compare commits

..

4 Commits

Author SHA1 Message Date
ilixiaocui b6b23aa97c curvefs/fix: addition of the objectPrefix field in the message S3Info has caused compatibility issues
Signed-off-by: ilixiaocui <ilixiaocui@163.com>
2023-07-10 17:03:12 +08:00
hzwuhongsong 6113dbe266 curvefs/client: fix s3 object will not be removed 2023-06-30 11:46:17 +08:00
Cyber-SiKu 057cac9f7d [fix] warmup to mem error
It turns out that mem and disk are not separated, the storage of mem is
asynchronous, and the storage of disk is synchronous, so when it is
deleted later, it is generally written. Later, after the separation of
the two, an exception occurred in the asynchronous save of mem.

Signed-off-by: Cyber-SiKu <Cyber-SiKu@outlook.com>
2023-06-27 14:09:43 +08:00
Wine93 150cd3b9b6 curvefs/client: fixed some minor bugs.
Signed-off-by: Wine93 <wine93.info@gmail.com>
2023-06-12 13:41:08 +08:00
366 changed files with 6129 additions and 11412 deletions

View File

@ -1,10 +1,7 @@
build --verbose_failures
build --define=with_glog=true --define=libunwind=true
build --copt -DHAVE_ZLIB=1 --copt -DGFLAGS_NS=google --copt -DUSE_BTHREAD_MUTEX
build --cxxopt -Wno-error=format-security
build:gcc7-later --cxxopt -faligned-new
build --incompatible_blacklisted_protos_requires_proto_info=false
build --copt=-fdiagnostics-color=always
run --copt=-fdiagnostics-color=always

9
.gitignore vendored
View File

@ -157,12 +157,3 @@ GPATH
GRTAGS
GTAGS
core.*
test/integration/*.conf
test/integration/client/config/client.conf*
test/integration/snapshotcloneserver/config/*.conf
.pre-commit-config.yaml
*.deb
*.whl

View File

@ -75,14 +75,11 @@ bind(
)
#import the gtest files.
http_archive(
new_git_repository(
name = "com_google_googletest",
urls = [
"https://curve-build.nos-eastchina1.126.net/googletest-release-1.12.1.tar.gz",
"https://github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz",
],
sha256 = "81964fe578e9bd7c94dfdb09c8e4d6e6759e19967e397dbea48d1c10e45d0df2",
strip_prefix = "googletest-release-1.12.1",
build_file = "//:thirdparties/gmock.BUILD",
remote = "https://github.com/google/googletest",
tag = "release-1.8.0",
)
bind(

View File

@ -7,22 +7,12 @@ then
exit
fi
if [ `gcc -dumpversion | awk -F'.' '{print $1}'` -le 6 ]
then
bazelflags=''
else
bazelflags='--copt -faligned-new'
fi
if [ "$1" = "debug" ]
then
DEBUG_FLAG="--compilation_mode=dbg"
fi
bazel build curvefs/... --copt -DHAVE_ZLIB=1 ${DEBUG_FLAG} -s \
--define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google --copt -Wno-error=format-security --copt \
-DUSE_BTHREAD_MUTEX --copt -DCURVEVERSION=${curve_version} --linkopt -L/usr/local/lib ${bazelflags}
bazel build curvefs/... --copt -DHAVE_ZLIB=1 ${DEBUG_FLAG} -s --define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google --copt -Wno-error=format-security --copt -DUSE_BTHREAD_MUTEX --copt -DCURVEVERSION=${curve_version} --linkopt -L/usr/local/lib
if [ $? -ne 0 ]
then
echo "build curvefs failed"
@ -44,5 +34,4 @@ then
echo "mds_test failed"
exit
fi
fi
echo "end compile"
fi

View File

@ -9,20 +9,13 @@ global.enable_external_server=true
global.external_ip=127.0.0.1 # __CURVEADM_TEMPLATE__ ${service_external_addr} __CURVEADM_TEMPLATE__
global.external_subnet=127.0.0.0/24
# chunk大小一般16MB
# it will be overwritten from chunkfilepool.meta if `chunkfilepool.enable_get_chunk_from_pool` is true
global.chunk_size=16777216
# chunk 元数据页大小一般4KB
# it will be overwritten from chunkfilepool.meta if `chunkfilepool.enable_get_chunk_from_pool` is true
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.
# it will be overwritten from chunkfilepool.meta if `chunkfilepool.enable_get_chunk_from_pool` is true
global.block_size=4096
# clone chunk允许的最长location长度
global.location_limit=3000
# minimum alignment for io request
global.min_io_alignment=512
#
# MDS settings
@ -115,7 +108,7 @@ copyset.scan_rpc_retry_times=3
# the follower send scanmap to leader rpc retry interval
copyset.scan_rpc_retry_interval_us=100000
# enable O_DSYNC when open chunkfile
copyset.enable_odsync_when_open_chunkfile=true
copyset.enable_odsync_when_open_chunkfile=false
# sync trigger seconds
copyset.sync_trigger_seconds=25
# sync chunk limit default = 2MB

View File

@ -13,12 +13,9 @@ 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
# minimum alignment for io request
global.min_io_alignment=512
#
# MDS settings
@ -111,7 +108,7 @@ copyset.scan_rpc_retry_times=3
# the follower send scanmap to leader rpc retry interval
copyset.scan_rpc_retry_interval_us=100000
# enable O_DSYNC when open chunkfile
copyset.enable_odsync_when_open_chunkfile=true
copyset.enable_odsync_when_open_chunkfile=false
# sync trigger seconds
copyset.sync_trigger_seconds=25
# sync chunk limit default = 2MB

View File

@ -168,6 +168,13 @@ discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
##### alignment #####
# default alignment
global.alignment.commonVolume=512
# alignment for clone volume
# default is 4096, because lazy clone chunk bitmap granularity is 4096
global.alignment.cloneVolume=4096
##### chunkserver client option #####
# chunkserver client rpc timeout time
csClientOpt.rpcTimeoutMs=500
@ -181,3 +188,4 @@ csClientOpt.rpcMaxTimeoutMs=8000
##### chunkserver broadcaster option #####
# broad cast max machine num
csBroadCasterOpt.broadCastMaxNum=200

View File

@ -159,3 +159,10 @@ discard.enable=false
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
##### alignment #####
# default alignment
global.alignment.commonVolume=512
# alignment for clone volume
# default is 4096, because lazy clone chunk bitmap granularity is 4096
global.alignment.cloneVolume=4096

View File

@ -197,8 +197,6 @@ 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
@ -239,16 +237,3 @@ mds.throttle.iopsPerGB=30
mds.throttle.bpsMinInMB=120
mds.throttle.bpsMaxInMB=260
mds.throttle.bpsPerGBInMB=0.3
#
## poolset rules
#
# for backward compatibility, rules are applied for select poolset when creating file
#
# for example
# mds.poolset.rules=/dir1/:poolset1;/dir2/:poolset2;/dir1/sub/:sub
#
# when creating file reqeust doesn't have poolset, above rules are used to select poolset
# - if filename is /dir1/file, then poolset1 is select
# - if filename is /dir1/sub/file, then sub is select
mds.poolset.rules=

View File

@ -153,3 +153,10 @@ discard.enable=false
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
##### alignment #####
# default alignment
global.alignment.commonVolume=512
# alignment for clone volume
# default is 4096, because lazy clone chunk bitmap granularity is 4096
global.alignment.cloneVolume=4096

View File

@ -159,3 +159,10 @@ discard.enable=false
discard.granularity=4096
# discard cleanup task delay times in millisecond
discard.taskDelayMs=60000
##### alignment #####
# default alignment
global.alignment.commonVolume=512
# alignment for clone volume
# default is 4096, because lazy clone chunk bitmap granularity is 4096
global.alignment.cloneVolume=4096

View File

@ -164,6 +164,7 @@ chunkserver_walfilepool_retry_times: 5
chunkserver_trash_expire_after_sec: 300
chunkserver_trash_scan_period_sec: 120
chunkserver_common_log_dir: ./runlog/
chunkserver_min_io_alignment: 512
# 快照克隆配置默认值
snap_client_config_path: /etc/curve/snap_client.conf
@ -243,6 +244,8 @@ client_throttle_enable: false
client_discard_enable: true
client_discard_granularity: 4096
client_discard_task_delay_ms: 60000
client_alignment_common: 512
client_alignment_clone: 4096
# nebd默认配置
client_config_path: /etc/curve/client.conf

View File

@ -14,6 +14,8 @@ global.chunk_size={{ chunk_size }}
global.meta_page_size={{ chunkserver_meta_page_size }}
# clone chunk允许的最长location长度
global.location_limit={{ chunkserver_location_limit }}
# minimum alignment for io request
global.min_io_alignment={{ chunkserver_min_io_alignment }}
#
# MDS settings

View File

@ -175,3 +175,10 @@ discard.enable={{ client_discard_enable }}
discard.granularity={{ client_discard_granularity }}
# discard cleanup task delay times in millisecond
discard.taskDelayMs={{ client_discard_task_delay_ms }}
##### alignment #####
# default alignment
global.alignment.commonVolume={{ client_alignment_common }}
# alignment for clone volume
# default is 4096, because lazy clone chunk bitmap granularity is 4096
global.alignment.cloneVolume={{ client_alignment_clone }}

View File

@ -6,9 +6,6 @@ mds.listen.addr=127.0.0.1:6700 #__CURVEADM_TEMPLATE__ ${service_addr}:${service
mds.dummy.port=7700 # __CURVEADM_TEMPLATE__ ${service_dummy_port} __CURVEADM_TEMPLATE__ __ANSIBLE_TEMPLATE__ {{ curvefs_mds_listen_dummy_port }} __ANSIBLE_TEMPLATE__
mds.common.logDir=/tmp/curvefs/mds # __CURVEADM_TEMPLATE__ ${prefix}/logs __CURVEADM_TEMPLATE__ __ANSIBLE_TEMPLATE__ /tmp/{{ inventory_hostname }}/curvefs/mds __ANSIBLE_TEMPLATE__
mds.loglevel=0
# If a connection does not read or write,it's treated as "idle" and will be closed by server soon.
# Default value is -1 which disables the feature.
mds.server.idleTimeoutSec=-1
#
# space options

View File

@ -128,25 +128,16 @@ copyset.trash.scan_periodsec=120
# this config item should be tuned according cpu/memory/disk
service.max_inflight_request=5000
#
# Concurrent apply queue
### concurrent apply queue options for each copyset
### concurrent apply queue is used to isolate raft threads, each worker has its own queue
### when a task can be applied it's been pushed into a corresponding read/write worker queue by certain rules
### apply queue options for each copyset
### apply queue is used to isolate raft threads, each worker has its own queue
### when a task can be applied it's been pushed into a corresponding worker queue by certain rules
# number of apply queue workers for each, each worker will start a indepent thread
applyqueue.worker_count=3
# worker_count: number of apply queue workers for each, each worker will start a indepent thread
# queue_depth: apply queue depth for each copyset
# apply queue depth for each copyset
# all tasks in queue must be done when do raft snapshot, and raft apply and raft snapshot are executed in same thread
# so, if queue depth is too large, it will cause other tasks to wait too long for apply
# write apply queue workers count
applyqueue.write_worker_count=3
# write apply queue depth
applyqueue.write_queue_depth=1
# read apply queue workers count
applyqueue.read_worker_count=2
# read apply queue depth
applyqueue.read_queue_depth=1
applyqueue.queue_depth=1
# number of worker threads that created by brpc::Server
# if set to |auto|, threads create by brpc::Server is equal to `getconf _NPROCESSORS_ONLN` + 1
@ -154,10 +145,6 @@ applyqueue.read_queue_depth=1
# it is recommended to set it to |auto| unless there is a significant performance improvement
bthread.worker_count=auto
# If a connection does not read or write, it's treated as "idle" and will be closed by server soon.
# Default value is -1 which disables the feature.
server.idleTimeoutSec=-1
### Braft related flags
### These configurations are ignored if the command line startup options are set
# Call fsync when need

View File

@ -66,8 +66,6 @@ void MDS::InitOptions(std::shared_ptr<Configuration> conf) {
conf_ = std::move(conf);
conf_->GetValueFatalIfFail("mds.listen.addr", &options_.mdsListenAddr);
conf_->GetValueFatalIfFail("mds.dummy.port", &options_.dummyPort);
conf_->GetValueFatalIfFail("mds.server.idleTimeoutSec",
&options_.idleTimeoutSec);
InitMetaServerOption(&options_.metaserverOptions);
InitTopologyOption(&options_.topologyOptions);
@ -277,7 +275,6 @@ void MDS::Run() {
// start rpc server
brpc::ServerOptions option;
option.idle_timeout_sec = options_.idleTimeoutSec;
LOG_IF(FATAL, server.Start(options_.mdsListenAddr.c_str(), &option) != 0)
<< "start brpc server error";
running_ = true;

View File

@ -85,8 +85,6 @@ using ::curvefs::mds::space::MdsProxyOptions;
struct MDSOptions {
int dummyPort;
std::string mdsListenAddr;
int idleTimeoutSec;
MetaserverOptions metaserverOptions;
// TODO(add EtcdConf): add etcd configure

View File

@ -0,0 +1,135 @@
/*
* 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
* Date: Thu Sep 2 14:49:04 CST 2021
* Author: wuhanqing
*/
#include "curvefs/src/metaserver/copyset/apply_queue.h"
#include <glog/logging.h>
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "curvefs/src/common/threading.h"
#include "curvefs/src/metaserver/copyset/copyset_node.h"
namespace curvefs {
namespace metaserver {
namespace copyset {
using ::curvefs::common::SetThreadName;
void ApplyQueue::StartWorkers() {
for (uint32_t i = 0; i < option_.workerCount; ++i) {
std::string name = [this, i]() -> std::string {
if (option_.copysetNode == nullptr) {
return "apply";
}
return absl::StrCat("apply", ":", option_.copysetNode->GetPoolId(),
"_", option_.copysetNode->GetCopysetId(), ":",
i);
}();
auto taskThread =
absl::make_unique<TaskWorker>(option_.queueDepth, std::move(name));
taskThread->Start();
workers_.emplace_back(std::move(taskThread));
}
}
bool ApplyQueue::Start(const ApplyQueueOption& option) {
if (running_) {
return true;
}
if (option.queueDepth < 1 || option.workerCount < 1) {
LOG(ERROR) << "ApplyQueue start failed, invalid argument, queue depth: "
<< option.queueDepth
<< ", worker count: " << option.workerCount;
return false;
}
option_ = option;
StartWorkers();
running_.store(true);
return true;
}
void ApplyQueue::Flush() {
if (!running_.load(std::memory_order_relaxed)) {
return;
}
curve::common::CountDownEvent event(option_.workerCount);
auto flush = [&event]() { event.Signal(); };
for (auto& worker : workers_) {
worker->tasks.Push(flush);
}
event.Wait();
}
void ApplyQueue::Stop() {
if (!running_.exchange(false)) {
return;
}
LOG(INFO) << "Going to stop apply queue";
for (auto& worker : workers_) {
worker->Stop();
}
workers_.clear();
LOG(INFO) << "Apply queue stopped";
}
void ApplyQueue::TaskWorker::Start() {
if (running.exchange(true)) {
return;
}
worker = std::thread(&TaskWorker::Work, this);
}
void ApplyQueue::TaskWorker::Stop() {
if (!running.exchange(false)) {
return;
}
auto wakeup = []() {};
tasks.Push(wakeup);
worker.join();
}
void ApplyQueue::TaskWorker::Work() {
SetThreadName(workerName_.c_str());
while (running.load(std::memory_order_relaxed)) {
tasks.Pop()();
}
}
} // namespace copyset
} // namespace metaserver
} // namespace curvefs

View File

@ -0,0 +1,98 @@
/*
* 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
* Date: Thu Sep 2 14:49:04 CST 2021
* Author: wuhanqing
*/
#ifndef CURVEFS_SRC_METASERVER_COPYSET_APPLY_QUEUE_H_
#define CURVEFS_SRC_METASERVER_COPYSET_APPLY_QUEUE_H_
#include <atomic>
#include <cstdint>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
#include "include/curve_compiler_specific.h"
#include "src/common/concurrent/count_down_event.h"
#include "src/common/concurrent/task_queue.h"
namespace curvefs {
namespace metaserver {
namespace copyset {
class CopysetNode;
struct ApplyQueueOption {
uint32_t workerCount = 1;
uint32_t queueDepth = 1;
CopysetNode* copysetNode = nullptr;
};
class CURVE_CACHELINE_ALIGNMENT ApplyQueue {
public:
ApplyQueue() : option_(), running_(false), workers_() {}
bool Start(const ApplyQueueOption& option);
template <typename Func, typename... Args>
void Push(uint64_t hash, Func&& f, Args&&... args) {
workers_[hash % option_.workerCount]->tasks.Push(
std::forward<Func>(f), std::forward<Args>(args)...);
}
void Flush();
void Stop();
private:
void StartWorkers();
struct TaskWorker {
TaskWorker(size_t cap, std::string workerName)
: running(false),
worker(),
tasks(cap),
workerName_(std::move(workerName)) {}
void Start();
void Stop();
void Work();
std::atomic<bool> running;
std::thread worker;
curve::common::TaskQueue tasks;
std::string workerName_;
};
private:
ApplyQueueOption option_;
std::atomic<bool> running_;
std::vector<std::unique_ptr<TaskWorker>> workers_;
};
} // namespace copyset
} // namespace metaserver
} // namespace curvefs
#endif // CURVEFS_SRC_METASERVER_COPYSET_APPLY_QUEUE_H_

View File

@ -1,198 +0,0 @@
/*
* Copyright (c) 2023 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: 20230521
* Author: Xinlong-Chen
*/
#include "curvefs/src/metaserver/copyset/concurrent_apply_queue.h"
#include <algorithm>
namespace curvefs {
namespace metaserver {
namespace copyset {
bool ApplyQueue::Init(const ApplyOption &opt) {
if (start_) {
LOG(WARNING) << "concurrent module already start!";
return true;
}
if (false == CheckOptAndInit(opt)) {
return false;
}
start_ = true;
cond_.Reset(opt.rconcurrentsize + opt.wconcurrentsize);
InitThreadPool(ThreadPoolType::READ, rconcurrentsize_, rqueuedepth_);
InitThreadPool(ThreadPoolType::WRITE, wconcurrentsize_, wqueuedepth_);
if (!cond_.WaitFor(5000)) {
LOG(ERROR) << "init concurrent module's threads fail";
start_ = false;
}
LOG(INFO) << "Init concurrent module's threads success";
return start_;
}
bool ApplyQueue::CheckOptAndInit(const ApplyOption &opt) {
if (opt.rconcurrentsize <= 0 || opt.wconcurrentsize <= 0 ||
opt.rqueuedepth <= 0 || opt.wqueuedepth <= 0) {
LOG(INFO) << "init concurrent module fail, params must >=0"
<< ", rconcurrentsize=" << opt.rconcurrentsize
<< ", wconcurrentsize=" << opt.wconcurrentsize
<< ", rqueuedepth=" << opt.rqueuedepth
<< ", wconcurrentsize=" << opt.wqueuedepth;
return false;
}
wconcurrentsize_ = opt.wconcurrentsize;
wqueuedepth_ = opt.wqueuedepth;
rconcurrentsize_ = opt.rconcurrentsize;
rqueuedepth_ = opt.rqueuedepth;
return true;
}
void ApplyQueue::InitThreadPool(
ThreadPoolType type, int concurrent, int depth) {
for (int i = 0; i < concurrent; i++) {
auto asyncth = new (std::nothrow) TaskThread(depth);
CHECK(asyncth != nullptr) << "allocate failed!";
switch (type) {
case ThreadPoolType::READ:
rapplyMap_.insert(std::make_pair(i, asyncth));
break;
case ThreadPoolType::WRITE:
wapplyMap_.insert(std::make_pair(i, asyncth));
break;
}
}
for (int i = 0; i < concurrent; i++) {
switch (type) {
case ThreadPoolType::READ:
rapplyMap_[i]->th =
std::thread(&ApplyQueue::Run, this, type, i);
break;
case ThreadPoolType::WRITE:
wapplyMap_[i]->th =
std::thread(&ApplyQueue::Run, this, type, i);
break;
}
}
}
void ApplyQueue::Run(ThreadPoolType type, int index) {
cond_.Signal();
while (start_) {
switch (type) {
case ThreadPoolType::READ:
rapplyMap_[index]->tq.Pop()();
break;
case ThreadPoolType::WRITE:
wapplyMap_[index]->tq.Pop()();
break;
}
}
}
void ApplyQueue::Stop() {
if (!start_.exchange(false)) {
return;
}
LOG(INFO) << "stop ApplyQueue...";
auto wakeup = []() {};
for (auto iter : rapplyMap_) {
iter.second->tq.Push(wakeup);
iter.second->th.join();
delete iter.second;
}
rapplyMap_.clear();
for (auto iter : wapplyMap_) {
iter.second->tq.Push(wakeup);
iter.second->th.join();
delete iter.second;
}
wapplyMap_.clear();
LOG(INFO) << "stop ApplyQueue ok.";
}
void ApplyQueue::Flush() {
if (!start_.load(std::memory_order_relaxed)) {
return;
}
CountDownEvent event(wconcurrentsize_);
auto flushtask = [&event]() {
event.Signal();
};
for (int i = 0; i < wconcurrentsize_; i++) {
wapplyMap_[i]->tq.Push(flushtask);
}
event.Wait();
}
void ApplyQueue::FlushAll() {
if (!start_.load(std::memory_order_relaxed)) {
return;
}
CountDownEvent event(wconcurrentsize_ + rconcurrentsize_);
auto flushtask = [&event]() {
event.Signal();
};
for (int i = 0; i < wconcurrentsize_; i++) {
wapplyMap_[i]->tq.Push(flushtask);
}
for (int i = 0; i < rconcurrentsize_; i++) {
rapplyMap_[i]->tq.Push(flushtask);
}
event.Wait();
}
ThreadPoolType ApplyQueue::Schedule(OperatorType optype) {
switch (optype) {
case OperatorType::GetDentry:
case OperatorType::ListDentry:
case OperatorType::GetInode:
case OperatorType::BatchGetInodeAttr:
case OperatorType::BatchGetXAttr:
case OperatorType::GetVolumeExtent:
return ThreadPoolType::READ;
default:
return ThreadPoolType::WRITE;
}
}
} // namespace copyset
} // namespace metaserver
} // namespace curvefs

View File

@ -1,152 +0,0 @@
/*
* Copyright (c) 2023 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: 20230521
* Author: Xinlong-Chen
*/
#ifndef CURVEFS_SRC_METASERVER_COPYSET_CONCURRENT_APPLY_QUEUE_H_
#define CURVEFS_SRC_METASERVER_COPYSET_CONCURRENT_APPLY_QUEUE_H_
#include <bthread/condition_variable.h>
#include <bthread/mutex.h>
#include <glog/logging.h>
#include <atomic>
#include <thread>
#include <unordered_map>
#include <utility>
#include "include/curve_compiler_specific.h"
#include "src/common/concurrent/count_down_event.h"
#include "src/common/concurrent/task_queue.h"
#include "curvefs/src/metaserver/copyset/operator_type.h"
namespace curvefs {
namespace metaserver {
namespace copyset {
using curve::common::CountDownEvent;
using curve::common::GenericTaskQueue;
struct ApplyOption {
int wconcurrentsize = 3;
int wqueuedepth = 1;
int rconcurrentsize = 1;
int rqueuedepth = 1;
ApplyOption(int wsize, int wdepth, int rsize, int rdepth) :
wconcurrentsize(wsize),
wqueuedepth(wdepth),
rconcurrentsize(rsize),
rqueuedepth(rdepth) {}
ApplyOption() {}
};
enum class ThreadPoolType {READ, WRITE};
/*
TODO: this moudle is same as curvebs's ConcurrentApplyModule,
only Schedule function is different.
we can make ApplyQueue to a base class,
and define Schedule with virtual function,
derive class override Schedule.
*/
class CURVE_CACHELINE_ALIGNMENT ApplyQueue {
public:
ApplyQueue(): start_(false),
rconcurrentsize_(0),
rqueuedepth_(0),
wconcurrentsize_(0),
wqueuedepth_(0),
cond_(0) {}
/**
* Init: initialize ApplyQueue
* @param[in] wconcurrentsize: num of write threads
* @param[in] wqueuedepth: depth of write queue in ervery thread
* @param[in] rconcurrentsizee: num of read threads
* @param[in] wqueuedephth: depth of read queue in every thread
*/
bool Init(const ApplyOption &opt);
/**
* Push: apply task will be push to ApplyQueue
* @param[in] key: used to hash task to specified queue
* @param[in] optype: operation type defined in proto
* @param[in] f: task
* @param[in] args: param to excute task
*/
template <class F, class... Args>
bool Push(uint64_t key, OperatorType optype, F&& f, Args&&... args) {
switch (Schedule(optype)) {
case ThreadPoolType::READ:
rapplyMap_[Hash(key, rconcurrentsize_)]->tq.Push(
std::forward<F>(f), std::forward<Args>(args)...);
break;
case ThreadPoolType::WRITE:
wapplyMap_[Hash(key, wconcurrentsize_)]->tq.Push(
std::forward<F>(f), std::forward<Args>(args)...);
break;
}
return true;
}
/**
* Flush: finish all task in write threads
*/
void Flush();
void FlushAll();
void Stop();
private:
bool CheckOptAndInit(const ApplyOption &option);
void Run(ThreadPoolType type, int index);
static ThreadPoolType Schedule(OperatorType optype);
void InitThreadPool(ThreadPoolType type, int concorrent, int depth);
static int Hash(uint64_t key, int concurrent) {
return key % concurrent;
}
private:
struct TaskThread {
std::thread th;
GenericTaskQueue<bthread::Mutex, bthread::ConditionVariable> tq;
explicit TaskThread(size_t capacity) : tq(capacity) {}
};
std::atomic<bool> start_;
int rconcurrentsize_;
int rqueuedepth_;
int wconcurrentsize_;
int wqueuedepth_;
CountDownEvent cond_;
CURVE_CACHELINE_ALIGNMENT std::unordered_map<int, TaskThread*> wapplyMap_;
CURVE_CACHELINE_ALIGNMENT std::unordered_map<int, TaskThread*> rapplyMap_;
};
} // namespace copyset
} // namespace metaserver
} // namespace curvefs
#endif // CURVEFS_SRC_METASERVER_COPYSET_CONCURRENT_APPLY_QUEUE_H_

View File

@ -31,7 +31,7 @@
#include <memory>
#include <string>
#include "curvefs/src/metaserver/copyset/concurrent_apply_queue.h"
#include "curvefs/src/metaserver/copyset/apply_queue.h"
#include "curvefs/src/metaserver/copyset/trash.h"
#include "curvefs/src/metaserver/storage/config.h"
#include "src/fs/local_filesystem.h"
@ -74,7 +74,7 @@ struct CopysetNodeOptions {
uint32_t checkLoadMarginIntervalMs;
// apply queue options
ApplyOption applyQueueOption;
ApplyQueueOption applyQueueOption;
// filesystem adaptor
curve::fs::LocalFileSystem* localFileSystem;

View File

@ -120,8 +120,9 @@ bool CopysetNode::Init(const CopysetNodeOptions& options) {
// init apply queue
applyQueue_ = absl::make_unique<ApplyQueue>();
if (!applyQueue_->Init(options_.applyQueueOption)) {
LOG(ERROR) << "init concurrent apply queue failed";
options_.applyQueueOption.copysetNode = this;
if (!applyQueue_->Start(options_.applyQueueOption)) {
LOG(ERROR) << "Start apply queue failed";
return false;
}
@ -257,7 +258,6 @@ void CopysetNode::on_apply(braft::Iterator& iter) {
iter.index(), doneGuard.release(),
TimeUtility::GetTimeofDayUs());
applyQueue_->Push(metaClosure->GetOperator()->HashCode(),
metaClosure->GetOperator()->GetOperatorType(),
std::move(task));
timer.stop();
g_concurrent_apply_wait_latency << timer.u_elapsed();
@ -268,11 +268,10 @@ void CopysetNode::on_apply(braft::Iterator& iter) {
butil::Timer timer;
timer.start();
auto hashcode = metaOperator->HashCode();
auto type = metaOperator->GetOperatorType();
auto task =
std::bind(&MetaOperator::OnApplyFromLog, metaOperator.release(),
TimeUtility::GetTimeofDayUs());
applyQueue_->Push(hashcode, type, std::move(task));
applyQueue_->Push(hashcode, std::move(task));
timer.stop();
g_concurrent_apply_from_log_wait_latency << timer.u_elapsed();
}
@ -427,9 +426,6 @@ int CopysetNode::on_snapshot_load(braft::SnapshotReader* reader) {
}
void CopysetNode::on_leader_start(int64_t term) {
LOG(INFO) << "Copyset: " << name_ << ", peer id: " << peerId_.to_string()
<< " going to flush apply queue, term is " << term;
applyQueue_->Flush();
leaderTerm_.store(term, std::memory_order_release);
LOG(INFO) << "Copyset: " << name_ << ", peer id: " << peerId_.to_string()

View File

@ -31,7 +31,7 @@
#include <vector>
#include "curvefs/src/metaserver/common/types.h"
#include "curvefs/src/metaserver/copyset/concurrent_apply_queue.h"
#include "curvefs/src/metaserver/copyset/apply_queue.h"
#include "curvefs/src/metaserver/copyset/conf_epoch_file.h"
#include "curvefs/src/metaserver/copyset/config.h"
#include "curvefs/src/metaserver/copyset/copyset_conf_change.h"
@ -123,7 +123,7 @@ class CopysetNode : public braft::StateMachine {
#ifdef UNIT_TEST
void SetMetaStore(MetaStore* metastore) { metaStore_.reset(metastore); }
void FlushApplyQueue() { applyQueue_->FlushAll(); }
void FlushApplyQueue() { applyQueue_->Flush(); }
void SetRaftNode(RaftNode* raftNode) { raftNode_.reset(raftNode); }
#endif // UNIT_TEST

View File

@ -107,8 +107,7 @@ void MetaOperator::FastApplyTask() {
auto task =
std::bind(&MetaOperator::OnApply, this, node_->GetAppliedIndex(),
new MetaOperatorClosure(this), TimeUtility::GetTimeofDayUs());
node_->GetApplyQueue()->Push(HashCode(),
GetOperatorType(), std::move(task));
node_->GetApplyQueue()->Push(HashCode(), std::move(task));
timer.stop();
g_concurrent_fast_apply_wait_latency << timer.u_elapsed();
}

View File

@ -68,6 +68,7 @@ using ::curve::fs::FileSystemType;
using ::curve::fs::LocalFsFactory;
using ::curve::fs::LocalFileSystemOption;
using ::curvefs::metaserver::copyset::ApplyQueueOption;
using ::curvefs::client::rpcclient::MetaServerClientImpl;
using ::curvefs::client::rpcclient::ChannelManager;
using ::curvefs::client::rpcclient::MetaCache;
@ -99,9 +100,6 @@ void Metaserver::InitOptions(std::shared_ptr<Configuration> conf) {
<< "Parse bthread.worker_count to int failed, string value: "
<< value;
}
conf_->GetValueFatalIfFail("server.idleTimeoutSec",
&options_.idleTimeoutSec);
InitBRaftFlags(conf);
}
@ -458,7 +456,6 @@ void Metaserver::Run() {
if (options_.bthreadWorkerCount != -1) {
option.num_threads = options_.bthreadWorkerCount;
}
option.idle_timeout_sec = options_.idleTimeoutSec;
LOG_IF(FATAL, server_->Start(listenAddr, &option) != 0)
<< "start internal brpc server error";
@ -656,18 +653,13 @@ void Metaserver::InitCopysetNodeOptions() {
"copyset.check_loadmargin_interval_ms",
&copysetNodeOptions_.checkLoadMarginIntervalMs));
LOG_IF(FATAL, !conf_->GetIntValue(
"applyqueue.write_worker_count",
&copysetNodeOptions_.applyQueueOption.wconcurrentsize));
LOG_IF(FATAL, !conf_->GetIntValue(
"applyqueue.write_queue_depth",
&copysetNodeOptions_.applyQueueOption.wqueuedepth));
LOG_IF(FATAL, !conf_->GetIntValue(
"applyqueue.read_worker_count",
&copysetNodeOptions_.applyQueueOption.rconcurrentsize));
LOG_IF(FATAL, !conf_->GetIntValue(
"applyqueue.read_queue_depth",
&copysetNodeOptions_.applyQueueOption.rqueuedepth));
LOG_IF(FATAL, !conf_->GetUInt32Value(
"applyqueue.worker_count",
&copysetNodeOptions_.applyQueueOption.workerCount));
LOG_IF(FATAL, !conf_->GetUInt32Value(
"applyqueue.queue_depth",
&copysetNodeOptions_.applyQueueOption.queueDepth));
LOG_IF(FATAL,
!conf_->GetStringValue("copyset.trash.uri",
&copysetNodeOptions_.trashOptions.trashUri));

View File

@ -28,6 +28,7 @@
#include <memory>
#include <string>
#include "curvefs/src/metaserver/copyset/apply_queue.h"
#include "curvefs/src/metaserver/copyset/config.h"
#include "curvefs/src/metaserver/copyset/copyset_node_manager.h"
#include "curvefs/src/metaserver/copyset/raft_cli_service2.h"
@ -51,6 +52,7 @@ namespace metaserver {
using ::curve::common::Configuration;
using ::curvefs::metaserver::storage::StorageOptions;
using ::curvefs::metaserver::copyset::ApplyQueue;
using ::curvefs::metaserver::copyset::CopysetNodeManager;
using ::curvefs::metaserver::copyset::CopysetNodeOptions;
using ::curvefs::metaserver::copyset::CopysetServiceImpl;
@ -68,7 +70,6 @@ struct MetaserverOptions {
std::string externalIp;
int externalPort;
int bthreadWorkerCount = -1;
int idleTimeoutSec = -1;
bool enableExternalServer;
};

View File

@ -34,7 +34,6 @@ namespace curvefs {
namespace client {
using ::testing::SetArgPointee;
using ::testing::DoAll;
using rpcclient::MockMetaServerClient;
using rpcclient::MockMdsClient;

View File

@ -36,7 +36,7 @@ using curvefs::mds::topology::PartitionTxId;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::DoAll;
namespace curvefs {
namespace client {

View File

@ -21,6 +21,8 @@
*/
#include <gmock/gmock-generated-actions.h>
#include <gmock/gmock-more-actions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@ -73,7 +75,6 @@ namespace client {
using ::curve::common::Configuration;
using ::curvefs::mds::topology::PartitionTxId;
using ::testing::_;
using ::testing::DoAll;
using ::testing::AtLeast;
using ::testing::Contains;
using ::testing::Invoke;

View File

@ -56,7 +56,6 @@ namespace client {
using ::curve::common::Configuration;
using ::curvefs::mds::topology::PartitionTxId;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Contains;
using ::testing::Invoke;
using ::testing::Return;

View File

@ -69,7 +69,6 @@ using ::testing::_;
using ::testing::Invoke;
using ::testing::Matcher;
using ::testing::Return;
using ::testing::DoAll;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::curvefs::common::S3Info;

View File

@ -23,6 +23,7 @@
#ifndef CURVEFS_TEST_MDS_MOCK_MOCK_METASERVER_CLIENT_H_
#define CURVEFS_TEST_MDS_MOCK_MOCK_METASERVER_CLIENT_H_
#include <gmock/gmock-generated-function-mockers.h>
#include <gmock/gmock.h>
#include <set>
#include <string>

View File

@ -36,7 +36,6 @@ using ::testing::_;
using ::testing::AnyOf;
using ::testing::Contains;
using ::testing::SetArgPointee;
using ::testing::DoAll;
using ::curve::common::Configuration;
class TestTopology : public ::testing::Test {

View File

@ -0,0 +1,89 @@
/*
* 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
* Date: Thu Sep 2 14:49:04 CST 2021
* Author: wuhanqing
*/
#include "curvefs/src/metaserver/copyset/apply_queue.h"
#include <gtest/gtest.h>
#include <ctime>
#include "src/common/concurrent/count_down_event.h"
namespace curvefs {
namespace metaserver {
namespace copyset {
using ::curve::common::CountDownEvent;
TEST(ApplyQueueTest, StartAndStopTest) {
ApplyQueue applyQueue;
ApplyQueueOption option;
option.workerCount = 0;
option.queueDepth = 0;
EXPECT_FALSE(applyQueue.Start(option));
option.workerCount = 5;
option.queueDepth = 100 * 100 * 100;
ASSERT_TRUE(applyQueue.Start(option));
EXPECT_TRUE(applyQueue.Start(option));
std::atomic<bool> runned(false);
auto task = [&]() {
runned = true;
};
applyQueue.Push(time(nullptr), task);
while (!runned) {}
applyQueue.Stop();
applyQueue.Stop();
}
TEST(ApplyQueueTest, FlushTest) {
ApplyQueueOption option;
option.workerCount = 10;
option.queueDepth = 100 * 100;
ApplyQueue applyQueue;
ASSERT_TRUE(applyQueue.Start(option));
int taskCount = option.workerCount * option.queueDepth;
std::atomic<int> runned(0);
auto task = [&runned]() { runned.fetch_add(1, std::memory_order_relaxed); };
for (int i = 0; i < taskCount; ++i) {
applyQueue.Push(i, task);
}
applyQueue.Flush();
ASSERT_EQ(taskCount, runned.load(std::memory_order_relaxed));
applyQueue.Stop();
}
} // namespace copyset
} // namespace metaserver
} // namespace curvefs

View File

@ -1,222 +0,0 @@
/*
* Copyright (c) 2023 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: 20230521
* Author: Xinlong-Chen
*/
#include <gtest/gtest.h>
#include <vector>
#include <atomic>
#include <functional>
#include "src/common/timeutility.h"
#include "curvefs/src/metaserver/copyset/concurrent_apply_queue.h"
using curvefs::metaserver::copyset::ApplyQueue;
using curvefs::metaserver::copyset::ApplyOption;
using curvefs::metaserver::copyset::OperatorType;
TEST(ApplyQueue, InitTest) {
ApplyQueue concurrentapply;
{
// 1. init with invalid write-concurrentsize
ApplyOption opt(-1, 1, 1, 1);
ASSERT_FALSE(concurrentapply.Init(opt));
}
{
// 2. init with invalid write-concurrentdepth
ApplyOption opt(1, -1, 1, 1);
ASSERT_FALSE(concurrentapply.Init(opt));
}
{
// 3. init with invalid read-concurrentsize
ApplyOption opt(1, 1, -1, 1);
ASSERT_FALSE(concurrentapply.Init(opt));
}
{
// 4. init with invalid read-concurrentdepth
ApplyOption opt(1, 1, 1, -1);
ASSERT_FALSE(concurrentapply.Init(opt));
}
{
// 5. double init
ApplyOption opt(1, 1, 1, 1);
// init with vaild params
ASSERT_TRUE(concurrentapply.Init(opt));
// re-init
ASSERT_TRUE(concurrentapply.Init(opt));
}
concurrentapply.Stop();
// re-stop
concurrentapply.Stop();
}
static void InitReadWriteTypeList(std::vector<OperatorType> *readTypeList,
std::vector<OperatorType> *writeTypeList) {
*readTypeList = {
OperatorType::GetDentry,
OperatorType::ListDentry,
OperatorType::GetInode,
OperatorType::BatchGetInodeAttr,
OperatorType::BatchGetXAttr,
OperatorType::GetVolumeExtent
};
auto IsRead = [&readTypeList](OperatorType type) -> bool {
for (auto &readType : *readTypeList) {
if (type == readType) {
return true;
}
}
return false;
};
for (uint32_t i = 0; i < static_cast<uint32_t>(OperatorType::OperatorTypeMax); ++i) { // NOLINT
if (!IsRead(static_cast<OperatorType>(i))) {
writeTypeList->push_back(static_cast<OperatorType>(i));
}
}
}
OperatorType get_random_type(const std::vector<OperatorType> &type_list) {
return type_list[rand() % type_list.size()];
}
TEST(ApplyQueue, RunTest) {
std::vector<OperatorType> readTypeList;
std::vector<OperatorType> writeTypeList;
InitReadWriteTypeList(&readTypeList, &writeTypeList);
auto read_type = get_random_type(readTypeList);
auto write_type = get_random_type(writeTypeList);
ApplyQueue concurrentapply;
int testw = 0;
auto wtask = [&testw]() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
testw++;
};
int testr = 0;
auto rtask = [&testr]() {
testr++;
};
// push write and read tasks
ApplyOption opt(1, 1, 1, 1);
ASSERT_TRUE(concurrentapply.Init(opt));
ASSERT_TRUE(concurrentapply.Push(1, read_type, rtask));
ASSERT_TRUE(concurrentapply.Push(1, write_type, wtask));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
ASSERT_EQ(1, testr);
ASSERT_EQ(0, testw);
concurrentapply.Flush();
ASSERT_EQ(1, testw);
concurrentapply.Stop();
}
TEST(ApplyQueue, FlushTest) {
std::vector<OperatorType> readTypeList;
std::vector<OperatorType> writeTypeList;
InitReadWriteTypeList(&readTypeList, &writeTypeList);
ApplyQueue concurrentapply;
ApplyOption opt(2, 5000, 1, 1);
ASSERT_TRUE(concurrentapply.Init(opt));
std::atomic<uint32_t> testnum(0);
auto task = [&testnum]() {
testnum.fetch_add(1);
};
for (int i = 0; i < 5000; i++) {
auto write_type = get_random_type(writeTypeList);
concurrentapply.Push(i, write_type, task);
}
ASSERT_LE(testnum, 5000);
concurrentapply.Flush();
ASSERT_EQ(5000, testnum);
concurrentapply.Stop();
}
TEST(ApplyQueue, ConcurrentTest) {
std::vector<OperatorType> readTypeList;
std::vector<OperatorType> writeTypeList;
InitReadWriteTypeList(&readTypeList, &writeTypeList);
// interval flush when push
std::atomic<bool> stop(false);
std::atomic<uint32_t> testnum(0);
ApplyQueue concurrentapply;
ApplyOption opt(10, 1, 5, 2);
ASSERT_TRUE(concurrentapply.Init(opt));
auto push = [&concurrentapply, &stop, &testnum,
&readTypeList, &writeTypeList]() {
auto task = [&testnum]() {
testnum.fetch_add(1);
};
while (!stop.load()) {
for (int i = 0; i < 10; i++) {
auto read_type = get_random_type(readTypeList);
auto write_type = get_random_type(writeTypeList);
concurrentapply.Push(i, read_type, task);
concurrentapply.Push(i, write_type, task);
}
}
};
auto flush = [&concurrentapply, &stop, &testnum]() {
while (!stop.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
concurrentapply.Flush();
}
};
std::thread t(push);
std::thread f(flush);
while (testnum.load() <= 1000000) {
}
stop.store(true);
std::cout << "thread exit, join" << std::endl;
t.join();
f.join();
concurrentapply.Flush();
ASSERT_GT(testnum, 1000000);
concurrentapply.Stop();
}

View File

@ -111,10 +111,8 @@ TEST_F(CopysetNodeTest, TestInit) {
// apply queue init failed
{
CopysetNodeOptions options = options_;
options.applyQueueOption.wconcurrentsize = 0;
options.applyQueueOption.wqueuedepth = 0;
options.applyQueueOption.rconcurrentsize = 0;
options.applyQueueOption.rqueuedepth = 0;
options.applyQueueOption.queueDepth = 0;
options.applyQueueOption.workerCount = 0;
options.dataUri = "local:///mnt/data";
options.localFileSystem = &mockfs_;

View File

@ -468,17 +468,6 @@ TEST_F(MetaOperatorTest, PropostTest_PropostTaskFailed) {
CopysetNode node(poolId, copysetId, conf, &mockNodeManager_);
curve::fs::MockLocalFileSystem localFs;
CopysetNodeOptions options;
options.dataUri = "local:///mnt/data";
options.localFileSystem = &localFs;
options.storageOptions.type = "memory";
EXPECT_CALL(localFs, Mkdir(_))
.WillOnce(Return(0));
EXPECT_TRUE(node.Init(options));
node.on_leader_start(1);
node.UpdateAppliedIndex(101);

View File

@ -20,6 +20,8 @@
* @Author: chenwei
*/
#include <gmock/gmock-generated-matchers.h>
#include <gmock/gmock-spec-builders.h>
#include <gmock/gmock.h>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>

View File

@ -23,6 +23,7 @@
#ifndef CURVEFS_TEST_METASERVER_MOCK_MOCK_KV_STORAGE_H_
#define CURVEFS_TEST_METASERVER_MOCK_MOCK_KV_STORAGE_H_
#include <gmock/gmock-generated-function-mockers.h>
#include <gmock/gmock.h>
#include <memory>

View File

@ -1,5 +0,0 @@
1. `curvefs.py` and `curvefs_wrap.cxx` are generated by command `swig -c++ -python curvefs.i`.
2. Revert `ListDir` and Delete `Opendir`/`Closedir` functions in `curvefs.py` if you don intend to make changes about these functions.
3. Revert `_wrap_Read`/`_wrap_Listdir`/`_wrap_GetClusterId`/`_wrap_CBDClient_Read`/`_wrap_CBDClient_Listdir` if you don intend to make changes about these functions.
4. :exclamation: C functions in `libcurvefs.h` are not recommended for use anymore.
5. :exclamation: Types in `curve_type.h` are different from `include/client/*.h` even they have the similar name.

View File

@ -26,12 +26,9 @@
#include "src/client/libcurve_file.h"
namespace {
inline curve::client::UserInfo ToCurveClientUserInfo(
const UserInfo_t* userInfo) {
inline curve::client::UserInfo ToCurveClientUserInfo(UserInfo_t* userInfo) {
return curve::client::UserInfo(userInfo->owner, userInfo->password);
}
}
CBDClient::CBDClient() : client_(new curve::client::FileClient()) {}
@ -57,17 +54,10 @@ int CBDClient::Create(const char* filename, UserInfo_t* userInfo, size_t size) {
return client_->Create(filename, ToCurveClientUserInfo(userInfo), size);
}
int CBDClient::Create2(const CreateContext* context) {
curve::client::CreateFileContext internal;
internal.pagefile = true;
internal.name = context->name;
internal.user = ToCurveClientUserInfo(&context->user);
internal.length = context->length;
internal.poolset = context->poolset;
internal.stripeUnit = context->stripeUnit;
internal.stripeCount = context->stripeCount;
return client_->Create2(internal);
int CBDClient::Create2(const char* filename, UserInfo_t* userInfo, size_t size,
uint64_t stripeUnit, uint64_t stripeCount) {
return client_->Create2(filename, ToCurveClientUserInfo(userInfo),
size, stripeUnit, stripeCount);
}
int CBDClient::Unlink(const char* filename, UserInfo_t* userInfo) {
@ -176,7 +166,3 @@ int CBDClient::Rmdir(const char* dirpath, UserInfo_t* userInfo) {
std::string CBDClient::GetClusterId() {
return client_->GetClusterId();
}
std::vector<std::string> CBDClient::ListPoolset() {
return client_->ListPoolset();
}

View File

@ -25,7 +25,6 @@
#include <memory>
#include <string>
#include <vector>
#include "curvefs_python/curve_type.h"
@ -49,7 +48,8 @@ class CBDClient {
int Close(int fd);
int Create(const char* filename, UserInfo_t* userInfo, size_t size);
int Create2(const CreateContext* context);
int Create2(const char* filename, UserInfo_t* userInfo, size_t size,
uint64_t stripeUnit, uint64_t stripeCount);
int Unlink(const char* filename, UserInfo_t* info);
int DeleteForce(const char* filename, UserInfo_t* info);
int Recover(const char* filename, UserInfo_t* info, uint64_t fileId);
@ -76,8 +76,6 @@ class CBDClient {
std::string GetClusterId();
std::vector<std::string> ListPoolset();
private:
std::unique_ptr<curve::client::FileClient> client_;
};

View File

@ -27,8 +27,6 @@
#include <stdint.h>
#include <unistd.h>
#include <string>
#define CURVE_INODE_DIRECTORY 0
#define CURVE_INODE_PAGEFILE 1
#define CURVEINODE_APPENDFILE 2
@ -136,13 +134,4 @@ typedef struct DirInfos {
FileInfo_t* fileinfo;
} DirInfos_t;
struct CreateContext {
std::string name;
size_t length;
UserInfo user;
std::string poolset;
uint64_t stripeUnit;
uint64_t stripeCount;
};
#endif // CURVEFS_PYTHON_CURVE_TYPE_H_

View File

@ -313,48 +313,6 @@ class DirInfos_t(_object):
DirInfos_t_swigregister = _curvefs.DirInfos_t_swigregister
DirInfos_t_swigregister(DirInfos_t)
class CreateContext(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, CreateContext, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, CreateContext, name)
__repr__ = _swig_repr
__swig_setmethods__["name"] = _curvefs.CreateContext_name_set
__swig_getmethods__["name"] = _curvefs.CreateContext_name_get
if _newclass:
name = _swig_property(_curvefs.CreateContext_name_get, _curvefs.CreateContext_name_set)
__swig_setmethods__["length"] = _curvefs.CreateContext_length_set
__swig_getmethods__["length"] = _curvefs.CreateContext_length_get
if _newclass:
length = _swig_property(_curvefs.CreateContext_length_get, _curvefs.CreateContext_length_set)
__swig_setmethods__["user"] = _curvefs.CreateContext_user_set
__swig_getmethods__["user"] = _curvefs.CreateContext_user_get
if _newclass:
user = _swig_property(_curvefs.CreateContext_user_get, _curvefs.CreateContext_user_set)
__swig_setmethods__["poolset"] = _curvefs.CreateContext_poolset_set
__swig_getmethods__["poolset"] = _curvefs.CreateContext_poolset_get
if _newclass:
poolset = _swig_property(_curvefs.CreateContext_poolset_get, _curvefs.CreateContext_poolset_set)
__swig_setmethods__["stripeUnit"] = _curvefs.CreateContext_stripeUnit_set
__swig_getmethods__["stripeUnit"] = _curvefs.CreateContext_stripeUnit_get
if _newclass:
stripeUnit = _swig_property(_curvefs.CreateContext_stripeUnit_get, _curvefs.CreateContext_stripeUnit_set)
__swig_setmethods__["stripeCount"] = _curvefs.CreateContext_stripeCount_set
__swig_getmethods__["stripeCount"] = _curvefs.CreateContext_stripeCount_get
if _newclass:
stripeCount = _swig_property(_curvefs.CreateContext_stripeCount_get, _curvefs.CreateContext_stripeCount_set)
def __init__(self):
this = _curvefs.new_CreateContext()
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _curvefs.delete_CreateContext
__del__ = lambda self: None
CreateContext_swigregister = _curvefs.CreateContext_swigregister
CreateContext_swigregister(CreateContext)
def Init(path):
return _curvefs.Init(path)
@ -416,14 +374,14 @@ def Unlink(filename, info):
return _curvefs.Unlink(filename, info)
Unlink = _curvefs.Unlink
def Recover(filename, info, fileId):
return _curvefs.Recover(filename, info, fileId)
Recover = _curvefs.Recover
def DeleteForce(filename, info):
return _curvefs.DeleteForce(filename, info)
DeleteForce = _curvefs.DeleteForce
def Recover(filename, info, fileId):
return _curvefs.Recover(filename, info, fileId)
Recover = _curvefs.Recover
def Listdir(dirpath, info):
return _curvefs.Listdir(dirpath, info)
Listdir = _curvefs.Listdir
@ -474,8 +432,8 @@ class CBDClient(_object):
def Create(self, filename, userInfo, size):
return _curvefs.CBDClient_Create(self, filename, userInfo, size)
def Create2(self, context):
return _curvefs.CBDClient_Create2(self, context)
def Create2(self, filename, userInfo, size, stripeUnit, stripeCount):
return _curvefs.CBDClient_Create2(self, filename, userInfo, size, stripeUnit, stripeCount)
def Unlink(self, filename, info):
return _curvefs.CBDClient_Unlink(self, filename, info)
@ -521,9 +479,6 @@ class CBDClient(_object):
def GetClusterId(self):
return _curvefs.CBDClient_GetClusterId(self)
def ListPoolset(self):
return _curvefs.CBDClient_ListPoolset(self)
CBDClient_swigregister = _curvefs.CBDClient_swigregister
CBDClient_swigregister(CBDClient)

View File

@ -3022,24 +3022,22 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
#define SWIGTYPE_p_AioContext swig_types[0]
#define SWIGTYPE_p_CBDClient swig_types[1]
#define SWIGTYPE_p_CreateContext swig_types[2]
#define SWIGTYPE_p_DirInfos swig_types[3]
#define SWIGTYPE_p_FileInfo swig_types[4]
#define SWIGTYPE_p_UserInfo swig_types[5]
#define SWIGTYPE_p_char swig_types[6]
#define SWIGTYPE_p_f_p_AioContext__void swig_types[7]
#define SWIGTYPE_p_int swig_types[8]
#define SWIGTYPE_p_long_long swig_types[9]
#define SWIGTYPE_p_short swig_types[10]
#define SWIGTYPE_p_signed_char swig_types[11]
#define SWIGTYPE_p_std__vectorT_std__string_t swig_types[12]
#define SWIGTYPE_p_unsigned_char swig_types[13]
#define SWIGTYPE_p_unsigned_int swig_types[14]
#define SWIGTYPE_p_unsigned_long_long swig_types[15]
#define SWIGTYPE_p_unsigned_short swig_types[16]
#define SWIGTYPE_p_void swig_types[17]
static swig_type_info *swig_types[19];
static swig_module_info swig_module = {swig_types, 18, 0, 0, 0, 0};
#define SWIGTYPE_p_DirInfos swig_types[2]
#define SWIGTYPE_p_FileInfo swig_types[3]
#define SWIGTYPE_p_UserInfo swig_types[4]
#define SWIGTYPE_p_char swig_types[5]
#define SWIGTYPE_p_f_p_AioContext__void swig_types[6]
#define SWIGTYPE_p_int swig_types[7]
#define SWIGTYPE_p_long_long swig_types[8]
#define SWIGTYPE_p_short swig_types[9]
#define SWIGTYPE_p_signed_char swig_types[10]
#define SWIGTYPE_p_unsigned_char swig_types[11]
#define SWIGTYPE_p_unsigned_int swig_types[12]
#define SWIGTYPE_p_unsigned_long_long swig_types[13]
#define SWIGTYPE_p_unsigned_short swig_types[14]
#define SWIGTYPE_p_void swig_types[15]
static swig_type_info *swig_types[17];
static swig_module_info swig_module = {swig_types, 16, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
@ -3617,6 +3615,29 @@ SWIG_From_unsigned_SS_long_SS_long (unsigned long long value)
#endif
SWIGINTERN int
SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val)
{
unsigned long v;
int res = SWIG_AsVal_unsigned_SS_long (obj, &v);
if (SWIG_IsOK(res)) {
if ((v > UINT_MAX)) {
return SWIG_OverflowError;
} else {
if (val) *val = static_cast< unsigned int >(v);
}
}
return res;
}
SWIGINTERNINLINE PyObject*
SWIG_From_unsigned_SS_int (unsigned int value)
{
return PyInt_FromSize_t((size_t) value);
}
@ -3627,44 +3648,6 @@ SWIG_FromCharPtr(const char *cptr)
}
SWIGINTERN int
SWIG_AsPtr_std_string (PyObject * obj, std::string **val)
{
char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
if (buf) {
if (val) *val = new std::string(buf, size - 1);
if (alloc == SWIG_NEWOBJ) delete[] buf;
return SWIG_NEWOBJ;
} else {
if (val) *val = 0;
return SWIG_OLDOBJ;
}
} else {
static int init = 0;
static swig_type_info* descriptor = 0;
if (!init) {
descriptor = SWIG_TypeQuery("std::string" " *");
init = 1;
}
if (descriptor) {
std::string *vptr;
int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
if (SWIG_IsOK(res) && val) *val = vptr;
return res;
}
}
return SWIG_ERROR;
}
SWIGINTERNINLINE PyObject *
SWIG_From_std_string (const std::string& s)
{
return SWIG_FromCharPtrAndSize(s.data(), s.size());
}
SWIGINTERNINLINE int
SWIG_AsVal_size_t (PyObject * obj, size_t *val)
{
@ -3687,18 +3670,9 @@ SWIG_AsVal_size_t (PyObject * obj, size_t *val)
SWIGINTERNINLINE PyObject *
SWIG_From_size_t (size_t value)
{
#ifdef SWIG_LONG_LONG_AVAILABLE
if (sizeof(size_t) <= sizeof(unsigned long)) {
#endif
return SWIG_From_unsigned_SS_long (static_cast< unsigned long >(value));
#ifdef SWIG_LONG_LONG_AVAILABLE
} else {
/* assume sizeof(size_t) <= sizeof(unsigned long long) */
return SWIG_From_unsigned_SS_long_SS_long (static_cast< unsigned long long >(value));
}
#endif
SWIG_From_std_string (const std::string& s)
{
return SWIG_FromCharPtrAndSize(s.data(), s.size());
}
#ifdef __cplusplus
@ -4628,11 +4602,11 @@ SWIGINTERN PyObject *_wrap_FileInfo_t_fileStatus_get(PyObject *SWIGUNUSEDPARM(se
int res1 = 0 ;
PyObject * obj0 = 0 ;
int result;
if (!PyArg_ParseTuple(args,(char *)"O:FileInfo_t_fileStatus_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FileInfo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_fileStatus_get" "', argument " "1"" of type '" "FileInfo *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_fileStatus_get" "', argument " "1"" of type '" "FileInfo *""'");
}
arg1 = reinterpret_cast< FileInfo * >(argp1);
result = (int) ((arg1)->fileStatus);
@ -4646,25 +4620,25 @@ fail:
SWIGINTERN PyObject *_wrap_FileInfo_t_stripeUnit_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
FileInfo *arg1 = (FileInfo *) 0 ;
uint64_t arg2 ;
uint32_t arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
unsigned long long val2 ;
unsigned int val2 ;
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:FileInfo_t_stripeUnit_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FileInfo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeUnit_set" "', argument " "1"" of type '" "FileInfo *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeUnit_set" "', argument " "1"" of type '" "FileInfo *""'");
}
arg1 = reinterpret_cast< FileInfo * >(argp1);
ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2);
ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FileInfo_t_stripeUnit_set" "', argument " "2"" of type '" "uint64_t""'");
}
arg2 = static_cast< uint64_t >(val2);
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FileInfo_t_stripeUnit_set" "', argument " "2"" of type '" "uint32_t""'");
}
arg2 = static_cast< uint32_t >(val2);
if (arg1) (arg1)->stripeUnit = arg2;
resultobj = SWIG_Py_Void();
return resultobj;
@ -4679,16 +4653,16 @@ SWIGINTERN PyObject *_wrap_FileInfo_t_stripeUnit_get(PyObject *SWIGUNUSEDPARM(se
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
uint64_t result;
uint32_t result;
if (!PyArg_ParseTuple(args,(char *)"O:FileInfo_t_stripeUnit_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FileInfo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeUnit_get" "', argument " "1"" of type '" "FileInfo *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeUnit_get" "', argument " "1"" of type '" "FileInfo *""'");
}
arg1 = reinterpret_cast< FileInfo * >(argp1);
result = (uint64_t) ((arg1)->stripeUnit);
resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result));
resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
return resultobj;
fail:
return NULL;
@ -4698,25 +4672,25 @@ fail:
SWIGINTERN PyObject *_wrap_FileInfo_t_stripeCount_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
FileInfo *arg1 = (FileInfo *) 0 ;
uint64_t arg2 ;
uint32_t arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
unsigned long long val2 ;
unsigned int val2 ;
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:FileInfo_t_stripeCount_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FileInfo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeCount_set" "', argument " "1"" of type '" "FileInfo *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeCount_set" "', argument " "1"" of type '" "FileInfo *""'");
}
arg1 = reinterpret_cast< FileInfo * >(argp1);
ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2);
ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FileInfo_t_stripeCount_set" "', argument " "2"" of type '" "uint64_t""'");
}
arg2 = static_cast< uint64_t >(val2);
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FileInfo_t_stripeCount_set" "', argument " "2"" of type '" "uint32_t""'");
}
arg2 = static_cast< uint32_t >(val2);
if (arg1) (arg1)->stripeCount = arg2;
resultobj = SWIG_Py_Void();
return resultobj;
@ -4731,16 +4705,16 @@ SWIGINTERN PyObject *_wrap_FileInfo_t_stripeCount_get(PyObject *SWIGUNUSEDPARM(s
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
uint64_t result;
uint32_t result;
if (!PyArg_ParseTuple(args,(char *)"O:FileInfo_t_stripeCount_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FileInfo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeCount_get" "', argument " "1"" of type '" "FileInfo *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FileInfo_t_stripeCount_get" "', argument " "1"" of type '" "FileInfo *""'");
}
arg1 = reinterpret_cast< FileInfo * >(argp1);
result = (uint64_t) ((arg1)->stripeCount);
resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result));
resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
return resultobj;
fail:
return NULL;
@ -5046,373 +5020,6 @@ SWIGINTERN PyObject *DirInfos_t_swigregister(PyObject *SWIGUNUSEDPARM(self), PyO
return SWIG_Py_Void();
}
SWIGINTERN PyObject *_wrap_CreateContext_name_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
std::string *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 = SWIG_OLDOBJ ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_name_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_name_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
{
std::string *ptr = (std::string *)0;
res2 = SWIG_AsPtr_std_string(obj1, &ptr);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CreateContext_name_set" "', argument " "2"" of type '" "std::string const &""'");
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CreateContext_name_set" "', argument " "2"" of type '" "std::string const &""'");
}
arg2 = ptr;
}
if (arg1) (arg1)->name = *arg2;
resultobj = SWIG_Py_Void();
if (SWIG_IsNewObj(res2)) delete arg2;
return resultobj;
fail:
if (SWIG_IsNewObj(res2)) delete arg2;
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
std::string *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_name_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_name_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = (std::string *) & ((arg1)->name);
resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_length_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
size_t arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
size_t val2 ;
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_length_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_length_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
ecode2 = SWIG_AsVal_size_t(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CreateContext_length_set" "', argument " "2"" of type '" "size_t""'");
}
arg2 = static_cast< size_t >(val2);
if (arg1) (arg1)->length = arg2;
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_length_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
size_t result;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_length_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_length_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = ((arg1)->length);
resultobj = SWIG_From_size_t(static_cast< size_t >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_user_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
UserInfo *arg2 = (UserInfo *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_user_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_user_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_UserInfo, 0 | 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CreateContext_user_set" "', argument " "2"" of type '" "UserInfo *""'");
}
arg2 = reinterpret_cast< UserInfo * >(argp2);
if (arg1) (arg1)->user = *arg2;
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_user_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
UserInfo *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_user_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_user_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = (UserInfo *)& ((arg1)->user);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_UserInfo, 0 | 0 );
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_poolset_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
std::string *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 = SWIG_OLDOBJ ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_poolset_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_poolset_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
{
std::string *ptr = (std::string *)0;
res2 = SWIG_AsPtr_std_string(obj1, &ptr);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CreateContext_poolset_set" "', argument " "2"" of type '" "std::string const &""'");
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CreateContext_poolset_set" "', argument " "2"" of type '" "std::string const &""'");
}
arg2 = ptr;
}
if (arg1) (arg1)->poolset = *arg2;
resultobj = SWIG_Py_Void();
if (SWIG_IsNewObj(res2)) delete arg2;
return resultobj;
fail:
if (SWIG_IsNewObj(res2)) delete arg2;
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_poolset_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
std::string *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_poolset_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_poolset_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = (std::string *) & ((arg1)->poolset);
resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_stripeUnit_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
uint64_t arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
unsigned long long val2 ;
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_stripeUnit_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_stripeUnit_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CreateContext_stripeUnit_set" "', argument " "2"" of type '" "uint64_t""'");
}
arg2 = static_cast< uint64_t >(val2);
if (arg1) (arg1)->stripeUnit = arg2;
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_stripeUnit_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
uint64_t result;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_stripeUnit_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_stripeUnit_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = (uint64_t) ((arg1)->stripeUnit);
resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_stripeCount_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
uint64_t arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
unsigned long long val2 ;
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:CreateContext_stripeCount_set",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_stripeCount_set" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CreateContext_stripeCount_set" "', argument " "2"" of type '" "uint64_t""'");
}
arg2 = static_cast< uint64_t >(val2);
if (arg1) (arg1)->stripeCount = arg2;
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CreateContext_stripeCount_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
uint64_t result;
if (!PyArg_ParseTuple(args,(char *)"O:CreateContext_stripeCount_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CreateContext_stripeCount_get" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
result = (uint64_t) ((arg1)->stripeCount);
resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_new_CreateContext(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)":new_CreateContext")) SWIG_fail;
result = (CreateContext *)new CreateContext();
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CreateContext, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_delete_CreateContext(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CreateContext *arg1 = (CreateContext *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:delete_CreateContext",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CreateContext, SWIG_POINTER_DISOWN | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_CreateContext" "', argument " "1"" of type '" "CreateContext *""'");
}
arg1 = reinterpret_cast< CreateContext * >(argp1);
delete arg1;
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *CreateContext_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *obj;
if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
SWIG_TypeNewClientData(SWIGTYPE_p_CreateContext, SWIG_NewClientData(obj));
return SWIG_Py_Void();
}
SWIGINTERN PyObject *_wrap_Init(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
@ -5999,7 +5606,7 @@ SWIGINTERN PyObject *_wrap_Recover(PyObject *SWIGUNUSEDPARM(self), PyObject *arg
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
int result;
if (!PyArg_ParseTuple(args,(char *)"OOO:Recover",&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
if (!SWIG_IsOK(res1)) {
@ -6008,13 +5615,13 @@ SWIGINTERN PyObject *_wrap_Recover(PyObject *SWIGUNUSEDPARM(self), PyObject *arg
arg1 = reinterpret_cast< char * >(buf1);
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_UserInfo, 0 | 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Recover" "', argument " "2"" of type '" "UserInfo_t *""'");
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Recover" "', argument " "2"" of type '" "UserInfo_t *""'");
}
arg2 = reinterpret_cast< UserInfo_t * >(argp2);
ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(obj2, &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Recover" "', argument " "3"" of type '" "uint64_t""'");
}
}
arg3 = static_cast< uint64_t >(val3);
result = (int)Recover((char const *)arg1,arg2,arg3);
resultobj = SWIG_From_int(static_cast< int >(result));
@ -6403,7 +6010,7 @@ SWIGINTERN PyObject *_wrap_CBDClient_Open(PyObject *SWIGUNUSEDPARM(self), PyObje
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
int result;
if (!PyArg_ParseTuple(args,(char *)"OOO:CBDClient_Open",&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CBDClient, 0 | 0 );
if (!SWIG_IsOK(res1)) {
@ -6501,7 +6108,7 @@ SWIGINTERN PyObject *_wrap_CBDClient_Create(PyObject *SWIGUNUSEDPARM(self), PyOb
ecode4 = SWIG_AsVal_size_t(obj3, &val4);
if (!SWIG_IsOK(ecode4)) {
SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "CBDClient_Create" "', argument " "4"" of type '" "size_t""'");
}
}
arg4 = static_cast< size_t >(val4);
result = (int)(arg1)->Create((char const *)arg2,arg3,arg4);
resultobj = SWIG_From_int(static_cast< int >(result));
@ -6516,30 +6123,69 @@ fail:
SWIGINTERN PyObject *_wrap_CBDClient_Create2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CBDClient *arg1 = (CBDClient *) 0 ;
CreateContext *arg2 = (CreateContext *) 0 ;
char *arg2 = (char *) 0 ;
UserInfo_t *arg3 = (UserInfo_t *) 0 ;
size_t arg4 ;
uint32_t arg5 ;
uint32_t arg6 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
void *argp3 = 0 ;
int res3 = 0 ;
size_t val4 ;
int ecode4 = 0 ;
unsigned int val5 ;
int ecode5 = 0 ;
unsigned int val6 ;
int ecode6 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
PyObject * obj3 = 0 ;
PyObject * obj4 = 0 ;
PyObject * obj5 = 0 ;
int result;
if (!PyArg_ParseTuple(args,(char *)"OO:CBDClient_Create2",&obj0,&obj1)) SWIG_fail;
if (!PyArg_ParseTuple(args,(char *)"OOOOOO:CBDClient_Create2",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CBDClient, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CBDClient_Create2" "', argument " "1"" of type '" "CBDClient *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CBDClient_Create2" "', argument " "1"" of type '" "CBDClient *""'");
}
arg1 = reinterpret_cast< CBDClient * >(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_CreateContext, 0 | 0 );
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CBDClient_Create2" "', argument " "2"" of type '" "CreateContext const *""'");
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CBDClient_Create2" "', argument " "2"" of type '" "char const *""'");
}
arg2 = reinterpret_cast< CreateContext * >(argp2);
result = (int)(arg1)->Create2((CreateContext const *)arg2);
arg2 = reinterpret_cast< char * >(buf2);
res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_UserInfo, 0 | 0 );
if (!SWIG_IsOK(res3)) {
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CBDClient_Create2" "', argument " "3"" of type '" "UserInfo_t *""'");
}
arg3 = reinterpret_cast< UserInfo_t * >(argp3);
ecode4 = SWIG_AsVal_size_t(obj3, &val4);
if (!SWIG_IsOK(ecode4)) {
SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "CBDClient_Create2" "', argument " "4"" of type '" "size_t""'");
}
arg4 = static_cast< size_t >(val4);
ecode5 = SWIG_AsVal_unsigned_SS_int(obj4, &val5);
if (!SWIG_IsOK(ecode5)) {
SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "CBDClient_Create2" "', argument " "5"" of type '" "uint32_t""'");
}
arg5 = static_cast< uint32_t >(val5);
ecode6 = SWIG_AsVal_unsigned_SS_int(obj5, &val6);
if (!SWIG_IsOK(ecode6)) {
SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "CBDClient_Create2" "', argument " "6"" of type '" "uint32_t""'");
}
arg6 = static_cast< uint32_t >(val6);
result = (int)(arg1)->Create2((char const *)arg2,arg3,arg4,arg5,arg6);
resultobj = SWIG_From_int(static_cast< int >(result));
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
return resultobj;
fail:
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
return NULL;
}
@ -6629,7 +6275,6 @@ fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CBDClient_Recover(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CBDClient *arg1 = (CBDClient *) 0 ;
@ -6650,11 +6295,11 @@ SWIGINTERN PyObject *_wrap_CBDClient_Recover(PyObject *SWIGUNUSEDPARM(self), PyO
PyObject * obj2 = 0 ;
PyObject * obj3 = 0 ;
int result;
if (!PyArg_ParseTuple(args,(char *)"OOOO:CBDClient_Recover",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CBDClient, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CBDClient_Recover" "', argument " "1"" of type '" "CBDClient *""'");
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CBDClient_Recover" "', argument " "1"" of type '" "CBDClient *""'");
}
arg1 = reinterpret_cast< CBDClient * >(argp1);
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
@ -6664,13 +6309,13 @@ SWIGINTERN PyObject *_wrap_CBDClient_Recover(PyObject *SWIGUNUSEDPARM(self), PyO
arg2 = reinterpret_cast< char * >(buf2);
res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_UserInfo, 0 | 0 );
if (!SWIG_IsOK(res3)) {
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CBDClient_Recover" "', argument " "3"" of type '" "UserInfo_t *""'");
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CBDClient_Recover" "', argument " "3"" of type '" "UserInfo_t *""'");
}
arg3 = reinterpret_cast< UserInfo_t * >(argp3);
ecode4 = SWIG_AsVal_unsigned_SS_long_SS_long(obj3, &val4);
if (!SWIG_IsOK(ecode4)) {
SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "CBDClient_Recover" "', argument " "4"" of type '" "uint64_t""'");
}
}
arg4 = static_cast< uint64_t >(val4);
result = (int)(arg1)->Recover((char const *)arg2,arg3,arg4);
resultobj = SWIG_From_int(static_cast< int >(result));
@ -6681,7 +6326,6 @@ fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_CBDClient_Rename(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CBDClient *arg1 = (CBDClient *) 0 ;
@ -7361,34 +7005,6 @@ fail:
}
SWIGINTERN PyObject *_wrap_CBDClient_ListPoolset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CBDClient *arg1 = (CBDClient *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
std::vector< std::string > result;
if (!PyArg_ParseTuple(args,(char *)"O:CBDClient_ListPoolset",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CBDClient, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CBDClient_ListPoolset" "', argument " "1"" of type '" "CBDClient *""'");
}
arg1 = reinterpret_cast< CBDClient * >(argp1);
result = (arg1)->ListPoolset();
resultobj = PyList_New(result.size());
if (resultobj == nullptr) {
SWIG_exception_fail(-1, "memory alloc failed");
}
for (size_t i = 0; i < result.size(); ++i) {
PyList_SetItem(resultobj, i, SWIG_From_std_string(result[i]));
}
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *CBDClient_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *obj;
if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
@ -7454,21 +7070,6 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"new_DirInfos_t", _wrap_new_DirInfos_t, METH_VARARGS, NULL},
{ (char *)"delete_DirInfos_t", _wrap_delete_DirInfos_t, METH_VARARGS, NULL},
{ (char *)"DirInfos_t_swigregister", DirInfos_t_swigregister, METH_VARARGS, NULL},
{ (char *)"CreateContext_name_set", _wrap_CreateContext_name_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_name_get", _wrap_CreateContext_name_get, METH_VARARGS, NULL},
{ (char *)"CreateContext_length_set", _wrap_CreateContext_length_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_length_get", _wrap_CreateContext_length_get, METH_VARARGS, NULL},
{ (char *)"CreateContext_user_set", _wrap_CreateContext_user_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_user_get", _wrap_CreateContext_user_get, METH_VARARGS, NULL},
{ (char *)"CreateContext_poolset_set", _wrap_CreateContext_poolset_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_poolset_get", _wrap_CreateContext_poolset_get, METH_VARARGS, NULL},
{ (char *)"CreateContext_stripeUnit_set", _wrap_CreateContext_stripeUnit_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_stripeUnit_get", _wrap_CreateContext_stripeUnit_get, METH_VARARGS, NULL},
{ (char *)"CreateContext_stripeCount_set", _wrap_CreateContext_stripeCount_set, METH_VARARGS, NULL},
{ (char *)"CreateContext_stripeCount_get", _wrap_CreateContext_stripeCount_get, METH_VARARGS, NULL},
{ (char *)"new_CreateContext", _wrap_new_CreateContext, METH_VARARGS, NULL},
{ (char *)"delete_CreateContext", _wrap_delete_CreateContext, METH_VARARGS, NULL},
{ (char *)"CreateContext_swigregister", CreateContext_swigregister, METH_VARARGS, NULL},
{ (char *)"Init", _wrap_Init, METH_VARARGS, NULL},
{ (char *)"Open4Qemu", _wrap_Open4Qemu, METH_VARARGS, NULL},
{ (char *)"Open", _wrap_Open, METH_VARARGS, NULL},
@ -7484,8 +7085,8 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"Rename", _wrap_Rename, METH_VARARGS, NULL},
{ (char *)"Extend", _wrap_Extend, METH_VARARGS, NULL},
{ (char *)"Unlink", _wrap_Unlink, METH_VARARGS, NULL},
{ (char *)"Recover", _wrap_Recover, METH_VARARGS, NULL},
{ (char *)"DeleteForce", _wrap_DeleteForce, METH_VARARGS, NULL},
{ (char *)"Recover", _wrap_Recover, METH_VARARGS, NULL},
{ (char *)"OpenDir", _wrap_OpenDir, METH_VARARGS, NULL},
{ (char *)"CloseDir", _wrap_CloseDir, METH_VARARGS, NULL},
{ (char *)"Listdir", _wrap_Listdir, METH_VARARGS, NULL},
@ -7518,7 +7119,6 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"CBDClient_Mkdir", _wrap_CBDClient_Mkdir, METH_VARARGS, NULL},
{ (char *)"CBDClient_Rmdir", _wrap_CBDClient_Rmdir, METH_VARARGS, NULL},
{ (char *)"CBDClient_GetClusterId", _wrap_CBDClient_GetClusterId, METH_VARARGS, NULL},
{ (char *)"CBDClient_ListPoolset", _wrap_CBDClient_ListPoolset, METH_VARARGS, NULL},
{ (char *)"CBDClient_swigregister", CBDClient_swigregister, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL }
};
@ -7528,7 +7128,6 @@ static PyMethodDef SwigMethods[] = {
static swig_type_info _swigt__p_AioContext = {"_p_AioContext", "AioContext *|AioContext_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_CBDClient = {"_p_CBDClient", "CBDClient *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_CreateContext = {"_p_CreateContext", "CreateContext *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_DirInfos = {"_p_DirInfos", "DirInfos_t *|DirInfos *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_FileInfo = {"_p_FileInfo", "FileInfo *|FileInfo_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_UserInfo = {"_p_UserInfo", "UserInfo *|UserInfo_t *", 0, 0, (void*)0, 0};
@ -7538,7 +7137,6 @@ static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t
static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_std__vectorT_std__string_t = {"_p_std__vectorT_std__string_t", "std::vector< std::string > *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0};
@ -7548,7 +7146,6 @@ static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
static swig_type_info *swig_type_initial[] = {
&_swigt__p_AioContext,
&_swigt__p_CBDClient,
&_swigt__p_CreateContext,
&_swigt__p_DirInfos,
&_swigt__p_FileInfo,
&_swigt__p_UserInfo,
@ -7558,7 +7155,6 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_long_long,
&_swigt__p_short,
&_swigt__p_signed_char,
&_swigt__p_std__vectorT_std__string_t,
&_swigt__p_unsigned_char,
&_swigt__p_unsigned_int,
&_swigt__p_unsigned_long_long,
@ -7568,7 +7164,6 @@ static swig_type_info *swig_type_initial[] = {
static swig_cast_info _swigc__p_AioContext[] = { {&_swigt__p_AioContext, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_CBDClient[] = { {&_swigt__p_CBDClient, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_CreateContext[] = { {&_swigt__p_CreateContext, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_DirInfos[] = { {&_swigt__p_DirInfos, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_FileInfo[] = { {&_swigt__p_FileInfo, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_UserInfo[] = { {&_swigt__p_UserInfo, 0, 0, 0},{0, 0, 0, 0}};
@ -7578,7 +7173,6 @@ static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0
static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_std__vectorT_std__string_t[] = { {&_swigt__p_std__vectorT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}};
@ -7588,7 +7182,6 @@ static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0,
static swig_cast_info *swig_cast_initial[] = {
_swigc__p_AioContext,
_swigc__p_CBDClient,
_swigc__p_CreateContext,
_swigc__p_DirInfos,
_swigc__p_FileInfo,
_swigc__p_UserInfo,
@ -7598,7 +7191,6 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_long_long,
_swigc__p_short,
_swigc__p_signed_char,
_swigc__p_std__vectorT_std__string_t,
_swigc__p_unsigned_char,
_swigc__p_unsigned_int,
_swigc__p_unsigned_long_long,

View File

@ -26,9 +26,10 @@ 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
global.min_io_alignment=512
#
# MDS settings
#
@ -81,7 +82,7 @@ copyset.scan_rpc_timeout_ms=1000
copyset.scan_rpc_retry_times=3
copyset.scan_rpc_retry_interval_us=100000
# enable O_DSYNC when open chunkfile
copyset.enable_odsync_when_open_chunkfile=true
copyset.enable_odsync_when_open_chunkfile=false
# sync timer timeout interval
copyset.synctimer_interval_ms=30000
# check syncing interval

View File

@ -26,9 +26,10 @@ 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
global.min_io_alignment=512
#
# MDS settings
#
@ -81,7 +82,7 @@ copyset.scan_rpc_timeout_ms=1000
copyset.scan_rpc_retry_times=3
copyset.scan_rpc_retry_interval_us=100000
# enable O_DSYNC when open chunkfile
copyset.enable_odsync_when_open_chunkfile=true
copyset.enable_odsync_when_open_chunkfile=false
# sync timer timeout interval
copyset.synctimer_interval_ms=30000
# check syncing interval

View File

@ -26,9 +26,10 @@ 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
global.min_io_alignment=512
#
# MDS settings
#
@ -81,7 +82,7 @@ copyset.scan_rpc_timeout_ms=1000
copyset.scan_rpc_retry_times=3
copyset.scan_rpc_retry_interval_us=100000
# enable O_DSYNC when open chunkfile
copyset.enable_odsync_when_open_chunkfile=true
copyset.enable_odsync_when_open_chunkfile=false
# sync timer timeout interval
copyset.synctimer_interval_ms=30000
# check syncing interval

View File

@ -1,7 +1,9 @@
FROM opencurvedocker/curve-base:debian9
COPY --from=opencurvedocker/curve-base:curve-tgt-debian9 /curve-tgt/ /curve-tgt/
COPY --from=opencurvedocker/curve-base:curve-tgt-debian9 /curve/curve-sdk /curve-tgt/curve-sdk
RUN cd /curve-tgt/curve-sdk \
RUN apt update \
&& apt install -y kmod \
&& cd /curve-tgt/curve-sdk \
&& cp -f lib/* /usr/lib \
&& cp -f bin/* /usr/bin \
&& mkdir -p /usr/curvefs \

View File

@ -23,24 +23,23 @@
1. 从Turtle派生一个类MockTurtle。
2. 使用Turtle的虚函数计算它有多少参数。
3. 在子类的public部分使用 `MOCK_METHOD` 创建 mock 函数
3. 在子类的public部分写MOCK_METHODn; 或MOCK_CONST_METHODn;如果你是一个const方法其中n是参数的数量;如果你计数错误,产生一个一个编译器错误。
4. 使用函数名作为宏的第一个参数,第二个参数是函数的类型。
例:
```cpp
#include "gmock/gmock.h" // Brings in Google Mock.
class MockTurtle : public Turtle {
public:
// ...
MOCK_METHOD(void, PenUp, (), (override));
MOCK_METHOD(void, PenDown, (), (override));
MOCK_METHOD(void, Forward, (int), (override));
MOCK_METHOD(void, Turn, (int), (override));
MOCK_METHOD(void, GoTo, (int, int), (override));
MOCK_METHOD(int, GetX, (), (const, override));
MOCK_METHOD(int, GetY, (), (const, override));
};
```
#include "gmock/gmock.h" // Brings in Google Mock.
class MockTurtle : public Turtle {
public:
...
MOCK_METHOD0(PenUp, void());
MOCK_METHOD0(PenDown, void());
MOCK_METHOD1(Forward, void(int distance));
MOCK_METHOD1(Turn, void(int degrees));
MOCK_METHOD2(GoTo, void(int x, int y));
MOCK_CONST_METHOD0(GetX, int());
MOCK_CONST_METHOD0(GetY, int());
};
### 在测试中使用mock类

View File

@ -18,7 +18,7 @@ load("//:copts.bzl", "CURVE_DEFAULT_COPTS")
cc_library(
name = "include-common",
hdrs = ["curve_compiler_specific.h"],
srcs = ["curve_compiler_specific.h"],
copts = CURVE_DEFAULT_COPTS,
visibility = ["//visibility:public"],
)

View File

@ -123,12 +123,6 @@ inline std::string ToGroupIdString(const LogicPoolID &logicPoolId,
}
#define ToGroupIdStr ToGroupIdString
// Meta page is header of chunkfile, and is used to store meta data of
// chunkfile.
// Currently, we need to ensure the atomicity of the meta page update, so set
// its size to 4k.
constexpr size_t kChunkfileMetaPageSize = 4096;
} // namespace chunkserver
} // namespace curve

View File

@ -54,7 +54,6 @@ typedef struct FileStatInfo {
int fileStatus;
uint64_t stripeUnit;
uint64_t stripeCount;
uint32_t blocksize;
} FileStatInfo_t;
// 存储用户信息
@ -127,6 +126,20 @@ int Create(const char* filename,
const C_UserInfo_t* userinfo,
size_t size);
/**
* create file with stripe
* @param: filename file name
* @param: userinfo user info
* @param: size file size
* @param: stripeUnit block in stripe size
* @param: stripeCount stripe count in one stripe
*
* @return: success return 0, fail return less than 0
*/
int Create2(const char* filename,
const C_UserInfo_t* userinfo,
size_t size, uint64_t stripeUnit, uint64_t stripeCount);
/**
*
* @param: fd为当前open返回的文件描述符
@ -369,7 +382,6 @@ inline bool operator==(const UserInfo& lhs, const UserInfo& rhs) {
struct OpenFlags {
bool exclusive;
std::string confPath;
OpenFlags() : exclusive(true) {}
};
@ -436,10 +448,10 @@ class CurveClient {
/**
*
* @param fd fd
* @param filename _用户名_
* @return
*/
virtual int64_t StatFile(int fd, FileStatInfo* fileStat);
virtual int64_t StatFile(const std::string& filename);
/**
*

View File

@ -63,7 +63,7 @@ enum LIBCURVE_ERROR {
// parameter error
PARAM_ERROR = 16,
// internal error
INTERNAL_ERROR = 17,
INTERNAL_ERROR = 17,
// CRC error
CRC_ERROR = 18,
// parameter invalid

View File

@ -26,13 +26,20 @@
#define CURVE_CACHELINE_SIZE 64
#define CURVE_CACHELINE_ALIGNMENT alignas(CURVE_CACHELINE_SIZE)
#if defined(__GNUC__) || defined(__clang__)
#if defined(COMPILER_GCC)
#if defined(__cplusplus)
#define CURVE_LIKELY(expr) \
(__builtin_expect(static_cast<bool>(expr), true))
#define CURVE_UNLIKELY(expr) \
(__builtin_expect(static_cast<bool>(expr), false))
#else
#define CURVE_LIKELY(expr) (__builtin_expect(!!(expr), 1))
#define CURVE_UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
#endif
#else
#define CURVE_LIKELY(expr) (expr)
#define CURVE_UNLIKELY(expr) (expr)
#endif // defined(__GNUC__) || defined(__clang__)
#endif // defined(COMPILER_GCC)
#ifdef UNIT_TEST
#define CURVE_MOCK virtual
@ -48,6 +55,4 @@
#define FALLTHROUGH_INTENDED ((void)0)
#endif /* __GNUC__ >= 7 */
#define CURVE_UNUSED __attribute__((__unused__))
#endif // INCLUDE_CURVE_COMPILER_SPECIFIC_H_

View File

@ -108,13 +108,13 @@ function build_curvefs_python() {
rm -rf ./bazel-bin/curvefs_python
if [ "$1" = "release" ]; then
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --copt -O2 \
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --copt -O2 -s \
--define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google \
--copt -Wno-error=format-security --copt -DUSE_BTHREAD_MUTEX --linkopt \
-L${dir}/curvefs_python/tmplib/ --copt -DCURVEVERSION=${curve_version} \
${bazelflags}
else
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --compilation_mode=dbg \
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --compilation_mode=dbg -s \
--define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google \
--copt -Wno-error=format-security --copt -DUSE_BTHREAD_MUTEX --linkopt \
-L${dir}/curvefs_python/tmplib/ --copt -DCURVEVERSION=${curve_version} \
@ -189,7 +189,7 @@ if [ "$1" = "debug" ]; then
exit
fi
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --compilation_mode=dbg \
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --compilation_mode=dbg -s \
--define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google \
--copt \
-Wno-error=format-security --copt -DUSE_BTHREAD_MUTEX --linkopt \
@ -211,7 +211,7 @@ else
exit
fi
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --copt -O2 \
bazel build curvefs_python:curvefs --copt -DHAVE_ZLIB=1 --copt -O2 -s \
--define=with_glog=true --define=libunwind=true --copt -DGFLAGS_NS=google \
--copt \
-Wno-error=format-security --copt -DUSE_BTHREAD_MUTEX --linkopt \

2
nbd

@ -1 +1 @@
Subproject commit 631784c37f929727916a325737543de6a3ceff47
Subproject commit 6231d3bc4954a5f2427148475cf39a2fdc4e3bad

View File

@ -98,7 +98,6 @@ message FileInfo {
required uint64 size = 1;
required uint64 objSize = 2;
required uint64 objNums = 3;
optional uint32 blocksize = 4;
}
message GetInfoRequest {

View File

@ -118,10 +118,6 @@ 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);
}

View File

@ -159,8 +159,6 @@ int nebd_lib_sync(int fd);
*/
int64_t nebd_lib_filesize(int fd);
int64_t nebd_lib_blocksize(int fd);
/**
* @brief resize文件
* @param fdfd

View File

@ -51,10 +51,6 @@ 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);
}

View File

@ -62,9 +62,6 @@ int Extend4Nebd(int fd, int64_t newsize);
* @return size
*/
int64_t GetFileSize4Nebd(int fd);
int64_t GetBlockSize4Nebd(int fd);
/**
* @brief discard文件
* @param fdfd

View File

@ -320,44 +320,6 @@ 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_);

View File

@ -100,8 +100,6 @@ class NebdClient {
*/
int64_t GetFileSize(int fd);
int64_t GetBlockSize(int fd);
/**
* @brief discard文件
* @param fdfd

View File

@ -71,6 +71,4 @@ struct HeartbeatOption {
int64_t rpcTimeoutMs;
};
constexpr uint32_t kDefaultBlockSize = 4096;
#endif // NEBD_SRC_PART1_NEBD_COMMON_H_

View File

@ -105,8 +105,6 @@ struct NebdFileInfo {
uint64_t obj_size;
// object数量
uint64_t num_objs;
// block size
uint32_t block_size;
};
using ExtendAttribute = std::map<std::string, std::string>;

View File

@ -298,7 +298,6 @@ 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);
}

View File

@ -34,54 +34,50 @@ using ::curve::client::UserInfo_t;
const char* kSessionAttrKey = "session";
const char* kOpenFlagsAttrKey = "openflags";
curve::client::OpenFlags ConverToCurveOpenFlags(
const OpenFlags* flags, const std::string& confPath) {
curve::client::OpenFlags ConverToCurveOpenFlags(const OpenFlags* flags) {
curve::client::OpenFlags curveflags;
curveflags.confPath = confPath;
if (!flags) {
return curveflags;
} else {
if (flags->has_exclusive()) {
curveflags.exclusive = flags->exclusive();
}
return curveflags;
}
}
std::pair<std::string, std::string>
FileNameParser::Parse(const std::string& fileName) {
std::string confPath;
std::string FileNameParser::Parse(const std::string& fileName) {
auto beginPos = fileName.find_first_of("/");
if (beginPos == std::string::npos) {
LOG(ERROR) << "error format fileName: " << fileName;
return std::make_pair("", "");
return "";
}
beginPos += 1;
auto endPos = fileName.find_last_of(":");
if (endPos == std::string::npos) {
LOG(ERROR) << "error format fileName: " << fileName;
return std::make_pair("", "");
return "";
}
if (endPos < beginPos) {
endPos = fileName.length();
} else if (endPos < fileName.length() - 1) {
confPath = fileName.substr(endPos + 1);
}
if (beginPos >= endPos) {
LOG(ERROR) << "error format fileName: " << fileName;
return std::make_pair("", "");
return "";
}
auto length = endPos - beginPos;
if (length <= 2) {
LOG(ERROR) << "error format fileName: " << fileName;
return std::make_pair("", "");
return "";
}
return std::make_pair(fileName.substr(beginPos, length), confPath);
return fileName.substr(beginPos, length);
}
void CurveRequestExecutor::Init(const std::shared_ptr<CurveClient> &client) {
@ -90,19 +86,17 @@ void CurveRequestExecutor::Init(const std::shared_ptr<CurveClient> &client) {
std::shared_ptr<NebdFileInstance> CurveRequestExecutor::Open(
const std::string& filename, const OpenFlags* openFlags) {
auto curveFileInfo = FileNameParser::Parse(filename);
if (curveFileInfo.first.empty()) {
std::string curveFileName = FileNameParser::Parse(filename);
if (curveFileName.empty()) {
return nullptr;
}
int fd = client_->Open(
curveFileInfo.first,
ConverToCurveOpenFlags(openFlags, curveFileInfo.second));
int fd = client_->Open(curveFileName, ConverToCurveOpenFlags(openFlags));
if (fd >= 0) {
auto curveFileInstance = std::make_shared<CurveFileInstance>();
curveFileInstance->fd = fd;
curveFileInstance->fileName = curveFileInfo.first;
curveFileInstance->fileName = curveFileName;
curveFileInstance->xattr[kSessionAttrKey] = "";
if (openFlags) {
@ -119,8 +113,8 @@ std::shared_ptr<NebdFileInstance> CurveRequestExecutor::Open(
std::shared_ptr<NebdFileInstance>
CurveRequestExecutor::Reopen(const std::string& filename,
const ExtendAttribute& xattr) {
auto curveFileInfo = FileNameParser::Parse(filename);
if (curveFileInfo.first.empty()) {
std::string curveFileName = FileNameParser::Parse(filename);
if (curveFileName.empty()) {
return nullptr;
}
@ -135,13 +129,11 @@ CurveRequestExecutor::Reopen(const std::string& filename,
}
}
int fd = client_->ReOpen(
curveFileInfo.first,
ConverToCurveOpenFlags(&flags, curveFileInfo.second));
int fd = client_->ReOpen(curveFileName, ConverToCurveOpenFlags(&flags));
if (fd >= 0) {
auto curveFileInstance = std::make_shared<CurveFileInstance>();
curveFileInstance->fd = fd;
curveFileInstance->fileName = curveFileInfo.first;
curveFileInstance->fileName = curveFileName;
curveFileInstance->xattr[kSessionAttrKey] = newSessionId;
if (xattr.count(kOpenFlagsAttrKey)) {
curveFileInstance->xattr[kOpenFlagsAttrKey] =
@ -183,20 +175,17 @@ int CurveRequestExecutor::Extend(NebdFileInstance* fd, int64_t newsize) {
int CurveRequestExecutor::GetInfo(
NebdFileInstance* fd, NebdFileInfo* fileInfo) {
int curveFd = GetCurveFdFromNebdFileInstance(fd);
if (curveFd < 0) {
LOG(ERROR) << "Parse curve fd failed";
std::string fileName = GetFileNameFromNebdFileInstance(fd);
if (fileName.empty()) {
return -1;
}
FileStatInfo statInfo;
int64_t rc = client_->StatFile(curveFd, &statInfo);
if (rc < 0) {
int64_t size = client_->StatFile(fileName);
if (size < 0) {
return -1;
}
fileInfo->size = statInfo.length;
fileInfo->block_size = statInfo.blocksize;
fileInfo->size = size;
return 0;
}

View File

@ -25,7 +25,6 @@
#include <string>
#include <memory>
#include <utility>
#include "nebd/src/part2/request_executor.h"
#include "nebd/src/part2/define.h"
#include "include/client/libcurve.h"
@ -59,12 +58,9 @@ class FileNameParser {
* qemu "cbd:pool1//cinder/volume-6f30d296-07f7-452e-a983-513191f8cd95_cinder_:/etc/curve/client.conf" //NOLINT
* nbd "cbd:pool1//cinder/volume-6f30d296-07f7-452e-a983-513191f8cd95_cinder_" // NOLINT
* @param[in] fileName
* @return
* qemu "/cinder/volume-6f30d296-07f7-452e-a983-513191f8cd95_cinder_", "/etc/curve/client.conf" //NOLINT
* nbd "/cinder/volume-6f30d296-07f7-452e-a983-513191f8cd95_cinder_", "" //NOLINT
* @return : "/cinder/volume-6f30d296-07f7-452e-a983-513191f8cd95_cinder_" //NOLINT
*/
static std::pair<std::string, std::string>
Parse(const std::string& fileName);
static std::string Parse(const std::string& fileName);
};
class CurveRequestExecutor : public NebdRequestExecutor {

View File

@ -157,7 +157,6 @@ 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);

View File

@ -27,15 +27,13 @@
#include <brpc/controller.h>
#include <string>
#include "nebd/proto/client.pb.h"
#include "nebd/src/part1/nebd_common.h"
namespace nebd {
namespace client {
class FakeNebdFileService: public NebdFileService {
public:
explicit FakeNebdFileService(uint32_t blockSize = kDefaultBlockSize)
: fileSize_(0), blockSize_(blockSize) {}
FakeNebdFileService() {}
virtual ~FakeNebdFileService() {}
@ -86,7 +84,6 @@ class FakeNebdFileService: public NebdFileService {
private:
int64_t fileSize_;
uint32_t blockSize_;
};
} // namespace client
} // namespace nebd

View File

@ -269,7 +269,6 @@ TEST_F(NebdFileClientTest, NoNebdServerTest) {
}
ASSERT_EQ(-1, Extend4Nebd(1, kFileSize));
ASSERT_EQ(-1, GetFileSize4Nebd(1));
ASSERT_EQ(-1, GetBlockSize4Nebd(1));
ASSERT_EQ(-1, GetInfo4Nebd(1));
ASSERT_EQ(-1, InvalidCache4Nebd(1));
ASSERT_EQ(-1, Close4Nebd(1));
@ -293,7 +292,6 @@ TEST_F(NebdFileClientTest, CommonTest) {
ASSERT_EQ(0, Extend4Nebd(fd, kFileSize));
ASSERT_EQ(kFileSize, GetFileSize4Nebd(fd));
ASSERT_EQ(kFileSize, GetInfo4Nebd(fd));
ASSERT_EQ(kDefaultBlockSize, GetBlockSize4Nebd(fd));
ASSERT_EQ(0, InvalidCache4Nebd(fd));
char buffer[kBufSize];
@ -445,17 +443,6 @@ TEST_F(NebdFileClientTest, ResponseFailTest) {
ASSERT_EQ(-1, GetFileSize4Nebd(1));
}
{
GetInfoResponse response;
response.set_retcode(RetCode::kNoOK);
EXPECT_CALL(mockService, GetInfo(_, _, _, _))
.Times(1)
.WillOnce(DoAll(
SetArgPointee<2>(response),
Invoke(MockClientFunc<GetInfoRequest, GetInfoResponse>)));
ASSERT_EQ(-1, GetBlockSize4Nebd(1));
}
{
GetInfoResponse response;
response.set_retcode(RetCode::kNoOK);

View File

@ -41,7 +41,6 @@ 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 {
@ -90,7 +89,7 @@ class NebdLibTest : public ::testing::Test {
}
brpc::Server server;
FakeNebdFileService fakeService{kBlockSize};
FakeNebdFileService fakeService;
MockNebdFileService mockService;
};
@ -107,7 +106,6 @@ 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));

View File

@ -41,7 +41,7 @@ class MockCurveClient : public ::curve::client::CurveClient {
int(const std::string&, const ::curve::client::OpenFlags&));
MOCK_METHOD1(Close, int(int));
MOCK_METHOD2(Extend, int(const std::string&, int64_t));
MOCK_METHOD2(StatFile, int64_t(int, FileStatInfo*));
MOCK_METHOD1(StatFile, int64_t(const std::string&));
MOCK_METHOD3(AioRead,
int(int, CurveAioContext*, curve::client::UserDataType));
MOCK_METHOD3(AioWrite,

View File

@ -36,7 +36,6 @@ using ::testing::_;
using ::testing::SetArgPointee;
using ::testing::DoAll;
using ::testing::SaveArg;
using ::testing::Invoke;
class TestReuqestExecutorCurveClosure : public google::protobuf::Closure {
public:
@ -227,48 +226,38 @@ TEST_F(TestReuqestExecutorCurve, test_Extend) {
TEST_F(TestReuqestExecutorCurve, test_GetInfo) {
auto executor = CurveRequestExecutor::GetInstance();
NebdFileInfo fileInfo;
int curveFd = 123;
std::string curveFilename("/cinder/volume-1234_cinder_");
// 1. nebdFileIns不是CurveFileInstance类型, stat失败
{
auto nebdFileIns = new NebdFileInstance();
EXPECT_CALL(*curveClient_, StatFile(curveFd, _)).Times(0);
EXPECT_CALL(*curveClient_, StatFile(_)).Times(0);
ASSERT_EQ(-1, executor.GetInfo(nebdFileIns, &fileInfo));
}
// 2. nebdFileIns中的fd为空, stat失败
// 2. nebdFileIns中的fileName为空, extend失败
{
auto curveFileIns = new CurveFileInstance();
EXPECT_CALL(*curveClient_, StatFile(curveFd, _)).Times(0);
EXPECT_CALL(*curveClient_, StatFile(_)).Times(0);
ASSERT_EQ(-1, executor.GetInfo(curveFileIns, &fileInfo));
}
// 3. 调用curveclient的stat接口失败, stat失败
// 3. 调用curveclient的extend接口失败 extend失败
{
auto curveFileIns = new CurveFileInstance();
curveFileIns->fd = curveFd;
EXPECT_CALL(*curveClient_, StatFile(curveFd, _))
curveFileIns->fileName = curveFilename;
EXPECT_CALL(*curveClient_, StatFile(curveFilename))
.WillOnce(Return(-1));
ASSERT_EQ(-1, executor.GetInfo(curveFileIns, &fileInfo));
}
// 4. stat成功
// 4. extend成功
{
const uint64_t size = 10ull * 1024 * 1024 * 1024;
const uint32_t blocksize = 4096;
auto curveFileIns = new CurveFileInstance();
curveFileIns->fd = curveFd;
EXPECT_CALL(*curveClient_, StatFile(curveFd, _))
.WillOnce(Invoke(
[size, blocksize](int /*fd*/, FileStatInfo* info) {
info->length = size;
info->blocksize = blocksize;
return 0;
}));
curveFileIns->fileName = curveFilename;
EXPECT_CALL(*curveClient_, StatFile(curveFilename)).WillOnce(Return(1));
ASSERT_EQ(0, executor.GetInfo(curveFileIns, &fileInfo));
ASSERT_EQ(size, fileInfo.size);
ASSERT_EQ(blocksize, fileInfo.block_size);
ASSERT_EQ(1, fileInfo.size);
}
}
@ -481,23 +470,20 @@ TEST_F(TestReuqestExecutorCurve, test_InvalidCache) {
TEST(TestFileNameParser, test_Parse) {
std::string fileName("cbd:pool1//cinder/volume-1234_cinder_:/client.conf");
std::pair<std::string, std::string> res(
"/cinder/volume-1234_cinder_", "/client.conf");
ASSERT_EQ(res, FileNameParser::Parse(fileName));
fileName = "cbd:pool1//cinder/volume-1234_cinder_";
res = std::make_pair("/cinder/volume-1234_cinder_", "");
std::string res("/cinder/volume-1234_cinder_");
ASSERT_EQ(res, FileNameParser::Parse(fileName));
fileName = "cbd:pool1";
res = std::make_pair("", "");
ASSERT_EQ("", FileNameParser::Parse(fileName));
fileName = "cbd:pool1//cinder/volume-1234_cinder_";
ASSERT_EQ(res, FileNameParser::Parse(fileName));
fileName = "cbd:pool1//:";
ASSERT_EQ(res, FileNameParser::Parse(fileName));
ASSERT_EQ("", FileNameParser::Parse(fileName));
fileName = "cbd:pool1//";
ASSERT_EQ(res, FileNameParser::Parse(fileName));
ASSERT_EQ("", FileNameParser::Parse(fileName));
}

View File

@ -93,8 +93,6 @@ message FileInfo {
optional FileThrottleParams throttleParams = 17;
optional uint64 epoch = 18;
optional string poolset = 19;
optional uint32 blocksize = 20;
}
// status code
@ -168,8 +166,7 @@ enum StatusCode {
kRecoverFileError = 139;
// epoch too old
kEpochTooOld = 140;
// poolset doesn't exist
kPoolsetNotExist = 141;
//
kStorageError = 501;
//
@ -205,7 +202,6 @@ message CreateFileRequest {
required uint64 date = 6;
optional uint64 stripeUnit = 7;
optional uint64 stripeCount = 8;
optional string poolset = 9;
};
message CreateFileResponse {
@ -503,7 +499,6 @@ message CreateCloneFileRequest {
required string cloneSource = 9;
optional uint64 stripeUnit = 10;
optional uint64 stripeCount = 11;
optional string poolset = 12;
}
message CreateCloneFileResponse {

View File

@ -51,7 +51,6 @@ message SnapshotInfoData {
required int32 status = 10;
optional uint64 stripeUnit = 11;
optional uint64 stripeCount = 12;
optional string poolset = 13;
};
message CloneInfoData {
@ -67,7 +66,6 @@ message CloneInfoData {
required bool isLazy = 10;
required int32 nextStep = 11;
required int32 status = 12;
optional string poolset = 13;
};
message HttpRequest {};
@ -77,3 +75,4 @@ message HttpResponse {};
service SnapshotCloneService{
rpc default_method(HttpRequest) returns (HttpResponse);
};

View File

@ -61,13 +61,6 @@ message ClusterInfoData {
required string clusterId = 1;
}
message PoolsetData {
required uint32 poolsetId = 1;
required string poolsetName = 2;
required string type = 3;
required string desc = 4;
}
message LogicalPoolData {
required uint32 logicalPoolId = 1;
required string logicalPoolName = 2;
@ -86,7 +79,6 @@ message PhysicalPoolData {
required uint32 physicalPoolId = 1;
required string physicalPoolName = 2;
required string desc = 3;
optional uint32 poolsetId = 4;
}
message ZoneData {
@ -167,8 +159,6 @@ message ChunkServerRegistRequest {
optional uint64 chunkFilepoolSize = 8;
optional bool useChunkFilePoolAsWalPool = 9;
optional uint32 useChunkFilePoolAsWalPoolReserve = 10;
optional uint32 blockSize = 11;
optional uint32 chunkSize = 12;
};
message ChunkServerRegistResponse {
@ -256,7 +246,6 @@ message ServerRegistRequest {
optional uint32 physicalPoolID = 8;
optional string physicalPoolName = 9; //physicalPoolName is unique
required string desc = 10;
required string poolsetName = 11;
}
message ServerRegistResponse {
@ -338,8 +327,6 @@ message PhysicalPoolInfo {
required uint32 physicalPoolID = 1;
required string physicalPoolName = 2;
optional string desc = 3;
required uint32 poolsetId = 4;
required string poolsetName = 5;
}
message PhysicalPoolRequest {
@ -347,7 +334,6 @@ message PhysicalPoolRequest {
optional uint32 physicalPoolID = 1;
optional string physicalPoolName = 2;
optional string desc = 3;
optional string poolsetName = 4;
}
message PhysicalPoolResponse {
@ -358,43 +344,11 @@ message PhysicalPoolResponse {
message ListPhysicalPoolRequest {
}
message ListPhysicalPoolsInPoolsetRequest {
repeated uint32 poolsetId = 1;
}
message ListPhysicalPoolResponse {
required sint32 statusCode = 1;
repeated PhysicalPoolInfo physicalPoolInfos = 2;
}
//poolset message
message PoolsetRequest {
//use either poolsetID or poolsetName
optional uint32 poolsetID = 1;
optional string poolsetName = 2;
optional string type = 3;
optional string desc = 4;
}
message PoolsetInfo {
required uint32 poolsetID = 1;
required string poolsetName = 2;
required string type = 3;
optional string desc = 4;
}
message PoolsetResponse {
required sint32 statusCode = 1;
optional PoolsetInfo poolsetInfo = 2;
}
message ListPoolsetRequest {}
message ListPoolsetResponse {
required sint32 statusCode = 1;
repeated PoolsetInfo poolsetInfos = 2;
}
//logicalpool message
message LogicalPoolInfo {
required uint32 logicalPoolID = 1;
@ -560,7 +514,7 @@ service TopologyService {
rpc DeleteChunkServer(DeleteChunkServerRequest) returns (DeleteChunkServerResponse);
rpc SetChunkServer(SetChunkServerStatusRequest) returns (SetChunkServerStatusResponse);
rpc RegistServer(ServerRegistRequest) returns (ServerRegistResponse);
rpc RegistServer(ServerRegistRequest) returns (ServerRegistResponse);
rpc GetServer(GetServerRequest) returns (GetServerResponse);
rpc DeleteServer(DeleteServerRequest) returns (DeleteServerResponse);
rpc ListZoneServer(ListZoneServerRequest) returns (ListZoneServerResponse);
@ -570,16 +524,11 @@ service TopologyService {
rpc GetZone(ZoneRequest) returns (ZoneResponse);
rpc ListPoolZone(ListPoolZoneRequest) returns (ListPoolZoneResponse);
rpc CreatePhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc DeletePhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc GetPhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc ListPhysicalPool(ListPhysicalPoolRequest) returns (ListPhysicalPoolResponse);
rpc ListPhysicalPoolsInPoolset(ListPhysicalPoolsInPoolsetRequest) returns (ListPhysicalPoolResponse);
rpc CreatePoolset(PoolsetRequest) returns (PoolsetResponse);
rpc DeletePoolset(PoolsetRequest) returns (PoolsetResponse);
rpc GetPoolset(PoolsetRequest) returns (PoolsetResponse);
rpc ListPoolset(ListPoolsetRequest) returns (ListPoolsetResponse);
rpc CreatePhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc DeletePhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc GetPhysicalPool(PhysicalPoolRequest) returns (PhysicalPoolResponse);
rpc ListPhysicalPool(ListPhysicalPoolRequest) returns (ListPhysicalPoolResponse);
rpc CreateLogicalPool(CreateLogicalPoolRequest) returns (CreateLogicalPoolResponse);
rpc DeleteLogicalPool(DeleteLogicalPoolRequest) returns (DeleteLogicalPoolResponse);
@ -596,3 +545,4 @@ service TopologyService {
rpc SetCopysetsAvailFlag(SetCopysetsAvailFlagRequest) returns (SetCopysetsAvailFlagResponse);
rpc ListUnAvailCopySets(ListUnAvailCopySetsRequest) returns (ListUnAvailCopySetsResponse);
}

View File

@ -14,6 +14,9 @@ sed -i "s;https://zlib.net/zlib-1.2.11.tar.gz;https://curve-build.nos-eastchina1
# protobuf
sed -i "s;https://github.com/google/protobuf/archive/v3.6.1.3.zip;https://curve-build.nos-eastchina1.126.net/protobuf-3.6.1.3.zip;g" WORKSPACE
# googletest
sed -i "s;https://github.com/google/googletest;https://gitee.com/mirrors/googletest;g" WORKSPACE
# gflags
sed -i "s;https://github.com/gflags/gflags/archive/v2.2.2.tar.gz;https://curve-build.nos-eastchina1.126.net/gflags-2.2.2.tar.gz;g" WORKSPACE

View File

@ -1449,11 +1449,11 @@ read write iosize 512
${fd} open libcurve file
${new_fd} Convert To Integer ${fd}
${rc} write libcurve file error ${new_fd} length=512
${expect_rc} evaluate int(-22)
should be equal ${rc} ${expect_rc}
${rc} read libcurve file ${new_fd} length=512
${expect_rc} evaluate int(-22)
${expect_rc} evaluate int(512)
should be equal ${rc} ${expect_rc}
${content} read libcurve file ${new_fd} length=512
${expect_content} evaluate str("a")*512
should be equal ${content} ${expect_content}
[Teardown] file clean ${new_fd}
@ -1480,11 +1480,11 @@ read write iosize 512
${fd} open libcurve file
${new_fd} Convert To Integer ${fd}
${rc} write libcurve file error ${new_fd} length=512
${expect_rc} evaluate int(-22)
should be equal ${rc} ${expect_rc}
${rc} read libcurve file ${new_fd} length=512
${expect_rc} evaluate int(-22)
${expect_rc} evaluate int(512)
should be equal ${rc} ${expect_rc}
${content} read libcurve file ${new_fd} length=512
${expect_content} evaluate str("a")*512
should be equal ${content} ${expect_content}
[Teardown] file clean ${new_fd}
read write iosize 1k
@ -1493,9 +1493,22 @@ read write iosize 1k
${fd} open libcurve file
${new_fd} Convert To Integer ${fd}
${rc} write libcurve file error ${new_fd} length=1024
${expect_rc} evaluate int(1024)
should be equal ${rc} ${expect_rc}
${content} read libcurve file ${new_fd} length=1024
${expect_content} evaluate str("a")*1024
should be equal ${content} ${expect_content}
[Teardown] file clean ${new_fd}
read write iosize not 512 alignment
[Tags] P0 base first release
[Setup] file init
${fd} open libcurve file
${new_fd} Convert To Integer ${fd}
${rc} write libcurve file error ${new_fd} length=511
${expect_rc} evaluate int(-22)
should be equal ${rc} ${expect_rc}
${rc} read libcurve file ${new_fd} length=1024
${rc} read libcurve file ${new_fd} length=511
${expect_rc} evaluate int(-22)
should be equal ${rc} ${expect_rc}
[Teardown] file clean ${new_fd}
@ -2552,9 +2565,3 @@ check chunkserver should be exsits
start mds with sleep
start mds
Sleep 5s

View File

@ -48,7 +48,6 @@ cc_library(
"//src/common:curve_s3_adapter",
"//src/fs:lfs",
"//src/client:curve_client",
"//include:include-common",
"//include/client:include_client",
"//proto:scan_cc_proto",
],

View File

@ -35,23 +35,18 @@
#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"
#include "include/curve_compiler_specific.h"
#include "src/common/fast_align.h"
namespace curve {
namespace chunkserver {
using ::curve::common::is_aligned;
ChunkServiceImpl::ChunkServiceImpl(
const ChunkServiceOptions& chunkServiceOptions,
const std::shared_ptr<EpochMap>& epochMap)
: chunkServiceOptions_(chunkServiceOptions),
copysetNodeManager_(chunkServiceOptions.copysetNodeManager),
inflightThrottle_(chunkServiceOptions.inflightThrottle),
epochMap_(epochMap),
blockSize_(copysetNodeManager_->GetCopysetNodeOptions().blockSize) {
ChunkServiceImpl::ChunkServiceImpl(ChunkServiceOptions chunkServiceOptions,
const std::shared_ptr<EpochMap> &epochMap) :
chunkServiceOptions_(chunkServiceOptions),
copysetNodeManager_(chunkServiceOptions.copysetNodeManager),
inflightThrottle_(chunkServiceOptions.inflightThrottle),
epochMap_(epochMap) {
maxChunkSize_ = copysetNodeManager_->GetCopysetNodeOptions().maxChunkSize;
}
@ -578,13 +573,14 @@ void ChunkServiceImpl::UpdateEpoch(RpcController *controller,
}
bool ChunkServiceImpl::CheckRequestOffsetAndLength(uint32_t offset,
uint32_t len) const {
uint32_t len) {
// 检查offset+len是否越界
if (CURVE_UNLIKELY(offset + len > maxChunkSize_)) {
if (offset + len > maxChunkSize_) {
return false;
}
return is_aligned(offset, blockSize_) && is_aligned(len, blockSize_);
return common::is_aligned(offset, FLAGS_minIoAlignment) &&
common::is_aligned(len, FLAGS_minIoAlignment);
}
} // namespace chunkserver

View File

@ -41,7 +41,7 @@ class CopysetNodeManager;
class ChunkServiceImpl : public ChunkService {
public:
explicit ChunkServiceImpl(const ChunkServiceOptions& chunkServiceOptions,
explicit ChunkServiceImpl(ChunkServiceOptions chunkServiceOptions,
const std::shared_ptr<EpochMap> &epochMap);
~ChunkServiceImpl() {}
@ -105,7 +105,7 @@ class ChunkServiceImpl : public ChunkService {
* @param len[in]: op request' length
* @return truefalse
*/
bool CheckRequestOffsetAndLength(uint32_t offset, uint32_t len) const;
bool CheckRequestOffsetAndLength(uint32_t offset, uint32_t len);
private:
ChunkServiceOptions chunkServiceOptions_;
@ -114,7 +114,6 @@ class ChunkServiceImpl : public ChunkService {
uint32_t maxChunkSize_;
std::shared_ptr<EpochMap> epochMap_;
uint32_t blockSize_;
};
} // namespace chunkserver

View File

@ -59,7 +59,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", "chunkserver meta uri");
"local://./0/chunkserver.dat", "chunnkserver meata 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");
@ -109,6 +109,12 @@ int ChunkServer::Run(int argc, char** argv) {
// ============================初始化各模块==========================//
LOG(INFO) << "Initializing ChunkServer modules";
LOG_IF(FATAL, !conf.GetUInt32Value("global.min_io_alignment",
&FLAGS_minIoAlignment))
<< "Failed to get global.min_io_alignment";
LOG_IF(FATAL, !common::is_aligned(FLAGS_minIoAlignment, 512))
<< "minIoAlignment should align to 512";
// 优先初始化 metric 收集模块
ChunkServerMetricOptions metricOptions;
InitMetricOptions(&conf, &metricOptions);
@ -137,7 +143,6 @@ int ChunkServer::Run(int argc, char** argv) {
InitChunkFilePoolOptions(&conf, &chunkFilePoolOptions);
std::shared_ptr<FilePool> chunkfilePool =
std::make_shared<FilePool>(fs);
LOG_IF(FATAL, false == chunkfilePool->Initialize(chunkFilePoolOptions))
<< "Failed to init chunk file pool";
@ -196,14 +201,12 @@ int ChunkServer::Run(int argc, char** argv) {
registerOptions.useChunkFilePoolAsWalPool = useChunkFilePoolAsWalPool;
registerOptions.fs = fs;
registerOptions.chunkFilepool = chunkfilePool;
registerOptions.blockSize = chunkfilePool->GetFilePoolOpt().blockSize;
registerOptions.chunkSize = chunkfilePool->GetFilePoolOpt().fileSize;
Register registerMDS(registerOptions);
ChunkServerMetadata metadata;
ChunkServerMetadata localMetadata;
// 从本地获取meta
std::string metaPath = UriParser::GetPathFromUri(
registerOptions.chunkserverMetaUri);
registerOptions.chunkserverMetaUri).c_str();
auto epochMap = std::make_shared<EpochMap>();
if (fs->FileExists(metaPath)) {
@ -246,13 +249,6 @@ int ChunkServer::Run(int argc, char** argv) {
FilePoolOptions poolOpt = walFilePool->GetFilePoolOpt();
uint32_t maxWalSegmentSize = poolOpt.fileSize + poolOpt.metaPageSize;
copysetNodeOptions.maxWalSegmentSize = maxWalSegmentSize;
if (poolOpt.getFileFromPool) {
// overwrite from file pool
copysetNodeOptions.maxChunkSize = poolOpt.fileSize;
copysetNodeOptions.metaPageSize = poolOpt.metaPageSize;
copysetNodeOptions.blockSize = poolOpt.blockSize;
}
}
// install snapshot的带宽限制
@ -484,15 +480,8 @@ 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))
<< "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";
&chunkFilePoolOptions->metaPageSize));
LOG_IF(FATAL, !conf->GetUInt32Value("chunkfilepool.cpmeta_file_size",
&chunkFilePoolOptions->metaFileSize));
LOG_IF(FATAL, !conf->GetBoolValue(
@ -597,12 +586,10 @@ void ChunkServer::InitCopysetNodeOptions(
&copysetNodeOptions->recyclerUri));
LOG_IF(FATAL, !conf->GetUInt32Value("global.chunk_size",
&copysetNodeOptions->maxChunkSize));
LOG_IF(FATAL, !conf->GetUInt32Value("global.meta_page_size",
&copysetNodeOptions->metaPageSize));
LOG_IF(FATAL, !conf->GetUInt32Value("global.block_size",
&copysetNodeOptions->blockSize));
LOG_IF(FATAL, !conf->GetUInt32Value("global.location_limit",
&copysetNodeOptions->locationLimit));
LOG_IF(FATAL, !conf->GetUInt32Value("global.meta_page_size",
&copysetNodeOptions->pageSize));
LOG_IF(FATAL, !conf->GetUInt32Value("copyset.load_concurrency",
&copysetNodeOptions->loadConcurrency));
LOG_IF(FATAL, !conf->GetUInt32Value("copyset.check_retrytimes",
@ -883,6 +870,10 @@ void ChunkServer::LoadConfigFromCmdline(common::Configuration *conf) {
conf->SetIntValue("copyset.load_concurrency",
FLAGS_copysetLoadConcurrency);
}
if (GetCommandLineFlagInfo("minIoAlignment", &info) && !info.is_default) {
conf->SetUInt32Value("global.min_io_alignment", FLAGS_minIoAlignment);
}
}
int ChunkServer::GetChunkServerMetaFromLocal(

View File

@ -140,24 +140,24 @@ int CloneCore::CloneReadByLocalInfo(
const ChunkRequest* request = readRequest->request_;
off_t offset = request->offset();
size_t length = request->size();
const uint32_t blockSize = chunkInfo.blockSize;
uint32_t pageSize = chunkInfo.pageSize;
// offset and length must be aligned with blockSize
if (offset % blockSize != 0 || length % blockSize != 0) {
// offset 和 length 必须与 pageSize 对齐
if (offset % pageSize != 0 || length % pageSize != 0) {
LOG(ERROR) << "Invalid offset or length: "
<< " logic pool id: " << request->logicpoolid()
<< " copyset id: " << request->copysetid()
<< " chunkid: " << request->chunkid()
<< " offset: " << offset
<< " length: " << length
<< " block size: " << blockSize;
<< " page size: " << pageSize;
SetResponse(readRequest,
CHUNK_OP_STATUS::CHUNK_OP_STATUS_INVALID_REQUEST);
return -1;
}
uint32_t beginIndex = offset / blockSize;
uint32_t endIndex = (offset + length - 1) / blockSize;
uint32_t beginIndex = offset / pageSize;
uint32_t endIndex = (offset + length - 1) / pageSize;
// 请求提交到CloneManager的时候chunk一定是clone chunk
// 但是由于有其他请求操作相同的chunk此时chunk有可能已经被遍写过了
@ -358,9 +358,9 @@ int CloneCore::ReadThenMerge(std::shared_ptr<ReadChunkRequest> readRequest,
off_t offset = request->offset();
size_t length = request->size();
uint32_t blockSize = chunkInfo.blockSize;
uint32_t beginIndex = offset / blockSize;
uint32_t endIndex = (offset + length - 1) / blockSize;
uint32_t pageSize = chunkInfo.pageSize;
uint32_t beginIndex = offset / pageSize;
uint32_t endIndex = (offset + length - 1) / pageSize;
// 获取chunk文件已经写过和未被写过的区域
std::vector<BitRange> copiedRanges;
std::vector<BitRange> uncopiedRanges;
@ -385,8 +385,8 @@ int CloneCore::ReadThenMerge(std::shared_ptr<ReadChunkRequest> readRequest,
// 1.Read 对于已写过的区域从chunk文件中读取
CSErrorCode errorCode;
for (auto& range : copiedRanges) {
readOff = range.beginIndex * blockSize;
readSize = (range.endIndex - range.beginIndex + 1) * blockSize;
readOff = range.beginIndex * pageSize;
readSize = (range.endIndex - range.beginIndex + 1) * pageSize;
relativeOff = readOff - offset;
errorCode = dataStore->ReadChunk(request->chunkid(),
request->sn(),
@ -407,8 +407,8 @@ int CloneCore::ReadThenMerge(std::shared_ptr<ReadChunkRequest> readRequest,
// 2.Merge 对于未写过的区域从源端下载的区域中拷贝出来进行merge
for (auto& range : uncopiedRanges) {
readOff = range.beginIndex * blockSize;
readSize = (range.endIndex - range.beginIndex + 1) * blockSize;
readOff = range.beginIndex * pageSize;
readSize = (range.endIndex - range.beginIndex + 1) * pageSize;
relativeOff = readOff - offset;
cloneData->copy_to(chunkData + relativeOff, readSize, relativeOff);
}

View File

@ -0,0 +1,54 @@
/*
* 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

View File

@ -89,9 +89,7 @@ struct CopysetNodeOptions {
// WAL segment file size
uint32_t maxWalSegmentSize;
// chunk文件的page大小
uint32_t metaPageSize;
// alignment for I/O request
uint32_t blockSize;
uint32_t pageSize;
// clone chunk的location长度限制
uint32_t locationLimit;
@ -148,27 +146,6 @@ struct ChunkServiceOptions {
std::shared_ptr<InflightThrottle> 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

View File

@ -126,8 +126,7 @@ int CopysetNode::Init(const CopysetNodeOptions &options) {
DataStoreOptions dsOptions;
dsOptions.baseDir = chunkDataApath_;
dsOptions.chunkSize = options.maxChunkSize;
dsOptions.metaPageSize = options.metaPageSize;
dsOptions.blockSize = options.blockSize;
dsOptions.pageSize = options.pageSize;
dsOptions.locationLimit = options.locationLimit;
dsOptions.enableOdsyncWhenOpenChunkFile =
options.enableOdsyncWhenOpenChunkFile;
@ -209,10 +208,7 @@ int CopysetNode::Run() {
<< "Copyset: " << GroupIdString();
return -1;
}
if (!enableOdsyncWhenOpenChunkFile_) {
syncThread_.Run();
}
syncThread_.Run();
LOG(INFO) << "Run copyset success."
<< "Copyset: " << GroupIdString();

View File

@ -31,8 +31,7 @@ cc_library(
"//include/chunkserver:include-chunkserver",
"//src/fs:lfs",
"//src/common:curve_common",
"//external:json",
"@com_google_absl//absl/utility",
"//external:json"
],
copts = CURVE_DEFAULT_COPTS,
)

View File

@ -31,6 +31,19 @@
namespace curve {
namespace chunkserver {
namespace {
bool ValidMinIoAlignment(const char* /*flagname*/, uint32_t value) {
return common::is_aligned(value, 512);
}
} // namespace
DEFINE_uint32(minIoAlignment, 512,
"minimum alignment for io request, must align to 512");
DEFINE_validator(minIoAlignment, ValidMinIoAlignment);
ChunkFileMetaPage::ChunkFileMetaPage(const ChunkFileMetaPage& metaPage) {
version = metaPage.version;
sn = metaPage.sn;
@ -139,8 +152,7 @@ CSChunkFile::CSChunkFile(std::shared_ptr<LocalFileSystem> lfs,
chunkrate_(nullptr),
fd_(-1),
size_(options.chunkSize),
blockSize_(options.blockSize),
metaPageSize_(options.metaPageSize),
pageSize_(options.pageSize),
chunkId_(options.id),
baseDir_(options.baseDir),
isCloneChunk_(false),
@ -157,7 +169,7 @@ CSChunkFile::CSChunkFile(std::shared_ptr<LocalFileSystem> lfs,
// If location is not empty, it is CloneChunk,
// and Bitmap needs to be initialized
if (!metaPage_.location.empty()) {
uint32_t bits = size_ / blockSize_;
uint32_t bits = size_ / pageSize_;
metaPage_.bitmap = std::make_shared<Bitmap>(bits);
}
if (metric_ != nullptr) {
@ -193,8 +205,8 @@ CSErrorCode CSChunkFile::Open(bool createFile) {
if (createFile
&& !lfs_->FileExists(chunkFilePath)
&& metaPage_.sn > 0) {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
metaPage_.version = FORMAT_VERSION_V2;
metaPage_.encode(buf.get());
@ -264,8 +276,7 @@ CSErrorCode CSChunkFile::LoadSnapshot(SequenceNum sn) {
options.sn = sn;
options.baseDir = baseDir_;
options.chunkSize = size_;
options.blockSize = blockSize_;
options.metaPageSize = metaPageSize_;
options.pageSize = pageSize_;
options.metric = metric_;
snapshot_ = new(std::nothrow) CSSnapshot(lfs_,
chunkFilePool_,
@ -291,14 +302,16 @@ CSErrorCode CSChunkFile::Write(SequenceNum sn,
uint32_t* cost) {
(void)cost;
WriteLockGuard writeGuard(rwLock_);
if (!CheckOffsetAndLength(offset, length)) {
if (!CheckOffsetAndLength(
offset, length, isCloneChunk_ ? pageSize_ : FLAGS_minIoAlignment)) {
LOG(ERROR) << "Write chunk failed, invalid offset or length."
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length
<< ", page size: " << metaPageSize_
<< ", page size: " << pageSize_
<< ", chunk size: " << size_
<< ", block size: " << blockSize_;
<< ", align: "
<< (isCloneChunk_ ? pageSize_ : FLAGS_minIoAlignment);
return CSErrorCode::InvalidArgError;
}
// Curve will ensure that all previous requests arrive or time out
@ -341,8 +354,7 @@ CSErrorCode CSChunkFile::Write(SequenceNum sn,
options.sn = metaPage_.sn;
options.baseDir = baseDir_;
options.chunkSize = size_;
options.blockSize = blockSize_;
options.metaPageSize = metaPageSize_;
options.pageSize = pageSize_;
options.metric = metric_;
snapshot_ = new(std::nothrow) CSSnapshot(lfs_,
chunkFilePool_,
@ -439,26 +451,26 @@ CSErrorCode CSChunkFile::Sync() {
CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) {
WriteLockGuard writeGuard(rwLock_);
if (!CheckOffsetAndLength(offset, length)) {
LOG(ERROR) << "Paste chunk failed, invalid offset or length."
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length
<< ", page size: " << metaPageSize_
<< ", chunk size: " << size_
<< ", block size: " << blockSize_;
return CSErrorCode::InvalidArgError;
}
// If it is not a clone chunk, return success directly
if (!isCloneChunk_) {
return CSErrorCode::Success;
}
if (!CheckOffsetAndLength(offset, length, pageSize_)) {
LOG(ERROR) << "Paste chunk failed, invalid offset or length."
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length
<< ", page size: " << pageSize_
<< ", chunk size: " << size_
<< ", align: " << pageSize_;
return CSErrorCode::InvalidArgError;
}
// The request above must be blocksize aligned
// the starting block index number of the paste area
uint32_t beginIndex = offset / blockSize_;
// the last block index number of the paste area
uint32_t endIndex = (offset + length - 1) / blockSize_;
// The request above must be pagesize aligned
// the starting page index number of the paste area
uint32_t beginIndex = offset / pageSize_;
// the last page index number of the paste area
uint32_t endIndex = (offset + length - 1) / pageSize_;
// Get the unwritten range of the current file
std::vector<BitRange> uncopiedRange;
metaPage_.bitmap->Divide(beginIndex,
@ -470,8 +482,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 * blockSize_;
pasteSize = (range.endIndex - range.beginIndex + 1) * blockSize_;
pasteOff = range.beginIndex * pageSize_;
pasteSize = (range.endIndex - range.beginIndex + 1) * pageSize_;
int rc = writeData(buf + (pasteOff - offset), pasteOff, pasteSize);
if (rc < 0) {
LOG(ERROR) << "Paste data to chunk failed."
@ -496,25 +508,27 @@ CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) {
CSErrorCode CSChunkFile::Read(char * buf, off_t offset, size_t length) {
ReadLockGuard readGuard(rwLock_);
if (!CheckOffsetAndLength(offset, length)) {
if (!CheckOffsetAndLength(
offset, length, isCloneChunk_ ? pageSize_ : FLAGS_minIoAlignment)) {
LOG(ERROR) << "Read chunk failed, invalid offset or length."
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length
<< ", page size: " << metaPageSize_
<< ", page size: " << pageSize_
<< ", chunk size: " << size_
<< ", block size: " << blockSize_;
<< ", align: "
<< (isCloneChunk_ ? pageSize_ : FLAGS_minIoAlignment);
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 blocksize aligned
// the starting block index number of the paste area
uint32_t beginIndex = offset / blockSize_;
// the last block index number of the paste area
uint32_t endIndex = (offset + length - 1) / blockSize_;
// The request above must be pagesize aligned
// the starting page index number of the paste area
uint32_t beginIndex = offset / pageSize_;
// the last page index number of the paste area
uint32_t endIndex = (offset + length - 1) / pageSize_;
if (metaPage_.bitmap->NextClearBit(beginIndex, endIndex)
!= Bitmap::NO_POS) {
LOG(ERROR) << "Read chunk file failed, has page never written."
@ -552,14 +566,14 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn,
off_t offset,
size_t length) {
ReadLockGuard readGuard(rwLock_);
if (!CheckOffsetAndLength(offset, length)) {
if (!CheckOffsetAndLength(offset, length, pageSize_)) {
LOG(ERROR) << "Read specified chunk failed, invalid offset or length."
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length
<< ", page size: " << metaPageSize_
<< ", page size: " << pageSize_
<< ", chunk size: " << size_
<< ", block size: " << blockSize_;
<< ", align: " << pageSize_;
return CSErrorCode::InvalidArgError;
}
// If the sequence equals the sequence of the current chunk,
@ -581,13 +595,13 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn,
}
// Get the copied areas and uncopied areas in the snapshot file
uint32_t blockBeginIndex = offset / blockSize_;
uint32_t blockEndIndex = (offset + length - 1) / blockSize_;
uint32_t pageBeginIndex = offset / pageSize_;
uint32_t pageEndIndex = (offset + length - 1) / pageSize_;
std::vector<BitRange> copiedRange;
std::vector<BitRange> uncopiedRange;
std::shared_ptr<const Bitmap> snapBitmap = snapshot_->GetPageStatus();
snapBitmap->Divide(blockBeginIndex,
blockEndIndex,
snapBitmap->Divide(pageBeginIndex,
pageEndIndex,
&uncopiedRange,
&copiedRange);
@ -606,8 +620,8 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn,
size_t readSize;
// For uncopied extents, read chunk data
for (auto& range : uncopiedRange) {
readOff = range.beginIndex * blockSize_;
readSize = (range.endIndex - range.beginIndex + 1) * blockSize_;
readOff = range.beginIndex * pageSize_;
readSize = (range.endIndex - range.beginIndex + 1) * pageSize_;
int rc = readData(buf + (readOff - offset),
readOff,
readSize);
@ -620,8 +634,8 @@ CSErrorCode CSChunkFile::ReadSpecifiedChunk(SequenceNum sn,
}
// For the copied range, read the snapshot data
for (auto& range : copiedRange) {
readOff = range.beginIndex * blockSize_;
readSize = (range.endIndex - range.beginIndex + 1) * blockSize_;
readOff = range.beginIndex * pageSize_;
readSize = (range.endIndex - range.beginIndex + 1) * pageSize_;
errorCode = snapshot_->Read(buf + (readOff - offset),
readOff,
readSize);
@ -761,9 +775,8 @@ CSErrorCode CSChunkFile::DeleteSnapshotOrCorrectSn(SequenceNum correctedSn) {
void CSChunkFile::GetInfo(CSChunkInfo* info) {
ReadLockGuard readGuard(rwLock_);
info->chunkId = chunkId_;
info->metaPageSize = metaPageSize_;
info->pageSize = pageSize_;
info->chunkSize = size_;
info->blockSize = blockSize_;
info->curSn = metaPage_.sn;
info->correctedSn = metaPage_.correctedSn;
info->snapSn = (snapshot_ == nullptr
@ -884,8 +897,8 @@ bool CSChunkFile::needCow(SequenceNum sn) {
}
CSErrorCode CSChunkFile::updateMetaPage(ChunkFileMetaPage* metaPage) {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
metaPage->encode(buf.get());
int rc = writeMetaPage(buf.get());
if (rc < 0) {
@ -898,8 +911,8 @@ CSErrorCode CSChunkFile::updateMetaPage(ChunkFileMetaPage* metaPage) {
}
CSErrorCode CSChunkFile::loadMetaPage() {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
int rc = readMetaPage(buf.get());
if (rc < 0) {
LOG(ERROR) << "Error occured when reading metaPage_."
@ -911,8 +924,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 / blockSize_;
uint32_t pageEndIndex = (offset + length - 1) / blockSize_;
uint32_t pageBeginIndex = offset / pageSize_;
uint32_t pageEndIndex = (offset + length - 1) / pageSize_;
std::vector<BitRange> uncopiedRange;
std::shared_ptr<const Bitmap> snapBitmap = snapshot_->GetPageStatus();
snapBitmap->Divide(pageBeginIndex,
@ -926,9 +939,10 @@ 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 * blockSize_;
copySize = (range.endIndex - range.beginIndex + 1) * blockSize_;
std::unique_ptr<char[]> buf(new char[copySize]);
copyOff = range.beginIndex * pageSize_;
copySize = (range.endIndex - range.beginIndex + 1) * pageSize_;
std::shared_ptr<char> buf(new char[copySize],
std::default_delete<char[]>());
int rc = readData(buf.get(),
copyOff,
copySize);

View File

@ -42,6 +42,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 {
@ -106,10 +107,9 @@ struct ChunkOptions {
std::string location;
// chunk size
ChunkSizeType chunkSize;
// The size of the block, each bit in the bitmap represents 1 block,
ChunkSizeType blockSize;
// The size of the meta page, each bit in the bitmap represents 1 block
PageSizeType metaPageSize;
// 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;
// enable O_DSYNC When Open ChunkFile
bool enableOdsyncWhenOpenChunkFile;
// datastore internal statistical metric
@ -121,8 +121,7 @@ struct ChunkOptions {
, baseDir("")
, location("")
, chunkSize(0)
, blockSize(0)
, metaPageSize(0)
, pageSize(0)
, metric(nullptr) {}
};
@ -322,32 +321,32 @@ class CSChunkFile {
FileNameOperator::GenerateChunkFileName(chunkId_);
}
inline uint32_t fileSize() const {
return metaPageSize_ + size_;
inline uint32_t fileSize() {
return pageSize_ + size_;
}
inline int readMetaPage(char* buf) {
return lfs_->Read(fd_, buf, 0, metaPageSize_);
return lfs_->Read(fd_, buf, 0, pageSize_);
}
inline int writeMetaPage(const char* buf) {
return lfs_->Write(fd_, buf, 0, metaPageSize_);
return lfs_->Write(fd_, buf, 0, pageSize_);
}
inline int readData(char* buf, off_t offset, size_t length) {
return lfs_->Read(fd_, buf, offset + metaPageSize_, length);
return lfs_->Read(fd_, buf, offset + pageSize_, length);
}
inline int writeData(const char* buf, off_t offset, size_t length) {
int rc = lfs_->Write(fd_, buf, offset + metaPageSize_, length);
int rc = lfs_->Write(fd_, buf, offset + pageSize_, 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 / blockSize_;
uint32_t endIndex = (offset + length - 1) / blockSize_;
uint32_t beginIndex = offset / pageSize_;
uint32_t endIndex = (offset + length - 1) / pageSize_;
for (uint32_t i = beginIndex; i <= endIndex; ++i) {
// record dirty page
if (!metaPage_.bitmap->Test(i)) {
@ -359,16 +358,15 @@ class CSChunkFile {
}
inline int writeData(const butil::IOBuf& buf, off_t offset, size_t length) {
int rc = lfs_->Write(fd_, buf, offset + metaPageSize_, length);
int rc = lfs_->Write(fd_, buf, offset + pageSize_, 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 / blockSize_;
uint32_t endIndex = (offset + length - 1) / blockSize_;
uint32_t beginIndex = offset / pageSize_;
uint32_t endIndex = (offset + length - 1) / pageSize_;
for (uint32_t i = beginIndex; i <= endIndex; ++i) {
// record dirty page
if (!metaPage_.bitmap->Test(i)) {
@ -383,14 +381,14 @@ class CSChunkFile {
return lfs_->Sync(fd_);
}
inline bool CheckOffsetAndLength(off_t offset, size_t len) {
inline bool CheckOffsetAndLength(off_t offset, size_t len, size_t align) {
// Check if offset+len is out of bounds
if (offset + len > size_) {
return false;
}
return common::is_aligned(offset, blockSize_) &&
common::is_aligned(len, blockSize_);
return common::is_aligned(offset, align) &&
common::is_aligned(len, align);
}
uint64_t MayUpdateWriteLimits(uint64_t write_len) {
@ -409,8 +407,8 @@ class CSChunkFile {
int fd_;
// The logical size of the chunk, not including metapage
ChunkSizeType size_;
ChunkSizeType blockSize_;
PageSizeType metaPageSize_;
// The smallest atomic read and write unit
PageSizeType pageSize_;
// chunk id
ChunkID chunkId_;
// The directory where the chunk is located

View File

@ -38,8 +38,7 @@ CSDataStore::CSDataStore(std::shared_ptr<LocalFileSystem> lfs,
std::shared_ptr<FilePool> chunkFilePool,
const DataStoreOptions& options)
: chunkSize_(options.chunkSize),
blockSize_(options.blockSize),
metaPageSize_(options.metaPageSize),
pageSize_(options.pageSize),
locationLimit_(options.locationLimit),
baseDir_(options.baseDir),
chunkFilePool_(chunkFilePool),
@ -251,8 +250,7 @@ CSErrorCode CSDataStore::WriteChunk(ChunkID id,
options.baseDir = baseDir_;
options.chunkSize = chunkSize_;
options.location = cloneSourceLocation;
options.blockSize = blockSize_;
options.metaPageSize = metaPageSize_;
options.pageSize = pageSize_;
options.metric = metric_;
options.enableOdsyncWhenOpenChunkFile = enableOdsyncWhenOpenChunkFile_;
CSErrorCode errorCode = CreateChunkFile(options, &chunkFile);
@ -316,8 +314,7 @@ CSErrorCode CSDataStore::CreateCloneChunk(ChunkID id,
options.location = location;
options.baseDir = baseDir_;
options.chunkSize = chunkSize_;
options.blockSize = blockSize_;
options.metaPageSize = metaPageSize_;
options.pageSize = pageSize_;
options.metric = metric_;
CSErrorCode errorCode = CreateChunkFile(options, &chunkFile);
if (errorCode != CSErrorCode::Success) {
@ -409,8 +406,7 @@ CSErrorCode CSDataStore::loadChunkFile(ChunkID id) {
options.sn = 0;
options.baseDir = baseDir_;
options.chunkSize = chunkSize_;
options.blockSize = blockSize_;
options.metaPageSize = metaPageSize_;
options.pageSize = pageSize_;
options.metric = metric_;
CSChunkFilePtr chunkFilePtr =
std::make_shared<CSChunkFile>(lfs_,

View File

@ -53,14 +53,12 @@ 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
* blockSize: the size of the smallest read-write unit
* metaPageSize: meta page size for chunk
* pageSize: the size of the smallest read-write unit
*/
struct DataStoreOptions {
std::string baseDir;
ChunkSizeType chunkSize;
ChunkSizeType blockSize;
PageSizeType metaPageSize;
PageSizeType pageSize;
uint32_t locationLimit;
bool enableOdsyncWhenOpenChunkFile;
};
@ -345,8 +343,7 @@ class CSDataStore {
// The size of each chunk
ChunkSizeType chunkSize_;
// page size, which is the smallest atomic read and write unit
ChunkSizeType blockSize_;
PageSizeType metaPageSize_;
PageSizeType pageSize_;
// clone chunk location length limit
uint32_t locationLimit_;
// datastore management directory

View File

@ -111,15 +111,14 @@ CSSnapshot::CSSnapshot(std::shared_ptr<LocalFileSystem> lfs,
: fd_(-1),
chunkId_(options.id),
size_(options.chunkSize),
blockSize_(options.blockSize),
metaPageSize_(options.metaPageSize),
pageSize_(options.pageSize),
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_ / blockSize_;
uint32_t bits = size_ / pageSize_;
metaPage_.bitmap = std::make_shared<Bitmap>(bits);
metaPage_.sn = options.sn;
if (metric_ != nullptr) {
@ -147,8 +146,8 @@ CSErrorCode CSSnapshot::Open(bool createFile) {
if (createFile
&& !lfs_->FileExists(snapshotPath)
&& metaPage_.sn > 0) {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
metaPage_.encode(buf.get());
int ret = chunkFilePool_->GetFile(snapshotPath, buf.get());
if (ret != 0) {
@ -218,8 +217,8 @@ CSErrorCode CSSnapshot::Write(const char * buf, off_t offset, size_t length) {
<< ",snapshot sn: " << metaPage_.sn;
return CSErrorCode::InternalError;
}
uint32_t pageBeginIndex = offset / blockSize_;
uint32_t pageEndIndex = (offset + length - 1) / blockSize_;
uint32_t pageBeginIndex = offset / pageSize_;
uint32_t pageEndIndex = (offset + length - 1) / pageSize_;
for (uint32_t i = pageBeginIndex; i <= pageEndIndex; ++i) {
dirtyPages_.insert(i);
}
@ -239,8 +238,8 @@ CSErrorCode CSSnapshot::Flush() {
}
CSErrorCode CSSnapshot::updateMetaPage(SnapshotMetaPage* metaPage) {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
metaPage->encode(buf.get());
int rc = writeMetaPage(buf.get());
if (rc < 0) {
@ -253,8 +252,8 @@ CSErrorCode CSSnapshot::updateMetaPage(SnapshotMetaPage* metaPage) {
}
CSErrorCode CSSnapshot::loadMetaPage() {
std::unique_ptr<char[]> buf(new char[metaPageSize_]);
memset(buf.get(), 0, metaPageSize_);
std::unique_ptr<char[]> buf(new char[pageSize_]);
memset(buf.get(), 0, pageSize_);
int rc = readMetaPage(buf.get());
if (rc < 0) {
LOG(ERROR) << "Error occured when reading metaPage_."

View File

@ -150,24 +150,24 @@ class CSSnapshot {
FileNameOperator::GenerateSnapshotName(chunkId_, metaPage_.sn);
}
uint32_t fileSize() const {
return metaPageSize_ + size_;
inline uint32_t fileSize() {
return pageSize_ + size_;
}
inline int readMetaPage(char* buf) {
return lfs_->Read(fd_, buf, 0, metaPageSize_);
return lfs_->Read(fd_, buf, 0, pageSize_);
}
inline int writeMetaPage(const char* buf) {
return lfs_->Write(fd_, buf, 0, metaPageSize_);
return lfs_->Write(fd_, buf, 0, pageSize_);
}
inline int readData(char* buf, off_t offset, size_t length) {
return lfs_->Read(fd_, buf, offset + metaPageSize_, length);
return lfs_->Read(fd_, buf, offset + pageSize_, length);
}
inline int writeData(const char* buf, off_t offset, size_t length) {
return lfs_->Write(fd_, buf, offset + metaPageSize_, length);
return lfs_->Write(fd_, buf, offset + pageSize_, length);
}
private:
@ -177,10 +177,9 @@ 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 metaPageSize_;
PageSizeType pageSize_;
// The directory where the snapshot file is located
std::string baseDir_;
// The metapage of the snapshot file

View File

@ -40,6 +40,8 @@ const uint8_t FORMAT_VERSION = 1;
const uint8_t FORMAT_VERSION_V2 = 2;
const SequenceNum kInvalidSeq = 0;
DECLARE_uint32(minIoAlignment);
// define error code
enum CSErrorCode {
// success
@ -80,11 +82,9 @@ struct CSChunkInfo {
// the id of the chunk
ChunkID chunkId;
// page size
uint32_t metaPageSize;
uint32_t pageSize;
// The size of the chunk
uint32_t chunkSize;
// The size of the block, smallest read/write granularity and alignment
uint32_t blockSize;
// The sequence number of the chunk file
SequenceNum curSn;
// The sequence number of the chunk snapshot,
@ -101,9 +101,8 @@ struct CSChunkInfo {
// otherwise it is nullptr
std::shared_ptr<Bitmap> bitmap;
CSChunkInfo() : chunkId(0)
, metaPageSize(4096)
, pageSize(4096)
, chunkSize(16 * 4096 * 4096)
, blockSize(4096)
, curSn(0)
, snapSn(0)
, correctedSn(0)
@ -113,9 +112,8 @@ struct CSChunkInfo {
bool operator== (const CSChunkInfo& rhs) const {
if (chunkId != rhs.chunkId ||
metaPageSize != rhs.metaPageSize ||
pageSize != rhs.pageSize ||
chunkSize != rhs.chunkSize ||
blockSize != rhs.blockSize ||
curSn != rhs.curSn ||
snapSn != rhs.snapSn ||
correctedSn != rhs.correctedSn ||

View File

@ -34,7 +34,6 @@
#include <cstring>
#include <memory>
#include <vector>
#include <utility>
#include "src/common/string_util.h"
#include "src/common/throttle.h"
@ -42,50 +41,42 @@
#include "src/common/crc32.h"
#include "src/common/curve_define.h"
#include "absl/utility/utility.h"
using curve::common::kFilePoolMagic;
using curve::common::kFilePoolMaigic;
namespace curve {
namespace chunkserver {
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 char *FilePoolHelper::kFileSize = "chunkSize";
const char *FilePoolHelper::kMetaPageSize = "metaPageSize";
const char *FilePoolHelper::kFilePoolPath = "chunkfilepool_path";
const char *FilePoolHelper::kCRC = "crc";
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);
using ::curve::common::kDefaultBlockSize;
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;
return os;
}
} // namespace
int FilePoolHelper::PersistEnCodeMetaInfo(
std::shared_ptr<LocalFileSystem> fsptr,
const FilePoolMeta& meta,
const std::string& persistPath) {
std::shared_ptr<LocalFileSystem> fsptr, uint32_t chunkSize,
uint32_t metaPageSize, const std::string &filePoolPath,
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();
root[kFileSize] = chunkSize;
root[kMetaPageSize] = metaPageSize;
root[kFilePoolPath] = filePoolPath;
uint32_t crcsize = sizeof(kFilePoolMaigic) + sizeof(chunkSize) +
sizeof(metaPageSize) + filePoolPath.size();
char *crcbuf = new char[crcsize];
::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;
root[kCRC] = crc;
int fd = fsptr->Open(persistPath.c_str(), O_RDWR | O_CREAT | O_SYNC);
if (fd < 0) {
@ -93,7 +84,7 @@ int FilePoolHelper::PersistEnCodeMetaInfo(
return -1;
}
LOG(INFO) << root.toStyledString();
LOG(INFO) << root.toStyledString().c_str();
char *writeBuffer = new char[kPersistSize];
memset(writeBuffer, 0, kPersistSize);
@ -115,11 +106,10 @@ int FilePoolHelper::PersistEnCodeMetaInfo(
}
int FilePoolHelper::DecodeMetaInfoFromMetaFile(
std::shared_ptr<LocalFileSystem> fsptr,
const std::string& metaFilePath,
uint32_t metaFileSize,
FilePoolMeta* meta) {
int fd = fsptr->Open(metaFilePath, O_RDONLY);
std::shared_ptr<LocalFileSystem> fsptr, const std::string &metaFilePath,
uint32_t metaFileSize, uint32_t *chunksize, uint32_t *metapagesize,
std::string *chunkfilePath) {
int fd = fsptr->Open(metaFilePath, O_RDWR);
if (fd < 0) {
LOG(ERROR) << "meta file open failed, " << metaFilePath;
return -1;
@ -151,7 +141,7 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile(
}
if (!value[kFileSize].isNull()) {
meta->chunkSize = value[kFileSize].asUInt();
*chunksize = value[kFileSize].asUInt();
} else {
LOG(ERROR) << "chunkfile meta file got error!"
<< " no chunksize!";
@ -159,25 +149,15 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile(
}
if (!value[kMetaPageSize].isNull()) {
meta->metaPageSize = value[kMetaPageSize].asUInt();
*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;
meta->blockSize = kDefaultBlockSize;
LOG(WARNING) << "chunkfile meta file doesn't has `" << kBlockSize
<< "`, use default value " << kDefaultBlockSize;
}
if (!value[kFilePoolPath].isNull()) {
meta->filePoolPath = value[kFilePoolPath].asString();
*chunkfilePath = value[kFilePoolPath].asString();
} else {
LOG(ERROR) << "chunkfile meta file got error!"
<< " no FilePool path!";
@ -200,10 +180,25 @@ int FilePoolHelper::DecodeMetaInfoFromMetaFile(
return -1;
}
auto crcCalc = meta->Crc32();
uint32_t crcCheckSize =
2 * sizeof(uint32_t) + sizeof(kFilePoolMaigic) + chunkfilePath->size();
std::unique_ptr<char[]> 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);
if (crcvalue != crcCalc) {
LOG(ERROR) << "crc check failed, calculate crc: " << crcCalc
<< ", record: " << crcvalue << ", decoded meta: " << *meta;
LOG(ERROR) << "crc check failed!";
return -1;
}
@ -227,7 +222,7 @@ bool FilePool::Initialize(const FilePoolOptions &cfopt) {
LOG(ERROR) << "check valid failed!";
return false;
}
if (fsptr_->DirExists(currentdir_)) {
if (fsptr_->DirExists(currentdir_.c_str())) {
return ScanInternal();
} else {
LOG(ERROR) << "chunkfile pool not exists, inited failed!"
@ -244,35 +239,21 @@ bool FilePool::Initialize(const FilePoolOptions &cfopt) {
}
bool FilePool::CheckValid() {
FilePoolMeta meta;
uint32_t chunksize = 0;
uint32_t metapagesize = 0;
std::string filePath;
int ret = FilePoolHelper::DecodeMetaInfoFromMetaFile(
fsptr_, poolOpt_.metaPath, poolOpt_.metaFileSize, &meta);
fsptr_, poolOpt_.metaPath, poolOpt_.metaFileSize, &chunksize,
&metapagesize, &filePath);
if (ret == -1) {
LOG(ERROR) << "Decode meta info from meta file failed!";
return false;
}
// reset options from meta file
if (poolOpt_.fileSize != meta.chunkSize) {
auto old = absl::exchange(poolOpt_.fileSize, meta.chunkSize);
LOG(WARNING) << "Reset file size from " << old << " to "
<< poolOpt_.fileSize;
}
if (poolOpt_.metaPageSize != meta.metaPageSize) {
auto old = absl::exchange(poolOpt_.metaPageSize, meta.metaPageSize);
LOG(WARNING) << "Reset meta page size from " << old << " to "
<< poolOpt_.metaFileSize;
}
if (poolOpt_.blockSize != meta.blockSize) {
auto old = absl::exchange(poolOpt_.blockSize, meta.blockSize);
LOG(WARNING) << "Reset block size from " << old << " to "
<< poolOpt_.blockSize;
}
currentdir_ = std::move(meta.filePoolPath);
currentState_.chunkSize = meta.chunkSize;
currentState_.metaPageSize = meta.metaPageSize;
currentState_.blockSize = meta.blockSize;
currentdir_ = filePath;
currentState_.chunkSize = chunksize;
currentState_.metaPageSize = metapagesize;
return true;
}
@ -726,38 +707,7 @@ size_t FilePool::Size() {
return currentState_.preallocatedChunksLeft;
}
FilePoolState FilePool::GetState() const {
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<char[]> 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);
}
FilePoolState_t FilePool::GetState() { return currentState_; }
} // namespace chunkserver
} // namespace curve

View File

@ -59,7 +59,6 @@ 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
@ -74,57 +73,24 @@ struct FilePoolOptions {
fileSize = 0;
metaPageSize = 0;
retryTimes = 5;
blockSize = 0;
::memset(metaPath, 0, 256);
::memset(filePoolDir, 0, 256);
}
};
struct FilePoolState {
typedef struct FilePoolState {
// How many dirty chunks are not used by the datastore
uint64_t dirtyChunksLeft = 0;
uint64_t dirtyChunksLeft;
// How many clean chunks are not used by the datastore
uint64_t cleanChunksLeft = 0;
uint64_t cleanChunksLeft;
// How many pre-allocated chunks are not used by the datastore
uint64_t preallocatedChunksLeft = 0;
uint64_t preallocatedChunksLeft;
// chunksize
uint32_t chunkSize = 0;
uint32_t chunkSize;
// metapage size
uint32_t metaPageSize = 0;
// io alignment
uint32_t 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;
};
uint32_t metaPageSize;
} FilePoolState_t;
class FilePoolHelper {
public:
@ -132,7 +98,6 @@ class FilePoolHelper {
static const char* kMetaPageSize;
static const char* kFilePoolPath;
static const char* kCRC;
static const char* kBlockSize;
static const uint32_t kPersistSize;
/**
@ -145,8 +110,10 @@ class FilePoolHelper {
* @return: success 0, otherwise -1
*/
static int PersistEnCodeMetaInfo(std::shared_ptr<LocalFileSystem> fsptr,
const FilePoolMeta& meta,
const std::string& persistPath);
uint32_t fileSize,
uint32_t metaPageSize,
const std::string& filepoolPath,
const std::string& persistPath);
/**
* Parse the current chunk pool information from the persistent meta data
@ -159,10 +126,12 @@ class FilePoolHelper {
* @return: success 0, otherwise -1
*/
static int DecodeMetaInfoFromMetaFile(
std::shared_ptr<LocalFileSystem> fsptr,
const std::string& metaFilePath,
uint32_t metaFileSize,
FilePoolMeta* meta);
std::shared_ptr<LocalFileSystem> fsptr,
const std::string& metaFilePath,
uint32_t metaFileSize,
uint32_t* fileSize,
uint32_t* metaPageSize,
std::string* filepoolPath);
};
class CURVE_CACHELINE_ALIGNMENT FilePool {
@ -197,7 +166,7 @@ class CURVE_CACHELINE_ALIGNMENT FilePool {
/**
* Get the allocation status of FilePool
*/
virtual FilePoolState GetState() const;
virtual FilePoolState_t GetState();
/**
* Get the option configuration information of the current FilePool
*/
@ -320,7 +289,7 @@ class CURVE_CACHELINE_ALIGNMENT FilePool {
FilePoolOptions poolOpt_;
// FilePool allocation status
FilePoolState currentState_;
FilePoolState_t currentState_;
// Whether the clean thread is alive
Atomic<bool> cleanAlived_;

Some files were not shown because too many files have changed in this diff Show More