├── 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++、libai​o-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 | ![image.png](https://raw.githubusercontent.com/alibaba/PolarDB-for-PostgreSQL/main/doc/PolarDB-EN/pic/polardb_group.png) 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 | --------------------------------------------------------------------------------