├── CMakeLists-config.txt
├── CMakeLists.txt
├── LICENSE.txt
├── NOTICE.txt
├── Readme-CN.md
├── Readme-FUSE-CN.md
├── Readme-FUSE.md
├── Readme.md
├── autobuild.sh
├── conf
└── pfsd_logger.conf
├── deploy_scripts
├── clean_pfsd.sh
├── mount_pfs_fuse.sh
├── pfsd_entry.sh
├── start_pfsd.sh
├── stop_pfsd.sh
└── umount_pfs_fuse.sh
├── docker
├── pfsd
│ ├── Dockerfile
│ ├── log.conf
│ ├── pfsd_supervisor.py
│ └── pre_stop_pfsd.sh
└── tool
│ ├── Dockerfile
│ ├── entry_oper.py
│ ├── log.conf
│ ├── pfsd_oper.py
│ └── pre_stop_pfsd.sh
├── docs
├── PFS_Tools-CN.md
├── PFS_Tools-EN.md
└── pic
│ └── dinggroup.png
├── etc
└── polarfs.conf
├── install.sh
├── src
├── CMakeLists.txt
├── pfs_core
│ ├── CMakeLists.txt
│ ├── devio_disk.cc
│ ├── lib
│ │ └── fnv_hash.h
│ ├── pfs.init
│ ├── pfs_admin.cc
│ ├── pfs_admin.h
│ ├── pfs_alloc.cc
│ ├── pfs_alloc.h
│ ├── pfs_api.cc
│ ├── pfs_api.h
│ ├── pfs_avl.cc
│ ├── pfs_avl.h
│ ├── pfs_blkio.cc
│ ├── pfs_blkio.h
│ ├── pfs_chunk.cc
│ ├── pfs_chunk.h
│ ├── pfs_command.cc
│ ├── pfs_command.h
│ ├── pfs_config.cc
│ ├── pfs_config.h
│ ├── pfs_def.h
│ ├── pfs_devio.cc
│ ├── pfs_devio.h
│ ├── pfs_devstat.cc
│ ├── pfs_devstat.h
│ ├── pfs_dir.cc
│ ├── pfs_dir.h
│ ├── pfs_file.cc
│ ├── pfs_file.h
│ ├── pfs_impl.h
│ ├── pfs_inode.cc
│ ├── pfs_inode.h
│ ├── pfs_log.cc
│ ├── pfs_log.h
│ ├── pfs_memory.cc
│ ├── pfs_memory.h
│ ├── pfs_meta.cc
│ ├── pfs_meta.h
│ ├── pfs_mount.cc
│ ├── pfs_mount.h
│ ├── pfs_namecache.cc
│ ├── pfs_namecache.h
│ ├── pfs_namei.cc
│ ├── pfs_namei.h
│ ├── pfs_option.cc
│ ├── pfs_option.h
│ ├── pfs_paxos.cc
│ ├── pfs_paxos.h
│ ├── pfs_stat.cc
│ ├── pfs_stat.h
│ ├── pfs_stat_file_type.cc
│ ├── pfs_stat_file_type.h
│ ├── pfs_tls.cc
│ ├── pfs_tls.h
│ ├── pfs_trace.cc
│ ├── pfs_trace.h
│ ├── pfs_tx.cc
│ ├── pfs_tx.h
│ ├── pfs_util.cc
│ ├── pfs_util.h
│ ├── pfs_version.cc
│ └── pfs_version.h
├── pfs_fuse
│ ├── CMakeLists.txt
│ ├── pfs_fuse.cc
│ └── pfs_fuse_main.cc
├── pfs_sdk
│ ├── CMakeLists.txt
│ ├── pfsd_chnl.cc
│ ├── pfsd_chnl_shm.cc
│ ├── pfsd_common.cc
│ ├── pfsd_memory.cc
│ ├── pfsd_sdk.cc
│ ├── pfsd_sdk.h
│ ├── pfsd_sdk_file.cc
│ ├── pfsd_sdk_file.h
│ ├── pfsd_sdk_mount.cc
│ ├── pfsd_sdk_mount.h
│ ├── pfsd_shm.cc
│ └── pfsd_shm_tool.cc
├── pfs_tools
│ ├── CMakeLists.txt
│ ├── cmd_chunk.cc
│ ├── cmd_cp.cc
│ ├── cmd_dir.cc
│ ├── cmd_du.cc
│ ├── cmd_dumpfs.cc
│ ├── cmd_dumple.cc
│ ├── cmd_flushlog.cc
│ ├── cmd_fscp.cc
│ ├── cmd_fstrim.cc
│ ├── cmd_impl.h
│ ├── cmd_info.cc
│ ├── cmd_map.cc
│ ├── cmd_mkdir.cc
│ ├── cmd_mkfs.cc
│ ├── cmd_mount.cc
│ ├── cmd_pfs.cc
│ ├── cmd_rename.cc
│ ├── cmd_rm.cc
│ ├── cmd_usedinfo.cc
│ ├── cmd_util.cc
│ ├── pfsadm
│ ├── pfstemp.cc
│ └── pfsthread.cc
├── pfsd
│ ├── CMakeLists.txt
│ ├── pfsd.init
│ ├── pfsd_api.cc
│ ├── pfsd_api.h
│ ├── pfsd_chnl.cc
│ ├── pfsd_chnl.h
│ ├── pfsd_chnl_impl.h
│ ├── pfsd_chnl_shm.cc
│ ├── pfsd_chnl_shm.h
│ ├── pfsd_common.cc
│ ├── pfsd_common.h
│ ├── pfsd_main.cc
│ ├── pfsd_memory.cc
│ ├── pfsd_memory.h
│ ├── pfsd_option.cc
│ ├── pfsd_option.h
│ ├── pfsd_proto.h
│ ├── pfsd_shm.cc
│ ├── pfsd_shm.h
│ ├── pfsd_worker.cc
│ ├── pfsd_worker.h
│ ├── pfsd_zlog.h
│ └── sdk_demo.cc
├── pfsd_unittest
│ ├── dcache_test_performance.cc
│ ├── dcache_test_rw_ro_sync.cc
│ ├── pfsd_filetest.cc
│ ├── pfsd_testenv.cc
│ ├── pfsd_testenv.h
│ └── pfsd_unittest.cc
└── trace
│ └── include
│ ├── trace_common.h
│ ├── trace_pfs_ctx.h
│ └── trace_type.h
└── uninstall.sh
/CMakeLists-config.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | execute_process(COMMAND git describe --long --always OUTPUT_VARIABLE RAW_GIT_DESC)
15 | if (RAW_GIT_DESC STREQUAL "")
16 | set(RAW_GIT_DESC "_")
17 | endif()
18 | string(REPLACE "\n" "" RAW_GIT_DESC ${RAW_GIT_DESC})
19 | message("build git version: (\"${RAW_GIT_DESC} \")")
20 |
21 | if (CMAKE_BUILD_TYPE STREQUAL "Release")
22 | execute_process(COMMAND date OUTPUT_VARIABLE RAW_DATE)
23 | string(REPLACE "\n" "" RAW_DATE ${RAW_DATE})
24 | message("build date: (\"${RAW_DATE} \")")
25 |
26 | else()
27 | set (RAW_DATE "debug")
28 | endif()
29 |
30 | set (VERSION_DETAIL "(\"pfsd-build-desc-${RAW_GIT_DESC}-${RAW_DATE}\")")
31 |
32 | add_definitions(-DVERSION_DETAIL=${VERSION_DETAIL})
33 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | cmake_minimum_required (VERSION 2.8)
15 | project(pfsd CXX C ASM)
16 |
17 | message("compile pfsd for PostgreSQL")
18 |
19 | set(CMAKE_BUILD_TYPE "Release")
20 | #set(CMAKE_BUILD_TYPE "Debug")
21 |
22 | include(CMakeLists-config.txt)
23 |
24 | set(COMMON_FLAGS
25 | -fno-strict-aliasing
26 | #-fstack-protector
27 | #-fsanitize=address
28 | #-DEV_STANDALONE
29 | -Wall
30 | -Werror
31 | -Wno-deprecated-declarations
32 | -Wno-unused-result
33 | -Wno-format-overflow
34 | -Wno-misleading-indentation
35 | -Wno-format-truncation
36 | -Wno-stringop-truncation
37 | -Wno-int-in-bool-context
38 | -Wno-stringop-overflow
39 | -Wno-error=attributes
40 | -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
41 | -Wno-missing-declarations -fno-strict-aliasing
42 | -Wformat -Wformat-security -Wformat-nonliteral
43 | -g
44 | )
45 |
46 | if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
47 | set(COMMON_FLAGS ${COMMON_FLAGS} -march=native -m64)
48 | endif()
49 |
50 | set(CMAKE_EXE_LINKER_FLAGS
51 | # Enable full RELRO - no lazy relocation (resolve everything at load time).
52 | # This allows the GOT to be made read-only early in the loading process.
53 | -Wl,-z,relro,-z,now,-z,noexecstack
54 | # Make the stack non-executable.
55 | # This is the default in most environments, but it doesn't hurt to set it explicitly.
56 | #-Wl,-z,noexecstack
57 | )
58 |
59 | set(COMMON_FLAGS ${COMMON_FLAGS} -DPFS_DISK_IO_ONLY)
60 |
61 | set(CXX_FLAGS
62 | ${COMMON_FLAGS}
63 | -std=c++11
64 | -Wno-deprecated
65 | -Wno-unused-local-typedefs
66 | -Wno-sign-compare
67 | -fpermissive
68 | -Wno-unused-variable
69 | -Wno-unused-function
70 | )
71 |
72 | set(C_FLAGS
73 | ${COMMON_FLAGS}
74 | )
75 |
76 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
77 | string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}")
78 |
79 | set(CMAKE_CXX_COMPILER "g++")
80 | set(CMAKE_C_COMPILER "cc")
81 |
82 | set(DEBUG_LEVEL 20)
83 | set(RELEASE_LEVEL 40)
84 |
85 | if(DEFINED ENV{POLAR_LOG_DEBUG_LEVEL})
86 | set(DEBUG_LEVEL $ENV{POLAR_LOG_DEBUG_LEVEL})
87 | endif()
88 | if(DEFINED ENV{POLAR_LOG_RELEASE_LEVEL})
89 | set(RELEASE_LEVEL $ENV{POLAR_LOG_RELEASE_LEVEL})
90 | endif()
91 |
92 | message("build log level release level "${RELEASE_LEVEL} " debug level "${DEBUG_LEVEL})
93 | set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -ggdb -DDEBUG -DCHKSVR_LOG_LEVEL=${DEBUG_LEVEL}")
94 | set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -finline-limit=100000 -DNDEBUG -DCHKSVR_LOG_LEVEL=${RELEASE_LEVEL}")
95 | set(CMAKE_C_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -ggdb -DDEBUG -DCHKSVR_LOG_LEVEL=${DEBUG_LEVEL}")
96 | set(CMAKE_C_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -finline-limit=100000 -DNDEBUG -DCHKSVR_LOG_LEVEL=${RELEASE_LEVEL}")
97 |
98 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
99 | set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
100 |
101 | string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
102 | message(STATUS "CXX_FLAGS = " ${CMAKE_CXX_FLAGS} " " ${CMAKE_CXX_FLAGS_${BUILD_TYPE}})
103 | message(STATUS "C_FLAGS = " ${CMAKE_C_FLAGS} " " ${CMAKE_C_FLAGS_${BUILD_TYPE}})
104 |
105 | execute_process(COMMAND mkdir -p ${PROJECT_SOURCE_DIR}/include)
106 | execute_process(COMMAND cp ${PROJECT_SOURCE_DIR}/src/pfs_sdk/pfsd_sdk.h ${PROJECT_SOURCE_DIR}/include/)
107 |
108 | add_subdirectory(src)
109 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | PolarDB File System
2 |
3 | Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | Other dependencies and licenses:
17 |
18 | Fowler / Noll / Vo Hash (FNV Hash)
19 |
20 | http://www.isthe.com/chongo/tech/comp/fnv/
21 | This is an implementation of the algorithms posted above.
22 | This file is placed in the public domain by Peter Wemm.
23 | $FreeBSD: src/sys/sys/fnv_hash.h,v 1.3 2005/01/07 02:29:23 imp Exp $
24 |
25 | CRC Algorithm
26 |
27 | COPYRIGHT (C) 1986 Gary S. Brown.
28 | You may use this program, or code or tables extracted from it, as
29 | desired without restriction.
30 |
--------------------------------------------------------------------------------
/Readme-CN.md:
--------------------------------------------------------------------------------
1 | # 什么是PFS
2 | PolarDB File System,简称PFS或PolarFS,是由阿里云自主研发的高性能类POSIX的用户态分布式文件系统,服务于阿里云数据库PolarDB产品。
3 | # 快速入门
4 | PFS(PostgreSQL版)是以后台进程(pfsdaemon)的方式提供服务,目前完成基于AliOS以及CentOS 7.5的开发和测试工作,其他Linux版本理论上也可以搭建。
5 |
6 |
7 | ## 安装依赖
8 | 以CentOS 7.5为例,构建工程需要完成以下软件安装:
9 |
10 | - [CMake](https://cmake.org/):需要2.8及以上版本。
11 | - [gcc&g++](http://www.gnu.org/software/gcc/):需要4.8.5及以上版本。
12 | - [zlog](https://github.com/HardySimpson/zlog/releases):需要1.2.12及以上版本。
13 | - [libaio-devel](https://pagure.io/libaio)
14 |
15 | CMake、gcc&g++、libaio-devel的安装建议使用yum或apt-get。
16 | zlog需要下载源码后执行 `make && sudo make install` 安装,而且由于zlog安装的目录在`/usr/local/lib`,如果运行时找不到动态库,可以通过`ldconfig`配置进行添加。
17 | 本项目也提供rpm包安装,如果使用rpm包安装,跳过编译和安装这2个步骤。
18 |
19 | ## 编译
20 | 依赖项准备好后,进入代码根目录,执行脚本进行编译:
21 | ```bash
22 | ./autobuild.sh
23 | ```
24 | ## 安装pfsdaemon
25 | 安装pfsdaemon需要root权限。
26 | 在完成编译工作后,使用安装脚本 install.sh 进行自动化安装:
27 | ```bash
28 | sudo ./install.sh
29 | ```
30 |
31 |
32 |
33 | ## 运行pfsdaemon
34 |
35 | ##### 1. 格式化存储设备。首先执行以下命令查找现有的块设备:
36 | ```bash
37 | lsblk
38 | ```
39 | 选择需要格式化的块设备名,例如 nvme1n1,运行pfs格式化命令:
40 | ```bash
41 | sudo pfs -C disk mkfs nvme1n1
42 | ```
43 |
44 | ##### 2. 执行如下脚本启动pfsdaemon:
45 | ```bash
46 | sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme1n1
47 | ```
48 | 其中,"-p 设备名"必须设置,nvme1n1指代设备名。
49 | 其他可选启动参数如下:
50 |
51 | ```bash
52 | -f (not daemon mode)
53 | -w #nworkers
54 | -c log_config_file
55 | -b (if bind cpuset)
56 | -e db ins id
57 | -a shm directory
58 | -i #inode_list_size
59 | ```
60 |
61 | ##### 3. 可执行如下脚本停止pfsdaemon:
62 | ```bash
63 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh nvme1n1
64 | ```
65 | nvme1n1指代设备名。
66 |
67 | ##### 4. 清除pfsdaemon运行文件。
68 |
69 | 停止pfsdaemon后,清理运行时产生的临时文件、日志、共享内存文件:
70 |
71 | ```bash
72 | sudo /usr/local/polarstore/pfsd/bin/clean_pfsd.sh nvme1n1
73 | ```
74 | nvme1n1指代设备名。
75 |
76 | ##### 5. 使用PFS工具进行检查。
77 |
78 | 参照[PFS工具使用说明](docs/PFS_Tools-CN.md),进行常见的文件操作,验证文件系统是否正确安装。
79 | 例如使用如下命令,可以查看创建的新文件 hello.txt:
80 |
81 | ```bash
82 | sudo pfs -C disk touch /nvme1n1/hello.txt
83 | sudo pfs -C disk ls /nvme1n1/
84 | ```
85 | nvme1n1指代设备名。
86 |
87 |
88 | ## 卸载pfsdaemon
89 | 卸载pfsdaemon需要root权限。
90 |
91 | ##### 1. 执行如下脚本停止pfsdaemon:
92 | ```bash
93 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh nvme1n1
94 | ```
95 |
96 | ##### 2. 使用卸载脚本 uninstall.sh 进行卸载:
97 | ```bash
98 | sudo ./uninstall.sh
99 | ```
100 |
101 |
102 | # 文档
103 | 在docs目录下,包括内容如下:
104 |
105 | - [PFS_Tools-CN.md](docs/PFS_Tools-CN.md):PFS工具的命令使用手册。
106 |
107 | # License
108 | PFS基于[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)协议开源。
109 |
110 | # 出版物
111 |
112 | - 《PolarFS: An Ultra-low Latency and Failure Resilient Distributed File System for Shared Storage Cloud Database》VLDB2018
113 | - 《POLARDB Meets Computational Storage: Efficiently Support Analytical Workloads in Cloud-Native Relational Database》FAST2020
114 |
115 |
116 |
117 | # 联系我们
118 |
119 | - 产品官网:[阿里云原生关系型数据库PolarDB](https://help.aliyun.com/product/172538.html)
120 | - 使用钉钉扫描如下二维码,加入钉钉群。
121 |
122 | 
123 |
--------------------------------------------------------------------------------
/Readme-FUSE-CN.md:
--------------------------------------------------------------------------------
1 | # FUSE on pfs
2 |
3 | 用户态文件系统(FUSE)是Unix和类似Unix的计算机操作系统的一个软件接口,允许非特权用户在不编辑内核代码的情况下创建自己的文件系统。这是通过在用户空间运行文件系统代码来实现的,而FUSE模块只提供了一个通往实际内核接口的桥梁。
4 |
5 | 为了让用户像其他内核内置文件系统一样使用PFS的内核接口,我们实现了一个FUSE on PFS的处理程序,它被链接到LibFUSE库。这个程序定义了内核接口与 PFS 操作的请求-响应映射,即它指定了PFS如何响应读/写/统计请求。同时,这个程序也被用来挂载 PFS,在挂载PFS的时候,处理程序被注册到内核中。如果用户现在对PFS发出读/写/统计请求,内核会将这些IO请求转发给处理程序,然后将处理程序的响应发回给用户。
6 |
7 | # FUSE主要模块
8 |
9 | ##### FUSE内核模块(内核状态)
10 |
11 | FUSE内核模块实现了VFS接口(它实现了fuse文件驱动、fuse设备驱动的注册,并提供了超级块、inode等的维护)。它接收来自VFS的请求并将其传递给LibFUSE,然后LibFUSE将请求传递给PFS处理程序;
12 |
13 | ##### LibFUSE模块(用户态)
14 |
15 | LibFUSE实现了文件系统的主要框架、PFS操作的封装、挂载管理以及通过/dev/fuse设备与内核模块的通信;
16 |
17 | ##### 用户程序模块(用户态)
18 |
19 | 用户程序在用户空间实现由LibFUSE库封装的PFS操作。
20 |
21 | # 接口
22 |
23 | FUSE接口在`fusepfs_operations`中定义,主要分为以下几类。
24 |
25 | 1. FUSE环境构建:init, destroy
26 |
27 | 2. 文件操作:create, mknod, open, rename, truncate, ftruncate
28 |
29 | 3. 目录操作:mkdir, opendir, readdir, rmdir
30 |
31 | 4. 链接:symlink, readlink, unlink
32 |
33 | 5. 文件属性:statfs, access, getattr, fgetattr
34 |
35 | 6. 扩展属性:getxattr, setxattr, listxattr, removexattr
36 |
37 | 7. 读写:read, write, read_buf, write_buf, fallocate
38 |
39 | 8. 同步I/O:fsync, fsyncdir
40 |
41 | 9. 多路复用:poll
42 |
43 | 10. 释放:release, releasedir
44 |
45 | 11. 其他:ioctl, lock, bmap
46 |
47 | # 使用FUSE on PFS
48 |
49 | #### 1. 安装PFS依赖
50 |
51 | 安装步骤详见文档[Readme-CN.md](./Readme-CN.md)中的【安装依赖】
52 |
53 | #### 2. 加载FUSE模块
54 |
55 | ##### I. 下载FUSE资源包并解压
56 |
57 | ```bash
58 | tar -zxvf fuse.tar.gz
59 | ```
60 |
61 | 推荐FUSE版本:2.9.2
62 |
63 | ##### II. 安装FUSE(3.2版本或以上需要安装Meson或Ninj)
64 |
65 | ```bash
66 | ./configure && sudo make install
67 | ```
68 |
69 | ##### III. 检查是否加载成功
70 |
71 | ```bash
72 | # 检查FUSE模块是否加载成功
73 | lsmod | grep fuse
74 | # 如果尚未加载成功,你可以通过以下命令来挂载FUSE
75 | modprobe fuse
76 | # 查看版本信息
77 | fusermount --version
78 | ```
79 |
80 | #### 3. 编译与安装
81 |
82 | 依赖项准备好后,进入代码根目录,执行脚本进行编译:
83 |
84 | ```bash
85 | ./autobuild.sh && sudo ./install.sh
86 | ```
87 |
88 | #### 4. 使用FUSE
89 |
90 | ##### I. 挂载FUSE on PFS
91 |
92 | 挂载前需要对/etc/fuse.conf进行配置,在文件中添加一行`user_allow_other`即可
93 |
94 | ```bash
95 | /usr/local/polarstore/pfsd/bin/mount_pfs_fuse.sh [-p diskname] [-c rw/ro] mount_dir
96 | # 示例
97 | /usr/local/polarstore/pfsd/bin/mount_pfs_fuse.sh -p nvme1n1 -c rw ./fuse_mntdir
98 | ```
99 |
100 | `diskname`代表块设备名称。可以通过命令`lsblk`列出所有可用块设备信息;
101 |
102 | `rw/ro`代表所启动实例为启动读写实例或者只读实例;
103 |
104 | `mount_dir`指fuse挂载目录。
105 |
106 | 说明:挂载FUSE on PFS首先会启动pfsdaemon后台进程,然后启动pfs-fuse进程并挂载PFS到制定目录。
107 |
108 | ##### II. 通过FUSE访问PFS
109 |
110 | 在后台启动FUSE实例后,现在你可以 `cd` 进入挂载目录,像平常使用内核内置的文件系统一样操作PFS。所有操作的结果将被送入PFS挂载的磁盘。示例如下:
111 |
112 | ```bash
113 | # 进入挂载目录
114 | $cd path/to/fuse_mount_dir
115 | # 创建文件 写文件
116 | $echo "hello pfs fuse">test_file.txt
117 | # 打印文件内容
118 | $cat test_file.txt
119 | hello pfs fuse
120 | ```
121 |
122 | ##### III. 结束使用
123 |
124 | 1. 解挂FUSE on PFS
125 |
126 | 你可以通过单独指定一个挂载路径来解挂特定FUSE实例,路径需要以绝对路径的形式指定;
127 | 也可以选择`all`参数来解挂所有已挂载的PFS FUSE实例。
128 |
129 | ```bash
130 | /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh [mount_dir/all]
131 | # 示例
132 | /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh /fuse_mntdir
133 | /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh all
134 | ```
135 |
136 | 2. 停止pfsdaemon后台进程
137 |
138 | 支持两种方式:
139 | 1. 通过盘名以停止指定pfsdaemon
140 | 2. 以停止所有正在运行的pfsdaemon
141 |
142 | ```bash
143 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh [diskname]
144 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh
145 |
146 | example:
147 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh nvme1n1
148 | sudo /usr/local/polarstore/pfsd/bin/stop_pfsd.sh
149 | ```
150 |
151 | ##### IV. 使用卸载脚本uninstall.sh进行卸载:
152 |
153 | ```bash
154 | sudo ./uninstall.sh
155 | ```
--------------------------------------------------------------------------------
/autobuild.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | BASE_DIR=$(cd "$(dirname "$0")"; pwd)
17 | cd $BASE_DIR
18 |
19 | echo -e "\033[33m begin compile pfsdaemon|pfs|libpfs.a|libpfsd.a \033[0m"
20 | mkdir -p build
21 | pushd build
22 | cmake ../ && make -j128
23 | popd
24 |
25 | echo -e "\033[33m end compile, binary's in ./bin, library's in ./lib \033[0m"
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/conf/pfsd_logger.conf:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | [global]
15 | strict init = true
16 | buffer min = 1024
17 | buffer max = 2MB
18 | default format = "%d.%us|%6V|%p|%U:%f:%L|%m%n"
19 | file perms = 644
20 | [formats]
21 | simple = "%d.%us|%-5V|%f:%L|%m%n"
22 | trace = "%m%n"
23 | [rules]
24 | pfsd_cat.* "/var/log/pfsd-%E(PFSD_PBDNAME)/pfsd.log", 100MB * 10 ~ "/var/log/pfsd-%E(PFSD_PBDNAME)/pfsd.log.#r";simple
25 | original_cat.* "/var/log/pfsd-%E(PFSD_PBDNAME)/pfsd.log", 100MB * 10 ~ "/var/log/pfsd-%E(PFSD_PBDNAME)/pfsd.log.#r";trace
26 | test_cat.* >stdout; simple
27 |
--------------------------------------------------------------------------------
/deploy_scripts/clean_pfsd.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # cleanup resources
17 |
18 | pbd=$1
19 | if test -z $pbd;then
20 | echo "Error: not get pbdname"
21 | exit
22 | fi
23 |
24 | /usr/local/polarstore/pfsd/bin/stop_pfsd.sh $pbd
25 |
26 | pidfile="/var/run/pfsd/pfsd_${pbd}.pid"
27 | echo $pidfile | xargs rm -f
28 |
29 | clientpiddir="/var/run/pfsd/${pbd}"
30 | echo $clientpiddir | xargs rm -rf
31 |
32 | shmfile="/dev/shm/pfsd/shm_pfsd-${pbd}_*"
33 | echo $shmfile | xargs rm -f
34 |
35 | logdir="/var/log/pfsd-${pbd}"
36 | echo $logdir | xargs rm -rf
37 |
38 | echo "clean pfsd $pbd files success"
39 |
--------------------------------------------------------------------------------
/deploy_scripts/mount_pfs_fuse.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | BASE_DIR=$(cd "$(dirname "$0")"; pwd)
17 | FUSE_BIN=${BASE_DIR}/pfs-fuse
18 |
19 | usage(){
20 | echo "[mount_pfs_fuse.sh] usage: "
21 | echo " /usr/local/polarstore/pfsd/bin/mount_pfs_fuse.sh [-p diskname] [-c rw/ro] mount_dir"
22 | echo "example:"
23 | echo " /usr/local/polarstore/pfsd/bin/mount_pfs_fuse.sh -p nvme1n1 -c rw fuse/mount/dir"
24 | echo "logger location:"
25 | echo " /var/log/pfs-[disk].log"
26 | }
27 |
28 | if [ $# -eq 0 ]; then
29 | usage
30 | exit
31 | else
32 | # parameters check
33 | if [ $# -ne 5 ]; then
34 | usage
35 | exit
36 | fi
37 |
38 | # PFS options
39 | if [ "$1" = '-p' ] && [ "$3" = '-c' ]; then
40 | DISK_NAME=$2
41 | PFS_FLAGS=$4
42 | elif [ "$1" = '-c' ] && [ "$3" = '-p' ]; then
43 | PFS_FLAGS=$2
44 | DISK_NAME=$4
45 | else
46 | echo "Invalid arguments"
47 | usage
48 | exit
49 | fi
50 | MNT_DIR=$5
51 |
52 | if [ "$PFS_FLAGS" = 'rw' ] || [ "$PFS_FLAGS" = 'RW' ];then
53 | is_rw=1
54 | elif [ "$PFS_FLAGS" = 'ro' ] || [ "$PFS_FLAGS" = 'RO' ];then
55 | is_rw=0
56 | else
57 | echo "-c (read/write flag) should be followed by 'rw'(read and write)/'ro'(read only)"
58 | usage
59 | exit 1
60 | fi
61 |
62 | # check if pfdameon exist
63 | pfsd_exist="ps -ef | grep pfsdaemon | grep -w '\-p $DISK_NAME' | wc -l"
64 | exist_ret0=$(eval $pfsd_exist)
65 |
66 | if [ $exist_ret0 -eq 0 ]; then
67 | mkdir -p /var/run/pfs
68 | mkdir -p /var/run/pfsd
69 | mkdir -p /dev/shm/pfsd
70 |
71 | chmod 777 /var/run/pfs
72 | chmod 777 /var/run/pfsd
73 | chmod 777 /dev/shm/pfsd
74 |
75 | CONF_FILE=${BASE_DIR}/../conf
76 |
77 | ulimit -c unlimited
78 | ${BASE_DIR}/../bin/pfsdaemon -p ${DISK_NAME} -c ${CONF_FILE}/pfsd_logger.conf
79 |
80 | sleep 1
81 |
82 | # check if start success
83 | exist_ret0=$(eval $pfsd_exist)
84 | if [ $exist_ret0 -eq 0 ]; then
85 | echo "pfsdaemon $DISK_NAME start failed"
86 | usage
87 | exit 1
88 | fi
89 |
90 | echo "pfsdaemon $DISK_NAME start success"
91 | fi
92 |
93 | # parameters check
94 | echo "[mount_pfs_fuse.sh] pfs fuse mount..."
95 | mntdir_exist="ps -ef | grep 'pfs-fuse' | grep -w '$MNT_DIR' | wc -l"
96 | exist_ret1=$(eval $mntdir_exist)
97 | # if multi-write instance on ont disk
98 | diskname_rw_exist="ps -ef | grep 'pfs-fuse' | grep -w '$DISK_NAME' | grep -w 'rw'| wc -l"
99 | exist_ret2=$(eval $diskname_rw_exist)
100 | if [ $exist_ret1 -ge 1 ]; then
101 | echo "[mount_pfs_fuse.sh] mount error: path $MNT_DIR is already mounted"
102 | fi
103 | if [ $is_rw -eq 1 ] && [ $exist_ret2 -ge 1 ]; then
104 | echo "[mount_pfs_fuse.sh] mount error: disk $DISK_NAME is already mounted with a rw instance! a disk can only be mounted with one rw instance, you can mount a ro instance or choose another disk."
105 | exit 1
106 | fi
107 |
108 | # pfs fuse mount
109 | sudo $FUSE_BIN -s -o allow_other -o direct_io -o auto_unmount --pbdname=$DISK_NAME --flags=$PFS_FLAGS $MNT_DIR
110 | sleep 1
111 | # check if pfs fuse mount success
112 | mount_exist="ps -ef | grep 'pfs-fuse' | grep -w '$MNT_DIR' | grep -w '$DISK_NAME' | grep -w '$PFS_FLAGS' | wc -l"
113 | exist_ret=$(eval $mount_exist)
114 | if [ $exist_ret -eq 0 ]; then
115 | echo "[mount_pfs_fuse.sh] pfs fuse mount failed!"
116 | usage
117 | exit 1
118 | else
119 | echo "[mount_pfs_fuse.sh] pfs fuse mount success!"
120 | fi
121 | fi
122 |
--------------------------------------------------------------------------------
/deploy_scripts/pfsd_entry.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | sh /usr/local/polarstore/pfsd/bin/start_pfsd.sh $*
17 |
18 | while true
19 | do
20 | sleep 1
21 | done
22 |
--------------------------------------------------------------------------------
/deploy_scripts/start_pfsd.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | usage(){
17 | echo "[start_pfsd.sh] usage: "
18 | echo " sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p DISKNAME [other options]"
19 | echo "example:"
20 | echo " sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme1n1"
21 | echo "logger location:"
22 | echo " /var/log/pfsd-DISKNAME/pfsd.log"
23 | }
24 |
25 | mkdir -p /var/run/pfs
26 | mkdir -p /var/run/pfsd
27 | mkdir -p /dev/shm/pfsd
28 |
29 | chmod 777 /var/run/pfs
30 | chmod 777 /var/run/pfsd
31 | chmod 777 /dev/shm/pfsd
32 |
33 | BASE_DIR=$(cd "$(dirname "$0")"; pwd)
34 | CONF_FILE=$BASE_DIR/../conf
35 |
36 | # check if pfdameon exist
37 | pbdname=$2
38 | exist_command="ps -ef | grep pfsdaemon |grep -w '$pbdname' | wc -l"
39 | exist=$(eval $exist_command)
40 | if [ $exist -ge 1 ]; then
41 | echo "$pbdname already exist"
42 | usage
43 | exit 1
44 | fi
45 |
46 | ulimit -c unlimited
47 |
48 | ${BASE_DIR}/../bin/pfsdaemon $* -c ${CONF_FILE}/pfsd_logger.conf
49 |
50 | sleep 1
51 |
52 | # check if start success
53 | exist=$(eval $exist_command)
54 | if [ $exist -eq 0 ]; then
55 | echo "pfsdaemon $pfsdname start failed"
56 | usage
57 | exit 1
58 | fi
59 |
60 | echo "pfsdaemon $pbdname start success"
61 |
--------------------------------------------------------------------------------
/deploy_scripts/stop_pfsd.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | kill_single_pfsd() {
17 | pbd=$1
18 | pfsdname="pfsdaemon -p $pbd"
19 | exist_command="ps -ef | grep pfsdaemon |grep -w '\-p $pbd' | wc -l"
20 | exist=$(eval $exist_command)
21 | if [ $exist -eq 0 ]; then
22 | echo "$pfsdname not exist"
23 | exit 1
24 | fi
25 |
26 | pid=`ps -ef |grep pfsdaemon |grep -w '\-p '$pbd'' |awk '{print $2}'`
27 | kill -2 $pid
28 | sleep 1
29 |
30 | # check if stop success, if not, use kill -9
31 | exist=$(eval $exist_command)
32 | if [ $exist -eq 0 ]; then
33 | echo "$pfsdname stop success"
34 | exit 0
35 | fi
36 |
37 | echo "going to kill -9 $pfsdname"
38 | kill -9 $pid
39 | sleep 1
40 | exist=$(eval $exist_command)
41 | if [ $exist -eq 0 ]; then
42 | echo "$pfsdname stop success"
43 | else
44 | echo "$pfsdname stop failed!"
45 | fi
46 | }
47 |
48 | kill_all_pfsd() {
49 | pkill -2 pfsdaemon
50 | sleep 1
51 | cnt=`ps -ef | grep pfsdaemon | grep -v grep | wc -l`
52 | if [ $cnt -eq 0 ]; then
53 | echo "pkill -2 all pfsdaemon success"
54 | exit 0
55 | fi
56 |
57 | echo "going to pkill -9 all pfsdaemon"
58 | pkill -9 pfsdaemon
59 | sleep 1
60 | cnt=`ps -ef | grep pfsdaemon | grep -v grep | wc -l`
61 | if [ $cnt -eq 0 ]; then
62 | echo "pkill -9 all pfsdaemon success"
63 | exit 0
64 | fi
65 | echo "pkill -9 all pfsdaemon failed!"
66 | }
67 |
68 | if [ $# -gt 0 ]; then
69 | kill_single_pfsd $1
70 | else
71 | kill_all_pfsd
72 | fi
73 |
--------------------------------------------------------------------------------
/deploy_scripts/umount_pfs_fuse.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | usage(){
17 | echo "[umount_pfs_fuse.sh] usage: "
18 | echo " /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh [absolute_mount_dir/all]"
19 | echo "example:"
20 | echo " /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh /fuse/mount/dir"
21 | echo " /usr/local/polarstore/pfsd/bin/umount_pfs_fuse.sh all"
22 | echo "logger location:"
23 | echo " /var/log/pfs-[disk].log"
24 | }
25 |
26 | kill_single_fuse() {
27 | echo "[umount_pfs_fuse.sh] umount pfs fuse $MNTDIR..."
28 | MNTDIR=$1
29 |
30 | sudo umount -l $MNT_DIR
31 | sleep 1
32 |
33 | exist_command="ps -ef | grep 'pfs-fuse' | grep -w '$MNTDIR' | wc -l"
34 | exist=$(eval $exist_command)
35 | if [ $exist -eq 0 ]; then
36 | echo "[umount_pfs_fuse.sh] pfs fuse $MNT_DIR umount success!"
37 | exit 0
38 | fi
39 |
40 | ps -ef |grep 'pfs-fuse' | grep -w $MNTDIR | awk '{print $2}' | xargs kill -9
41 | sleep 1
42 |
43 | exist=$(eval $exist_command)
44 | if [ $exist -eq 0 ]; then
45 | echo "[umount_pfs_fuse.sh] pfs fuse $MNT_DIR umount success!"
46 | exit 0
47 | else
48 | echo "[umount_pfs_fuse.sh] pfs fuse $MNT_DIR umount failed!"
49 | usage
50 | fi
51 | }
52 |
53 | kill_all_fuse() {
54 | echo "[umount_pfs_fuse.sh] umount all pfs fuses..."
55 |
56 | ps -ef |grep 'pfs-fuse' | grep 'pbdname' | awk '{print $2}'| xargs kill -9
57 | sleep 1
58 |
59 | exist_command="ps -ef | grep 'pfs-fuse' | grep 'pbdname' | wc -l"
60 | exist=$(eval $exist_command)
61 |
62 | if [ $exist -eq 0 ]; then
63 | echo "[umount_pfs_fuse.sh] umount all pfs fuses success!"
64 | exit 0
65 | else
66 | echo "[umount_pfs_fuse.sh] pfs fuse umount failed!"
67 | usage
68 | fi
69 | }
70 |
71 | # umount pfs fuse
72 | if [ $# -ne 1 ]; then
73 | usage
74 | exit
75 | else
76 | # umount fuse
77 | echo "[umount_pfs_fuse.sh] pfs fuse umount..."
78 | if [ "$1" == 'all' ]; then
79 | kill_all_fuse
80 | elif [ "$1" = '--help' ] || [ "$1" = '-h' ]; then
81 | usage
82 | exit
83 | else
84 | MNT_DIR=$1
85 | kill_single_fuse $MNT_DIR
86 | fi
87 | fi
88 |
--------------------------------------------------------------------------------
/docker/pfsd/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | ARG IMAGE
15 | FROM $IMAGE
16 |
17 | ARG RPM
18 | ARG VERSION
19 |
20 | LABEL dev_version="$VERSION"
21 |
22 | USER root
23 |
24 | COPY pfsd_supervisor.py /docker_script/
25 | COPY log.conf /docker_script/
26 | COPY libzlog.so* /usr/lib64/
27 | COPY pre_stop_pfsd.sh /usr/local/polarstore/pfsd/bin/
28 | COPY $RPM /opt/
29 |
30 | ENV PYTHONPATH /docker_script
31 | ENV RPM_ENV $RPM
32 |
33 | ENTRYPOINT ["python", "/docker_script/pfsd_supervisor.py"]
34 | CMD ["-f", "-c", "/usr/local/polarstore/pfsd/conf/pfsd_logger.conf"]
35 |
36 | RUN /usr/bin/yum makecache && \
37 | yum install -y python27 &&\
38 | ln -s /usr/bin/python2.7 /usr/bin/python && \
39 | /usr/bin/yum install -y libaio && \
40 | rpm -ivh /opt/$RPM_ENV && \
41 | chmod +x /usr/local/polarstore/pfsd/bin/start_pfsd.sh && \
42 | chmod +x /usr/local/polarstore/pfsd/bin/stop_pfsd.sh && \
43 | mkdir -p /dev/shm/pfsd && \
44 | chmod 777 /dev/shm/pfsd && \
45 | mkdir -p /var/log && \
46 | chmod 777 /var/log && \
47 | mkdir -p /var/run/pfsd && \
48 | chmod 777 /var/run/pfsd && \
49 | chmod 777 /docker_script && \
50 | /usr/bin/yum install -y gdb
51 |
52 |
--------------------------------------------------------------------------------
/docker/pfsd/log.conf:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | [loggers]
15 | keys=root,pfsd_super
16 |
17 | [handlers]
18 | keys=consoleHandler,fileHandler
19 |
20 | [formatters]
21 | keys=pfsd_super
22 |
23 | [logger_root]
24 | level=DEBUG
25 | handlers=consoleHandler,fileHandler
26 |
27 | [logger_pfsd_super]
28 | level=DEBUG
29 | handlers=consoleHandler,fileHandler
30 | qualname=pfsd_super
31 | propagate=0
32 |
33 | [handler_consoleHandler]
34 | class=StreamHandler
35 | level=DEBUG
36 | formatter=pfsd_super
37 | args=(sys.stdout,)
38 |
39 | [handler_fileHandler]
40 | class=FileHandler
41 | level=DEBUG
42 | formatter=pfsd_super
43 | args=("/var/log/pfsd_super.log",)
44 |
45 | [formatter_pfsd_super]
46 | format=[%(asctime)s](%(filename)s:%(lineno)s)%(levelname)s: %(message)s
47 | datefmt=
48 |
--------------------------------------------------------------------------------
/docker/pfsd/pre_stop_pfsd.sh:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | #! /bin/bash
15 |
16 | # stop pfsd and cleanup resources
17 |
18 | # 1. check arg for pbdname
19 | pbd=$1
20 | if test -z $pbd;then
21 | echo "Error: not get pbdname"
22 | exit
23 | fi
24 |
25 | echo "Exec: pre_stop_pfsd $pbd"
26 |
27 | # 2. create exit file
28 | exit_file="/scripts/pfsd_ins_exit"
29 | touch $exit_file
30 |
31 | # 3. check if pfsdaemon alive
32 | pfsd_pid=`ps -ef|grep pfsdaemon|grep -v grep|gawk '{print $2}'`
33 |
34 | if test -z "$pfsd_pid";then
35 | echo "Error: not found pfsd running"
36 | else
37 | # 4. kill pfsdaemon
38 | echo "kill -2 $pfsd_pid"
39 | kill -2 $pfsd_pid
40 | sleep 1
41 | pfsd_pid2=`ps -ef|grep pfsdaemon|grep -v grep|gawk '{print $2}'`
42 | if test -n "$pfsd_pid2";then
43 | echo "kill -9 $pfsd_pid2"
44 | kill -9 $pfsd_pid2
45 | exit
46 | fi
47 | fi
48 |
49 | # 5. exec clean pfsd
50 | echo "/usr/local/polarstore/pfsd/bin/clean_pfsd.sh $pbd"
51 | exec /usr/local/polarstore/pfsd/bin/clean_pfsd.sh $pbd
52 |
53 |
--------------------------------------------------------------------------------
/docker/tool/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | ARG IMAGE
15 |
16 | FROM $IMAGE
17 |
18 | ARG RPM
19 | ARG VERSION
20 |
21 | LABEL dev_version="$VERSION"
22 |
23 | USER root
24 |
25 | COPY entry_oper.py /docker_script/
26 | COPY pfsd_oper.py /docker_script/
27 | COPY log.conf /docker_script/
28 | COPY $RPM /opt/
29 | COPY pre_stop_pfsd.sh /usr/local/polarstore/pfsd/bin/
30 |
31 | ENV RPM_ENV $RPM
32 | ENV PYTHONPATH /docker_script
33 | ENTRYPOINT ["python2", "/docker_script/pfsd_oper.py"]
34 |
35 | RUN touch /var/lib/yum && \
36 | touch /var/lib/rpm/* &&\
37 | yum install -y python27 && \
38 | ln -s /usr/bin/python2.7 /usr/bin/python && \
39 | yum install -y libaio && \
40 | rpm -ivh /opt/$RPM_ENV && \
41 | chmod -R +x /docker_script && \
42 | yum install -y gdb
43 |
44 |
--------------------------------------------------------------------------------
/docker/tool/log.conf:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | [loggers]
15 | keys=root,pfsd_oper
16 |
17 | [handlers]
18 | keys=consoleHandler,fileHandler
19 |
20 | [formatters]
21 | keys=pfsd_oper
22 |
23 | [logger_root]
24 | level=DEBUG
25 | handlers=consoleHandler,fileHandler
26 |
27 | [logger_pfsd_oper]
28 | level=DEBUG
29 | handlers=consoleHandler,fileHandler
30 | qualname=pfsd_oper
31 | propagate=0
32 |
33 | [handler_consoleHandler]
34 | class=StreamHandler
35 | level=DEBUG
36 | formatter=pfsd_oper
37 | args=(sys.stdout,)
38 |
39 | [handler_fileHandler]
40 | class=FileHandler
41 | level=DEBUG
42 | formatter=pfsd_oper
43 | args=("/var/log/pfsd_oper.log",)
44 |
45 | [formatter_pfsd_oper]
46 | format=[%(asctime)s](%(filename)s:%(lineno)s)%(levelname)s: %(message)s
47 | datefmt=
48 |
--------------------------------------------------------------------------------
/docker/tool/pfsd_oper.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 |
15 | #!/usr/bin/python
16 | # -*- coding: utf-8 -*-
17 |
18 | import time
19 |
20 | def main():
21 | while True:
22 | time.sleep(86400 * 365)
23 |
24 | # pfsd管理容器
25 | if __name__ == "__main__":
26 | main()
27 |
28 |
--------------------------------------------------------------------------------
/docker/tool/pre_stop_pfsd.sh:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | #! /bin/bash
15 |
16 | # stop pfsd and cleanup resources
17 |
18 | # 1. check arg for pbdname
19 | pbd=$1
20 | if test -z $pbd;then
21 | echo "Error: not get pbdname"
22 | exit
23 | fi
24 |
25 | echo "Exec: pre_stop_pfsd $pbd"
26 |
27 | # 2. create exit file
28 | exit_file="/scripts/pfsd_ins_exit"
29 | touch $exit_file
30 |
31 | # 3. check if pfsdaemon alive
32 | pfsd_pid=`ps -ef|grep pfsdaemon|grep -v grep|gawk '{print $2}'`
33 |
34 | if test -z "$pfsd_pid";then
35 | echo "Error: not found pfsd running"
36 | else
37 | # 4. kill pfsdaemon
38 | echo "kill -2 $pfsd_pid"
39 | kill -2 $pfsd_pid
40 | sleep 1
41 | pfsd_pid2=`ps -ef|grep pfsdaemon|grep -v grep|gawk '{print $2}'`
42 | if test -n "$pfsd_pid2";then
43 | echo "kill -9 $pfsd_pid2"
44 | kill -9 $pfsd_pid2
45 | exit
46 | fi
47 | fi
48 |
49 | # 5. exec clean pfsd
50 | echo "/usr/local/polarstore/pfsd/bin/clean_pfsd.sh $pbd"
51 | exec /usr/local/polarstore/pfsd/bin/clean_pfsd.sh $pbd
52 |
53 |
--------------------------------------------------------------------------------
/docs/pic/dinggroup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApsaraDB/PolarDB-FileSystem/d0c5dc6d8a7363722c8c70b6bd9c6727ef6e1c0d/docs/pic/dinggroup.png
--------------------------------------------------------------------------------
/etc/polarfs.conf:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | #polarfs common config
15 | [common]
16 | discard_interval=5
17 | poll_interval=1 #poll_interval > 0, second
18 | orphan_interval=1 #orphan_interval > 0, second
19 | file_shrink_size=10737418240 #0 < file_shrink_size <= 10737418240
20 | trimgroup_ntx_threshold_hard=39999 #trimgroup_ntx_threshold_hard > 0
21 | log_trim_interval=10 #log_trim_interval > 0, second
22 | du_nblk_limit=1 #du_nblk_limit > 0
23 | nc_lru_window=100000 #nc_lru_window > 0
24 | trace_plevel=3 #trace_plevel must be 1,2,3,4,5
25 | trimgroup_ntx_threshold=20000 #trimgroup_ntx_threshold > 0
26 | trimgroup_nsects_swapinmax=2562 #trimgroup_nsects_swapinmax > 0
27 | paxos_wait_time=300 #paxos_wait_time > 0, second
28 | paxos_acquire_time=10 #paxos_acquire_time > 0
29 | log_paxos_lease=1 #log_paxos_lease > 0, second
30 | paxos_hold_time=150 #paxos_hold_time > 0, second
31 | io_wait_deadline=10000000 #io_wait_deadline > 0, ns
32 | pangu_client_nthread=4 #pangu_client_nthread > 0
33 | discard_ninp=500 #discard_ninp > 0
34 | discard_period=100 #discard_period > 0
35 | orphan_select_max_num=100 #0 < orphan_select_max_num <= 500
36 | nc_max=32768 #nc_max > 0
37 | nc_max_bucket_len=200 #nc_max_bucket_len > 0
38 | trimgroup_nsect_threshold=32768 #trimgroup_nsect_threshold > 0
39 | pangu_iodepth=8 #pangu_iodepth > 0, but depends on store
40 | polar_iodepth=8 #pangu_iodepth > 0, but depends on store
41 | nc_enable=1
42 | readtx_skip_sync=1
43 | devstat_enable=0
44 | mountstat_enable=1
45 | loadthread_count=8 #loadthread_count > 0,but no more than chunks
46 | file_max_nfd=204800 #max open file num limit,upto 2048000
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | INSTALL_BASE_DIR="/usr/local/polarstore"
17 |
18 | #prepare dir
19 | mkdir -p ${INSTALL_BASE_DIR}
20 | mkdir -p ${INSTALL_BASE_DIR}/pfsd
21 | mkdir -p ${INSTALL_BASE_DIR}/pfsd/bin
22 | mkdir -p ${INSTALL_BASE_DIR}/pfsd/conf
23 | mkdir -p ${INSTALL_BASE_DIR}/pfsd/include
24 | mkdir -p ${INSTALL_BASE_DIR}/pfsd/lib
25 |
26 | #check install
27 | if [ -f "${INSTALL_BASE_DIR}/pfsd/include/pfsd_sdk.h" ] || \
28 | [ -f "${INSTALL_BASE_DIR}/pfsd/lib/libpfsd.a" ] || \
29 | [ -f "${INSTALL_BASE_DIR}/pfsd/lib/libpfsd_test.so" ] || \
30 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/pfsdaemon" ] || \
31 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/pfs-fuse" ] || \
32 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/pfsd_shm_tool" ] || \
33 | [ -f "${INSTALL_BASE_DIR}/pfsd/conf/pfsd_logger.conf" ] || \
34 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/start_pfsd.sh" ] || \
35 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/stop_pfsd.sh" ] || \
36 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/mount_pfs_fuse.sh" ] || \
37 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/umount_pfs_fuse.sh" ] || \
38 | [ -f "${INSTALL_BASE_DIR}/pfsd/bin/clean_pfsd.sh" ] || \
39 | [ -f "/etc/init.d/pfsd_env" ] || \
40 | [ -f "/etc/polarfs.conf" ] || \
41 | [ -f "/usr/local/bin/pfs" ] || \
42 | [ -f "/usr/local/bin/pfsadm" ];then
43 | echo "pfsd/fuse has installed, install failed"
44 | exit 1
45 | fi
46 |
47 | if [ ! -f "src/pfs_sdk/pfsd_sdk.h" ] || \
48 | [ ! -f "lib/libpfsd.a" ] || \
49 | [ ! -f "lib/libpfsd_test.so" ] || \
50 | [ ! -f "bin/pfsdaemon" ] || \
51 | [ ! -f "bin/pfs-fuse" ] || \
52 | [ ! -f "bin/pfsd_shm_tool" ] || \
53 | [ ! -f "conf/pfsd_logger.conf" ] || \
54 | [ ! -f "deploy_scripts/start_pfsd.sh" ] || \
55 | [ ! -f "deploy_scripts/stop_pfsd.sh" ] || \
56 | [ ! -f "deploy_scripts/mount_pfs_fuse.sh" ] || \
57 | [ ! -f "deploy_scripts/umount_pfs_fuse.sh" ] || \
58 | [ ! -f "deploy_scripts/clean_pfsd.sh" ] || \
59 | [ ! -f "src/pfsd/pfsd.init" ] || \
60 | [ ! -f "etc/polarfs.conf" ] || \
61 | [ ! -f "bin/pfs" ] || \
62 | [ ! -f "bin/pfsadm" ];then
63 | echo "installing files not found, please check files or run autobuild.sh first"
64 | exit 1
65 | fi
66 |
67 | if [[ $EUID -ne 0 ]];then
68 | echo "pfsd/fuse install script must be run as root"
69 | exit 1
70 | fi
71 |
72 | #install
73 | install -m 0644 src/pfs_sdk/pfsd_sdk.h ${INSTALL_BASE_DIR}/pfsd/include/pfsd_sdk.h
74 | install -m 0755 lib/libpfsd.a ${INSTALL_BASE_DIR}/pfsd/lib/libpfsd.a
75 | install -m 0755 lib/libpfsd_test.so ${INSTALL_BASE_DIR}/pfsd/lib/libpfsd_test.so
76 | install -m 0755 bin/pfsdaemon ${INSTALL_BASE_DIR}/pfsd/bin/pfsdaemon
77 | install -m 0755 bin/pfs-fuse ${INSTALL_BASE_DIR}/pfsd/bin/pfs-fuse
78 | install -m 0755 bin/pfsd_shm_tool ${INSTALL_BASE_DIR}/pfsd/bin/pfsd_shm_tool
79 | install -m 0644 conf/pfsd_logger.conf ${INSTALL_BASE_DIR}/pfsd/conf/pfsd_logger.conf
80 | install -m 0755 deploy_scripts/start_pfsd.sh ${INSTALL_BASE_DIR}/pfsd/bin/start_pfsd.sh
81 | install -m 0755 deploy_scripts/stop_pfsd.sh ${INSTALL_BASE_DIR}/pfsd/bin/stop_pfsd.sh
82 | install -m 0755 deploy_scripts/mount_pfs_fuse.sh ${INSTALL_BASE_DIR}/pfsd/bin/mount_pfs_fuse.sh
83 | install -m 0755 deploy_scripts/umount_pfs_fuse.sh ${INSTALL_BASE_DIR}/pfsd/bin/umount_pfs_fuse.sh
84 | install -m 0755 deploy_scripts/clean_pfsd.sh ${INSTALL_BASE_DIR}/pfsd/bin/clean_pfsd.sh
85 | install -m 0755 src/pfsd/pfsd.init /etc/init.d/pfsd_env
86 | install -m 0644 etc/polarfs.conf /etc/polarfs.conf
87 |
88 | install -m 0755 bin/pfs /usr/local/bin/pfs
89 | install -m 0755 bin/pfsadm /usr/local/bin/pfsadm
90 |
91 | #prepare for pfsd running
92 | mkdir -p /dev/shm/pfsd
93 | mkdir -p /var/run/pfsd
94 | mkdir -p /var/run/pfs
95 | chmod 777 /var/run/pfsd
96 | chmod 777 /dev/shm/pfsd
97 | chmod 777 /var/run/pfs
98 | touch /var/run/pfsd/.pfsd
99 | chkconfig --add pfsd_env
100 |
101 | echo "install pfsd success!"
102 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | add_subdirectory(pfs_core)
15 | add_subdirectory(pfs_sdk)
16 | add_subdirectory(pfsd)
17 | add_subdirectory(pfs_tools)
18 | add_subdirectory(pfs_fuse)
19 |
--------------------------------------------------------------------------------
/src/pfs_core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | include_directories(
15 | ${PROJECT_SOURCE_DIR}/src/pfs_core/
16 | ${PROJECT_SOURCE_DIR}/src/pfs_core/lib/
17 | ${PROJECT_SOURCE_DIR}/src/trace/include/
18 | )
19 |
20 | set(SRC_LIST
21 | devio_disk.cc
22 | pfs_admin.cc
23 | pfs_alloc.cc
24 | pfs_api.cc
25 | pfs_blkio.cc
26 | pfs_command.cc
27 | pfs_config.cc
28 | pfs_devio.cc
29 | pfs_devstat.cc
30 | pfs_dir.cc
31 | pfs_file.cc
32 | pfs_inode.cc
33 | pfs_log.cc
34 | pfs_memory.cc
35 | pfs_meta.cc
36 | pfs_mount.cc
37 | pfs_namecache.cc
38 | pfs_namei.cc
39 | pfs_option.cc
40 | pfs_paxos.cc
41 | pfs_stat.cc
42 | pfs_stat_file_type.cc
43 | pfs_tls.cc
44 | pfs_trace.cc
45 | pfs_tx.cc
46 | pfs_util.cc
47 | pfs_version.cc
48 | pfs_chunk.cc
49 | pfs_avl.cc
50 | )
51 |
52 | # lib pfs
53 | add_library(pfs STATIC
54 | ${SRC_LIST}
55 | ${SRC_LIST_LIB}
56 | )
57 |
58 | target_link_libraries(pfs
59 | -Wl,--start-group
60 | rt
61 | pthread
62 | dl
63 | aio
64 | -Wl,--end-group
65 | )
66 |
67 | set_property(TARGET pfs PROPERTY POSITION_INDEPENDENT_CODE ON)
68 |
69 |
--------------------------------------------------------------------------------
/src/pfs_core/lib/fnv_hash.h:
--------------------------------------------------------------------------------
1 | /*-
2 | * Fowler / Noll / Vo Hash (FNV Hash)
3 | * http://www.isthe.com/chongo/tech/comp/fnv/
4 | *
5 | * This is an implementation of the algorithms posted above.
6 | * This file is placed in the public domain by Peter Wemm.
7 | *
8 | * $FreeBSD: src/sys/sys/fnv_hash.h,v 1.3 2005/01/07 02:29:23 imp Exp $
9 | */
10 |
11 | #include
12 |
13 | typedef u_int32_t Fnv32_t;
14 | typedef u_int64_t Fnv64_t;
15 |
16 | #define FNV1_32_INIT ((Fnv32_t) 33554467UL)
17 | #define FNV1_64_INIT ((Fnv64_t) 0xcbf29ce484222325ULL)
18 |
19 | #define FNV_32_PRIME ((Fnv32_t) 0x01000193UL)
20 | #define FNV_64_PRIME ((Fnv64_t) 0x100000001b3ULL)
21 |
22 | static __inline Fnv32_t
23 | fnv_32_buf(const void *buf, size_t len, Fnv32_t hval)
24 | {
25 | const u_int8_t *s = (const u_int8_t *)buf;
26 |
27 | while (len-- != 0) {
28 | hval *= FNV_32_PRIME;
29 | hval ^= *s++;
30 | }
31 | return hval;
32 | }
33 |
34 | static __inline Fnv32_t
35 | fnv_32_str(const char *str, Fnv32_t hval)
36 | {
37 | const u_int8_t *s = (const u_int8_t *)str;
38 | Fnv32_t c;
39 |
40 | while ((c = *s++) != 0) {
41 | hval *= FNV_32_PRIME;
42 | hval ^= c;
43 | }
44 | return hval;
45 | }
46 |
47 | static __inline Fnv64_t
48 | fnv_64_buf(const void *buf, size_t len, Fnv64_t hval)
49 | {
50 | const u_int8_t *s = (const u_int8_t *)buf;
51 |
52 | while (len-- != 0) {
53 | hval *= FNV_64_PRIME;
54 | hval ^= *s++;
55 | }
56 | return hval;
57 | }
58 |
59 | static __inline Fnv64_t
60 | fnv_64_str(const char *str, Fnv64_t hval)
61 | {
62 | const u_int8_t *s = (const u_int8_t *)str;
63 | unsigned long c; /* 32 bit on i386, 64 bit on alpha,ia64 */
64 |
65 | while ((c = *s++) != 0) {
66 | hval *= FNV_64_PRIME;
67 | hval ^= c;
68 | }
69 | return hval;
70 | }
71 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs.init:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # pfs_env prepare pfs running environment
17 | #
18 | # chkconfig: 35 99 99
19 | # description: create directories and files for pfs
20 |
21 | mkdir -m 0777 /var/run/pfs && touch /var/run/pfs/.pfs
22 |
23 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_alloc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_ALLOC_H_
17 | #define _PFS_ALLOC_H_
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #include "pfs_impl.h"
24 |
25 | #define PFS_MAX_ANODE_NCNT \
26 | (MAX(MAX(PFS_NBT_PERCHUNK, PFS_NIN_PERCHUNK), PFS_NDE_PERCHUNK))
27 |
28 | typedef struct pfs_txop pfs_txop_t;
29 | typedef struct pfs_anode pfs_anode_t;
30 | typedef bool pfs_allocfunc_t(pfs_anode_t *, uint64_t);
31 | typedef void pfs_freefunc_t(pfs_anode_t *, uint64_t);
32 | typedef void * pfs_getfunc_t(pfs_anode_t *, uint64_t, pfs_txop_t *);
33 | typedef int pfs_redofunc_t(pfs_anode_t *, uint64_t, pfs_txop_t *);
34 | typedef int pfs_undofunc_t(pfs_anode_t *, uint64_t, pfs_txop_t *);
35 |
36 | typedef int pfs_anode_walkfn_t(pfs_anode_t *, void *data);
37 | typedef void pfs_anode_visitfn_t(pfs_anode_t *, uint64_t, void *);
38 |
39 | typedef struct pfs_anode {
40 | /* callback functions and data */
41 | void *an_host;
42 | pfs_allocfunc_t *an_allocfunc; /* metaset_alloc */
43 | pfs_freefunc_t *an_freefunc; /* metaset_free */
44 | pfs_getfunc_t *an_getfunc; /* metaset_get */
45 | pfs_undofunc_t *an_undofunc; /* metaset_undo */
46 | pfs_redofunc_t *an_redofunc; /* metaset_redo */
47 |
48 | pfs_anode_t *an_parent; /* XXX: for debug only */
49 | pfs_anode_t **an_children;
50 | uint64_t an_id;
51 | uint32_t an_shift; /* shift to get sub object id */
52 | int32_t an_nchild;
53 | int32_t an_nall;
54 | int32_t an_nfree;
55 | int32_t an_next;
56 | uint64_t an_free_bmp[
57 | howmany(PFS_MAX_ANODE_NCNT, sizeof(uint64_t)*8)];
58 | } pfs_anode_t;
59 |
60 | int pfs_anode_alloc(pfs_anode_t *an, uint64_t *pval);
61 | void pfs_anode_free(pfs_anode_t *an, uint64_t val);
62 | void pfs_anode_nfree_inc(pfs_anode_t *an, uint64_t val, int delta);
63 | void * pfs_anode_get(pfs_anode_t *an, uint64_t, pfs_txop_t *);
64 | int pfs_anode_undo(pfs_anode_t *an, uint64_t val, pfs_txop_t *top);
65 | int pfs_anode_redo(pfs_anode_t *an, uint64_t val, pfs_txop_t *top);
66 | void pfs_anode_destroy(pfs_anode_t *an);
67 | int pfs_anode_dump(pfs_anode_t *an, int type, int depth, int lvl,
68 | pfs_printer_t *printer);
69 | int pfs_anode_walk(pfs_anode_t *an, pfs_anode_walkfn_t *walkfn,
70 | void *data);
71 | void pfs_anode_visit(pfs_anode_t *an, uint64_t val, pfs_anode_visitfn_t *visfn,
72 | void *data);
73 |
74 | #endif /* _PFS_ALLOC_H_ */
75 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_avl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_AVL_H
17 | #define _PFS_AVL_H
18 |
19 | #include
20 |
21 | typedef int pfs_avl_compare_fn_t(const void *, const void *);
22 |
23 | typedef struct pfs_avl_node {
24 | struct pfs_avl_node *avl_child[2]; /* left/right children nodes */
25 | uintptr_t avl_pcb; /* parent, child_index, balance */
26 | } pfs_avl_node_t;
27 |
28 | typedef struct pfs_avl_tree {
29 | pfs_avl_node_t *avl_root; /* root node in tree */
30 | pfs_avl_compare_fn_t *avl_compar;
31 | size_t avl_offset; /* offsetof(type, avl_link_t field) */
32 | uint64_t avl_numnodes; /* number of nodes in the tree */
33 | } pfs_avl_tree_t;
34 |
35 | static inline uint64_t
36 | pfs_avl_numnodes(pfs_avl_tree_t *tree)
37 | {
38 | return tree->avl_numnodes;
39 | }
40 |
41 | static inline bool
42 | pfs_avl_is_empty(pfs_avl_tree_t *tree)
43 | {
44 | return tree->avl_numnodes == 0;
45 | }
46 |
47 | void pfs_avl_create(pfs_avl_tree_t *tree, pfs_avl_compare_fn_t *compar, size_t offset);
48 | void pfs_avl_destroy(pfs_avl_tree_t *tree);
49 | void *pfs_avl_find(pfs_avl_tree_t *tree, const void *node, uintptr_t *where);
50 | void pfs_avl_add(pfs_avl_tree_t *tree, void *node);
51 | void pfs_avl_remove(pfs_avl_tree_t *tree, void *node);
52 | void *pfs_avl_first(pfs_avl_tree_t *tree);
53 | void *pfs_avl_last(pfs_avl_tree_t *tree);
54 | void *pfs_avl_next(pfs_avl_tree_t *tree, void *data);
55 | void *pfs_avl_prev(pfs_avl_tree_t *tree, void *data);
56 |
57 | #endif /* _PFS_AVL_H */
58 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_blkio.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_BLKIO_H_
17 | #define _PFS_BLKIO_H_
18 |
19 | #include
20 |
21 | #include "pfs_impl.h"
22 |
23 | typedef struct pfs_mount pfs_mount_t;
24 |
25 | ssize_t pfs_blkio_read(pfs_mount_t *mnt, char *data,
26 | pfs_blkno_t blkno, off_t off, ssize_t len);
27 | ssize_t pfs_blkio_write(pfs_mount_t *mnt, char *data,
28 | pfs_blkno_t blkno, off_t off, ssize_t len);
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_chunk.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_CHUNK_H_
17 | #define _PFS_CHUNK_H_
18 |
19 | #include "pfs_api.h"
20 | #include "pfs_impl.h"
21 |
22 | typedef struct pfs_chunkstream_desc {
23 | uint32_t csd_nchunk; /* formatted chunk number of PBD */
24 | char csd_pbdname[PFS_MAX_PBDLEN];
25 | char csd_cluster[PFS_MAX_CLUSTERLEN];
26 | int csd_ioch_desc;
27 | int csd_meta_fd;
28 | int csd_flags;
29 | uint64_t csd_pfs_run_ver;
30 | } pfs_chunkstream_desc_t;
31 |
32 | typedef struct pfs_chunkstream {
33 | pfs_chunkstream_desc_t *cs_desc;
34 | int cs_ckid;
35 | uint64_t cs_time_us;
36 | } pfs_chunkstream_t;
37 |
38 | extern "C" {
39 | pfs_chunkstream_desc_t *
40 | pfs_chunkstream_init(const char *cluster, const char *pbdname, int flags);
41 | pfs_chunkstream_t *
42 | pfs_chunkstream_open(const pfs_chunkstream_desc_t *desc, int chunkid);
43 | int64_t pfs_chunkstream_read(pfs_chunkstream_t *stream, char *buf, size_t len);
44 | int64_t pfs_chunkstream_write(pfs_chunkstream_t *stream, const char *buf,
45 | size_t len);
46 | int pfs_chunkstream_close(pfs_chunkstream_t *stream);
47 | int pfs_chunkstream_fini(pfs_chunkstream_desc_t *desc);
48 | int pfs_chunkstream_eof(pfs_chunkstream_t *stream);
49 | void pfs_chunkstream_get_nchunk(const pfs_chunkstream_desc_t *desc,
50 | int *nchunk);
51 | }
52 |
53 |
54 | int pfs_chunk_backup_init(pfs_chunkstream_desc_t *desc);
55 | int pfs_chunk_restore_init(pfs_chunkstream_desc_t *desc);
56 | pfs_chunkstream_t *
57 | pfs_chunk_readstream_open(const pfs_chunkstream_desc_t *desc,
58 | int chunkid);
59 | pfs_chunkstream_t *
60 | pfs_chunk_writestream_open(const pfs_chunkstream_desc_t *desc,
61 | int chunkid);
62 | int64_t pfs_chunk_readstream(pfs_chunkstream_t *cs, char *buf, size_t len);
63 | int64_t pfs_chunk_writestream(pfs_chunkstream_t *cs, const char *buf, size_t len);
64 | void pfs_chunk_readstream_close(pfs_chunkstream_t *cs);
65 | void pfs_chunk_writesteam_close(pfs_chunkstream_t *cs);
66 | void pfs_chunk_fini(pfs_chunkstream_desc_t *desc);
67 | int pfs_chunk_readstream_isfinish(pfs_chunkstream_t *cs);
68 | int pfs_chunk_writestream_isfinish(pfs_chunkstream_t *cs);
69 |
70 |
71 | #endif
72 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_command.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_COMMAND_H_
17 | #define _PFS_COMMAND_H_
18 |
19 | #include
20 |
21 | #include "pfs_impl.h"
22 |
23 |
24 | struct cmdinfo {
25 | int ci_donefd;
26 | int ci_clisock;
27 | int ci_cmdop;
28 | int ci_stopcmd;
29 | pthread_t ci_tid;
30 | msg_command_t ci_msgcmd;
31 | };
32 |
33 | void *pfs_command_entry(void *);
34 |
35 | #endif /* _PFS_COMMAND_H_ */
36 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _CHUNK_SERVER_PFS_CONFIG_H_
17 | #define _CHUNK_SERVER_PFS_CONFIG_H_
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #define DEFAULT_CONFIG_PATH "/etc/polarfs.conf"
24 |
25 | #define MAX_KEY_LEN 32
26 | #define MAX_VAL_LEN 20
27 |
28 | #define MAX_CONFIG_LINE_LEN 4096
29 |
30 | /*
31 | * return ret
32 | */
33 | typedef enum {
34 | CONFIG_OK = 0,
35 | CONFIG_ERR_FILE,
36 | CONFIG_ERR_PARAMS,
37 | CONFIG_ERR_PARSING,
38 | CONFIG_ERR_MEM,
39 | CONFIG_ERR_VAL,
40 | } pfs_config_ret;
41 |
42 | /*
43 | * \brief: config item key-value pair, key is config name, value is config value
44 | * for compatible, value type is char[], work with specified translating func
45 | */
46 | typedef struct pfs_config_kv {
47 | char kv_key[MAX_KEY_LEN];
48 | char kv_value[MAX_VAL_LEN];
49 |
50 | TAILQ_ENTRY(pfs_config_kv) next;
51 | } pfs_config_kv_t;
52 |
53 | /*
54 | * \brief: declare config section
55 | * contains section list and kv_list of every section
56 | */
57 | typedef struct pfs_config_section {
58 | char sect_name[MAX_KEY_LEN];
59 | int num_of_kv;
60 |
61 | TAILQ_HEAD(, pfs_config_kv) kv_list;
62 | TAILQ_ENTRY(pfs_config_section) next;
63 | } pfs_config_section_t;
64 |
65 | /*
66 | * \brief: configuration handle
67 | */
68 | typedef struct pfs_config {
69 | int num_of_sect;
70 |
71 | TAILQ_HEAD(, pfs_config_section) sect_list;
72 | } pfs_config_t;
73 |
74 | /* brief: reload config from file */
75 | int pfs_config_load(const char *config_path, void (*func)(const char *, const char *, void*), void *data);
76 |
77 | #endif //_CHUNK_SERVER_PFS_CONFIG_H_
78 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_def.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_DEF_H_
17 | #define _PFS_DEF_H_
18 |
19 | #ifndef likely
20 | #define likely(c) __builtin_expect(!!(c), 1)
21 | #endif
22 | #ifndef unlikely
23 | #define unlikely(c) __builtin_expect(!!(c), 0)
24 | #endif
25 |
26 | #define STATIC_ASSERT(sentence) \
27 | typedef __attribute__ ((unused)) char __sassert[(sentence)*2-1];
28 |
29 | #define OUT
30 |
31 | #endif // _PFS_DEF_H_
32 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_devstat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_DEVSTAT_H_
17 | #define _PFS_DEVSTAT_H_
18 |
19 | #include "pfs_impl.h"
20 | #ifndef PFS_DISK_IO_ONLY
21 | #include "pfs_iochnl.h"
22 | #else
23 | enum {
24 | PFSDEV_REQ_NOP = 0,
25 | PFSDEV_REQ_INFO = 1,
26 | PFSDEV_REQ_RD = 2,
27 | PFSDEV_REQ_WR = 3,
28 | PFSDEV_REQ_TRIM = 4,
29 |
30 | PFSDEV_REQ_MAX,
31 | };
32 | #endif
33 |
34 | typedef struct pfs_devio pfs_devio_t;
35 | typedef struct admin_buf admin_buf_t;
36 |
37 | /* device statistics */
38 | typedef struct pfs_devstat {
39 | pthread_rwlock_t ds_rwlock;
40 | /* statistics */
41 | #define ds_iostat_start ds_start_count
42 | uint64_t ds_start_count;
43 | uint64_t ds_end_count;
44 | struct timeval ds_busy_time;
45 | uint64_t ds_bytes[PFSDEV_REQ_MAX];
46 | uint64_t ds_ops[PFSDEV_REQ_MAX];
47 | struct timeval ds_duration[PFSDEV_REQ_MAX];
48 | #define ds_iostat_end ds_busy_from
49 | struct timeval ds_busy_from;
50 | } pfs_devstat_t;
51 |
52 | void pfs_devstat_init(pfs_devstat_t *ds);
53 | void pfs_devstat_uninit(pfs_devstat_t *ds);
54 | void pfs_devstat_io_start(pfs_devstat_t *ds, const pfs_devio_t *io);
55 | void pfs_devstat_io_end(pfs_devstat_t *ds, const pfs_devio_t *io);
56 | int pfs_devstat_snap(int devi, admin_buf_t *ab);
57 |
58 | #endif /* _PFS_DEVSTAT_H_ */
59 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_dir.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_DIR_H_
17 | #define _PFS_DIR_H_
18 |
19 | #include
20 |
21 | #include "pfs_impl.h"
22 | #include "pfs_file.h"
23 | #include "pfs_namei.h"
24 | #include "pfs_api.h"
25 |
26 | #define PFS_DIR_END 1 // end of direntry
27 | #define PFS_DE_UNLINKED 2
28 |
29 | #define INVALID_EXTDENO 0 // root deno is sentinel
30 | #define DE_ISEXT(de) (de->de_ino != INVALID_INO && de->de_dirino == INVALID_INO)
31 |
32 | typedef struct pfs_tx pfs_tx_t;
33 | typedef struct pfs_mount pfs_mount_t;
34 |
35 | typedef struct pfs_direntry_phy { /* diretory entry */
36 | char de_name[PFS_MAX_NAMELEN_OLD];
37 | union {
38 | pfs_ino_t de_ino; /* (head de) ino for entry */
39 | uint64_t de_headdeno; /* (ext de) head deno */
40 | }; /* XXX: mo_number is u64 */
41 | pfs_ino_t de_dirino;
42 | uint64_t de_extdeno;
43 | } pfs_direntry_phy_t;
44 |
45 | struct __dirstream {
46 | struct direntplus d_deplus; /* should be the first member,
47 | * depended on by pfs_readdir */
48 |
49 | int d_mntid;
50 | pfs_mount_t *d_mnt;
51 | int64_t d_epoch;
52 | pfs_ino_t d_ino; /* dir ino */
53 |
54 | /*
55 | * When read dir, first copy all direntry numbers
56 | * into d_deno_vect, then iterate over the vector
57 | * and discard all deleted entries. This approach
58 | * is intended to provide a consistent view of a
59 | * big directory and still unable to include new
60 | * added direntries.
61 | */
62 | uint64_t *d_deno_vect;
63 | uint64_t d_deno_index;
64 | uint64_t d_deno_count;
65 | };
66 |
67 | typedef struct __dirstream DIR;
68 | struct dirent;
69 |
70 | /* maintain lifetime of directories' meminode */
71 | void pfs_memdir_load(pfs_mount_t *mnt);
72 | void pfs_memdir_unload(pfs_mount_t *mnt);
73 |
74 | /* directory tree resolving & updating */
75 | int pfs_memdir_xlookup(pfs_mount_t *mnt, nameinfo_t *ni, int oflags);
76 | int pfs_memdir_xremove(pfs_mount_t *mnt, nameinfo_t *ni);
77 | int pfs_memdir_xrename(pfs_mount_t *mnt, nameinfo_t *oldni, nameinfo_t *newni);
78 |
79 | /* dirstream */
80 | int pfs_memdir_xopen(pfs_mount_t *mnt, nameinfo_t *ni, DIR **dirp);
81 | int pfs_memdir_xread(pfs_mount_t *mnt, DIR *dir, struct dirent *den_result,
82 | struct direntplus **result, bool isplus);
83 | int pfs_memdir_close(pfs_mount_t *mnt, DIR *dir);
84 |
85 | /* current working directory */
86 | int pfs_memdir_xsetwd(pfs_mount_t *mnt, nameinfo_t *ni);
87 | int pfs_memdir_xgetwd(char *buf, size_t len);
88 |
89 | /* others */
90 | int pfs_memdir_xdu(pfs_mount_t *mnt, nameinfo_t *ni, int all, int level,
91 | int depth, pfs_printer_t *printer, const char *path);
92 |
93 | /* meta-dir api */
94 | void pfs_direntry_getname(pfs_mount_t *mnt, pfs_direntry_phy_t *headde,
95 | char *buf, size_t len);
96 | int pfs_dir_add(pfs_mount_t *mnt, pfs_ino_t dirino, const char *name, bool isdir,
97 | pfs_ino_t *inop, uint64_t *btimep);
98 | int pfs_dir_del(pfs_mount_t *mnt, pfs_ino_t dirino, pfs_ino_t ino,
99 | const char *name, bool isdir);
100 | int pfs_dir_rename(pfs_mount_t *mnt,
101 | pfs_ino_t odirino, pfs_ino_t oino, const char *oldname,
102 | pfs_ino_t ndirino, pfs_ino_t nino, const char *newname);
103 | int pfs_dir_path(pfs_mount_t *mnt, pfs_ino_t ino, char *path, size_t len,
104 | uint64_t btime);
105 | int pfs_dir_info(pfs_mount_t *mnt, pfs_ino_t dirino, char *dename,
106 | size_t len, pfs_ino_t *parinop);
107 |
108 | #endif /* _PFS_DIR_H_ */
109 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_file.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_FILEOPS_H_
17 | #define _PFS_FILEOPS_H_
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include "pfs_impl.h"
26 | #include "pfs_tx.h"
27 |
28 | typedef struct pfs_inode pfs_inode_t;
29 | typedef struct nameinfo nameinfo_t;
30 |
31 | #define OFFSET_FILE_POS (-1) /* offset is current file position */
32 | #define OFFSET_FILE_SIZE (-2) /* offset is file size */
33 |
34 | extern int64_t file_shrink_size;
35 |
36 | /*
37 | * I: file lock f_rwlock
38 | */
39 | typedef struct pfs_file {
40 | pthread_rwlock_t f_rwlock; /* (I) */
41 | int f_fd; /* file description */
42 | int f_mntid;
43 | int f_flags;
44 | off_t f_offset; /* next expected read/write offset,
45 | atomic add\sub */
46 | uint64_t f_btime;
47 | pfs_inode_t *f_inode;
48 | int32_t f_refcnt; /* readers and writers count, only
49 | changed when holding fdtbl lock */
50 | int f_type;
51 | } pfs_file_t;
52 |
53 | /* file lock flag when pfs_file_get */
54 | #define RDLOCK_FLAG 0x01 /* Result in file read lock */
55 | #define WRLOCK_FLAG 0x02 /* Result in file write lock */
56 |
57 | #define FILE_RDLOCK(file) rwlock_rdlock(&(file)->f_rwlock)
58 | #define FILE_WRLOCK(file) rwlock_wrlock(&(file)->f_rwlock)
59 | #define FILE_UNLOCK(file) rwlock_unlock(&(file)->f_rwlock)
60 |
61 | #define INNER_FILE_BTIME 0
62 |
63 | #define FALLOC_PFSFL_FIXED_OFFSET 0x0100 /* lower bits defined in falloc.h */
64 |
65 | pfs_file_t *
66 | pfs_file_get(int fd, int lockflag);
67 | void pfs_file_put(pfs_file_t *file);
68 | int pfs_file_open(pfs_mount_t *mnt, nameinfo_t *ni, int oflags, pfs_file_t **filep);
69 | int pfs_file_open_impl(pfs_mount_t *mnt, pfs_ino_t ino, int flags,
70 | pfs_file_t **filep, uint64_t btime);
71 | int pfs_file_close(pfs_file_t *file);
72 | int pfs_file_close_locked(pfs_file_t *file);
73 | int pfs_file_xstat(pfs_file_t *file, struct stat *st);
74 | ssize_t pfs_file_xpread(pfs_file_t *file, void *buf, size_t len, off_t offset);
75 | ssize_t pfs_file_xpwrite(pfs_file_t *file, const void *buf, size_t len,
76 | off_t offset);
77 | int pfs_file_xftruncate(pfs_file_t *file, off_t len);
78 | int pfs_file_xfallocate(pfs_file_t *file, off_t offset, size_t len, int mode);
79 | off_t pfs_file_xlseek(pfs_file_t *file, off_t offset, int whence);
80 | int pfs_file_xmap(pfs_file_t *file, fmap_entry_t *fmapv, int count);
81 | ssize_t pfs_file_size(pfs_file_t *file, uint64_t btime);
82 | ssize_t pfs_file_pread(pfs_file_t *file, void *buf, size_t len, off_t offset);
83 | ssize_t pfs_file_pwrite(pfs_file_t *file, const void *buf, size_t len, off_t offset);
84 | int pfs_file_release(pfs_mount_t *mnt, pfs_ino_t ino, uint64_t btime);
85 | int pfs_file_xsetxattr(pfs_file_t *file, const char *name, const void *value, size_t size);
86 |
87 | typedef struct admin_buf admin_buf_t;
88 | int pfs_fdtbl_dump(admin_buf_t *ab);
89 | void pfs_fdtbl_init();
90 |
91 | /*
92 | * Helper inline functions to calculate block id and offset.
93 | */
94 | static inline pfs_blkid_t
95 | fblkid(off_t off, size_t blksize)
96 | {
97 | PFS_ASSERT((blksize & (blksize -1)) == 0); /* power of 2 */
98 | PFS_ASSERT(off >= 0);
99 | return (pfs_blkid_t)(off / blksize);
100 | }
101 |
102 | static inline off_t
103 | fblkoff(off_t off, size_t blksize)
104 | {
105 | PFS_ASSERT((blksize & (blksize -1)) == 0); /* power of 2 */
106 | PFS_ASSERT(off >= 0);
107 | return (off_t)(off & (blksize - 1));
108 | }
109 |
110 | #endif
111 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_log.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_LOG_H_
17 | #define _PFS_LOG_H_
18 |
19 | #include
20 | #include
21 |
22 | #include "pfs_paxos.h"
23 | #include "pfs_tx.h"
24 |
25 | typedef struct pfs_mount pfs_mount_t;
26 | typedef struct pfs_file pfs_file_t;
27 | typedef struct pfs_tx pfs_tx_t;
28 | typedef struct pfs_sectbuf pfs_sectbuf_t;
29 |
30 | enum {
31 | LOG_MERGED = 0,
32 |
33 | LOG_LOAD,
34 | LOG_REPLAYDONE,
35 | LOG_TRIM,
36 | LOG_POLL,
37 | LOG_TRY_RESET_LOCK,
38 | LOG_WRITE,
39 | LOG_FLUSH,
40 | LOG_SUSPEND,
41 | LOG_RESUME,
42 | LOG_STOP,
43 |
44 | LOG_NREQ,
45 |
46 | LOG_REPLAY_WAIT, /* private wait queue */
47 |
48 | LOG_NMAX,
49 | };
50 |
51 | struct log_req;
52 | TAILQ_HEAD(req_qhead, log_req);
53 | typedef struct log_req {
54 | TAILQ_ENTRY(log_req) r_next;
55 | pthread_mutex_t r_mtx;
56 | pthread_cond_t r_cond;
57 | int r_type;
58 | bool r_done;
59 | int r_error;
60 | pfs_tx_t *r_itx;
61 | struct tx_qhead *r_otxq;
62 | int r_hostid;
63 | int r_next_hostid;
64 | } log_req_t;
65 |
66 | /*
67 | * A trimgroup collects dirty sectors of meta data that
68 | * should be flushed onto disk when log trim is performed.
69 | *
70 | * The meta data sectors are from transactions in the range
71 | * (g_ltxid, g_rtxid], as sorted in g_sects. These sectors
72 | * are also sorted by their block addresses in a search tree
73 | * g_rootp. The search tree helps to find out whether a sector
74 | * is modified multiple times.
75 | */
76 | typedef struct pfs_trimgroup {
77 | pfs_txid_t g_ltxid;
78 | pfs_txid_t g_rtxid;
79 | uint64_t g_roffset;
80 | int64_t g_nsects;
81 | int64_t g_nsects_empty;
82 | pfs_sectbuf_t *g_sect_empty_first; /* before the pointer in g_sects,
83 | every sect must have been memcpied.*/
84 | struct sectbuf_qhead g_sects; /* sort by txid in
85 | non-descending order */
86 | void *g_rootp; /* bda search index */
87 | } pfs_trimgroup_t;
88 |
89 | typedef struct pfs_log {
90 | pfs_mount_t *log_mount;
91 | int log_state;
92 | int log_flags;
93 |
94 | pthread_t log_tid; /* log IO thread */
95 | pthread_mutex_t log_mtx;
96 | pthread_cond_t log_cond;
97 | struct req_qhead log_reqhead;
98 |
99 | pfs_file_t *log_file;
100 | pfs_leader_record_t log_leader;
101 | char *log_workbuf;
102 | ssize_t log_workbufsz;
103 |
104 | log_req_t log_trimreq;
105 |
106 | pfs_trimgroup_t log_grpbuf[2];
107 | pfs_trimgroup_t *log_workgrp; /* somewhere to collect new tx */
108 | pfs_trimgroup_t *log_waitgrp; /* somewhere existed txs wait to be trimmed */
109 |
110 | struct timespec log_trimts;
111 |
112 | bool log_paxos_got; /* whether got paxos */
113 | pfs_leader_record_t log_leader_latest;/* cache of disk pfs_leader_record */
114 | struct timespec log_paxos_ts; /* timestamp of having got paxos */
115 | } pfs_log_t;
116 |
117 | typedef struct pfs_logentry_phy {
118 | pfs_metaobj_phy_t le_obj_val;
119 | int64_t le_lsn;
120 | uint64_t le_sector_bda;
121 | int64_t le_txid;
122 | uint32_t le_obj_idx;
123 | uint32_t le_checksum;
124 | int le_more;
125 | } __attribute__((aligned(256))) pfs_logentry_phy_t;
126 |
127 | void pfs_log_dump(pfs_logentry_phy_t *lebuf, uint32_t nle, int level);
128 |
129 | int pfs_log_start(pfs_log_t *log);
130 | void pfs_log_stop(pfs_log_t *log);
131 | int pfs_log_write(pfs_log_t *log, char *buf, size_t buflen,
132 | uint64_t offset);
133 | void pfs_log_suspend(pfs_log_t *log);
134 | void pfs_log_resume(pfs_log_t *log);
135 | int pfs_log_commit(pfs_log_t *log, pfs_txid_t txid, pfs_lsn_t lsn);
136 | void pfs_log_enqueue(pfs_log_t *log, pfs_tx_t *tx);
137 | int pfs_log_preload(pfs_log_t *log);
138 |
139 | #define pfs_log_request(log, type, tx, rplhead) pfs_log_request_impl(log, \
140 | type, tx, rplhead, -1, -1)
141 | int pfs_log_request_impl(pfs_log_t *log, int type, pfs_tx_t *tx,
142 | struct tx_qhead *rplhead, int host_id, int next_host_id);
143 |
144 | #endif /* _PFS_LOG_H_ */
145 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_memory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_MEMORY_H_
17 | #define _PFS_MEMORY_H_
18 |
19 | enum {
20 | M_NONE = 0,
21 | M_SECTOR,
22 | M_FRAG,
23 | M_TX,
24 | M_TXOP,
25 | M_TXCB,
26 | M_REQWAIT,
27 | M_DBLKV,
28 | M_CHUNKV,
29 | M_CHDESC,
30 | M_TLS,
31 | M_INODE,
32 | M_DIR,
33 | M_FILE,
34 | M_FILEHOLE,
35 | M_CHUNK,
36 | M_MOUNT,
37 | M_OBJBUFV,
38 | M_METASET,
39 | M_ANODEV,
40 | M_PAXOS_SECTOR,
41 | M_ADMINFO,
42 | M_ADMBUF,
43 | M_CMDINFO,
44 | M_SECTHDR,
45 | M_SECTBUF,
46 | M_OIDV,
47 | M_IO_TMPBUF,
48 | M_ZERO_BUF,
49 | M_DEV_IO,
50 | M_POLAR_DEV,
51 | M_POLAR_IOQ,
52 | M_PANGU_DEV,
53 | M_PANGU_IOQ,
54 | M_PANGU_TASK,
55 | M_DISK_DEV,
56 | M_DISK_IOQ,
57 | M_DISK_DIOBUF,
58 | M_DENO_VECT,
59 | M_CHUNK_META,
60 | M_CHUNK_READSTREAM,
61 | M_CHUNK_WRITESTREAM,
62 | M_CHUNK_METABUF,
63 | M_CHUNK_CRCBUF,
64 | M_CHUNK_BLOCKUSED,
65 | M_NAMECACHE,
66 | M_OIDV_HOLEOFF,
67 | M_DXENT,
68 | M_INSTK_VEC,
69 | M_CONFIG,
70 | M_CONFIG_SECT,
71 | M_CONFIG_KV,
72 | M_FDTBL_PTR,
73 | M_INODE_BLK_TABLE,
74 |
75 | M_NTYPE
76 | };
77 |
78 | typedef struct admin_buf admin_buf_t;
79 |
80 | void * pfs_mem_malloc(size_t size, int type);
81 | void pfs_mem_free(void *ptr, int type);
82 | void * pfs_mem_realloc(void *ptr, size_t newsize, int type);
83 | int pfs_mem_memalign(void **pp, size_t alignment, size_t size, int type);
84 | int pfs_mem_stat(admin_buf_t *dbuf);
85 |
86 | #endif /* _PFS_MEMORY_H_ */
87 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_namecache.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_NAME_CACHE_H_
17 | #define _PFS_NAME_CACHE_H_ 1
18 |
19 | typedef struct admin_buf admin_buf_t;
20 |
21 | #ifndef NAMECACHE_TEST
22 | void pfs_namecache_enter(pfs_mount_t *mnt, pfs_ino_t parent_ino,
23 | pfs_ino_t child_ino, const char *name, int64_t deno);
24 |
25 | #if 0
26 | void pfs_namecache_delete(pfs_mount_t *mnt, pfs_ino_t parent_ino,
27 | const char *name);
28 | #endif
29 |
30 | void pfs_namecache_delete_by_deno(pfs_mount_t *mnt, int64_t deno);
31 |
32 | int pfs_namecache_lookup(pfs_mount_t *mnt, pfs_ino_t parent_ino,
33 | const char *name, pfs_ino_t *child_ino);
34 |
35 | void pfs_namecache_clear_mount(pfs_mount_t *mnt);
36 | #endif
37 |
38 | int pfs_get_namecache_enable(void);
39 | void pfs_set_namecache_enable(int enable);
40 |
41 | struct namecache_stat
42 | {
43 | unsigned long hashsize;
44 | unsigned long numcache;
45 | unsigned long numchecks;
46 | unsigned long numhits;
47 | unsigned long nummiss;
48 | unsigned long numdelbydeno;
49 | unsigned long numdelbyname;
50 | unsigned long numevicts;
51 | unsigned long numrejects;
52 | };
53 |
54 | void pfs_namecache_stat(namecache_stat *stat);
55 | int pfs_namecache_dump(int type, admin_buf_t *ab);
56 | int pfs_namecache_dumpbin(struct cmdinfo *ci, admin_buf_t *ab);
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_namei.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_NAMEI_H_
17 | #define _PFS_NAMEI_H_
18 |
19 | #include "pfs_impl.h"
20 |
21 | typedef struct pfs_inode pfs_inode_t;
22 | struct stkent;
23 |
24 | struct instack {
25 | struct stkent *s_vec;
26 | int s_i;
27 | int s_size;
28 | char s_path[PFS_MAX_PATHLEN];/* formatted path */
29 | char *s_nextpos; /* to locate component */
30 | };
31 |
32 | typedef struct nameinfo {
33 | /* a copy of path from user */
34 | char ni_buf[PFS_MAX_PATHLEN];
35 | /* decomposed path components */
36 | char *ni_pbd;
37 | char *ni_path;
38 | /*
39 | * While resolving dotdot we should jump to parent dir,
40 | * so we copy ni_ino's de_name into ni_name_buf and let ni_srch_name
41 | * point to it.
42 | */
43 | char *ni_srch_name;
44 | char ni_name_buf[PFS_MAX_NAMELEN];
45 |
46 | pfs_ino_t ni_par_ino;
47 | pfs_ino_t ni_ino;
48 | uint64_t ni_par_btime;
49 | uint64_t ni_btime;
50 | int ni_tgt_type;
51 | /*
52 | * When resolving inner path components we can't step
53 | * forward or backward, the path is broken.
54 | */
55 | bool ni_broken_path;
56 |
57 | struct instack ni_instk;
58 | } nameinfo_t;
59 |
60 | typedef struct pfs_mount pfs_mount_t;
61 |
62 | /* nameinfo-related func */
63 | int pfs_namei_init(nameinfo_t *ni, const char *path, int type);
64 | int pfs_namei_lookup(pfs_mount_t *mnt, nameinfo_t *ni, int oflags,
65 | pfs_inode_t **dirinp, pfs_inode_t **tgtinp, int *typep);
66 | int pfs_namei_check_stale(pfs_mount_t *mnt, nameinfo_t *ni, int type);
67 | void pfs_namei_lookup_done(nameinfo_t *ni);
68 | void pfs_namei_fini(nameinfo_t *ni);
69 |
70 | static inline bool
71 | pfs_namei_broken_path(nameinfo_t *ni)
72 | {
73 | return ni->ni_broken_path;
74 | }
75 |
76 | static inline int
77 | pfs_path_enter(pfs_mount_t *mnt, nameinfo_t *ni, int oflags,
78 | pfs_inode_t **dirinp, pfs_inode_t **tgtinop, int *typep)
79 | {
80 | /*
81 | * The searching result is just a indicator since it releases meta
82 | * lock in the middle. Any updates on meta may happen before rechecking
83 | * under meta lock.
84 | *
85 | * However, in most cases, we can still trust in the result if it means
86 | * 'parent directory exists but target not', that is for simplicity of
87 | * codes. If target file is newly-created during path lookup, the
88 | * result of inexistence still make sense.
89 | *
90 | * @dirinp and @tgtinp shall be synced before any further access.
91 | */
92 | return pfs_namei_lookup(mnt, ni, oflags, dirinp, tgtinop, typep);
93 | }
94 |
95 | static inline void
96 | pfs_path_exit(nameinfo_t *ni)
97 | {
98 | pfs_namei_lookup_done(ni);
99 | }
100 |
101 | static inline int
102 | pfs_path_check(pfs_mount_t *mnt, nameinfo_t *ni, int type)
103 | {
104 | return pfs_namei_check_stale(mnt, ni, type);
105 | }
106 |
107 | #endif /* _PFS_NAMEI_H */
108 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_option.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_OPTION_H_
17 | #define _PFS_OPTION_H_
18 |
19 | #include "pfs_util.h"
20 |
21 | #define PFS_OPT_DISABLE 0
22 | #define PFS_OPT_ENABLE 1
23 |
24 | #define PFS_MAX_OPTLEN 128
25 | #define MAX_NORPHAN 500
26 |
27 | typedef struct msg_header msg_header_t;
28 | typedef struct msg_option msg_option_t;
29 |
30 | typedef bool pfs_option_checkfunc_t(int64_t);
31 |
32 | typedef struct pfs_option {
33 | const char *o_file;
34 | int o_line;
35 | const char *o_name;
36 | int64_t *o_valuep; /* pointer of option */
37 | int64_t o_valued; /* default value */
38 | bool (*check_func)(void*); /* check value */
39 | } pfs_option_t;
40 |
41 | #define PFS_OPTION_REG(name, check_func) \
42 | static pfs_option_t opt_##name __attribute__((used)) = { \
43 | __FILE__, __LINE__, \
44 | #name, \
45 | &name, \
46 | name, \
47 | check_func, \
48 | }; \
49 | static pfs_option_t *opt_##name##_ptr DATA_SET_ATTR(_pfsopt) \
50 | = &opt_##name
51 |
52 | bool pfs_check_ival_normal(void *data);
53 | bool pfs_check_ival_switch(void *data);
54 |
55 | int pfs_option_handle(int sock, msg_header_t *mh, msg_option_t *msgopt);
56 |
57 | int pfs_option_init(const char *config_path);
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_paxos.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_PAXOS_H_
17 | #define _PFS_PAXOS_H_
18 |
19 | typedef struct pfs_mount pfs_mount_t;
20 |
21 | #define NAME_ID_SIZE 48
22 | #define DEFAULT_MAX_HOSTS 254
23 |
24 | #define PFS_LEADER_MAGIC 0xbabababa
25 | #define PFS_LEADER_CLEAR 0x11282016
26 | #define PFS_LEADER_VERSION_PRIMARY 0x00010000
27 | #define PFS_LEADER_VERSION_SECONDARY 0x00000002
28 | #define PFS_LEADER_UNUSED 0xb0
29 |
30 | typedef struct pfs_leader_record {
31 | uint32_t magic;
32 | uint32_t version;
33 | uint32_t flags;
34 | uint32_t sector_size;
35 | uint64_t num_hosts;
36 | uint64_t max_hosts;
37 |
38 | uint8_t unused[PFS_LEADER_UNUSED];
39 |
40 | /*
41 | * Fields for log. The txid range on log is (tail, head].
42 | * Tx upto tail have been committed to PBD.
43 | */
44 | uint64_t tail_txid; /* tx in range (tail, head] is */
45 | uint64_t head_txid; /* in log; (-max, tail] is on pbd */
46 | uint64_t tail_offset;
47 | uint64_t head_offset;
48 | uint64_t log_size;
49 | uint64_t head_lsn; /* sequence number; (0, head_lsn] */
50 | uint32_t checksum;
51 | } pfs_leader_record_t;
52 |
53 | /* LR size only relating to paxos */
54 | #define LR_PAXOS_SIZE offsetof(pfs_leader_record, tail_txid)
55 | #define LEADER_CHECKSUM_LEN offsetof(pfs_leader_record, checksum)
56 |
57 | #define PFS_OK 1
58 | #define PFS_NONE 0 /* unused */
59 | #define PFS_ERROR -201
60 | #define PFS_AIO_TIMEOUT -202
61 | #define PFS_WD_ERROR -203
62 |
63 | #define PFS_LEADER_EMAGIC -223
64 | #define PFS_LEADER_EVERSION -224
65 | #define PFS_LEADER_ESECTORSIZE -225
66 | #define PFS_LEADER_ENUMHOSTS -228
67 | #define PFS_LEADER_ECHECKSUM -229
68 |
69 | static inline uint32_t
70 | leader_checksum(struct pfs_leader_record *lr)
71 | {
72 | return crc32c((uint32_t)~1, (uint8_t *)lr, LEADER_CHECKSUM_LEN);
73 | }
74 |
75 | int pfs_leader_init(pfs_mount_t *mnt, int num_hosts, int max_hosts,
76 | int write_clear, size_t logsize);
77 | int pfs_leader_load(pfs_mount_t *mnt);
78 | void pfs_leader_unload(pfs_mount_t *mnt);
79 | int pfs_leader_write(pfs_mount_t *mnt, pfs_leader_record_t *nl);
80 | int pfs_leader_read(pfs_mount_t *mnt, pfs_leader_record_t *leader_ret);
81 |
82 | int paxos_hostid_local_lock(const char *pbdname, int hostid, const char *caller);
83 | void paxos_hostid_local_unlock(int fd);
84 |
85 | #endif
86 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_stat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef PFS_MOUNTSTAT_H
17 | #define PFS_MOUNTSTAT_H
18 |
19 | #include
20 | #include "pfs_stat_file_type.h"
21 |
22 | enum {
23 | MNT_STAT_BASE = -1,
24 | MNT_STAT_FILE_OPEN,
25 | MNT_STAT_FILE_OPEN_CREAT,
26 | MNT_STAT_FILE_READ,
27 | MNT_STAT_FILE_WRITE,
28 | MNT_STAT_FILE_LSEEK,
29 | MNT_STAT_FILE_FSTAT,
30 | MNT_STAT_FILE_TRUNCATE,
31 | MNT_STAT_FILE_FALLOCATE,
32 | MNT_STAT_FILE_UNLINK,
33 |
34 | MNT_STAT_DIR_DU,
35 | MNT_STAT_DIR_RENAME,
36 | MNT_STAT_DIR_REMOVE,
37 | MNT_STAT_DIR_OPENDIR,
38 | MNT_STAT_DIR_READDIR,
39 |
40 | MNT_STAT_SYNC_MOUNT,
41 | MNT_STAT_SYNC_INODE_RELOAD,
42 | MNT_STAT_SYNC_INODE_WAIT,
43 |
44 | MNT_STAT_JOURNAL_POLL,
45 | MNT_STAT_JOURNAL_REPLAY,
46 | MNT_STAT_JOURNAL_TRIM,
47 | MNT_STAT_JOURNAL_WRITE,
48 |
49 | MNT_STAT_CONTAINER_INODE_GET,
50 | MNT_STAT_CONTAINER_INODE_PUT,
51 |
52 | MNT_STAT_DEV_SLEEP,
53 | MNT_STAT_DEV_NOBUF,
54 | MNT_STAT_DEV_THROTTLE,
55 | MNT_STAT_DEV_READ,
56 | MNT_STAT_DEV_WRITE,
57 | MNT_STAT_DEV_TRIM,
58 |
59 | MNT_STAT_META_RDLOCK,
60 | MNT_STAT_META_WRLOCK,
61 |
62 | MNT_STAT_TYPE_COUNT
63 | };
64 |
65 | enum {
66 | MNT_STAT_API_NONE = -1,
67 | MNT_STAT_BACK_READ,
68 | MNT_STAT_BACK_WRITE,
69 | MNT_STAT_API_READ,
70 | MNT_STAT_API_WRITE,
71 | MNT_STAT_API_PREAD,
72 | MNT_STAT_API_PWRITE,
73 | MNT_STAT_TX_WRITE,
74 |
75 | MNT_STAT_API_OPEN,
76 | MNT_STAT_API_OPEN_CREAT,
77 | MNT_STAT_API_LSEEK,
78 | MNT_STAT_API_FSTAT,
79 | MNT_STAT_API_FTRUNCATE,
80 | MNT_STAT_API_FALLOCATE,
81 | MNT_STAT_API_UNLINK,
82 | MNT_STAT_API_STAT,
83 | MNT_STAT_API_TRUNCATE,
84 | MNT_STAT_API_CREAT,
85 | MNT_STAT_API_FSYNC,
86 | MNT_STAT_API_FDATASYNC,
87 |
88 | MNT_STAT_INODE_WAIT,
89 |
90 | MNT_STAT_FILE_SPEC_TYPE_COUNT
91 | };
92 |
93 | enum {
94 | MNT_STAT_TH_NCOUNT,
95 | MNT_STAT_TH_ACTIVE,
96 |
97 | MNT_STAT_TH_TYPE_COUNT
98 | };
99 |
100 | struct timeval;
101 | typedef struct admin_buf admin_buf_t;
102 |
103 | void pfs_mntstat_init();
104 | void pfs_mntstat_prepare(struct timeval* stat_begin, int api_type);
105 | void pfs_mntstat_set_file_type(int file_type);
106 | void pfs_mntstat_store(struct timeval* stat_begin, struct timeval* stat_end,
107 | int stat_type, bool file_type_spec, uint32_t size);
108 | void pfs_mntstat_reinit(struct timeval* stat_time);
109 | void pfs_mntstat_sync(struct timeval* stat_time);
110 | void pfs_mntstat_clear();
111 |
112 | void pfs_mntstat_nthreads_change(int delta);
113 |
114 | int pfs_mntstat_snap(admin_buf_t *ab, int64_t begin_time,
115 | int64_t time_range, char* file_type_pattern, int file_type_pattern_len);
116 | int pfs_mntstat_sample(char* sample_pattern, int sample_pattern_len);
117 |
118 | #define MNT_STAT_CLEAR() pfs_mntstat_clear()
119 |
120 | #define MNT_STAT_BEGIN() \
121 | struct timeval __stat_begin; \
122 | pfs_mntstat_prepare(&__stat_begin, MNT_STAT_API_NONE)
123 |
124 | #define MNT_STAT_END(type) \
125 | pfs_mntstat_store(&__stat_begin, NULL, type, false, 0)
126 |
127 | #define MNT_STAT_API_BEGIN(type) \
128 | struct timeval __stat_begin; \
129 | pfs_mntstat_prepare(&__stat_begin, type)
130 |
131 | #define MNT_STAT_API_END(type) do { \
132 | pfs_mntstat_store(&__stat_begin, NULL, type, true, 0); \
133 | MNT_STAT_CLEAR(); \
134 | } while(0)
135 |
136 | #define MNT_STAT_END_BANDWIDTH(type, size) \
137 | pfs_mntstat_store(&__stat_begin, NULL, type, true, (uint32_t)size)
138 |
139 | #define MNT_STAT_API_END_BANDWIDTH(type, size) do { \
140 | MNT_STAT_END_BANDWIDTH(type, size); \
141 | MNT_STAT_CLEAR(); \
142 | } while(0)
143 |
144 | #define MNT_STAT_END_VALUE(type, stat_begin) \
145 | pfs_mntstat_store(stat_begin, NULL, type, false, 0)
146 |
147 | #define MNT_STAT_END_VALUE_BANDWIDTH(type, stat_begin, size) \
148 | pfs_mntstat_store(stat_begin, NULL, type, false, (uint32_t)size)
149 |
150 | #endif //POLARDB_PFS_MOUNTSTAT_H
151 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_stat_file_type.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef PFS_FILE_TYPE_H
17 | #define PFS_FILE_TYPE_H
18 |
19 | #define FILE_COLOR_TYPE_NCOUNT 2
20 |
21 | #define PGSQL
22 |
23 | #ifndef PGSQL
24 |
25 | enum {
26 | FILE_PFS_INITED,
27 | FILE_PFS_PAXOS,
28 | FILE_PFS_JOUNAL,
29 | FILE_SYSTEM_SPACE,
30 | FILE_USER_SPACE,
31 | FILE_REPLICATION,
32 | FILE_CHECKPOINT,
33 | FILE_UNDO_LOG,
34 | FILE_REDO_LOG,
35 | FILE_BIN_LOG,
36 | FILE_PURGE,
37 | FILE_WRITE_BACK,
38 | FILE_SWAP_OUT,
39 | FILE_OTHERS,
40 |
41 | FILE_COLOR_0,
42 | FILE_COLOR_1,
43 | FILE_TYPE_COUNT
44 | };
45 |
46 | #else
47 |
48 | enum {
49 | FILE_PFS_INITED,
50 | FILE_PFS_PAXOS,
51 | FILE_PFS_JOUNAL,
52 | FILE_SYSTEM_SPACE,
53 | FILE_USER_SPACE,
54 | FILE_USER_SPACE_VM,
55 | FILE_USER_SPACE_FSM,
56 | FILE_CLOG,
57 | FILE_REDO_LOG,
58 | FILE_LOG_INDEX,
59 | FILE_FULL_PAGE,
60 |
61 | FILE_WRITE_BACK,
62 | FILE_SWAP_OUT,
63 | FILE_OTHERS,
64 |
65 | FILE_COLOR_0,
66 | FILE_COLOR_1,
67 | FILE_TYPE_COUNT
68 | };
69 |
70 | #endif
71 |
72 | int pfs_get_file_type(const char* file_path);
73 | int pfs_get_file_type_index_pat(char* file_type_pattern, int file_type_len,
74 | bool *filter);
75 | const char* pfs_get_file_type_name(int type);
76 | int pfs_get_file_type_index(const char* file_type, int file_type_len);
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_tls.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include
19 | #include
20 |
21 | #include "pfs_impl.h"
22 | #include "pfs_tls.h"
23 | #include "pfs_trace.h"
24 | #include "pfs_stat.h"
25 |
26 | /*
27 | * TLS manages txs, locks, and meta data exception handling.
28 | *
29 | * A tx is a description about the modification to meta data by one thread,
30 | * and is the unit to ensure aomicity of the modification. There are two
31 | * kinds of txs. One is write tx, that holds the modification by this node.
32 | * The other is replay tx, polled by log thread, that hold modification by
33 | * other node. TLS manages the write tx only.
34 | *
35 | * Locks are needed to access inode and meta data. All locks acquired by
36 | * the thread is saved in TLS, so that when meta data exception is encountered,
37 | * they can be released.
38 | *
39 | * Meta data exception means invalid meta data caused by replay tx is encountered
40 | * when traversing the meta data cache. In such a case, there is no simple and
41 | * clean way to handle it, since we may be deep in the dirtory entry tree. We
42 | * exploy longjmp to return to our starting point, alougth it is not elegant.
43 | */
44 |
45 | static pthread_key_t pfs_tls_key;
46 |
47 | static pfs_tls_t *
48 | pfs_tls_create()
49 | {
50 | pfs_tls_t *tls;
51 |
52 | tls = (pfs_tls_t *)pfs_mem_malloc(sizeof(*tls), M_TLS);
53 | PFS_ASSERT(tls != NULL);
54 |
55 | memset(tls, 0, sizeof(*tls));
56 | tls->tls_tx = NULL;
57 | tls->tls_req_ttl = 0;
58 | tls->tls_bdi = NULL;
59 | tls->tls_meta_locked = false;
60 |
61 | tls->tls_stat_ver = 0;
62 | tls->tls_stat_api_type = MNT_STAT_BASE;
63 | tls->tls_stat_file_type = FILE_PFS_INITED;
64 | pfs_mntstat_nthreads_change(1);
65 |
66 | for (int i = 0; i < PFS_MAX_NCHD; i++) {
67 | tls->tls_ioqueue[i] = NULL;
68 | }
69 | return tls;
70 | }
71 |
72 | static void
73 | pfs_tls_destroy(void *data)
74 | {
75 | pfs_tls_t *tls = (pfs_tls_t *)data;
76 | pfs_ioq_t *ioq;
77 |
78 | if (tls == NULL)
79 | return;
80 | /*
81 | * NOTE: never call get_current_tls() in this func!
82 | * or we will get a new tls, rather than the "tls" refered to
83 | */
84 | PFS_ASSERT(tls->tls_tx == NULL);
85 | for (int i = 0; i < PFS_MAX_NCHD; i++) {
86 | ioq = tls->tls_ioqueue[i];
87 | if (ioq) {
88 | ioq->ioq_destroy(ioq);
89 | tls->tls_ioqueue[i] = NULL;
90 | }
91 | }
92 | pfs_mem_free(tls, M_TLS);
93 | pfs_mntstat_nthreads_change(-1);
94 | }
95 |
96 | void __attribute__((constructor))
97 | init_pfs_tls()
98 | {
99 | int err;
100 |
101 | /*
102 | * Create the tls key even before entering into main, to
103 | * provide context for each comming thread.
104 | */
105 | err = pthread_key_create(&pfs_tls_key, pfs_tls_destroy);
106 | PFS_VERIFY(err == 0);
107 | }
108 |
109 | void
110 | pfs_tls_fini()
111 | {
112 | pthread_key_delete(pfs_tls_key);
113 | }
114 |
115 | pfs_tls_t *
116 | pfs_current_tls()
117 | {
118 | int err;
119 | pfs_tls_t *tls;
120 |
121 | tls = (pfs_tls_t *)pthread_getspecific(pfs_tls_key);
122 | if (tls == NULL) {
123 | tls = pfs_tls_create();
124 | err = pthread_setspecific(pfs_tls_key, tls);
125 | PFS_VERIFY(err == 0);
126 | }
127 | return tls;
128 | }
129 |
130 | pfs_ioq_t *
131 | pfs_tls_get_ioq(int devi, uint64_t epoch)
132 | {
133 | pfs_tls_t *tls = pfs_current_tls();
134 | pfs_ioq_t *ioq;
135 | PFS_VERIFY(tls != NULL);
136 | PFS_ASSERT(0 <= devi && devi < PFS_MAX_NCHD);
137 | /*
138 | * the expiring of ioq indicates the device is umounted,
139 | * reset it before returning to IO thread
140 | */
141 | ioq = tls->tls_ioqueue[devi];
142 | if (ioq != NULL && ioq->ioq_epoch != epoch) {
143 | ioq->ioq_destroy(ioq);
144 | tls->tls_ioqueue[devi] = NULL;
145 | }
146 | return tls->tls_ioqueue[devi];
147 | }
148 |
149 | void
150 | pfs_tls_set_ioq(int devi, pfs_ioq_t *ioq)
151 | {
152 | pfs_tls_t *tls = pfs_current_tls();
153 | PFS_VERIFY(tls != NULL);
154 | PFS_ASSERT(0 <= devi && devi < PFS_MAX_NCHD);
155 | /* overwrite is not allowed */
156 | PFS_ASSERT(tls->tls_ioqueue[devi] == NULL && ioq != NULL);
157 | tls->tls_ioqueue[devi] = ioq;
158 | }
159 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_trace.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_TRACE_H_
17 | #define _PFS_TRACE_H_
18 |
19 | #include
20 |
21 | #include "trace_pfs_ctx.h"
22 | #include "pfs_util.h"
23 |
24 | enum {
25 | PFS_TRACE_OFF = 0,
26 | PFS_TRACE_ERROR = 1,
27 | PFS_TRACE_WARN = 2,
28 | PFS_TRACE_INFO = 3,
29 | PFS_TRACE_DBG = 4,
30 | PFS_TRACE_DEBUG = PFS_TRACE_DBG,
31 | PFS_TRACE_VERB = 5,
32 | };
33 |
34 | void pfs_vtrace(int level, const char *fmt, ...);
35 |
36 | extern int64_t trace_plevel;
37 |
38 | #define pfs_trace(level, force, fmt,...) \
39 | do { \
40 | if (level <= trace_plevel || force) \
41 | pfs_vtrace(level, fmt, ##__VA_ARGS__); \
42 | } while(0)
43 |
44 | #define pfs_itrace(fmt,...) \
45 | do { \
46 | if (PFS_TRACE_INFO <= trace_plevel) \
47 | pfs_vtrace(PFS_TRACE_INFO, fmt, ##__VA_ARGS__); \
48 | } while(0)
49 |
50 | #define pfs_etrace(fmt,...) \
51 | do { \
52 | if (PFS_TRACE_ERROR <= trace_plevel) \
53 | pfs_vtrace(PFS_TRACE_ERROR, fmt, ##__VA_ARGS__); \
54 | } while(0)
55 |
56 | #define pfs_dbgtrace(fmt,...) \
57 | do { \
58 | if (PFS_TRACE_DBG <= trace_plevel) \
59 | pfs_vtrace(PFS_TRACE_DBG, fmt, ##__VA_ARGS__); \
60 | } while(0)
61 |
62 | typedef struct tracectl {
63 | const char *tc_file;
64 | const char *tc_func;
65 | int tc_line;
66 | int tc_level;
67 | int tc_enable;
68 | const char *tc_format;
69 | } tracectl_t;
70 |
71 | #define pfs_verbtrace(fmt, ...) do { \
72 | static tracectl_t _tc = { \
73 | __FILE__, __func__, __LINE__, \
74 | PFS_TRACE_DBG, \
75 | false, \
76 | fmt, \
77 | }; \
78 | static tracectl_t *_ptr DATA_SET_ATTR(_tracectl) = &_tc; \
79 | \
80 | if (_tc.tc_enable) \
81 | pfs_trace(_tc.tc_level, true, fmt, ##__VA_ARGS__); \
82 | } while (0)
83 |
84 | typedef struct msg_header msg_header_t;
85 | typedef struct msg_trace msg_trace_t;
86 |
87 | int pfs_trace_handle(int sock, msg_header_t *mh, msg_trace_t *tr);
88 | void pfs_trace_redirect(const char *pbdname, int hostid);
89 |
90 | typedef void pfs_log_func_t(const char *buf);
91 | extern pfs_log_func_t *pfs_log_functor;
92 |
93 | #endif
94 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_UTIL_H_
17 | #define _PFS_UTIL_H_
18 |
19 | #include
20 | #include
21 |
22 | uint32_t crc32c(uint32_t crc, const void *buf, size_t size);
23 | uint64_t roundup_power2(uint64_t val);
24 | int strncpy_safe(char *dst, const char *src, size_t n);
25 | uint32_t crc32c_compute(const void *buf, size_t size, size_t offset);
26 | uint64_t gettimeofday_us();
27 |
28 | #define DATA_SET_ATTR(set) \
29 | __attribute__((used)) \
30 | __attribute__((section(#set)))
31 |
32 | #define DATA_SET_DECL(type, set) \
33 | extern struct type *__start_##set[], *__stop_##set[];
34 |
35 | #define DATA_SET_FOREACH(var, set) \
36 | for (var = __start_##set; var < __stop_##set; var++)
37 |
38 | typedef struct oidvect {
39 | uint64_t *ov_buf;
40 | size_t ov_size;
41 | int ov_next;
42 | int32_t *ov_holeoff_buf;
43 | } oidvect_t;
44 | void oidvect_init(oidvect_t *ov);
45 | int oidvect_push(oidvect_t *ov, uint64_t val, int32_t holeoff);
46 | uint64_t oidvect_pop(oidvect_t *ov);
47 | void oidvect_fini(oidvect_t *ov);
48 | static inline int
49 | oidvect_begin(const oidvect_t *ov)
50 | {
51 | return 0;
52 | }
53 |
54 | static inline int
55 | oidvect_end(const oidvect_t *ov)
56 | {
57 | return ov->ov_next;
58 | }
59 |
60 | static inline uint64_t
61 | oidvect_get(const oidvect_t *ov, int indx)
62 | {
63 | return ov->ov_buf[indx];
64 | }
65 |
66 | static inline int32_t
67 | oidvect_get_holeoff(const oidvect_t *ov, int indx)
68 | {
69 | return ov->ov_holeoff_buf[indx];
70 | }
71 |
72 | typedef struct pfs_printer {
73 | void *pr_dest;
74 | int (*pr_func)(void *dest, const char *fmt, va_list ap);
75 | } pfs_printer_t;
76 | int pfs_printf(pfs_printer_t *pr, const char *fmt, ...);
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_version.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include "pfs_impl.h"
19 | #include "pfs_mount.h"
20 | #include "pfs_meta.h"
21 | #include "pfs_version.h"
22 | #include "pfs_devio.h"
23 |
24 | static uint64_t pfs_current_version = 2;
25 |
26 | /* table of features supported by all versions */
27 | static uint64_t pfs_feature_table[PFS_MAX_VERSION] = {
28 | [0] = PFS_FEATURE_NONE,
29 | [1] = PFS_FEATURE_BLKHOLE,
30 | [2] = PFS_FEATURE_BLKHOLE | PFS_FEATURE_EXTNAME,
31 | [3] = PFS_FEATURE_BLKHOLE | PFS_FEATURE_EXTNAME | PFS_FEATURE_PVTID,
32 | };
33 |
34 | int
35 | pfs_version_select(pfs_mount_t *mnt)
36 | {
37 | uint64_t diskver;
38 |
39 | diskver = mnt->mnt_disk_version =
40 | chunk_magic_version(mnt->mnt_chunkv[0]->ck_phyck->ck_magic);
41 |
42 | pfs_itrace("pfs version: current %llu vs on-disk %llu\n",
43 | pfs_current_version, diskver);
44 |
45 | if (pfs_current_version < diskver)
46 | ERR_RETVAL(ENOTSUP);
47 |
48 | /*
49 | * To avoid confusing DB instances, pfs tools always use the
50 | * on disk version. Whileas DB instances always run with the
51 | * version of the binary executable.
52 | */
53 | if (pfs_istool(mnt))
54 | mnt->mnt_run_version = diskver;
55 | else
56 | mnt->mnt_run_version = pfs_current_version;
57 | pfs_itrace("pfs run version: %llu\n", mnt->mnt_run_version);
58 | return 0;
59 | }
60 |
61 | int
62 | pfs_version_upgrade(pfs_mount_t *mnt)
63 | {
64 | pfs_chunk_phy_t *phyck = NULL;
65 |
66 | PFS_ASSERT(!pfs_istool(mnt) && pfs_writable(mnt));
67 | PFS_ASSERT(mnt->mnt_run_version == pfs_current_version);
68 |
69 | /*
70 | * A RW DB instance can upgrade version only if current
71 | * version is newer than the on disk one.
72 | */
73 | PFS_ASSERT(mnt->mnt_disk_version <= mnt->mnt_run_version);
74 | if (mnt->mnt_disk_version == mnt->mnt_run_version)
75 | return 0;
76 |
77 | pfs_itrace("pfs upgrade version from %llu to %llu\n",
78 | mnt->mnt_disk_version, mnt->mnt_run_version);
79 | phyck = mnt->mnt_chunkv[0]->ck_phyck;
80 | phyck->ck_magic = chunk_magic_make(0);
81 | phyck->ck_checksum = crc32c_compute(phyck, sizeof(*phyck),
82 | offsetof(struct pfs_chunk_phy, ck_checksum));
83 | return pfsdev_pwrite(mnt->mnt_ioch_desc, phyck, PBD_SECTOR_SIZE, 0);
84 | }
85 |
86 | bool
87 | pfs_version_has_features(pfs_mount_t *mnt, uint64_t features)
88 | {
89 | uint64_t rv = mnt->mnt_run_version;
90 |
91 | PFS_ASSERT(rv <= pfs_current_version);
92 | return (pfs_feature_table[rv] & features) == features;
93 | }
94 |
95 | bool
96 | pfs_version_has_features(uint64_t rv, uint64_t features)
97 | {
98 | PFS_ASSERT(rv <= pfs_current_version);
99 | return (pfs_feature_table[rv] & features) == features;
100 | }
101 |
102 |
103 | uint64_t
104 | pfs_version_get()
105 | {
106 | return pfs_current_version;
107 | }
108 |
--------------------------------------------------------------------------------
/src/pfs_core/pfs_version.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFS_VERSION_H_
17 | #define _PFS_VERSION_H_
18 |
19 | enum {
20 | PFS_FEATURE_NONE = 0,
21 | PFS_FEATURE_BLKHOLE = (1ULL << 0),
22 | PFS_FEATURE_EXTNAME = (1ULL << 1),
23 | PFS_FEATURE_PVTID = (1ULL << 2),
24 | };
25 |
26 | typedef struct pfs_chunk_phy pfs_chunk_phy_t;
27 | typedef struct pfs_mount pfs_mount_t;
28 | int pfs_version_select(pfs_mount_t *mnt);
29 | int pfs_version_upgrade(pfs_mount_t *mnt);
30 | bool pfs_version_has_features(pfs_mount_t *mnt, uint64_t features);
31 | bool pfs_version_has_features(uint64_t rv, uint64_t features);
32 | uint64_t pfs_version_get();
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/src/pfs_fuse/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | include_directories(
15 | ${PROJECT_SOURCE_DIR}/src/pfs_fuse/
16 | ${PROJECT_SOURCE_DIR}/src/pfs_sdk/
17 | ${PROJECT_SOURCE_DIR}/src/trace/include/
18 | )
19 |
20 | link_directories(
21 | ${LIBRARY_OUTPUT_PATH}
22 | )
23 |
24 | SET(SRC_LIST_FUSE pfs_fuse_main.cc
25 | pfs_fuse.cc
26 | )
27 |
28 | add_executable(pfs-fuse
29 | ${SRC_LIST_FUSE}
30 | )
31 |
32 | add_definitions(-D_FILE_OFFSET_BITS=64)
33 |
34 | set(CXXFLAGS
35 | -Werror=no-literal-suffix
36 | -g
37 | -O0
38 | )
39 |
40 | if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
41 | set(CXXFLAGS ${CXXFLAGS} -march=native)
42 | endif()
43 |
44 | target_link_libraries(pfs-fuse
45 | -Wl,--start-group
46 | -Wl,--no-as-needed
47 | pfsd
48 | pthread
49 | fuse
50 | -Wl,--end-group
51 | )
52 |
53 | add_dependencies(pfs-fuse
54 | pfsd
55 | )
56 |
--------------------------------------------------------------------------------
/src/pfs_fuse/pfs_fuse_main.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | extern int pfs_fuse_main(int argc, char *argv[]);
24 |
25 | int main(int argc, char *argv[])
26 | {
27 | int rv;
28 |
29 | rv = pfs_fuse_main(argc, argv);
30 | if(rv < 0){
31 | fprintf(stderr, "[pfsd fuse] pfs_fuse_main error, err=%d\n", rv);
32 | return -1;
33 | }
34 |
35 | return 0;
36 | }
37 |
--------------------------------------------------------------------------------
/src/pfs_sdk/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | include_directories(
15 | ${PROJECT_SOURCE_DIR}/src/pfsd/
16 | ${PROJECT_SOURCE_DIR}/src/pfs_sdk/
17 | ${PROJECT_SOURCE_DIR}/src/pfs_core/
18 | ${PROJECT_SOURCE_DIR}/src/trace/include/
19 | )
20 |
21 | link_directories(
22 | ${LIBRARY_OUTPUT_PATH}
23 | )
24 |
25 | SET(SRC_LIST_PFSD_SDK pfsd_common.cc
26 | pfsd_chnl.cc
27 | pfsd_chnl_shm.cc
28 | pfsd_memory.cc
29 | pfsd_sdk_file.cc
30 | pfsd_sdk_mount.cc
31 | pfsd_sdk.cc
32 | pfsd_shm.cc
33 | )
34 | # objects
35 | add_library(tmp_object_lib OBJECT ${SRC_LIST_PFSD_SDK})
36 | target_compile_definitions(tmp_object_lib PUBLIC PFSD_CLIENT)
37 | set_property(TARGET tmp_object_lib PROPERTY POSITION_INDEPENDENT_CODE ON)
38 |
39 | # lib pfsd
40 | add_library(pfsd STATIC
41 | $
42 | )
43 | add_dependencies(pfsd
44 | tmp_object_lib
45 | )
46 |
47 | # lib pfsd
48 | add_library(pfsd_test SHARED
49 | $
50 | )
51 | add_dependencies(pfsd_test
52 | tmp_object_lib
53 | )
54 | set_property(TARGET pfsd PROPERTY POSITION_INDEPENDENT_CODE ON)
55 | set_property(TARGET pfsd_test PROPERTY POSITION_INDEPENDENT_CODE ON)
56 |
57 | target_link_libraries(pfsd; rt;pthread;dl)
58 |
59 |
60 | # pfsd shm tool
61 | add_executable(pfsd_shm_tool
62 | pfsd_shm_tool.cc
63 | )
64 |
65 | add_dependencies(pfsd_shm_tool
66 | pfsd
67 | )
68 |
69 | target_link_libraries(pfsd_shm_tool; pfsd;rt;pthread)
70 |
71 | SET_TARGET_PROPERTIES(pfsd PROPERTIES LINKER_LANGUAGE CXX)
72 | SET_TARGET_PROPERTIES(pfsd_shm_tool PROPERTIES LINKER_LANGUAGE CXX)
73 |
--------------------------------------------------------------------------------
/src/pfs_sdk/pfsd_common.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "pfsd_common.h"
22 | #include "pfsd_proto.h"
23 |
24 | void
25 | pfsd_robust_mutex_init(pthread_mutex_t *mutex)
26 | {
27 | int r = 0;
28 |
29 | pthread_mutexattr_t attr;
30 | r |= pthread_mutexattr_init(&attr);
31 | r |= pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
32 | r |= pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
33 | r |= pthread_mutex_init(mutex, &attr);
34 | pthread_mutexattr_destroy(&attr);
35 | assert (r == 0);
36 | }
37 |
38 | int
39 | pfsd_robust_mutex_lock(pthread_mutex_t *mutex)
40 | {
41 | if (mutex == NULL)
42 | return -1;
43 |
44 | int r = pthread_mutex_lock(mutex);
45 | if (r == EOWNERDEAD)
46 | r = pthread_mutex_consistent(mutex);
47 |
48 | assert (r == 0);
49 | return r;
50 | }
51 |
52 | int
53 | pfsd_robust_mutex_trylock(pthread_mutex_t *mutex)
54 | {
55 | if (mutex == NULL)
56 | return -1;
57 |
58 | int r = pthread_mutex_trylock(mutex);
59 | if (r != 0 && r != EOWNERDEAD)
60 | return -1;
61 |
62 | if (r == EOWNERDEAD)
63 | r = pthread_mutex_consistent(mutex);
64 |
65 | assert (r == 0);
66 | return r;
67 | }
68 |
69 | int
70 | pfsd_robust_mutex_unlock(pthread_mutex_t *mutex)
71 | {
72 | if (mutex == NULL)
73 | return -1;
74 |
75 | int r = pthread_mutex_unlock(mutex);
76 | assert (r == 0);
77 | return 0;
78 | }
79 |
80 | long
81 | pfsd_tolong(void *ptr)
82 | {
83 | union {
84 | long v;
85 | void *p;
86 | } vp;
87 | vp.p = ptr;
88 | return vp.v;
89 | }
90 |
91 | bool
92 | pfsd_request_alive(pfsd_request_t *req)
93 | {
94 | //This is special for thread mode mount to avoid alive check that only
95 | //relies on fd close detection.
96 | if (req->connid % 2)
97 | return true;
98 | int r = kill(req->owner, 0);
99 | if (r == -1 && errno == ESRCH)
100 | return false;
101 |
102 | return true;
103 | }
104 |
105 | int
106 | pfsd_sdk_pbdname(const char *pbdpath, char *pbdname)
107 | {
108 | if (pbdpath == NULL || pbdpath[0] != '/')
109 | return -1;
110 |
111 | int i = 1;
112 | while (pbdpath[i] != '\0' && pbdpath[i] == '/')
113 | i++;
114 |
115 | if (pbdpath[i] == '\0')
116 | return -1;
117 |
118 | const char *slash = strchr(pbdpath + i, '/');
119 | if (slash == NULL)
120 | return -1;
121 |
122 | size_t len = slash - (pbdpath + i);
123 | if (len == 0)
124 | return -1;
125 | else if (len >= PFS_MAX_NAMELEN)
126 | return -1;
127 |
128 | strncpy(pbdname, pbdpath + i, len);
129 | pbdname[len] = 0;
130 | return 0;
131 | }
132 |
133 | int
134 | pfsd_write_pid(const char *pbdname) {
135 | char file[4*1024] = "";
136 | snprintf(file, sizeof(file), "/var/run/pfsd/pfsd_%s.pid", pbdname);
137 | int fd = ::open(file, O_RDWR | O_CREAT | O_CLOEXEC, 0644);
138 | if (fd < 0)
139 | return -errno;
140 |
141 | if (::flock(fd, LOCK_EX | LOCK_NB) != 0) {
142 | close(fd);
143 | return -errno;
144 | }
145 |
146 | char buf[128];
147 | size_t size = snprintf(buf, sizeof(buf), "%ld", (long)getpid());
148 | int ret = write(fd, buf, size);
149 | if (ret != (int)size) {
150 | close(fd);
151 | return -EIO;
152 | }
153 |
154 | return 0;
155 | }
156 |
157 | const char mon_name[][4] = {
158 | "Jan", "Feb", "Mar", "Apr", "May", "Jun",
159 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
160 | };
161 |
162 |
--------------------------------------------------------------------------------
/src/pfs_sdk/pfsd_memory.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include "pfsd_memory.h"
23 |
24 | typedef struct pfsd_memory {
25 | const char *mt_name;
26 | pthread_mutex_t mt_mtx;
27 | ssize_t mt_bytes_alloc;
28 | ssize_t mt_bytes_free;
29 | int64_t mt_count_alloc;
30 | int64_t mt_count_free;
31 | } pfsd_memtype_t;
32 |
33 | #define MEMTYPE_ENTRY(tag) [tag] = { #tag, PTHREAD_MUTEX_INITIALIZER, }
34 | static pfsd_memtype_t pfsd_mem_type[MD_NTYPE] = {
35 | MEMTYPE_ENTRY(MD_NONE),
36 | MEMTYPE_ENTRY(MD_DIR),
37 | MEMTYPE_ENTRY(MD_FILE),
38 | };
39 |
40 | static inline const char *
41 | memtype_name(int type)
42 | {
43 | return pfsd_mem_type[type].mt_name;
44 | }
45 |
46 | static void
47 | memtype_inc(int type, int count, size_t size)
48 | {
49 | pfsd_memtype_t *mt;
50 |
51 | assert (0 < type && type < MD_NTYPE);
52 |
53 | mt = &pfsd_mem_type[type];
54 | pthread_mutex_lock(&mt->mt_mtx);
55 | mt->mt_bytes_alloc += (ssize_t)size;
56 | mt->mt_count_alloc += count;
57 | pthread_mutex_unlock(&mt->mt_mtx);
58 | }
59 |
60 | static void
61 | memtype_dec(int type, size_t size)
62 | {
63 | pfsd_memtype_t *mt;
64 |
65 | assert (0 < type && type < MD_NTYPE);
66 |
67 | mt = &pfsd_mem_type[type];
68 | pthread_mutex_lock(&mt->mt_mtx);
69 | mt->mt_bytes_free += (ssize_t)size;
70 | mt->mt_count_free += 1;
71 | pthread_mutex_unlock(&mt->mt_mtx);
72 | }
73 |
74 | void *
75 | pfsd_mem_malloc(size_t size, int type)
76 | {
77 | void* ptr = malloc(size);
78 | if (ptr == NULL) {
79 | fprintf(stderr, "malloc failed: type %s, size %zu\n",
80 | memtype_name(type), size);
81 | return NULL;
82 | }
83 | memset(ptr, 0, size);
84 | memtype_inc(type, 1, malloc_usable_size(ptr));
85 |
86 | return ptr;
87 | }
88 |
89 | void *
90 | pfsd_mem_malloc_array(size_t nelem, size_t elemsize, int type)
91 | {
92 | return pfsd_mem_malloc(nelem * elemsize, type);
93 | }
94 |
95 | void
96 | pfsd_mem_free(void *ptr, int type)
97 | {
98 | if (ptr) {
99 | memtype_dec(type, malloc_usable_size(ptr));
100 | free(ptr);
101 | }
102 | }
103 |
104 | void *
105 | pfsd_mem_realloc(void *ptr, size_t newsize, int type)
106 | {
107 | void *newptr;
108 | int inc;
109 | size_t oldsize;
110 |
111 | if (ptr) {
112 | oldsize = malloc_usable_size(ptr);
113 | inc = 0;
114 | } else {
115 | oldsize = 0;
116 | inc = 1;
117 | }
118 | newptr = realloc(ptr, newsize);
119 | if (newptr) {
120 | memtype_inc(type, inc, malloc_usable_size(newptr) - oldsize);
121 | }
122 | return newptr;
123 | }
124 |
125 | int
126 | pfsd_mem_memalign(void **pp, size_t alignment, size_t size, int type)
127 | {
128 | int err;
129 |
130 | err = posix_memalign(pp, alignment, size);
131 | if (err == 0)
132 | memtype_inc(type, 1, malloc_usable_size(*pp));
133 | return err;
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/src/pfs_sdk/pfsd_sdk_file.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFSD_SDK_FILE_H_
17 | #define _PFSD_SDK_FILE_H_
18 |
19 | #include "pfs_impl.h"
20 |
21 | #include
22 | #include
23 |
24 | #include "pfsd_proto.h"
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 |
31 | bool pfsd_writable(int mnt_flags);
32 |
33 | typedef struct pfsd_file {
34 | pthread_rwlock_t f_rwlock;
35 | int f_fd;
36 | int f_flags;
37 | off_t f_offset;
38 |
39 | int64_t f_inode;
40 | int32_t f_refcnt; /* incr when be reading/writing */
41 | pfsd_chnl_payload_common_t f_common_pl;
42 | } pfsd_file_t;
43 |
44 | void pfsd_sdk_file_init();
45 |
46 | /* for sdk internal */
47 | pfsd_file_t *
48 | pfsd_alloc_file();
49 | void pfsd_free_file(pfsd_file_t*);
50 | int pfsd_alloc_fd(pfsd_file_t*);
51 | pfsd_file_t *
52 | pfsd_get_file(int fd, bool writelock);
53 | void pfsd_put_file(pfsd_file_t *file);
54 | int pfsd_close_file(pfsd_file_t *file);
55 | void pfsd_file_cleanup();
56 |
57 | /* dir */
58 | bool pfsd_chdir_begin();
59 | bool pfsd_chdir_end();
60 | int pfsd_dir_xsetwd(const char *path, size_t len);
61 | int pfsd_dir_xgetwd(char *buf, size_t len);
62 |
63 | /* name and cwd */
64 | const char *
65 | pfsd_name_init(const char *pbdpath, char *abspbdpath, size_t size);
66 | int pfsd_normalize_path(char *pbdpath);
67 |
68 | #ifdef __cplusplus
69 | }
70 | #endif
71 |
72 | #endif
73 |
74 |
--------------------------------------------------------------------------------
/src/pfs_sdk/pfsd_sdk_mount.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 |
17 | #ifndef PFSD_MOUNT_SHARE_H_
18 | #define PFSD_MOUNT_SHARE_H_
19 |
20 | void *pfs_mount_prepare(const char *cluster, const char *pbdname,
21 | int host_id, int flags);
22 | void pfs_mount_post(void *handle, int err);
23 | void pfs_mount_atfork_child(void *handle);
24 | void *pfs_remount_prepare(const char *cluster, const char *pbdname,
25 | int host_id, int flags);
26 | void pfs_remount_post(void *handle, int err);
27 |
28 | void pfs_umount_prepare(const char *pbdname, void *handle);
29 | void pfs_umount_post(const char *pbdname, void *handle);
30 |
31 | #endif //PFSD_MOUNT_SHARE_H_
32 |
--------------------------------------------------------------------------------
/src/pfs_tools/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | include_directories(
15 | ${PROJECT_SOURCE_DIR}/src/pfs_tools
16 | ${PROJECT_SOURCE_DIR}/src/pfs_core/
17 | ${PROJECT_SOURCE_DIR}/src/pfsd/
18 | ${PROJECT_SOURCE_DIR}/src/pfs_sdk/
19 | ${PROJECT_SOURCE_DIR}/src/trace/include/
20 | )
21 |
22 | link_directories(
23 | ${LIBRARY_OUTPUT_PATH}
24 | )
25 |
26 | add_executable(pfs-tools
27 | cmd_pfs.cc
28 | cmd_util.cc
29 | cmd_chunk.cc
30 | cmd_cp.cc
31 | cmd_dir.cc
32 | cmd_du.cc
33 | cmd_dumpfs.cc
34 | cmd_dumple.cc
35 | cmd_flushlog.cc
36 | cmd_fscp.cc
37 | cmd_fstrim.cc
38 | cmd_info.cc
39 | cmd_map.cc
40 | cmd_mkdir.cc
41 | cmd_mkfs.cc
42 | cmd_mount.cc
43 | cmd_rename.cc
44 | cmd_rm.cc
45 | cmd_usedinfo.cc
46 | )
47 | SET_TARGET_PROPERTIES(pfs-tools
48 | PROPERTIES OUTPUT_NAME pfs
49 | )
50 |
51 | add_definitions(-D__STDC_FORMAT_MACROS)
52 |
53 | set(CXXFLAGS
54 | -Werror=no-literal-suffix
55 | -g
56 | -O0
57 | )
58 |
59 | if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
60 | set(CXXFLAGS ${CXXFLAGS} -march=native)
61 | endif()
62 |
63 | target_link_libraries(pfs-tools
64 | -Wl,--start-group
65 | -Wl,--no-as-needed
66 | pfs
67 | pfsd
68 | pthread
69 | -Wl,--end-group
70 | )
71 |
72 | add_dependencies(pfs-tools
73 | pfs
74 | pfsd
75 | )
76 |
77 | configure_file(${PROJECT_SOURCE_DIR}/src/pfs_tools/pfsadm
78 | ${EXECUTABLE_OUTPUT_PATH}/pfsadm COPYONLY)
79 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_dir.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_du.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include "cmd_impl.h"
19 | #include "pfs_impl.h"
20 | #include "pfs_api.h"
21 |
22 | typedef struct opts_du {
23 | opts_common_t common;
24 | bool all; // show all files, not just directories
25 | int depth; // show depth, start from 0, remained value -1 means max-depth
26 | } opts_du_t;
27 |
28 | void
29 | usage_du()
30 | {
31 | printf("pfs du [options] pbdpath\n"
32 | " -a: show all files, not just directories\n"
33 | " -d: max depth, start from 0\n");
34 | }
35 |
36 | int
37 | getopt_du(int argc, char *argv[], cmd_opts_t *co)
38 | {
39 | int opt;
40 | opts_du_t *co_du = (opts_du_t *)co;
41 |
42 | co_du->all = false;
43 | co_du->depth = -1;
44 | optind = 1;
45 | while ((opt = getopt(argc, argv, "hd:a")) != -1) {
46 | switch (opt) {
47 | case 'd':
48 | co_du->depth = atoi(optarg);
49 | if (co_du->depth < 0) {
50 | fprintf(stderr, "du: invalid depth %d\n", co_du->depth);
51 | return -EINVAL;
52 | }
53 | break;
54 |
55 | case 'a':
56 | co_du->all = true;
57 | break;
58 |
59 | case 'h':
60 | default:
61 | return -1;
62 | }
63 | }
64 | return optind;
65 | }
66 |
67 | int
68 | cmd_du(int argc, char *argv[], cmd_opts_t *co)
69 | {
70 | int err;
71 | const char *pbdpath;
72 | opts_du_t* co_du = (opts_du_t *)co;
73 |
74 | if (argc != 1)
75 | return -1;
76 |
77 | pbdpath = argv[0];
78 | err = pfs_du(pbdpath, co_du->all, co_du->depth, NULL);
79 | return err;
80 | }
81 |
82 | PFSCMD_INFO(du, CMDF_MOUNT, PFS_RD, getopt_du, cmd_du, usage_du, "display disk usage statistics");
83 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_flushlog.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "cmd_impl.h"
28 | #include "pfs_impl.h"
29 | #include "pfs_api.h"
30 | #include "pfs_mount.h"
31 |
32 | void
33 | usage_flushlog()
34 | {
35 | printf("pfs flushlog pbdname\n");
36 | }
37 |
38 | int
39 | cmd_flushlog(int argc, char *argv[], cmd_opts_t *co)
40 | {
41 | int err;
42 | pfs_mount_t *mnt;
43 | const char *pbdname;
44 |
45 | if (argc != 1)
46 | return -1;
47 |
48 | pbdname = argv[0];
49 | mnt = pfs_get_mount(pbdname);
50 | PFS_ASSERT(mnt != NULL);
51 | err = pfs_mount_flush(mnt);
52 | pfs_put_mount(mnt);
53 |
54 | return (err < 0 ? -1 : 0);
55 | }
56 |
57 | PFSCMD_INFO(flushlog, CMDF_MOUNT, PFS_RDWR, getopt_none, cmd_flushlog, usage_flushlog, "flush log to pbd");
58 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_fstrim.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 |
19 | #include "pfs_api.h"
20 | #include "pfs_mount.h"
21 |
22 | #include "cmd_impl.h"
23 |
24 | typedef struct opts_fstrim {
25 | opts_common_t common;
26 | int64_t beginid; /* beginning ckid, default value is 0. */
27 | int64_t endid; /* end ckid, -1 means the last,
28 | discard range is [begin, end).*/
29 | bool all; /* discard all unused blocks, no matter
30 | whether it is discarded. */
31 | bool quiet; /* no warning tips. */
32 | } opts_fstrim_t;
33 |
34 | static struct option long_opts[] = {
35 | { "beginid", optional_argument, NULL, 'b' },
36 | { "endid", optional_argument, NULL, 'e' },
37 | { "all", optional_argument, NULL, 'a' },
38 | { "quiet", optional_argument, NULL, 'q' },
39 | { 0 },
40 | };
41 |
42 | void
43 | usage_fstrim()
44 | {
45 | printf("pfs fstrim [options] pbdname\n"
46 | " -b, --beginid: beginning chunk id to discard (default is the first chunk)\n"
47 | " -e, --endid: end chunk id to discard (default is the last chunk)\n"
48 | " -a, --all: discard all unused blocks (default is disabled)\n"
49 | " -q, --quiet: don't show warning tips (default is disabled)\n"
50 | "discard unused blocks of chunks in [beginckid, endckid),\n"
51 | "fstrim must be the ONLY ONE writer of current filesystem,\n"
52 | "hostid must be set explicitly by '-H'.\n");
53 | }
54 |
55 | int
56 | getopt_fstrim(int argc, char *argv[], cmd_opts_t *co)
57 | {
58 | int opt;
59 | opts_fstrim_t *co_fstrim = (opts_fstrim_t *)co;
60 |
61 | co_fstrim->beginid = 0;
62 | co_fstrim->endid = -1;
63 | co_fstrim->all = false;
64 | co_fstrim->quiet = false;
65 |
66 | optind = 1;
67 | while ((opt = getopt_long(argc, argv, "hb:e:aq", long_opts, NULL)) != -1) {
68 | switch (opt) {
69 | case 'b':
70 | co_fstrim->beginid = strtol(optarg, NULL, 10);
71 | break;
72 |
73 | case 'e':
74 | co_fstrim->endid = strtol(optarg, NULL, 10);
75 | break;
76 |
77 | case 'a':
78 | co_fstrim->all = true;
79 | break;
80 |
81 | case 'q':
82 | co_fstrim->quiet = true;
83 | break;
84 |
85 | case'h':
86 | default:
87 | return -1;
88 | }
89 | }
90 | return optind;
91 | }
92 |
93 | int
94 | cmd_fstrim(int argc, char *argv[], cmd_opts_t *co)
95 | {
96 | #define WARNTIME 3
97 | int err;
98 | const char *pbdname;
99 | pfs_mount_t *mnt;
100 | opts_fstrim_t *co_fstrim = (opts_fstrim_t *)co;
101 |
102 | if (argc != 1) {
103 | usage_fstrim();
104 | exit(EINVAL);
105 | }
106 | pbdname = argv[0];
107 | pfs_trace_redirect(pbdname, 0);
108 |
109 | if (!co_fstrim->quiet) {
110 | printf("Make sure that fstrim is the ONLY ONE writer on"
111 | " current device %s. sleep %ds.\n", pbdname, WARNTIME);
112 | sleep(WARNTIME);
113 | }
114 |
115 | /*
116 | * TODO:
117 | * In a POLARDB cluster, only one node attaches PBD with
118 | * Read/Write permission. To make sure fstrim is the only
119 | * one writer of cluster, it uses iochannel 0 as same as
120 | * MySQL. Meanwhile, user must set hostid explicitly.
121 | */
122 | err = pfs_mount(co->co_common.cluster, pbdname, co->co_common.hostid,
123 | PFS_RDWR | PFS_TOOL | MNTFLG_DISCARD_BYFORCE);
124 | if (err < 0)
125 | return err;
126 |
127 | mnt = pfs_get_mount(pbdname);
128 | PFS_VERIFY(mnt != NULL);
129 |
130 | err = pfs_mount_fstrim(mnt, co_fstrim->beginid, co_fstrim->endid,
131 | co_fstrim->all);
132 | if (err < 0)
133 | ERR_GOTO(EIO, umount);
134 | err = 0;
135 |
136 | umount:
137 | pfs_put_mount(mnt);
138 | pfs_umount(pbdname);
139 | return err;
140 | }
141 |
142 | PFSCMD_INFO(fstrim, 0, PFS_RDWR, getopt_fstrim, cmd_fstrim, usage_fstrim, "trim filesystem");
143 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_info.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "cmd_impl.h"
31 | #include "pfs_impl.h"
32 | #include "pfs_api.h"
33 | #include "pfs_mount.h"
34 |
35 | typedef struct opts_info {
36 | opts_common_t common;
37 | int depth; /* anode's depth */
38 | } opts_info_t;
39 |
40 | void
41 | usage_info()
42 | {
43 | printf("pfs info [options] pbdname\n"
44 | " -d: info dump depth, start from 1\n");
45 | }
46 |
47 | int
48 | getopt_info(int argc, char *argv[], cmd_opts_t *co)
49 | {
50 | int opt;
51 | opts_info_t *co_info = (opts_info_t *)co;
52 |
53 | co_info->depth = 1;
54 | optind = 1;
55 | while ((opt = getopt(argc, argv, "hd:")) != -1) {
56 | switch (opt) {
57 | case 'd':
58 | co_info->depth = atoi(optarg);
59 | break;
60 |
61 | case 'h':
62 | default:
63 | return -1;
64 | }
65 | }
66 | return optind;
67 | }
68 |
69 |
70 | int
71 | cmd_info(int argc, char *argv[], cmd_opts_t *co)
72 | {
73 | int err;
74 | const char *pbdname;
75 | opts_info_t *co_info = (opts_info_t *)co;
76 | pfs_mount_t *mnt;
77 |
78 | if (argc < 1)
79 | return -1;
80 | if (co_info->depth <= 0)
81 | return -1;
82 |
83 | pbdname = argv[0];
84 |
85 | mnt = pfs_get_mount(pbdname);
86 | if (mnt == NULL) {
87 | pfs_etrace("cant get mount %s\n", pbdname);
88 | ERR_RETVAL(ENODEV);
89 | }
90 |
91 | err = pfs_meta_info(mnt, co_info->depth, NULL);
92 |
93 | pfs_put_mount(mnt);
94 | return err;
95 | }
96 |
97 | PFSCMD_INFO(info, CMDF_MOUNT, PFS_RD, getopt_info, cmd_info, usage_info, "show pfs meta info");
98 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_map.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "cmd_impl.h"
22 | #include "pfs_api.h"
23 | #include "pfs_impl.h"
24 |
25 | typedef struct opts_map {
26 | opts_common_t common;
27 | off_t offset; /* file offset */
28 | } opts_map_t;
29 |
30 | static struct option long_opts[] = {
31 | { "offset", optional_argument, NULL, 'o' },
32 | { 0 },
33 | };
34 |
35 | void
36 | usage_map()
37 | {
38 | printf("pfs map [options] pbdpath\n"
39 | " -o, --offset: offset(default is -1)\n"
40 | "dump the block index of specified file\n"
41 | "-------------------------\n"
42 | "blkidx: block index in current file\n"
43 | "offset: block offset in current file\n"
44 | "btno: blktag number, 0 represents file hole\n"
45 | "blkno: bock number, range in [0, %d * nchunk)\n"
46 | "chunk: block's chunk number, starts from 0\n"
47 | "bda: block absoulte device address in disk, bda = blkno * %d\n"
48 | "cka: block relative address in the chunk, cka = bda - chunk * %ld\n",
49 | PFS_NBT_PERCHUNK, PFS_BLOCK_SIZE, (long)PBD_CHUNK_SIZE);
50 | }
51 |
52 | int
53 | getopt_map(int argc, char *argv[], cmd_opts_t *co)
54 | {
55 | int opt;
56 | opts_map_t *co_map = (opts_map_t *)co;
57 |
58 | co_map->offset = -1;
59 |
60 | optind = 1;
61 | while ((opt = getopt_long(argc, argv, "ho:", long_opts, NULL)) != -1) {
62 | switch (opt) {
63 | case 'o':
64 | co_map->offset = strtol(optarg, NULL, 10);
65 | break;
66 |
67 | case'h':
68 | default:
69 | return -1;
70 | }
71 | }
72 |
73 | return optind;
74 | }
75 |
76 | int
77 | cmd_map(int argc, char *argv[], cmd_opts_t *co)
78 | {
79 | int err, i, count, fd = -1;
80 | opts_map_t *co_map = (opts_map_t *)co;
81 | const char *pbdpath = NULL;
82 | fmap_entry_t *fmap, *fmapv = NULL;
83 | struct stat st;
84 | uint64_t bda;
85 | off_t off;
86 |
87 | if (argc != 1) {
88 | usage_map();
89 | exit(EINVAL);
90 | }
91 | pbdpath = argv[0];
92 |
93 | fd = pfs_open(pbdpath, O_RDONLY, 0644);
94 | if (fd < 0)
95 | return fd;
96 |
97 | err = pfs_fstat(fd, &st);
98 | if (err < 0)
99 | goto out;
100 |
101 | if (!S_ISREG(st.st_mode)) {
102 | pfs_etrace("%s is a directory\n", pbdpath);
103 | ERR_GOTO(EISDIR, out);
104 | }
105 |
106 | if (co_map->offset >= st.st_size) {
107 | pfs_etrace("offset %ld >= filesize %ld\n", co_map->offset,
108 | st.st_size);
109 | ERR_GOTO(EINVAL, out);
110 | }
111 |
112 | if (co_map->offset >= 0) {
113 | off = co_map->offset;
114 | count = 1;
115 | } else {
116 | off = 0;
117 | count = howmany(st.st_size, st.st_blksize);
118 | }
119 |
120 | fmapv = (fmap_entry_t *)malloc(count * sizeof(fmap_entry_t));
121 | if (fmapv == NULL)
122 | ERR_GOTO(ENOMEM, out);
123 | memset(fmapv, 0, count * sizeof(fmap_entry_t));
124 |
125 | for (i = 0; i < count; i++) {
126 | fmapv[i].f_off = off;
127 | off += st.st_blksize;
128 | }
129 |
130 | err = pfs_fmap(fd, fmapv, count);
131 | if (err < 0) {
132 | pfs_etrace("fmap failed, err=%d, errno=%d\n", err, errno);
133 | goto out;
134 | }
135 |
136 | printf("filesize(B): %-8ld\tblksize(B): %-8ld\n", st.st_size, (long int)st.st_blksize);
137 | printf("------------------\n");
138 | printf("blkidx\t\toffset\t\tbtno\t\tbtholeoff\t\tblkno\t\tchunk\t\tbda\t\tcka\n");
139 | for (i = 0; i < count; i++) {
140 | fmap = &fmapv[i];
141 | bda = fmap->f_blkno * st.st_blksize +
142 | (fmap->f_off & (st.st_blksize - 1));
143 |
144 | printf("%-8ld\t%-8ld\t%-8ld\t%-8d\t\t%-8ld\t%-8ld\t%-8lu\t%-8ld\n",
145 | fmap->f_off / st.st_blksize, fmap->f_off, fmap->f_btno,
146 | fmap->f_bthoff, fmap->f_blkno, fmap->f_ckid, bda,
147 | (long)(bda - fmap->f_ckid * PBD_CHUNK_SIZE));
148 | }
149 |
150 | pfs_close(fd);
151 | free(fmapv);
152 | return 0;
153 |
154 | out:
155 | if (fd >= 0)
156 | pfs_close(fd);
157 |
158 | free(fmapv);
159 | return err;
160 | }
161 |
162 | PFSCMD_INFO(map, CMDF_MOUNT, PFS_RD, getopt_map, cmd_map, usage_map, "dump a file's block index");
163 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_mkdir.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "cmd_impl.h"
30 | #include "pfs_impl.h"
31 | #include "pfs_api.h"
32 |
33 | typedef struct opts_mkdir {
34 | opts_common_t common;
35 | bool parents; /* make parent directories as needed */
36 | } opts_mkdir_t;
37 |
38 | void
39 | usage_mkdir()
40 | {
41 | printf("pfs mkdir [options] pbdpath\n"
42 | " -p: make parent directories as needed\n");
43 | }
44 |
45 | int
46 | getopt_mkdir(int argc, char *argv[], cmd_opts_t *co)
47 | {
48 | int opt;
49 | opts_mkdir_t *co_mkdir = (opts_mkdir_t *)co;
50 |
51 | co_mkdir->parents = false;
52 |
53 | optind = 1;
54 | while ((opt = getopt(argc, argv, "hp")) != -1) {
55 | switch (opt) {
56 | case 'p':
57 | co_mkdir->parents = true;
58 | break;
59 |
60 | case 'h':
61 | default:
62 | return -1;
63 | }
64 | }
65 | return optind;
66 | }
67 |
68 | static char *
69 | findroot(char *pbdpath)
70 | {
71 | char *ptr = pbdpath;
72 | uint32_t nslash = 0;
73 |
74 | for (; *ptr != '\0' && nslash < 2; ptr++) {
75 | if (*ptr == '/')
76 | nslash++;
77 | }
78 |
79 | if (nslash == 2)
80 | return ptr;
81 | else
82 | return NULL;
83 | }
84 |
85 | int
86 | do_mkdir(char *path, bool parents)
87 | {
88 | int err;
89 | char *ptr;
90 |
91 | if (parents == false) {
92 | return pfs.mkdir(path, 0);
93 | } else {
94 | ptr = findroot(path);
95 | if (ptr == NULL)
96 | return -EINVAL;
97 |
98 | for (; ptr && *ptr != '\0'; ptr++) {
99 | if (*ptr == '/') {
100 | *ptr = '\0';
101 | err = pfs.mkdir(path, 0);
102 | *ptr = '/';
103 |
104 | if (err < 0 && errno != EEXIST)
105 | return err;
106 | }
107 | }
108 |
109 | err = pfs.mkdir(path, 0);
110 | if (err < 0)
111 | return (errno == EEXIST ? 0 : err);
112 | else
113 | return 0;
114 | }
115 | }
116 |
117 | int
118 | cmd_mkdir(int argc, char *argv[], cmd_opts_t *co)
119 | {
120 | int err;
121 | char pbdpath[PFS_MAX_PATHLEN];
122 | opts_mkdir_t *co_mkdir = (opts_mkdir_t *)co;
123 |
124 | if (argc != 1)
125 | return -1;
126 |
127 | pbdpath_copy(pbdpath, argv[0], sizeof(pbdpath));
128 | err = do_mkdir(pbdpath, co_mkdir->parents);
129 | if (err < 0)
130 | return -1;
131 |
132 | return 0;
133 | }
134 |
135 | PFSCMD_INFO(mkdir, CMDF_MOUNT_EX, PFS_RDWR, getopt_mkdir, cmd_mkdir, usage_mkdir, "create dir");
136 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_rename.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 |
18 | #include "cmd_impl.h"
19 | #include "pfs_api.h"
20 |
21 | void
22 | usage_rename()
23 | {
24 | printf(
25 | " rename directory or file" "\n"
26 | " $ pfs rename /1/mydir /1/mydir_newname" "\n");
27 | }
28 |
29 | int
30 | cmd_rename(int argc, char *argv[], cmd_opts_t *co)
31 | {
32 | int err;
33 | char oldpbdpath[PFS_MAX_PATHLEN] = {0};
34 | char newpbdpath[PFS_MAX_PATHLEN] = {0};
35 |
36 | if (argc != 2)
37 | return -1;
38 |
39 | pbdpath_copy(oldpbdpath, argv[0], sizeof(oldpbdpath));
40 | pbdpath_copy(newpbdpath, argv[1], sizeof(newpbdpath));
41 |
42 | err = pfs.rename(oldpbdpath, newpbdpath);
43 | if (err < 0)
44 | return -1;
45 |
46 | return 0;
47 | }
48 |
49 | PFSCMD_INFO(rename, CMDF_MOUNT_EX, PFS_RDWR, getopt_none, cmd_rename, usage_rename, "rename file");
50 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_usedinfo.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "pfs_impl.h"
24 | #include "pfs_api.h"
25 | #include "pfs_meta.h"
26 | #include "pfs_mount.h"
27 | #include "cmd_impl.h"
28 |
29 |
30 | typedef struct opts_usedinfo {
31 | opts_common_t common;
32 | int type;
33 | int beginchunk;
34 | int endchunk;
35 | } opts_usedinfo_t;
36 |
37 | void
38 | usage_usedinfo()
39 | {
40 | printf("pfs usedinfo [-h] -t [b | i | d] [-b begin_chunk] "
41 | "[-e end_chunk] pbdname\n"
42 | " -h: show help\n"
43 | " -t: used blktag, inode, direntry\n"
44 | " -b: begin chunk\n"
45 | " -e: end chunk\n");
46 | }
47 |
48 | int
49 | getopt_usedinfo(int argc, char *argv[], cmd_opts *co)
50 | {
51 | int opt;
52 | opts_usedinfo_t *co_usedinfo = (opts_usedinfo_t *)co;
53 |
54 | co_usedinfo->type = -1;
55 | co_usedinfo->beginchunk = -1;
56 | co_usedinfo->endchunk = -1;
57 |
58 | optind = 1;
59 | while ((opt = getopt(argc, argv, "ht:b:e:")) != -1) {
60 | switch (opt) {
61 | case 't':
62 | co_usedinfo->type =
63 | optarg[0] == 'b' ? MT_BLKTAG :
64 | optarg[0] == 'i' ? MT_INODE :
65 | optarg[0] == 'd' ? MT_DIRENTRY : -1;
66 | break;
67 |
68 | case 'b':
69 | co_usedinfo->beginchunk = atoi(optarg);
70 | break;
71 |
72 | case 'e':
73 | co_usedinfo->endchunk = atoi(optarg);
74 | break;
75 |
76 | case 'h':
77 | default:
78 | return -1;
79 | }
80 | }
81 |
82 | return optind;
83 | }
84 |
85 | int
86 | cmd_usedinfo(int argc, char *argv[], cmd_opts *co)
87 | {
88 | opts_usedinfo_t *co_usedinfo = (opts_usedinfo_t *)co;
89 | pfs_mount_t *mnt;
90 | int ckid[2];
91 |
92 | if (argc != 1 || co_usedinfo->type < 0)
93 | return -1;
94 |
95 | mnt = pfs_get_mount(argv[0]);
96 | ckid[0] = co_usedinfo->beginchunk;
97 | ckid[1] = co_usedinfo->endchunk;
98 | pfs_dump_used(mnt, co_usedinfo->type, ckid);
99 |
100 | pfs_put_mount(mnt);
101 | return 0;
102 | }
103 |
104 | PFSCMD_INFO(usedinfo, CMDF_MOUNT, PFS_RD, getopt_usedinfo, cmd_usedinfo,
105 | usage_usedinfo, "dump pbd info or data");
106 |
--------------------------------------------------------------------------------
/src/pfs_tools/cmd_util.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "pfs_api.h"
22 | #include "pfs_namei.h"
23 | #include "pfs_trace.h"
24 | #include "pfs_util.h"
25 |
26 | #include "cmd_impl.h"
27 |
28 | void
29 | pbdpath_copy(char *dst, const char *src, size_t len)
30 | {
31 | if (strncpy_safe(dst, src, len) < 0) {
32 | fprintf(stderr, "too long pbdpath\n");
33 | exit(ENAMETOOLONG);
34 | }
35 | }
36 |
37 | void
38 | pbdpath_gen(const char *pbdname, const char *filepath, char *buf, size_t len)
39 | {
40 | if (snprintf(buf, len, "/%s/%s", pbdname, filepath) >= (int)len) {
41 | pfs_etrace("too long path %s/%s\n", pbdname, filepath);
42 | exit(ENAMETOOLONG);
43 | }
44 | }
45 |
46 | void
47 | pbdpath_join(const char *pbdpath, const char *filepath, char *buf, size_t len)
48 | {
49 | if (snprintf(buf, len, "%s/%s", pbdpath, filepath) >= (int)len) {
50 | pfs_etrace("too long path %s/%s\n", pbdpath, filepath);
51 | exit(ENAMETOOLONG);
52 | }
53 | }
54 |
55 | /*
56 | * pbdpath_split
57 | *
58 | * Split valid pbdpath into pbdname & path
59 | * Caller should guarantee that buffer is large enough
60 | */
61 | void
62 | pbdpath_split(const char *pbdpath, char *pbdnamebuf, size_t nbuflen,
63 | char *pathbuf, size_t pbuflen)
64 | {
65 | nameinfo_t ni;
66 |
67 | if (pfs_namei_init(&ni, pbdpath, 0) != 0) {
68 | pfs_etrace("invalid pbdpath %s\n", pbdpath);
69 | exit(EINVAL);
70 | }
71 |
72 | if (strncpy_safe(pbdnamebuf, ni.ni_pbd, nbuflen) < 0) {
73 | pfs_etrace("too long pbdname %s\n", ni.ni_pbd);
74 | exit(ENAMETOOLONG);
75 | }
76 | if (pathbuf == NULL)
77 | return;
78 |
79 | if (strncpy_safe(pathbuf, ni.ni_path, pbuflen) < 0) {
80 | pfs_etrace("too long path %s\n", ni.ni_path);
81 | exit(ENAMETOOLONG);
82 | }
83 | }
84 |
85 | int
86 | pbdpath_traverse(const char *pbdpath, const char *filter, const user_action_t *action)
87 | {
88 | int err, err2;
89 | char filepath[PFS_MAX_PATHLEN];
90 | struct dirent *de;
91 | struct dirent debuf;
92 | DIR *dir;
93 |
94 | dir = pfs.opendir(pbdpath);
95 | if (dir == NULL)
96 | return -1;
97 |
98 | err2 = 0;
99 | while ((err = pfs.readdir_r(dir, &debuf, &de)) == 0 && de) {
100 | PFS_ASSERT(de->d_name[0] != '\0');
101 |
102 | if (filter && fnmatch(filter, de->d_name, FNM_NOESCAPE) != 0)
103 | continue;
104 |
105 | /* special skip journal and paxos */
106 | if (de->d_ino == PAXOS_FILE_MONO ||
107 | de->d_ino == JOURNAL_FILE_MONO) {
108 | pfs_itrace("skip paxos/journal file during path traversal\n");
109 | continue;
110 | }
111 |
112 | pbdpath_join(pbdpath, de->d_name, filepath, sizeof(filepath));
113 | switch (action->user_nargs) {
114 | case 0: {
115 | typedef int (*user_func_t)(const char*);
116 | user_func_t f = (user_func_t )action->user_func;
117 | err2 |= f(filepath);
118 | break;
119 | }
120 |
121 | case 1: {
122 | typedef int (*user_func_t)(const char*, int);
123 | user_func_t f = (user_func_t )action->user_func;
124 | err2 |= f(filepath, action->user_arg0);
125 | break;
126 | }
127 |
128 | case 2: {
129 | typedef int (*user_func_t)(const char*, int, int);
130 | user_func_t f = (user_func_t )action->user_func;
131 | err2 |= f(filepath, action->user_arg0, action->user_arg1);
132 | break;
133 | }
134 |
135 | default:
136 | fprintf(stderr, "wrong nargs %d, should <= 2\n", action->user_nargs);
137 | break;
138 | }
139 | }
140 |
141 | pfs.closedir(dir);
142 |
143 | err = (err != 0 || err2 != 0) ? -1 : 0;
144 | return err;
145 | }
146 |
--------------------------------------------------------------------------------
/src/pfs_tools/pfstemp.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "pfs_api.h"
22 | #include "pfs_trace.h"
23 | #include "pfs_mount.h"
24 |
25 | static void
26 | usage(void)
27 | {
28 | printf("usage: sudo ./pfstemp pbdname\n");
29 | }
30 |
31 |
32 | int
33 | main(int argc, char *argv[])
34 | {
35 | char pbdname[PFS_MAX_PATHLEN] = {'\0'};
36 | char path[4096];
37 | int i, ret = 0;
38 | const char *filename[] = {
39 | "vim",
40 | "vimdiff",
41 | "gcc",
42 | NULL,
43 | };
44 |
45 | if (argc < 2) {
46 | usage();
47 | return -1;
48 | }
49 |
50 | strncpy(pbdname, argv[1], PFS_MAX_PATHLEN);
51 | ret = pfs_mount("polarstore", pbdname, 1, PFS_RDWR);
52 | if (ret < 0) {
53 | pfs_etrace("Error in mount pbd %s\n", pbdname);
54 | return 0;
55 | }
56 |
57 | for (i = 0; filename[i]; i++) {
58 | snprintf(path, sizeof(path), "/%s/%s", pbdname, filename[i]);
59 | pfs_open(path, 0, 0);
60 | }
61 |
62 | while (1) {
63 | pfs_dbgtrace("sleeping 2 seconds\n");
64 | sleep(2);
65 | }
66 | return 0;
67 | }
68 |
--------------------------------------------------------------------------------
/src/pfs_tools/pfsthread.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "pfs_api.h"
28 | #include "pfs_trace.h"
29 | #include "pfs_devio.h"
30 |
31 | #define THREAD_MAX 100
32 |
33 | #define TOTAL_LENGTH (512*1024*1024)
34 | static char *data_buf;
35 | static uint32_t nfile_per_thread;
36 | static uint32_t hostid;
37 |
38 | typedef struct ThreadArg {
39 | char pbdname[PFS_MAX_PBDLEN];
40 | int tid;
41 | uint32_t filecnt;
42 | } ThreadArg_t;
43 |
44 | void *thread_run(void *arg);
45 |
46 | void
47 | umount(const char *pbdname)
48 | {
49 | pfs_umount(pbdname);
50 | }
51 |
52 | int
53 | mount(const char *pbdname)
54 | {
55 | int err = 0;
56 |
57 | err = pfs_mount(CL_DEFAULT, pbdname, hostid, PFS_RDWR);
58 | if (err != 0)
59 | printf("Mount failed\n");
60 |
61 | return err;
62 | }
63 |
64 | int main(int argc, char **argv)
65 | {
66 | int err;
67 | uint32_t i;
68 | char pbdname[PFS_MAX_PBDLEN] = {'\0'};
69 | pthread_t children[THREAD_MAX];
70 | ThreadArg_t children_arg[THREAD_MAX] = {0};
71 | uint32_t threadcnt;
72 |
73 | if (argc < 5) {
74 | printf("Usage: %s hostid pbdname thread_count nfile_per_thread\n", argv[0]);
75 | return -1;
76 | }
77 |
78 | data_buf = (char *)malloc(TOTAL_LENGTH);
79 | if(data_buf == NULL) {
80 | printf("create data buffer faield\n");
81 | return -1;
82 | }
83 | for(uint32_t i = 0; i < TOTAL_LENGTH/sizeof(uint64_t); i++) {
84 | *((uint64_t *)data_buf + 1) = rand();
85 | }
86 |
87 | hostid = strtoul(argv[1], NULL, 10);
88 | sprintf(pbdname, "%s", argv[2]);
89 | threadcnt = strtoul(argv[3], NULL, 10);
90 | threadcnt = threadcnt > THREAD_MAX ? THREAD_MAX : threadcnt;
91 |
92 | nfile_per_thread = strtoul(argv[4], NULL, 10);
93 |
94 | printf("Hostid: %u, Thread count: %u, file number per thread: %u\n", hostid, threadcnt, nfile_per_thread);
95 |
96 | err = mount(pbdname);
97 | if (err < 0)
98 | return -1;
99 |
100 | for (i = 0; i < threadcnt; ++i) {
101 | sprintf(children_arg[i].pbdname, "%s", pbdname);
102 | children_arg[i].tid = i;
103 | children_arg[i].filecnt = 0;
104 | pthread_create(&children[i], NULL, thread_run, (void *)&children_arg[i]);
105 | }
106 |
107 | for (i = 0; i < threadcnt; ++i) {
108 | pthread_join(children[i], NULL);
109 | }
110 |
111 | umount(pbdname);
112 | printf("Test Finish\n");
113 |
114 | uint32_t filecnt = 0;
115 | for (i = 0; i < threadcnt; ++i)
116 | filecnt += children_arg[i].filecnt;
117 | printf("Create file count %u\n", filecnt);
118 |
119 | return 0;
120 | }
121 |
122 | void *thread_run(void *arg)
123 | {
124 | uint32_t i;
125 | int fd;
126 | char pbdpath[PFS_MAX_PATHLEN] = {'\0'};
127 | ThreadArg_t *targ = (ThreadArg_t *)arg;
128 |
129 |
130 | for (i = 0; i < nfile_per_thread; ++i) {
131 | sprintf(pbdpath, "/%s/%u-%d", targ->pbdname, hostid, targ->tid * 10000 + i);
132 | do {
133 | errno = 0;
134 | fd = pfs_open(pbdpath, O_CREAT, 0);
135 | } while (fd < 0 && errno == EAGAIN);
136 | if (fd < 0) {
137 | switch (errno) {
138 | case EPFS_FILE_2MANY:
139 | printf("%d: Too many files in PBD\n", targ->tid);
140 | break;
141 | case EMFILE:
142 | printf("%d: Too many files opened in PBD\n", targ->tid);
143 | break;
144 | default:
145 | printf("%d: errno=%s\n", targ->tid, strerror(errno));
146 | break;
147 | }
148 | goto exit_thread;
149 | } else {
150 | printf("Create file %s\n", pbdpath);
151 |
152 | pfs_pwrite(fd, data_buf, TOTAL_LENGTH, 0);
153 |
154 | pfs_close(fd);
155 | ++targ->filecnt;
156 | usleep(10000);
157 | }
158 | }
159 |
160 | exit_thread:
161 | return NULL;
162 | }
163 |
--------------------------------------------------------------------------------
/src/pfsd/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | include_directories(
15 | ${PROJECT_SOURCE_DIR}/src/pfsd/
16 | ${PROJECT_SOURCE_DIR}/src/pfs_core/
17 | ${PROJECT_SOURCE_DIR}/src/trace/include/
18 | )
19 |
20 | link_directories(
21 | ${LIBRARY_OUTPUT_PATH}
22 | )
23 |
24 | SET(SRC_LIST_PFSD pfsd_main.cc
25 | pfsd_api.cc
26 | pfsd_chnl.cc
27 | pfsd_chnl_shm.cc
28 | pfsd_common.cc
29 | pfsd_memory.cc
30 | pfsd_option.cc
31 | pfsd_shm.cc
32 | pfsd_worker.cc
33 | )
34 |
35 | # macro definition
36 | add_definitions(
37 | -DPFS_IOCHNL_CLI
38 | )
39 |
40 |
41 | # pfsd daemon
42 | add_executable(pfsdaemon
43 | ${SRC_LIST_PFSD}
44 | )
45 |
46 | add_dependencies(pfsdaemon
47 | pfs
48 | )
49 |
50 | if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
51 | set(CXXFLAGS ${CXXFLAGS} -march=native)
52 | endif()
53 |
54 | target_link_libraries(pfsdaemon
55 | -Wl,--start-group
56 | -Wl,--no-as-needed
57 | pfs
58 | zlog
59 | pthread
60 | -Wl,--end-group
61 | )
62 |
63 | target_compile_definitions(pfsdaemon PUBLIC PFSD_SERVER)
64 |
65 | SET_TARGET_PROPERTIES(pfsdaemon PROPERTIES LINKER_LANGUAGE CXX)
66 |
67 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd.init:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # pfsd_env prepare pfsd running environment
17 | #
18 | # chkconfig: 35 99 99
19 | # description: create directories for pfsd
20 |
21 | mkdir -m 0777 /var/run/pfs && mkdir -m 0777 /var/run/pfsd && mkdir -m 0777 /dev/shm/pfsd && touch /var/run/pfsd/.pfsd
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_api.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFSD_API_H_
17 | #define _PFSD_API_H_
18 |
19 | #include "pfsd_common.h"
20 |
21 | typedef struct pfs_mount pfs_mount_t;
22 | typedef struct pfs_inode pfs_inode_t;
23 |
24 | /* return ino */
25 | int64_t pfsd_creat_svr(const char *pbdpath, mode_t , uint64_t *btime,
26 | int32_t *file_type);
27 | int64_t pfsd_open_svr(const char *pbdpath, int flags, mode_t,
28 | uint64_t *btime, int32_t *file_type);
29 |
30 | ssize_t pfsd_pread_svr(pfs_mount_t *mnt, pfs_inode_t *inode, void *buf,
31 | size_t len, off_t off, uint64_t btime);
32 | ssize_t pfsd_pwrite_svr(pfs_mount_t *mnt, pfs_inode_t *inode, int flags,
33 | const void *buf, size_t len, off_t off, ssize_t *file_size, uint64_t btime);
34 |
35 | int pfsd_truncate_svr(const char *pbdpath, off_t len);
36 | int pfsd_ftruncate_svr(pfs_mount_t *mnt, pfs_inode_t *in, off_t len, uint64_t btime);
37 |
38 | int pfsd_unlink_svr(const char *pbdpath);
39 |
40 | int pfsd_stat_svr(const char *pbdpath, struct stat *buf);
41 | int pfsd_fstat_svr(pfs_mount_t *mnt, pfs_inode_t *in, struct stat *buf, uint64_t btime);
42 |
43 | int pfsd_fallocate_svr(pfs_mount_t *mnt, pfs_inode_t *in, off_t offset,
44 | off_t len, int mode, uint64_t btime);
45 | int pfsd_chdir_svr(const char *pbdpath);
46 |
47 | int pfsd_opendir_svr(const char *pbdpath, int64_t *deno, int64_t *first_ino);
48 | int pfsd_readdir_svr(pfs_mount_t *mnt, int64_t dino, int64_t ino,
49 | uint64_t offset, struct dirent *entry, int64_t *next_ino);
50 |
51 | off_t pfsd_lseek_end_svr(pfs_mount_t *mnt, pfs_inode_t *in, off_t off, uint64_t btime);
52 |
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_chnl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef PFSD_CHNL_H_
17 | #define PFSD_CHNL_H_
18 |
19 | #include
20 | #include
21 |
22 | #define PFSD_MAX_SVR_ADDR_SIZE 4096
23 | #define PFSD_CONNECT_TIMEOUT_US (3 * 1000000)
24 | #define CHNL_MAX_CONN 16
25 |
26 | typedef struct pfsd_connect_entry pfsd_connect_entry_t;
27 |
28 | enum pfsd_chnl_req_type {
29 | CHNL_MOUNT = 0,
30 |
31 | //like growfs, remount
32 | CHNL_MOUNT_UPDATE = 1,
33 |
34 | //like stat
35 | CHNL_READ_META = 2,
36 | //like pread(it may also read meta)
37 | CHNL_READ_DATA = 3,
38 | CHNL_READ_DATA_AIO = 4,
39 | //like ftruncate
40 | CHNL_WRITE_META = 5,
41 | //like pwrite(it may also read/write meta)
42 | CHNL_WRITE_DATA = 6,
43 | CHNL_WRITE_DATA_AIO = 7,
44 |
45 | CHNL_ABORT = 8,
46 | };
47 |
48 | int32_t pfsd_chnl_connect(const char *svr_addr, const char *cluster,
49 | int timeout_ms, const char *pbdname, int host_id, int flags);
50 |
51 | int32_t pfsd_chnl_reconnect(int32_t conn_id, const char *cluster,
52 | int timeout_ms, const char *pbdname, int host_id, int flags);
53 |
54 | int pfsd_chnl_buffer_alloc(int32_t connect_id, int64_t max_req_len,
55 | void **req_buffer, int64_t max_rsp_len, void **rsp_buffer, void **io_buffer,
56 | long *buffer_meta);
57 |
58 | int64_t pfsd_chnl_send_recv(int32_t connect_id, void *req_buffer,
59 | int64_t req_len, void *rsp_buffer, int64_t max_rsp_len, void *io_buffer,
60 | long buffer_meta, int timout_us);
61 |
62 | void pfsd_chnl_buffer_free(int32_t connect_id, void *req_buf, void *rsp_buf,
63 | void *io_buf, long buffer_meta);
64 |
65 | void pfsd_chnl_update_meta(int32_t connect_id, long meta);
66 |
67 | int pfsd_chnl_get_logic_id(int32_t connect_id);
68 |
69 | int pfsd_chnl_abort(int32_t connect_id, pid_t pid);
70 |
71 | int pfsd_chnl_close(int32_t connect_id, bool force);
72 |
73 | int pfsd_chnl_listen(const char *svr_addr, const char *pbdname, int nworkers,
74 | void *arg1, void *arg2);
75 |
76 | /* server side */
77 | int32_t pfsd_chnl_accept_begin(void *ctx, void *op, int32_t conn_id_hint);
78 |
79 | void pfsd_chnl_accept_begin_rollback(int32_t conn_id);
80 |
81 | /* server side */
82 | void pfsd_chnl_accept_end(int32_t conn_id, int mnt_id);
83 |
84 | /* server side */
85 | int32_t pfsd_chnl_close_begin(int32_t connect_id);
86 |
87 | /* server side */
88 | void pfsd_chnl_close_end();
89 |
90 | bool pfsd_is_valid_connid(int32_t cid);
91 |
92 | bool pfsd_is_conn_closed(int32_t connect_id);
93 |
94 | #endif //PFSD_CHNL_H_
95 |
96 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_chnl_impl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef PFSD_CHNL_IMPL_H_
17 | #define PFSD_CHNL_IMPL_H_
18 |
19 | #include
20 | #include
21 |
22 | int32_t pfsd_chnl_get_channel_id();
23 |
24 | typedef struct pfsd_chnl_op {
25 | const char *chnl_type_name;
26 | void* (*chnl_ctx_create)(const char *svr_addr, bool is_svr);
27 | void (*chnl_ctx_destroy)(void *chnl_ctx);
28 |
29 | //return connection_id if succeed.
30 | int32_t (*chnl_connect)(void *chnl_ctx, const char *cluster,
31 | const char *pbdname, int host_id, int flags, int timout_us,
32 | bool reconn);
33 |
34 | int (*chnl_prepare)(const char *pbdname, int nworkers, void *arg);
35 | int (*chnl_recover)(void *ctx, void *op, const char *svr_addr,
36 | int workers, void *arg);
37 | int (*chnl_listen)(void *chnl_ctx, void *chnl_op, const char *svr_addr,
38 | void *arg1, void *arg2);
39 | int64_t (*chnl_send_req_sync)(void *chnl_ctx, int64_t max_req_len,
40 | void *req_buffer, int64_t max_rsp_len, void *rsp_buffer,
41 | void *io_buffer, long buffer_meta);
42 | int64_t (*chnl_recv_rsp_sync)(void *chnl_ctx, int64_t max_req_len,
43 | void *req_buffer, int64_t max_rsp_len, void *rsp_buffer,
44 | void *io_buffer, long buffer_meta);
45 |
46 | int (*chnl_alloc)(void *chnl_ctx, int64_t max_req_len, void **req_buffer,
47 | int64_t max_rsp_len, void **rsp_buffer, void **io_buffer,
48 | long *buffer_meta);
49 | void (*chnl_free)(void *chnl_ctx, void *req_buffer, void *rsp_buffer,
50 | void *io_buffer, long buffer_meta);
51 | void (*chnl_update_meta)(void *chnl_ctx, long meta);
52 | int (*chnl_abort)(void *chnl_ctx, int32_t pid);
53 | int (*chnl_close)(void *chnl_ctx, bool forced);
54 | } pfsd_chnl_op_t;
55 |
56 | typedef struct pfsd_connect_entry {
57 | int32_t connect_id;
58 | int32_t connect_refcnt;
59 | int connect_mntid;
60 | struct pfsd_chnl_op* connect_op;
61 | void* connect_data;
62 | } pfsd_connect_entry_t;
63 |
64 | void pfsd_chnl_ctx_create(const char *name, void **ctx, pfsd_chnl_op_t **op);
65 |
66 | #define PFSD_REGISTER_ASSIGN(name, type) .name = name##type,
67 | #define PFSD_CHNL_REGISTER(type, name) \
68 | static pfsd_chnl_op_t pfsd_chnl##type##_obj = { \
69 | .chnl_type_name = #name, \
70 | PFSD_REGISTER_ASSIGN(chnl_ctx_create, type) \
71 | PFSD_REGISTER_ASSIGN(chnl_ctx_destroy, type) \
72 | PFSD_REGISTER_ASSIGN(chnl_connect, type) \
73 | PFSD_REGISTER_ASSIGN(chnl_prepare, type) \
74 | PFSD_REGISTER_ASSIGN(chnl_recover, type) \
75 | PFSD_REGISTER_ASSIGN(chnl_listen, type) \
76 | PFSD_REGISTER_ASSIGN(chnl_send_req_sync, type) \
77 | PFSD_REGISTER_ASSIGN(chnl_recv_rsp_sync, type) \
78 | PFSD_REGISTER_ASSIGN(chnl_alloc, type) \
79 | PFSD_REGISTER_ASSIGN(chnl_free, type) \
80 | PFSD_REGISTER_ASSIGN(chnl_update_meta, type) \
81 | PFSD_REGISTER_ASSIGN(chnl_abort, type) \
82 | PFSD_REGISTER_ASSIGN(chnl_close, type) \
83 | }; \
84 | pfsd_chnl_op_t* pfsd_chnl##type##_pointer \
85 | __attribute__((used)) __attribute__((section("_pfsd_chnl"))) = \
86 | &pfsd_chnl##type##_obj
87 |
88 | #endif //PFSD_CHNL_IMPL_H_
89 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_chnl_shm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef PFSD_CHNL_SHM_H_
17 | #define PFSD_CHNL_SHM_H_
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | #include "pfsd_chnl.h"
25 | #include "pfsd_common.h"
26 |
27 | #define CHNL_SHM_VER 2
28 | #define CHNL_SHM_CONNECT_POLL_UNIT 100 // 0.1ms
29 |
30 |
31 | #define PBD_MAX_NAME_LEN 64
32 |
33 | // located at first [0, 4KB)
34 | typedef struct pidfile_sync_data {
35 | uint32_t ver;
36 | char cluster[PBD_MAX_NAME_LEN];
37 | char pbdname[PBD_MAX_NAME_LEN];
38 | int32_t host_id;
39 | int32_t flags;
40 | uint32_t shm_mnt_epoch;
41 | }__attribute__((aligned(4096))) pidfile_sync_data_t;
42 |
43 | // located at first [4KB, 8KB)
44 | typedef struct pidfile_ack_data {
45 | int32_t err;
46 | uint32_t ver;
47 | char err_msg[64];
48 | struct {
49 | int32_t shm_connect_id;
50 | char shm_fname[PFSD_SHM_MAX][FILE_MAX_FNAME];
51 | int32_t mntid;
52 | uint32_t shm_mnt_epoch;
53 | int32_t flags;
54 | int32_t err_remount;
55 | }v1;
56 | }__attribute__((aligned(4096))) pidfile_ack_data_t;
57 |
58 | typedef struct pidfile_data {
59 | pidfile_sync_data_t sync_data;
60 | pidfile_ack_data_t ack_data;
61 | }__attribute__((aligned(4096))) pidfile_data_t;
62 |
63 | typedef struct chnl_ctx_shm {
64 | int ctx_pidfile_fd;
65 | char ctx_pidfile_dir[PFSD_MAX_SVR_ADDR_SIZE]; /* pidfile dir which be watched by inotify */
66 | char ctx_pidfile_addr[PFSD_MAX_SVR_ADDR_SIZE];/* pidfile with absolute path */
67 | bool ctx_is_svr;
68 | union {
69 | /* For client if ctx_is_svr is false */
70 | struct {
71 | int32_t shm_connect_id;
72 | char *shm_ptr[PFSD_SHM_MAX];
73 | int64_t shm_len[PFSD_SHM_MAX];
74 | int32_t mntid;
75 | pidfile_data_t shm_pidfile_data;
76 | } clt;
77 | /* For server if ctx_is_svr is true */
78 | struct {
79 | sem_t shm_listen_thread_latch;
80 | int shm_inotify_fd;
81 | char shm_fname[PFSD_SHM_MAX][FILE_MAX_FNAME]; /* shm path for communication */
82 | } svr;
83 | };
84 | } chnl_ctx_shm_t;
85 |
86 | void pfsd_chnl_shm_client_init();
87 |
88 | #endif //PFSD_CHNL_SHM_H_
89 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_common.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "pfsd_common.h"
22 | #include "pfsd_proto.h"
23 |
24 | void
25 | pfsd_robust_mutex_init(pthread_mutex_t *mutex)
26 | {
27 | int r = 0;
28 |
29 | pthread_mutexattr_t attr;
30 | r |= pthread_mutexattr_init(&attr);
31 | r |= pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
32 | r |= pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
33 | r |= pthread_mutex_init(mutex, &attr);
34 | pthread_mutexattr_destroy(&attr);
35 | assert (r == 0);
36 | }
37 |
38 | int
39 | pfsd_robust_mutex_lock(pthread_mutex_t *mutex)
40 | {
41 | if (mutex == NULL)
42 | return -1;
43 |
44 | int r = pthread_mutex_lock(mutex);
45 | if (r == EOWNERDEAD)
46 | r = pthread_mutex_consistent(mutex);
47 |
48 | assert (r == 0);
49 | return r;
50 | }
51 |
52 | int
53 | pfsd_robust_mutex_trylock(pthread_mutex_t *mutex)
54 | {
55 | if (mutex == NULL)
56 | return -1;
57 |
58 | int r = pthread_mutex_trylock(mutex);
59 | if (r != 0 && r != EOWNERDEAD)
60 | return -1;
61 |
62 | if (r == EOWNERDEAD)
63 | r = pthread_mutex_consistent(mutex);
64 |
65 | assert (r == 0);
66 | return r;
67 | }
68 |
69 | int
70 | pfsd_robust_mutex_unlock(pthread_mutex_t *mutex)
71 | {
72 | if (mutex == NULL)
73 | return -1;
74 |
75 | int r = pthread_mutex_unlock(mutex);
76 | assert (r == 0);
77 | return 0;
78 | }
79 |
80 | long
81 | pfsd_tolong(void *ptr)
82 | {
83 | union {
84 | long v;
85 | void *p;
86 | } vp;
87 | vp.p = ptr;
88 | return vp.v;
89 | }
90 |
91 | bool
92 | pfsd_request_alive(pfsd_request_t *req)
93 | {
94 | //This is special for thread mode mount to avoid alive check that only
95 | //relies on fd close detection.
96 | if (req->connid % 2)
97 | return true;
98 | int r = kill(req->owner, 0);
99 | if (r == -1 && errno == ESRCH)
100 | return false;
101 |
102 | return true;
103 | }
104 |
105 | int
106 | pfsd_sdk_pbdname(const char *pbdpath, char *pbdname)
107 | {
108 | if (pbdpath == NULL || pbdpath[0] != '/')
109 | return -1;
110 |
111 | int i = 1;
112 | while (pbdpath[i] != '\0' && pbdpath[i] == '/')
113 | i++;
114 |
115 | if (pbdpath[i] == '\0')
116 | return -1;
117 |
118 | const char *slash = strchr(pbdpath + i, '/');
119 | if (slash == NULL)
120 | return -1;
121 |
122 | size_t len = slash - (pbdpath + i);
123 | if (len == 0)
124 | return -1;
125 | else if (len >= PFS_MAX_NAMELEN)
126 | return -1;
127 |
128 | strncpy(pbdname, pbdpath + i, len);
129 | pbdname[len] = 0;
130 | return 0;
131 | }
132 |
133 | int
134 | pfsd_write_pid(const char *pbdname) {
135 | char file[4*1024] = "";
136 | snprintf(file, sizeof(file), "/var/run/pfsd/pfsd_%s.pid", pbdname);
137 | int fd = ::open(file, O_RDWR | O_CREAT | O_CLOEXEC, 0644);
138 | if (fd < 0)
139 | return -errno;
140 |
141 | if (::flock(fd, LOCK_EX | LOCK_NB) != 0) {
142 | close(fd);
143 | return -errno;
144 | }
145 |
146 | char buf[128];
147 | size_t size = snprintf(buf, sizeof(buf), "%ld", (long)getpid());
148 | int ret = write(fd, buf, size);
149 | if (ret != (int)size) {
150 | close(fd);
151 | return -EIO;
152 | }
153 |
154 | return 0;
155 | }
156 |
157 | const char mon_name[][4] = {
158 | "Jan", "Feb", "Mar", "Apr", "May", "Jun",
159 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
160 | };
161 |
162 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_main.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 |
20 | #include "pfsd_common.h"
21 | #include "pfsd_shm.h"
22 | #include "pfsd_worker.h"
23 | #include "pfsd_option.h"
24 |
25 | #include "pfs_trace.h"
26 | #include "pfsd_zlog.h"
27 |
28 | #include "pfsd_chnl.h"
29 |
30 | static void
31 | signal_handler(int num)
32 | {
33 | g_stop = true;
34 | }
35 |
36 | static void
37 | reload_handler(int num)
38 | {
39 | }
40 |
41 | /* used for libpfs logger */
42 | zlog_category_t *original_zlog_cat = NULL;
43 |
44 | int main(int ac, char *av[])
45 | {
46 | const char *pbdname;
47 | int err;
48 | if (pfsd_parse_option(ac, av) != 0) {
49 | pfsd_usage(av[0]);
50 | return -1;
51 | }
52 |
53 | if (ac == 1)
54 | pfsd_usage(av[0]);
55 |
56 | pbdname = g_option.o_pbdname;
57 | err = pfsd_write_pid(pbdname);
58 | if (err != 0) {
59 | fprintf(stderr, "pfsd %s may already running, err %d.\n",
60 | pbdname, err);
61 | return -1;
62 | }
63 |
64 | /* init signal */
65 | struct sigaction sig;
66 | memset(&sig, 0, sizeof(sig));
67 | sig.sa_handler = signal_handler;
68 | sigaction(SIGINT, &sig, NULL);
69 | sig.sa_handler = reload_handler;
70 | sigaction(SIGHUP, &sig, NULL);
71 | sig.sa_handler = SIG_IGN;
72 | sigaction(SIGPIPE, &sig, NULL);
73 |
74 | if (g_option.o_daemon)
75 | daemon(1, 1);
76 |
77 | /* init logger: use env for pass logdir to zlog */
78 | if (setenv("PFSD_PBDNAME", pbdname, 1) != 0) {
79 | fprintf(stderr, "set env [%s] failed: %s\n", pbdname, strerror(errno));
80 | return -1;
81 | }
82 | char logdir[PFS_MAX_PATHLEN] = "";
83 | snprintf(logdir, PFS_MAX_PATHLEN-1, "/var/log/pfsd-%s", pbdname);
84 | mkdir(logdir, 0777);
85 | int rv = LogInit(g_option.o_log_cfg, (char *)"pfsd_cat");
86 | if (rv != 0) {
87 | fprintf(stderr, "Error: init log failed, ret:%d\n", rv);
88 | return rv;
89 | }
90 |
91 | /* init libpfs logger */
92 | original_zlog_cat = zlog_get_category("original_cat");
93 | if (original_zlog_cat == NULL) {
94 | pfsd_error("why no original category");
95 | original_zlog_cat = zlog_get_category("pfsd_cat");
96 | }
97 |
98 | pfs_log_functor = wrapper_zlog;
99 |
100 | fprintf(stderr, "starting pfsd[%d] %s\n", getpid(), pbdname);
101 | pfsd_info("starting pfsd[%d] %s", getpid(), pbdname);
102 |
103 | /* init communicate shm and inotify stuff */
104 | if (pfsd_chnl_listen(PFSD_USER_PID_DIR, pbdname, g_option.o_workers,
105 | g_shm_fname, g_option.o_shm_dir) != 0) {
106 | pfsd_error("[pfsd]pfsd_chnl_listen %s failed, errno %d",
107 | PFSD_USER_PID_DIR, errno);
108 | return -1;
109 | }
110 |
111 | /* notify worker start */
112 | for (int i = 0; i < g_option.o_workers; ++i) {
113 | worker_t *wk = g_workers + i;
114 | sem_post(&wk->w_sem);
115 | }
116 |
117 | int windex = 0;
118 | while (!g_stop) {
119 | windex = (windex + 1) % g_option.o_workers;
120 | /* recycle zombie */
121 | for (int ci = 0; ci < g_workers[windex].w_nch; ++ci) {
122 | pfsd_iochannel_t *ch = g_workers[windex].w_channels[ci];
123 | pfsd_shm_recycle_request(ch);
124 | }
125 |
126 | if (g_workers[windex].w_cr != NULL)
127 | g_workers[windex].w_cr->cr_ts = time(NULL);
128 |
129 | sleep(10);
130 | }
131 |
132 | /* exit */
133 | for (int i = 0; i < g_nworkers; ++i) {
134 | if (g_workers == NULL)
135 | break;
136 |
137 | if (g_workers[i].w_nch == 0)
138 | break;
139 |
140 | sem_post(&g_workers[i].w_sem);
141 |
142 | pfsd_info("[pfsd]pthread_join %d", i);
143 | pthread_join(g_workers[i].w_tid, NULL);
144 | }
145 |
146 | pfsd_destroy_workers(&g_workers);
147 |
148 | pfsd_info("[pfsd]bye bye");
149 | return 0;
150 | }
151 |
152 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_memory.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include "pfsd_memory.h"
23 |
24 | typedef struct pfsd_memory {
25 | const char *mt_name;
26 | pthread_mutex_t mt_mtx;
27 | ssize_t mt_bytes_alloc;
28 | ssize_t mt_bytes_free;
29 | int64_t mt_count_alloc;
30 | int64_t mt_count_free;
31 | } pfsd_memtype_t;
32 |
33 | #define MEMTYPE_ENTRY(tag) [tag] = { #tag, PTHREAD_MUTEX_INITIALIZER, }
34 | static pfsd_memtype_t pfsd_mem_type[MD_NTYPE] = {
35 | MEMTYPE_ENTRY(MD_NONE),
36 | MEMTYPE_ENTRY(MD_DIR),
37 | MEMTYPE_ENTRY(MD_FILE),
38 | };
39 |
40 | static inline const char *
41 | memtype_name(int type)
42 | {
43 | return pfsd_mem_type[type].mt_name;
44 | }
45 |
46 | static void
47 | memtype_inc(int type, int count, size_t size)
48 | {
49 | pfsd_memtype_t *mt;
50 |
51 | assert (0 < type && type < MD_NTYPE);
52 |
53 | mt = &pfsd_mem_type[type];
54 | pthread_mutex_lock(&mt->mt_mtx);
55 | mt->mt_bytes_alloc += (ssize_t)size;
56 | mt->mt_count_alloc += count;
57 | pthread_mutex_unlock(&mt->mt_mtx);
58 | }
59 |
60 | static void
61 | memtype_dec(int type, size_t size)
62 | {
63 | pfsd_memtype_t *mt;
64 |
65 | assert (0 < type && type < MD_NTYPE);
66 |
67 | mt = &pfsd_mem_type[type];
68 | pthread_mutex_lock(&mt->mt_mtx);
69 | mt->mt_bytes_free += (ssize_t)size;
70 | mt->mt_count_free += 1;
71 | pthread_mutex_unlock(&mt->mt_mtx);
72 | }
73 |
74 | void *
75 | pfsd_mem_malloc(size_t size, int type)
76 | {
77 | void* ptr = malloc(size);
78 | if (ptr == NULL) {
79 | fprintf(stderr, "malloc failed: type %s, size %zu\n",
80 | memtype_name(type), size);
81 | return NULL;
82 | }
83 | memset(ptr, 0, size);
84 | memtype_inc(type, 1, malloc_usable_size(ptr));
85 |
86 | return ptr;
87 | }
88 |
89 | void *
90 | pfsd_mem_malloc_array(size_t nelem, size_t elemsize, int type)
91 | {
92 | return pfsd_mem_malloc(nelem * elemsize, type);
93 | }
94 |
95 | void
96 | pfsd_mem_free(void *ptr, int type)
97 | {
98 | if (ptr) {
99 | memtype_dec(type, malloc_usable_size(ptr));
100 | free(ptr);
101 | }
102 | }
103 |
104 | void *
105 | pfsd_mem_realloc(void *ptr, size_t newsize, int type)
106 | {
107 | void *newptr;
108 | int inc;
109 | size_t oldsize;
110 |
111 | if (ptr) {
112 | oldsize = malloc_usable_size(ptr);
113 | inc = 0;
114 | } else {
115 | oldsize = 0;
116 | inc = 1;
117 | }
118 | newptr = realloc(ptr, newsize);
119 | if (newptr) {
120 | memtype_inc(type, inc, malloc_usable_size(newptr) - oldsize);
121 | }
122 | return newptr;
123 | }
124 |
125 | int
126 | pfsd_mem_memalign(void **pp, size_t alignment, size_t size, int type)
127 | {
128 | int err;
129 |
130 | err = posix_memalign(pp, alignment, size);
131 | if (err == 0)
132 | memtype_inc(type, 1, malloc_usable_size(*pp));
133 | return err;
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_memory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFSD_MEMORY_H_
17 | #define _PFSD_MEMORY_H_
18 |
19 | enum {
20 | MD_NONE = 0,
21 | MD_DIR,
22 | MD_FILE,
23 | MD_MOUNTARG,
24 |
25 | MD_NTYPE
26 | };
27 |
28 | void* pfsd_mem_malloc(size_t size, int type);
29 | void* pfsd_mem_malloc_array(size_t nelem, size_t elemsize, int type);
30 | void pfsd_mem_free(void *ptr, int type);
31 | void* pfsd_mem_realloc(void *ptr, size_t newsize, int type);
32 | int pfsd_mem_memalign(void **pp, size_t alignment, size_t size, int type);
33 |
34 | #endif /* _PFSD_MEMORY_H_ */
35 |
36 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_option.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "pfsd_option.h"
22 | #include "pfsd_common.h"
23 | #include "pfs_option.h"
24 |
25 | unsigned int server_id = 0; /* db ins id */
26 |
27 | pfsd_option_t g_option;
28 |
29 | static int64_t worker_usleep_us = 10;
30 | PFS_OPTION_REG(worker_usleep_us, pfs_check_ival_normal);
31 |
32 | #define PFSD_TRIM_VALUE(v, min_v, max_v) do {\
33 | if (v > max_v) \
34 | v = max_v; \
35 | else if (v < min_v) \
36 | v = min_v; \
37 | } while(0)
38 |
39 | static bool
40 | sanity_check()
41 | {
42 | PFSD_TRIM_VALUE(g_option.o_workers, 1, PFSD_WORKER_MAX);
43 | PFSD_TRIM_VALUE(g_option.o_usleep, 0, 1000);
44 | worker_usleep_us = g_option.o_usleep;
45 | if (worker_usleep_us == 0) {
46 | /* Don't set affinity if busy polling */
47 | g_option.o_affinity = 0;
48 | }
49 |
50 | if (strlen(g_option.o_pbdname) == 0) {
51 | fprintf(stderr, "pbdname is empty\n");
52 | return false;
53 | }
54 |
55 | fprintf(stderr, "option workers %d\n",g_option.o_workers);
56 | fprintf(stderr, "option pbdname %s\n",g_option.o_pbdname);
57 | fprintf(stderr, "option server id %u\n", server_id);
58 | fprintf(stderr, "option logconf %s\n",g_option.o_log_cfg);
59 |
60 | return true;
61 | }
62 |
63 | static void __attribute__((constructor))
64 | init_default_value()
65 | {
66 | g_option.o_workers = 32;
67 | g_option.o_usleep = int(worker_usleep_us);
68 | strncpy(g_option.o_log_cfg, "pfsd_logger.conf", sizeof g_option.o_log_cfg);
69 | strncpy(g_option.o_shm_dir, PFSD_SHM_PATH, sizeof g_option.o_shm_dir);
70 | g_option.o_daemon = 1;
71 | g_option.o_affinity = 1;
72 | server_id = 0;
73 | }
74 |
75 | int
76 | pfsd_parse_option(int ac, char *av[])
77 | {
78 | int ch = 0;
79 | while ((ch = getopt(ac, av, "w:s:i:c:p:a:l:b:e:fd")) != -1) {
80 | switch (ch) {
81 | case 'f':
82 | g_option.o_daemon = 0;
83 | break;
84 |
85 | case 'd':
86 | g_option.o_daemon = 1;
87 | break;
88 | case 'b':
89 | {
90 | errno = 0;
91 | long w = strtol(optarg, NULL, 10);
92 | if (errno == 0)
93 | g_option.o_affinity = (w == 0) ? 0 : 1;
94 | }
95 | break;
96 | case 'w':
97 | {
98 | errno = 0;
99 | long w = strtol(optarg, NULL, 10);
100 | if (errno == 0)
101 | g_option.o_workers = int(w);
102 | }
103 | break;
104 | case 's':
105 | {
106 | errno = 0;
107 | long us = strtol(optarg, NULL, 10);
108 | if (errno == 0)
109 | g_option.o_usleep = int(us);
110 | }
111 | break;
112 | case 'i':
113 | break;
114 | case 'e':
115 | {
116 | errno = 0;
117 | long w = strtol(optarg, NULL, 10);
118 | if (errno == 0)
119 | server_id = (unsigned int)(w);
120 | }
121 | break;
122 | case 'c':
123 | strncpy(g_option.o_log_cfg, optarg, sizeof g_option.o_log_cfg);
124 | break;
125 | case 'p':
126 | strncpy(g_option.o_pbdname, optarg, sizeof g_option.o_pbdname);
127 | break;
128 | case 'a':
129 | strncpy(g_option.o_shm_dir, optarg, sizeof g_option.o_shm_dir);
130 | break;
131 | default:
132 | return -1;
133 | }
134 | }
135 |
136 | if (!sanity_check())
137 | return -1;
138 |
139 | if (optind != ac)
140 | return -1;
141 |
142 | return 0;
143 | }
144 |
145 | void
146 | pfsd_usage(const char *prog)
147 | {
148 | fprintf(stderr, "Usage: %s \n"
149 | " -f (not daemon mode)\n"
150 | " -w #nworkers\n"
151 | " -c log_config_file\n"
152 | " -p pbdname\n"
153 | " -b (if bind cpuset)\n"
154 | " -e db ins id\n"
155 | " -a shm directory\n"
156 | " -i #inode_list_size\n", prog);
157 | }
158 |
159 | void
160 | pfsd_worker_usleep()
161 | {
162 | if (worker_usleep_us > 0)
163 | usleep(worker_usleep_us);
164 | }
165 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_option.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFSD_OPTION_H_
17 | #define _PFSD_OPTION_H_
18 |
19 | #include "pfs_impl.h"
20 |
21 | typedef struct {
22 | /* Worker threads, same as num of channels */
23 | int o_workers;
24 | /* Worker thread usleep interval in us */
25 | int o_usleep;
26 | /* pbdname like 1-1 */
27 | char o_pbdname[PFS_MAX_PBDLEN];
28 | /* shm directory */
29 | char o_shm_dir[PFS_MAX_PATHLEN];
30 | /* config file */
31 | char o_log_cfg[PFS_MAX_PATHLEN];
32 | /* daemon mode */
33 | int o_daemon;
34 | /* if bind cpuset */
35 | int o_affinity;
36 | } pfsd_option_t;
37 |
38 | extern pfsd_option_t g_option;
39 |
40 | int pfsd_parse_option(int ac, char *av[]);
41 | void pfsd_usage(const char *prog);
42 | void pfsd_worker_usleep();
43 |
44 | #endif
45 |
46 |
--------------------------------------------------------------------------------
/src/pfsd/pfsd_worker.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _PFSD_WORKER_H_
17 | #define _PFSD_WORKER_H_
18 |
19 | #include
20 | #include "pfsd_proto.h"
21 | #include "pfsd_common.h"
22 |
23 | struct pfsd_iochannel;
24 |
25 | extern volatile bool g_stop;
26 |
27 | /*A worker thread is dedicated to a shm */
28 | typedef struct worker {
29 | pthread_t w_tid;
30 | int w_idx;
31 | int w_nch;
32 | struct pfsd_iochannel *w_channels[PFSD_SHM_MAX *PFSD_WORKER_MAX];
33 | sem_t w_sem; /*for sync start thread */
34 | pfsd_cpu_record_t *w_cr; /*if it set affinity */
35 | } worker_t;
36 |
37 | extern worker_t *g_workers;
38 | extern int g_nworkers;
39 |
40 | worker_t *pfsd_create_workers(int nworkers);
41 | void pfsd_destroy_workers(worker_t **workers);
42 |
43 | void *pfsd_worker_routine(void *arg);
44 |
45 | extern pfsd_cpu_record_t *g_cpufile;
46 | extern int g_ncpu;
47 | /*Exec in main thread when start, find available core for worker threads */
48 | void *pfsd_worker_affinity_prepare(int nworkers);
49 | bool pfsd_worker_bind_cpuset(worker_t *worker);
50 | bool pfsd_is_busy_cpu(int cpuid, int ncpu);
51 |
52 | int pfsd_worker_handle_request(pfsd_iochannel *ch, int index);
53 |
54 | void pfsd_worker_handle_growfs(pfsd_iochannel *ch, int index, const growfs_request_t *req, growfs_response_t *rsp);
55 | void pfsd_worker_handle_rename(pfsd_iochannel *ch, int index, const rename_request_t *req, rename_response_t *rsp);
56 | void pfsd_worker_handle_open(pfsd_iochannel *ch, int index, const open_request_t *req, open_response_t *rsp);
57 | void pfsd_worker_handle_read(pfsd_iochannel *ch, int index, const read_request_t *req, read_response_t *rsp);
58 | void pfsd_worker_handle_write(pfsd_iochannel *ch, int index, const write_request_t *req, write_response_t *rsp);
59 | void pfsd_worker_handle_truncate(pfsd_iochannel *ch, int index, const truncate_request_t *req, truncate_response_t *rsp);
60 | void pfsd_worker_handle_ftruncate(pfsd_iochannel *ch, int index, const ftruncate_request_t *req, ftruncate_response_t *rsp);
61 | void pfsd_worker_handle_unlink(pfsd_iochannel *ch, int index, const unlink_request_t *req, unlink_response_t *rsp);
62 | void pfsd_worker_handle_stat(pfsd_iochannel *ch, int index, const stat_request_t *req, stat_response_t *rsp);
63 | void pfsd_worker_handle_fstat(pfsd_iochannel *ch, int index, const fstat_request_t *req, fstat_response_t *rsp);
64 | void pfsd_worker_handle_fallocate(pfsd_iochannel *ch, int index, const fallocate_request_t *req, fallocate_response_t *rsp);
65 | void pfsd_worker_handle_chdir(pfsd_iochannel *ch, int index, const chdir_request_t *req, chdir_response_t *rsp);
66 | void pfsd_worker_handle_mkdir(pfsd_iochannel *ch, int index, const mkdir_request_t *req, mkdir_response_t *rsp);
67 | void pfsd_worker_handle_rmdir(pfsd_iochannel *ch, int index, const rmdir_request_t *req, rmdir_response_t *rsp);
68 | void pfsd_worker_handle_opendir(pfsd_iochannel *ch, int index, const opendir_request_t *req, opendir_response_t *rsp);
69 | void pfsd_worker_handle_readdir(pfsd_iochannel *ch, int index, const readdir_request_t *req, readdir_response_t *rsp);
70 | void pfsd_worker_handle_access(pfsd_iochannel *ch, int index, const access_request_t *req, access_response_t *rsp);
71 | void pfsd_worker_handle_lseek(pfsd_iochannel *ch, int index, const lseek_request_t *req, lseek_response_t *rsp);
72 |
73 | /*for debug : return current processing request's pid */
74 | pid_t pfsd_worker_current_processing_pid();
75 |
76 | #endif
77 |
78 |
--------------------------------------------------------------------------------
/src/pfsd/sdk_demo.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "pfsd_sdk.h"
24 | #include "pfsd_shm.h"
25 |
26 | #define READ_SIZE (1 * 1024)
27 |
28 | int main(int ac, char* av[]) {
29 | std::string pbd = "86-1";
30 | std::string pbd_path("/" + pbd + "/");
31 | if (ac > 1) {
32 | pbd = av[1];
33 | pbd_path = "/"+pbd+"/";
34 | }
35 |
36 | int rflags = PFS_RD | MNTFLG_PAXOS_BYFORCE;
37 | int wflags = PFS_RDWR | MNTFLG_PAXOS_BYFORCE;
38 | int host_id = 1;
39 | const char* cluster = NULL;
40 |
41 | pfsd_set_mode(PFSD_SDK_THREADS);
42 |
43 | int r = pfsd_mount(cluster, pbd.data(), host_id, rflags);
44 | if (r != 0) {
45 | printf("pfsd_sdk_init failed %d\n", errno);
46 | return -1;
47 | }
48 | int fd = pfsd_open((pbd_path + "hello.txt").data(), O_RDWR|O_CREAT, 0);
49 | printf("hello.txt: open fd %d\n", fd);
50 | if (fd < 0) {
51 | printf("hello.txt: open failed %d, now remount \n", errno);
52 | r = pfsd_remount(cluster, pbd.data(), host_id, wflags);
53 | printf("remount: %d, err %d\n", r, errno);
54 |
55 | fd = pfsd_open((pbd_path + "hello.txt").data(), O_RDWR|O_CREAT, 0);
56 | }
57 |
58 | ssize_t wbytes = pfsd_pwrite(fd, "abcdefghijklmnopqrstuvwxyz", 26, 0);
59 | printf("hello.txt: write %ld errno %d\n", wbytes, errno);
60 |
61 | char buf[READ_SIZE] = "";
62 | ssize_t bytes = pfsd_read(fd, buf, READ_SIZE);
63 | if (bytes > 0)
64 | printf("read %.*s\n", int(bytes), buf);
65 | else
66 | printf("read error %d, %d\n", int(bytes), errno);
67 |
68 | pfsd_close(fd);
69 | pfsd_umount(pbd.data());
70 | return 0;
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/src/pfsd_unittest/dcache_test_performance.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * Dentry cache performance test
18 | */
19 | #include "pfs_api.h"
20 | #define NAMECACHE_TEST
21 | #include "pfs_namecache.h"
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | #define ASSERT(cond, msg) do { \
36 | if (!(cond)) { \
37 | fprintf(stderr, "assert %s, %s:%d, %s", #cond, __func__, __LINE__, msg); \
38 | exit(EXIT_FAILURE); \
39 | } \
40 | } while(0)
41 |
42 | char cluster[128];
43 | char device[128];
44 |
45 | std::string get_fname(const char *name);
46 | void create_files(int num);
47 | void mount_fs(void);
48 | void test(int);
49 |
50 | #define FILE_NUM 5000
51 |
52 | void usage(const char *prog)
53 | {
54 | printf("usage: %s [OPTION]...\n", prog);
55 | printf(" -C cluster specify cluster\n");
56 | printf(" -D device specify device\n");
57 | printf(" -i create files\n");
58 | printf(" -t loops run test\n");
59 | }
60 |
61 | int main(int argc, char **argv)
62 | {
63 | int opt;
64 | int touch_flag = 0;
65 | int test_flag = 0;
66 | int test_loops = 0;
67 | int touch_num = 0;
68 |
69 | while ((opt = getopt(argc, argv, "C:D:it:")) != -1) {
70 | switch (opt) {
71 | case 'C':
72 | strcpy(cluster, optarg);
73 | break;
74 | case 'D':
75 | strcpy(device, optarg);
76 | break;
77 | case 'i':
78 | touch_flag = 1;
79 | break;
80 | case 't':
81 | test_flag = 1;
82 | test_loops = atoi(optarg);
83 | break;
84 | default: /* '?' */
85 | usage(argv[0]);
86 | exit(EXIT_FAILURE);
87 | }
88 | }
89 |
90 | if (argc < 2) {
91 | return EXIT_FAILURE;
92 | }
93 |
94 | mount_fs();
95 |
96 | if (touch_flag) {
97 | create_files(FILE_NUM);
98 | } else if (test_flag) {
99 | test(test_loops);
100 | }
101 | return 0;
102 | }
103 |
104 | std::string get_fname(const char *name)
105 | {
106 | return std::string("/") + std::string(device) + name;
107 | }
108 |
109 | void mount_fs(void)
110 | {
111 | int ret = pfs_mount(cluster, device, 1, PFS_RDWR);
112 | if (ret != 0) {
113 | printf("can not mount");
114 | exit(EXIT_FAILURE);
115 | }
116 | }
117 |
118 | void create_files(int num)
119 | {
120 | char name[128];
121 |
122 | for (int i = 0; i < num; ++i) {
123 | sprintf(name, "/%s/test_%d", device, i);
124 | int ret = pfs_creat(name, 0);
125 | ASSERT(ret > 0, "pfs_creat");
126 | if (ret > 0)
127 | pfs_close(ret);
128 | }
129 | }
130 |
131 | void do_test(int loops, int *file_list, int count);
132 |
133 | void test(int loops)
134 | {
135 | const int N = 100;
136 | int file_list[N];
137 |
138 | srandom(time(NULL));
139 | for (int i = 0; i < N; ++i) {
140 | file_list[i] = random() % FILE_NUM;
141 | }
142 | printf("cache off\n");
143 | pfs_set_namecache_enable(false);
144 |
145 | auto start = std::chrono::system_clock::now();
146 | do_test(loops, file_list, N);
147 | auto end = std::chrono::system_clock::now();
148 | std::chrono::duration diff = end-start;
149 | printf("time: %f seconds\n", diff.count());
150 |
151 | printf("cache on\n");
152 | pfs_set_namecache_enable(true);
153 | start = std::chrono::system_clock::now();
154 | do_test(loops, file_list, N);
155 | end = std::chrono::system_clock::now();
156 | diff = end-start;
157 | printf("time: %f seconds\n", diff.count());
158 | }
159 |
160 | void do_test(int loops, int *file_list, int count)
161 | {
162 | char name[128];
163 | for (int i = 0; i < loops; ++i) {
164 | for (int j = 0; j < count; ++j) {
165 | sprintf(name, "/%s/test_%d", device, file_list[j]);
166 | int ret = pfs_open(name, O_RDONLY, 0);
167 | ASSERT(ret > 0, "pfs_open");
168 | pfs_close(ret);
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/pfsd_unittest/pfsd_testenv.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include "pfsd_testenv.h"
17 | #include "pfsd_sdk.h"
18 | #include "pfs_mount.h"
19 | #include "pfsd_common.h"
20 | #include
21 | #include
22 |
23 | using std::cout;
24 | using std::endl;
25 |
26 | PFSDTestEnv *g_testenv = NULL;
27 |
28 | #define TEST_CONNECT_TIMEOUT (5 * 1000)
29 |
30 | void PFSDTestEnv::SetUp() {
31 | cout << "Start PFSDTest of host " << hostid_
32 | << " on clsuter " << cluster_ << ", pbd " << pbdname_ << endl;
33 |
34 | int flags = MNTFLG_TOOL | MNTFLG_RDWR | MNTFLG_LOG;
35 | int err = pfsd_sdk_init(PFSD_SDK_THREADS, PFSD_USER_PID_DIR, TEST_CONNECT_TIMEOUT,
36 | cluster_.data(), pbdname_.data(), hostid_, flags);
37 | if (err < 0) {
38 | cout << "pfsd_sdk_init failed." << endl;
39 | abort();
40 | }
41 |
42 | cout << "Setup successful" << endl;
43 | }
44 |
45 | void PFSDTestEnv::TearDown() {
46 | cout << "Finish PFSDTest of host " << hostid_ << " on pbd " << pbdname_ << endl;
47 | umount();
48 | }
49 |
50 | int PFSDTestEnv::mount(int flags) {
51 | flags |= PFS_TOOL;
52 | int e = pfsd_sdk_init(PFSD_SDK_THREADS, PFSD_USER_PID_DIR, TEST_CONNECT_TIMEOUT,
53 | cluster_.data(), pbdname_.data(), hostid_, flags);
54 | return e >= 0 ? 0 : -1;
55 | }
56 |
57 | int PFSDTestEnv::umount() {
58 | return pfsd_umount(pbdname_.data());// just close pid file
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/src/pfsd_unittest/pfsd_testenv.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef __PFSD_TESTENV_H__
17 | #define __PFSD_TESTENV_H__
18 |
19 | #include
20 | #include
21 |
22 |
23 | #define UNIT_1G (1024*1024*1024)
24 | #define UNIT_4K (4*1024)
25 | #define UNIT_4M (4*1024*1024)
26 |
27 | #define CHECK_RET(expected, actual) do {\
28 | EXPECT_EQ(expected, actual);\
29 | if (expected != actual) {\
30 | cout << "--- unexpected error: [" << errno\
31 | << "] " << strerror(errno) << endl;\
32 | errno = 0; \
33 | } \
34 | } while (0)
35 |
36 | #define CHECK_ERR_RET(expected, actual, expected_errno) do { \
37 | EXPECT_EQ(expected, actual); \
38 | EXPECT_EQ(expected_errno, errno); \
39 | } while (0)
40 |
41 | #define CHECK_CUR_OFFSET(fd_, val) do { \
42 | off_t pos = pfsd_lseek(fd_, 0, SEEK_CUR); \
43 | EXPECT_EQ(pos, val); \
44 | } while(0)
45 |
46 | #define CHECK_FILESIZE(fd_, val) do { \
47 | struct stat fstat; \
48 | pfsd_fstat(fd_, &(fstat)); \
49 | EXPECT_EQ((fstat).st_size, val); \
50 | } while(0)
51 |
52 | #define CHECK_FILETYPE(pbdpath, type) do { \
53 | struct stat fstat; \
54 | pfsd_stat(pbdpath , &(fstat)); \
55 | EXPECT_TRUE(S_IS##type(fstat.st_mode)); \
56 | } while(0)
57 |
58 |
59 | class PFSDTestEnv : public testing::Environment
60 | {
61 | public:
62 | explicit PFSDTestEnv(const std::string &cluster, const std::string &pbdname, int hostid) :
63 | cluster_(cluster),
64 | pbdname_(pbdname),
65 | hostid_(hostid) {
66 | }
67 |
68 | virtual void SetUp();
69 | virtual void TearDown();
70 |
71 | int mount(int flags);
72 | int umount();
73 |
74 | std::string cluster_;
75 | std::string pbdname_; // "PBD-VERSION"
76 | int hostid_;
77 | };
78 |
79 | extern PFSDTestEnv *g_testenv;
80 |
81 | #endif
82 |
83 |
--------------------------------------------------------------------------------
/src/pfsd_unittest/pfsd_unittest.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 | #include "pfsd_testenv.h"
20 |
21 | using namespace std;
22 |
23 | int main(int argc, char **argv)
24 | {
25 | if (argc < 4) {
26 | cout << "Usage: " << argv[0] << " [hostid] [cluster] [pbdname]" << endl;
27 | return -1;
28 | } else {
29 | int hostid = atoi(argv[1]);
30 | string cluster(argv[2]);
31 | string pbdname(argv[3]);
32 |
33 | g_testenv = dynamic_cast(
34 | ::testing::AddGlobalTestEnvironment(
35 | new PFSDTestEnv(cluster, pbdname, hostid)
36 | )
37 | );
38 | ::testing::InitGoogleTest(&argc, argv);
39 |
40 | return RUN_ALL_TESTS();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/trace/include/trace_pfs_ctx.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021, Alibaba Group Holding Limited
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | #ifndef _TRACE_PFS_CTX_H_
17 | #define _TRACE_PFS_CTX_H_
18 |
19 | #include
20 | #include "trace_type.h"
21 |
22 | #ifdef __cplusplus
23 | extern "C" {
24 | #endif
25 |
26 | #define PFS_TRACE_STATCAP 256
27 | int _pfs_trace_ctx_init(unsigned int svrid, const char *pbdname);
28 | void _pfs_trace_ctx_stop();
29 | void pfs_trace_log_func(TraceLogLevel lv, const char *fmt, ...);
30 |
31 | #if defined(PFS_TRACE_ENABLE)
32 |
33 | #define pfs_trace_ctx_init(server_id, pbdname) \
34 | _pfs_trace_ctx_init(server_id, pbdname)
35 |
36 | #define pfs_trace_ctx_stop() \
37 | _pfs_trace_ctx_stop()
38 |
39 | #define PFS_STAT_BANDWIDTH(type, value) \
40 | polar_stat(0, 0, STAT_TYPE_HIST, STAT_OP_UPDATE_BW, type, value);
41 |
42 | #define PFS_INC_COUNTER(type) \
43 | polar_stat(0, 0, STAT_TYPE_CNT, STAT_OP_UPDATE_CNT, type, 1);
44 |
45 | #define PFS_STAT_LATENCY_ENTRY(type) \
46 | struct timeval __trace_ts__; \
47 | gettimeofday(&__trace_ts__, NULL);
48 |
49 | #define PFS_STAT_LATENCY(type) \
50 | polar_stat_latency(0, 0, type, &__trace_ts__);
51 |
52 | #define PFS_STAT_LATENCY_VALUE(type, pvalue) \
53 | polar_stat_latency(0, 0, type, pvalue);
54 |
55 | #else
56 |
57 | #define pfs_trace_ctx_init(server_id, pbdname) do{ } while(0)
58 | #define pfs_trace_ctx_stop() do{ } while(0)
59 |
60 | #define PFS_STAT_BANDWIDTH(type, value) do{ } while(0)
61 | #define PFS_INC_COUNTER(type) do{ } while(0)
62 | #define PFS_STAT_LATENCY_ENTRY(type) do{ } while(0)
63 | #define PFS_STAT_LATENCY(type) do{ } while(0)
64 | #define PFS_STAT_LATENCY_VALUE(type, pvalue) do{ } while(0)
65 | #endif
66 |
67 | #if defined(PFS_TRACEPOINT_ENABLE)
68 | // pfs trace
69 | extern uint32_t g_trace_server_id;
70 | #define PFS_SetTraceid(req) \
71 | do { \
72 | static uint32_t id = 0; \
73 | ATOMIC_FETCH_AND_ADD(&id, 1); \
74 | struct timeval ts; \
75 | gettimeofday(&ts, NULL); \
76 | req->trace_ts = ts.tv_sec * 1000000 + ts.tv_usec; \
77 | req->trace_spanid = 0; \
78 | req->trace_server_id = g_trace_server_id; \
79 | req->trace_main_id = id; \
80 | req->trace_pfs_sub_id = 0; \
81 | trace_set_type(req->trace_flags, TRACE_TYPE_PLS); \
82 | if(SAMPLE_POINT(req->trace_main_id)) \
83 | req->trace_flags |= TRACE_TP_FLAG; \
84 | fprintf(stderr, "[PFS_TRACE_LOG] trace main id %u\n", req->trace_main_id); \
85 | } while(0)
86 |
87 | #else
88 |
89 | #define PFS_SetTraceid(req) do{ } while(0)
90 |
91 | #endif
92 |
93 |
94 | #ifdef __cplusplus
95 | }
96 | #endif
97 |
98 | #endif
99 |
--------------------------------------------------------------------------------
/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (c) 2017-2021, Alibaba Group Holding Limited
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | INSTALL_BASE_DIR="/usr/local/polarstore"
17 |
18 | #uninstall check
19 | exist_command="ps -ef | grep -E 'pfsdaemon|pfs-fuse' | grep -v grep | wc -l"
20 | exist=$(eval $exist_command)
21 | if [ $exist -ge 1 ]; then
22 | echo "pfsd or fuse is running, before uninstall pfsd, please stop pfsd and fuse"
23 | exit 1
24 | fi
25 |
26 | if [[ $EUID -ne 0 ]];then
27 | echo "pfsd uninstall script must be run as root"
28 | exit 1
29 | fi
30 |
31 | #uninstall
32 | rm ${INSTALL_BASE_DIR}/pfsd/include/pfsd_sdk.h
33 | rm ${INSTALL_BASE_DIR}/pfsd/lib/libpfsd.a
34 | rm ${INSTALL_BASE_DIR}/pfsd/lib/libpfsd_test.so
35 | rm ${INSTALL_BASE_DIR}/pfsd/bin/pfsdaemon
36 | rm ${INSTALL_BASE_DIR}/pfsd/bin/pfs-fuse
37 | rm ${INSTALL_BASE_DIR}/pfsd/bin/pfsd_shm_tool
38 | rm ${INSTALL_BASE_DIR}/pfsd/conf/pfsd_logger.conf
39 | rm ${INSTALL_BASE_DIR}/pfsd/bin/start_pfsd.sh
40 | rm ${INSTALL_BASE_DIR}/pfsd/bin/stop_pfsd.sh
41 | rm ${INSTALL_BASE_DIR}/pfsd/bin/mount_pfs_fuse.sh
42 | rm ${INSTALL_BASE_DIR}/pfsd/bin/umount_pfs_fuse.sh
43 | rm ${INSTALL_BASE_DIR}/pfsd/bin/clean_pfsd.sh
44 | rm /etc/init.d/pfsd_env
45 | rm /etc/polarfs.conf
46 |
47 | rm /usr/local/bin/pfs
48 | rm /usr/local/bin/pfsadm
49 |
50 | echo "uninstall pfsd success!"
51 |
--------------------------------------------------------------------------------