Compare commits

...

34 Commits

Author SHA1 Message Date
Cyber-SiKu b4c55a04f1 [feat]curve: run deamon after start
Signed-off-by: Cyber-SiKu <Cyber-SiKu@outlook.com>
2023-04-18 09:35:44 +08:00
Cyber-SiKu b6f2c7c90d [feat]make image
Signed-off-by: Cyber-SiKu <Cyber-SiKu@outlook.com>
2023-04-18 09:35:44 +08:00
wanghai01 7dd82d6bb9 curve-nbd: change auto mount service to systemd 2021-11-19 10:01:01 +08:00
wuhanqing 2b2850a820 nbd: backup and recover curvetab 2021-11-19 10:01:01 +08:00
sean 0871306f85 ansible: fix copy file failed 2021-05-21 09:57:16 +08:00
sean d730a7f0f8 nbd: fix auto map at boot 2021-05-19 19:19:55 +08:00
sean e8ecb4992e nbd: add auto map at boot 2021-05-19 15:34:20 +08:00
chenwei ff12305692 change file param from hard code to config file 2021-04-21 10:27:24 +08:00
wuhanqing 9a39ffa9f6 client: fix potential dead lock in close file 2021-02-02 20:27:18 +08:00
xuchaojie 12c23c0feb mds/snapshotcloneserver : fix snapshot delete retry 2021-02-02 20:27:18 +08:00
wuhanqing d863271e1d nebd: fix jemalloc dependecy and shared library path 2021-01-29 10:03:08 +08:00
wuhanqing c674697424 ansible: fix nebd-daemon may stop failed 2021-01-29 10:03:08 +08:00
wuhanqing 46be3df900 scripts: fix nebd-daemon may stop failed 2021-01-29 10:03:08 +08:00
wuhanqing 441c440164 client/mds: chang some log level 2021-01-29 10:03:08 +08:00
wuhanqing 13202cf355 fix: forget set some fields in RequestSender 2021-01-27 18:52:20 +08:00
wuhanqing 8900f45b0a change some log level 2021-01-27 15:49:56 +08:00
xuchaojie a0779251e0 mds : fix clean manager retry & clone from snapshot do not send clonesource 2021-01-27 15:49:56 +08:00
wuhanqing 9f082ad9a7 client: send request source info only when clone source file segment is allocated 2021-01-27 15:49:56 +08:00
chenwei cfd58d9839 adjust log level 2021-01-27 15:49:56 +08:00
charisu c3272c4ef2 modify curve file service log level
Change-Id: I972235588f16ddbb5175b634647470e167b67593
2020-12-03 12:44:41 +08:00
xuchaojie 809a0ea7dc fix copyset codec bug 2020-12-03 12:44:41 +08:00
xuchaojie 5c1737c660 fix clone multi dest file bug 2020-12-03 12:44:41 +08:00
xuchaojie 44c4205ed0 fix snapshotclone Idempotent 2020-12-03 12:44:41 +08:00
xuchaojie 8b04e0ec42 fix ci write file fail bug 2020-11-03 10:50:10 +08:00
wuhanqing 02e39b02a6 unittest: fix client integration test failed 2020-11-03 10:50:10 +08:00
chenwei 7939ac77c7 fix mds mem leak in etcd client 2020-11-03 10:50:10 +08:00
ilixiaocui bd4ef481bf
Merge pull request #91 from xu-chaojie/release1.0
fix clone has same dest bug
2020-09-12 23:50:02 +08:00
xuchaojie ad16a38ac8 fix clone has same dest bug 2020-09-11 17:42:46 +08:00
charisu b1b78456bc modify server.ini and deploy.md 2020-08-31 14:59:00 +08:00
charisu 3e5cb8e70c Create CHANGELOG-1.0.md 2020-08-31 14:59:00 +08:00
charisu af8cd386c6 remove braft patch 2020-08-31 14:59:00 +08:00
charisu d8f7e8778e add back check health when rolling update 2020-08-28 10:04:56 +08:00
charisu 35991b9c1c add deploy monitor 2020-08-28 10:04:56 +08:00
charisu 1bd6bafa0b fix namespace_service_test 2020-08-28 10:04:56 +08:00
131 changed files with 4412 additions and 5683 deletions

1
.bazelversion Normal file
View File

@ -0,0 +1 @@
0.17.2

18
CHANGELOG-1.0.md Normal file
View File

@ -0,0 +1,18 @@
See [code changes](https://github.com/opencurve/curve/compare/v0.1.4...release1.0).
## The new features:
- Support external ip for ChunkServer to divide inter-cluster communication and communication with clients.
- The Curve_ops_tool supports printing space-info for each logical pool.
- Add snapshot clone tool.
- The curve-ansible adds deploy_monitor.yml.
## optimization
- Braft completely non-intrusive modifications.
- Replace HMacSha256 implementation.
## bug fix
- Fixed the bug that chunkserver_deploy.sh not able to delete the previous fstab record when deploy one.
- Fixed mds abort when exiting.
- Fixed curvefs_tool (curve) missing support for password.
- Fixed the bug that data from Etcd would not placed in LRU cache.
- Fixed ChunkServer not aborting when read returns an internal error.

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
# Copyright (C) 2021 Jingli Chen (Wine93), NetEase Inc.
.PHONY: list build install image clean
prefix?= "$(PWD)/projects"
release?= 0
only?= "*"
tag?= "curvebs:unknown"
tgt_pkg?= ""
list:
@bash util/build.sh --list
build:
@bash util/build.sh --only=$(only) --release=$(release)
install:
@bash util/install.sh --prefix=$(prefix) --only=$(only)
image:
@bash util/image.sh $(tag) $(tgt_pkg)
clean:
@bazel clean

View File

@ -123,7 +123,7 @@ global.fileIOSplitMaxSizeKB=64
# log等级 INFO=0/WARNING=1/ERROR=2/FATAL=3
global.logLevel=0
# 设置log的路径
global.logPath=/data/log/curve/
global.logPath=/data/log/curve/ # __CURVEADM_TEMPLATE__ /curvebs/client/logs __CURVEADM_TEMPLATE__
# 单元测试情况下
# logpath=./runlog/

View File

@ -165,6 +165,12 @@ mds.copyset.scatterWidthFloatingPercentage=20
#
# curvefs的默认chunk size大小16MB = 16*1024*1024 = 16777216
mds.curvefs.defaultChunkSize=16777216
# curvefs的默认segment size大小1GB = 1*1024*1024*1024 = 1073741824
mds.curvefs.defaultSegmentSize=1073741824
# curvefs的默认最小文件大小10GB = 10*1024*1024*1024 = 10737418240
mds.curvefs.minFileLength=10737418240
# curvefs的默认最大文件大小20TB = 20*1024*1024*1024*1024 = 21990232555520
mds.curvefs.maxFileLength=21990232555520
#
# chunkseverclient config

View File

@ -176,6 +176,12 @@ ansible-playbook deploy_curve.yml -i server.ini --tags snapshotclone
ansible-playbook deploy_curve.yml -i server.ini --tags snapshotclone_nginx
```
#### 1.10 部署监控
一键部署监控命令:
```shell
ansible-playbook deploy_monitor.yml -i server.ini
```
### 2、集群升级
目前curve的升级流程为先升级mds后升级chunkserver和快照克隆最后升级client。使用ansible需要指定一台主控机我们规定主控机为mds节点之一。ansible-playbook同时需要yml文件和inventory文件yml文件规定了要做哪些操作inventory指定了机器列表并定义了一些变量。yml文件在curve仓库的curve-ansible目录中inventory每个环境一份由用户自行管理。
@ -326,6 +332,7 @@ ansible-playbook stop_nebd_server.yml -i client.ini
├── common_tasks # 放置可以复用的代码(可以理解为各种函数)
│   ├── check_chunkserver.yml # 检查chunkserver机器配置
│   ├── check_cluster_healthy_status.yml # 检查集群健康状态
│   ├── check_docker_exists.yml # 检查是否安装了docker
│   ├── check_if_nbd_exists_in_kernel.yml # 检查内核是否有nbd模块
│   ├── check_mds.yml # 检查mds机器配置
│   ├── create_dir.yml # 创建目录
@ -341,7 +348,6 @@ ansible-playbook stop_nebd_server.yml -i client.ini
│   ├── wait_until_server_down.yml # 等待直到server停掉
│   └── wait_until_server_up.yml # 等待直到server起来
├── group_vars # 组变量
│   ├── all.yml # 属于所有host的变量
│   ├── chunkservers.yml # 属于chunkserver的变量
│   └── mds.yml # 属于mds的变量
├── host_vars # 主机变量, 其中的文件名要合inventory中定义的主机名一致
@ -394,6 +400,7 @@ ansible-playbook stop_nebd_server.yml -i client.ini
│   │   │   │   ├── copy_file_to_remote.yml # 将文件拷贝到远端
│   │   │   │   ├── install_curve-chunkserver.yml # 安装chunkserver
│   │   │   │   ├── install_curve-mds.yml # 安装mds
│   │   │   │   ├── install_curve-monitor.yml
│   │   │   │   ├── install_curve-nbd.yml # 安装nbd
│   │   │   │   ├── install_curve-sdk.yml # 安装curve-sdk
│   │   │   │   ├── install_curve-snapshotcloneserver-nginx.yml # 安装快照克隆使用的Nginx
@ -434,10 +441,15 @@ ansible-playbook stop_nebd_server.yml -i client.ini
│   │   ├── templates # 配置文件的模板
│   │   │   ├── chunkserver.conf.j2
│   │   │   ├── client.conf.j2
│   │   │   ├── docker-compose.yml.j2 # docker config for curve monitor
│   │   │   ├── etcd.conf.yml.j2
│   │   │   ├── grafana.ini.j2
│   │   │   ├── mds.conf.j2
│   │   │   ├── nebd-client.conf.j2
│   │   │   ├── nebd-server.conf.j2
│   │   │   ├── nginx_config.lua.j2
│   │   │   ├── nginx.conf.j2
│   │   │   ├── prometheus.yml.j2
│   │   │   ├── s3.conf.j2
│   │   │   ├── snapshot_clone_server.conf.j2
│   │   │   ├── snapshot_tools.conf.j2
@ -445,6 +457,9 @@ ansible-playbook stop_nebd_server.yml -i client.ini
│   │   │   └── topo.json.j2
│   │   └── vars
│   │   └── main.yml
│   ├── grafana_settings # set grafana datasource and dashboard
│   │   └── tasks
│   │   └── main.yml
│   ├── stop_service # 停止服务的role
│   │   ├── tasks
│   │   │   ├── include
@ -485,6 +500,7 @@ ansible-playbook stop_nebd_server.yml -i client.ini
├── deploy_curve.yml # 一键部署curve集群
├── deploy_etcd.yml # 部署etcd
├── deploy_mds.yml # 部署mds
├── deploy_monitor.yml # 部署监控服务
├── deploy_nbd.yml # 部署nbd
├── deploy_nebd.yml # 部署nebd
├── deploy_snapshotcloneserver_nginx.yml # 部署快照克隆所用Nginx

View File

@ -0,0 +1,32 @@
---
#
# 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.
#
# The deploy playbook of Curve
- name: check_ansible_version
tags:
- always
import_playbook: check_ansible_version.yml
- name: clean nbd
hosts: client
gather_facts: no
any_errors_fatal: true
become: "{{ sudo_or_not | bool }}"
tags:
- prepare
roles:
- { role: clean, module_name: nbd }

View File

@ -19,6 +19,8 @@ nebd_server_config_path=/etc/nebd/nebd-server.conf
nebd_data_dir=/data/nebd
nebd_log_dir=/data/log/nebd
curve_sdk_log_dir=/data/log/curve
curvetab_path=/etc/curve
curve_service_path=/etc/systemd/system
[mds:vars]
mds_port=6666
@ -30,3 +32,4 @@ ansible_ssh_port=22
lib_install_prefix=/usr/local
bin_install_prefix=/usr
ansible_connection=local
wait_service_timeout=20

View File

@ -0,0 +1,25 @@
---
#
# 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.
#
- name: check docker exist
shell: docker -v
register: docker_res
- name: fail when docker not exist
fail:
msg: "Docker should be installed on this machine!"
when: docker_res.rc != 0

View File

@ -89,7 +89,7 @@
tags: ["install_package", "install_tool_package"] }
- { role: generate_config, template_name: mds.conf, conf_path: "{{ mds_config_path }}",
tags: ["generate_config", "generage_mds_conf"] }
- { role: generate_config, template_name: tools.conf, conf_path: "{{ tool_config_path }}",
- { role: generate_config, template_name: tools.conf, conf_path: "{{ curve_ops_tool_config }}",
tags: ["generate_config", "generage_tools_conf"] }
- { role: generate_config, template_name: topo.json, conf_path: "{{ topo_file_path }}",
tags: ["generate_config", "generage_topo_json"] }
@ -202,6 +202,16 @@
############################## deploy snapshotcloneserver_nginx ##############################
- name: check docker exist
hosts: snapshotclone_nginx
any_errors_fatal: true
gather_facts: no
tags:
- snapshotclone_nginx
- never
tasks:
- include_tasks: common_tasks/check_docker_exists.yml
- name: prepare snapshotcloneserver_nginx
hosts: snapshotclone_nginx
any_errors_fatal: true

View File

@ -0,0 +1,74 @@
---
#
# 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.
#
# The deploy playbook of Curve
- name: check_ansible_version
tags:
- always
import_playbook: check_ansible_version.yml
- name: check docker exist
hosts: monitor
any_errors_fatal: true
gather_facts: no
tasks:
- include_tasks: common_tasks/check_docker_exists.yml
- name: prepare monitor
hosts: monitor
any_errors_fatal: true
gather_facts: no
become: yes
become_user: "{{ sudo_user }}"
become_flags: -iu {{ sudo_user }}
roles:
- { role: install_package, package_name: curve-monitor, package_version: "{{ monitor_package_version }}",
tags: ["install_package", "install_monitor_package"] }
- { role: install_package, package_name: curve-tools, package_version: "{{ tool_package_version }}",
tags: ["install_package", "install_tool_package"] }
- { role: generate_config, template_name: docker-compose.yml, conf_path: "{{ monitor_work_dir }}/docker-compose.yml",
tags: ["generate_config", "generage_docker_compose"] }
- { role: generate_config, template_name: grafana.ini, conf_path: "{{ monitor_work_dir }}/grafana/grafana.ini",
tags: ["generate_config", "generage_grafana_ini"] }
- { role: generate_config, template_name: prometheus.yml, conf_path: "{{ monitor_work_dir }}/prometheus/prometheus.yml",
tags: ["generate_config", "generage_prometheus_yml"] }
- { role: generate_config, template_name: tools.conf, conf_path: "{{ curve_ops_tool_config }}",
tags: ["generate_config", "generage_tools_conf"] }
- name: start monitor
hosts: monitor
any_errors_fatal: true
gather_facts: no
become: yes
become_user: "{{ sudo_user }}"
become_flags: -iu {{ sudo_user }}
tags:
- start
roles:
- { role: start_service, service_name: monitor }
- name: set grafana data source and dashboards
hosts: monitor
any_errors_fatal: true
gather_facts: no
become: yes
become_user: "{{ sudo_user }}"
become_flags: -iu {{ sudo_user }}
tags:
- grafana_settings
roles:
- { role: grafana_settings }

View File

@ -0,0 +1,23 @@
---
#
# 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.
#
- name: clean nbd auto start at boot
block:
- name: disable service
shell: sudo systemctl disable map_curve_disk.service
- name: remove map_curve_disk.service
shell: sudo rm -f {{ curve_service_path }}/map_curve_disk.service && sudo rm -f {{ curvetab_path }}/curvetab

View File

@ -19,6 +19,9 @@
curve_root_username: root
curve_root_password: root_password
chunk_size: 16777216
segment_size: 1073741824
min_file_length: 10737418240
max_file_length: 21990232555520
file_expired_time_us: 5000000
# mds配置默认值
@ -81,7 +84,7 @@ chunkserver_register_timeout: 1000
chunkserver_heartbeat_interval: 10
chunkserver_heartbeat_timeout: 5000
chunkserver_stor_uri: local://./0/
chunkserver_meta_uri: local://./0/chunkserver_dat
chunkserver_meta_uri: local://./0/chunkserver.dat
chunkserver_disk_type: nvme
chunkserver_snapshot_throttle_throughput_bytes: 20971520
chunkserver_snapshot_throttle_check_cycles: 4

View File

@ -0,0 +1,39 @@
version: '2.0'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus/:/etc/prometheus/:rw
- ./prometheus/data:/prometheus:rw
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time={{ monitor_retention_time }}'
- '--storage.tsdb.retention.size={{ monitor_retention_size }}'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.listen-address=:{{ prometheus_listen_port }}'
network_mode: host
grafana:
image: grafana/grafana
depends_on:
- prometheus
network_mode: host
volumes:
- ./grafana/data:/var/lib/grafana:rw
- ./grafana/grafana.ini:/etc/grafana/grafana.ini:rw
environment:
- GF_INSTALL_PLUGINS=grafana-piechart-panel
- GF_SECURITY_ADMIN_USER={{ grafana_username }}
- GF_SECURITY_ADMIN_PASSWORD={{ grafana_password }}
reporter:
image: promoon/reporter:latest
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./grafana/report:/tmp/report:rw
network_mode: host

View File

@ -0,0 +1,597 @@
#
# Copyright (c) 2020 NetEase Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
##################### Grafana Configuration Example #####################
#
# Everything has defaults so you only need to uncomment things you want to
# change
# possible values : production, development
;app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
;instance_name = ${HOSTNAME}
#################################### Paths ####################################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
;data = /var/lib/grafana
# Temporary files in `data` directory older than given duration will be removed
;temp_data_lifetime = 24h
# Directory where grafana can store logs
;logs = /var/log/grafana
# Directory where grafana will automatically scan and look for plugins
;plugins = /var/lib/grafana/plugins
# folder that contains provisioning config files that grafana will apply on startup and while running.
;provisioning = conf/provisioning
#################################### Server ####################################
[server]
# Protocol (http, https, socket)
;protocol = http
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
# The http port to use
;http_port = {{ grafana_listen_port }}
# The public facing domain name used to access grafana from a browser
;domain = localhost
# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false
# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = http://localhost:3000
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
;serve_from_sub_path = false
# Log web requests
;router_logging = false
# the path relative working path
;static_root_path = public
# enable gzip
;enable_gzip = false
# https certs & key file
;cert_file =
;cert_key =
# Unix socket path
;socket =
#################################### Database ####################################
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as separate properties or as on string using the url properties.
# Either "mysql", "postgres" or "sqlite3", it's your choice
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
;password =
# Use either URL or the previous fields to configure the database
# Example: mysql://user:secret@host:port/database
;url =
# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable
# For "sqlite3" only, path relative to data_path setting
;path = grafana.db
# Max idle conn setting default is 2
;max_idle_conn = 2
# Max conn setting default is 0 (mean not set)
;max_open_conn =
# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
;conn_max_lifetime = 14400
# Set to true to log the sql calls and execution times.
;log_queries =
# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
;cache_mode = private
#################################### Cache server #############################
[remote_cache]
# Either "redis", "memcached" or "database" default is "database"
;type = database
# cache connectionstring options
# database: will use Grafana primary database.
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0`. Only addr is required.
# memcache: 127.0.0.1:11211
;connstr =
#################################### Data proxy ###########################
[dataproxy]
# This enables data proxy logging, default is false
;logging = false
# How long the data proxy should wait before timing out default is 30 (seconds)
;timeout = 30
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
;send_user_header = false
#################################### Analytics ####################################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
;reporting_enabled = true
# Set to false to disable all checks to https://grafana.net
# for new vesions (grafana itself and plugins), check is used
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to http://grafana.com to get latest versions
;check_for_updates = true
# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =
# Google Tag Manager ID, only enabled if you specify an id here
;google_tag_manager_id =
#################################### Security ####################################
[security]
# default admin user, created on startup
;admin_user = admin
# default admin password, can be changed before first start of grafana, or in profile settings
;admin_password = admin
# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm
# disable gravatar profile images
;disable_gravatar = false
# data source proxy whitelist (ip_or_domain:port separated by spaces)
;data_source_proxy_whitelist =
# disable protection against brute force login attempts
;disable_brute_force_login_protection = false
# set to true if you host Grafana behind HTTPS. default is false.
;cookie_secure = false
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict" and "none"
;cookie_samesite = lax
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
;allow_embedding = false
# Set to true if you want to enable http strict transport security (HSTS) response header.
# This is only sent when HTTPS is enabled in this configuration.
# HSTS tells browsers that the site should only be accessed using HTTPS.
# The default version will change to true in the next minor release, 6.3.
;strict_transport_security = false
# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
;strict_transport_security_max_age_seconds = 86400
# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
;strict_transport_security_preload = false
# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
;strict_transport_security_subdomains = false
# Set to true to enable the X-Content-Type-Options response header.
# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
# in the Content-Type headers should not be changed and be followed. The default will change to true in the next minor release, 6.3.
;x_content_type_options = false
# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
# when they detect reflected cross-site scripting (XSS) attacks. The default will change to true in the next minor release, 6.3.
;x_xss_protection = false
#################################### Snapshots ###########################
[snapshots]
# snapshot sharing options
;external_enabled = true
;external_snapshot_url = https://snapshots-origin.raintank.io
;external_snapshot_name = Publish to snapshot.raintank.io
# remove expired snapshot
;snapshot_remove_expired = true
#################################### Dashboards History ##################
[dashboards]
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
;versions_to_keep = 20
#################################### Users ###############################
[users]
# disable user signup / registration
;allow_sign_up = true
# Allow non admin users to create organizations
;allow_org_create = true
# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true
# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer
# Background text for the user field on the login page
;login_hint = email or username
;password_hint = password
# Default UI theme ("dark" or "light")
;default_theme = dark
# External user management, these options affect the organization users view
;external_manage_link_url =
;external_manage_link_name =
;external_manage_info =
# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
;viewers_can_edit = false
# Editors can administrate dashboard, folders and teams they create
;editors_can_admin = false
[auth]
# Login cookie name
;login_cookie_name = grafana_session
# The lifetime (days) an authenticated user can be inactive before being required to login at next visit. Default is 7 days,
;login_maximum_inactive_lifetime_days = 7
# The maximum lifetime (days) an authenticated user can be logged in since login time before being required to login. Default is 30 days.
;login_maximum_lifetime_days = 30
# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
;token_rotation_interval_minutes = 10
# Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
;disable_login_form = false
# Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false
;disable_signout_menu = false
# URL to redirect the user to after sign out
;signout_redirect_url =
# Set to true to attempt login with OAuth automatically, skipping the login screen.
# This setting is ignored if multiple OAuth providers are configured.
;oauth_auto_login = false
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
;enabled = false
# specify organization name that should be used for unauthenticated users
;org_name = Main Org.
# specify role for unauthenticated users
;org_role = Viewer
#################################### Github Auth ##########################
[auth.github]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
;api_url = https://api.github.com/user
;team_ids =
;allowed_organizations =
#################################### Google Auth ##########################
[auth.google]
;enabled = false
;allow_sign_up = true
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
;auth_url = https://accounts.google.com/o/oauth2/auth
;token_url = https://accounts.google.com/o/oauth2/token
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
;allowed_domains =
#################################### Generic OAuth ##########################
[auth.generic_oauth]
;enabled = false
;name = OAuth
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://foo.bar/login/oauth/authorize
;token_url = https://foo.bar/login/oauth/access_token
;api_url = https://foo.bar/user
;team_ids =
;allowed_organizations =
;tls_skip_verify_insecure = false
;tls_client_cert =
;tls_client_key =
;tls_client_ca =
; Set to true to enable sending client_id and client_secret via POST body instead of Basic authentication HTTP header
; This might be required if the OAuth provider is not RFC6749 compliant, only supporting credentials passed via POST payload
;send_client_credentials_via_post = false
#################################### SAML Auth ###########################
;[auth.saml] # Enterprise only
;enabled = false
;private_key =
;private_key_path =
;certificate =
;certificate_path =
;idp_metadata =
;idp_metadata_path =
;idp_metadata_url =
;max_issue_delay = 90s
;metadata_valid_duration = 48h
#################################### Grafana.com Auth ####################
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =
#################################### Auth Proxy ##########################
[auth.proxy]
;enabled = false
;header_name = X-WEBAUTH-USER
;header_property = username
;auto_sign_up = true
;ldap_sync_ttl = 60
;whitelist = 192.168.1.1, 192.168.2.1
;headers = Email:X-User-Email, Name:X-User-Name
#################################### Basic Auth ##########################
[auth.basic]
;enabled = true
#################################### Auth LDAP ##########################
[auth.ldap]
;enabled = false
;config_file = /etc/grafana/ldap.toml
;allow_sign_up = true
# LDAP backround sync (Enterprise only)
# At 1 am every day
;sync_cron = "0 0 1 * * *"
;active_sync_enabled = true
#################################### SMTP / Emailing ##########################
[smtp]
;enabled = false
;host = localhost:25
;user =
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
;password =
;cert_file =
;key_file =
;skip_verify = false
;from_address = admin@grafana.localhost
;from_name = Grafana
# EHLO identity in SMTP dialog (defaults to instance_name)
;ehlo_identity = dashboard.example.com
[emails]
;welcome_email_on_sign_up = false
#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and file
# Use space to separate multiple modes, e.g. "console file"
;mode = console file
# Either "debug", "info", "warn", "error", "critical", default is "info"
;level = info
# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
;filters =
# For "console" mode only
[log.console]
;level =
# log line format, valid options are text, console and json
;format = console
# For "file" mode only
[log.file]
;level =
# log line format, valid options are text, console and json
;format = text
# This enables automated log rotate(switch of following options), default is true
;log_rotate = true
# Max line number of single file, default is 1000000
;max_lines = 1000000
# Max size shift of single file, default is 28 means 1 << 28, 256MB
;max_size_shift = 28
# Segment log daily, default is true
;daily_rotate = true
# Expired days of log file(delete after max days), default is 7
;max_days = 7
[log.syslog]
;level =
# log line format, valid options are text, console and json
;format = text
# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
;network =
;address =
# Syslog facility. user, daemon and local0 through local7 are valid.
;facility =
# Syslog tag. By default, the process' argv[0] is used.
;tag =
#################################### Alerting ############################
[alerting]
# Disable alerting engine & UI features
;enabled = true
# Makes it possible to turn off alert rule execution but alerting UI is visible
;execute_alerts = true
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
;error_or_timeout = alerting
# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
;nodata_or_nullvalues = no_data
# Alert notifications can include images, but rendering many images at the same time can overload the server
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
;concurrent_render_limit = 5
# Default setting for alert calculation timeout. Default value is 30
;evaluation_timeout_seconds = 30
# Default setting for alert notification timeout. Default value is 30
;notification_timeout_seconds = 30
# Default setting for max attempts to sending alert notifications. Default value is 3
;max_attempts = 3
#################################### Explore #############################
[explore]
# Enable the Explore section
;enabled = true
#################################### Internal Grafana Metrics ##########################
# Metrics available at HTTP API Url /metrics
[metrics]
# Disable / Enable internal metrics
;enabled = true
# Publish interval
;interval_seconds = 10
# Send internal metrics to Graphite
[metrics.graphite]
# Enable by setting the address setting (ex localhost:2003)
;address =
;prefix = prod.grafana.%(instance_name)s.
#################################### Distributed tracing ############
[tracing.jaeger]
# Enable by setting the address sending traces to jaeger (ex localhost:6831)
;address = localhost:6831
# Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
;always_included_tag = tag1:value1
# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
;sampler_type = const
# jaeger samplerconfig param
# for "const" sampler, 0 or 1 for always false/true respectively
# for "probabilistic" sampler, a probability between 0 and 1
# for "rateLimiting" sampler, the number of spans per second
# for "remote" sampler, param is the same as for "probabilistic"
# and indicates the initial sampling rate before the actual one
# is received from the mothership
;sampler_param = 1
# Whether or not to use Zipkin propagation (x-b3- HTTP headers).
;zipkin_propagation = false
# Setting this to true disables shared RPC spans.
# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
;disable_shared_zipkin_spans = false
#################################### Grafana.com integration ##########################
# Url used to import dashboards directly from Grafana.com
[grafana_com]
;url = https://grafana.com
#################################### External image storage ##########################
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
# you can choose between (s3, webdav, gcs, azure_blob, local)
;provider =
[external_image_storage.s3]
;bucket =
;region =
;path =
;access_key =
;secret_key =
[external_image_storage.webdav]
;url =
;public_url =
;username =
;password =
[external_image_storage.gcs]
;key_file =
;bucket =
;path =
[external_image_storage.azure_blob]
;account_name =
;account_key =
;container_name =
[external_image_storage.local]
# does not require any configuration
[rendering]
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
;server_url =
;callback_url =
[enterprise]
# Path to a valid Grafana Enterprise license.jwt file
;license_path =
[panels]
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
;disable_sanitize_html = false
[plugins]
;enable_alpha = false
;app_tls_skip_verify_insecure = false

View File

@ -173,6 +173,12 @@ mds.copyset.scatterWidthFloatingPercentage={{ mds_copyset_scatterwidth_floating_
#
# curvefs的默认chunk size大小16MB = 16*1024*1024 = 16777216
mds.curvefs.defaultChunkSize={{ chunk_size }}
# curvefs的默认segment size大小1GB = 1*1024*1024*1024 = 1073741824
mds.curvefs.defaultSegmentSize={{ segment_size }}
# curvefs的默认最小文件大小10GB = 10*1024*1024*1024 = 10737418240
mds.curvefs.minFileLength={{ min_file_length }}
# curvefs的默认最大文件大小20TB = 20*1024*1024*1024*1024 = 21990232555520
mds.curvefs.maxFileLength={{ max_file_length }}
#
# chunkseverclient config

View File

@ -0,0 +1,53 @@
#
# Copyright (c) 2020 NetEase Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# my global config
global:
scrape_interval: {{ prometheus_scrape_interval }} # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: {{ prometheus_evaluation_interval }} # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'curve_metrics'
file_sd_configs:
- files: ['*.json']

View File

@ -7,7 +7,7 @@
{% endfor -%}
mdsAddr={{ mds_address | join(',') }}
# mds dummy port
mdsDummyPort={{ mds_dummy_port }}
mdsDummyPort={{ hostvars[groups.mds[0]].mds_dummy_port }}
# 发送rpc的超时时间
rpcTimeout={{ tool_rpc_timeout }}
# rpc重试次数

View File

@ -0,0 +1,36 @@
---
#
# 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.
#
- name: set grafana datasource
grafana_datasource:
grafana_url: "http://localhost:{{ grafana_listen_port }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
access: proxy
ds_type: prometheus
is_default: true
name: Prometheus
org_id: 1
url: "localhost:{{ prometheus_listen_port }}"
- name: set grafana dashboard
shell: >
cat {{ item }} | jq '. * {overwrite: true, dashboard: {id: null}}' |
curl -s -X POST -H "Content-Type: application/json" --user {{ grafana_username }}:{{ grafana_password }}
localhost:{{ grafana_listen_port }}/api/dashboards/db -d @-
with_fileglob:
- "{{ monitor_work_dir }}/grafana/dashboards/*"

View File

@ -29,6 +29,9 @@ local_nebd_package_path: ../../nebd-package
local_nbd_package_path: ../../nbd-package
snapshot_clone_server_log_dir: /data/log/curve/snapshotclone
local_snapshotcloneserver_package_path: ../curve-snapshotcloneserver
local_monitor_package_path: ../../curve-monitor
curvetab_path: /etc/curve
curve_service_path: /etc/systemd/system
local_snapshotcloneserver_nginx_package_path: ../curve-nginx
snapshotcloneserver_nginx_dir: /etc/curve/nginx

View File

@ -0,0 +1,41 @@
---
#
# 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.
#
- name: pull prom/prometheus:latest
shell: sudo docker image pull prom/prometheus:latest
- name: pull grafana/grafana:latest
shell: sudo docker image pull grafana/grafana:latest
- name: promoon/reporter:latest
shell: sudo docker image pull promoon/reporter:latest
- name: install jq
vars:
apt_lib_name: jq
yum_lib_name: jq
include_tasks: common_tasks/install_with_yum_apt.yml
- name: install monitor work space
vars:
remote_dir_name: "{{ monitor_work_dir }}"
local_file_path: "{{ local_monitor_package_path }}/"
file_mode: 0777
include_tasks: copy_file_to_remote.yml
- name: generate curve-monitor.sh
template: src=curve-monitor.sh.j2 dest={{ deploy_dir }}/curve-monitor.sh mode=0755

View File

@ -33,3 +33,34 @@
local_file_path: "{{ local_nbd_package_path }}/bin/"
file_mode: 0755
include_tasks: copy_file_to_remote.yml
- name: check curvetab exist
stat:
path: "{{ curvetab_path }}/curvetab"
register: file_status
- name: install curvetab if not exist
vars:
remote_dir_name: "{{ curvetab_path }}"
local_file_path: "{{ local_nbd_package_path }}/etc/curvetab"
file_mode: 0755
include_tasks: copy_file_to_remote.yml
when: not file_status.stat.exists
- name: install map_curve_disk.sh
vars:
remote_dir_name: "{{ curve_bin_dir }}"
local_file_path: "{{ local_nbd_package_path }}/bin/map_curve_disk.sh"
file_mode: 0755
include_tasks: copy_file_to_remote.yml
- name: add nbd auto start at boot
block:
- name: install map_curve_disk.service
vars:
remote_dir_name: "{{ curve_service_path }}"
local_file_path: "{{ local_nbd_package_path }}/etc/map_curve_disk.service"
file_mode: 0755
include_tasks: copy_file_to_remote.yml
- name: enable service
shell: sudo systemctl daemon-reload && sudo systemctl enable map_curve_disk.service && sudo systemctl start map_curve_disk.service

View File

@ -0,0 +1,66 @@
#!/bin/sh
#sh update_dashboard.sh
#echo "update dashboards success!"
WORKDIR={{ monitor_work_dir }}
if [ ! -d $WORKDIR ]; then
echo "${WORKDIR} not exists"
exit 1
fi
cd $WORKDIR
chmod -R 777 prometheus
chmod -R 777 grafana
start() {
echo "==========start==========="
echo "" > monitor.log
stdbuf -oL python target_json.py >> monitor.log 2>&1 &
echo "start prometheus targets service success!"
docker-compose up >> monitor.log 2>&1 &
echo "start metric system success!"
}
stop() {
echo "===========stop============"
docker-compose down
ID=`(ps -ef | grep "target_json.py"| grep -v "grep") | awk '{print $2}'`
for id in $ID
do
kill -9 $id
echo "killed $id"
done
}
restart() {
stop
echo "sleeping........."
sleep 3
start
}
case "$1" in
'start')
start
;;
'stop')
stop
;;
'status')
status
;;
'restart')
restart
;;
*)
echo "usage: $0 {start|stop|restart}"
exit 1
;;
esac

View File

@ -37,7 +37,7 @@ daemonLog=${baseLogPath}/nebd-server-daemon.log
consoleLog=${baseLogPath}/nebd-server-console.log
function get_nebd_server_pid() {
local tmp=`ps -ef | grep nebd-server | grep -v grep | grep -v daemon | awk '{print $2}'`
local tmp=`pidof nebd-server`
echo $tmp
}
@ -103,11 +103,11 @@ function start() {
exit 1
fi
jemallocpath={{ jemalloc_path }}
# 检查jemalloc库文件
if [ ! -f ${jemallocpath} ]
jemallocpath=`find /usr/ -name "libjemalloc.so*" -print -quit`
if [ "${jemallocpath}" = "" ]
then
echo "Not found jemalloc library, Path is ${jemallocpath}"
echo "Not found jemalloc library in /usr/"
exit 1
fi
@ -146,6 +146,27 @@ function stop() {
then
echo "stop may not success!"
else
# wait 3s
retry_times=0
while [ $retry_times -le 3 ]
do
((retry_times=$retry_times+1))
pidof nebd-server > /dev/null 2>&1
if [ $? -eq 0 ]
then
sleep 1
else
break
fi
done
pidof nebd-server > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "nebd-server still exists after 3s, now kill it with SIGKILL"
kill -9 `pidof nebd-server`
fi
echo "nebd-server exit success!"
echo "daemon exit success!"
fi
@ -170,7 +191,7 @@ function restart() {
if [ $old_pid == $new_pid ]
then
echo "restart nebd-server may failed, try kill -9 nebd-server"
echo "restart nebd-server may failed, now kill it with SIGKILL"
kill -9 $old_pid
fi
}

View File

@ -0,0 +1,18 @@
---
#
# 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.
#
check_health: false

View File

@ -20,5 +20,4 @@
ch_dir: "{{ deploy_dir }}"
daemon_script: ./etcd-daemon.sh
service_port: "{{ etcd_listen_client_port }}"
check_health: true
include_tasks: restart_by_daemon.yml

View File

@ -32,6 +32,5 @@
ch_dir: "{{ deploy_dir }}"
daemon_script: ./mds-daemon.sh
service_port: "{{ mds_dummy_port }}"
check_health: true
include_tasks: restart_by_daemon.yml
when: need_restart

View File

@ -23,7 +23,7 @@
- name: get nebd version
vars:
service_port: "{{ nebd_port }}"
metric_port: "{{ nebd_port }}"
nebd_version:
include_tasks: common_tasks/get_nebd_version_from_metric.yml
@ -41,7 +41,6 @@
vars:
ch_dir: "{{ deploy_dir }}"
daemon_script: nebd-daemon
ping_port: "{{ nebd_port }}"
check_health: false
service_port: "{{ nebd_port }}"
include_tasks: restart_by_daemon.yml
when: need_restart

View File

@ -32,6 +32,5 @@
ch_dir: "{{ deploy_dir }}"
daemon_script: ./snapshot-daemon.sh
service_port: "{{ snapshot_dummy_port }}"
check_health: true
include_tasks: restart_by_daemon.yml
when: need_restart

View File

@ -24,6 +24,7 @@
shell: chdir={{ ch_dir }} {{ sudo }} {{ daemon_script }} start
- name: wait until server is up
ping_port: "{{ service_port }}"
wait_timeout: "{{ wait_service_timeout }}"
vars:
ping_port: "{{ service_port }}"
wait_timeout: "{{ wait_service_timeout }}"
include_tasks: common_tasks/wait_until_server_up.yml

View File

@ -0,0 +1,31 @@
---
#
# 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.
#
- name: start monitor
shell: chdir={{ deploy_dir }} sudo ./curve-monitor.sh start
- name: wait until prometheus is up
vars:
ping_port: "{{ prometheus_listen_port }}"
wait_timeout: "{{ wait_service_timeout }}"
include_tasks: common_tasks/wait_until_server_up.yml
- name: wait until grafana is up
vars:
ping_port: "{{ grafana_listen_port }}"
wait_timeout: "{{ wait_service_timeout }}"
include_tasks: common_tasks/wait_until_server_up.yml

View File

@ -82,7 +82,7 @@
tags: ["install_package", "install_tool_package"] }
- { role: generate_config, template_name: mds.conf, conf_path: "{{ mds_config_path }}",
tags: ["generate_config", "generage_mds_conf"] }
- { role: generate_config, template_name: tools.conf, conf_path: "{{ tool_config_path }}",
- { role: generate_config, template_name: tools.conf, conf_path: "{{ curve_ops_tool_config }}",
tags: ["generate_config", "generage_tools_conf"] }
- { role: generate_config, template_name: topo.json, conf_path: "{{ topo_file_path }}",
tags: ["generate_config", "generage_topo_json"] }
@ -142,7 +142,7 @@
- { role: generate_config, template_name: chunkserver.conf, conf_path: "{{ chunkserver_conf_path }}",
tags: ["generate_config", "generage_chunkserver_conf"] }
- { role: generate_config, template_name: client.conf, conf_path: "{{ chunkserver_client_config_path }}",
tags: ["generate_config", "generage_chunkserver_conf"] }
tags: ["generate_config", "generage_chunkserver_client_conf"] }
- { role: generate_config, template_name: s3.conf, conf_path: "{{ chunkserver_s3_config_path }}",
tags: ["generate_config", "generage_s3_conf"] }

View File

@ -21,28 +21,19 @@
- always
import_playbook: check_ansible_version.yml
- name: update config
- name: prepare nebd
hosts: client
gather_facts: no
any_errors_fatal: true
tags:
- update_config
- prepare
roles:
- { role: install_package, package_name: nebd, package_version: "{{ nebd_package_version }}",
tags: ["install_package"] }
- { role: generate_config, template_name: client.conf, conf_path: "{{ client_config_path }}" }
- { role: generate_config, template_name: nebd-client.conf, conf_path: "{{ nebd_client_config_path }}" }
- { role: generate_config, template_name: nebd-server.conf, conf_path: "{{ nebd_server_config_path }}" }
- name: update package
hosts: client
gather_facts: no
any_errors_fatal: true
tags:
- update_package
tasks:
- vars:
update_component: "nebd={{ nebd_package_version }}"
include_tasks: "common_tasks/update_package.yml"
- name: restart nebd server
hosts: client
gather_facts: no

View File

@ -14,6 +14,9 @@ localhost ansible_ssh_host=127.0.0.1
[chunkservers]
localhost ansible_ssh_host=127.0.0.1
[monitor]
localhost ansible_ssh_host=127.0.0.1
[mds:vars]
mds_dummy_port=6667
mds_port=6666
@ -24,7 +27,6 @@ tool_package_version="0.0.6.1+160be351"
# 启动命令是否用sudo
mds_need_sudo=true
mds_config_path=/etc/curve/mds.conf
tool_config_path=/etc/curve/tools.conf
mds_log_dir=/data/log/curve/mds
topo_file_path=/etc/curve/topo.json
@ -49,7 +51,6 @@ snapshot_need_sudo=true
snapshot_config_path=/etc/curve/snapshot_clone_server.conf
snap_s3_config_path=/etc/curve/s3.conf
snap_client_config_path=/etc/curve/snap_client.conf
snap_tool_config_path=/etc/curve/snapshot_tools.conf
client_register_to_mds=false
client_chunkserver_op_max_retry=50
client_chunkserver_max_rpc_timeout_ms=16000
@ -98,11 +99,24 @@ nginx_docker_external_port=5555
snapshot_nginx_name=curve-snapshotclone-nginx
snapshot_nginx_vip=127.0.0.1
[monitor:vars]
monitor_work_dir=/etc/curve/monitor
monitor_retention_time=7d
monitor_retention_size=256GB
prometheus_listen_port=9090
prometheus_scrape_interval=3s
prometheus_evaluation_interval=15s
grafana_username=curve
grafana_password=123
grafana_listen_port=3000
monitor_package_version="0.0.6.1.1+7af4d6a4"
[all:vars]
need_confirm=true
curve_ops_tool_config=/etc/curve/tools.conf
snap_tool_config_path=/etc/curve/snapshot_tools.conf
need_update_config=true
wait_service_timeout=10
wait_service_timeout=20
sudo_user=curve
deploy_dir=/home/curve
s3_ak=""
@ -115,3 +129,4 @@ curve_root_password=root_password
lib_install_prefix=/usr/local
bin_install_prefix=/usr
ansible_connection=local
check_health=false

11
docker/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM opencurvedocker/curvebs-base:debian9
ENV TZ=Asia/Shanghai
RUN mkdir -p /curvebs /etc/curve /etc/nebd /core /curve/init.d/
COPY curvebs /curvebs
COPY entrypoint.sh /
COPY curvebs/tools/sbin/curve_ops_tool curvebs/nbd/sbin/curve-nbd /usr/bin/
RUN ([ -f /curvebs/curvebs_tgt.deb ] && dpkg -i /curvebs/curvebs_tgt.deb && rm /curvebs/curvebs_tgt.deb) \
&& mv /curvebs/lib /usr/lib/nebd \
&& chmod a+x /entrypoint.sh \
&& apt update && apt install -y kmod
ENTRYPOINT ["/entrypoint.sh"]

127
docker/entrypoint.sh Normal file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env bash
# Copyright (C) 2021 Jingli Chen (Wine93), NetEase Inc.
############################ GLOBAL VARIABLES
g_role=""
g_args=""
g_prefix=""
g_preexec="/curvebs/tools-v2/sbin/daemon"
g_binary=""
g_start_args=""
############################ BASIC FUNCTIONS
function msg() {
printf '%b' "$1" >&2
}
function success() {
msg "\33[32m[✔]\33[0m ${1}${2}"
}
function die() {
msg "\33[31m[✘]\33[0m ${1}${2}"
exit 1
}
############################ FUNCTIONS
function usage () {
cat << _EOC_
Usage:
entrypoint.sh --role=ROLE
entrypoint.sh --role=ROLE --args=ARGS
Examples:
entrypoint.sh --role=etcd
entrypoint.sh --role=client --args="-o default_permissions"
_EOC_
}
function get_options() {
local long_opts="role:,args:,help"
local args=`getopt -o ra --long $long_opts -n "$0" -- "$@"`
eval set -- "${args}"
while true
do
case "$1" in
-r|--role)
g_role=$2
shift 2
;;
-a|--args)
g_args=$2
shift 2
;;
-h)
usage
exit 1
;;
--)
shift
break
;;
*)
exit 1
;;
esac
done
}
function prepare() {
g_prefix="/curvebs/$g_role"
conf_path="$g_prefix/conf/$g_role.conf"
case $g_role in
etcd)
g_binary="$g_prefix/sbin/etcd"
g_start_args="--config-file $conf_path"
;;
mds)
g_binary="$g_prefix/sbin/curvebs-mds"
g_start_args="--confPath $conf_path"
;;
chunkserver)
g_binary="$g_prefix/sbin/curvebs-chunkserver"
g_start_args="--conf=$conf_path"
;;
snapshotclone)
g_preexec="/usr/sbin/nginx -c $g_prefix/conf/nginx.conf"
g_binary="$g_prefix/sbin/curvebs-snapshotclone"
g_start_args="--conf=$conf_path"
;;
nebd)
g_binary="$g_prefix/sbin/nebd-server"
g_start_args="-confPath=$g_prefix/conf/nebd-server.conf -log_dir=$g_prefix/logs"
;;
*)
usage
exit 1
;;
esac
if [ "$g_args" != "" ]; then
g_start_args=$g_args
fi
}
function create_directory() {
chmod 700 "$g_prefix/data"
if [ "$g_role" == "etcd" ]; then
mkdir -p "$g_prefix/data/wal"
elif [ "$g_role" == "client" ]; then
mkdir -p "$g_prefix/mnt"
fi
}
function main() {
get_options "$@"
prepare
create_directory
[[ $(command -v crontab) ]] && cron
[[ ! -z $g_preexec ]] && $g_preexec &
exec $g_binary $g_start_args
}
############################ MAIN()
main "$@"

View File

@ -65,6 +65,7 @@ ansible是一款自动化运维工具curve-ansible 是基于 ansible playbook
$ pip install --upgrade pip
$ pip install --upgrade setuptools
```
4. 确保源里面有以下几个包net-tools, openssl>=1.1.1, perf, perl-podlators, make
##### Debian9环境准备具体步骤
1. root用户登录机器创建curve用户
@ -88,6 +89,7 @@ ansible是一款自动化运维工具curve-ansible 是基于 ansible playbook
$ pip install --upgrade pip
$ pip install --upgrade setuptools
```
4. 确保源里面有以下几个包net-tools, openssl>=1.1.1, perf, perl-podlators, make
#### 实施部署
@ -153,7 +155,10 @@ ansible是一款自动化运维工具curve-ansible 是基于 ansible playbook
curve-nbd list-mapped
```
9. 部署监控(可选)。关于监控体系的文档见[curve监控体系文档](./monitor.md)监控的部署需要用到docker编排首先请先确保安装了docker和docker-compose。其次需要在curve包的同一级目录下下载并解压curve-monitor的tar包。
```
ansible-playbook deploy_monitor.yml -i server.ini
```
## 多机部署
@ -196,7 +201,7 @@ ansible是一款自动化运维工具curve-ansible 是基于 ansible playbook
$ su curve # 切换到curve用户
$ sudo ls # 测试sudo是否正确配置
```
3. 检查其他依赖未安装的需要手动安装net-tools, openssl-1.1.1, perf, perl-podlators, make, gcc6.1, libstdc++.so.6.22
3. 确保源里面有以下几个包net-tools, openssl>=1.1.1, perf, perl-podlators, make
下面的步骤只需要在中控机上执行:
1. curve用户下配置ssh登陆到所有机器包括自己假设三台机器的ip分别为10.192.100.1,10.192.100.2,10.192.100.3
@ -216,6 +221,7 @@ ansible是一款自动化运维工具curve-ansible 是基于 ansible playbook
$ ansible-playbook # 如果没有报错的话说明安装成功,报错的话执行下面两步
$ pip install --upgrade pip
$ pip install --upgrade setuptools
3. 确保源里面有以下几个包net-tools, openssl>=1.1.1, perf, perl-podlators, make
#### Debian9环境准备步骤
下面这些步骤要三台机器都操作:

View File

@ -1,4 +1,4 @@
目前curve可以通过CSI插件的方式对接Kubernetes。本文给出的是CSI插件开发指导说明。内部使用的Curve CSI插件目前在联调测试中后续会开源出来
目前curve可以通过CSI插件的方式对接Kubernetes。本文给出的是CSI插件开发指导说明。curve csi插件源码请见[curve-csi](https://github.com/opencurve/curve-csi)
## Curve Interface

View File

@ -325,22 +325,8 @@ fi
# README
# curve-monitor
mkdir -p build/curve-monitor/bin
if [ $? -ne 0 ]
then
exit
fi
mkdir -p build/curve-monitor/etc/curve/monitor
if [ $? -ne 0 ]
then
exit
fi
cp monitor/curve-monitor.sh build/curve-monitor/bin/curve-monitor.sh
if [ $? -ne 0 ]
then
exit
fi
cp -r monitor/* build/curve-monitor/etc/curve/monitor
mkdir -p build/curve-monitor
cp -r monitor/* build/curve-monitor/
if [ $? -ne 0 ]
then
exit
@ -360,7 +346,11 @@ cp bazel-bin/nebd/src/part2/nebd-server build/nebd-package/bin
# step 3.2 prepare for curve-nbd package
mkdir -p build/nbd-package/bin
mkdir -p build/nbd-package/etc
cp bazel-bin/nbd/src/curve-nbd build/nbd-package/bin
cp nbd/nbd-package/usr/bin/map_curve_disk.sh build/nbd-package/bin
cp nbd/nbd-package/etc/curve/curvetab build/nbd-package/etc
cp nbd/nbd-package/etc/systemd/system/map_curve_disk.service build/nbd-package/etc
#step4 获取git提交版本信息
commit_id=`git show --abbrev-commit HEAD|head -n 1|awk '{print $2}'`

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -7833,4 +7834,5 @@
"title": "ChunkServer",
"uid": "4r3JKSGWz",
"version": 3
}
}

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -2446,4 +2447,5 @@
"title": "Client",
"uid": "DCy23HnWk",
"version": 5
}
}

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -2515,4 +2516,5 @@
"title": "Etcd",
"uid": "EuLA2DVZz",
"version": 135
}
}

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -2738,4 +2739,5 @@
"title": "MDS",
"uid": "EpuJscnWk",
"version": 7
}
}

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -3739,4 +3740,5 @@
"title": "Report",
"uid": "nj1Iq_2Wk",
"version": 14
}
}

View File

@ -1,4 +1,5 @@
{
"dashboard": {
"annotations": {
"list": [
{
@ -1052,4 +1053,5 @@
"title": "SnapshotCloneServer",
"uid": "TZzWso-Wz",
"version": 2
}
}

19
nbd/nbd-package/DEBIAN/postinst Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
set -e
chmod +x /usr/bin/map_curve_disk.sh
systemctl daemon-reload
systemctl enable map_curve_disk.service
systemctl start map_curve_disk.service
CURVETAB=/etc/curve/curvetab
CURVETABBAK=/etc/curve/curvetab-bak
if [ -f ${CURVETABBAK} ]; then
cp -f -p ${CURVETABBAK} ${CURVETAB}
rm -f ${CURVETABBAK}
fi
exit 0

12
nbd/nbd-package/DEBIAN/preinst Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
CURVETAB=/etc/curve/curvetab
CURVETABBAK=/etc/curve/curvetab-bak
if [ -f ${CURVETAB} ]; then
cp -f -p ${CURVETAB} ${CURVETABBAK}
fi
exit 0

7
nbd/nbd-package/DEBIAN/prerm Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -e
systemctl disable map_curve_disk.service
exit 0

View File

@ -0,0 +1,9 @@
#
# /etc/curvetab
# use for auto map and mount curve disk when boot
#
# this file record the correspondence of curve nbd images/ devices
# add record when 'curve-nbd map' and 'curve-nbd unmap'
#
# format: device image mount
# /dev/nbd0 cbd:pool//curvefile_test_ /curve

View File

@ -0,0 +1,22 @@
[Unit]
Description=curve-nbd auto map service
Before=kubelet.service
After=remote-fs.target
After=network-online.target
After=nebd-daemon.service
Wants=network-online.target
[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
SuccessExitStatus=5 6
ExecStart=/usr/bin/map_curve_disk.sh start
ExecStop=/usr/bin/map_curve_disk.sh stop
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,107 @@
#!/bin/bash
# default confpath
# file format is:dealflag \t device \t image \t mountpoint(option)
# + /dev/nbd0 cbd:pool//curvefile_test_ /test
confPath=/etc/curve/curvetab
# check sudo
if [[ $(id -u) -ne 0 ]]
then
echo "Please run with sudo"
exit 1
fi
# usage
function usage() {
echo "Usage: ./map_curve_disk.sh start"
echo " -c/--confPath: set the confPath (default /etc/curve/curvetab)"
echo " file format is:dealflag \t device \t image \t mountpoint(option)"
echo " example: + /dev/nbd0 cbd:pool//curvefile_test_ /test"
echo " -h/--help: get the script usage"
echo "Examples:"
echo " ./map_curve_disk.sh start //use the default configuration"
echo " ./map_curve_disk.sh start --confPath yourConfPath //use the new confPath"
}
# remove extra records
function dealcurvetab() {
if [ ! -f ${confPath} ]
then
echo "ERROR: not found configuration file, confPath is ${confPath}!"
exit
fi
declare -A recordmap
while read line
do
flag=$(echo $line | awk '{print $1}')
device=$(echo $line | awk '{print $2}')
if [ "$flag" = "+" ]
then
recordmap["$device"]=$line
elif [ "$flag" = "-" ]
then
unset recordmap[$device]
fi
done < ${confPath}
for key in ${!recordmap[@]}; do
echo ${recordmap[$key]} >> ${confPath}.bak
done
}
# map the curve disk based on curvetab
function map() {
if [ ! -f ${confPath}.bak ]
then
echo "ERROR: not found configuration file, confPath is ${confPath}.bak!"
exit
fi
cat ${confPath}.bak | grep -v '#' | while read line
do
device=$(echo $line | awk '{print $2}')
image=$(echo $line | awk '{print $3}')
mount=$(echo $line | awk '{print $4}')
curve-nbd map $image --device $device
if [ "$mount" != "" ]
then
mount $device $mount
fi
done
mv ${confPath}.bak ${confPath}
}
if [ $# -lt 1 ]
then
usage
exit
fi
case $1 in
"start")
shift # pass first argument
while [[ $# -gt 1 ]]
do
key=$1
case $key in
-c|--confPath)
confPath=`realpath $2`
shift # pass key
shift # pass value
;;
*)
usage
exit
;;
esac
done
dealcurvetab
map
;;
*)
usage
;;
esac

View File

@ -61,6 +61,7 @@ namespace nbd {
#define PROCESS_NAME "curve-nbd"
#define NBD_PATH_PREFIX "/sys/block/nbd"
#define DEV_PATH_PREFIX "/dev/nbd"
#define CURVETAB_PATH "/etc/curve/curvetab"
using std::cerr;

View File

@ -93,6 +93,24 @@ static void Usage() {
<< std::endl;
}
// use for record image and device info to auto map when boot
static int AddRecord(int flag) {
std::string record;
int fd = open(CURVETAB_PATH, O_WRONLY | O_APPEND);
if (fd < 0) {
std::cerr << "curve-nbd: open curvetab file failed.";
return -EINVAL;
}
if (1 == flag) {
record = "+\t" + nbdConfig->devpath + "\t" + nbdConfig->imgname + "\n";
} else if (-1 == flag) {
record = "-\t" + nbdConfig->devpath + "\n";
}
write(fd, record.c_str(), record.size());
close(fd);
return 0;
}
static int NBDConnect() {
int waitConnectPipe[2];
@ -138,6 +156,10 @@ static int NBDConnect() {
if (ret < 0) {
::write(waitConnectPipe[1], &connectionRes, sizeof(connectionRes));
} else {
ret = AddRecord(1);
if (0 != ret) {
return ret;
}
connectionRes = 0;
::write(waitConnectPipe[1], &connectionRes, sizeof(connectionRes));
nbdTool->RunServerUntilQuit();
@ -190,6 +212,10 @@ static int CurveNbdMain(int argc, const char* argv[]) {
return -EINVAL;
}
r = AddRecord(-1);
if (0 != r) {
return r;
}
break;
}
case Command::List: {

View File

@ -1,8 +1,8 @@
# part2 socket file address
nebdserver.serverAddress=/data/nebd/nebd.sock
nebdserver.serverAddress=/data/nebd/nebd.sock # __CURVEADM_TEMPLATE__ ${prefix}/data/nebd.sock __CURVEADM_TEMPLATE__
# 文件锁路径
metacache.fileLockPath=/data/nebd/lock
metacache.fileLockPath=/data/nebd/lock # __CURVEADM_TEMPLATE__ ${prefix}/data/lock __CURVEADM_TEMPLATE__
# 同步rpc的最大重试次数
request.syncRpcMaxRetryTimes=50
@ -23,4 +23,4 @@ heartbeat.intervalS=5
heartbeat.rpcTimeoutMs=500
# 日志路径
log.path=/data/log/nebd/client
log.path=/data/log/nebd/client # __CURVEADM_TEMPLATE__ ${prefix}/logs __CURVEADM_TEMPLATE__

View File

@ -1,11 +1,11 @@
# curve-client配置文件地址
curveclient.confPath=/etc/curve/client.conf
curveclient.confPath=/etc/curve/client.conf # __CURVEADM_TEMPLATE__ ${prefix}/conf/client.conf __CURVEADM_TEMPLATE__
#brpc server监听端口
listen.address=/data/nebd/nebd.sock
listen.address=/data/nebd/nebd.sock # __CURVEADM_TEMPLATE__ ${prefix}/data/nebd.sock __CURVEADM_TEMPLATE__
#元数据文件地址,包含文件名
meta.file.path=/data/nebd/nebdserver.meta
meta.file.path=/data/nebd/nebdserver.meta # __CURVEADM_TEMPLATE__ ${prefix}/data/nebdserver.meta __CURVEADM_TEMPLATE__
#心跳超时时间
heartbeat.timeout.sec=30

View File

@ -1,7 +1,7 @@
Package: nebd
Section:
Priority: optional
Depends: libunwind8, libjemalloc1(= 3.6.0-9.1)
Depends: libunwind8, libjemalloc1(= 3.6.0-9.1) | libjemalloc2(>= 5.1.0-3)
Suggests:
Architecture:amd64
Installed-Size:

View File

@ -37,7 +37,7 @@ daemonLog=${baseLogPath}/nebd-server-daemon.log
consoleLog=${baseLogPath}/nebd-server-console.log
function get_nebd_server_pid() {
local tmp=`ps -ef | grep nebd-server | grep -v grep | grep -v daemon | awk '{print $2}'`
local tmp=`pidof nebd-server`
echo $tmp
}
@ -103,11 +103,11 @@ function start() {
exit 1
fi
jemallocpath=/usr/lib/x86_64-linux-gnu/libjemalloc.so.1
# 检查jemalloc库文件
if [ ! -f ${jemallocpath} ]
jemallocpath=`find /usr/ -name "libjemalloc.so*" -print -quit`
if [ "${jemallocpath}" = "" ]
then
echo "Not found jemalloc library, Path is ${jemallocpath}"
echo "Not found jemalloc library in /usr/"
exit 1
fi
@ -146,6 +146,27 @@ function stop() {
then
echo "stop may not success!"
else
# wait 3s
retry_times=0
while [ $retry_times -le 3 ]
do
((retry_times=$retry_times+1))
pidof nebd-server > /dev/null 2>&1
if [ $? -eq 0 ]
then
sleep 1
else
break
fi
done
pidof nebd-server > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "nebd-server still exists after 3s, now kill it with SIGKILL"
kill -9 `pidof nebd-server`
fi
echo "nebd-server exit success!"
echo "daemon exit success!"
fi
@ -170,7 +191,7 @@ function restart() {
if [ $old_pid == $new_pid ]
then
echo "restart nebd-server may failed, try kill -9 nebd-server"
echo "restart nebd-server may failed, now kill it with SIGKILL"
kill -9 $old_pid
fi
}

View File

@ -345,6 +345,11 @@ message ProtoSession {
// other useful infos
};
message CloneSourceSegment {
required uint64 segmentSize = 1;
repeated uint64 allocatedSegmentOffset = 2;
}
message OpenFileRequest {
required string fileName = 1;
required string owner = 2;
@ -363,6 +368,7 @@ message OpenFileResponse {
required StatusCode statusCode = 1;
optional ProtoSession protoSession = 2;
optional FileInfo fileInfo = 3;
optional CloneSourceSegment cloneSourceSegment = 4;
};
message CloseFileRequest {

21
robot/curve_init.txt Normal file
View File

@ -0,0 +1,21 @@
*** Settings ***
Library Collections
#Library RequestsLibrary
Library Process
#Library SSHLibrary
Suite Setup init
Suite Teardown clean
*** Test Cases ***
inject cases
[Tags] P0 base init
log hello word
*** Keywords ***
init
log init cluster
clean
log clean

View File

@ -67,8 +67,6 @@ void CurveFileService::get_file(::google::protobuf::RpcController* controller,
* uri format为:remote://ip:port/reader_id所以使用ENXIO
* reader id不存在的错误
*/
LOG(ERROR) << "reader " << request->reader_id()
<< " not found in reader map";
cntl->SetFailed(ENXIO, "Fail to find reader=%" PRId64,
request->reader_id());
return;
@ -82,7 +80,6 @@ void CurveFileService::get_file(::google::protobuf::RpcController* controller,
<< request->count();
if (request->count() <= 0 || request->offset() < 0) {
LOG(ERROR) << "request count or offset elegal";
cntl->SetFailed(brpc::EREQUEST, "Invalid request=%s",
request->ShortDebugString().c_str());
return;
@ -160,8 +157,6 @@ void CurveFileService::get_file(::google::protobuf::RpcController* controller,
&read_count,
&is_eof);
if (rc != 0) {
LOG(ERROR) << "Fail to read file " << reader->path() << "/"
<< request->filename() << " error code: " << rc;
cntl->SetFailed(rc, "Fail to read from path=%s filename=%s : %s",
reader->path().c_str(),
request->filename().c_str(), berror(rc));

View File

@ -279,7 +279,7 @@ void ClientClosure::Run() {
default:
needRetry = true;
LOG_EVERY_N(ERROR, 10) << OpTypeToString(reqCtx_->optype_)
LOG(WARNING) << OpTypeToString(reqCtx_->optype_)
<< " failed for UNKNOWN reason, " << *reqCtx_
<< ", status="
<< curve::chunkserver::CHUNK_OP_STATUS_Name(
@ -309,7 +309,7 @@ void ClientClosure::OnRpcFailed() {
MetricHelper::IncremTimeOutRPCCount(fileMetric_, reqCtx_->optype_);
}
LOG_EVERY_N(ERROR, 10) << OpTypeToString(reqCtx_->optype_)
LOG_EVERY_SECOND(WARNING) << OpTypeToString(reqCtx_->optype_)
<< " failed, error code: "
<< cntl_->ErrorCode()
<< ", error: " << cntl_->ErrorText()
@ -444,7 +444,7 @@ void ClientClosure::OnRetry() {
failReqOpt_.chunkserverMaxRetryTimesBeforeConsiderSuspend) {
reqDone_->SetSuspendRPCFlag();
MetricHelper::IncremIOSuspendNum(fileMetric_);
LOG(WARNING) << "IO Retried "
LOG(ERROR) << "IO Retried "
<< failReqOpt_.chunkserverMaxRetryTimesBeforeConsiderSuspend
<< " times, set suspend flag! " << *reqCtx_
<< ", IO id = " << reqDone_->GetIOTracker()->GetID()

View File

@ -35,6 +35,8 @@ const char* OpTypeToString(OpType optype) {
return "ReadSnapshot";
case OpType::DELETE_SNAP:
return "DeleteSnapshot";
case OpType::CREATE_CLONE:
return "CreateCloneChunk";
case OpType::RECOVER_CHUNK:
return "RecoverChunk";
case OpType::GET_CHUNK_INFO:
@ -47,4 +49,3 @@ const char* OpTypeToString(OpType optype) {
} // namespace client
} // namespace curve

View File

@ -31,6 +31,7 @@
#include <string>
#include <atomic>
#include <vector>
#include <unordered_set>
#include "include/client/libcurve.h"
#include "src/common/net_common.h"
@ -137,6 +138,23 @@ typedef struct SegmentInfo {
LogicalPoolCopysetIDInfo lpcpIDInfo;
} SegmentInfo_t;
struct CloneSourceInfo {
std::string name;
uint64_t length = 0;
uint64_t segmentSize = 0;
std::unordered_set<uint64_t> allocatedSegmentOffsets;
CloneSourceInfo() = default;
CloneSourceInfo(const CloneSourceInfo& other)
: name(other.name),
length(other.length),
segmentSize(other.segmentSize),
allocatedSegmentOffsets(other.allocatedSegmentOffsets) {}
bool IsSegmentAllocated(uint64_t offset) const;
};
typedef struct FInfo {
uint64_t id;
uint64_t parentid;
@ -153,8 +171,7 @@ typedef struct FInfo {
std::string filename;
std::string fullPathName;
FileStatus filestatus;
std::string cloneSource;
uint64_t cloneLength{0};
CloneSourceInfo sourceInfo;
FInfo() {
id = 0;
@ -218,6 +235,7 @@ struct ChunkServerAddr {
};
const char* OpTypeToString(OpType optype);
struct ClusterContext {
std::string clusterId;
};
@ -273,6 +291,36 @@ class ClientDummyServerInfo {
bool register_ = false;
};
inline void TrivialDeleter(void* ptr) {}
inline const char* FileStatusToName(FileStatus status) {
switch (status) {
case FileStatus::Created:
return "Created";
case FileStatus::Deleting:
return "Deleting";
case FileStatus::Cloning:
return "Cloning";
case FileStatus::CloneMetaInstalled:
return "CloneMetaInstalled";
case FileStatus::Cloned:
return "Cloned";
case FileStatus::BeingCloned:
return "BeingCloned";
default:
return "Unknown";
}
}
inline bool CloneSourceInfo::IsSegmentAllocated(uint64_t offset) const {
if (length == 0) {
return false;
}
uint64_t segmentOffset = offset / segmentSize * segmentSize;
return allocatedSegmentOffsets.count(segmentOffset) != 0;
}
} // namespace client
} // namespace curve

View File

@ -134,7 +134,7 @@ struct FileMetric {
// 用于全局mds接口统计信息调用信息统计
struct MDSClientMetric {
const std::string prefix = "curve mds client";
std::string prefix;
// mds的地址信息
std::string metaserverAddr;
@ -174,8 +174,12 @@ struct MDSClientMetric {
// 切换mds server总次数
bvar::Adder<uint64_t> mdsServerChangeTimes;
MDSClientMetric()
: metaserverAddress(prefix, "current_metaserver_addr", GetStringValue,
explicit MDSClientMetric(const std::string& prefix_ = "")
: prefix(!prefix_.empty()
? prefix_
: "curve_mds_client_" +
std::to_string(reinterpret_cast<uint64_t>(this))),
metaserverAddress(prefix, "current_metaserver_addr", GetStringValue,
&metaserverAddr),
mdsServerChangeTimes(prefix, "mds_server_change_times"),
openFile(prefix, "openFile"),

View File

@ -294,11 +294,17 @@ void IOTracker::Done() {
MetricHelper::IncremUserEPSCount(fileMetric_, type_);
if (type_ == OpType::READ || type_ == OpType::WRITE) {
LOG(ERROR) << "file [" << fileMetric_->filename << "]"
<< ", IO Error, OpType = " << static_cast<int>(type_)
<< ", IO Error, OpType = " << OpTypeToString(type_)
<< ", offset = " << offset_
<< ", length = " << length_;
} else {
LOG(ERROR) << ", IO Error, OpType = " << static_cast<int>(type_);
if (OpType::CREATE_CLONE == type_ &&
LIBCURVE_ERROR::EXISTS == errcode_) {
// if CreateCloneChunk return Exists
// no error should be reported
} else {
LOG(ERROR) << "IO Error, OpType = " << OpTypeToString(type_);
}
}
}

View File

@ -97,14 +97,14 @@ bool LeaseExecutor::RefreshLease() {
return true;
} else if (LIBCURVE_ERROR::AUTHFAIL == ret) {
iomanager_->LeaseTimeoutBlockIO();
LOG(WARNING) << "Refresh session auth fail, block io. "
<< "session id = " << leasesession_.sessionID
<< ", filename = " << fullFileName_;
LOG(ERROR) << "Refresh session auth fail, block io. "
<< "session id = " << leasesession_.sessionID
<< ", filename = " << fullFileName_;
return true;
}
if (response.status == LeaseRefreshResult::Status::OK) {
CheckNeedUpdateVersion(response.finfo.seqnum);
CheckNeedUpdateFileInfo(response.finfo);
failedrefreshcount_.store(0);
isleaseAvaliable_.store(true);
iomanager_->RefeshSuccAndResumeIO();
@ -112,12 +112,12 @@ bool LeaseExecutor::RefreshLease() {
} else if (response.status == LeaseRefreshResult::Status::NOT_EXIST) {
iomanager_->LeaseTimeoutBlockIO();
isleaseAvaliable_.store(false);
LOG(WARNING) << "session or file not exists, no longer refresh!"
<< ", sessionid = " << leasesession_.sessionID
<< ", filename = " << fullFileName_;
LOG(ERROR) << "session or file not exists, no longer refresh!"
<< ", sessionid = " << leasesession_.sessionID
<< ", filename = " << fullFileName_;
return false;
} else {
LOG(WARNING) << "Refresh session failed, filename = " << fullFileName_;
LOG(ERROR) << "Refresh session failed, filename = " << fullFileName_;
return true;
}
return true;
@ -146,14 +146,27 @@ void LeaseExecutor::IncremRefreshFailed() {
}
}
void LeaseExecutor::CheckNeedUpdateVersion(uint64_t newversion) {
const uint64_t currentFileSn = iomanager_->GetLatestFileSn();
void LeaseExecutor::CheckNeedUpdateFileInfo(const FInfo& fileInfo) {
MetaCache* metaCache = iomanager_->GetMetaCache();
DVLOG(9) << "new file version = " << newversion
<< ", current version = " << currentFileSn
<< ", filename = " << fullFileName_;
if (newversion > currentFileSn) {
iomanager_->SetLatestFileSn(newversion);
uint64_t currentFileSn = metaCache->GetLatestFileSn();
uint64_t newSn = fileInfo.seqnum;
if (newSn > currentFileSn) {
LOG(INFO) << "Update file sn, new file sn = " << newSn
<< ", current sn = " << currentFileSn
<< ", filename = " << fullFileName_;
metaCache->SetLatestFileSn(newSn);
}
FileStatus currentFileStatus = metaCache->GetLatestFileStatus();
FileStatus newFileStatus = fileInfo.filestatus;
if (newFileStatus != currentFileStatus) {
LOG(INFO) << "Update file status, new status = "
<< FileStatusToName(newFileStatus)
<< ", current file status = "
<< FileStatusToName(currentFileStatus)
<< ", filename = " << fullFileName_;
metaCache->SetLatestFileStatus(newFileStatus);
}
}

View File

@ -24,6 +24,8 @@
#define SRC_CLIENT_LEASE_EXECUTOR_H_
#include <brpc/periodic_task.h>
#include <bthread/condition_variable.h>
#include <bthread/mutex.h>
#include <memory>
#include <string>
@ -127,10 +129,11 @@ class LeaseExecutor {
void IncremRefreshFailed();
/**
*
* @param: newversion是lease续约后从mds端携带回来的版本号
* @brief Updating local file information consistent with MDS record.
* Currently, only seqnum and file status are updated
* @param fileInfo Latest file information returned by refresh session RPC
*/
void CheckNeedUpdateVersion(uint64_t newversion);
void CheckNeedUpdateFileInfo(const FInfo& fileInfo);
private:
// 与mds进行lease续约的文件名
@ -197,7 +200,7 @@ class RefreshSessionTask : public brpc::PeriodicTask {
* false
*/
bool OnTriggeringTask(timespec* next_abstime) override {
std::lock_guard<std::mutex> lk(stopMtx_);
std::lock_guard<bthread::Mutex> lk(stopMtx_);
if (stopped_) {
return false;
}
@ -210,7 +213,7 @@ class RefreshSessionTask : public brpc::PeriodicTask {
* @brief
*/
void Stop() {
std::lock_guard<std::mutex> lk(stopMtx_);
std::lock_guard<bthread::Mutex> lk(stopMtx_);
stopped_ = true;
}
@ -218,7 +221,7 @@ class RefreshSessionTask : public brpc::PeriodicTask {
* @brief
*/
void OnDestroyingTask() override {
std::unique_lock<std::mutex> lk(terminatedMtx_);
std::unique_lock<bthread::Mutex> lk(terminatedMtx_);
terminated_ = true;
terminatedCv_.notify_one();
}
@ -227,8 +230,10 @@ class RefreshSessionTask : public brpc::PeriodicTask {
* @brief 退
*/
void WaitTaskExit() {
std::unique_lock<std::mutex> lk(terminatedMtx_);
terminatedCv_.wait(lk, [this]() { return terminated_ == true; });
std::unique_lock<bthread::Mutex> lk(terminatedMtx_);
while (terminated_ != true) {
terminatedCv_.wait(lk);
}
}
/**
@ -244,11 +249,11 @@ class RefreshSessionTask : public brpc::PeriodicTask {
uint64_t refreshIntervalUs_;
bool stopped_;
std::mutex stopMtx_;
bthread::Mutex stopMtx_;
bool terminated_;
std::mutex terminatedMtx_;
std::condition_variable terminatedCv_;
bthread::Mutex terminatedMtx_;
bthread::ConditionVariable terminatedCv_;
};
} // namespace client

View File

@ -174,7 +174,8 @@ int FileClient::Open(const std::string& filename,
int ret = fileserv->Open(filename, userinfo, sessionId);
if (ret != LIBCURVE_ERROR::OK) {
LOG(ERROR) << "Open file fail, retCode = " << ret;
LOG(ERROR) << "Open file failed, filename: " << filename
<< ", retCode: " << ret;
fileserv->UnInitialize();
delete fileserv;
return ret;
@ -261,6 +262,8 @@ int FileClient::Create(const std::string& filename,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->CreateFile(filename, userinfo, size);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Create file failed, filename: " << filename << ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -355,6 +358,10 @@ int FileClient::Rename(const UserInfo_t& userinfo,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->RenameFile(userinfo, oldpath, newpath);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Rename failed, OldPath: " << oldpath
<< ", NewPath: " << newpath
<< ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -367,6 +374,10 @@ int FileClient::Extend(const std::string& filename,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->Extend(filename, userinfo, newsize);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Extend failed, filename: " << filename
<< ", NewSize: " << newsize
<< ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -379,6 +390,10 @@ int FileClient::Unlink(const std::string& filename,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->DeleteFile(filename, userinfo, deleteforce);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Unlink failed, filename: " << filename
<< ", force: " << deleteforce
<< ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -392,6 +407,8 @@ int FileClient::StatFile(const std::string& filename,
int ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->GetFileInfo(filename, userinfo, &fi);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "StatFile failed, filename: " << filename << ", ret" << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -420,6 +437,9 @@ int FileClient::Listdir(const std::string& dirpath,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->Listdir(dirpath, userinfo, filestatVec);
LOG_IF(ERROR,
ret != LIBCURVE_ERROR::OK && ret != LIBCURVE_ERROR::NOTEXIST)
<< "Listdir failed, Path: " << dirpath << ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -431,6 +451,8 @@ int FileClient::Mkdir(const std::string& dirpath, const UserInfo_t& userinfo) {
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->CreateFile(dirpath, userinfo, 0, false);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Create file failed, filename: " << dirpath << ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -442,6 +464,8 @@ int FileClient::Rmdir(const std::string& dirpath, const UserInfo_t& userinfo) {
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->DeleteFile(dirpath, userinfo);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "Rmdir failed, Path: " << dirpath << ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -454,6 +478,8 @@ int FileClient::ChangeOwner(const std::string& filename,
LIBCURVE_ERROR ret;
if (mdsClient_ != nullptr) {
ret = mdsClient_->ChangeOwner(filename, newOwner, userinfo);
LOG_IF(ERROR, ret != LIBCURVE_ERROR::OK)
<< "ChangeOwner failed, filename: " << filename << ", ret: " << ret;
} else {
LOG(ERROR) << "global mds client not inited!";
return -LIBCURVE_ERROR::FAILED;
@ -550,6 +576,7 @@ std::string FileClient::GetClusterId() {
return clsctx.clusterId;
}
LOG(ERROR) << "GetClusterId failed, ret: " << ret;
return {};
}

View File

@ -112,7 +112,7 @@ int SnapshotClient::GetSnapShot(const std::string& filename,
if (ret == LIBCURVE_ERROR::OK && !infomap.empty()) {
auto it = infomap.begin();
if (it->first != seq) {
LOG(ERROR) << "Snapshot info not found with seqnum = " << seq;
LOG(WARNING) << "Snapshot info not found with seqnum = " << seq;
return -LIBCURVE_ERROR::NOTEXIST;
}
*snapinfo = it->second;
@ -138,11 +138,11 @@ int SnapshotClient::GetSnapshotSegmentInfo(const std::string& filename,
seq, offset, segInfo);
if (ret != LIBCURVE_ERROR::OK) {
LOG(ERROR) << "GetSnapshotSegmentInfo failed, ret = " << ret;
LOG(WARNING) << "GetSnapshotSegmentInfo failed, ret = " << ret;
return -ret;
}
for (auto iter : segInfo->chunkvec) {
for (const auto& iter : segInfo->chunkvec) {
iomanager4chunk_.GetMetaCache()->UpdateChunkInfoByID(iter.cid_, iter);
}

View File

@ -70,7 +70,8 @@ using curve::mds::topology::GetChunkServerListInCopySetsResponse;
namespace curve {
namespace client {
MDSClient::MDSClient() {
MDSClient::MDSClient(const std::string& metricPrefix)
: mdsClientMetric_(metricPrefix) {
inited_ = false;
}
@ -232,7 +233,7 @@ int MDSClient::MDSRPCExcutor::ExcuteTask(
brpc::Channel channel;
int ret = channel.Init(mdsaddr.c_str(), nullptr);
if (ret != 0) {
LOG(WARNING) << "Init channel failed! addr = " << mdsaddr.c_str();
LOG(WARNING) << "Init channel failed! addr = " << mdsaddr;
// 返回EHOSTDOWN给上层调用者促使其切换mds
return -EHOSTDOWN;
}
@ -265,8 +266,8 @@ LIBCURVE_ERROR MDSClient::OpenFile(const std::string& filename,
LIBCURVE_ERROR retcode = LIBCURVE_ERROR::FAILED;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "OpenFile: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "OpenFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
@ -279,10 +280,25 @@ LIBCURVE_ERROR MDSClient::OpenFile(const std::string& filename,
lease->leaseTime = leasesession.leasetime();
lease->createTime = leasesession.createtime();
FileInfo finfo = response.fileinfo();
ServiceHelper::ProtoFileInfo2Local(&finfo, fi);
const curve::mds::FileInfo& protoFileInfo = response.fileinfo();
ServiceHelper::ProtoFileInfo2Local(protoFileInfo, fi);
if (protoFileInfo.has_clonesource() &&
protoFileInfo.filestatus() ==
curve::mds::FileStatus::kFileCloneMetaInstalled) {
if (!response.has_clonesourcesegment()) {
LOG(WARNING) << filename
<< " has clone source and status is "
"CloneMetaInstalled, but response does not "
"contains clone source segment";
return retcode;
}
ServiceHelper::ProtoCloneSourceInfo2Local(response,
&fi->sourceInfo);
}
} else {
LOG(ERROR) << "mds response has no file info or session info!";
LOG(WARNING) << "mds response has no file info or session info!";
return LIBCURVE_ERROR::FAILED;
}
@ -311,8 +327,8 @@ LIBCURVE_ERROR MDSClient::CreateFile(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "CreateFile: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "CreateFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", is nomalfile: " << normalFile
<< ", errocde = " << retcode
@ -343,8 +359,8 @@ LIBCURVE_ERROR MDSClient::CloseFile(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "CloseFile: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "CloseFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", sessionid = " << sessionid
<< ", errocde = " << retcode
@ -371,15 +387,14 @@ LIBCURVE_ERROR MDSClient::GetFileInfo(const std::string& filename,
}
if (response.has_fileinfo()) {
FileInfo finfo = response.fileinfo();
ServiceHelper::ProtoFileInfo2Local(&finfo, fi);
ServiceHelper::ProtoFileInfo2Local(response.fileinfo(), fi);
}
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "GetFileInfo: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "GetFileInfo: filename = " << filename
<< ", owner = " << uinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
@ -410,8 +425,7 @@ LIBCURVE_ERROR MDSClient::CreateSnapShot(const std::string& filename,
stcode == StatusCode::kFileUnderSnapShot) &&
hasinfo) {
FInfo_t* fi = new (std::nothrow) FInfo_t;
curve::mds::FileInfo finfo = response.snapshotfileinfo();
ServiceHelper::ProtoFileInfo2Local(&finfo, fi);
ServiceHelper::ProtoFileInfo2Local(response.snapshotfileinfo(), fi);
*seq = fi->seqnum;
delete fi;
if (stcode == StatusCode::kOK) {
@ -426,14 +440,14 @@ LIBCURVE_ERROR MDSClient::CreateSnapShot(const std::string& filename,
if (hasinfo) {
FInfo_t fi;
ServiceHelper::ProtoFileInfo2Local(&response.snapshotfileinfo(), &fi); // NOLINT
ServiceHelper::ProtoFileInfo2Local(response.snapshotfileinfo(), &fi); // NOLINT
*seq = fi.seqnum;
}
LIBCURVE_ERROR retcode;
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "CreateSnapShot: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "CreateSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
@ -460,8 +474,8 @@ LIBCURVE_ERROR MDSClient::DeleteSnapShot(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "DeleteSnapShot: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "DeleteSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", seqnum = " << seq << ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
@ -489,8 +503,8 @@ LIBCURVE_ERROR MDSClient::ListSnapShot(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "ListSnapShot: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "ListSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode);
@ -501,8 +515,7 @@ LIBCURVE_ERROR MDSClient::ListSnapShot(const std::string& filename,
for (int i = 0; i < response.fileinfo_size(); i++) {
FInfo_t tempInfo;
FileInfo finfo = response.fileinfo(i);
ServiceHelper::ProtoFileInfo2Local(&finfo, &tempInfo);
ServiceHelper::ProtoFileInfo2Local(response.fileinfo(i), &tempInfo);
snapif->insert(std::make_pair(tempInfo.seqnum, tempInfo));
}
@ -522,7 +535,7 @@ LIBCURVE_ERROR MDSClient::GetSnapshotSegmentInfo(const std::string& filename,
auto task = RPCTaskDefine {
GetOrAllocateSegmentResponse response;
mdsClientBase_.GetSnapshotSegmentInfo(filename, userinfo, seq, offset,
&response, cntl, channel);
&response, cntl, channel);
if (cntl->Failed()) {
LOG(WARNING) << "get snap file segment info failed, errcorde = "
<< cntl->ErrorCode()
@ -533,8 +546,8 @@ LIBCURVE_ERROR MDSClient::GetSnapshotSegmentInfo(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "GetSnapshotSegmentInfo: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "GetSnapshotSegmentInfo: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", offset = " << offset
<< ", seqnum = " << seq
@ -542,7 +555,7 @@ LIBCURVE_ERROR MDSClient::GetSnapshotSegmentInfo(const std::string& filename,
<< ", error msg = " << StatusCode_Name(stcode);
if (stcode != StatusCode::kOK) {
LOG(ERROR) << "GetSnapshotSegmentInfo return error, "
LOG(WARNING) << "GetSnapshotSegmentInfo return error, "
<< ", filename = " << filename
<< ", seq = " << seq;
return retcode;
@ -561,7 +574,7 @@ LIBCURVE_ERROR MDSClient::GetSnapshotSegmentInfo(const std::string& filename,
int chunksNum = pfs.chunks_size();
if (chunksNum == 0) {
LOG(ERROR) << "mds allocate segment, but no chunk!";
LOG(WARNING) << "mds allocate segment, but no chunk!";
return LIBCURVE_ERROR::FAILED;
}
@ -597,18 +610,19 @@ LIBCURVE_ERROR MDSClient::RefreshSession(const std::string& filename,
}
StatusCode stcode = response.statuscode();
LOG_IF(WARNING, stcode != StatusCode::kOK)
<< "RefreshSession NOT OK: filename = "
<< filename.c_str() << ", owner = "
<< userinfo.owner << ", sessionid = "
<< sessionid << ", status code = "
<< StatusCode_Name(stcode);
LOG_EVERY_N(INFO, 10) << "RefreshSession returned: filename = "
<< filename.c_str() << ", owner = "
<< userinfo.owner << ", sessionid = "
<< sessionid << ", status code = "
<< StatusCode_Name(stcode);
if (stcode != StatusCode::kOK) {
LOG(WARNING)
<< "RefreshSession NOT OK: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", sessionid = " << sessionid
<< ", status code = " << StatusCode_Name(stcode);
} else {
LOG_EVERY_SECOND(INFO)
<< "RefreshSession returned: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", sessionid = " << sessionid
<< ", status code = " << StatusCode_Name(stcode);
}
switch (stcode) {
case StatusCode::kSessionNotExist:
@ -621,8 +635,8 @@ LIBCURVE_ERROR MDSClient::RefreshSession(const std::string& filename,
break;
case StatusCode::kOK:
if (response.has_fileinfo()) {
FileInfo finfo = response.fileinfo();
ServiceHelper::ProtoFileInfo2Local(&finfo, &resp->finfo);
ServiceHelper::ProtoFileInfo2Local(response.fileinfo(),
&resp->finfo);
resp->status = LeaseRefreshResult::Status::OK;
} else {
LOG(WARNING) << "session response has no fileinfo!";
@ -630,7 +644,7 @@ LIBCURVE_ERROR MDSClient::RefreshSession(const std::string& filename,
}
if (nullptr != lease) {
if (!response.has_protosession()) {
LOG(ERROR) << "session response has no protosession";
LOG(WARNING) << "session response has no protosession";
return LIBCURVE_ERROR::FAILED;
}
ProtoSession leasesession = response.protosession();
@ -671,8 +685,8 @@ LIBCURVE_ERROR MDSClient::CheckSnapShotStatus(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "CheckSnapShotStatus: filename = " << filename.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "CheckSnapShotStatus: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", seqnum = " << seq << ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode);
@ -732,10 +746,10 @@ LIBCURVE_ERROR MDSClient::GetServerList(const LogicPoolID& logicalpooid,
}
cpinfoVec->push_back(copysetseverl);
DVLOG(9) << "copyset id : " << copysetseverl.cpid_
<< ", peer info : " << copyset_peer.c_str();
<< ", peer info : " << copyset_peer;
}
LOG_IF(ERROR, response.statuscode() != 0)
LOG_IF(WARNING, response.statuscode() != 0)
<< "GetServerList failed"
<< ", errocde = " << response.statuscode()
<< ", log id = " << cntl->log_id();
@ -752,10 +766,9 @@ LIBCURVE_ERROR MDSClient::GetClusterInfo(ClusterContext* clsctx) {
mdsClientBase_.GetClusterInfo(&response, cntl, channel);
if (cntl->Failed()) {
LOG(ERROR) << "get cluster info from mds failed, status code = "
<< cntl->ErrorCode()
<< ", error content: "
<< cntl->ErrorText();
LOG(WARNING) << "get cluster info from mds failed, status code = "
<< cntl->ErrorCode()
<< ", error content: " << cntl->ErrorText();
return -cntl->ErrorCode();
}
@ -789,18 +802,19 @@ LIBCURVE_ERROR MDSClient::CreateCloneFile(const std::string& source,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "CreateCloneFile: source = " << source
<< ", destination = " << destination
<< ", owner = " << userinfo.owner.c_str() << ", seqnum = " << sn
<< ", owner = " << userinfo.owner << ", seqnum = " << sn
<< ", size = " << size << ", chunksize = " << chunksize
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
<< ", log id = " << cntl->log_id();
if (stcode == StatusCode::kOK) {
FileInfo finfo = response.fileinfo();
ServiceHelper::ProtoFileInfo2Local(&finfo, fileinfo);
ServiceHelper::ProtoFileInfo2Local(response.fileinfo(), fileinfo);
fileinfo->sourceInfo.name = response.fileinfo().clonesource();
fileinfo->sourceInfo.length = response.fileinfo().clonelength();
}
return retcode;
@ -835,9 +849,9 @@ LIBCURVE_ERROR MDSClient::SetCloneFileStatus(const std::string &filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "SetCloneFileStatus failed, filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "SetCloneFileStatus failed, filename = " << filename
<< ", owner = " << userinfo.owner
<< ", filestatus = " << static_cast<int>(filestatus)
<< ", fileID = " << fileID
<< ", errocde = " << retcode
@ -858,7 +872,7 @@ LIBCURVE_ERROR MDSClient::GetOrAllocateSegment(bool allocate, uint64_t offset,
&response, cntl, channel);
if (cntl->Failed()) {
mdsClientMetric_.getOrAllocateSegment.eps.count << 1;
LOG_EVERY_SECOND(ERROR)
LOG(WARNING)
<< "allocate segment failed, error code = "
<< cntl->ErrorCode()
<< ", error content:" << cntl->ErrorText()
@ -869,7 +883,7 @@ LIBCURVE_ERROR MDSClient::GetOrAllocateSegment(bool allocate, uint64_t offset,
auto statuscode = response.statuscode();
switch (statuscode) {
case StatusCode::kOwnerAuthFail:
LOG(ERROR) << "GetOrAllocateSegment Auth failed!";
LOG(WARNING) << "GetOrAllocateSegment Auth failed!";
return LIBCURVE_ERROR::AUTHFAIL;
break;
case StatusCode::kSegmentNotAllocated:
@ -888,7 +902,7 @@ LIBCURVE_ERROR MDSClient::GetOrAllocateSegment(bool allocate, uint64_t offset,
int chunksNum = pfs.chunks_size();
if (allocate && chunksNum <= 0) {
LOG(ERROR) << "MDS allocate segment, but no chunkinfo!";
LOG(WARNING) << "MDS allocate segment, but no chunkinfo!";
return LIBCURVE_ERROR::FAILED;
}
@ -923,12 +937,12 @@ LIBCURVE_ERROR MDSClient::RenameFile(const UserInfo_t& userinfo,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "RenameFile: origin = " << origin.c_str()
<< ", destination = " << destination.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "RenameFile: origin = " << origin
<< ", destination = " << destination
<< ", originId = " << originId
<< ", destinationId = " << destinationId
<< ", owner = " << userinfo.owner.c_str()
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = "
<< StatusCode_Name(stcode)
@ -959,9 +973,9 @@ LIBCURVE_ERROR MDSClient::Extend(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "Extend: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "Extend: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", newsize = " << newsize
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
@ -990,9 +1004,9 @@ LIBCURVE_ERROR MDSClient::DeleteFile(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "DeleteFile: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "DeleteFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
<< ", log id = " << cntl->log_id();
@ -1020,10 +1034,10 @@ LIBCURVE_ERROR MDSClient::ChangeOwner(const std::string& filename,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "ChangeOwner: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
<< ", new owner = " << newOwner.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "ChangeOwner: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", new owner = " << newOwner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
<< ", log id = " << cntl->log_id();
@ -1051,9 +1065,9 @@ LIBCURVE_ERROR MDSClient::Listdir(const std::string& dirpath,
LIBCURVE_ERROR retcode;
StatusCode stcode = response.statuscode();
MDSStatusCode2LibcurveError(stcode, &retcode);
LOG_IF(ERROR, retcode != LIBCURVE_ERROR::OK)
<< "Listdir: filename = " << dirpath.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG_IF(WARNING, retcode != LIBCURVE_ERROR::OK)
<< "Listdir: filename = " << dirpath
<< ", owner = " << userinfo.owner
<< ", errocde = " << retcode
<< ", error msg = " << StatusCode_Name(stcode)
<< ", log id = " << cntl->log_id();
@ -1072,7 +1086,7 @@ LIBCURVE_ERROR MDSClient::Listdir(const std::string& dirpath,
memcpy(filestat.owner, finfo.owner().c_str(), NAME_MAX_SIZE);
memset(filestat.filename, 0, NAME_MAX_SIZE);
memcpy(filestat.filename, finfo.filename().c_str(),
NAME_MAX_SIZE);
NAME_MAX_SIZE);
filestatVec->push_back(filestat);
}
}
@ -1116,7 +1130,7 @@ LIBCURVE_ERROR MDSClient::GetChunkServerInfo(const ChunkServerAddr& csAddr,
}
int statusCode = response.statuscode();
LOG_IF(ERROR, statusCode != 0)
LOG_IF(WARNING, statusCode != 0)
<< "GetChunkServerInfo: errocde = " << statusCode
<< ", log id = " << cntl->log_id();
@ -1163,7 +1177,7 @@ LIBCURVE_ERROR MDSClient::ListChunkServerInServer(
}
int statusCode = response.statuscode();
LOG_IF(ERROR, statusCode != 0)
LOG_IF(WARNING, statusCode != 0)
<< "ListChunkServerInServer failed, "
<< "errorcode = " << response.statuscode()
<< ", chunkserver ip = " << serverIp

View File

@ -57,7 +57,7 @@ struct LeaseRefreshResult;
// MDSClient是client与MDS通信的唯一窗口
class MDSClient {
public:
MDSClient();
explicit MDSClient(const std::string& metricPrefix = "");
~MDSClient() = default;
using RPCFunc = std::function<int(int, uint64_t,
brpc::Channel*, brpc::Controller*)>;

View File

@ -42,7 +42,7 @@ void MDSClientBase::OpenFile(const std::string& filename,
request.set_clientversion(curve::common::CurveVersion());
FillUserInfo<OpenFileRequest>(&request, userinfo);
LOG(INFO) << "OpenFile: filename = " << filename.c_str()
LOG(INFO) << "OpenFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
@ -68,7 +68,7 @@ void MDSClientBase::CreateFile(const std::string& filename,
FillUserInfo<CreateFileRequest>(&request, userinfo);
LOG(INFO) << "CreateFile: filename = " << filename.c_str()
LOG(INFO) << "CreateFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", is nomalfile: " << normalFile
<< ", log id = " << cntl->log_id();
@ -88,7 +88,7 @@ void MDSClientBase::CloseFile(const std::string& filename,
request.set_sessionid(sessionid);
FillUserInfo<curve::mds::CloseFileRequest>(&request, userinfo);
LOG(INFO) << "CloseFile: filename = " << filename.c_str()
LOG(INFO) << "CloseFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", sessionid = " << sessionid
<< ", log id = " << cntl->log_id();
@ -106,9 +106,9 @@ void MDSClientBase::GetFileInfo(const std::string& filename,
request.set_filename(filename);
FillUserInfo<curve::mds::GetFileInfoRequest>(&request, userinfo);
LOG(INFO) << "GetFileInfo: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
LOG_EVERY_SECOND(INFO) << "GetFileInfo: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
curve::mds::CurveFSService_Stub stub(channel);
stub.GetFileInfo(cntl, &request, response, nullptr);
@ -123,7 +123,7 @@ void MDSClientBase::CreateSnapShot(const std::string& filename,
request.set_filename(filename);
FillUserInfo<::curve::mds::CreateSnapShotRequest>(&request, userinfo);
LOG(INFO) << "CreateSnapShot: filename = " << filename.c_str()
LOG(INFO) << "CreateSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
@ -142,7 +142,7 @@ void MDSClientBase::DeleteSnapShot(const std::string& filename,
request.set_filename(filename);
FillUserInfo<::curve::mds::DeleteSnapShotRequest>(&request, userinfo);
LOG(INFO) << "DeleteSnapShot: filename = " << filename.c_str()
LOG(INFO) << "DeleteSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", seqnum = " << seq
<< ", log id = " << cntl->log_id();
@ -164,7 +164,7 @@ void MDSClientBase::ListSnapShot(const std::string& filename,
request.set_filename(filename);
FillUserInfo<ListSnapShotFileInfoRequest>(&request, userinfo);
LOG(INFO) << "ListSnapShot: filename = " << filename.c_str()
LOG(INFO) << "ListSnapShot: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", seqnum = " << [seq] () {
std::string data("[ ");
@ -195,7 +195,7 @@ void MDSClientBase::GetSnapshotSegmentInfo(const std::string& filename,
request.set_seqnum(seq);
FillUserInfo<GetOrAllocateSegmentRequest>(&request, userinfo);
LOG(INFO) << "GetSnapshotSegmentInfo: filename = " << filename.c_str()
LOG(INFO) << "GetSnapshotSegmentInfo: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", offset = " << offset
<< ", seqnum = " << seq
@ -226,7 +226,7 @@ void MDSClientBase::RefreshSession(const std::string& filename,
FillUserInfo<ReFreshSessionRequest>(&request, userinfo);
LOG_EVERY_N(INFO, 10) << "RefreshSession: filename = " << filename.c_str()
LOG_EVERY_N(INFO, 10) << "RefreshSession: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", sessionid = " << sessionid
<< ", log id = " << cntl->log_id();
@ -246,7 +246,7 @@ void MDSClientBase::CheckSnapShotStatus(const std::string& filename,
request.set_filename(filename);
FillUserInfo<CheckSnapShotStatusRequest>(&request, userinfo);
LOG(INFO) << "CheckSnapShotStatus: filename = " << filename.c_str()
LOG(INFO) << "CheckSnapShotStatus: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", seqnum = " << seq
<< ", log id = " << cntl->log_id();
@ -299,7 +299,7 @@ void MDSClientBase::CreateCloneFile(const std::string& source,
LOG(INFO) << "CreateCloneFile: source = " << source
<< ", destination = " << destination
<< ", owner = " << userinfo.owner.c_str() << ", seqnum = " << sn
<< ", owner = " << userinfo.owner << ", seqnum = " << sn
<< ", size = " << size << ", chunksize = " << chunksize
<< ", log id = " << cntl->log_id();
@ -322,8 +322,8 @@ void MDSClientBase::SetCloneFileStatus(const std::string &filename,
}
FillUserInfo<SetCloneFileStatusRequest>(&request, userinfo);
LOG(INFO) << "SetCloneFileStatus: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG(INFO) << "SetCloneFileStatus: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", filestatus = " << static_cast<int>(filestatus)
<< ", fileID = " << fileID
<< ", log id = " << cntl->log_id();
@ -350,7 +350,7 @@ void MDSClientBase::GetOrAllocateSegment(bool allocate,
FillUserInfo<GetOrAllocateSegmentRequest>(&request, fi->userinfo);
LOG(INFO) << "GetOrAllocateSegment: allocate = " << allocate
<< ", owner = " << fi->owner.c_str()
<< ", owner = " << fi->owner
<< ", offset = " << offset
<< ", segment offset = " << seg_offset
<< ", log id = " << cntl->log_id();
@ -376,11 +376,11 @@ void MDSClientBase::RenameFile(const UserInfo_t& userinfo,
}
FillUserInfo<RenameFileRequest>(&request, userinfo);
LOG(INFO) << "RenameFile: origin = " << origin.c_str()
<< ", destination = " << destination.c_str()
LOG(INFO) << "RenameFile: origin = " << origin
<< ", destination = " << destination
<< ", originId = " << originId
<< ", destinationId = " << destinationId
<< ", owner = " << userinfo.owner.c_str()
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
curve::mds::CurveFSService_Stub stub(channel);
@ -398,8 +398,8 @@ void MDSClientBase::Extend(const std::string& filename,
request.set_newsize(newsize);
FillUserInfo<ExtendFileRequest>(&request, userinfo);
LOG(INFO) << "Extend: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG(INFO) << "Extend: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", newsize = " << newsize
<< ", log id = " << cntl->log_id();
@ -422,8 +422,8 @@ void MDSClientBase::DeleteFile(const std::string& filename,
}
FillUserInfo<DeleteFileRequest>(&request, userinfo);
LOG(INFO) << "DeleteFile: filename = " << filename.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG(INFO) << "DeleteFile: filename = " << filename
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
curve::mds::CurveFSService_Stub stub(channel);
@ -444,9 +444,9 @@ void MDSClientBase::ChangeOwner(const std::string& filename,
request.set_rootowner(userinfo.owner);
request.set_signature(CalcSignature(userinfo, date));
LOG(INFO) << "ChangeOwner: filename = " << filename.c_str()
<< ", operator owner = " << userinfo.owner.c_str()
<< ", new owner = " << newOwner.c_str()
LOG(INFO) << "ChangeOwner: filename = " << filename
<< ", operator owner = " << userinfo.owner
<< ", new owner = " << newOwner
<< ", log id = " << cntl->log_id();
curve::mds::CurveFSService_Stub stub(channel);
@ -463,8 +463,8 @@ void MDSClientBase::Listdir(const std::string& dirpath,
FillUserInfo<::curve::mds::ListDirRequest>(&request, userinfo);
LOG(INFO) << "Listdir: filename = " << dirpath.c_str()
<< ", owner = " << userinfo.owner.c_str()
LOG(INFO) << "Listdir: filename = " << dirpath
<< ", owner = " << userinfo.owner
<< ", log id = " << cntl->log_id();
curve::mds::CurveFSService_Stub stub(channel);

View File

@ -125,7 +125,7 @@ int MetaCache::GetLeader(LogicPoolID logicPoolId,
}
if (ret == -1) {
LOG_EVERY_N(ERROR, 10) << "get leader failed after retry!"
LOG(WARNING) << "get leader failed after retry!"
<< ", copyset id = " << copysetId
<< ", logicpool id = " << logicPoolId;
return -1;
@ -149,7 +149,7 @@ int MetaCache::UpdateLeaderInternal(LogicPoolID logicPoolId,
getLeaderInfo, &leaderaddr, &csid, fm);
if (ret == -1) {
LOG_EVERY_N(ERROR, 10) << "get leader failed!"
LOG(WARNING) << "get leader failed!"
<< ", copyset id = " << copysetId
<< ", logicpool id = " << logicPoolId;
return -1;
@ -304,7 +304,7 @@ int MetaCache::SetServerUnstable(const std::string& serverIp) {
std::vector<ChunkServerID> csIds;
int ret = mdsclient_->ListChunkServerInServer(serverIp, &csIds);
if (ret != LIBCURVE_ERROR::OK) {
LOG(WARNING) << "ListChunkServer failed";
LOG(ERROR) << "ListChunkServer failed, server ip: " << serverIp;
return -1;
}

View File

@ -237,6 +237,12 @@ class MetaCache {
fileInfo_.seqnum = newSn;
}
FileStatus GetLatestFileStatus() const { return fileInfo_.filestatus; }
void SetLatestFileStatus(FileStatus status) {
fileInfo_.filestatus = status;
}
/**
* copyset的LeaderMayChange标志
*/

View File

@ -34,19 +34,22 @@ namespace client {
struct RequestSourceInfo {
std::string cloneFileSource;
uint64_t cloneFileOffset{0};
uint64_t cloneFileOffset = 0;
bool valid = false;
RequestSourceInfo() = default;
RequestSourceInfo(const std::string& source, uint64_t offset)
: cloneFileSource(source), cloneFileOffset(offset) {}
: cloneFileSource(source), cloneFileOffset(offset), valid(true) {}
bool IsValid() const { return valid; }
};
inline std::ostream& operator<<(std::ostream& os,
const RequestSourceInfo& location) {
if (location.cloneFileSource.empty()) {
os << "empty";
} else {
if (location.IsValid()) {
os << location.cloneFileSource << ":" << location.cloneFileOffset;
} else {
os << "empty";
}
return os;

View File

@ -37,6 +37,36 @@ namespace client {
static void EmptyDeleter(void* ptr) {}
using curve::chunkserver::ChunkRequest;
using curve::chunkserver::ChunkResponse;
using curve::chunkserver::ChunkService_Stub;
using curve::chunkserver::GetChunkInfoRequest;
using curve::chunkserver::GetChunkInfoResponse;
using curve::common::TimeUtility;
using ::google::protobuf::Closure;
inline void RequestSender::UpdateRpcRPS(ClientClosure* done,
OpType type) const {
RequestClosure* request = static_cast<RequestClosure*>(done->GetClosure());
MetricHelper::IncremRPCRPSCount(request->GetMetric(), type);
}
inline void RequestSender::SetRpcStuff(
ClientClosure* done, brpc::Controller* cntl,
google::protobuf::Message* rpcResponse) const {
RequestClosure* request = static_cast<RequestClosure*>(done->GetClosure());
request->SetStartTime(TimeUtility::GetTimeofDayUs());
cntl->set_timeout_ms(
std::max(request->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
done->SetResponse(rpcResponse);
done->SetChunkServerID(chunkServerId_);
done->SetChunkServerEndPoint(serverEndPoint_);
}
int RequestSender::Init(const IOSenderOption_t& ioSenderOpt) {
if (0 != channel_.Init(serverEndPoint_, NULL)) {
LOG(ERROR) << "failed to init channel to server, id: " << chunkServerId_
@ -49,7 +79,7 @@ int RequestSender::Init(const IOSenderOption_t& ioSenderOpt) {
return 0;
}
int RequestSender::ReadChunk(ChunkIDInfo idinfo,
int RequestSender::ReadChunk(const ChunkIDInfo& idinfo,
uint64_t sn,
off_t offset,
size_t length,
@ -57,20 +87,11 @@ int RequestSender::ReadChunk(ChunkIDInfo idinfo,
const RequestSourceInfo& sourceInfo,
ClientClosure *done) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
MetricHelper::IncremRPCRPSCount(rc->GetMetric(), OpType::READ);
rc->SetStartTime(TimeUtility::GetTimeofDayUs());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
done->SetChunkServerID(chunkServerId_);
done->SetChunkServerEndPoint(serverEndPoint_);
UpdateRpcRPS(done, OpType::READ);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(curve::chunkserver::CHUNK_OP_TYPE::CHUNK_OP_READ);
@ -80,7 +101,7 @@ int RequestSender::ReadChunk(ChunkIDInfo idinfo,
request.set_offset(offset);
request.set_size(length);
if (!sourceInfo.cloneFileSource.empty()) {
if (sourceInfo.IsValid()) {
request.set_clonefilesource(sourceInfo.cloneFileSource);
request.set_clonefileoffset(sourceInfo.cloneFileOffset);
}
@ -94,7 +115,7 @@ int RequestSender::ReadChunk(ChunkIDInfo idinfo,
return 0;
}
int RequestSender::WriteChunk(ChunkIDInfo idinfo,
int RequestSender::WriteChunk(const ChunkIDInfo& idinfo,
uint64_t sn,
const char *buf,
off_t offset,
@ -102,22 +123,14 @@ int RequestSender::WriteChunk(ChunkIDInfo idinfo,
const RequestSourceInfo& sourceInfo,
ClientClosure *done) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
MetricHelper::IncremRPCRPSCount(rc->GetMetric(), OpType::WRITE);
rc->SetStartTime(TimeUtility::GetTimeofDayUs());
brpc::Controller *cntl = new brpc::Controller();
ChunkResponse *response = new ChunkResponse();
DVLOG(9) << "Sending request, buf header: "
<< " buf: " << *(unsigned int *)buf;
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
done->SetChunkServerID(chunkServerId_);
done->SetChunkServerEndPoint(serverEndPoint_);
UpdateRpcRPS(done, OpType::WRITE);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(curve::chunkserver::CHUNK_OP_TYPE::CHUNK_OP_WRITE);
@ -128,7 +141,7 @@ int RequestSender::WriteChunk(ChunkIDInfo idinfo,
request.set_offset(offset);
request.set_size(length);
if (!sourceInfo.cloneFileSource.empty()) {
if (sourceInfo.IsValid()) {
request.set_clonefilesource(sourceInfo.cloneFileSource);
request.set_clonefileoffset(sourceInfo.cloneFileOffset);
}
@ -141,21 +154,17 @@ int RequestSender::WriteChunk(ChunkIDInfo idinfo,
return 0;
}
int RequestSender::ReadChunkSnapshot(ChunkIDInfo idinfo,
int RequestSender::ReadChunkSnapshot(const ChunkIDInfo& idinfo,
uint64_t sn,
off_t offset,
size_t length,
ClientClosure *done) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
UpdateRpcRPS(done, OpType::READ_SNAP);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(curve::chunkserver::CHUNK_OP_TYPE::CHUNK_OP_READ_SNAP);
@ -171,19 +180,15 @@ int RequestSender::ReadChunkSnapshot(ChunkIDInfo idinfo,
return 0;
}
int RequestSender::DeleteChunkSnapshotOrCorrectSn(ChunkIDInfo idinfo,
uint64_t correctedSn,
ClientClosure *done) {
int RequestSender::DeleteChunkSnapshotOrCorrectSn(const ChunkIDInfo& idinfo,
uint64_t correctedSn,
ClientClosure* done) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
UpdateRpcRPS(done, OpType::DELETE_SNAP);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(curve::chunkserver::CHUNK_OP_TYPE::CHUNK_OP_DELETE_SNAP);
@ -199,18 +204,14 @@ int RequestSender::DeleteChunkSnapshotOrCorrectSn(ChunkIDInfo idinfo,
return 0;
}
int RequestSender::GetChunkInfo(ChunkIDInfo idinfo,
int RequestSender::GetChunkInfo(const ChunkIDInfo& idinfo,
ClientClosure *done) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
GetChunkInfoResponse *response = new GetChunkInfoResponse();
done->SetResponse(response);
UpdateRpcRPS(done, OpType::GET_CHUNK_INFO);
SetRpcStuff(done, cntl, response);
GetChunkInfoRequest request;
request.set_logicpoolid(idinfo.lpid_);
@ -221,22 +222,18 @@ int RequestSender::GetChunkInfo(ChunkIDInfo idinfo,
return 0;
}
int RequestSender::CreateCloneChunk(ChunkIDInfo idinfo,
int RequestSender::CreateCloneChunk(const ChunkIDInfo& idinfo,
ClientClosure *done,
const std::string &location,
uint64_t correntSn,
uint64_t sn,
uint64_t chunkSize) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
UpdateRpcRPS(done, OpType::CREATE_CLONE);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(
@ -258,15 +255,11 @@ int RequestSender::RecoverChunk(const ChunkIDInfo& idinfo,
uint64_t offset,
uint64_t len) {
brpc::ClosureGuard doneGuard(done);
RequestClosure* rc = static_cast<RequestClosure*>(done->GetClosure());
brpc::Controller *cntl = new brpc::Controller();
cntl->set_timeout_ms(
std::max(rc->GetNextTimeoutMS(),
iosenderopt_.failRequestOpt.chunkserverRPCTimeoutMS));
done->SetCntl(cntl);
ChunkResponse *response = new ChunkResponse();
done->SetResponse(response);
UpdateRpcRPS(done, OpType::RECOVER_CHUNK);
SetRpcStuff(done, cntl, response);
ChunkRequest request;
request.set_optype(curve::chunkserver::CHUNK_OP_TYPE::CHUNK_OP_RECOVER);

View File

@ -37,13 +37,6 @@
namespace curve {
namespace client {
using curve::chunkserver::ChunkRequest;
using curve::chunkserver::ChunkResponse;
using curve::chunkserver::GetChunkInfoRequest;
using curve::chunkserver::GetChunkInfoResponse;
using curve::chunkserver::ChunkService_Stub;
using ::google::protobuf::Closure;
/**
* RequestSender负责管理一个ChunkServer的所有
* connectionChunkServer仅有一个connection
@ -69,7 +62,7 @@ class RequestSender {
* @param sourceInfo
* @param done:closure
*/
int ReadChunk(ChunkIDInfo idinfo,
int ReadChunk(const ChunkIDInfo& idinfo,
uint64_t sn,
off_t offset,
size_t length,
@ -87,7 +80,7 @@ class RequestSender {
* @param sourceInfo
* @param done:closure
*/
int WriteChunk(ChunkIDInfo idinfo,
int WriteChunk(const ChunkIDInfo& idinfo,
uint64_t sn,
const char *buf,
off_t offset,
@ -103,7 +96,7 @@ class RequestSender {
* @param length:
* @param done:closure
*/
int ReadChunkSnapshot(ChunkIDInfo idinfo,
int ReadChunkSnapshot(const ChunkIDInfo& idinfo,
uint64_t sn,
off_t offset,
size_t length,
@ -116,7 +109,7 @@ class RequestSender {
* @param correctedSn:chunk需要修正的版本号
* @param done:closure
*/
int DeleteChunkSnapshotOrCorrectSn(ChunkIDInfo idinfo,
int DeleteChunkSnapshotOrCorrectSn(const ChunkIDInfo& idinfo,
uint64_t correctedSn,
ClientClosure *done);
@ -126,7 +119,7 @@ class RequestSender {
* @param done:closure
* @param retriedTimes:
*/
int GetChunkInfo(ChunkIDInfo idinfo,
int GetChunkInfo(const ChunkIDInfo& idinfo,
ClientClosure *done);
/**
@ -146,7 +139,7 @@ class RequestSender {
*
* @return
*/
int CreateCloneChunk(ChunkIDInfo idinfo,
int CreateCloneChunk(const ChunkIDInfo& idinfo,
ClientClosure *done,
const std::string &location,
uint64_t sn,
@ -178,6 +171,12 @@ class RequestSender {
return channel_.CheckHealth() == 0;
}
private:
void UpdateRpcRPS(ClientClosure* done, OpType type) const;
void SetRpcStuff(ClientClosure* done, brpc::Controller* cntl,
google::protobuf::Message* rpcResponse) const;
private:
// Rpc stub配置
IOSenderOption_t iosenderopt_;

View File

@ -35,49 +35,59 @@
namespace curve {
namespace client {
void ServiceHelper::ProtoFileInfo2Local(const curve::mds::FileInfo* finfo,
void ServiceHelper::ProtoFileInfo2Local(const curve::mds::FileInfo& finfo,
FInfo_t* fi) {
if (finfo->has_owner()) {
fi->owner = finfo->owner();
if (finfo.has_owner()) {
fi->owner = finfo.owner();
}
if (finfo->has_filename()) {
fi->filename = finfo->filename();
if (finfo.has_filename()) {
fi->filename = finfo.filename();
}
if (finfo->has_id()) {
fi->id = finfo->id();
if (finfo.has_id()) {
fi->id = finfo.id();
}
if (finfo->has_parentid()) {
fi->parentid = finfo->parentid();
if (finfo.has_parentid()) {
fi->parentid = finfo.parentid();
}
if (finfo->has_filetype()) {
fi->filetype = static_cast<FileType>(finfo->filetype());
if (finfo.has_filetype()) {
fi->filetype = static_cast<FileType>(finfo.filetype());
}
if (finfo->has_chunksize()) {
fi->chunksize = finfo->chunksize();
if (finfo.has_chunksize()) {
fi->chunksize = finfo.chunksize();
}
if (finfo->has_length()) {
fi->length = finfo->length();
if (finfo.has_length()) {
fi->length = finfo.length();
}
if (finfo->has_ctime()) {
fi->ctime = finfo->ctime();
if (finfo.has_ctime()) {
fi->ctime = finfo.ctime();
}
if (finfo->has_chunksize()) {
fi->chunksize = finfo->chunksize();
if (finfo.has_chunksize()) {
fi->chunksize = finfo.chunksize();
}
if (finfo->has_segmentsize()) {
fi->segmentsize = finfo->segmentsize();
if (finfo.has_segmentsize()) {
fi->segmentsize = finfo.segmentsize();
}
if (finfo->has_seqnum()) {
fi->seqnum = finfo->seqnum();
if (finfo.has_seqnum()) {
fi->seqnum = finfo.seqnum();
}
if (finfo->has_filestatus()) {
fi->filestatus = (FileStatus)finfo->filestatus();
if (finfo.has_filestatus()) {
fi->filestatus = (FileStatus)finfo.filestatus();
}
if (finfo->has_clonesource()) {
fi->cloneSource = finfo->clonesource();
}
if (finfo->has_clonelength()) {
fi->cloneLength = finfo->clonelength();
}
void ServiceHelper::ProtoCloneSourceInfo2Local(
const curve::mds::OpenFileResponse& openFileResponse,
CloneSourceInfo* info) {
const curve::mds::FileInfo& fileInfo = openFileResponse.fileinfo();
const curve::mds::CloneSourceSegment& sourceSegment =
openFileResponse.clonesourcesegment();
info->name = fileInfo.clonesource();
info->length = fileInfo.clonelength();
info->segmentSize = sourceSegment.segmentsize();
for (int i = 0; i < sourceSegment.allocatedsegmentoffset_size(); ++i) {
info->allocatedSegmentOffsets.insert(
sourceSegment.allocatedsegmentoffset(i));
}
}
@ -338,7 +348,6 @@ bool ServiceHelper::GetUserInfoFromFilename(const std::string& filename,
*realfilename = filename.substr(0, user_begin);
*user = filename.substr(user_begin + 1, user_end - user_begin - 1);
LOG(INFO) << "user info [" << *user << "]";
return true;
}
@ -375,4 +384,3 @@ int ServiceHelper::CheckChunkServerHealth(
} // namespace client
} // namespace curve

View File

@ -95,8 +95,13 @@ class ServiceHelper {
* @param: finfo为proto格式的文件信息
* @param: fi为本地格式的文件信息
*/
static void ProtoFileInfo2Local(const curve::mds::FileInfo* finfo,
static void ProtoFileInfo2Local(const curve::mds::FileInfo& finfo,
FInfo_t* fi);
static void ProtoCloneSourceInfo2Local(
const curve::mds::OpenFileResponse& openFileResponse,
CloneSourceInfo* info);
/**
* chunkserver端获取最新的leader信息
* @param[in]: getLeaderInfo为对应copyset的信息

View File

@ -178,7 +178,7 @@ bool Splitor::AssignInternal(IOTracker* iotracker,
(off_t)chunkidx * fileinfo->chunksize,
fileinfo,
&segInfo);
if (re == LIBCURVE_ERROR::FAILED || re == LIBCURVE_ERROR::AUTHFAIL) {
if (re != LIBCURVE_ERROR::OK) {
LOG(ERROR) << "GetOrAllocateSegment failed! "
<< "offset = " << chunkidx * fileinfo->chunksize;
return false;
@ -281,23 +281,21 @@ RequestContext* Splitor::GetInitedRequestContext() {
RequestSourceInfo Splitor::CalcRequestSourceInfo(IOTracker* ioTracker,
MetaCache* metaCache,
ChunkIndex chunkIdx) {
const FInfo* fileInfo = metaCache->GetFileInfo();
if (fileInfo->cloneSource.empty()) {
return {};
}
OpType type = ioTracker->Optype();
if (type != OpType::READ && type != OpType::WRITE) {
return {};
}
uint64_t offset = static_cast<uint64_t>(chunkIdx) * fileInfo->chunksize;
if (offset >= fileInfo->cloneLength) {
return {};
const FInfo* fileInfo = metaCache->GetFileInfo();
if (fileInfo->filestatus == FileStatus::CloneMetaInstalled) {
const CloneSourceInfo& sourceInfo = fileInfo->sourceInfo;
uint64_t offset = static_cast<uint64_t>(chunkIdx) * fileInfo->chunksize;
if (sourceInfo.IsSegmentAllocated(offset)) {
return {sourceInfo.name, offset};
}
}
return {fileInfo->cloneSource, offset};
return {};
}
} // namespace client

View File

@ -39,7 +39,20 @@ const char CHUNKSTOREKEYEND[] = "06";
const char LEADERCAMPAIGNNPFX[] = "07leader";
const char SEGMENTALLOCSIZEKEY[] = "08";
const char SEGMENTALLOCSIZEKEYEND[] = "09";
const char TOPOLOGYITEMPRIFIX[] = "10";
const char LOGICALPOOLKEYPREFIX[] = "1001";
const char LOGICALPOOLKEYEND[] = "1002";
const char PHYSICALPOOLKEYPREFIX[] = "1002";
const char PHYSICALPOOLKEYEND[] = "1003";
const char ZONEKEYPREFIX[] = "1003";
const char ZONEKEYEND[] = "1004";
const char SERVERKEYPREFIX[] = "1004";
const char SERVERKEYEND[] = "1005";
const char CHUNKSERVERKEYPREFIX[] = "1005";
const char CHUNKSERVERKEYEND[] = "1006";
const char CLUSTERINFOKEY[] = "1007";
const char COPYSETKEYPREFIX[] = "1008";
const char COPYSETKEYEND[] = "1009";
const char SNAPINFOKEYPREFIX[] = "11";
const char SNAPINFOKEYEND[] = "12";

View File

@ -129,6 +129,7 @@ int EtcdClientImp::List(const std::string &startKey, const std::string &endKey,
out->emplace_back(
std::string(objRes.r1, objRes.r1 + objRes.r2));
free(objRes.r1);
free(objRes.r3);
}
EtcdClientRemoveObject(res.r1);
}

View File

@ -126,11 +126,7 @@ const uint64_t kMB = 1024*kKB;
const uint64_t kGB = 1024*kMB;
const uint64_t kTB = 1024*kGB;
extern uint64_t DefaultSegmentSize;
extern uint64_t kMiniFileLength;
const uint64_t kMaxFileLength = 4 * kTB;
// curve默认root目录&inodeid
// curve default root path and inodeid
const InodeID ROOTINODEID = 0;
const char ROOTFILENAME[] = "/";

View File

@ -35,12 +35,12 @@ DEFINE_uint32(dummyPort, 6667, "dummy server port");
using ::curve::mds::kMB;
using ::curve::mds::kGB;
using ::curve::mds::DefaultSegmentSize;
using ::curve::mds::kMiniFileLength;
using ::curve::mds::kTB;
DEFINE_uint64(chunkSize, 16 * kMB, "chunk size");
DEFINE_uint64(segmentSize, 1 * kGB, "segment size");
DEFINE_uint64(minFileLength, 10 * kGB, "min filglength");
DEFINE_uint64(minFileLength, 10 * kGB, "min filelength");
DEFINE_uint64(maxFileLength, 20 * kTB, "max filelength");
void LoadConfigFromCmdline(Configuration *conf) {
google::CommandLineFlagInfo info;
@ -57,11 +57,16 @@ void LoadConfigFromCmdline(Configuration *conf) {
}
if (GetCommandLineFlagInfo("segmentSize", &info) && !info.is_default) {
DefaultSegmentSize = FLAGS_segmentSize;
conf->SetUInt64Value(
"mds.curvefs.defaultSegmentSize", FLAGS_segmentSize);
}
if (GetCommandLineFlagInfo("minFileLength", &info) && !info.is_default) {
kMiniFileLength = FLAGS_minFileLength;
conf->SetUInt64Value("mds.curvefs.minFileLength", FLAGS_minFileLength);
}
if (GetCommandLineFlagInfo("maxFileLength", &info) && !info.is_default) {
conf->SetUInt64Value("mds.curvefs.maxFileLength", FLAGS_maxFileLength);
}
if (GetCommandLineFlagInfo("mdsDbName", &info) && !info.is_default) {

View File

@ -37,8 +37,13 @@ namespace mds {
typedef uint64_t TaskIDType;
// default clean task retry times
const uint32_t kDefaultTaskRetryTimes = 5;
class Task {
public:
Task() : taskID_(0), progress_(), retry_(1) {}
virtual void Run(void) = 0;
std::function<void()> Closure() {
@ -67,9 +72,24 @@ class Task {
return taskID_;
}
void SetRetryTimes(uint32_t retry) {
retry_ = retry;
}
void Retry() {
retry_--;
progress_ = TaskProgress();
}
bool RetryTimesExceed() {
return retry_ == 0;
}
protected:
TaskIDType taskID_;
TaskProgress progress_;
// 任务最大重试次数
uint32_t retry_;
};
class SnapShotCleanTask: public Task {
@ -82,6 +102,7 @@ class SnapShotCleanTask: public Task {
SetTaskProgress(TaskProgress());
SetTaskID(taskID);
asyncEntity_ = entity;
SetRetryTimes(kDefaultTaskRetryTimes);
}
void Run(void) override {
StatusCode ret = cleanCore_->CleanSnapShotFile(fileInfo_,
@ -126,6 +147,7 @@ class CommonFileCleanTask: public Task {
fileInfo_ = fileInfo;
SetTaskProgress(TaskProgress());
SetTaskID(taskID);
SetRetryTimes(kDefaultTaskRetryTimes);
}
void Run(void) override {

View File

@ -47,10 +47,22 @@ void CleanTaskManager::CheckCleanResult(void) {
iter = cleanTasks_.erase(iter);
continue;
} else if (taskProgress.GetStatus() == TaskStatus::FAILED) {
LOG(WARNING) << "CleanTaskManager find Task Failed, retry,"
<< " taskID = " << iter->second->GetTaskID();
iter->second->SetTaskProgress(TaskProgress());
cleanWorkers_->Enqueue(iter->second->Closure());
iter->second->Retry();
if (!iter->second->RetryTimesExceed()) {
LOG(WARNING) << "CleanTaskManager find Task Failed,"
<< " retry,"
<< " taskID = "
<< iter->second->GetTaskID();
cleanWorkers_->Enqueue(iter->second->Closure());
} else {
LOG(ERROR) << "CleanTaskManager find Task Failed,"
<< " retry times exceed,"
<< " going to remove task,"
<< " taskID = "
<< iter->second->GetTaskID();
iter = cleanTasks_.erase(iter);
continue;
}
}
++iter;
}

View File

@ -31,6 +31,7 @@
#include "src/common/timeutility.h"
#include "src/mds/nameserver2/namespace_storage.h"
#include "src/mds/common/mds_define.h"
#include "src/mds/nameserver2/helper/namespace_helper.h"
using curve::common::TimeUtility;
using ::std::chrono::steady_clock;
@ -100,6 +101,9 @@ bool CurveFS::Init(std::shared_ptr<NameServerStorage> storage,
rootAuthOptions_ = curveFSOptions.authOptions;
defaultChunkSize_ = curveFSOptions.defaultChunkSize;
defaultSegmentSize_ = curveFSOptions.defaultSegmentSize;
minFileLength_ = curveFSOptions.minFileLength;
maxFileLength_ = curveFSOptions.maxFileLength;
topology_ = topology;
InitRootFile();
@ -220,24 +224,24 @@ StatusCode CurveFS::CreateFile(const std::string & fileName,
// check param
if (filetype == FileType::INODE_PAGEFILE) {
if (length < kMiniFileLength) {
LOG(ERROR) << "file Length < MinFileLength " << kMiniFileLength
if (length < minFileLength_) {
LOG(ERROR) << "file Length < MinFileLength " << minFileLength_
<< ", length = " << length;
return StatusCode::kFileLengthNotSupported;
}
if (length > kMaxFileLength) {
if (length > maxFileLength_) {
LOG(ERROR) << "CreateFile file length > maxFileLength, fileName = "
<< fileName << ", length = " << length
<< ", maxFileLength = " << kMaxFileLength;
<< ", maxFileLength = " << maxFileLength_;
return StatusCode::kFileLengthNotSupported;
}
if (length % DefaultSegmentSize != 0) {
if (length % defaultSegmentSize_ != 0) {
LOG(ERROR) << "Create file length not align to segment size, "
<< "fileName = " << fileName
<< ", length = " << length
<< ", segment size = " << DefaultSegmentSize;
<< ", segment size = " << defaultSegmentSize_;
return StatusCode::kFileLengthNotSupported;
}
}
@ -271,7 +275,7 @@ StatusCode CurveFS::CreateFile(const std::string & fileName,
fileInfo.set_filetype(filetype);
fileInfo.set_owner(owner);
fileInfo.set_chunksize(defaultChunkSize_);
fileInfo.set_segmentsize(DefaultSegmentSize);
fileInfo.set_segmentsize(defaultSegmentSize_);
fileInfo.set_length(length);
fileInfo.set_ctime(::curve::common::TimeUtility::GetTimeofDayUs());
fileInfo.set_seqnum(kStartSeqNum);
@ -848,10 +852,10 @@ StatusCode CurveFS::ExtendFile(const std::string &filename,
return StatusCode::kNotSupported;
}
if (newLength > kMaxFileLength) {
if (newLength > maxFileLength_) {
LOG(ERROR) << "ExtendFile newLength > maxFileLength, fileName = "
<< filename << ", newLength = " << newLength
<< ", maxFileLength = " << kMaxFileLength;
<< ", maxFileLength = " << maxFileLength_;
return StatusCode::kFileLengthNotSupported;
}
@ -1201,7 +1205,7 @@ StatusCode CurveFS::CheckSnapShotFileStatus(const std::string &fileName,
FileInfo snapShotFileInfo;
StatusCode ret = GetSnapShotFileInfo(fileName, seq, &snapShotFileInfo);
if (ret != StatusCode::kOK) {
LOG(ERROR) << "GetSnapShotFileInfo file fail, fileName = "
LOG(WARNING) << "GetSnapShotFileInfo file fail, fileName = "
<< fileName << ", seq = " << seq << ", ret = " << ret;
return ret;
}
@ -1211,25 +1215,35 @@ StatusCode CurveFS::CheckSnapShotFileStatus(const std::string &fileName,
TaskIDType taskID = static_cast<TaskIDType>(snapShotFileInfo.id());
auto task = cleanManager_->GetTask(taskID);
if (task == nullptr) {
*progress = 100;
return StatusCode::kOK;
// GetSnapShotFileInfo again
StatusCode ret2 =
GetSnapShotFileInfo(fileName, seq, &snapShotFileInfo);
// if not exist, means delete succeed.
if (StatusCode::kSnapshotFileNotExists == ret2) {
*progress = 100;
return StatusCode::kSnapshotFileNotExists;
// else the snapshotFile still exist,
// means delete failed and retry times exceed.
} else {
*progress = 0;
LOG(ERROR) << "snapshot file delete fail, fileName = "
<< fileName << ", seq = " << seq;
return StatusCode::kSnapshotFileDeleteError;
}
}
TaskStatus taskStatus = task->GetTaskProgress().GetStatus();
switch (taskStatus) {
case TaskStatus::PROGRESSING:
case TaskStatus::FAILED: // FAILED task will retry
*progress = task->GetTaskProgress().GetProgress();
break;
case TaskStatus::FAILED:
*progress = 0;
LOG(ERROR) << "snapshot file delete fail, fileName = "
<< fileName << ", seq = " << seq;
return StatusCode::kSnapshotFileDeleteError;
case TaskStatus::SUCCESS:
*progress = 100;
break;
}
} else {
// means delete haven't begin.
*progress = 0;
}
@ -1246,7 +1260,7 @@ StatusCode CurveFS::GetSnapShotFileSegment(
FileInfo snapShotFileInfo;
StatusCode ret = GetSnapShotFileInfo(fileName, seq, &snapShotFileInfo);
if (ret != StatusCode::kOK) {
LOG(ERROR) << "GetSnapShotFileInfo file fail, fileName = "
LOG(WARNING) << "GetSnapShotFileInfo file fail, fileName = "
<< fileName << ", seq = " << seq << ", ret = " << ret;
return ret;
}
@ -1308,8 +1322,9 @@ StatusCode CurveFS::GetSnapShotFileSegment(
StatusCode CurveFS::OpenFile(const std::string &fileName,
const std::string &clientIP,
ProtoSession *protoSession,
FileInfo *fileInfo) {
// 检查文件是否存在
FileInfo *fileInfo,
CloneSourceSegment* cloneSourceSegment) {
// check the existence of the file
StatusCode ret;
ret = GetFileInfo(fileName, fileInfo);
if (ret == StatusCode::kFileNotExists) {
@ -1326,6 +1341,8 @@ StatusCode CurveFS::OpenFile(const std::string &fileName,
return ret;
}
LOG(INFO) << "FileInfo, " << fileInfo->DebugString();
if (fileInfo->filetype() != FileType::INODE_PAGEFILE) {
LOG(ERROR) << "OpenFile file type not support, fileName = " << fileName
<< ", clientIP = " << clientIP
@ -1335,6 +1352,11 @@ StatusCode CurveFS::OpenFile(const std::string &fileName,
fileRecordManager_->GetRecordParam(protoSession);
// clone file
if (fileInfo->has_clonesource() && isPathValid(fileInfo->clonesource())) {
return ListCloneSourceFileSegments(fileInfo, cloneSourceSegment);
}
return StatusCode::kOK;
}
@ -1418,9 +1440,9 @@ StatusCode CurveFS::CreateCloneFile(const std::string &fileName,
return StatusCode::kParaError;
}
if (length < kMiniFileLength || seq < kStartSeqNum) {
if (length < minFileLength_ || seq < kStartSeqNum) {
LOG(WARNING) << "CreateCloneFile err, filename = " << fileName
<< "file Length < MinFileLength " << kMiniFileLength
<< "file Length < MinFileLength " << minFileLength_
<< ", length = " << length;
return StatusCode::kParaError;
}
@ -1461,7 +1483,7 @@ StatusCode CurveFS::CreateCloneFile(const std::string &fileName,
fileInfo.set_owner(owner);
fileInfo.set_chunksize(chunksize);
fileInfo.set_segmentsize(DefaultSegmentSize);
fileInfo.set_segmentsize(defaultSegmentSize_);
fileInfo.set_length(length);
fileInfo.set_ctime(::curve::common::TimeUtility::GetTimeofDayUs());
@ -1809,6 +1831,61 @@ StatusCode CurveFS::ListClient(bool listAllClient,
return StatusCode::kOK;
}
StatusCode CurveFS::ListCloneSourceFileSegments(
const FileInfo* fileInfo, CloneSourceSegment* cloneSourceSegment) const {
if (fileInfo->filestatus() != FileStatus::kFileCloneMetaInstalled) {
LOG(INFO) << fileInfo->filename()
<< " hash clone source, but file status is "
<< FileStatus_Name(fileInfo->filestatus())
<< ", return empty CloneSourceSegment";
return StatusCode::kOK;
}
if (!cloneSourceSegment) {
LOG(ERROR) << "OpenFile failed, file has clone source, but "
"cloneSourceSegments is nullptr, filename = "
<< fileInfo->filename();
return StatusCode::kParaError;
}
FileInfo cloneSourceFileInfo;
StatusCode ret = GetFileInfo(fileInfo->clonesource(), &cloneSourceFileInfo);
if (ret != StatusCode::kOK) {
LOG(ERROR)
<< "OpenFile failed, Get clone source file info failed, ret = "
<< StatusCode_Name(ret) << ", filename = " << fileInfo->filename()
<< ", clone source = " << fileInfo->clonesource()
<< ", file status = " << FileStatus_Name(fileInfo->filestatus());
return ret;
}
std::vector<PageFileSegment> segments;
StoreStatus status =
storage_->ListSegment(cloneSourceFileInfo.id(), &segments);
if (status != StoreStatus::OK) {
LOG(ERROR) << "OpenFile failed, list clone source segment failed, "
"filename = "
<< fileInfo->filename()
<< ", source file name = " << fileInfo->clonesource()
<< ", ret = " << status;
return StatusCode::kStorageError;
}
cloneSourceSegment->set_segmentsize(fileInfo->segmentsize());
if (segments.empty()) {
LOG(WARNING) << "Clone source file has no segments, filename = "
<< fileInfo->clonesource();
} else {
for (const auto& segment : segments) {
cloneSourceSegment->add_allocatedsegmentoffset(
segment.startoffset());
}
}
return StatusCode::kOK;
}
StatusCode CurveFS::FindFileMountPoint(
const std::string& fileName,
ClientInfo* clientInfo) {
@ -1836,6 +1913,18 @@ uint64_t CurveFS::GetDefaultChunkSize() {
return defaultChunkSize_;
}
uint64_t CurveFS::GetDefaultSegmentSize() {
return defaultSegmentSize_;
}
uint64_t CurveFS::GetMinFileLength() {
return minFileLength_;
}
uint64_t CurveFS::GetMaxFileLength() {
return maxFileLength_;
}
CurveFS &kCurveFS = CurveFS::GetInstance();
uint64_t GetOpenFileNum(void *varg) {

View File

@ -52,6 +52,9 @@ struct RootAuthOption {
struct CurveFSOption {
uint64_t defaultChunkSize;
uint64_t defaultSegmentSize;
uint64_t minFileLength;
uint64_t maxFileLength;
RootAuthOption authOptions;
FileRecordOptions fileRecordOptions;
};
@ -307,7 +310,8 @@ class CurveFS {
StatusCode OpenFile(const std::string &fileName,
const std::string &clientIP,
ProtoSession *protoSession,
FileInfo *fileInfo);
FileInfo *fileInfo,
CloneSourceSegment* cloneSourceSegment = nullptr);
/**
* @brief
@ -465,6 +469,27 @@ class CurveFS {
*/
uint64_t GetDefaultChunkSize();
/**
* @brief get the defaultSegmentSize info of curvefs
* @param:
* @return return defaultSegmentSize info obtained
*/
uint64_t GetDefaultSegmentSize();
/**
* @brief get the minFileLength info of curvefs
* @param:
* @return return minFileLength info obtained
*/
uint64_t GetMinFileLength();
/**
* @brief get the maxFileLength info of curvefs
* @param:
* @return return maxFileLength info obtained
*/
uint64_t GetMaxFileLength();
private:
CurveFS() = default;
@ -593,6 +618,28 @@ class CurveFS {
const FileInfo& fileInfo,
uint64_t* fileSize);
/**
* @brief check whether mds has started for enough time, based on the
* file record expiration time(mds.file.expiredTimeUs)
* @param times multiple of file record expiration time
* @return return true if ok, otherwise return false
*/
bool IsStartEnoughTime(int times) const {
std::chrono::steady_clock::duration timePass =
std::chrono::steady_clock::now() - startTime_;
uint32_t expiredUs = fileRecordManager_->GetFileRecordExpiredTimeUs();
return timePass >= times * std::chrono::microseconds(expiredUs);
}
/**
* @brief list clone source file's segment,
* if current file status is in kFileCloneMetaInstalled
* @param fileInfo current file info
* @param[out] cloneSourceSegment source file allocated segments
*/
StatusCode ListCloneSourceFileSegments(
const FileInfo* fileInfo, CloneSourceSegment* cloneSourceSegment) const;
private:
FileInfo rootFileInfo_;
std::shared_ptr<NameServerStorage> storage_;
@ -605,6 +652,9 @@ class CurveFS {
struct RootAuthOption rootAuthOptions_;
uint64_t defaultChunkSize_;
uint64_t defaultSegmentSize_;
uint64_t minFileLength_;
uint64_t maxFileLength_;
std::chrono::steady_clock::time_point startTime_;
};
extern CurveFS &kCurveFS;

View File

@ -51,6 +51,32 @@ class NameSpaceStorageCodec {
static bool DecodeSegmentAllocValue(
const std::string &value, uint16_t *lid, uint64_t *alloc);
};
inline bool isPathValid(const std::string path) {
if (path.empty() || path[0] != '/') {
return false;
}
if (path.size() > 1U && path[path.size() - 1] == '/') {
return false;
}
bool slash = false;
for (uint32_t i = 0; i < path.size(); i++) {
if (path[i] == '/') {
if (slash) {
return false;
}
slash = true;
} else {
slash = false;
}
}
// if some other limits to path can add here in the future
return true;
}
} // namespace mds
} // namespace curve

View File

@ -28,6 +28,7 @@
#include "src/mds/nameserver2/file_lock.h"
#include "src/common/string_util.h"
#include "src/common/timeutility.h"
#include "src/mds/nameserver2/helper/namespace_helper.h"
namespace curve {
namespace mds {
@ -1179,10 +1180,12 @@ void NameSpaceService::OpenFile(::google::protobuf::RpcController* controller,
ProtoSession *protoSession = new ProtoSession();
FileInfo *fileInfo = new FileInfo();
CloneSourceSegment* cloneSourceSegment = new CloneSourceSegment();
retCode = kCurveFS.OpenFile(request->filename(),
clientIP,
protoSession,
fileInfo);
fileInfo,
cloneSourceSegment);
if (retCode != StatusCode::kOK) {
response->set_statuscode(retCode);
if (google::ERROR != GetMdsLogLevel(retCode)) {
@ -1206,11 +1209,19 @@ void NameSpaceService::OpenFile(::google::protobuf::RpcController* controller,
}
delete protoSession;
delete fileInfo;
delete cloneSourceSegment;
return;
} else {
response->set_allocated_protosession(protoSession);
response->set_allocated_fileinfo(fileInfo);
response->set_statuscode(StatusCode::kOK);
if (cloneSourceSegment->IsInitialized()) {
response->set_allocated_clonesourcesegment(cloneSourceSegment);
} else {
delete cloneSourceSegment;
}
LOG(INFO) << "logid = " << cntl->log_id()
<< ", OpenFile ok, filename = " << request->filename()
<< ", clientip = " << clientIP
@ -1430,32 +1441,6 @@ void NameSpaceService::RefreshSession(
return;
}
bool isPathValid(const std::string path) {
if (path.empty() || path[0] != '/') {
return false;
}
if (path.size() > 1U && path[path.size() - 1] == '/') {
return false;
}
bool slash = false;
for (uint32_t i = 0; i < path.size(); i++) {
if (path[i] == '/') {
if (slash) {
return false;
}
slash = true;
} else {
slash = false;
}
}
// 将来如果有path有其他限制可以在此处继续添加
return true;
}
bool IsRenamePathValid(const std::string& oldFileName,
const std::string& newFileName) {
std::vector<std::string> oldFilePaths;
@ -1815,6 +1800,7 @@ uint32_t GetMdsLogLevel(StatusCode code) {
case StatusCode::kFileIdNotMatch:
case StatusCode::kSessionNotExist:
case StatusCode::kFileOccupied:
case StatusCode::kFileExists:
case StatusCode::kFileNotExists:
case StatusCode::kParaError:
return google::WARNING;

View File

@ -129,7 +129,7 @@ bool OperatorController::ApplyOperator(const CopySetInfo &originInfo,
// operator timeout or finish
if (operators_[originInfo.id].IsTimeout()) {
LOG(ERROR) << "apply operator: "
LOG(WARNING) << "apply operator: "
<< operators_[originInfo.id].OpToString()
<< " on " << originInfo.CopySetInfoStr()
<< " fail, operator is timeout";
@ -139,10 +139,10 @@ bool OperatorController::ApplyOperator(const CopySetInfo &originInfo,
auto res = operators_[originInfo.id].Apply(originInfo, newConf);
switch (res) {
case ApplyStatus::Failed:
LOG(ERROR) << "apply operator"
<< operators_[originInfo.id].OpToString()
<< " on " << originInfo.CopySetInfoStr()
<< " failed";
LOG(WARNING) << "apply operator"
<< operators_[originInfo.id].OpToString()
<< " on " << originInfo.CopySetInfoStr()
<< " failed";
RemoveOperatorLocked(originInfo.id);
return false;
case ApplyStatus::Finished:

View File

@ -221,7 +221,7 @@ void RecoverScheduler::CalculateExcludesChunkServer(
if (item.second.size() < chunkserverFailureTolerance_) {
continue;
}
LOG(ERROR) << "server " << item.first << " has "
LOG(WARNING) << "server " << item.first << " has "
<< item.second.size() << " offline chunkservers";
for (auto cs : item.second) {
excludes->emplace(cs);

View File

@ -458,6 +458,12 @@ void MDS::InitAuthOptions(RootAuthOption *authOptions) {
void MDS::InitCurveFSOptions(CurveFSOption *curveFSOptions) {
conf_->GetValueFatalIfFail(
"mds.curvefs.defaultChunkSize", &curveFSOptions->defaultChunkSize);
conf_->GetValueFatalIfFail(
"mds.curvefs.defaultSegmentSize", &curveFSOptions->defaultSegmentSize);
conf_->GetValueFatalIfFail(
"mds.curvefs.minFileLength", &curveFSOptions->minFileLength);
conf_->GetValueFatalIfFail(
"mds.curvefs.maxFileLength", &curveFSOptions->maxFileLength);
FileRecordOptions fileRecordOptions;
InitFileRecordOptions(&curveFSOptions->fileRecordOptions);

View File

@ -33,7 +33,7 @@ namespace topology {
std::string TopologyStorageCodec::EncodeLogicalPoolKey(
LogicalPoolIdType id) {
std::string key = TopologyStorageCodec::GetLogicalPoolKeyPrefix();
std::string key = LOGICALPOOLKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id);
@ -52,7 +52,7 @@ bool TopologyStorageCodec::DecodeLogicalPoolData(
std::string TopologyStorageCodec::EncodePhysicalPoolKey(
PhysicalPoolIdType id) {
std::string key = TopologyStorageCodec::GetPhysicalPoolKeyPrefix();
std::string key = PHYSICALPOOLKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id);
@ -71,7 +71,7 @@ bool TopologyStorageCodec::DecodePhysicalPoolData(
std::string TopologyStorageCodec::EncodeZoneKey(
ZoneIdType id) {
std::string key = TopologyStorageCodec::GetZoneKeyPrefix();
std::string key = ZONEKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id);
@ -90,7 +90,7 @@ bool TopologyStorageCodec::DecodeZoneData(
std::string TopologyStorageCodec::EncodeServerKey(
ServerIdType id) {
std::string key = TopologyStorageCodec::GetServerKeyPrefix();
std::string key = SERVERKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id);
@ -109,7 +109,7 @@ bool TopologyStorageCodec::DecodeServerData(
std::string TopologyStorageCodec::EncodeChunkServerKey(
ChunkServerIdType id) {
std::string key = TopologyStorageCodec::GetChunkServerKeyPrefix();
std::string key = CHUNKSERVERKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id);
@ -128,11 +128,11 @@ bool TopologyStorageCodec::DecodeChunkServerData(
std::string TopologyStorageCodec::EncodeCopySetKey(
const CopySetKey &id) {
std::string key = TopologyStorageCodec::GetCopysetKeyPrefix();
std::string key = COPYSETKEYPREFIX;
size_t prefixLen = key.size();
key.resize(prefixLen + sizeof(uint64_t) + sizeof(uint64_t));
::curve::common::EncodeBigEndian(&(key[prefixLen]), id.first);
::curve::common::EncodeBigEndian(&(key[prefixLen + sizeof(id.first)]),
::curve::common::EncodeBigEndian(&(key[prefixLen + sizeof(uint64_t)]),
id.second);
return key;
}

View File

@ -28,7 +28,19 @@
#include "src/common/namespace_define.h"
#include "src/mds/topology/topology_item.h"
using ::curve::common::TOPOLOGYITEMPRIFIX;
using ::curve::common::LOGICALPOOLKEYPREFIX;
using ::curve::common::LOGICALPOOLKEYEND;
using ::curve::common::PHYSICALPOOLKEYPREFIX;
using ::curve::common::PHYSICALPOOLKEYEND;
using ::curve::common::ZONEKEYPREFIX;
using ::curve::common::ZONEKEYEND;
using ::curve::common::SERVERKEYPREFIX;
using ::curve::common::SERVERKEYEND;
using ::curve::common::CHUNKSERVERKEYPREFIX;
using ::curve::common::CHUNKSERVERKEYEND;
using ::curve::common::CLUSTERINFOKEY;
using ::curve::common::COPYSETKEYPREFIX;
using ::curve::common::COPYSETKEYEND;
namespace curve {
namespace mds {
@ -76,66 +88,6 @@ class TopologyStorageCodec {
const ClusterInformation &data, std::string *value);
bool DecodeCluserInfoData(const std::string &value,
ClusterInformation *data);
public:
static std::string GetLogicalPoolKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "01";
return key;
}
static std::string GetPhysicalPoolKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "02";
return key;
}
static std::string GetZoneKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "03";
return key;
}
static std::string GetServerKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "04";
return key;
}
static std::string GetChunkServerKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "05";
return key;
}
static std::string GetCopysetKeyPrefix() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "06";
return key;
}
static std::string GetClusterInfoKey() {
static std::string key = std::string(TOPOLOGYITEMPRIFIX) + "07";
return key;
}
static std::string GetLogicalPoolKeyEnd() {
return GetPhysicalPoolKeyPrefix();
}
static std::string GetPhysicalPoolKeyEnd() {
return GetZoneKeyPrefix();
}
static std::string GetZoneKeyEnd() {
return GetServerKeyPrefix();
}
static std::string GetServerKeyEnd() {
return GetChunkServerKeyPrefix();
}
static std::string GetChunkServerKeyEnd() {
return GetCopysetKeyPrefix();
}
static std::string GetCopysetKeyEnd() {
return GetClusterInfoKey();
}
};

View File

@ -34,12 +34,10 @@ namespace topology {
bool TopologyStorageEtcd::LoadLogicalPool(
std::unordered_map<PoolIdType, LogicalPool> *logicalPoolMap,
PoolIdType *maxLogicalPoolId) {
std::string startKey = TopologyStorageCodec::GetLogicalPoolKeyPrefix();
std::string endKey = TopologyStorageCodec::GetLogicalPoolKeyEnd();
std::vector<std::string> out;
logicalPoolMap->clear();
*maxLogicalPoolId = 0;
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(LOGICALPOOLKEYPREFIX, LOGICALPOOLKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -72,12 +70,11 @@ bool TopologyStorageEtcd::LoadLogicalPool(
bool TopologyStorageEtcd::LoadPhysicalPool(
std::unordered_map<PoolIdType, PhysicalPool> *physicalPoolMap,
PoolIdType *maxPhysicalPoolId) {
std::string startKey = TopologyStorageCodec::GetPhysicalPoolKeyPrefix();
std::string endKey = TopologyStorageCodec::GetPhysicalPoolKeyEnd();
std::vector<std::string> out;
physicalPoolMap->clear();
*maxPhysicalPoolId = 0;
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(
PHYSICALPOOLKEYPREFIX, PHYSICALPOOLKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -110,12 +107,10 @@ bool TopologyStorageEtcd::LoadPhysicalPool(
bool TopologyStorageEtcd::LoadZone(
std::unordered_map<ZoneIdType, Zone> *zoneMap,
ZoneIdType *maxZoneId) {
std::string startKey = TopologyStorageCodec::GetZoneKeyPrefix();
std::string endKey = TopologyStorageCodec::GetZoneKeyEnd();
std::vector<std::string> out;
zoneMap->clear();
*maxZoneId = 0;
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(ZONEKEYPREFIX, ZONEKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -148,12 +143,10 @@ bool TopologyStorageEtcd::LoadZone(
bool TopologyStorageEtcd::LoadServer(
std::unordered_map<ServerIdType, Server> *serverMap,
ServerIdType *maxServerId) {
std::string startKey = TopologyStorageCodec::GetServerKeyPrefix();
std::string endKey = TopologyStorageCodec::GetServerKeyEnd();
std::vector<std::string> out;
serverMap->clear();
*maxServerId = 0;
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(SERVERKEYPREFIX, SERVERKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -186,12 +179,10 @@ bool TopologyStorageEtcd::LoadServer(
bool TopologyStorageEtcd::LoadChunkServer(
std::unordered_map<ChunkServerIdType, ChunkServer> *chunkServerMap,
ChunkServerIdType *maxChunkServerId) {
std::string startKey = TopologyStorageCodec::GetChunkServerKeyPrefix();
std::string endKey = TopologyStorageCodec::GetChunkServerKeyEnd();
std::vector<std::string> out;
chunkServerMap->clear();
*maxChunkServerId = 0;
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(CHUNKSERVERKEYPREFIX, CHUNKSERVERKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -226,12 +217,10 @@ bool TopologyStorageEtcd::LoadChunkServer(
bool TopologyStorageEtcd::LoadCopySet(
std::map<CopySetKey, CopySetInfo> *copySetMap,
std::map<PoolIdType, CopySetIdType> *copySetIdMaxMap) {
std::string startKey = TopologyStorageCodec::GetCopysetKeyPrefix();
std::string endKey = TopologyStorageCodec::GetCopysetKeyEnd();
std::vector<std::string> out;
copySetMap->clear();
copySetIdMaxMap->clear();
int errCode = client_->List(startKey, endKey, &out);
int errCode = client_->List(COPYSETKEYPREFIX, COPYSETKEYEND, &out);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -481,9 +470,8 @@ bool TopologyStorageEtcd::UpdateCopySet(const CopySetInfo &data) {
bool TopologyStorageEtcd::LoadClusterInfo(
std::vector<ClusterInformation> *info) {
std::string key = TopologyStorageCodec::GetClusterInfoKey();
std::string value;
int errCode = client_->Get(key, &value);
int errCode = client_->Get(CLUSTERINFOKEY, &value);
if (errCode == EtcdErrCode::EtcdKeyNotExist) {
return true;
}
@ -503,7 +491,7 @@ bool TopologyStorageEtcd::LoadClusterInfo(
}
bool TopologyStorageEtcd::StorageClusterInfo(const ClusterInformation &info) {
std::string key = TopologyStorageCodec::GetClusterInfoKey();
std::string key = CLUSTERINFOKEY;
std::string value;
if (codec_->EncodeClusterInfoData(info, &value)
!= true) {

View File

@ -60,19 +60,43 @@ int CloneCoreImpl::CloneOrRecoverPre(const UUID &source,
// 查询数据库中是否有任务正在执行
std::vector<CloneInfo> cloneInfoList;
metaStore_->GetCloneInfoByFileName(destination, &cloneInfoList);
bool needJudgeFileExist = false;
std::vector<CloneInfo> existCloneInfos;
for (auto &info : cloneInfoList) {
if ((taskType == CloneTaskType::kClone) &&
(info.GetTaskType() == CloneTaskType::kClone)) {
if (info.GetStatus() == CloneStatus::done ||
info.GetStatus() == CloneStatus::error ||
info.GetStatus() == CloneStatus::metaInstalled ||
info.GetStatus() == CloneStatus::cloning ||
LOG(INFO) << "CloneOrRecoverPre find same clone task"
<< ", source = " << source
<< ", user = " << user
<< ", destination = " << destination
<< ", Exist CloneInfo : " << info;
// is clone
if (taskType == CloneTaskType::kClone) {
if (info.GetStatus() == CloneStatus::cloning ||
info.GetStatus() == CloneStatus::retrying) {
if ((info.GetUser() == user) &&
(info.GetSrc() == source) &&
(info.GetIsLazy() == lazyFlag) &&
(info.GetTaskType() == taskType)) {
// 视为同一个clone
*cloneInfo = info;
return kErrCodeTaskExist;
} else {
// 视为不同的克隆,那么文件实际上已被占用,返回文件已存在
return kErrCodeFileExist;
}
} else if (info.GetStatus() == CloneStatus::done ||
info.GetStatus() == CloneStatus::error ||
info.GetStatus() == CloneStatus::metaInstalled) {
// 可能已经删除,需要再判断文件存不存在,
// 在已删除的条件下,允许再克隆
existCloneInfos.push_back(info);
needJudgeFileExist = true;
} else {
// 此时,有个相同的克隆任务正在删除中, 返回文件被占用
return kErrCodeFileExist;
}
} else { // is recover
if (info.GetStatus() == CloneStatus::recovering ||
info.GetStatus() == CloneStatus::retrying) {
LOG(INFO) << "CloneOrRecoverPre find same clone task"
<< ", source = " << source
<< ", user = " << user
<< ", destination = " << destination
<< ", Exist CloneInfo : " << info;
if ((info.GetUser() == user) &&
(info.GetSrc() == source) &&
(info.GetIsLazy() == lazyFlag) &&
@ -84,30 +108,14 @@ int CloneCoreImpl::CloneOrRecoverPre(const UUID &source,
// 视为不同的克隆,那么文件实际上已被占用,返回文件已存在
return kErrCodeFileExist;
}
} else if (info.GetStatus() == CloneStatus::done ||
info.GetStatus() == CloneStatus::error ||
info.GetStatus() == CloneStatus::metaInstalled) {
// nothing
} else {
// 此时,有个相同的克隆任务正在删除中, 返回文件被占用
// 此时,有个相同的任务正在删除中, 返回文件被占用
return kErrCodeFileExist;
}
} else {
if (info.GetStatus() == CloneStatus::cloning ||
info.GetStatus() == CloneStatus::recovering ||
info.GetStatus() == CloneStatus::retrying) {
LOG(INFO) << "CloneOrRecoverPre find some task in progress"
<< ", source = " << source
<< ", user = " << user
<< ", destination = " << destination
<< ", Exist CloneInfo : " << info;
if ((info.GetUser() == user) &&
(info.GetSrc() == source) &&
(info.GetIsLazy() == lazyFlag) &&
(info.GetTaskType() == taskType)) {
// 视为同一个clone返回任务已存在
return kErrCodeTaskExist;
} else {
// 视为不同的克隆,那么文件实际上已被占用,返回文件已存在
return kErrCodeFileExist;
}
}
}
}
@ -117,11 +125,36 @@ int CloneCoreImpl::CloneOrRecoverPre(const UUID &source,
switch (ret) {
case LIBCURVE_ERROR::OK:
if (CloneTaskType::kClone == taskType) {
LOG(ERROR) << "Clone dest file must not exist"
<< ", source = " << source
<< ", user = " << user
<< ", destination = " << destination;
return kErrCodeFileExist;
if (needJudgeFileExist) {
bool match = false;
// 找出inodeid匹配的cloneInfo
for (auto& existInfo : existCloneInfos) {
if (destFInfo.id == existInfo.GetDestId()) {
*cloneInfo = existInfo;
match = true;
break;
}
}
if (match) {
return kErrCodeTaskExist;
} else {
// 如果没找到那么dest file都不是这些clone任务创建的
// 意味着文件重名了
LOG(ERROR) << "Clone dest file exist, "
<< "but task not match! "
<< "source = " << source
<< ", user = " << user
<< ", destination = " << destination;
return kErrCodeFileExist;
}
} else {
// 没有对应的cloneInfo意味着文件重名了
LOG(ERROR) << "Clone dest file must not exist"
<< ", source = " << source
<< ", user = " << user
<< ", destination = " << destination;
return kErrCodeFileExist;
}
}
break;
case -LIBCURVE_ERROR::NOTEXIST:
@ -577,7 +610,11 @@ int CloneCoreImpl::CreateCloneFile(
uint64_t fileLength = fInfo.length;
uint64_t seqNum = fInfo.seqnum;
uint32_t chunkSize = fInfo.chunksize;
std::string source = task->GetCloneInfo().GetSrc();
std::string source = "";
// 只有从文件克隆才带clone source
if (CloneFileType::kFile == task->GetCloneInfo().GetFileType()) {
source = task->GetCloneInfo().GetSrc();
}
FInfo fInfoOut;
int ret = client_->CreateCloneFile(source, fileName,

View File

@ -616,15 +616,12 @@ int SnapshotCoreImpl::DeleteSnapshotOnCurvefs(const SnapshotInfo &info) {
<< ", seqNum = " << seqNum
<< ", status = " << static_cast<int>(status)
<< ", uuid = " << info.GetUuid();
// NOTEXIST means delete succeed.
if (-LIBCURVE_ERROR::NOTEXIST == ret) {
LOG(INFO) << "Check snapShot delete success"
<< ", uuid = " << info.GetUuid();
break;
// 目前mds删除快照失败会重试, 失败返回错误码DELETE_ERROR,
// 返回其他错误码一律InternalError
} else if (LIBCURVE_ERROR::OK == ret ||
-LIBCURVE_ERROR::DELETE_ERROR == ret) {
// nothing
} else if (LIBCURVE_ERROR::OK == ret) {
if (status != FileStatus::Deleting) {
LOG(ERROR) << "CheckSnapShotStatus fail"
<< ", ret = " << ret
@ -640,8 +637,7 @@ int SnapshotCoreImpl::DeleteSnapshotOnCurvefs(const SnapshotInfo &info) {
}
std::this_thread::sleep_for(
std::chrono::milliseconds(checkSnapshotStatusIntervalMs_));
} while (LIBCURVE_ERROR::OK == ret ||
-LIBCURVE_ERROR::DELETE_ERROR == ret);
} while (LIBCURVE_ERROR::OK == ret);
return kErrCodeSuccess;
}

View File

@ -49,6 +49,7 @@ cc_test(
"libcurve_client_unittest.cpp",
"lease_executor_test.cpp",
"request_sender_test.cpp",
"mds_client_test.cpp"
]
),
copts = COPTS,

View File

@ -1464,8 +1464,8 @@ TEST_F(MDSClientTest, CreateCloneFile) {
10 * 1024 * 1024, 0, 4 * 1024 * 1024,
&finfo));
ASSERT_EQ(5, finfo.id);
ASSERT_EQ(cloneSource, finfo.cloneSource);
ASSERT_EQ(cloneLength, finfo.cloneLength);
ASSERT_EQ(cloneSource, finfo.sourceInfo.name);
ASSERT_EQ(cloneLength, finfo.sourceInfo.length);
}
TEST_F(MDSClientTest, CompleteCloneMeta) {

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