New upstream version 8.1.0
This commit is contained in:
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve BeeGFS
|
||||
title: ''
|
||||
labels: bug, new
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is, which component (mgmtd, meta, storage, client, others or any combination) is affected and what effects (error messages, performance degradation, crashes, ...) can be observed.
|
||||
|
||||
**Describe the system**
|
||||
A short description of the system BeeGFS is running on that covers all information relevant to the issue. For example (but not limited to):
|
||||
1. Number and type of BeeGFS services and their distribution across physical machines
|
||||
2. Information about the network interconnect (technology, protocols, topology)
|
||||
3. Information about underlying file systems and storage hardware
|
||||
4. Operating system and proprietary driver information (versions, RDMA drivers)
|
||||
5. Software that is accessing BeeGFS
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Set configuration option "x" to "y" for component "c"
|
||||
2. Start component "c" on machine "m"
|
||||
3. Run application "a" with parameters "p"
|
||||
4. Observe behavior "b"
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Log messages, error outputs**
|
||||
If available, add relevant log files (anonymize if necessary), error messages, `perf` measurements, `strace` outputs, core dumps and everything else you have collected and can share publicly.
|
||||
|
||||
**Additional context**
|
||||
Add any other context not covered above.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest a feature or improvement for BeeGFS
|
||||
title: ''
|
||||
labels: enhancement, new
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the feature request here.
|
||||
140
CMakeLists.txt
Normal file
140
CMakeLists.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
|
||||
project(
|
||||
BeeGFS
|
||||
LANGUAGES CXX C
|
||||
)
|
||||
|
||||
set(BEEGFS_VERSION "" CACHE STRING "Defaults to current git version.")
|
||||
if(BEEGFS_VERSION STREQUAL "")
|
||||
execute_process(
|
||||
COMMAND git describe --match *.* --abbrev=10
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE BEEGFS_VERSION_FROM_GIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(BEEGFS_VERSION_FROM_GIT STREQUAL "")
|
||||
message(FATAL_ERROR "Cannot determine BeeGFS version. Specify with `cmake -DBEEGFS_VERSION=...`")
|
||||
endif()
|
||||
|
||||
set(BEEGFS_VERSION ${BEEGFS_VERSION_FROM_GIT} CACHE STRING "Defaults to current git version" FORCE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBEEGFS_VERSION=\\\"${BEEGFS_VERSION}\\\"")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBEEGFS_VERSION=\\\"${BEEGFS_VERSION}\\\"")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wunused-variable -Woverloaded-virtual -Wno-unused-parameter -Wuninitialized -Wno-missing-field-initializers")
|
||||
|
||||
set(BEEGFS_DEBUG OFF CACHE BOOL "Build with debug information.")
|
||||
if(BEEGFS_DEBUG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBEEGFS_DEBUG=1 -Werror")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBEEGFS_DEBUG=1")
|
||||
endif()
|
||||
|
||||
set(BEEGFS_INSTRUMENTATION "" CACHE STRING "Instrumentation for testing.")
|
||||
if(BEEGFS_INSTRUMENTATION STREQUAL "")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||
elseif(BEEGFS_INSTRUMENTATION STREQUAL "coverage")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -O0")
|
||||
elseif(BEEGFS_INSTRUMENTATION STREQUAL "address")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O0")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||
elseif(BEEGFS_INSTRUMENTATION STREQUAL "thread")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -O0")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||
elseif(BEEGFS_INSTRUMENTATION STREQUAL "undefined")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -O0")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||
elseif(BEEGFS_INSTRUMENTATION STREQUAL "iwyu")
|
||||
if(NOT DEFINED CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
|
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "include-what-you-use")
|
||||
endif()
|
||||
list(APPEND CMAKE_CXX_INCLUDE_WHAT_YOU_USE "-Xiwyu" "--mapping_file=${CMAKE_SOURCE_DIR}/iwyu-mappings.imp")
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid instrumentation.")
|
||||
endif()
|
||||
|
||||
set(BEEGFS_SKIP_TESTS OFF CACHE BOOL "Skip building and running tests.")
|
||||
set(BEEGFS_SKIP_CLIENT OFF CACHE BOOL "Skip building the kernel module.")
|
||||
set(BEEGFS_KERNELDIR "" CACHE PATH "Path to kernel for kernel module (optional).")
|
||||
set(BEEGFS_OFEDDIR "" CACHE PATH "Path to OFED for kernel module (optional).")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb3")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb3")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lrt")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
include_directories(common/source)
|
||||
include_directories(SYSTEM thirdparty/source/boost)
|
||||
include_directories(SYSTEM thirdparty/source/nu/include)
|
||||
include_directories(thirdparty/source/gtest/googletest/include)
|
||||
|
||||
if(NOT BEEGFS_SKIP_TESTS)
|
||||
enable_testing()
|
||||
option(INSTALL_GMOCK OFF)
|
||||
option(INSTALL_GTEST OFF)
|
||||
add_subdirectory("thirdparty/source/gtest")
|
||||
endif()
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "/")
|
||||
|
||||
add_subdirectory("beeond")
|
||||
# add_subdirectory("client_devel")
|
||||
# add_subdirectory("client_module")
|
||||
add_subdirectory("common")
|
||||
add_subdirectory("event_listener")
|
||||
add_subdirectory("fsck")
|
||||
add_subdirectory("meta")
|
||||
add_subdirectory("mon")
|
||||
add_subdirectory("storage")
|
||||
add_subdirectory("utils")
|
||||
|
||||
add_custom_target(
|
||||
dkms-install
|
||||
COMMAND dkms install "beegfs/${BEEGFS_VERSION}"
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
dkms-uninstall
|
||||
COMMAND dkms remove "beegfs/${BEEGFS_VERSION}" --all
|
||||
)
|
||||
|
||||
|
||||
### Packaging settings ###
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "BeeGFS Maintainers <packages@beegfs.com>")
|
||||
set(CPACK_PACKAGE_VENDOR "ThinkparQ GmbH")
|
||||
|
||||
string(REGEX REPLACE "^([^.]+)\\.([^-]+)-([^-]+)(-.*)?$" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${BEEGFS_VERSION}")
|
||||
string(REGEX REPLACE "^([^.]+)\\.([^-]+)-([^-]+)(-.*)?$" "\\2" CPACK_PACKAGE_VERSION_MINOR "${BEEGFS_VERSION}")
|
||||
string(REGEX REPLACE "^([^.]+)\\.([^-]+)-([^-]+)(-.*)?$" "\\3" CPACK_PACKAGE_VERSION_PATCH "${BEEGFS_VERSION}")
|
||||
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
|
||||
|
||||
# silence cpack warnings about non relocatable package.
|
||||
set(CPACK_PACKAGE_RELOCATABLE OFF)
|
||||
set(CPACK_GENERATOR "DEB" "RPM")
|
||||
|
||||
# enable creation of separate packages
|
||||
set(CPACK_DEB_COMPONENT_INSTALL ON)
|
||||
set(CPACK_RPM_COMPONENT_INSTALL ON)
|
||||
|
||||
set(CPACK_STRIP_FILES OFF)
|
||||
|
||||
# cpack tries to create these directories with nonstandard /
|
||||
# conflicting permissions in some versions. solve by assuming that
|
||||
# these directories already exist.
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/sbin;/usr/sbin")
|
||||
|
||||
include(CPack)
|
||||
118
CODE_OF_CONDUCT.md
Normal file
118
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# BeeGFS Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as BeeGFS contributors and maintainers pledge to make participation in our community a
|
||||
harassment-free experience for everyone, regardless of age, body size, visible or invisible
|
||||
disability, ethnicity, sex characteristics, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or
|
||||
sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and
|
||||
healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the
|
||||
experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address, without their
|
||||
explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
The BeeGFS community managers are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in response to any behavior
|
||||
that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
The BeeGFS community managers have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of
|
||||
Conduct, and will communicate reasons for moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when an individual is
|
||||
officially representing the community in public spaces. Examples of representing our community
|
||||
include using an official email address, posting via an official social media account, or acting as
|
||||
an appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community
|
||||
managers responsible for enforcement at
|
||||
[community-managers@thinkparq.com](mailto:community-managers@thinkparq.com). All complaints will be
|
||||
reviewed and investigated promptly and fairly.
|
||||
|
||||
All community managers are obligated to respect the privacy and security of the reporter of any
|
||||
incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community managers will follow these Community Impact Guidelines in determining the consequences for
|
||||
any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or
|
||||
unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community managers, providing clarity around the
|
||||
nature of the violation and an explanation of why the behavior was inappropriate. A public apology
|
||||
may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with the people
|
||||
involved, including unsolicited interaction with those enforcing the Code of Conduct, for a
|
||||
specified period of time. This includes avoiding interactions in community spaces as well as
|
||||
external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including sustained inappropriate
|
||||
behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the
|
||||
community for a specified period of time. No public or private interaction with the people involved,
|
||||
including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this
|
||||
period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including
|
||||
sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement
|
||||
of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla
|
||||
CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
66
CONTRIBUTING.md
Normal file
66
CONTRIBUTING.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Contributing <!-- omit in toc -->
|
||||
Thank you for your interest in contributing to `beegfs`! 🎉
|
||||
|
||||
We appreciate that you want to take the time to contribute. Please follow these steps before
|
||||
submitting your PR.
|
||||
|
||||
# Contents <!-- omit in toc -->
|
||||
|
||||
- [ThinkParQ Contributor License Agreement (CLA)](#thinkparq-contributor-license-agreement-cla)
|
||||
- [Creating a Pull Request](#creating-a-pull-request)
|
||||
- [Our Commitment](#our-commitment)
|
||||
|
||||
# ThinkParQ Contributor License Agreement (CLA)
|
||||
|
||||
Before contributions can be accepted we must have a signed CLA on file for all contributor(s):
|
||||
|
||||
* Download and fill out and sign the ThinkParQ CLA found at:
|
||||
https://www.beegfs.io/docs/ThinkParQ_CLA.pdf.
|
||||
* Email your signed copy to <info@thinkparq.com>.
|
||||
|
||||
|
||||
# Creating a Pull Request
|
||||
|
||||
1. Please search [existing issues](https://github.com/ThinkParQ/beegfs/issues) to determine if an
|
||||
issue already exists for what you intend to contribute.
|
||||
2. If the issue does not exist, [create a new
|
||||
one](https://github.com/ThinkParQ/beegfs/issues/new) that explains the bug or feature request.
|
||||
* Let us know in the issue that you plan on creating a pull request for it. This helps us to keep
|
||||
track of the pull request and avoid any duplicate efforts.
|
||||
3. Before creating a pull request, write up a brief proposal in the issue describing what your
|
||||
change would be and how it would work so that others can comment.
|
||||
* It's better to wait for feedback from the maintainers before writing code. We don't have an
|
||||
SLA for our feedback, but we will do our best to respond in a timely manner (at a minimum, to
|
||||
give you an idea if you're on the right track and that you should proceed, or not).
|
||||
4. When ready refer to the guidelines and process for submitting a [Pull
|
||||
Request](https://github.com/ThinkParQ/beegfs-go/wiki/Pull-Requests).
|
||||
|
||||
|
||||
# Our Commitment
|
||||
While we truly appreciate your efforts on pull requests and will accept contributions as often as we
|
||||
can, we **cannot** commit to accepting all PRs. Here are a few reasons why a PR may be rejected:
|
||||
|
||||
* There are many factors involved in integrating new code into this project including:
|
||||
* Adding appropriate unit and end-to-end test coverage for new/changed functionality.
|
||||
* Ensuring adherence with ThinkParQ and industry standards around security and licensing.
|
||||
* Validating new functionality doesn't raise long-term maintainability and/or supportability
|
||||
concerns.
|
||||
* Verifying changes fit with the current and/or planned architecture.
|
||||
* etc.
|
||||
|
||||
In other words, while your bug fix or feature may be perfect as a standalone patch, we have to
|
||||
ensure the changes also work in all use cases, supported, configurations, and across our support
|
||||
matrix.
|
||||
|
||||
* The BeeGFS development team must plan resources to integrate your code into our code base and CI
|
||||
platform, and depending on the complexity of your PR, we may or may not have the resources
|
||||
available to make it happen in a timely fashion. We'll do our best, but typically the earliest
|
||||
changes can be merged into the master branch is with our next formal release, unless they resolve
|
||||
a critical bug or security vulnerability.
|
||||
|
||||
* Sometimes a PR doesn't fit into our future plans or conflicts with other items on the roadmap.
|
||||
It's possible that a PR you submit doesn't align with our upcoming plans, thus we won't be able to
|
||||
use it. It's not personal and why we highly recommend submitting an issue with your proposed
|
||||
changes so we can provide feedback before you expend significant effort on development.
|
||||
|
||||
Thank you for considering to contribute to `beegfs`!
|
||||
48
LICENSE.txt
Normal file
48
LICENSE.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
BeeGFS END USER LICENSE AGREEMENT
|
||||
=================================
|
||||
|
||||
Copyright (c) 2009 Fraunhofer ITWM, 2022 ThinkParQ GmbH
|
||||
|
||||
Use of the provided software and libraries is governed by the BeeGFS End User License Agreement
|
||||
found at https://www.beegfs.io/docs/BeeGFS_EULA.txt.
|
||||
|
||||
THIRD PARTY LICENSES
|
||||
====================
|
||||
|
||||
Paul Hsieh OLD BSD license
|
||||
--------------------------
|
||||
|
||||
The files `common/source/common/toolkit/BufferTk.cpp` and `client_module/source/common/toolkit/
|
||||
HashTk.c` contain a hash implementation distributed under the following license:
|
||||
|
||||
Copyright (c) 2010, Paul Hsieh All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
Neither my name, Paul Hsieh, nor the names of any other contributors to the code use may
|
||||
be used to endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR SEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ANY
|
||||
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
See http://www.azillionmonkeys.com/qed/hash.html and http://www.azillionmonkeys.com/qed/weblicense.html.
|
||||
|
||||
Other third party code
|
||||
----------------------
|
||||
|
||||
The directory `thirdparty` contains code distributed under the terms of the included license files.
|
||||
198
Makefile
Normal file
198
Makefile
Normal file
@@ -0,0 +1,198 @@
|
||||
# all variables used by package builds must be exported.
|
||||
export BEEGFS_DEBUG
|
||||
export USER_CXXFLAGS
|
||||
export USER_LDFLAGS
|
||||
export BEEGFS_DEBUG_RDMA
|
||||
export BEEGFS_DEBUG_IP
|
||||
|
||||
export KDIR
|
||||
export KSRCDIR
|
||||
|
||||
BEEGFS_THIRDPARTY_OPTIONAL =
|
||||
export BEEGFS_THIRDPARTY_OPTIONAL
|
||||
|
||||
WITHOUT_COMM_DEBUG = true
|
||||
|
||||
# if version is not set, derive from current git.
|
||||
# debian epoch for unversioned builds (usually dev builds) is 19 because it was 18 previously.
|
||||
# versioned builds (usually from tags) are set to epoch 20, allowing upgrades from all previous versions.
|
||||
ifndef BEEGFS_VERSION
|
||||
BEEGFS_VERSION := $(shell git describe --tags --match '*.*' --abbrev=10)
|
||||
BEEGFS_EPOCH := 19
|
||||
else
|
||||
BEEGFS_EPOCH := 20
|
||||
endif
|
||||
|
||||
# underscores are not allowed in version strings, because they are not valid semver
|
||||
ifneq (,$(findstring _,$(BEEGFS_VERSION)))
|
||||
$(error Underscores not allowed in versions. BEEGFS_VERSION is $(BEEGFS_VERSION))
|
||||
endif
|
||||
|
||||
# dashes in semver for pre-releases should be converted to tildes for package managers in the
|
||||
# distributions we support
|
||||
BEEGFS_VERSION_RPM := $(subst -,~,$(BEEGFS_VERSION))
|
||||
BEEGFS_VERSION_DEB := $(BEEGFS_EPOCH):$(subst -,~,$(BEEGFS_VERSION))
|
||||
export BEEGFS_VERSION
|
||||
|
||||
ifneq ($(NVFS_INCLUDE_PATH),)
|
||||
BEEGFS_NVFS=1
|
||||
endif
|
||||
export BEEGFS_NVFS
|
||||
|
||||
PREFIX ?= /opt/beegfs
|
||||
DESTDIR ?=
|
||||
|
||||
DAEMONS := meta storage mon
|
||||
UTILS := fsck event_listener $(if $(WITHOUT_COMM_DEBUG),,comm_debug)
|
||||
|
||||
# exclude components with no runnable tests from `test'.
|
||||
DO_NOT_TEST := thirdparty event_listener
|
||||
|
||||
ALL_COMPONENTS := thirdparty common $(DAEMONS) $(UTILS)
|
||||
TIDY_COMPONENTS := $(filter-out thirdparty event_listener, $(ALL_COMPONENTS))
|
||||
|
||||
all: daemons utils client
|
||||
|
||||
.PHONY: daemons
|
||||
daemons: $(patsubst %,%-all,$(DAEMONS))
|
||||
@
|
||||
|
||||
.PHONY: utils
|
||||
utils: $(patsubst %,%-all,$(UTILS))
|
||||
@
|
||||
|
||||
.PHONY: $(patsubst %,%-all,$(DAEMONS) $(UTILS))
|
||||
$(patsubst %,%-all,$(DAEMONS) $(UTILS)): common-all
|
||||
$(MAKE) -C $(subst -all,,$@)/build all
|
||||
|
||||
.PHONY: common-all common
|
||||
common-all: thirdparty
|
||||
$(MAKE) -C common/build all
|
||||
|
||||
.PHONY: thirdparty
|
||||
thirdparty:
|
||||
$(MAKE) -C thirdparty/build all $(BEEGFS_THIRDPARTY_OPTIONAL)
|
||||
|
||||
.PHONY: client
|
||||
client:
|
||||
$(MAKE) -C client_module/build
|
||||
|
||||
.PHONY: tidy
|
||||
tidy: $(addsuffix -tidy,$(TIDY_COMPONENTS))
|
||||
@
|
||||
|
||||
define tidy_component
|
||||
.PHONY: $1-tidy
|
||||
$1-tidy:
|
||||
+$(MAKE) -C $1/build tidy
|
||||
endef
|
||||
|
||||
$(foreach C,$(TIDY_COMPONENTS),$(eval $(call tidy_component,$(C))))
|
||||
|
||||
_tested_components := $(filter-out $(DO_NOT_TEST),$(ALL_COMPONENTS))
|
||||
|
||||
.PHONY: test
|
||||
test: $(patsubst %,%-test,$(_tested_components))
|
||||
@
|
||||
|
||||
define test_component
|
||||
.PHONY: $1-test
|
||||
$1-test: $1-all
|
||||
cd $1/build && ./test-runner --compiler
|
||||
endef
|
||||
|
||||
$(foreach C,$(_tested_components),$(eval $(call test_component,$(C))))
|
||||
|
||||
.PHONY: install
|
||||
install: daemons-install utils-install common-install client-install event_listener-install
|
||||
@
|
||||
|
||||
define install_component
|
||||
.PHONY: $1-install
|
||||
$1-install: $1-all
|
||||
install -t $(DESTDIR)/$(PREFIX)/$2 -D \
|
||||
$1/build/beegfs-$$(or $$(install_name),$1)
|
||||
endef
|
||||
|
||||
comm_debug-install: install_name=comm-debug
|
||||
|
||||
$(foreach D,$(DAEMONS),$(eval $(call install_component,$D,sbin)))
|
||||
$(foreach U,$(filter-out event_listener,$(UTILS)),$(eval $(call install_component,$U,sbin)))
|
||||
|
||||
.PHONY: daemons-install
|
||||
daemons-install: $(patsubst %,%-install,$(DAEMONS))
|
||||
@
|
||||
|
||||
.PHONY: utils-install
|
||||
utils-install: $(patsubst %,%-install,$(UTILS))
|
||||
@
|
||||
|
||||
.PHONY: common-install
|
||||
common-install: common-all
|
||||
install -t $(DESTDIR)/$(PREFIX)/lib -D \
|
||||
common/build/libbeegfs_ib.so
|
||||
|
||||
.PHONY: client-install
|
||||
client-install: client
|
||||
install -t $(DESTDIR)/$(PREFIX)/lib/modules/$(KVER)/kernel/beegfs -D \
|
||||
client_module/build/beegfs.ko
|
||||
|
||||
## Overriding previous generic rule due to non-matching executable name
|
||||
.PHONY: event_listener-intsall
|
||||
event_listener-install: event_listener-all
|
||||
install -t $(DESTDIR)/$(PREFIX)/sbin -D \
|
||||
event_listener/build/beegfs-event-listener
|
||||
|
||||
.PHONY: clean
|
||||
clean: $(patsubst %,%-clean,$(ALL_COMPONENTS)) client-clean
|
||||
@
|
||||
|
||||
.PHONY: $(patsubst %,%-clean,$(ALL_COMPONENTS))
|
||||
$(patsubst %,%-clean,$(ALL_COMPONENTS)):
|
||||
$(MAKE) -C $(subst -clean,,$@)/build clean
|
||||
|
||||
.PHONY: client-clean
|
||||
client-clean:
|
||||
$(MAKE) -C client_module/build clean
|
||||
|
||||
# use DEBUILD_OPTS to pass more options to debuild, eg
|
||||
# DEBUILD_OPTS='-j32 --prepend-path=/usr/lib/ccache'
|
||||
# for greater concurrency during build and ccache support
|
||||
.PHONY: package-deb
|
||||
package-deb: clean
|
||||
[ '$(PACKAGE_DIR)' ] || { echo need a PACKAGE_DIR >&2; false; }
|
||||
! [ -d '$(PACKAGE_DIR)' ] || { echo choose a new directory for PACKAGE_DIR, please >&2; false; }
|
||||
mkdir -p '$(PACKAGE_DIR)'
|
||||
cd '$(PACKAGE_DIR)' && \
|
||||
dpkg-source -I '-I$(PACKAGE_DIR)' -z1 -b '$(dir $(realpath $(firstword $(MAKEFILE_LIST))))' && \
|
||||
rm -rf build && \
|
||||
dpkg-source -x *.dsc build && \
|
||||
( \
|
||||
cd build; \
|
||||
sed -i -e 's/beegfs (.*)/beegfs ($(BEEGFS_VERSION_DEB))/' debian/changelog; \
|
||||
sed -i -e 's/@DATE/$(shell date -R)/' debian/changelog; \
|
||||
debuild -eBEEGFS_\* $(DEBUILD_OPTS) -us -uc -b 2>&1 | grep -Ev "dir-or-file-in-opt" \
|
||||
) && \
|
||||
rm -rf build *.dsc *.tar.gz \
|
||||
# Replace tilde in package filename with hypens.
|
||||
# Github release action and api substitutes tilde (~) with dot (.) in file names when uploaded to Github packages.
|
||||
find -type f -name "*~*.deb" -exec bash -c 'mv "$$1" "$${1//\~/-}"' _ {} \;
|
||||
|
||||
# use RPMBUILD_OPTS to pass more options to rpmuild, eg
|
||||
# RPMBUILD_OPTS='-D "MAKE_CONCURRENCY 32"'
|
||||
# for greater concurrency during build
|
||||
.PHONY: package-rpm
|
||||
package-rpm: clean
|
||||
[ '$(PACKAGE_DIR)' ] || { echo need a PACKAGE_DIR >&2; false; }
|
||||
! [ -d '$(PACKAGE_DIR)' ] || { echo choose a new directory for PACKAGE_DIR, please >&2; false; }
|
||||
mkdir -p $(PACKAGE_DIR)/SOURCES
|
||||
tar --exclude $(PACKAGE_DIR) --exclude .git --exclude .ccache \
|
||||
-cf $(PACKAGE_DIR)/SOURCES/beegfs-$(BEEGFS_VERSION_RPM).tar .
|
||||
rpmbuild --clean -bb beegfs.spec \
|
||||
--define '_topdir $(abspath $(PACKAGE_DIR))' \
|
||||
--define 'EPOCH $(BEEGFS_EPOCH)' \
|
||||
--define 'BEEGFS_VERSION $(BEEGFS_VERSION_RPM)' \
|
||||
$(RPMBUILD_OPTS) \
|
||||
# Replace tilde in package filename with hypens.
|
||||
# Github release action and api substitutes tilde (~) with dot (.) in file names when uploaded to Github packages.
|
||||
find $(PACKAGE_DIR)/RPMS -type f -name "*~*.rpm" -exec bash -c 'mv "$$1" "$${1//\~/-}"' _ {} \;
|
||||
185
README.md
Normal file
185
README.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# BeeGFS Parallel File System
|
||||
BeeGFS (formerly FhGFS) is the leading parallel cluster file system, developed with a strong focus
|
||||
on performance and designed for very easy installation and management. If I/O intensive workloads
|
||||
are your problem, BeeGFS is the solution.
|
||||
|
||||
Homepage: https://www.beegfs.io
|
||||
|
||||
Documentation: https://doc.beegfs.io/
|
||||
|
||||
# Getting Started with BeeGFS
|
||||
|
||||
## How do I download BeeGFS?
|
||||
|
||||
If you don't need/want to build BeeGFS from sources, prebuilt packages for both x86 and ARM [are
|
||||
available](https://www.beegfs.io/c/download/) for many popular Linux distributions.
|
||||
|
||||
## How do I build BeeGFS from sources?
|
||||
|
||||
Prior to BeeGFS 8, all development happened in a private Git repository, with the source code for
|
||||
each release squashed into a single commit in the public Git repository. As part of BeeGFS 8, the
|
||||
opportunity came up to rewrite some components and make the full history of the new components
|
||||
public. For this to happen the source code is split across these repositories:
|
||||
|
||||
* `beegfs` - The main public repository containing all original C/C++ components, notably the
|
||||
Metadata and Storage services along with the Client kernel module and file system checker.
|
||||
* `beegfs-rust` - New BeeGFS components written in Rust, notably the Management service.
|
||||
* `beegfs-go` - New BeeGFS components written in Go, notably the BeeGFS command-line tool (CTL).
|
||||
* `protobuf` - Common protocol buffer and gRPC service definitions along with generated library code
|
||||
to interact with new BeeGFS services from multiple languages including C++, Go, Rust, etc.
|
||||
* For Go, comprehensive libraries for fully managing BeeGFS can be found in `beegfs-go`.
|
||||
|
||||
It is only necessary to clone the repo(s) containing the component(s) you wish to modify or build
|
||||
from sources. If you wanted to build everything you would need to clone all three repositories:
|
||||
|
||||
* `git clone git@github.com:ThinkParQ/beegfs.git`
|
||||
* `git clone git@github.com:ThinkParQ/beegfs-rust.git`
|
||||
* `git clone git@github.com:ThinkParQ/beegfs-go.git`
|
||||
|
||||
Then refer to each repositories' README for directions on how to get started including installing any
|
||||
prerequisites and building packaged or unpackaged binaries for the components provided by that repo.
|
||||
|
||||
Note: It is not necessary to clone the `protobuf` repo to build BeeGFS from sources. This is only
|
||||
needed to modify the protocol buffers or develop an application that integrates with BeeGFS.
|
||||
|
||||
# Getting Started with BeeGFS C/C++ Components (this repo)
|
||||
|
||||
## Prerequisites
|
||||
Before building BeeGFS, install the following dependency packages:
|
||||
|
||||
### Red Hat / CentOS
|
||||
```
|
||||
$ yum install libuuid-devel libibverbs-devel librdmacm-devel libattr-devel redhat-rpm-config \
|
||||
rpm-build xfsprogs-devel zlib-devel gcc-c++ gcc \
|
||||
redhat-lsb-core unzip libcurl-devel elfutils-libelf-devel kernel-devel \
|
||||
libblkid-devel libnl3-devel
|
||||
```
|
||||
|
||||
The `elfutils-libelf-devel` and `kernel-devel` packages can be omitted if you don't intend to
|
||||
build the client module.
|
||||
|
||||
On RHEL releases older than 8, the additional `devtoolset-7` package is also required,
|
||||
which provides a newer compiler version. The installation steps are outlined here.
|
||||
Please consult the documentation of your distribution for details.
|
||||
|
||||
1. Install a package with repository for your system:
|
||||
- On CentOS, install package centos-release-scl available in CentOS repository:
|
||||
```
|
||||
$ sudo yum install centos-release-scl
|
||||
```
|
||||
- On RHEL, enable RHSCL repository for you system:
|
||||
```
|
||||
$ sudo yum-config-manager --enable rhel-server-rhscl-7-rpms
|
||||
```
|
||||
2. Install the collection:
|
||||
```
|
||||
$ sudo yum install devtoolset-7
|
||||
```
|
||||
|
||||
3. Start using software collections:
|
||||
```
|
||||
$ scl enable devtoolset-7 bash
|
||||
```
|
||||
4. Follow the instructions below to build BeeGFS.
|
||||
|
||||
### Debian and Ubuntu
|
||||
|
||||
#### Option 1: Semi-automatic installation of build dependencies
|
||||
|
||||
Install required utilities:
|
||||
```
|
||||
$ apt install --no-install-recommends devscripts equivs
|
||||
```
|
||||
Automatically install build dependencies:
|
||||
```
|
||||
$ mk-build-deps --install debian/control
|
||||
```
|
||||
|
||||
#### Option 2: Manual installation of build dependencies
|
||||
|
||||
Run this command to install the required packages:
|
||||
```
|
||||
$ sudo apt install build-essential autoconf automake pkg-config devscripts debhelper \
|
||||
libtool libattr1-dev xfslibs-dev lsb-release kmod librdmacm-dev libibverbs-dev \
|
||||
default-jdk zlib1g-dev libssl-dev libcurl4-openssl-dev libblkid-dev uuid-dev \
|
||||
libnl-3-200 libnl-3-dev libnl-genl-3-200 libnl-route-3-200 libnl-route-3-dev dh-dkms
|
||||
```
|
||||
Note: If you have an older Debian system you might have to install the `module-init-tools`
|
||||
package instead of `kmod`. You also have the choice between the openssl, nss, or gnutls version
|
||||
of `libcurl-dev`. Choose the one you prefer. On Debian versions older than 12, replace `dh-dkms`
|
||||
by `dkms`.
|
||||
|
||||
## Building Packages
|
||||
|
||||
### For development systems
|
||||
|
||||
BeeGFS comes with a Makefile capable of building packages for the system on which it is executed.
|
||||
These include all services, the client module and utilities.
|
||||
|
||||
To build RPM packages, run
|
||||
```
|
||||
$ make package-rpm PACKAGE_DIR=packages
|
||||
```
|
||||
You may also enable parallel execution with
|
||||
```
|
||||
$ make package-rpm PACKAGE_DIR=packages RPMBUILD_OPTS="-D 'MAKE_CONCURRENCY <n>'"
|
||||
```
|
||||
where `<n>` is the number of concurrent processes.
|
||||
|
||||
For DEB packages use this command:
|
||||
```
|
||||
$ make package-deb PACKAGE_DIR=packages
|
||||
```
|
||||
Or start with `<n>` jobs running in parallel:
|
||||
```
|
||||
$ make package-deb PACKAGE_DIR=packages DEBUILD_OPTS="-j<n>"
|
||||
```
|
||||
|
||||
This will generate individual packages for each service (management, meta-data, storage)
|
||||
as well as the client kernel module and administration tools.
|
||||
|
||||
The above examples use `packages` as the output folder for packages, which must not exist
|
||||
and will be created during the build process.
|
||||
You may specify any other non-existent directory instead.
|
||||
|
||||
Note, however, that having `PACKAGE_DIR` on a NFS or similar network share may slow down
|
||||
the build process significantly.
|
||||
|
||||
### For production systems, or from source snapshots
|
||||
|
||||
By default the packaging system generates version numbers suitable only for development
|
||||
packages. Packages intended for installation on production systems must be built differently.
|
||||
All instructions to build development packages (as given above) apply, but additionally the
|
||||
package version must be explicitly set. This is done by passing `BEEGFS_VERSION=<version>`
|
||||
in the make command line, e.g.
|
||||
```
|
||||
$ make package-deb PACKAGE_DIR=packages DEBUILD_OPTS="-j<n>" BEEGFS_VERSION=7.1.4-local1
|
||||
```
|
||||
|
||||
Setting the version explicitly is required to generate packages that can be easily upgraded
|
||||
with the system package manager.
|
||||
|
||||
|
||||
## Building without packaging
|
||||
To build the complete project without generating any packages,
|
||||
simply run
|
||||
```
|
||||
$ make
|
||||
```
|
||||
|
||||
The sub-projects have individual make targets, for example `storage-all`,
|
||||
`meta-all`, etc.
|
||||
|
||||
To speed things you can use the `-j` option of `make`.
|
||||
Additionally, the build system supports `distcc`:
|
||||
```
|
||||
$ make DISTCC=distcc
|
||||
```
|
||||
|
||||
# Setup Instructions
|
||||
Detailed guides on how to configure BeeGFS can be found at
|
||||
[doc.beegfs.io](https://doc.beegfs.io/latest/index.html)
|
||||
|
||||
# Share your thoughts
|
||||
Of course, we are curious about what you are doing with the BeeGFS sources, so
|
||||
don't forget to drop us a note...
|
||||
137
SUPPORT.md
Normal file
137
SUPPORT.md
Normal file
@@ -0,0 +1,137 @@
|
||||
Support for BeeGFS <!-- omit in toc -->
|
||||
==================
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Documentation](#documentation)
|
||||
- [Community Support](#community-support)
|
||||
- [Enterprise Support](#enterprise-support)
|
||||
- [Support Lifecycle and Policies](#support-lifecycle-and-policies)
|
||||
- [BeeGFS Versioning](#beegfs-versioning)
|
||||
- [Release Lifecycle](#release-lifecycle)
|
||||
- [End-of-Life (EOL)](#end-of-life-eol)
|
||||
- [End-of-Support (EOS)](#end-of-support-eos)
|
||||
- [Example Scenarios](#example-scenarios)
|
||||
|
||||
# Overview
|
||||
The BeeGFS community edition is available free of charge and shares a common codebase with our
|
||||
[enterprise edition](https://www.beegfs.io/c/enterprise/enterprise-features/). The enterprise
|
||||
edition includes support alongside additional features, and is how we fund ongoing BeeGFS
|
||||
development. Regardless of whether you use the paid or community edition, we welcome [GitHub
|
||||
issues](https://github.com/ThinkParQ/beegfs/issues) for bugs and feature requests from everyone in
|
||||
our community.
|
||||
|
||||
**Please note:** GitHub issues are not the place for general questions on how to deploy or use
|
||||
BeeGFS. Refer to the resources below. If you are unsure if your issue is a bug or "working as
|
||||
designed," feel free to open an issue, and we will politely direct you to community support options
|
||||
if necessary.
|
||||
|
||||
Thank you for being part of the BeeGFS community!
|
||||
|
||||
# Documentation
|
||||
|
||||
* [BeeGFS Documentation Site](https://doc.beegfs.io).
|
||||
* [Building BeeGFS from sources](README.md) (for developers).
|
||||
* Check out the [contributing guide](CONTRIBUTING.md) if you'd like to contribute to BeeGFS!
|
||||
|
||||
# Community Support
|
||||
|
||||
BeeGFS is fortunate to have an active community of users who are often willing to help with general
|
||||
questions on designing, deploying, and otherwise administering BeeGFS.
|
||||
|
||||
* [BeeGFS Google Groups](https://groups.google.com/g/fhgfs-user).
|
||||
* [GitHub Discussions](https://github.com/ThinkParQ/beegfs/discussions).
|
||||
|
||||
While our team moderates these forums to ensure posts are on-topic and meet our [Code of
|
||||
Conduct](code-of-conduct.md), we generally do not actively respond to posts. However, we are always
|
||||
keeping an eye out for ways to improve BeeGFS and our documentation.
|
||||
|
||||
# Enterprise Support
|
||||
|
||||
The BeeGFS [enterprise edition](https://www.beegfs.io/c/enterprise/enterprise-features/) offers:
|
||||
|
||||
- Dedicated support from BeeGFS experts.
|
||||
- Access to features not available in the community edition such as storage pools and quotas.
|
||||
- Assistance with designing, deploying, and managing BeeGFS.
|
||||
|
||||
If you are a current BeeGFS enterprise customer with a valid support contract, please contact our
|
||||
support team via the channels specified in your support contract documentation.
|
||||
|
||||
If you are interested in enterprise support, professional services, or learning more about the
|
||||
additional features of the enterprise edition, please contact us at
|
||||
[info@thinkparq.com](mailto:info@thinkparq.com).
|
||||
|
||||
# Support Lifecycle and Policies
|
||||
|
||||
## BeeGFS Versioning
|
||||
Starting with BeeGFS 8, we will more strictly adhere to [Semantic Versioning](https://semver.org/)
|
||||
to ensure a predictable and consistent support lifecycle. BeeGFS releases follow a MAJOR.MINOR.PATCH
|
||||
versioning scheme, where:
|
||||
|
||||
* Major releases (e.g., 8.x) introduce breaking changes and new features.
|
||||
* Minor releases (e.g., 8.1, 8.2) add functionality in a backward-compatible manner.
|
||||
* Note: Enabling new functionality typically requires all components to be on the same version
|
||||
otherwise older components may see errors about unknown functionality.
|
||||
* Patch releases (e.g., 8.0.1, 8.1.2) contain only backward-compatible bug fixes and security
|
||||
updates.
|
||||
|
||||
## Release Lifecycle
|
||||
|
||||
* Latest Major Release (e.g., BeeGFS 8.x)
|
||||
* Actively maintained with bug fixes, security patches, and feature enhancements.
|
||||
* Receives support for new operating systems, kernels, and DOCA/OFED versions.
|
||||
* New deployments are recommended to use this version to ensure continued support without
|
||||
requiring a major upgrade.
|
||||
* Previous Major Releases (e.g., BeeGFS 7.x)
|
||||
* Receive critical security and stability fixes until the release reaches EOL.
|
||||
* Receive best effort support for new operating systems, kernels, and DOCA/OFED versions until the
|
||||
release reaches EOL.
|
||||
* New deployments are strongly discouraged from using these versions.
|
||||
* Minor and Patch Releases (e.g., 8.1.0, 8.0.1)
|
||||
* To receive bug fixes and security patches, users must upgrade to the latest available patch or
|
||||
minor version within their major release, as fixes will not be backported to older minor
|
||||
versions.
|
||||
|
||||
## End-of-Life (EOL)
|
||||
|
||||
* A BeeGFS release reaches EOL when it no longer receives regular updates, including:
|
||||
* Bug fixes
|
||||
* Security patches
|
||||
* Support for new OS/kernel/DOCA/OFED versions.
|
||||
* New deployments should not be performed using a release that has reached EOL.
|
||||
* Users with active support contracts for systems originally deployed on that version may still
|
||||
receive best-effort patches if they cannot upgrade to the latest major version due to
|
||||
incompatibilities.
|
||||
* Patches made after a release reaches EOL will typically be private unless they address a
|
||||
security vulnerability that affects all users.
|
||||
* EOL timing: When a new major BeeGFS is made available, adoption trends, stability, and customer
|
||||
feedback are considered before announcing the EOL date for the previous major release. Generally
|
||||
the EOL date will be no less than 12 months from the release date of the new major version.
|
||||
|
||||
## End-of-Support (EOS)
|
||||
|
||||
* When a BeeGFS release reaches EOS it is considered obsolete and no further updates will be
|
||||
made—even for customers with a support contract.
|
||||
* EOS timing: Depending on customer demand and extended support contracts EOS will typically follow
|
||||
EOL by 12-24 months.
|
||||
* ThinkParQ support will assist all customers holding a valid support contract regardless if the
|
||||
BeeGFS version has reached EOS.
|
||||
|
||||
If support identifies a software issue in an EOS release, the recommended action will be to upgrade
|
||||
to a supported version where the issue is (or can be) resolved. Support will assist as needed to
|
||||
define a recommended upgrade path.
|
||||
|
||||
## Example Scenarios
|
||||
|
||||
* A user with/without support running BeeGFS 8.0.0 finds a bug before BeeGFS 7 reaches EOL:
|
||||
* If critical, it may be fixed in a patch release (8.0.1).
|
||||
* If less severe or found/fixed close to the next scheduled release, it may be fixed in a minor
|
||||
release (8.1.0).
|
||||
* If this bug also affects BeeGFS 7, it would be backported to the latest 7.x patch release (e.g.,
|
||||
7.4.x).
|
||||
* A user with support running BeeGFS 7 after it reaches EOL finds a bug impacting performance or
|
||||
stability:
|
||||
* If the bug affects BeeGFS 8 and has not yet been fixed, a fix will be made in the latest 8.x
|
||||
release and the user advised to upgrade if possible.
|
||||
* If the user is unable to upgrade to BeeGFS 8 due to incompatibilities in their OS/kernel/etc.,
|
||||
the feasibility of patching BeeGFS 7 will be evaluated and decided on a case-by-case basis
|
||||
working in conjunction with the user to identify the best possible solution.
|
||||
631
beegfs.spec
Normal file
631
beegfs.spec
Normal file
@@ -0,0 +1,631 @@
|
||||
%define VER %(echo '%{BEEGFS_VERSION}' | cut -d - -f 1)
|
||||
|
||||
%define BEEGFS_MAJOR_VERSION %(echo '%{BEEGFS_VERSION}' | cut -d . -f 1)
|
||||
%define CLIENT_DIR /opt/beegfs/src/client/client_module_%{BEEGFS_MAJOR_VERSION}
|
||||
%define CLIENT_COMPAT_DIR /opt/beegfs/src/client/client_compat_module_%{BEEGFS_MAJOR_VERSION}
|
||||
|
||||
%define is_sles %(test -f /etc/os-release && grep -q "openSUSE" /etc/os-release || test -f /etc/SUSEConnect && echo 1 || echo 0)
|
||||
|
||||
%if %is_sles
|
||||
%define distver %(release="`rpm -qf --queryformat='%%{VERSION}' /etc/os-release 2> /dev/null | tr . : | sed s/:.*$//g`" ; if test $? != 0 ; then release="" ; fi ; echo "$release")
|
||||
%define RELEASE sles%{distver}
|
||||
|
||||
%else
|
||||
%if %{defined ?dist}
|
||||
%define RELEASE %(tr -d . <<< %{?dist})
|
||||
|
||||
%else
|
||||
%define RELEASE generic
|
||||
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%define post_package() if [ "$1" = 1 ] \
|
||||
then \
|
||||
output=$(systemctl is-system-running 2> /dev/null) \
|
||||
if [ "$?" == 127 ] \
|
||||
then \
|
||||
chkconfig %1 on \
|
||||
elif [ "$?" == 0 ] || ( [ "$output" != "offline" ] && [ "$output" != "unknown" ] ) \
|
||||
then \
|
||||
systemctl enable %1.service \
|
||||
else \
|
||||
chkconfig %1 on \
|
||||
fi \
|
||||
fi
|
||||
|
||||
%define preun_package() if [ "$1" = 0 ] \
|
||||
then \
|
||||
output=$(systemctl is-system-running 2> /dev/null) \
|
||||
if [ "$?" == 127 ] \
|
||||
then \
|
||||
chkconfig %1 off \
|
||||
elif [ "$?" == 0 ] || ( [ "$output" != "offline" ] && [ "$output" != "unknown" ] ) \
|
||||
then \
|
||||
systemctl disable %1.service \
|
||||
else \
|
||||
chkconfig %1 off \
|
||||
fi \
|
||||
fi
|
||||
|
||||
|
||||
Name: beegfs
|
||||
Summary: BeeGFS parallel file system
|
||||
License: BeeGFS EULA
|
||||
Version: %{VER}
|
||||
Release: %{RELEASE}
|
||||
URL: http://www.beegfs.io
|
||||
Source: beegfs-%{BEEGFS_VERSION}.tar
|
||||
Vendor: ThinkParQ GmbH
|
||||
BuildRoot: %{_tmppath}/beegfs-root
|
||||
Epoch: %{EPOCH}
|
||||
|
||||
%description
|
||||
|
||||
Distribution of the BeeGFS parallel filesystem.
|
||||
|
||||
%clean
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%prep
|
||||
%setup -c
|
||||
|
||||
%define make_j %{?MAKE_CONCURRENCY:-j %{MAKE_CONCURRENCY}}
|
||||
|
||||
%build
|
||||
|
||||
export BEEGFS_VERSION=%{BEEGFS_VERSION}
|
||||
export WITHOUT_COMM_DEBUG=1
|
||||
export BEEGFS_NVFS=1
|
||||
|
||||
make %make_j daemons utils
|
||||
|
||||
%install
|
||||
|
||||
export BEEGFS_VERSION=%{BEEGFS_VERSION}
|
||||
export WITHOUT_COMM_DEBUG=1
|
||||
|
||||
|
||||
# makefiles need some adjustments still
|
||||
mkdir -p \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/sbin \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/lib \
|
||||
${RPM_BUILD_ROOT}/usr/bin \
|
||||
${RPM_BUILD_ROOT}/usr/include \
|
||||
${RPM_BUILD_ROOT}/sbin \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client-devel/examples/ \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils-devel/examples/beegfs-event-listener/build \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils-devel/examples/beegfs-event-listener/source \
|
||||
${RPM_BUILD_ROOT}/etc/bash_completion.d
|
||||
|
||||
|
||||
##########
|
||||
########## libbeegfs-ib files
|
||||
##########
|
||||
|
||||
install -D common/build/libbeegfs_ib.so \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/lib/libbeegfs_ib.so
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/libbeegfs-ib/copyright
|
||||
|
||||
##########
|
||||
########## daemons, utils
|
||||
##########
|
||||
|
||||
make DESTDIR=${RPM_BUILD_ROOT} daemons-install utils-install
|
||||
|
||||
##########
|
||||
########## common directories for extra files
|
||||
##########
|
||||
mkdir -p \
|
||||
${RPM_BUILD_ROOT}/etc/beegfs \
|
||||
${RPM_BUILD_ROOT}/etc/init.d \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/scripts/grafana
|
||||
|
||||
##########
|
||||
########## meta extra files
|
||||
##########
|
||||
|
||||
cp -a meta/build/dist/etc/*.conf ${RPM_BUILD_ROOT}/etc/beegfs
|
||||
|
||||
#install systemd unit description
|
||||
install -D -m644 meta/build/dist/usr/lib/systemd/system/beegfs-meta.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-meta.service
|
||||
install -D -m644 meta/build/dist/usr/lib/systemd/system/beegfs-meta@.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-meta@.service
|
||||
|
||||
install -D meta/build/dist/sbin/beegfs-setup-meta \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/sbin/beegfs-setup-meta
|
||||
|
||||
install -D meta/build/dist/etc/default/beegfs-meta ${RPM_BUILD_ROOT}/etc/default/beegfs-meta
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-meta/copyright
|
||||
|
||||
##########
|
||||
########## storage extra files
|
||||
##########
|
||||
|
||||
cp -a storage/build/dist/etc/*.conf ${RPM_BUILD_ROOT}/etc/beegfs/
|
||||
|
||||
#install systemd unit description
|
||||
install -D -m644 storage/build/dist/usr/lib/systemd/system/beegfs-storage.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-storage.service
|
||||
install -D -m644 storage/build/dist/usr/lib/systemd/system/beegfs-storage@.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-storage@.service
|
||||
|
||||
install -D storage/build/dist/sbin/beegfs-setup-storage \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/sbin/beegfs-setup-storage
|
||||
|
||||
install -D storage/build/dist/etc/default/beegfs-storage ${RPM_BUILD_ROOT}/etc/default/beegfs-storage
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-storage/copyright
|
||||
|
||||
##########
|
||||
########## mon extra files
|
||||
##########
|
||||
|
||||
install -D -m644 mon/build/dist/etc/beegfs-mon.conf ${RPM_BUILD_ROOT}/etc/beegfs
|
||||
install -D -m600 mon/build/dist/etc/beegfs-mon.auth ${RPM_BUILD_ROOT}/etc/beegfs
|
||||
|
||||
#install systemd unit description
|
||||
install -D -m644 mon/build/dist/usr/lib/systemd/system/beegfs-mon.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-mon.service
|
||||
install -D -m644 mon/build/dist/usr/lib/systemd/system/beegfs-mon@.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-mon@.service
|
||||
|
||||
install -D mon/build/dist/etc/default/beegfs-mon ${RPM_BUILD_ROOT}/etc/default/beegfs-mon
|
||||
cp -a mon/scripts/grafana/* ${RPM_BUILD_ROOT}/opt/beegfs/scripts/grafana/
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-mon/copyright
|
||||
|
||||
##########
|
||||
########## mon-grafana
|
||||
##########
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-mon-grafana/copyright
|
||||
|
||||
##########
|
||||
########## utils
|
||||
##########
|
||||
|
||||
cp -a utils/scripts/fsck.beegfs ${RPM_BUILD_ROOT}/sbin/
|
||||
|
||||
ln -s /opt/beegfs/sbin/beegfs-fsck ${RPM_BUILD_ROOT}/usr/bin/beegfs-fsck
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils/copyright
|
||||
|
||||
##########
|
||||
########## utils-devel
|
||||
##########
|
||||
|
||||
cp -a event_listener/include/* ${RPM_BUILD_ROOT}/usr/include/
|
||||
cp -a event_listener/build/Makefile \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils-devel/examples/beegfs-event-listener/build/
|
||||
cp -a event_listener/source/beegfs-event-listener.cpp \
|
||||
event_listener/source/beegfs-file-event-log.cpp \
|
||||
event_listener/source/seqpacket-reader-new-protocol.cpp \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils-devel/examples/beegfs-event-listener/source/
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-utils-devel/copyright
|
||||
|
||||
##########
|
||||
########## client
|
||||
##########
|
||||
|
||||
make -C client_module/build %make_j \
|
||||
RELEASE_PATH=${RPM_BUILD_ROOT}/opt/beegfs/src/client KDIR="%{KDIR}" V=1 \
|
||||
prepare_release
|
||||
cp client_module/build/dist/etc/*.conf ${RPM_BUILD_ROOT}/etc/beegfs/
|
||||
cp client_module/build/dist/etc/beegfs-client-build.mk ${RPM_BUILD_ROOT}/etc/beegfs/beegfs-client-build.mk
|
||||
|
||||
|
||||
# compat files
|
||||
cp -a ${RPM_BUILD_ROOT}/%{CLIENT_DIR} ${RPM_BUILD_ROOT}/%{CLIENT_COMPAT_DIR}
|
||||
|
||||
echo beegfs-%{BEEGFS_MAJOR_VERSION} | tr -d . > ${RPM_BUILD_ROOT}/%{CLIENT_COMPAT_DIR}/build/beegfs.fstype
|
||||
|
||||
# we use the redhat script for all rpm distros, as we now provide our own
|
||||
# daemon() and killproc() function library (derived from redhat)
|
||||
install -D client_module/build/dist/sbin/beegfs-client.init ${RPM_BUILD_ROOT}/opt/beegfs/sbin/beegfs-client
|
||||
%if !%is_sles
|
||||
ln -s /opt/beegfs/sbin/beegfs-client ${RPM_BUILD_ROOT}/etc/init.d/beegfs-client
|
||||
%endif
|
||||
#install systemd unit description
|
||||
install -D -m644 client_module/build/dist/usr/lib/systemd/system/beegfs-client.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-client.service
|
||||
|
||||
install -D -m644 client_module/build/dist/usr/lib/systemd/system/beegfs-client@.service \
|
||||
${RPM_BUILD_ROOT}/usr/lib/systemd/system/beegfs-client@.service
|
||||
|
||||
|
||||
install -D client_module/build/dist/etc/default/beegfs-client ${RPM_BUILD_ROOT}/etc/default/beegfs-client
|
||||
|
||||
install -D client_module/scripts/etc/beegfs/lib/init-multi-mode.beegfs-client \
|
||||
${RPM_BUILD_ROOT}/etc/beegfs/lib/init-multi-mode.beegfs-client
|
||||
|
||||
install -D client_module/build/dist/sbin/beegfs-setup-client \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/sbin/beegfs-setup-client
|
||||
|
||||
install -D client_module/build/dist/sbin/mount.beegfs \
|
||||
${RPM_BUILD_ROOT}/sbin/mount.beegfs
|
||||
|
||||
install -D client_module/build/dist/etc/beegfs-client-mount-hook.example \
|
||||
${RPM_BUILD_ROOT}/etc/beegfs/beegfs-client-mount-hook.example
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client/copyright
|
||||
|
||||
##########
|
||||
########## client-dkms
|
||||
##########
|
||||
|
||||
cp client_module/build/dist/etc/*.conf ${RPM_BUILD_ROOT}/etc/beegfs/
|
||||
|
||||
mkdir -p ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}
|
||||
|
||||
cp -r client_module/build ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}
|
||||
cp -r client_module/source ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}
|
||||
cp -r client_module/include ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}
|
||||
|
||||
rm -Rf ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}/build/dist
|
||||
|
||||
|
||||
install -D client_module/build/dist/sbin/beegfs-setup-client \
|
||||
${RPM_BUILD_ROOT}/opt/beegfs/sbin/beegfs-setup-client
|
||||
install -D client_module/build/dist/sbin/mount.beegfs \
|
||||
${RPM_BUILD_ROOT}/sbin/mount.beegfs
|
||||
|
||||
sed -e 's/__VERSION__/%{VER}/g' -e 's/__NAME__/beegfs/g' -e 's/__MODNAME__/beegfs/g' \
|
||||
< client_module/dkms.conf.in \
|
||||
> ${RPM_BUILD_ROOT}/usr/src/beegfs-%{VER}/dkms.conf
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client-dkms/copyright
|
||||
|
||||
##########
|
||||
########## client-compat
|
||||
##########
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client-compat/copyright
|
||||
|
||||
##########
|
||||
########## client-devel
|
||||
##########
|
||||
|
||||
cp -a client_devel/include/beegfs \
|
||||
${RPM_BUILD_ROOT}/usr/include/
|
||||
cp -a client_module/include/uapi/* \
|
||||
${RPM_BUILD_ROOT}/usr/include/beegfs/
|
||||
sed -i '~s~uapi/beegfs_client~beegfs/beegfs_client~g' \
|
||||
${RPM_BUILD_ROOT}/usr/include/beegfs/*.h
|
||||
cp -a client_devel/build/dist/usr/share/doc/beegfs-client-devel/examples/* \
|
||||
${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client-devel/examples/
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beegfs-client-devel/copyright
|
||||
|
||||
##########
|
||||
########## beeond
|
||||
##########
|
||||
|
||||
install -D beeond/source/beeond ${RPM_BUILD_ROOT}/opt/beegfs/sbin/beeond
|
||||
install -D beeond/source/beeond-cp ${RPM_BUILD_ROOT}/opt/beegfs/sbin/beeond-cp
|
||||
cp beeond/scripts/lib/* ${RPM_BUILD_ROOT}/opt/beegfs/lib/
|
||||
ln -s /opt/beegfs/sbin/beeond ${RPM_BUILD_ROOT}/usr/bin/beeond
|
||||
ln -s /opt/beegfs/sbin/beeond-cp ${RPM_BUILD_ROOT}/usr/bin/beeond-cp
|
||||
|
||||
install -D debian/copyright ${RPM_BUILD_ROOT}/usr/share/doc/beeond/copyright
|
||||
|
||||
%package -n libbeegfs-ib
|
||||
|
||||
Summary: BeeGFS InfiniBand support
|
||||
Group: Software/Other
|
||||
Buildrequires: librdmacm-devel, libibverbs-devel
|
||||
BuildRequires: libnl3-devel
|
||||
Provides: libbeegfs-ib = %{VER}
|
||||
|
||||
%description -n libbeegfs-ib
|
||||
This package contains support libraries for InfiniBand.
|
||||
|
||||
%files -n libbeegfs-ib
|
||||
%license /usr/share/doc/libbeegfs-ib/copyright
|
||||
/opt/beegfs/lib/libbeegfs_ib.so
|
||||
|
||||
|
||||
|
||||
%package meta
|
||||
|
||||
Summary: BeeGFS meta server daemon
|
||||
Group: Software/Other
|
||||
BuildRequires: libnl3-devel
|
||||
Provides: beegfs-meta = %{VER}
|
||||
|
||||
%description meta
|
||||
This package contains the BeeGFS meta server binaries.
|
||||
|
||||
%post meta
|
||||
%post_package beegfs-meta
|
||||
|
||||
%preun meta
|
||||
%preun_package beegfs-meta
|
||||
|
||||
%files meta
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-meta/copyright
|
||||
%config(noreplace) /etc/beegfs/beegfs-meta.conf
|
||||
%config(noreplace) /etc/default/beegfs-meta
|
||||
/opt/beegfs/sbin/beegfs-meta
|
||||
/opt/beegfs/sbin/beegfs-setup-meta
|
||||
/usr/lib/systemd/system/beegfs-meta.service
|
||||
/usr/lib/systemd/system/beegfs-meta@.service
|
||||
|
||||
|
||||
%package storage
|
||||
|
||||
Summary: BeeGFS storage server daemon
|
||||
Group: Software/Other
|
||||
BuildRequires: libnl3-devel
|
||||
Provides: beegfs-storage = %{VER}
|
||||
|
||||
%description storage
|
||||
This package contains the BeeGFS storage server binaries.
|
||||
|
||||
%post storage
|
||||
%post_package beegfs-storage
|
||||
|
||||
%preun storage
|
||||
%preun_package beegfs-storage
|
||||
|
||||
%files storage
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-storage/copyright
|
||||
%config(noreplace) /etc/beegfs/beegfs-storage.conf
|
||||
%config(noreplace) /etc/default/beegfs-storage
|
||||
/opt/beegfs/sbin/beegfs-storage
|
||||
/opt/beegfs/sbin/beegfs-setup-storage
|
||||
/usr/lib/systemd/system/beegfs-storage.service
|
||||
/usr/lib/systemd/system/beegfs-storage@.service
|
||||
|
||||
|
||||
|
||||
%package mon
|
||||
|
||||
Summary: BeeGFS mon server daemon
|
||||
Group: Software/Other
|
||||
BuildRequires: libnl3-devel
|
||||
Provides: beegfs-mon = %{VER}
|
||||
|
||||
%description mon
|
||||
This package contains the BeeGFS mon server binaries.
|
||||
|
||||
%post mon
|
||||
%post_package beegfs-mon
|
||||
|
||||
%preun mon
|
||||
%preun_package beegfs-mon
|
||||
|
||||
%files mon
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-mon/copyright
|
||||
%config(noreplace) /etc/beegfs/beegfs-mon.conf
|
||||
%config(noreplace) /etc/beegfs/beegfs-mon.auth
|
||||
%config(noreplace) /etc/default/beegfs-mon
|
||||
/opt/beegfs/sbin/beegfs-mon
|
||||
/usr/lib/systemd/system/beegfs-mon.service
|
||||
/usr/lib/systemd/system/beegfs-mon@.service
|
||||
|
||||
|
||||
|
||||
%package mon-grafana
|
||||
|
||||
Summary: BeeGFS mon dashboards for Grafana
|
||||
Group: Software/Other
|
||||
BuildArch: noarch
|
||||
Provides: beegfs-mon-grafana = %{VER}
|
||||
|
||||
%description mon-grafana
|
||||
This package contains the BeeGFS mon dashboards to display monitoring data in Grafana.
|
||||
|
||||
The default dashboard setup requires both Grafana, and InfluxDB.
|
||||
|
||||
%files mon-grafana
|
||||
%license /usr/share/doc/beegfs-mon-grafana/copyright
|
||||
%defattr(-,root,root)
|
||||
/opt/beegfs/scripts/grafana/
|
||||
|
||||
|
||||
|
||||
%package utils
|
||||
|
||||
Summary: BeeGFS utilities
|
||||
Group: Software/Other
|
||||
BuildRequires: libnl3-devel
|
||||
Provides: beegfs-utils = %{VER}
|
||||
|
||||
%description utils
|
||||
This package contains BeeGFS utilities.
|
||||
|
||||
%files utils
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-utils/copyright
|
||||
%attr(0755, root, root) /opt/beegfs/sbin/beegfs-fsck
|
||||
/usr/bin/beegfs-fsck
|
||||
/sbin/fsck.beegfs
|
||||
/opt/beegfs/sbin/beegfs-event-listener
|
||||
|
||||
|
||||
%package utils-devel
|
||||
|
||||
Summary: BeeGFS utils devel files
|
||||
Group: Software/Other
|
||||
BuildArch: noarch
|
||||
Provides: beegfs-utils-devel = %{VER}
|
||||
|
||||
%description utils-devel
|
||||
This package contains BeeGFS utils development files and examples.
|
||||
|
||||
%files utils-devel
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-utils-devel/copyright
|
||||
/usr/include/beegfs/beegfs_file_event_log.hpp
|
||||
/usr/include/beegfs/seqpacket-reader-new-protocol.hpp
|
||||
/usr/share/doc/beegfs-utils-devel/examples/beegfs-event-listener/*
|
||||
|
||||
|
||||
|
||||
%package client
|
||||
|
||||
Summary: BeeGFS client kernel module
|
||||
License: GPL v2
|
||||
Group: Software/Other
|
||||
BuildArch: noarch
|
||||
%if %is_sles
|
||||
Requires: make, gcc, kernel-default-devel, elfutils
|
||||
%else
|
||||
Requires: make, gcc
|
||||
Recommends: kernel-devel, elfutils-libelf-devel
|
||||
%endif
|
||||
Conflicts: beegfs-client-dkms
|
||||
Provides: beegfs-client = %{VER}
|
||||
|
||||
%description client
|
||||
This package contains scripts, config and source files to build and
|
||||
start beegfs-client.
|
||||
|
||||
%post client
|
||||
%post_package beegfs-client
|
||||
|
||||
# make the script to run autobuild
|
||||
mkdir -p /var/lib/beegfs/client
|
||||
touch /var/lib/beegfs/client/force-auto-build
|
||||
|
||||
%preun client
|
||||
%preun_package beegfs-client
|
||||
|
||||
%files client
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-client/copyright
|
||||
%config(noreplace) /etc/beegfs/beegfs-client-autobuild.conf
|
||||
%config(noreplace) /etc/beegfs/beegfs-client-mount-hook.example
|
||||
%config(noreplace) /etc/beegfs/beegfs-client.conf
|
||||
%config(noreplace) /etc/beegfs/beegfs-mounts.conf
|
||||
%dir /etc/beegfs/lib/
|
||||
%config(noreplace) /etc/beegfs/lib/init-multi-mode.beegfs-client
|
||||
%config(noreplace) /etc/default/beegfs-client
|
||||
/opt/beegfs/sbin/beegfs-client
|
||||
%if !%is_sles
|
||||
/etc/init.d/beegfs-client
|
||||
%endif
|
||||
/opt/beegfs/sbin/beegfs-setup-client
|
||||
/sbin/mount.beegfs
|
||||
/usr/lib/systemd/system/beegfs-client.service
|
||||
/usr/lib/systemd/system/beegfs-client@.service
|
||||
%{CLIENT_DIR}
|
||||
|
||||
%postun client
|
||||
rm -rf /lib/modules/*/updates/fs/beegfs_autobuild
|
||||
|
||||
%package client-dkms
|
||||
|
||||
Summary: BeeGFS client kernel module (DKMS version)
|
||||
License: GPL v2
|
||||
Group: Software/Other
|
||||
BuildArch: noarch
|
||||
%if %is_sles
|
||||
Requires: make, dkms, kernel-default-devel, elfutils
|
||||
%else
|
||||
Requires: make, dkms
|
||||
Recommends: kernel-devel, elfutils-libelf-devel
|
||||
%endif
|
||||
Conflicts: beegfs-client
|
||||
Provides: beegfs-client = %{VER}
|
||||
|
||||
%description client-dkms
|
||||
This package contains scripts, config and source files to build and
|
||||
start beegfs-client. It uses DKMS to build the kernel module.
|
||||
|
||||
%post client-dkms
|
||||
dkms install beegfs/%{VER}
|
||||
|
||||
%preun client-dkms
|
||||
dkms remove beegfs/%{VER} --all
|
||||
|
||||
%files client-dkms
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-client-dkms/copyright
|
||||
%config(noreplace) /etc/beegfs/beegfs-client.conf
|
||||
%config(noreplace) /etc/beegfs/beegfs-client-build.mk
|
||||
/sbin/mount.beegfs
|
||||
/usr/src/beegfs-%{VER}
|
||||
|
||||
|
||||
|
||||
%package client-compat
|
||||
|
||||
Summary: BeeGFS client compat module, allows to run two different client versions.
|
||||
License: GPL v2
|
||||
Group: Software/Other
|
||||
%if %is_sles
|
||||
Requires: make, gcc, kernel-default-devel, elfutils
|
||||
%else
|
||||
Requires: make, gcc
|
||||
Recommends: kernel-devel, elfutils-libelf-devel
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
Provides: beegfs-client-compat = %{VER}
|
||||
|
||||
%description client-compat
|
||||
This package allows to build and to run a compatbility beegfs-client kernel module
|
||||
on a system that has a newer beegfs-client version installed.
|
||||
|
||||
%files client-compat
|
||||
%license /usr/share/doc/beegfs-client-compat/copyright
|
||||
%defattr(-,root,root)
|
||||
%{CLIENT_COMPAT_DIR}
|
||||
|
||||
|
||||
|
||||
%package client-devel
|
||||
|
||||
Summary: BeeGFS client devel files
|
||||
Group: Software/Other
|
||||
BuildArch: noarch
|
||||
Provides: beegfs-client-devel = %{VER}
|
||||
|
||||
%description client-devel
|
||||
This package contains BeeGFS client development files.
|
||||
|
||||
%files client-devel
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beegfs-client-devel/copyright
|
||||
%dir /usr/include/beegfs
|
||||
/usr/include/beegfs/beegfs.h
|
||||
/usr/include/beegfs/beegfs_client.h
|
||||
/usr/include/beegfs/beegfs_ioctl.h
|
||||
/usr/include/beegfs/beegfs_ioctl_functions.h
|
||||
/usr/share/doc/beegfs-client-devel/examples/createFileWithStripePattern.cpp
|
||||
/usr/share/doc/beegfs-client-devel/examples/getStripePatternOfFile.cpp
|
||||
|
||||
|
||||
|
||||
%package -n beeond
|
||||
|
||||
Summary: BeeOND
|
||||
Group: Software/Other
|
||||
# The dependecies used to be on FULL_VERSION=%{EPOCH}:%{VER}-%{RELEASE}, which
|
||||
# doesn't work with BeeGFS 8, because the distribution independent packages
|
||||
# can not append an OS RELEASE. We also don't need to depend on the EPOCH, the
|
||||
# semantic version should be enough, so we just depend on %{VER} now.
|
||||
Requires: beegfs-tools = %{VER}, beegfs-mgmtd = %{VER}, beegfs-meta = %{VER}, beegfs-storage = %{VER}, beegfs-client = %{VER}, libbeegfs-license = %{VER}, psmisc
|
||||
BuildArch: noarch
|
||||
Provides: beeond = %{VER}
|
||||
|
||||
%description -n beeond
|
||||
This package contains BeeOND.
|
||||
|
||||
%files -n beeond
|
||||
%defattr(-,root,root)
|
||||
%license /usr/share/doc/beeond/copyright
|
||||
/opt/beegfs/sbin/beeond
|
||||
/usr/bin/beeond
|
||||
/opt/beegfs/sbin/beeond-cp
|
||||
/usr/bin/beeond-cp
|
||||
/opt/beegfs/lib/beeond-lib
|
||||
/opt/beegfs/lib/beegfs-ondemand-stoplocal
|
||||
11
beeond/CMakeLists.txt
Normal file
11
beeond/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
install(
|
||||
PROGRAMS "beegfs-ondemand-stoplocal" "beeond-lib"
|
||||
DESTINATION "usr/share/beeond"
|
||||
COMPONENT "beeond"
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS "beeond" "beeond-cp"
|
||||
DESTINATION "usr/bin"
|
||||
COMPONENT "beeond"
|
||||
)
|
||||
400
beeond/scripts/lib/beegfs-ondemand-stoplocal
Normal file
400
beeond/scripts/lib/beegfs-ondemand-stoplocal
Normal file
@@ -0,0 +1,400 @@
|
||||
#!/bin/bash
|
||||
|
||||
# beegfs-ondemand-stoplocal
|
||||
# This file contains helper functions to stop BeeOND services locally on one node.
|
||||
# This is meant to be sourced from another script (i.e. beeond)
|
||||
|
||||
|
||||
# Checks the return code of the last command that has been executed. If the code is !=0, indicating
|
||||
# an error, it prints a message and sets an error flag.
|
||||
# Parameters:
|
||||
# * The return code of the last command
|
||||
# * A string containing a hint on what was being done that could have caused the error. It is
|
||||
# used for the error message.
|
||||
# Modifies:
|
||||
# ERROR: Is set to "true" when an error was encountered.
|
||||
sl_checkerror()
|
||||
{
|
||||
if [ "${1}" != 0 ]
|
||||
then
|
||||
echo "ERROR: There was a problem ${2} on host $(hostname)"
|
||||
ERROR="true"
|
||||
fi
|
||||
}
|
||||
|
||||
# Prints an info message if the QUIET variable is not set.
|
||||
# Parameter:
|
||||
# A string (the message). It is prefixed with INFO when printed.
|
||||
# Checks:
|
||||
# QUIET: If "true", nothing is printed.
|
||||
sl_print_info()
|
||||
{
|
||||
local MESSAGE=${1}
|
||||
if [ "${QUIET}" != "true" ]
|
||||
then
|
||||
echo "INFO: ${MESSAGE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# unmounts tmpfs mounts listed in the status file
|
||||
sl_unmount_tmpfs()
|
||||
{
|
||||
local SERVICE MOUNTPOINT _
|
||||
IFS=,
|
||||
while read -r _ SERVICE MOUNTPOINT _ _
|
||||
do
|
||||
if [ "${SERVICE}" != "tmpfs" ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
sl_print_info "Unmounting tmpfs at ${MOUNTPOINT}"
|
||||
|
||||
if [ "${CLEANUP}" != "true" ]
|
||||
then
|
||||
fuser -k "${MOUNTPOINT}"
|
||||
umount -l "${MOUNTPOINT}"
|
||||
|
||||
sl_checkerror $? "unmounting tmpfs"
|
||||
else
|
||||
fuser -k "${MOUNTPOINT}" 2>/dev/null
|
||||
umount -l "${MOUNTPOINT}" 2>/dev/null
|
||||
true
|
||||
fi
|
||||
done < "${STATUSFILE}"
|
||||
unset IFS
|
||||
}
|
||||
|
||||
# Unmounts all local mounts listed in the status file
|
||||
sl_unmount_local_mounts()
|
||||
{
|
||||
local SERVICE MOUNTPOINT _
|
||||
IFS=,
|
||||
while read -r _ SERVICE MOUNTPOINT _ _
|
||||
do
|
||||
if [ "${SERVICE}" != "${CLIENTSERVICE}" ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
sl_print_info "Unmounting ${MOUNTPOINT}"
|
||||
if [ "${CLEANUP}" != "true" ]
|
||||
then
|
||||
fuser -k "${MOUNTPOINT}" # no "sl_checkerror" after this, becuase fuser also returns
|
||||
# non-zero when there are no processes accessing the file system
|
||||
umount -l "${MOUNTPOINT}"
|
||||
sl_checkerror $? "unmounting the ondemand file system"
|
||||
else
|
||||
fuser -k "${MOUNTPOINT}" 2>/dev/null
|
||||
umount -l "${MOUNTPOINT}" 2>/dev/null
|
||||
true # reset error code before next invocation of sl_checkerror
|
||||
fi
|
||||
done < "${STATUSFILE}"
|
||||
unset IFS
|
||||
|
||||
# try to remove the client module - this is allowed to fail, because we might have a "normal"
|
||||
# beegfs mount somewhere in the system.
|
||||
rmmod beegfs 2>/dev/null || true
|
||||
}
|
||||
|
||||
# sends a SIGTERM to a process, then waits until the process is stopped or appriximately 10 seconds
|
||||
# have passed.
|
||||
# Parameter:
|
||||
# The PID of the proces
|
||||
# Returns:
|
||||
# 0 if process was stopped within 10 seconds, 1 if it wasn't, 255 if initial kill returned an
|
||||
# error.
|
||||
sl_kill_check()
|
||||
{
|
||||
local PID=$1
|
||||
|
||||
if ! kill "$PID"
|
||||
then
|
||||
return 255
|
||||
fi
|
||||
|
||||
for ((i=0; i<100; i++))
|
||||
do
|
||||
if kill -0 "$PID" 2>/dev/null
|
||||
then
|
||||
sleep 0.1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# stops all services listed in the status file except for clients
|
||||
sl_stop_services()
|
||||
{
|
||||
local SERVICE DATAPATH PIDFILE _
|
||||
IFS=,
|
||||
while read -r _ SERVICE DATAPATH _ PIDFILE
|
||||
do
|
||||
if [ "${PIDFILE}" != "-" ] # pidfile is "-" for beegfs-client and tmpfs, because it is not
|
||||
# a process
|
||||
then
|
||||
if [ -e "${PIDFILE}" ]
|
||||
then
|
||||
PID=$(cat "${PIDFILE}")
|
||||
sl_kill_check "${PID}"
|
||||
RES=$?
|
||||
if [ $RES -eq 1 ]
|
||||
then
|
||||
echo "ERROR: ${SERVICE} did not stop within 10 seconds (PID ${PID})."
|
||||
ERROR="true"
|
||||
elif [ $RES -eq 255 ]
|
||||
then
|
||||
echo "ERROR: ${SERVICE} does not seem to be running any more (PID ${PID})."
|
||||
fi
|
||||
else
|
||||
if [ "${CLEANUP}" != "true" ]
|
||||
then
|
||||
echo "ERROR: PID file ${PIDFILE} does not exist on host $(hostname)"
|
||||
ERROR="true"
|
||||
fi
|
||||
fi
|
||||
|
||||
# delete data...
|
||||
if [ "${DELETE_DATA}" = "true" ]
|
||||
then
|
||||
if [ "${DATAPATH}" != "-" ]
|
||||
then
|
||||
sl_print_info "Deleting stored data; Data path: ${DATAPATH}"
|
||||
rm -rf "${DATAPATH}"
|
||||
sl_checkerror $? "deleting ${DATAPATH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# delete preferredMds and preferredTarget files
|
||||
rm -f "${PREFERRED_MDS_FILE}"
|
||||
sl_checkerror $? "deleting ${PREFERRED_MDS_FILE}"
|
||||
rm -f "${PREFERRED_TARGET_FILE}"
|
||||
sl_checkerror $? "deleting ${PREFERRED_TARGET_FILE}"
|
||||
fi
|
||||
done < "${STATUSFILE}"
|
||||
unset IFS
|
||||
|
||||
# unmount tempfs if it was used
|
||||
sl_unmount_tmpfs
|
||||
}
|
||||
|
||||
# deletes the logfiles listed in the status file if ERROR is set to false
|
||||
# If the log directory is empty afterwards, it is also deleted
|
||||
sl_delete_logfiles()
|
||||
{
|
||||
local LOGFILE # declare it here, because the last LOGFILE path is needed to delete the directory
|
||||
# after the loop
|
||||
|
||||
# delete log files
|
||||
if [ "${ERROR}" != "true" ] # if we haven't encountered an error yet.
|
||||
then
|
||||
# delete log files
|
||||
local SERVICE LOGFILE _
|
||||
IFS=,
|
||||
while read -r _ SERVICE _ LOGFILE _
|
||||
do
|
||||
if [ "${ONLY_UNMOUNT}" = "true" ] && [ "${SERVICE}" != "${CLIENTSERVICE}" ]
|
||||
then continue; fi
|
||||
if [ "${ONLY_STOP_SERVER}" = "true" ] && [ "${SERVICE}" = "${CLIENTSERVICE}" ]
|
||||
then continue; fi
|
||||
if [ "${LOGFILE}" != "-" ]
|
||||
then
|
||||
sl_print_info "Deleting log file ${LOGFILE}"
|
||||
rm -f "${LOGFILE}" 2>/dev/null # beegfs-client does not (always) generate a logfile.
|
||||
# in this case rm gives an error message, but we don't
|
||||
# want to see it. - for the same reason no sl_checkerror
|
||||
# here
|
||||
fi
|
||||
done < "${STATUSFILE}"
|
||||
unset IFS
|
||||
|
||||
# delete log directory if empty
|
||||
local LOG_DIR
|
||||
LOG_DIR=$(dirname "${LOGFILE}")
|
||||
if [ "${LOG_DIR}" != "." ] && [ ! "$(ls -A "${LOG_DIR}")" ]
|
||||
then
|
||||
echo "Deleting log directory ${LOG_DIR}"
|
||||
rmdir "${LOG_DIR}"
|
||||
sl_checkerror $? "deleting ${LOG_DIR}"
|
||||
fi
|
||||
else
|
||||
sl_print_info "Not deleting log files because of a previous error."
|
||||
fi
|
||||
}
|
||||
|
||||
# The "main" stoplocal function. From here, the functions to unmount the file system and stop the
|
||||
# services are called. If there was no error, sl_delete_logfiles is called, and the status file is
|
||||
# also removed.
|
||||
# Checks the following variables:
|
||||
# STATUSFILE The location of the status file
|
||||
# ONLY_STOP_SERVER If "true", the umount_local_mounts step is skipped, and status file is not
|
||||
# removed.
|
||||
# ONLY_UNMOUNT If "true", the stop_services step is skipped, and status file is not
|
||||
# removed.
|
||||
# Modifies:
|
||||
# ERROR Is set to "true" (and an error message is printed to %2) if an error is
|
||||
# encountered in any step.
|
||||
stoplocal()
|
||||
{
|
||||
sl_print_info "Using status file ${STATUSFILE}"
|
||||
|
||||
# do the actual shutdown process
|
||||
|
||||
# unmount the file system (skip this step if we only want to stop the server)
|
||||
if [ "${ONLY_STOP_SERVER}" != "true" ]
|
||||
then
|
||||
sl_unmount_local_mounts
|
||||
fi
|
||||
|
||||
# stop the services (skip this step if we only got asked to unmount the file system)
|
||||
if [ "${ONLY_UNMOUNT}" != "true" ]
|
||||
then
|
||||
sl_stop_services
|
||||
fi
|
||||
|
||||
# delete the logfiles
|
||||
if [ "${ERROR}" != "true" ] && [ "${DELETE_LOGS}" = "true" ]
|
||||
then
|
||||
sl_delete_logfiles
|
||||
fi
|
||||
|
||||
|
||||
# delete the status file (only if a full shutdown was requested)
|
||||
if [ "${ONLY_UNMOUNT}" != "true" ] && [ "${ONLY_STOP_SERVER}" != "true" ]
|
||||
then
|
||||
rm -f "${STATUSFILE}"
|
||||
sl_checkerror $? "deleting the status file"
|
||||
fi
|
||||
}
|
||||
|
||||
# the user interface / main entry point to stoplocal
|
||||
# Options:
|
||||
# -i FILENAME => Status information filename
|
||||
# (DEFAULT: ${DEFAULT_STATUSFILE})
|
||||
# -d => Delete BeeGFS data on disks
|
||||
# -L => Delete log files after successful shutdown
|
||||
# -q => Suppress \"INFO\" messages, only print \"ERROR\"s
|
||||
# -c => "Cleanup": Remove remaining processes and directories of a
|
||||
# potentially unsuccessful shutdown of an earlier beeond
|
||||
# instance. This switch silences the error message when a status
|
||||
# information file is not found or an unmount command fails;
|
||||
# instead, a message is printed (if \"INFO\" messages are not
|
||||
# suppressed) when a status file DOES exist, because this means
|
||||
# there actually was an instance before that is now being
|
||||
# cleaned up.
|
||||
# -u => ONLY unmount the file systems(*)
|
||||
# -s => ONLY stop non-client services(*)
|
||||
#
|
||||
# (*) Options -u and -s are mutually exclusive
|
||||
# If -u or -s are given, the status file is not deleted.
|
||||
do_stoplocal()
|
||||
{
|
||||
local DEFAULT_STATUSFILE=/tmp/beeond.tmp
|
||||
local CLIENTSERVICE=beegfs-client
|
||||
local DELETE_DATA="false"
|
||||
local DELETE_LOGS="false"
|
||||
local ONLY_UNMOUNT="false"
|
||||
local ONLY_STOP_SERVER="false"
|
||||
local PREFERRED_MDS_FILE=/tmp/preferredMds.fod
|
||||
local PREFERRED_TARGET_FILE=/tmp/preferredTarget.fod
|
||||
local QUIET="false"
|
||||
|
||||
local ERROR="false"
|
||||
local STATUSFILE="${DEFAULT_STATUSFILE}"
|
||||
|
||||
local OPTIND=1
|
||||
local OPTARG=""
|
||||
while getopts ":i:dLusqc" opt "$@"
|
||||
do
|
||||
case $opt in
|
||||
i)
|
||||
STATUSFILE=${OPTARG}
|
||||
;;
|
||||
d)
|
||||
DELETE_DATA="true"
|
||||
;;
|
||||
L)
|
||||
DELETE_LOGS="true"
|
||||
;;
|
||||
u)
|
||||
if [ "${ONLY_STOP_SERVER}" = "true" ]
|
||||
then
|
||||
echo "ERROR: Options -s and -${OPTARG} are mutually exclusive" >&2
|
||||
if declare -f -F print_usage_and_exit >/dev/null
|
||||
then print_usage_and_exit; fi
|
||||
return 1
|
||||
fi
|
||||
ONLY_UNMOUNT="true"
|
||||
;;
|
||||
s)
|
||||
if [ "${ONLY_UNMOUNT}" = "true" ]
|
||||
then
|
||||
echo "ERROR: Options -u and -${OPTARG} are mutually exclusive" >&2
|
||||
if declare -f -F print_usage_and_exit >/dev/null
|
||||
then print_usage_and_exit; fi
|
||||
return 1
|
||||
fi
|
||||
ONLY_STOP_SERVER="true"
|
||||
;;
|
||||
q)
|
||||
QUIET="true"
|
||||
;;
|
||||
c)
|
||||
CLEANUP="true"
|
||||
;;
|
||||
\?)
|
||||
echo "ERROR: invalid option -${OPTARG}" >&2
|
||||
if declare -f -F print_usage_and_exit >/dev/null
|
||||
then print_usage_and_exit; fi
|
||||
return 1
|
||||
;;
|
||||
:)
|
||||
echo "ERROR: Option -${OPTARG} requires an argument" >&2
|
||||
if declare -f -F print_usage_and_exit >/dev/null
|
||||
then print_usage_and_exit; fi
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# if statusfile can't be found, print a message and exit.
|
||||
if [ ! -f ${STATUSFILE} ]
|
||||
then
|
||||
# only print message when we're not doing a cleanup run.
|
||||
if [ "${CLEANUP}" != "true" ]
|
||||
then
|
||||
echo "ERROR: Status file ${STATUSFILE} not found." >&2
|
||||
|
||||
# If the user has specified a status file, just give a brief error message and exit.
|
||||
# If the user has not specified a status file, give the full usage info - maybe the user
|
||||
# didn't know how to specify a status file.
|
||||
if [ "${STATUSFILE}" = "${DEFAULT_STATUSFILE}" ]
|
||||
then
|
||||
if declare -f -F "print_usage_and_exit" >/dev/null
|
||||
then print_usage_and_exit; fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
else
|
||||
return 0 # return 0 if we're doing a cleanup so that pdsh doesn't complain
|
||||
fi
|
||||
fi
|
||||
|
||||
# if we're doing a cleanup run, inform the user that a status file was found.
|
||||
if [ "${CLEANUP}" = "true" ]
|
||||
then
|
||||
sl_print_info "Status file found."
|
||||
fi
|
||||
|
||||
stoplocal
|
||||
|
||||
if [ "${ERROR}" = "true" ]
|
||||
then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
392
beeond/scripts/lib/beeond-lib
Normal file
392
beeond/scripts/lib/beeond-lib
Normal file
@@ -0,0 +1,392 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This file contains some functions used across all of the BeeOND scripts.
|
||||
|
||||
BEEOND_FILENAME_PREFIX=".beeond_"
|
||||
BEEOND_COPY_FILE_LIST="${BEEOND_FILENAME_PREFIX}files_copy"
|
||||
BEEOND_COPY_SCAN_LIST="${BEEOND_FILENAME_PREFIX}scan_list" # List of dirs that have to be scanned.
|
||||
BEEOND_COPY_DIR_LIST="${BEEOND_FILENAME_PREFIX}dirs_copy"
|
||||
BEEOND_START_FILE_LIST="${BEEOND_FILENAME_PREFIX}files_start"
|
||||
BEEOND_END_FILE_LIST="${BEEOND_FILENAME_PREFIX}files_end"
|
||||
BEEOND_END_UPDATED_FILE_LIST="${BEEOND_FILENAME_PREFIX}files_end_updated"
|
||||
BEEOND_START_DIR_LIST="${BEEOND_FILENAME_PREFIX}dirs_start"
|
||||
BEEOND_END_DIR_LIST="${BEEOND_FILENAME_PREFIX}dirs_end"
|
||||
BEEOND_END_UPDATED_DIR_LIST="${BEEOND_FILENAME_PREFIX}dirs_end_updated"
|
||||
BEEOND_SESSION_FILE="${BEEOND_FILENAME_PREFIX}session"
|
||||
|
||||
BEEOND_BATCH_SIZE=20
|
||||
|
||||
beeond_print_error()
|
||||
{
|
||||
echo "ERROR: ${1}" >&2
|
||||
echo ""
|
||||
}
|
||||
|
||||
beeond_print_error_and_exit()
|
||||
{
|
||||
beeond_print_error "${1}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
beeond_print_info()
|
||||
{
|
||||
local MESSAGE="${1}"
|
||||
if [ "${QUIET}" != "true" ]
|
||||
then
|
||||
echo "INFO: ${MESSAGE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Saves the session info file which contains the paths of the global store and the node file.
|
||||
beeond_save_session_info()
|
||||
{
|
||||
local NODEFILE="${1}"
|
||||
local GLOBAL_PATH="${2}"
|
||||
|
||||
if ! printf "NodeFile=%q\nGlobalPath=%q\n" "${NODEFILE}" "${GLOBAL_PATH}" \
|
||||
> "${LOCAL_PATH}/${BEEOND_SESSION_FILE}"
|
||||
then
|
||||
beeond_print_error_and_exit "Could not write to session file."
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate the list of files in the beeond folder.
|
||||
beeond_generate_file_list()
|
||||
{
|
||||
local LOCAL_PATH="${1}"
|
||||
local LISTFILE="${2}"
|
||||
local REFERENCE_FILE="${3}"
|
||||
|
||||
|
||||
pushd "${LOCAL_PATH}"
|
||||
if [ "${REFERENCE_FILE}" = "" ]
|
||||
then # No reference file - just generate the full list (e.g. on startup).
|
||||
|
||||
beeond_print_info "Generating file list ${LISTFILE}..."
|
||||
|
||||
find . ! -path ./${BEEOND_FILENAME_PREFIX}\* \( -type f -or -type l \)\
|
||||
-exec bash -c 'printf "%q\n" "$0"' {} \; \
|
||||
| grep -v ^\\$ | sort > "${LISTFILE}"
|
||||
|
||||
# The grep statement filters out file names with newlines in them. While they are technically
|
||||
# legal they would cause problems later on due to the way the script run by parallel handles
|
||||
# the arguments.
|
||||
|
||||
else # Reference file given: Compare timestamps.
|
||||
|
||||
beeond_print_info \
|
||||
"Generating file list ${LISTFILE}. Timestamp reference: ${REFERENCE_FILE}..."
|
||||
|
||||
find . ! -path ./${BEEOND_FILENAME_PREFIX}\* \( -type f -or -type l \) \
|
||||
\( -cnewer "${REFERENCE_FILE}" -or -newer "${REFERENCE_FILE}" \) \
|
||||
-exec bash -c 'printf "%q\n" "$0"' {} \; \
|
||||
| grep -v ^\\$ | sort > "${LISTFILE}"
|
||||
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
||||
# Generate list of directories - this is necessary in case directories were created during the
|
||||
# session and need to be created on the global store as well.
|
||||
beeond_generate_directory_list()
|
||||
{
|
||||
local LOCAL_PATH="${1}"
|
||||
local LISTFILE="${2}"
|
||||
local REFERENCE_FILE="${3}"
|
||||
|
||||
pushd "${LOCAL_PATH}"
|
||||
if [ "${REFERENCE_FILE}" = "" ]
|
||||
then # No reference file - just generate the full list (e.g. on startup).
|
||||
|
||||
beeond_print_info "Generating directory list ${LISTFILE}..."
|
||||
|
||||
find . ! -path . -type d \
|
||||
-exec bash -c 'printf "%q\n" "$0"' {} \; \
|
||||
| grep -v ^\\$ | sort > "${LISTFILE}"
|
||||
|
||||
else # Reference file given: Compare timestamps.
|
||||
|
||||
beeond_print_info \
|
||||
"Generating directory list ${LISTFILE}. Timestamp reference: ${REFERENCE_FILE}..."
|
||||
|
||||
find . ! -path . -type d \
|
||||
\( -cnewer "${REFERENCE_FILE}" -or -newer "${REFERENCE_FILE}" \) \
|
||||
-exec bash -c 'printf "%q\n" "$0"' {} \; \
|
||||
| grep -v ^\\$ | sort > "${LISTFILE}"
|
||||
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
||||
# Generate copy file list. If we do a parallel copy, we can't just list the paths to all the files
|
||||
# to be copied, because we have to "flatten" the folder hierarchy (e.g. when the user says
|
||||
# "copy dir/subfir/file_a anotherdir/file_b target_dir" we want to end up with
|
||||
# target_dir/file_a and target_dir/file_b. To achieve this, we just save an explicit target path
|
||||
# to each source file. We also have to keep a list of directories we encounter because we want to
|
||||
# create them before we start copying.
|
||||
beeond_generate_copy_lists()
|
||||
{
|
||||
local TARGET="${1}"
|
||||
local NODE_LIST="${2}"
|
||||
local CONCURRENCY="${3}"
|
||||
shift 3
|
||||
|
||||
# Note: We do relative path expansion here, (and not directly in the do_... functions)
|
||||
# because this is the first time we iterate over the source list.
|
||||
|
||||
# Expand target path.
|
||||
if [ ! "${TARGET:0:1}" = "/" ]
|
||||
then
|
||||
TARGET="${PWD}/${TARGET}"
|
||||
fi
|
||||
|
||||
# Delete possibly left over file lists.
|
||||
rm -f "${TARGET}/${BEEOND_COPY_SCAN_LIST}" \
|
||||
"${TARGET}/${BEEOND_COPY_DIR_LIST}" \
|
||||
"${TARGET}/${BEEOND_COPY_FILE_LIST}"
|
||||
|
||||
# Generate lists: A list of files which can be used directly, and a list of directories which
|
||||
# have to be scanned first.
|
||||
for ENTRY in "$@"
|
||||
do
|
||||
# Expand path if it's relative.
|
||||
if [ ! "${ENTRY:0:1}" = "/" ]
|
||||
then
|
||||
ENTRY="${PWD}/${ENTRY}"
|
||||
fi
|
||||
|
||||
beeond_print_info "Path to scan: ${ENTRY}"
|
||||
if [ -d "${ENTRY}" ]; then
|
||||
printf "%q\n" "${ENTRY}" >> "${TARGET}/${BEEOND_COPY_SCAN_LIST}"
|
||||
elif [ -f "${ENTRY}" ]; then
|
||||
printf "%q\n" >> "${TARGET}/${BEEOND_COPY_FILE_LIST}"
|
||||
else
|
||||
beeond_print_error_and_exit "File or directory does not exist: ${ENTRY}"
|
||||
fi
|
||||
done
|
||||
|
||||
beeond_print_info "Scanning sources..."
|
||||
|
||||
< "${TARGET}/${BEEOND_COPY_SCAN_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read DIR; do \
|
||||
cd \"\${DIR}\"; \
|
||||
find . -type d -exec bash -c \\\'printf \"%s/%q\n\" \"\$0\" \"\$1\"\' \"\`basename \"\${DIR}\"\`\" \{\} \; \
|
||||
| grep -v ^\\$; \
|
||||
done;
|
||||
" \
|
||||
| sort > "${TARGET}/${BEEOND_COPY_DIR_LIST}"
|
||||
|
||||
< "${TARGET}/${BEEOND_COPY_SCAN_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read DIR; do \
|
||||
cd \"\${DIR}\"; \
|
||||
find . \( -type f -or -type l \) -exec bash -c \
|
||||
\\\'printf \"%q %q\n\" \"\${PWD}/\$0\" \"${TARGET}/\`basename \"\${PWD}\"\`/\$0\"\' \{\} \; \
|
||||
| grep -v ^\\$; \
|
||||
done; \
|
||||
" \
|
||||
| sort > "${TARGET}/${BEEOND_COPY_FILE_LIST}"
|
||||
}
|
||||
|
||||
# Parallel copy of the files from a previously generated file list to the target directory.
|
||||
# First, the directory structure is generated, then the files are copied into it.
|
||||
beeond_parallel_copy()
|
||||
{
|
||||
local TARGET="${1}"
|
||||
local NODE_LIST="${2}"
|
||||
local CONCURRENCY="${3}"
|
||||
|
||||
# Expand target path.
|
||||
if [ ! "${TARGET:0:1}" = "/" ]
|
||||
then
|
||||
TARGET="${PWD}/${TARGET}"
|
||||
fi
|
||||
|
||||
beeond_print_info "Generating target directory structure..."
|
||||
|
||||
< "${TARGET}/${BEEOND_COPY_DIR_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read DIR; do \
|
||||
mkdir -pv \"${TARGET}/\${DIR}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
beeond_print_info "Copying files..."
|
||||
|
||||
< "${TARGET}/${BEEOND_COPY_FILE_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read -a LINE; do \
|
||||
cp -av \"\${LINE[0]}\" \"\${LINE[1]}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
# Delete temporary files.
|
||||
# rm "${TARGET}/${BEEOND_COPY_SCAN_LIST}" \
|
||||
# "${TARGET}/${BEEOND_COPY_DIR_LIST}" \
|
||||
# "${TARGET}/${BEEOND_COPY_FILE_LIST}"
|
||||
}
|
||||
|
||||
# Remove all files from the global store that have been deleted during the session.
|
||||
beeond_remove_removed_files()
|
||||
{
|
||||
local GLOBAL_PATH="${1}"
|
||||
local LOCAL_PATH="${2}"
|
||||
local NODE_LIST="${3}"
|
||||
local CONCURRENCY="${4}"
|
||||
|
||||
beeond_print_info "Deleting files:"
|
||||
comm -23 "${LOCAL_PATH}/${BEEOND_START_FILE_LIST}" "${LOCAL_PATH}/${BEEOND_END_FILE_LIST}" | \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read FILE; do \
|
||||
rm -v \"${GLOBAL_PATH}/\${FILE}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
beeond_print_info "Deleting directories:"
|
||||
comm -23 "${LOCAL_PATH}/${BEEOND_START_DIR_LIST}" "${LOCAL_PATH}/${BEEOND_END_DIR_LIST}" | \
|
||||
tac | \
|
||||
xargs -I{} rmdir -v "${GLOBAL_PATH}/{}"
|
||||
# Not being done in parallel to avoid deleting a subdirectory before its parent (this is also
|
||||
# the reason the list is inverted (tac)).
|
||||
}
|
||||
|
||||
# Copy back all files to the global store that have been updated during the session.
|
||||
beeond_copy_updated_files()
|
||||
{
|
||||
local GLOBAL_PATH="${1}"
|
||||
local LOCAL_PATH="${2}"
|
||||
local NODE_LIST="${3}"
|
||||
local CONCURRENCY="${4}"
|
||||
|
||||
beeond_print_info "Creating new directories:"
|
||||
|
||||
< "${LOCAL_PATH}/${BEEOND_END_DIR_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read DIR; do \
|
||||
mkdir -pv \"${GLOBAL_PATH}/\${DIR}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
beeond_print_info "Copying back changed files:"
|
||||
|
||||
< "${LOCAL_PATH}/${BEEOND_END_UPDATED_FILE_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read FILE; do \
|
||||
cp -uv \"${LOCAL_PATH}/\${FILE}\" \"${GLOBAL_PATH}/\${FILE}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
# Copy files into updated directories. (When a directory is renamed or files
|
||||
# are moved to a directory, the files in it don't have their timestamp
|
||||
# updated. Therefore, we need to check all the updated directories again).
|
||||
|
||||
beeond_print_info "Copying back changed files (updated dirs):"
|
||||
|
||||
pushd "${LOCAL_PATH}"
|
||||
< "${LOCAL_PATH}/${BEEOND_END_UPDATED_DIR_LIST}" \
|
||||
xargs -I{} find {} -maxdepth 1 \( -type f -or -type l \) | \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read FILE; do \
|
||||
cp -uv \"${LOCAL_PATH}/\${FILE}\" \"\`dirname \"${GLOBAL_PATH}/\${FILE}\"\`\"; \
|
||||
done; \
|
||||
"
|
||||
popd
|
||||
}
|
||||
|
||||
# Stage in process: Copy all files from the global store to the local store.
|
||||
beeond_stage_in()
|
||||
{
|
||||
local GLOBAL_PATH="${1}"
|
||||
local LOCAL_PATH="${2}"
|
||||
local NODE_LIST="${3}"
|
||||
local CONCURRENCY="${4}"
|
||||
|
||||
# Generate list of files that have to be copied.
|
||||
beeond_generate_file_list "${GLOBAL_PATH}" "${LOCAL_PATH}/${BEEOND_START_FILE_LIST}"
|
||||
beeond_generate_directory_list "${GLOBAL_PATH}" "${LOCAL_PATH}/${BEEOND_START_DIR_LIST}"
|
||||
|
||||
beeond_print_info "Creating directory structure..."
|
||||
< "${LOCAL_PATH}/${BEEOND_START_DIR_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read DIR; do \
|
||||
mkdir -pv \"${LOCAL_PATH}/\${DIR}\"; \
|
||||
touch --reference=\"${GLOBAL_PATH}/\${DIR}\" \"${LOCAL_PATH}/\${DIR}\"; \
|
||||
done; \
|
||||
"
|
||||
|
||||
beeond_print_info "Copying files to local directory..."
|
||||
if ! < "${LOCAL_PATH}/${BEEOND_START_FILE_LIST}" \
|
||||
${PARALLEL} -S "${NODE_LIST}" -j"${CONCURRENCY}" --pipe --recend "\n" \
|
||||
-N${BEEOND_BATCH_SIZE} --controlmaster --will-cite \
|
||||
" \
|
||||
while read FILE; do \
|
||||
cp -av \"${GLOBAL_PATH}/\${FILE}\" \"\`dirname \"${LOCAL_PATH}/\${FILE}\"\`\"/; \
|
||||
done;
|
||||
"
|
||||
then
|
||||
beeond_print_error "Stage-in copy did not succeed. Data is incompletely staged in."
|
||||
fi
|
||||
|
||||
# Generate list of files and dirs that were actually copied to keep track if the user deletes
|
||||
# files during a session. (re-generate list here, so that if something went wrong during the
|
||||
# stage-in copy, we don't start deleting stuff from the global store by accident).
|
||||
beeond_generate_file_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_START_FILE_LIST}"
|
||||
beeond_generate_directory_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_START_DIR_LIST}"
|
||||
}
|
||||
|
||||
# Stage out process: remove all the files that have been removed during the beeond session,
|
||||
# and copy back the files which have been changed.
|
||||
beeond_stage_out()
|
||||
{
|
||||
local GLOBAL_PATH="${1}"
|
||||
local LOCAL_PATH="${2}"
|
||||
local NODE_LIST="${3}"
|
||||
local CONCURRENCY="${4}"
|
||||
|
||||
beeond_print_info "Nodes for parallel stage out: ${NODE_LIST}."
|
||||
|
||||
beeond_generate_file_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_END_FILE_LIST}"
|
||||
beeond_generate_file_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_END_UPDATED_FILE_LIST}" \
|
||||
"${BEEOND_START_FILE_LIST}"
|
||||
|
||||
beeond_generate_directory_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_END_DIR_LIST}"
|
||||
beeond_generate_directory_list "${LOCAL_PATH}" "${LOCAL_PATH}/${BEEOND_END_UPDATED_DIR_LIST}" \
|
||||
"${BEEOND_START_DIR_LIST}"
|
||||
|
||||
beeond_remove_removed_files "${GLOBAL_PATH}" "${LOCAL_PATH}" "${NODE_LIST}" "${CONCURRENCY}"
|
||||
|
||||
beeond_copy_updated_files "${GLOBAL_PATH}" "${LOCAL_PATH}" "${NODE_LIST}" "${CONCURRENCY}"
|
||||
}
|
||||
|
||||
# Parallel copy process: copy all files and directories (recursively) into the target directory.
|
||||
beeond_copy()
|
||||
{
|
||||
local NODE_LIST="${1}"
|
||||
local CONCURRENCY="${2}"
|
||||
shift 2
|
||||
|
||||
beeond_print_info "Nodes for parallel copy: ${NODE_LIST}; Concurrency: ${CONCURRENCY}"
|
||||
|
||||
beeond_generate_copy_lists "${@:$#}" "${NODE_LIST}" "${CONCURRENCY}" "${@:1:$#-1}"
|
||||
beeond_parallel_copy "${@:$#}" "${NODE_LIST}" "${CONCURRENCY}"
|
||||
|
||||
}
|
||||
1606
beeond/source/beeond
Executable file
1606
beeond/source/beeond
Executable file
File diff suppressed because it is too large
Load Diff
354
beeond/source/beeond-cp
Executable file
354
beeond/source/beeond-cp
Executable file
@@ -0,0 +1,354 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source helper script.
|
||||
ABSOLUTE_PATH=$(dirname "$(readlink -e "$0")") # using readlink, because somone might be calling
|
||||
# this script using a symlink
|
||||
|
||||
if [ -e "${ABSOLUTE_PATH}/../lib/beeond-lib" ]
|
||||
then
|
||||
BEEOND_LIB="${ABSOLUTE_PATH}/../lib/beeond-lib"
|
||||
else
|
||||
BEEOND_LIB="${ABSOLUTE_PATH}/../scripts/lib/beeond-lib"
|
||||
fi
|
||||
|
||||
#shellcheck source=scripts/lib/beeond-lib
|
||||
source "${BEEOND_LIB}"
|
||||
PARALLEL="${ABSOLUTE_PATH}/../thirdparty/parallel/parallel"
|
||||
|
||||
# Print usage.
|
||||
print_usage_and_exit()
|
||||
{
|
||||
echo ""
|
||||
echo "BeeOND copy (http://www.beegfs.com)"
|
||||
echo ""
|
||||
echo "DESCRIPTION:"
|
||||
echo " BeeGFS OnDemand copying/staging system."
|
||||
echo ""
|
||||
echo "USAGE: $(basename "$0") <mode> <options>"
|
||||
echo ""
|
||||
echo "ACTIONS:"
|
||||
echo " The first argument to $(basename "$0") is considered to be an action that the script"
|
||||
echo " should perform."
|
||||
echo ""
|
||||
echo " The following actions are available:"
|
||||
echo ""
|
||||
echo " stagein: (EXPERIMENTAL)"
|
||||
echo " Stage a complete directory from the global storage in to BeeOND."
|
||||
echo ""
|
||||
echo " Mandatory arguments:"
|
||||
echo " -n FILENAME => File containing the list of nodes where the parallel"
|
||||
echo " copy should be performed. All nodes must have access to"
|
||||
echo " the global and local directories."
|
||||
echo " -g PATH => Directory on global storage. (*)"
|
||||
echo " -l PATH => Directory on local (BeeOND) storage. (*)"
|
||||
echo ""
|
||||
echo " Notes:"
|
||||
echo " (*) Global and local directories have to be specified in form of an"
|
||||
echo " absolute path."
|
||||
echo ""
|
||||
echo " stageout: (EXPERIMENTAL)"
|
||||
echo " Stage a complete directory out from BeeOND to the global storage."
|
||||
echo " Only changes will be staged out of the local directory and committed to"
|
||||
echo " the global directory."
|
||||
echo ""
|
||||
echo " Mandatory arguments:"
|
||||
echo " -l PATH => Local directory."
|
||||
echo ""
|
||||
echo " Notes:"
|
||||
echo " The contents will be completely synchronized, i.e. deleted files on "
|
||||
echo " BeeOND will get deleted on global storage, too."
|
||||
echo ""
|
||||
echo " copy:"
|
||||
echo " Perform a parallel copy of a set of files or folders."
|
||||
echo " Files will be copied into the target directory, folders will be copied"
|
||||
echo " recursively. The copy process is parallelized across the set of nodes"
|
||||
echo " specified in the nodefile."
|
||||
echo ""
|
||||
echo " Mandatory arguments:"
|
||||
echo " -n FILENAME => File containing the list of nodes where the parallel"
|
||||
echo " copy should be performed. All nodes must have access to"
|
||||
echo " the sources and the target directory."
|
||||
echo ""
|
||||
echo " Notes:"
|
||||
echo " Further command line arguments are consdiered source directory or file"
|
||||
echo " names. The last command line argument specifies the target directory"
|
||||
echo ""
|
||||
echo "EXAMPLES:"
|
||||
echo " Stage data from /mnt/beegfs-global/dataset in to BeeOND mounted at /mnt/beeond,"
|
||||
echo " using the nodes given in /tmp/nodefile:"
|
||||
echo " beeond-cp stagein -n /tmp/nodefile -g /mnt/beegfs-global/dataset -l /mnt/beeond"
|
||||
echo ""
|
||||
echo " Stage out modified data from BeeOND mounted at /mnt/beeond to the global "
|
||||
echo " storage:"
|
||||
echo " beeond-cp stageout -n /tmp/nodefile -g /mnt/beegfs-global/dataset -l /mnt/beeond"
|
||||
echo ""
|
||||
echo " Recursively copy the directories dir_1 and dir_2 to /mnt/beegfs, using the nodes"
|
||||
echo " in /tmp/nodefile:"
|
||||
echo " beeond-cp copy -n /tmp/nodefile dir_1 dir_2 /mnt/beegfs"
|
||||
echo ""
|
||||
echo "NOTE:"
|
||||
echo " BeeOND copy uses GNU Parallel -"
|
||||
echo " When using programs that use GNU Parallel to process data for publication"
|
||||
echo " please cite:"
|
||||
echo " O. Tange (2011): GNU Parallel - The Command-Line Power Tool,"
|
||||
echo " ;login: The USENIX Magazine, February 2011:42-47."
|
||||
echo ""
|
||||
echo " SSH is used to log into the nodes specified in the nodefile. Please make"
|
||||
echo " sure your SSH configuration allows for enough concurrent sessions and pending"
|
||||
echo " logins. You might have to (ask your admin to) raise the MaxSessions and"
|
||||
echo " MaxStartups settings in the sshd_config file."
|
||||
echo ""
|
||||
echo " Also please make sure you have the access rights needed to write to the"
|
||||
echo " global store. Otherwise the stage-out might fail. Note that the access rights"
|
||||
echo " in the BeeOND local store do not necessarily reflect those in the global"
|
||||
echo " store."
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
### main functions
|
||||
do_start()
|
||||
{
|
||||
local NODEFILE="${1}"
|
||||
local GLOBAL_PATH="${2}"
|
||||
local LOCAL_PATH="${3}"
|
||||
|
||||
beeond_print_info "BeeOND startup..."
|
||||
|
||||
beeond_print_info "nodefile: ${NODEFILE}"
|
||||
beeond_print_info "global path: ${GLOBAL_PATH}"
|
||||
beeond_print_info "local path: ${LOCAL_PATH}"
|
||||
|
||||
MISSING_PARAM=0
|
||||
if [ "${NODEFILE}" = "" ]
|
||||
then
|
||||
beeond_print_error "No nodefile specified."
|
||||
MISSING_PARAM=1
|
||||
fi
|
||||
if [ "${GLOBAL_PATH}" = "" ]
|
||||
then
|
||||
beeond_print_error "Global path not specified."
|
||||
MISSING_PARAM=1
|
||||
fi
|
||||
if [ "${LOCAL_PATH}" = "" ]
|
||||
then
|
||||
beeond_print_error "Local path not specified."
|
||||
MISSING_PARAM=1
|
||||
fi
|
||||
|
||||
# Expand relative path to nodefile.
|
||||
if [ ! "${NODEFILE:0:1}" = "/" ]
|
||||
then
|
||||
NODEFILE="${PWD}/${NODEFILE}"
|
||||
fi
|
||||
|
||||
if [ ! -e "${NODEFILE}" ]
|
||||
then
|
||||
beeond_print_error_and_exit "Node file does not exist."
|
||||
fi
|
||||
|
||||
# The paths to the global and local directory have to be specified as absolute paths to prevent
|
||||
# user errors (like copying a lot of files to ~/mnt/beeond).
|
||||
if [ ! "${GLOBAL_PATH:0:1}" = "/" ] || [ ! "${LOCAL_PATH:0:1}" = "/" ]
|
||||
then
|
||||
beeond_print_error_and_exit "Global path and local path have to be absolute."
|
||||
fi
|
||||
|
||||
[ "${MISSING_PARAM}" = "1" ] && exit 1
|
||||
|
||||
# Make sure target directory is empty before starting.
|
||||
if [ -e "${LOCAL_PATH}" ]
|
||||
then
|
||||
[ -d "${LOCAL_PATH}" ] \
|
||||
|| beeond_print_error_and_exit "Target path is not a directory."
|
||||
|
||||
find "${LOCAL_PATH}" -maxdepth 0 -type d -empty | read -r _ \
|
||||
|| beeond_print_error_and_exit "Target directory is not empty."
|
||||
else
|
||||
mkdir -p "${LOCAL_PATH}" \
|
||||
|| beeond_print_error_and_exit "Cannot create target directory."
|
||||
fi
|
||||
|
||||
local CONCURRENCY=$(( $(wc -l < "${NODEFILE}") ))
|
||||
beeond_print_info "Concurrency: ${CONCURRENCY}"
|
||||
|
||||
beeond_print_info "Writing session information."
|
||||
beeond_save_session_info "${NODEFILE}" "${GLOBAL_PATH}"
|
||||
|
||||
beeond_print_info "Starting stage-in..."
|
||||
NODES=( $(grep -v '^$' "${NODEFILE}" | uniq) ) # Store as array and ignore empty lines.
|
||||
NODELIST=$(IFS=,; echo "${NODES[*]}") # turn argument list into comma-separated string for PDSH
|
||||
|
||||
beeond_stage_in "${GLOBAL_PATH}" "${LOCAL_PATH}" "${NODELIST}" ${CONCURRENCY}
|
||||
|
||||
beeond_print_info "Done."
|
||||
}
|
||||
|
||||
do_stop()
|
||||
{
|
||||
local LOCAL_PATH="${1}"
|
||||
|
||||
if [ "${LOCAL_PATH}" = "" ]
|
||||
then
|
||||
beeond_print_error_and_exit "No path specified."
|
||||
fi
|
||||
|
||||
# Expand relative local path.
|
||||
# Note: Don't have to ensure that it's an absolute path here: We confirm it's a BeeOND instance
|
||||
# by looking for the session info file.
|
||||
if [ ! "${LOCAL_PATH:0:1}" = "/" ]
|
||||
then
|
||||
LOCAL_PATH="${PWD}/${LOCAL_PATH}"
|
||||
fi
|
||||
|
||||
# Read parameters from session info file.
|
||||
NODEFILE=$(grep NodeFile "${LOCAL_PATH}/${BEEOND_SESSION_FILE}" | cut -d = -f 2-)
|
||||
GLOBAL_PATH=$(grep GlobalPath "${LOCAL_PATH}/${BEEOND_SESSION_FILE}" | cut -d = -f 2-)
|
||||
|
||||
if [ "${NODEFILE}" = "" ]
|
||||
then
|
||||
beeond_print_error "Error reading node file name from session file."
|
||||
MISSING_PARAM=1
|
||||
fi
|
||||
if [ "${GLOBAL_PATH}" = "" ]
|
||||
then
|
||||
beeond_print_error "Error reading global path from session file."
|
||||
MISSING_PARAM=1
|
||||
fi
|
||||
|
||||
[ "${MISSING_PARAM}" = "1" ] && exit 1
|
||||
|
||||
if [ ! -e "${NODEFILE}" ]
|
||||
then
|
||||
beeond_print_error_and_exit "Node file does not exist."
|
||||
fi
|
||||
|
||||
beeond_print_info "BeeOND shutdown..."
|
||||
|
||||
beeond_print_info "nodefile: ${NODEFILE}"
|
||||
beeond_print_info "global path: ${GLOBAL_PATH}"
|
||||
beeond_print_info "local path: ${LOCAL_PATH}"
|
||||
|
||||
NODES=( $(grep -v '^$' "${NODEFILE}" | uniq) ) # Store as array and ignore empty lines.
|
||||
NODELIST=$(IFS=,; echo "${NODES[*]}")
|
||||
|
||||
local CONCURRENCY=$(( $(wc -l < "${NODEFILE}") ))
|
||||
beeond_print_info "Concurrency: ${CONCURRENCY}"
|
||||
|
||||
beeond_stage_out "${GLOBAL_PATH}" "${LOCAL_PATH}" "${NODELIST}" ${CONCURRENCY}
|
||||
|
||||
beeond_print_info "Done."
|
||||
}
|
||||
|
||||
do_copy()
|
||||
{
|
||||
local NODEFILE="${1}"
|
||||
shift
|
||||
|
||||
beeond_print_info "BeeOND copy..."
|
||||
|
||||
if [ "${NODEFILE}" = "" ]
|
||||
then
|
||||
beeond_print_error "No nodefile specified."
|
||||
fi
|
||||
|
||||
# Expand relative path to nodefile.
|
||||
if [ ! "${NODEFILE:0:1}" = "/" ]
|
||||
then
|
||||
NODEFILE="${PWD}/${NODEFILE}"
|
||||
fi
|
||||
|
||||
if [ ! -e "${NODEFILE}" ]
|
||||
then
|
||||
beeond_print_error_and_exit "Node file does not exist."
|
||||
fi
|
||||
|
||||
NODES=( $(grep -v '^$' "${NODEFILE}" | uniq) ) # Store as array and ignore empty lines.
|
||||
NODELIST=$(IFS=,; echo "${NODES[*]}")
|
||||
|
||||
local CONCURRENCY=$(( $(wc -l < "${NODEFILE}") ))
|
||||
beeond_print_info "Concurrency: ${CONCURRENCY}"
|
||||
|
||||
beeond_copy "${NODELIST}" "${CONCURRENCY}" "$@"
|
||||
}
|
||||
|
||||
# Print help if no arguments given.
|
||||
if [ $# -eq 0 ] ; then
|
||||
print_usage_and_exit
|
||||
fi
|
||||
|
||||
# Do it.
|
||||
ACTION="${1}"
|
||||
|
||||
if [ "${ACTION}" = "stagein" ]
|
||||
then
|
||||
shift
|
||||
while getopts ":n:g:l:" opt; do
|
||||
case $opt in
|
||||
n)
|
||||
NODEFILE="${OPTARG}"
|
||||
;;
|
||||
g)
|
||||
GLOBAL_PATH="${OPTARG}"
|
||||
;;
|
||||
l)
|
||||
LOCAL_PATH="${OPTARG}"
|
||||
;;
|
||||
\?)
|
||||
beeond_print_error_and_exit "Invalid option: -${OPTARG}."
|
||||
;;
|
||||
:)
|
||||
beeond_print_error_and_exit "Option -${OPTARG} requires an argument."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
do_start "${NODEFILE}" "${GLOBAL_PATH}" "${LOCAL_PATH}"
|
||||
elif [ "${ACTION}" = "stageout" ]
|
||||
then
|
||||
shift
|
||||
while getopts ":l:" opt; do
|
||||
case $opt in
|
||||
l)
|
||||
LOCAL_PATH="${OPTARG}"
|
||||
;;
|
||||
\?)
|
||||
beeond_print_error_and_exit "Invalid option: -${OPTARG}."
|
||||
;;
|
||||
:)
|
||||
beeond_print_error_and_exit "Option -${OPTARG} requires an argument."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
do_stop "${LOCAL_PATH}"
|
||||
elif [ "${ACTION}" = "copy" ]
|
||||
then
|
||||
shift
|
||||
|
||||
# Nodefile has to be given as the only command line argument.
|
||||
if getopts ":n:" opt
|
||||
then
|
||||
if [ "$opt" = "n" ]
|
||||
then
|
||||
NODEFILE="${OPTARG}"
|
||||
else
|
||||
beeond_print_error_and_exit "Invalid option: -${opt}"
|
||||
fi
|
||||
|
||||
else
|
||||
beeond_print_error_and_exit "No nodefile specified."
|
||||
fi
|
||||
|
||||
# All following command line arguments are file or directory names, specifying the sources and
|
||||
# the target of the copy ancion
|
||||
shift # shift out -n parameter
|
||||
shift # shift out name of node file
|
||||
|
||||
do_copy "${NODEFILE}" "$@"
|
||||
elif [ "${ACTION}" = "info" ]
|
||||
then
|
||||
do_print_info
|
||||
else
|
||||
print_usage_and_exit
|
||||
fi
|
||||
598
build/Makefile
Normal file
598
build/Makefile
Normal file
@@ -0,0 +1,598 @@
|
||||
##### BASE MAKEFILE
|
||||
#
|
||||
# This makefile is intended to be a basis on which new makefiles are written.
|
||||
# It is divided into five parts:
|
||||
# * help text generation
|
||||
# * path for subproject locations and thirparty include/library paths
|
||||
# * default values for tools (like CXX) and compiler/linker flags
|
||||
# * description of known libraries that may be used in the build
|
||||
# * functions that define build artifacts
|
||||
#
|
||||
# library handling will be described in detail later.
|
||||
#
|
||||
# we have three functions that defined build artifacts:
|
||||
# * build-executable
|
||||
# * build-static-library
|
||||
# * build-dynamic-library
|
||||
#
|
||||
# they all have the same, basic signature:
|
||||
# (name: string, sources: list<string>, usedLibraries: list<string>)
|
||||
#
|
||||
# $name determines the name given to the output file (for executables) or the library name given
|
||||
# to the output library (for libraries).
|
||||
#
|
||||
# $sources must be a list of source files (allowed types are .cpp and .c), relative to the directory
|
||||
# of the Makefile you are writing (see example below).
|
||||
#
|
||||
# $usedLibraries is a (possibly empty) list of libraries as defined in the KNOWN LIBRARIES section
|
||||
# below. they will be automatically added to compiler and linker invocations as needed.
|
||||
#
|
||||
# EXAMPLE:
|
||||
#
|
||||
# imagine you have a project with a directory structure like this:
|
||||
# - /build
|
||||
# - Makefile
|
||||
# - /source
|
||||
# - /lib
|
||||
# - ...
|
||||
# - /exe
|
||||
# - ...
|
||||
#
|
||||
# you want your Makefile to build a shared library from /source/lib and an executable from
|
||||
# /source/exe. the you could write your Makefile like this:
|
||||
#
|
||||
# include ,../../build/Makefile
|
||||
#
|
||||
# # will generate a libFancy.so in /build, uses libz
|
||||
# $(call build-static-library,\
|
||||
# Fancy,\
|
||||
# $(shell find ../source/lib -iname '*.cpp'),\
|
||||
# z)
|
||||
#
|
||||
# # this registers libFancy as a shared library. see details below (KNOWN LIBRARIES).
|
||||
# $(call define-dep-lib, Fancy, -I ../source/lib/include, -L . -l Fancy)
|
||||
#
|
||||
# # will generate an executable file Run in /build, uses libFancy
|
||||
# $(call build-executable,\
|
||||
# Run,\
|
||||
# $(shell find ../source/exe -iname '*.cpp'),\
|
||||
# Fancy)
|
||||
#
|
||||
# # a dependency must be added between Run and Fancy, to ensure that Fancy is built first.
|
||||
# Run: | libFancy.so
|
||||
|
||||
override V := $(if $V,,@)
|
||||
|
||||
all:
|
||||
|
||||
define HELP_ARGS_GENERIC
|
||||
@echo ' BEEGFS_DEBUG=1 Enables debug information and symbols'
|
||||
@echo ' BEEGFS_DEBUG_OPT=1 Enables internal debug code, but compiled'
|
||||
@echo ' with optimizations'
|
||||
@echo ' BEEGFS_DEBUG_IP=1 Enables low-level debug of network sendto'
|
||||
@echo ' and recvfrom'
|
||||
@echo ' CXX=<compiler> Specifies a c++ compiler'
|
||||
@echo ' DISTCC=distcc Enables the usage of distcc'
|
||||
@echo ' V=1 Print command lines of tool invocations'
|
||||
@echo ' BEEGFS_COMMON_PATH=<path> Path to the common directory'
|
||||
@echo ' BEEGFS_THIRDPARTY_PATH=<path>'
|
||||
@echo ' Path to the thirdparty directory'
|
||||
@echo ' BEEGFS_USE_PCH=1 Enables use of precompiled headers'
|
||||
endef
|
||||
define HELP_TARGETS_GENERIC
|
||||
@echo ' all (default) build only'
|
||||
@echo ' clean delete compiled files'
|
||||
@echo ' help print this help message'
|
||||
endef
|
||||
|
||||
help:
|
||||
@echo 'Optional arguments:'
|
||||
$(HELP_ARGS_GENERIC)
|
||||
$(HELP_ARGS_SPECIFIC)
|
||||
@echo
|
||||
@echo 'Targets:'
|
||||
$(HELP_TARGETS_GENERIC)
|
||||
$(HELP_TARGETS_SPECIFIC)
|
||||
|
||||
root_dir := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))/..)
|
||||
build_dir := $(realpath $(dir $(firstword $(MAKEFILE_LIST))))
|
||||
|
||||
BEEGFS_COMMON_PATH ?= $(root_dir)/common
|
||||
BEEGFS_COMMON_PCH_H ?= $(BEEGFS_COMMON_PATH)/source/common/pch.h
|
||||
BEEGFS_THIRDPARTY_PATH ?= $(root_dir)/thirdparty
|
||||
BEEGFS_COMM_DEBUG_PATH ?= $(root_dir)/comm_debug
|
||||
BEEGFS_FSCK_PATH ?= $(root_dir)/fsck
|
||||
BEEGFS_EVENT_LISTENER_PATH ?= $(root_dir)/event_listener
|
||||
BEEGFS_DEVEL_INCLUDE_PATH ?= $(root_dir)/client_devel/include
|
||||
BEEGFS_CLIENT_PATH ?= $(root_dir)/client_module/include
|
||||
|
||||
BOOST_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/boost
|
||||
NU_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/nu/include
|
||||
|
||||
GTEST_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/gtest/googletest/include
|
||||
GTEST_LIB_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/build
|
||||
|
||||
ifneq ($(target_arch),)
|
||||
STRIP := $(target_arch)-strip
|
||||
AR := $(target_arch)-ar
|
||||
CC := $(target_arch)-gcc
|
||||
CXX := $(target_arch)-g++
|
||||
endif
|
||||
|
||||
SHELL := /bin/bash
|
||||
STRIP ?= strip
|
||||
CXX ?= g++
|
||||
AR ?= ar
|
||||
CLANG_TIDY ?= clang-tidy
|
||||
|
||||
# if -T is supported by ar, use it. thin archives are quicker to create and maintain.
|
||||
ifeq ($(shell ar -TM 2>&1 <<<""),)
|
||||
AR += -T
|
||||
endif
|
||||
|
||||
CXXFLAGS = \
|
||||
-std=c++17 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \
|
||||
-isystem $(BOOST_INC_PATH) -isystem $(NU_INC_PATH) \
|
||||
-pthread \
|
||||
-fno-strict-aliasing -fmessage-length=0 \
|
||||
-Wall -Wextra -Wunused-variable -Woverloaded-virtual -Wno-unused-parameter -Wuninitialized \
|
||||
-Wno-missing-field-initializers \
|
||||
-Winvalid-pch \
|
||||
-ggdb3 \
|
||||
$(USER_CXXFLAGS)
|
||||
CXXFLAGS_RELEASE = -O3 -Wuninitialized
|
||||
CXXFLAGS_DEBUG = -O1 -D_FORTIFY_SOURCE=2 \
|
||||
-DBEEGFS_DEBUG -DDEBUG_READWRITE -DDEBUG_MUTEX_LOCKING -DDEBUG_REFCOUNT \
|
||||
-DDEBUG_BACKTRACE -DLOG_DEBUG_MESSAGES
|
||||
CXXFLAGS_COVERAGE = --coverage -O1 -fno-inline
|
||||
|
||||
LDFLAGS = -std=c++1y \
|
||||
-rdynamic \
|
||||
-pthread -lrt \
|
||||
-Wl,-rpath,'$$ORIGIN/../lib' \
|
||||
$(USER_LDFLAGS)
|
||||
LDFLAGS_COVERAGE = --coverage
|
||||
|
||||
ifneq ($(BEEGFS_DEBUG),)
|
||||
CXXFLAGS += $(CXXFLAGS_DEBUG)
|
||||
else ifneq ($(BEEGFS_COVERAGE),)
|
||||
CXXFLAGS += $(CXXFLAGS_COVERAGE)
|
||||
LDFLAGS += $(LDFLAGS_COVERAGE)
|
||||
else
|
||||
CXXFLAGS += $(CXXFLAGS_RELEASE)
|
||||
endif
|
||||
|
||||
|
||||
CXXFLAGS += -DBEEGFS_VERSION="\"$(BEEGFS_VERSION)\""
|
||||
|
||||
ifeq ($(BEEGFS_NVFS),1)
|
||||
CXXFLAGS += -DBEEGFS_NVFS
|
||||
endif
|
||||
|
||||
ifeq ($(BEEGFS_DEBUG_RDMA),1)
|
||||
CXXFLAGS += -DBEEGFS_DEBUG_RDMA
|
||||
endif
|
||||
|
||||
ifneq ($(BEEGFS_DEBUG_IP),)
|
||||
CXXFLAGS += -DBEEGFS_DEBUG_IP
|
||||
endif
|
||||
|
||||
###### KNOWN LIBRARIES
|
||||
#
|
||||
# this is our local registry of known libraries, both our own and thirdparty libraries.
|
||||
#
|
||||
# currently supports building with our own libraries common and client-devel.
|
||||
# thirdparty packages supported are:
|
||||
# * dl (from system)
|
||||
#
|
||||
# to define new libraries, add appriopriate calls to define-dep-lib in this section.
|
||||
# the signature of define-dep-lib is:
|
||||
# (name: string, CXXFLAGS: string, libraryPath: string[, LDFLAGS: string])
|
||||
#
|
||||
# $name is used to identify the library within this registry, and is otherwise unused.
|
||||
#
|
||||
# $CXXFLAGS will be added to the set of CXXFLAGS used when compiling files from projects that use
|
||||
# this library (see example at the beginning of this file for reference).
|
||||
#
|
||||
# $libraryPath is the path (absolute or relative) to the library. glob patterns are allowed, and in
|
||||
# fact required if you want to link a dynamic library.
|
||||
#
|
||||
# $LDFLAGS will be added to the set of LDFLAGS used when linking shared libraries or executables
|
||||
# that use this library. if the library you want to link is static, LDFLAGS need not be set - the
|
||||
# library will be added to the list of archives.
|
||||
#
|
||||
#
|
||||
# to define libraries that are taken from the system, use define-dep-lib-system. it will use its
|
||||
# arguments to ask pkgconfig for the correct compiler and linker flags. then signature of
|
||||
# define-dep-lib-system is:
|
||||
# (name: string, pkgconfigID: string)
|
||||
#
|
||||
# $name is used only to identify the library.
|
||||
#
|
||||
# $pkgconfigID is the identifier pkgconfig will be asked about.
|
||||
define resolve-dep-cflags
|
||||
$(if $(filter undefined,$(origin _DEP_LIB_CXX[$(strip $1)])),\
|
||||
$(error I have no CXXFLAGS for $1!),\
|
||||
$(_DEP_LIB_CXX[$(strip $1)]))
|
||||
endef
|
||||
define resolve-dep-ldflags
|
||||
$(if $(filter undefined,$(origin _DEP_LIB_LD[$(strip $1)])),\
|
||||
$(error I have no LDFLAGS for $1!),\
|
||||
$(_DEP_LIB_LD[$(strip $1)]))
|
||||
endef
|
||||
define resolve-dep-deps
|
||||
$(if $(filter undefined,$(origin _DEP_LIB_DEPS[$(strip $1)])),\
|
||||
$(error I have no library dependencies for $1!),\
|
||||
$(_DEP_LIB_DEPS[$(strip $1)]))
|
||||
endef
|
||||
define define-dep-lib
|
||||
$(strip
|
||||
$(eval _DEP_LIB_CXX[$(strip $1)] = $(strip $2))
|
||||
$(eval _DEP_LIB_LD[$(strip $1)] = $(strip $(or $4, $3)))
|
||||
$(eval _DEP_LIB_DEPS[$(strip $1)] = $(strip $3))
|
||||
$(eval $(strip $3): ))
|
||||
endef
|
||||
define define-dep-lib-system
|
||||
$(strip
|
||||
$(if $(shell pkg-config --exists $2 || echo fail),
|
||||
$(error Could not find library $2 in system!))
|
||||
$(call define-dep-lib,
|
||||
$1,
|
||||
$(shell pkg-config --cflags $2),
|
||||
$(shell pkg-config --libs $2)))
|
||||
endef
|
||||
|
||||
# don't bother to search the system for libraries if we only run `make clean'
|
||||
# this also has the nice side effect that libraries needn't be present in the system
|
||||
# when `make clean' is run - if we override dependency resolution to not do anything.
|
||||
ifeq ($(strip $(MAKECMDGOALS)),clean)
|
||||
resolve-dep-cflags :=
|
||||
resolve-dep-ldflags :=
|
||||
resolve-dep-deps :=
|
||||
else
|
||||
$(call define-dep-lib, common,\
|
||||
-I $(BEEGFS_COMMON_PATH)/source \
|
||||
-I $(BEEGFS_CLIENT_PATH), \
|
||||
-ldl $(BEEGFS_COMMON_PATH)/build/libbeegfs-common.a)
|
||||
|
||||
$(call define-dep-lib, client-devel,\
|
||||
-I $(BEEGFS_DEVEL_INCLUDE_PATH),)
|
||||
|
||||
$(call define-dep-lib, dl, , , -ldl)
|
||||
|
||||
$(call define-dep-lib, rdma, , -lrdmacm -libverbs)
|
||||
|
||||
$(call define-dep-lib, gtest,\
|
||||
-isystem $(GTEST_INC_PATH)/include,\
|
||||
$(GTEST_LIB_PATH)/libgtest.a)
|
||||
|
||||
$(call define-dep-lib, cassandra, -I$(BEEGFS_THIRDPARTY_PATH)/source/datastax)
|
||||
|
||||
$(call define-dep-lib-system, curl, libcurl)
|
||||
$(call define-dep-lib-system, z, zlib)
|
||||
|
||||
$(call define-dep-lib, blkid, , , -lblkid)
|
||||
$(call define-dep-lib, uuid, , , -luuid)
|
||||
$(call define-dep-lib-system, nl3-route, libnl-route-3.0)
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
@$(RM) -rf $(if $V,,-v) $(CLEANUP_FILES)
|
||||
|
||||
|
||||
NONDEP_MAKEFILES = $(filter-out %.d,$(MAKEFILE_LIST))
|
||||
|
||||
%.autogen.h:
|
||||
@# Generate a proxy-header for precompilation.
|
||||
@true > $@ # truncate file
|
||||
@echo '/* Autogenerated precompiled header (PCH)' >> $@
|
||||
@echo ' * For each set of compiler options we need to compile ' >> $@
|
||||
@echo ' * a PCH separately. To realize that, we create ' >> $@
|
||||
@echo ' * proxy PCHs like this file and compile these. */' >> $@
|
||||
@echo '#include "$(BEEGFS_COMMON_PCH_H)"' >> $@
|
||||
|
||||
%.h.gch: %.h
|
||||
@echo "[CXX] $@"
|
||||
$V$(CXX) $(CXXFLAGS) -c $< -E -MMD -MP -MF$<.d -MT$@ -o/dev/null
|
||||
$V$(DISTCC) $(CXX) $(CXXFLAGS) -o$@ -c $(realpath $<)
|
||||
|
||||
%.cpp.o: %.cpp $(NONDEP_MAKEFILES)
|
||||
@echo "[CXX] $<"
|
||||
$V$(DISTCC) $(CXX) $(CXXFLAGS) -MMD -MF$<.d -MT$<.o -MP -o $<.o -c $(realpath $<)
|
||||
|
||||
%.c.o: %.c $(NONDEP_MAKEFILES)
|
||||
@echo "[CXX] $<"
|
||||
$V$(DISTCC) $(CXX) $(CXXFLAGS) -MMD -MF$<.d -MT$<.o -MP -o$<.o -c $(realpath $<)
|
||||
|
||||
# first partial list: checks we want to exclude on a general basis right now
|
||||
# second list: very minor problems we don't want to be bugged about yet, but want to fix over time
|
||||
# third list: definite errors, fix as soon as possible
|
||||
define -clang_tidy_checks
|
||||
-clang-analyzer-alpha.deadcode.UnreachableCode
|
||||
-fuchsia-default-arguments
|
||||
-fuchsia-overloaded-operator
|
||||
-google-build-using-namespace
|
||||
-google-readability-braces-around-statements
|
||||
-google-readability-casting
|
||||
-google-readability-namespace-comments
|
||||
-hicpp-braces-around-statements
|
||||
-llvm-header-guard
|
||||
-llvm-include-order
|
||||
-llvm-namespace-comment
|
||||
-readability-braces-around-statements
|
||||
-readability-implicit-bool-conversion
|
||||
|
||||
-android-cloexec-accept
|
||||
-android-cloexec-creat
|
||||
-android-cloexec-dup
|
||||
-android-cloexec-epoll-create
|
||||
-android-cloexec-fopen
|
||||
-android-cloexec-open
|
||||
-boost-use-to-string
|
||||
-bugprone-branch-clone
|
||||
-bugprone-exception-escape
|
||||
-bugprone-narrowing-conversions
|
||||
-bugprone-sizeof-expression
|
||||
-cert-oop54-cpp
|
||||
-clang-analyzer-core.CallAndMessage
|
||||
-clang-analyzer-core.uninitialized.Assign
|
||||
-clang-analyzer-cplusplus.NewDeleteLeaks
|
||||
-clang-analyzer-deadcode.DeadStores
|
||||
-clang-analyzer-optin.cplusplus.UninitializedObject
|
||||
-clang-diagnostic-deprecated-copy
|
||||
-cppcoreguidelines-avoid-c-arrays
|
||||
-cppcoreguidelines-avoid-goto
|
||||
-cppcoreguidelines-avoid-magic-numbers
|
||||
-cppcoreguidelines-init-variables
|
||||
-cppcoreguidelines-interfaces-global-init
|
||||
-cppcoreguidelines-macro-usage
|
||||
-cppcoreguidelines-narrowing-conversions
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index
|
||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic
|
||||
-cppcoreguidelines-pro-type-const-cast
|
||||
-cppcoreguidelines-pro-type-cstyle-cast
|
||||
-cppcoreguidelines-pro-type-member-init
|
||||
-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
-cppcoreguidelines-pro-type-static-cast-downcast
|
||||
-cppcoreguidelines-pro-type-union-access
|
||||
-cppcoreguidelines-pro-type-vararg
|
||||
-cppcoreguidelines-special-member-functions
|
||||
-fuchsia-default-arguments-calls
|
||||
-fuchsia-default-arguments-declarations
|
||||
-fuchsia-statically-constructed-objects
|
||||
-google-default-arguments
|
||||
-google-explicit-constructor
|
||||
-google-readability-avoid-underscore-in-googletest-name
|
||||
-google-readability-redundant-smartptr-get
|
||||
-google-readability-todo
|
||||
-google-runtime-int
|
||||
-google-runtime-references
|
||||
-hicpp-avoid-c-arrays
|
||||
-hicpp-avoid-goto
|
||||
-hicpp-deprecated-headers
|
||||
-hicpp-explicit-conversions
|
||||
-hicpp-member-init
|
||||
-hicpp-multiway-paths-covered
|
||||
-hicpp-no-array-decay
|
||||
-hicpp-no-assembler
|
||||
-hicpp-no-malloc
|
||||
-hicpp-signed-bitwise
|
||||
-hicpp-special-member-functions
|
||||
-hicpp-uppercase-literal-suffix
|
||||
-hicpp-use-auto
|
||||
-hicpp-use-emplace
|
||||
-hicpp-use-equals-default
|
||||
-hicpp-use-equals-delete
|
||||
-hicpp-use-noexcept
|
||||
-hicpp-use-nullptr
|
||||
-hicpp-vararg
|
||||
-llvm-qualified-auto
|
||||
-misc-misplaced-widening-cast
|
||||
-misc-move-constructor-init
|
||||
-misc-non-private-member-variables-in-classes
|
||||
-misc-redundant-expression
|
||||
-misc-string-compare
|
||||
-misc-unused-parameters
|
||||
-modernize-avoid-bind
|
||||
-modernize-avoid-c-arrays
|
||||
-modernize-loop-convert
|
||||
-modernize-make-shared
|
||||
-modernize-make-unique
|
||||
-modernize-pass-by-value
|
||||
-modernize-raw-string-literal
|
||||
-modernize-replace-random-shuffle
|
||||
-modernize-return-braced-init-list
|
||||
-modernize-use-auto
|
||||
-modernize-use-default
|
||||
-modernize-use-default-member-init
|
||||
-modernize-use-nodiscard
|
||||
-modernize-use-emplace
|
||||
-modernize-use-equals-default
|
||||
-modernize-use-equals-delete
|
||||
-modernize-use-noexcept
|
||||
-modernize-use-nullptr
|
||||
-modernize-use-trailing-return-type
|
||||
-modernize-use-using
|
||||
-performance-faster-string-find
|
||||
-performance-inefficient-string-concatenation
|
||||
-performance-unnecessary-copy-initialization
|
||||
-performance-unnecessary-value-param
|
||||
-readability-const-return-type
|
||||
-readability-convert-member-functions-to-static
|
||||
-readability-else-after-return
|
||||
-readability-implicit-bool-cast
|
||||
-readability-isolate-declaration
|
||||
-readability-magic-numbers
|
||||
-readability-make-member-function-const
|
||||
-readability-named-parameter
|
||||
-readability-non-const-parameter
|
||||
-readability-qualified-auto
|
||||
-readability-redundant-control-flow
|
||||
-readability-redundant-smartptr-get
|
||||
-readability-redundant-string-cstr
|
||||
-readability-string-compare
|
||||
-readability-uppercase-literal-suffix
|
||||
|
||||
-cert-err58-cpp
|
||||
-cert-err60-cpp
|
||||
-cert-msc30-c
|
||||
-cert-msc50-cpp
|
||||
-clang-analyzer-alpha.cplusplus.VirtualCall
|
||||
-clang-analyzer-core.DivideZero
|
||||
-clang-analyzer-optin.cplusplus.VirtualCall
|
||||
-cppcoreguidelines-no-malloc
|
||||
-cppcoreguidelines-owning-memory
|
||||
-readability-misleading-indentation
|
||||
endef
|
||||
clang_tidy_checks := *,$(shell echo $(strip $(-clang_tidy_checks)) | tr ' ' ',')
|
||||
|
||||
# make-tidy-rule
|
||||
#
|
||||
# add a rule to invoke clang-tidy for the given source files
|
||||
# arguments:
|
||||
# #1: identifier for library/executable
|
||||
# #2: source files
|
||||
# #3: include paths and defines
|
||||
make-tidy-rule = $(eval $(call -make-tidy-rule,$(strip $1),$2,$3))
|
||||
define -specific-tidy-rule
|
||||
$1:
|
||||
@echo "[TIDY] $2"
|
||||
$V$(CLANG_TIDY) -checks='$(clang_tidy_checks)' -quiet $2 -- $$(CXXFLAGS) $3
|
||||
endef
|
||||
define -make-tidy-rule
|
||||
.PHONY: tidy
|
||||
tidy: tidy-$1
|
||||
|
||||
.PHONY: tidy-$1 $(foreach file,$2,$(file).tidy-$1)
|
||||
tidy-$1: $(foreach file,$2,$(file).tidy-$1)
|
||||
|
||||
$(foreach file,$2,$(eval $(call -specific-tidy-rule,$(file).tidy-$1,$(file),$3)))
|
||||
endef
|
||||
|
||||
define -build-pch-fragment
|
||||
ifneq ($(BEEGFS_USE_PCH),)
|
||||
# .o files depend on precompiled headers.
|
||||
$(addsuffix .o,$2): CXXFLAGS += -include $(1).autogen.h
|
||||
$(addsuffix .o,$2): $(1).autogen.h.gch
|
||||
endif
|
||||
# not behind conditional -- let's delete these always
|
||||
CLEANUP_FILES += $(1).autogen.h $(1).autogen.h.gch
|
||||
CLEANUP_FILES += $(1).autogen.h.d # "dependency" files that get produced when compiling the header
|
||||
endef
|
||||
|
||||
|
||||
# build-executable
|
||||
#
|
||||
# define a new executable for the build
|
||||
# arguments:
|
||||
# #1: name of the executable
|
||||
# #2: sources
|
||||
# #3: required libraries
|
||||
# #4: include directories
|
||||
build-executable = $(eval $(call -build-executable-fragment,$(strip $1),$2,$3,$4))
|
||||
define -build-executable-fragment
|
||||
all: $1
|
||||
|
||||
$(call -build-pch-fragment,$1,$2)
|
||||
|
||||
CLEANUP_FILES += $1 $(addsuffix .o,$2) $(addsuffix .d,$2)
|
||||
|
||||
$(addsuffix .o .tidy-%,$2): CXXFLAGS += \
|
||||
$(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4)
|
||||
|
||||
$1: LDFLAGS += \
|
||||
-Wl,--start-group $(foreach lib,$3,$(call resolve-dep-ldflags,$(lib))) -Wl,--end-group
|
||||
|
||||
$1: $(addsuffix .o,$2) $(foreach lib,$3,$(call resolve-dep-deps,$(lib)))
|
||||
@echo "[LD] $$@"
|
||||
$$V$$(CXX) -o $$@ $(addsuffix .o,$2) $$(LDFLAGS)
|
||||
|
||||
-include $(addsuffix .d,$2)
|
||||
|
||||
$(call make-tidy-rule, $1, $2,\
|
||||
$(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4))
|
||||
endef
|
||||
|
||||
# build-test
|
||||
#
|
||||
# build a test runner from specified test files. acts much like build-executable, except that it
|
||||
# includes gtest in the build as a non-library .a
|
||||
# #1: name if the test executable
|
||||
# #2: sources
|
||||
# #3: required libraries (not including gtest)
|
||||
# #4: included directories (not including gtest)
|
||||
define build-test
|
||||
$(call build-executable, $1, $2, $3, $4 -isystem $(GTEST_INC_PATH))
|
||||
|
||||
$1: LDFLAGS += $(GTEST_LIB_PATH)/libgtest.a
|
||||
endef
|
||||
|
||||
# build-static-library
|
||||
#
|
||||
# define a new (static) library for the build
|
||||
# arguments:
|
||||
# #1: name of the library
|
||||
# #2: sources
|
||||
# #3: required libraries
|
||||
# #4: include directories
|
||||
build-static-library = $(eval $(call -build-static-library-fragment,lib$(strip $1).a,$2,$3,$4))
|
||||
define -build-static-library-fragment
|
||||
all: $1
|
||||
|
||||
$(call -build-pch-fragment,$1,$2)
|
||||
|
||||
CLEANUP_FILES += $1 $(addsuffix .o,$2) $(addsuffix .d,$2)
|
||||
|
||||
$(addsuffix .o .tidy-%,$2): CXXFLAGS += \
|
||||
$(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4)
|
||||
|
||||
$(build_dir)/$1: $(addsuffix .o,$2)
|
||||
@echo "[AR] $1"
|
||||
@rm -f $$@
|
||||
$$V$(AR) -rcs $$@ $$^
|
||||
|
||||
$1: $(build_dir)/$1
|
||||
|
||||
-include $(addsuffix .d,$2)
|
||||
|
||||
$(call make-tidy-rule, $1, $2,\
|
||||
$(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4))
|
||||
endef
|
||||
|
||||
# build-shared-library
|
||||
#
|
||||
# define a new (shared) library for the build
|
||||
# arguments:
|
||||
# #1: name of the library
|
||||
# #2: sources
|
||||
# #3: required libraries
|
||||
# #4: include directories
|
||||
build-shared-library = $(eval $(call -build-shared-library-fragment,lib$(strip $1).so,$2,$3,$4))
|
||||
define -build-shared-library-fragment
|
||||
all: $1
|
||||
|
||||
$(call -build-pch-fragment,$1,$2)
|
||||
|
||||
CLEANUP_FILES += $1 $(addsuffix .o,$2) $(addsuffix .d,$2)
|
||||
|
||||
$(addsuffix .o .tidy-%,$2): CXXFLAGS += \
|
||||
-fPIC $(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4)
|
||||
|
||||
$1: LDFLAGS += \
|
||||
-Wl,--start-group $(foreach lib,$3,$(call resolve-dep-ldflags,$(lib))) -Wl,--end-group
|
||||
|
||||
$(build_dir)/$1: $(addsuffix .o,$2) $(foreach lib,$3,$(call resolve-dep-deps,$(lib)))
|
||||
@echo "[LD] $1"
|
||||
$$V$$(CXX) -shared -o $$@ $(addsuffix .o,$2) \
|
||||
-Wl,--whole-archive $$(LDFLAGS) -Wl,--no-whole-archive
|
||||
|
||||
$1: $(build_dir)/$1
|
||||
|
||||
-include $(addsuffix .d,$2)
|
||||
|
||||
$(call make-tidy-rule, $1, $2,\
|
||||
$(foreach lib,$3,$(call resolve-dep-cflags,$(lib))) $(addprefix -I, $4))
|
||||
endef
|
||||
3
build/filter-requires.sh
Executable file
3
build/filter-requires.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
$* | sed -e '/libibverbs|librdmacm/ d'
|
||||
28
build/make-deb-common
Normal file
28
build/make-deb-common
Normal file
@@ -0,0 +1,28 @@
|
||||
export TOP_PID=$$
|
||||
|
||||
function die() {
|
||||
echo "${*}" >&2
|
||||
kill $TOP_PID
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
dpkg-query -f '${Version}' -W "${1}" 2>/dev/null || die "Package ${1} is not installed."
|
||||
}
|
||||
|
||||
function isNewerVersion() {
|
||||
local v=$(getVersion "${1}")
|
||||
dpkg --compare-versions "${v}" \>= "${2}"
|
||||
}
|
||||
|
||||
function runDebuild() {
|
||||
# build the package and supress lintian warnings. Lintian in Lenny cannot
|
||||
# do that itself yet
|
||||
# NOTE: package not signed yet! (-us -uc)`
|
||||
yes | debuild -us -uc 2>&1 | egrep -v "dir-or-file-in-opt | file-in-unusual-dir"
|
||||
|
||||
if $(isNewerVersion devscripts 2.16.10); then
|
||||
yes | debuild -- clean
|
||||
else
|
||||
yes | debuild clean
|
||||
fi
|
||||
}
|
||||
11
client_devel/CMakeLists.txt
Normal file
11
client_devel/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
install(
|
||||
FILES "include/beegfs/beegfs.h" "include/beegfs/beegfs_ioctl.h" "include/beegfs/beegfs_ioctl_functions.h"
|
||||
DESTINATION "usr/include/beegfs"
|
||||
COMPONENT "client-devel"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "build/dist/usr/share/doc/beegfs-client-devel/examples/createFileWithStripePattern.cpp"
|
||||
DESTINATION "usr/share/doc/beegfs/examples/createFileWithStripePattern"
|
||||
COMPONENT "client-devel"
|
||||
)
|
||||
34
client_devel/build/Makefile
Normal file
34
client_devel/build/Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
BEEGFS_COMMON_PATH ?= ../../common/
|
||||
|
||||
ifneq ($(BEEGFS_VERSION),)
|
||||
BEEGFS_EXTRA_FLAGS += 'BEEGFS_VERSION="$(BEEGFS_VERSION)"'
|
||||
endif
|
||||
|
||||
ifneq ($(BEEGFS_DEBUG),)
|
||||
BEEGFS_EXTRA_FLAGS += 'BEEGFS_DEBUG=$(BEEGFS_DEBUG)'
|
||||
endif
|
||||
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
|
||||
help:
|
||||
@echo 'Optional Arguments:'
|
||||
@echo ' BEEGFS_DEBUG=1:'
|
||||
@echo ' Enables debug information and symbols.'
|
||||
@echo ' CXX=<compiler>:'
|
||||
@echo ' Specifies a c++ compiler.'
|
||||
@echo ' BEEGFS_COMMON_PATH=<path>:'
|
||||
@echo ' Path to the common directory.'
|
||||
@echo
|
||||
@echo 'Targets:'
|
||||
@echo ' all (default) - build only'
|
||||
@echo ' help - print this help message'
|
||||
|
||||
|
||||
# Include dependency files
|
||||
ifneq ($(DEPENDENCY_FILES),)
|
||||
include $(DEPENDENCY_FILES)
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <beegfs/beegfs.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
static const mode_t MODE_FLAG = S_IRWXU | S_IRGRP | S_IROTH;
|
||||
static const unsigned numtargets = 8;
|
||||
static const unsigned chunksize = 1048576; // 1 Mebibyte
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// check if a path to the file is provided
|
||||
if(argc != 2)
|
||||
{
|
||||
std::cout << "Usage: " << argv[0] << " $PATH_TO_FILE" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string file(argv[1]);
|
||||
std::string fileName(basename(argv[1]) );
|
||||
std::string parentDirectory(dirname(argv[1]) );
|
||||
|
||||
// check if we got a file name from the given path
|
||||
if(fileName.empty() )
|
||||
{
|
||||
std::cout << "Can not get file name from given path: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// check if we got the parent directory path from the given path
|
||||
if(parentDirectory.empty() )
|
||||
{
|
||||
std::cout << "Can not get parent directory path from given path: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// open the directory to get a directory stream
|
||||
DIR* parentDir = opendir(parentDirectory.c_str() );
|
||||
if(parentDir == NULL)
|
||||
{
|
||||
std::cout << "Can not get directory stream of directory: " << parentDirectory
|
||||
<< " errno: " << errno << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// get a fd of the parent directory
|
||||
int fd = dirfd(parentDir);
|
||||
if(fd == -1)
|
||||
{
|
||||
std::cout << "Can not get fd from directory: " << parentDirectory
|
||||
<< " errno: " << errno << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// check if the parent directory is located on a BeeGFS, because the striping API works only on
|
||||
// BeeGFS (Results of BeeGFS ioctls on other file systems are undefined.)
|
||||
bool isBeegfs = beegfs_testIsBeeGFS(fd);
|
||||
if(!isBeegfs)
|
||||
{
|
||||
std::cout << "The given file is not located on an BeeGFS: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// create the file with the given stripe pattern
|
||||
bool isFileCreated = beegfs_createFile(fd, fileName.c_str(), MODE_FLAG, numtargets, chunksize);
|
||||
if(isFileCreated)
|
||||
{
|
||||
std::cout << "File successful created: " << file << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Can not create file: " << file << " errno: " << errno << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
108
client_devel/build/dist/usr/share/doc/beegfs-client-devel/examples/getStripePatternOfFile.cpp
vendored
Normal file
108
client_devel/build/dist/usr/share/doc/beegfs-client-devel/examples/getStripePatternOfFile.cpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <beegfs/beegfs.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
static const mode_t MODE_FLAG = S_IRWXU | S_IRGRP | S_IROTH;
|
||||
static const int OPEN_FLAGS = O_RDWR;
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// check if a path to the file is provided
|
||||
if(argc != 2)
|
||||
{
|
||||
std::cout << "Usage: " << argv[0] << " $PATH_TO_FILE" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string file(argv[1]);
|
||||
|
||||
// open the provided file
|
||||
int fd = open(file.c_str(), OPEN_FLAGS, MODE_FLAG);
|
||||
if(fd == -1)
|
||||
{
|
||||
std::cout << "Open: can not open file: " << file << " errno: " << errno << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// check if the file is located on a BeeGFS, because the striping API works only on a BeeGFS
|
||||
// (Results of BeeGFS ioctls on other file systems are undefined.)
|
||||
bool isBeegfs = beegfs_testIsBeeGFS(fd);
|
||||
if(!isBeegfs)
|
||||
{
|
||||
std::cout << "The given file is not located on an BeeGFS: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
unsigned outPatternType = 0;
|
||||
unsigned outChunkSize = 0;
|
||||
uint16_t outNumTargets = 0;
|
||||
|
||||
// retrive the stripe pattern of the file and print them to the console
|
||||
bool stripeInfoRetVal = beegfs_getStripeInfo(fd, &outPatternType, &outChunkSize, &outNumTargets);
|
||||
if(stripeInfoRetVal)
|
||||
{
|
||||
std::string patternType;
|
||||
switch(outPatternType)
|
||||
{
|
||||
case BEEGFS_STRIPEPATTERN_RAID0:
|
||||
patternType = "RAID0";
|
||||
break;
|
||||
case BEEGFS_STRIPEPATTERN_RAID10:
|
||||
patternType = "RAID10";
|
||||
break;
|
||||
case BEEGFS_STRIPEPATTERN_BUDDYMIRROR:
|
||||
patternType = "BUDDYMIRROR";
|
||||
break;
|
||||
default:
|
||||
patternType = "INVALID";
|
||||
}
|
||||
std::cout << "Stripe pattern of file: " << file << std::endl;
|
||||
std::cout << "+ Type: " << patternType << std::endl;
|
||||
std::cout << "+ Chunksize: " << outChunkSize << " Byte" << std::endl;
|
||||
std::cout << "+ Number of storage targets: " << outNumTargets << std::endl;
|
||||
std::cout << "+ Storage targets:" << std::endl;
|
||||
|
||||
// get the targets which are used for the file and print them to the console
|
||||
for (int targetIndex = 0; targetIndex < outNumTargets; targetIndex++)
|
||||
{
|
||||
struct BeegfsIoctl_GetStripeTargetV2_Arg outTargetInfo;
|
||||
|
||||
bool stripeTargetRetVal = beegfs_getStripeTargetV2(fd, targetIndex, &outTargetInfo);
|
||||
if(stripeTargetRetVal)
|
||||
{
|
||||
if(outPatternType == BEEGFS_STRIPEPATTERN_BUDDYMIRROR)
|
||||
{
|
||||
std::cout << " + " << outTargetInfo.targetOrGroup
|
||||
<< " @ " << outTargetInfo.primaryTarget
|
||||
<< " @ " << outTargetInfo.primaryNodeAlias
|
||||
<< " [ID: "<< outTargetInfo.primaryNodeID << "]" << std::endl;
|
||||
std::cout << " + " << outTargetInfo.targetOrGroup
|
||||
<< " @ " << outTargetInfo.secondaryTarget
|
||||
<< " @ " << outTargetInfo.secondaryNodeAlias
|
||||
<< " [ID: "<< outTargetInfo.secondaryNodeID << "]" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " + " << outTargetInfo.targetOrGroup
|
||||
<< " @ " << outTargetInfo.primaryNodeAlias
|
||||
<< " [ID: "<< outTargetInfo.primaryNodeID << "]" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Can not get stripe targets of file: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Can not get stripe info of file: " << file << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
6
client_devel/include/beegfs/beegfs.h
Normal file
6
client_devel/include/beegfs/beegfs.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __BEEGFS_H__
|
||||
#define __BEEGFS_H__
|
||||
|
||||
#include <beegfs/beegfs_ioctl.h>
|
||||
|
||||
#endif /* __BEEGFS_H__ */
|
||||
11
client_devel/include/beegfs/beegfs_ioctl.h
Normal file
11
client_devel/include/beegfs/beegfs_ioctl.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __BEEGFS_IOCTL_H__
|
||||
#define __BEEGFS_IOCTL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <uapi/beegfs_client.h>
|
||||
#include <beegfs/beegfs_ioctl_functions.h>
|
||||
|
||||
|
||||
#endif /* __BEEGFS_IOCTL_H__ */
|
||||
335
client_devel/include/beegfs/beegfs_ioctl_functions.h
Normal file
335
client_devel/include/beegfs/beegfs_ioctl_functions.h
Normal file
@@ -0,0 +1,335 @@
|
||||
#ifndef __BEEGFS_IOCTL_FUNCTIONS_H__
|
||||
#define __BEEGFS_IOCTL_FUNCTIONS_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#define BEEGFS_API_MAJOR_VERSION 1 // major version number of the API, different major version
|
||||
// are incompatible
|
||||
#define BEEGFS_API_MINOR_VERSION 1 // minor version number of the API, the minor versions of the
|
||||
// same major version are backward compatible
|
||||
|
||||
#define beegfs_api_version_check() { return beegfs_checkApiVersion(); } // backward compatibility
|
||||
|
||||
static inline bool beegfs_getConfigFile(int fd, char** outCfgFile);
|
||||
static inline bool beegfs_getRuntimeConfigFile(int fd, char** outCfgFile);
|
||||
static inline bool beegfs_testIsBeeGFS(int fd);
|
||||
static inline bool beegfs_getMountID(int fd, char** outMountID);
|
||||
static inline bool beegfs_getStripeInfo(int fd, unsigned* outPatternType, unsigned* outChunkSize,
|
||||
uint16_t* outNumTargets);
|
||||
static inline bool beegfs_getStripeTarget(int fd, uint16_t targetIndex, uint16_t* outTargetNumID,
|
||||
uint16_t* outNodeNumID, char** outNodeStrID);
|
||||
static inline bool beegfs_getStripeTargetV2(int fd, uint32_t targetIndex,
|
||||
struct BeegfsIoctl_GetStripeTargetV2_Arg* outTargetInfo);
|
||||
static inline bool beegfs_createFile(int fd, const char* filename, mode_t mode,
|
||||
unsigned numtargets, unsigned chunksize);
|
||||
static inline bool beegfs_getInodeID(int fd, const char* entryID, uint64_t* outInodeID);
|
||||
static inline bool beegfs_getEntryInfo(int fd, uint32_t* ownerID, char* parentEntryID,
|
||||
char* entryID, int* entryType, int* featureFlags);
|
||||
static inline bool beegfs_checkApiVersion(const unsigned required_major_version,
|
||||
const unsigned required_minor_version);
|
||||
static inline bool beegfs_pingNode(int fd, struct BeegfsIoctl_PingNode_Arg* ping);
|
||||
|
||||
|
||||
/**
|
||||
* Get the path to the client config file of an active BeeGFS mountpoint.
|
||||
*
|
||||
* @param fd filedescriptor pointing to file or dir inside BeeGFS mountpoint.
|
||||
* @param outCfgFile buffer for config file path; will be malloc'ed and needs to be free'd by
|
||||
* caller if success was returned.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getConfigFile(int fd, char** outCfgFile)
|
||||
{
|
||||
struct BeegfsIoctl_GetCfgFile_Arg getCfgFile;
|
||||
getCfgFile.length = BEEGFS_IOCTL_CFG_MAX_PATH;
|
||||
|
||||
int res = ioctl(fd, BEEGFS_IOC_GET_CFG_FILE, &getCfgFile);
|
||||
if(res)
|
||||
return false;
|
||||
|
||||
*outCfgFile = strndup(getCfgFile.path, BEEGFS_IOCTL_CFG_MAX_PATH);
|
||||
if(!*outCfgFile)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the client runtime config file in procfs.
|
||||
*
|
||||
* @param fd filedescriptor pointing to file or dir inside BeeGFS mountpoint.
|
||||
* @param outCfgFile buffer for config file path; will be malloc'ed and needs to be free'd by
|
||||
* caller if success was returned.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getRuntimeConfigFile(int fd, char** outCfgFile)
|
||||
{
|
||||
struct BeegfsIoctl_GetCfgFile_Arg getCfgFile;
|
||||
getCfgFile.length = BEEGFS_IOCTL_CFG_MAX_PATH;
|
||||
|
||||
int res = ioctl(fd, BEEGFS_IOC_GET_RUNTIME_CFG_FILE, &getCfgFile);
|
||||
if(res)
|
||||
return false;
|
||||
|
||||
*outCfgFile = strndup(getCfgFile.path, BEEGFS_IOCTL_CFG_MAX_PATH);
|
||||
if(!*outCfgFile)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the underlying file system is a BeeGFS.
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file or dir that should be checked for whether it is
|
||||
* located inside a BeeGFS mount.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_testIsBeeGFS(int fd)
|
||||
{
|
||||
char testArray[sizeof(BEEGFS_IOCTL_TEST_STRING)];
|
||||
|
||||
#ifdef BEEGFS_DEBUG
|
||||
// just calm valgrind; it does not detect that the array is initialized by the ioctl
|
||||
memset(testArray, 0, sizeof(BEEGFS_IOCTL_TEST_STRING) );
|
||||
#endif
|
||||
|
||||
int ioctlRes = ioctl(fd, BEEGFS_IOC_TEST_IS_BEEGFS, testArray);
|
||||
if(ioctlRes)
|
||||
return false;
|
||||
|
||||
int memCmpRes = memcmp(testArray, BEEGFS_IOCTL_TEST_STRING, sizeof(BEEGFS_IOCTL_TEST_STRING) );
|
||||
if(memCmpRes)
|
||||
{ // ioctl was accepted by underlying fs, but buffer wasn't filled correctly
|
||||
errno = EPROTO;
|
||||
return false; // verification through buffer failed, probably just not a beegfs
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mountID aka clientID aka nodeID of client mount aka sessionID.
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file or dir that should be checked for whether it is
|
||||
* located inside a BeeGFS mount.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getMountID(int fd, char** outMountID)
|
||||
{
|
||||
char mountIDBuf[BEEGFS_IOCTL_MOUNTID_BUFLEN];
|
||||
|
||||
#ifdef BEEGFS_DEBUG
|
||||
// just calm valgrind; it does not detect that the array is initialized by the ioctl
|
||||
memset(mountIDBuf, 0, sizeof(mountIDBuf) );
|
||||
#endif
|
||||
|
||||
int ioctlRes = ioctl(fd, BEEGFS_IOC_GET_MOUNTID, mountIDBuf);
|
||||
if(ioctlRes)
|
||||
return false;
|
||||
|
||||
*outMountID = strndup(mountIDBuf, sizeof(mountIDBuf) );
|
||||
if(!*outMountID)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stripe info of a file.
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file inside a BeeGFS mount.
|
||||
* @param outPatternType type of stripe pattern (BEEGFS_STRIPEPATTERN_...)
|
||||
* @param outChunkSize chunk size for striping.
|
||||
* @param outNumTargets number of targets for striping.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getStripeInfo(int fd, unsigned* outPatternType, unsigned* outChunkSize,
|
||||
uint16_t* outNumTargets)
|
||||
{
|
||||
struct BeegfsIoctl_GetStripeInfo_Arg getStripeInfo;
|
||||
|
||||
int res = ioctl(fd, BEEGFS_IOC_GET_STRIPEINFO, &getStripeInfo);
|
||||
if(res)
|
||||
return false;
|
||||
|
||||
*outPatternType = getStripeInfo.outPatternType;
|
||||
*outChunkSize = getStripeInfo.outChunkSize;
|
||||
*outNumTargets = getStripeInfo.outNumTargets;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stripe target of a file (with 0-based index).
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file inside a BeeGFS mount.
|
||||
* @param targetIndex index of target that should be retrieved (start with 0 and then call this
|
||||
* again with index up to "*outNumTargets-1" to retrieve remaining targets).
|
||||
* @param outTargetNumID numeric ID of target at given index.
|
||||
* @param outNodeNumID numeric ID to node to which this target is assigned.
|
||||
* @param outNodeAlias alias (formerly string ID) of the node to which this target is assigned;
|
||||
* buffer will be alloc'ed and needs to be free'd by caller if success is returned.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getStripeTarget(int fd, uint16_t targetIndex, uint16_t* outTargetNumID,
|
||||
uint16_t* outNodeNumID, char** outNodeAlias)
|
||||
{
|
||||
struct BeegfsIoctl_GetStripeTarget_Arg getStripeTarget;
|
||||
|
||||
getStripeTarget.targetIndex = targetIndex;
|
||||
|
||||
int res = ioctl(fd, BEEGFS_IOC_GET_STRIPETARGET, &getStripeTarget);
|
||||
if(res)
|
||||
return false;
|
||||
|
||||
*outTargetNumID = getStripeTarget.outTargetNumID;
|
||||
*outNodeNumID = getStripeTarget.outNodeNumID;
|
||||
|
||||
*outNodeAlias = strndup(getStripeTarget.outNodeAlias, BEEGFS_IOCTL_CFG_MAX_PATH);
|
||||
if(!*outNodeAlias)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stripe target of a file (with 0-based index).
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file inside a BeeGFS mount.
|
||||
* @param targetIndex index of target that should be retrieved (start with 0 and then call this
|
||||
* again with index up to "*outNumTargets-1" to retrieve remaining targets).
|
||||
* @param outTargetInfo pointer to struct that will be filled with information about the selected
|
||||
* stripe target
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_getStripeTargetV2(int fd, uint32_t targetIndex,
|
||||
struct BeegfsIoctl_GetStripeTargetV2_Arg* outTargetInfo)
|
||||
{
|
||||
memset(outTargetInfo, 0, sizeof(*outTargetInfo));
|
||||
|
||||
outTargetInfo->targetIndex = targetIndex;
|
||||
|
||||
return ioctl(fd, BEEGFS_IOC_GET_STRIPETARGET_V2, outTargetInfo) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new regular file with stripe hints.
|
||||
*
|
||||
* As the stripe pattern cannot be changed when a file is already created, this is an exclusive
|
||||
* create, so it will return an error if the file already existed.
|
||||
*
|
||||
* @param fd filedescriptor pointing to parent directory for the new file.
|
||||
* @param filename name of created file.
|
||||
* @param mode permission bits of new file (i.e. symbolic constants like S_IRWXU or 0644).
|
||||
* @param numtargets desired number of storage targets for striping; 0 for directory default; ~0 to
|
||||
* use all available targets.
|
||||
* @param chunksize chunksize per storage target for striping in bytes; 0 for directory default;
|
||||
* must be 2^n >= 64KiB.
|
||||
* @return true on success, false on error (in which case errno will be set).
|
||||
*/
|
||||
bool beegfs_createFile(int fd, const char* filename, mode_t mode, unsigned numtargets,
|
||||
unsigned chunksize)
|
||||
{
|
||||
struct BeegfsIoctl_MkFileWithStripeHints_Arg createFileArg;
|
||||
|
||||
createFileArg.filename = filename;
|
||||
createFileArg.mode = mode;
|
||||
|
||||
createFileArg.numtargets = numtargets;
|
||||
createFileArg.chunksize = chunksize;
|
||||
|
||||
int res = ioctl(fd, BEEGFS_IOC_MKFILE_STRIPEHINTS, &createFileArg);
|
||||
if(res)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool beegfs_getInodeID(int fd, const char* entryID, uint64_t* outInodeID)
|
||||
{
|
||||
struct BeegfsIoctl_GetInodeID_Arg getInodeIDArg;
|
||||
|
||||
getInodeIDArg.entryID[BEEGFS_IOCTL_ENTRYID_MAXLEN] = '\0';
|
||||
strncpy(getInodeIDArg.entryID, entryID, BEEGFS_IOCTL_ENTRYID_MAXLEN);
|
||||
|
||||
if(ioctl(fd, BEEGFS_IOC_GETINODEID, &getInodeIDArg))
|
||||
{
|
||||
*outInodeID = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*outInodeID = getInodeIDArg.inodeID;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entryInfo data for given file.
|
||||
*
|
||||
* @param fd filedescriptor pointing to some file inside a BeeGFS mount.
|
||||
* @param ownerID pointer to an uint32_t in which the ownerID shall be stored
|
||||
* @param parentEntryID pointer to a buffer for the parent entryID. The buffer must
|
||||
* be at least BEEGFS_IOCTL_ENTRYID_MAXLEN + 1 bytes long.
|
||||
* @param entryID pointer to a buffer for the entryID. The buffer must
|
||||
* be at least BEEGFS_IOCTL_ENTRYID_MAXLEN + 1 bytes long.
|
||||
* @param entryType pointer to an int in which the entryType shall be stored
|
||||
* @param featureFlags pointer to an int in which the feature flags shall be stored
|
||||
* @return success/failure
|
||||
*/
|
||||
bool beegfs_getEntryInfo(int fd, uint32_t* ownerID, char* parentEntryID,
|
||||
char* entryID, int* entryType, int* featureFlags)
|
||||
{
|
||||
struct BeegfsIoctl_GetEntryInfo_Arg arg;
|
||||
|
||||
if(ioctl(fd, BEEGFS_IOC_GETENTRYINFO, &arg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*ownerID = arg.ownerID;
|
||||
strncpy(parentEntryID, arg.parentEntryID, BEEGFS_IOCTL_ENTRYID_MAXLEN + 1);
|
||||
strncpy(entryID, arg.entryID, BEEGFS_IOCTL_ENTRYID_MAXLEN + 1);
|
||||
*entryType = arg.entryType;
|
||||
*featureFlags = arg.featureFlags;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the required API version of the application is compatible to current API version
|
||||
*
|
||||
* @param required_major_version the required major API version of the user application
|
||||
* @param required_minor_version the minimal required minor API version of the user application
|
||||
* @return true if the required version and the API version are compatible, if not false is returned
|
||||
*/
|
||||
bool beegfs_checkApiVersion(const unsigned required_major_version,
|
||||
const unsigned required_minor_version)
|
||||
{
|
||||
if(required_major_version != BEEGFS_API_MAJOR_VERSION)
|
||||
return false;
|
||||
|
||||
if(required_minor_version > BEEGFS_API_MINOR_VERSION)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool beegfs_pingNode(int fd, struct BeegfsIoctl_PingNode_Arg* inoutPing)
|
||||
{
|
||||
if(ioctl(fd, BEEGFS_IOC_PINGNODE, inoutPing))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __BEEGFS_IOCTL_FUNCTIONS_H__ */
|
||||
102
client_module/CMakeLists.txt
Normal file
102
client_module/CMakeLists.txt
Normal file
@@ -0,0 +1,102 @@
|
||||
if(NOT BEEGFS_SKIP_CLIENT)
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(
|
||||
client-module
|
||||
BUILD_IN_SOURCE ON
|
||||
URL "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND make -C build -j $(nproc) "KDIR=${BEEGFS_KERNELDIR}" "OFED_INCLUDE_PATH=${BEEGFS_OFEDDIR}"
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build/dkms.conf.client"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.client"
|
||||
)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build/dkms.conf.compat"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.compat"
|
||||
)
|
||||
|
||||
configure_file(
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build/postinst.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/postinst"
|
||||
)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build/prerm.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/prerm"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY ""
|
||||
DESTINATION "usr/src/beegfs-${BEEGFS_VERSION}"
|
||||
COMPONENT "client"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
PATTERN "CMakeLists.txt" EXCLUDE
|
||||
PATTERN "dkms.conf.*" EXCLUDE
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.client"
|
||||
DESTINATION "usr/src/beegfs-${BEEGFS_VERSION}"
|
||||
RENAME "dkms.conf"
|
||||
COMPONENT "client"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "build/dist/etc/beegfs-client.conf"
|
||||
DESTINATION "etc/beegfs"
|
||||
COMPONENT "client"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY ""
|
||||
DESTINATION "usr/src/beegfs-compat-${BEEGFS_VERSION}"
|
||||
COMPONENT "client-compat"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
PATTERN "CMakeLists.txt" EXCLUDE
|
||||
PATTERN "dkms.conf.*" EXCLUDE
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.compat"
|
||||
DESTINATION "usr/src/beegfs-compat-${BEEGFS_VERSION}"
|
||||
RENAME "dkms.conf"
|
||||
COMPONENT "client-compat"
|
||||
)
|
||||
|
||||
# Debian package settings
|
||||
set(CPACK_DEBIAN_CLIENT_PACKAGE_DEPENDS "dkms" PARENT_SCOPE)
|
||||
|
||||
set(
|
||||
CPACK_DEBIAN_CLIENT_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/prerm;${CMAKE_CURRENT_BINARY_DIR}/postinst;${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.client"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
# currently no dkms in compat package
|
||||
# set(
|
||||
# CPACK_DEBIAN_CLIENT-COMPAT_PACKAGE_CONTROL_EXTRA
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/dkms.conf.compat"
|
||||
# PARENT_SCOPE
|
||||
# )
|
||||
|
||||
# RPM package settings
|
||||
set(CPACK_RPM_CLIENT_PACKAGE_REQUIRES "dkms" PARENT_SCOPE)
|
||||
|
||||
set(
|
||||
CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/prerm"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
set(
|
||||
CPACK_RPM_POST_INSTALL_SCRIPT_FILE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/postinst"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
52
client_module/build/AutoRebuild.mk
Normal file
52
client_module/build/AutoRebuild.mk
Normal file
@@ -0,0 +1,52 @@
|
||||
# Automatic rebuild of BeeGFS client modules on kernel change.
|
||||
|
||||
|
||||
AUTO_REBUILD_KVER_FILE := auto_rebuild_kernel.ver
|
||||
AUTO_REBUILD_KVER_CURRENT = $(shell uname -srvmpi)
|
||||
|
||||
AUTO_REBUILD_LOG_PREFIX := "BeeGFS Client Auto-Rebuild:"
|
||||
|
||||
# config file (keys)
|
||||
AUTO_REBUILD_CONF_FILE := /etc/beegfs/beegfs-client-autobuild.conf
|
||||
AUTO_REBUILD_CONF_ENABLED_KEY := buildEnabled
|
||||
AUTO_REBUILD_CONF_BUILDARGS_KEY := buildArgs
|
||||
|
||||
# config file (values)
|
||||
AUTO_REBUILD_CONF_ENABLED = $(shell \
|
||||
grep -s "^\s*$(AUTO_REBUILD_CONF_ENABLED_KEY)\s*=" "$(AUTO_REBUILD_CONF_FILE)" | \
|
||||
cut --delimiter="=" --fields="2-" )
|
||||
AUTO_REBUILD_CONF_BUILDARGS = $(shell \
|
||||
grep "^\s*$(AUTO_REBUILD_CONF_BUILDARGS_KEY)\s*=" "$(AUTO_REBUILD_CONF_FILE)" | \
|
||||
cut --delimiter="=" --fields="2-" )
|
||||
|
||||
# add build dependency if rebuild has been enabled in config file
|
||||
ifeq ($(AUTO_REBUILD_CONF_ENABLED), true)
|
||||
AUTO_REBUILD_CONFIGURED_DEPS := auto_rebuild_install
|
||||
endif
|
||||
|
||||
# environment variables (intentionally commented out here; just to mention
|
||||
# them somewhere)
|
||||
# - AUTO_REBUILD_KVER_STORED: internally for target auto_rebuild
|
||||
|
||||
|
||||
auto_rebuild:
|
||||
$(MAKE) auto_rebuild_clean $(AUTO_REBUILD_CONF_BUILDARGS)
|
||||
$(MAKE) $(AUTO_REBUILD_CONF_BUILDARGS)
|
||||
|
||||
# checked rebuild and install
|
||||
auto_rebuild_install: auto_rebuild
|
||||
$(MAKE) install $(AUTO_REBUILD_CONF_BUILDARGS)
|
||||
|
||||
|
||||
# run checked rebuild and install if enabled in config file
|
||||
auto_rebuild_configured: $(AUTO_REBUILD_CONFIGURED_DEPS)
|
||||
@ /bin/true
|
||||
|
||||
|
||||
auto_rebuild_clean: clean
|
||||
@ /bin/true
|
||||
|
||||
|
||||
auto_rebuild_help:
|
||||
@echo 'No Auto-Rebuild Arguments defined.'
|
||||
|
||||
334
client_module/build/KernelFeatureDetection.mk
Normal file
334
client_module/build/KernelFeatureDetection.mk
Normal file
@@ -0,0 +1,334 @@
|
||||
# All detected features are included in "KERNEL_FEATURE_DETECTION"
|
||||
|
||||
# parameters:
|
||||
# $1: name to define when grep finds something
|
||||
# $2: grep flags and expression
|
||||
# $3: input files in linux source tree
|
||||
define define_if_matches
|
||||
$(eval \
|
||||
KERNEL_FEATURE_DETECTION += $$(shell \
|
||||
grep -q -s $2 $(addprefix ${KSRCDIR_PRUNED_HEAD}/include/linux/,$3) \
|
||||
&& echo "-D$(strip $1)"))
|
||||
endef
|
||||
|
||||
ifneq ($(OFED_INCLUDE_PATH),)
|
||||
OFED_DETECTION_PATH := $(OFED_INCLUDE_PATH)
|
||||
else
|
||||
OFED_DETECTION_PATH := ${KSRCDIR_PRUNED_HEAD}/include
|
||||
endif
|
||||
|
||||
|
||||
# Find out whether rdma_create_id function has qp_type argument.
|
||||
# This is tricky because the function declaration spans multiple lines.
|
||||
# Note: Was introduced in vanilla 3.0
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sA2 "struct rdma_cm_id \*rdma_create_id(" ${OFED_DETECTION_PATH}/rdma/rdma_cm.h 2>&1 \
|
||||
| grep -qs "ib_qp_type qp_type);" \
|
||||
&& echo "-DOFED_HAS_RDMA_CREATE_QPTYPE")
|
||||
|
||||
# Find out whether rdma_set_service_type function has been declared.
|
||||
# Note: Was introduced in vanilla 2.6.24
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs "rdma_set_service_type(struct rdma_cm_id \*id, int tos)" \
|
||||
${OFED_DETECTION_PATH}/rdma/rdma_cm.h \
|
||||
&& echo "-DOFED_HAS_SET_SERVICE_TYPE")
|
||||
|
||||
# Find out whether ib_create_cq function has cq_attr argument
|
||||
# This is tricky because the function declaration spans multiple lines.
|
||||
# Note: Was introduced in vanilla 4.2
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sA4 "struct ib_cq \*ib_create_cq(struct ib_device \*device," ${OFED_DETECTION_PATH}/rdma/ib_verbs.h 2>&1 \
|
||||
| grep -qs "const struct ib_cq_init_attr \*cq_attr);" \
|
||||
&& echo "-DOFED_HAS_IB_CREATE_CQATTR")
|
||||
|
||||
# Find out whether rdma_reject function has reason argument
|
||||
# This is tricky because the function declaration spans multiple lines.
|
||||
# Note: Was introduced in MLNX OFED 5.1
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sA1 "int rdma_reject(" ${OFED_DETECTION_PATH}/rdma/rdma_cm.h 2>&1 \
|
||||
| grep -qs "u8 reason);" \
|
||||
&& echo "-DOFED_RDMA_REJECT_NEEDS_REASON")
|
||||
|
||||
# kernels >=v4.4 expect a netns argument for rdma_create_id
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs "struct rdma_cm_id \*rdma_create_id.struct net \*net," \
|
||||
${OFED_DETECTION_PATH}/rdma/rdma_cm.h \
|
||||
&& echo "-DOFED_HAS_NETNS")
|
||||
|
||||
# kernels >=v4.4 split up ib_send_wr into a lot of other structs
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs -F "struct ib_atomic_wr {" \
|
||||
${OFED_DETECTION_PATH}/rdma/ib_verbs.h \
|
||||
&& echo "-DOFED_SPLIT_WR")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs -F "IB_PD_UNSAFE_GLOBAL_RKEY" \
|
||||
${OFED_DETECTION_PATH}/rdma/ib_verbs.h \
|
||||
&& echo "-DOFED_UNSAFE_GLOBAL_RKEY")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs -F "ib_get_dma_mr" \
|
||||
${OFED_DETECTION_PATH}/rdma/ib_verbs.h \
|
||||
&& echo "-DOFED_IB_GET_DMA_MR")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qs -F "static inline void ib_destroy_cq" \
|
||||
${OFED_DETECTION_PATH}/rdma/ib_verbs.h \
|
||||
&& echo "-DOFED_IB_DESTROY_CQ_IS_VOID")
|
||||
|
||||
# Find out whether the kernel has a scsi/fc_compat.h file, which defines
|
||||
# vlan_dev_vlan_id.
|
||||
# Note: We need this, because some kernels (e.g. RHEL 5.9's 2.6.18) forgot this
|
||||
# include in their rdma headers, leading to implicit function declarations.
|
||||
$(call define_if_matches, KERNEL_HAS_SCSI_FC_COMPAT, "vlan_dev_vlan_id", scsi/fc_compat.h)
|
||||
|
||||
# Find out whether the kernel has a ihold function.
|
||||
# Note: Was added in vanilla 2.6.37, but RedHat adds it to their 2.6.32.
|
||||
$(call define_if_matches, KERNEL_HAS_IHOLD, ' ihold(struct inode.*)', fs.h)
|
||||
|
||||
# Find out whether the kernel has fsync start and end range arguments.
|
||||
# Note: fsync start and end were added in vanilla 3.1, but SLES11SP3 adds it to its 3.0 kernel.
|
||||
$(call define_if_matches, KERNEL_HAS_FSYNC_RANGE, \
|
||||
-F "int (*fsync) (struct file *, loff_t, loff_t, int datasync);", fs.h)
|
||||
|
||||
# Find out whether the kernel has define struct dentry_operations *s_d_op
|
||||
# in struct super_block. If it has it used that to check if the file system
|
||||
# needs to revalidate dentries.
|
||||
$(call define_if_matches, KERNEL_HAS_S_D_OP, -F "struct dentry_operations *s_d_op;", fs.h)
|
||||
|
||||
# Find out whether the kernel has d_materialise_unique() to
|
||||
# add dir dentries.
|
||||
#
|
||||
# Note: d_materialise_unique was added in vanilla 2.6.19 (backported to rhel5
|
||||
# 2.6.18) and got merged into d_splice_alias in vanilla 3.19.
|
||||
$(call define_if_matches, KERNEL_HAS_D_MATERIALISE_UNIQUE, \
|
||||
-F "d_materialise_unique(struct dentry *, struct inode *)", dcache.h)
|
||||
|
||||
# Find out whether the kernel has a PDE_DATA method.
|
||||
#
|
||||
# Note: This method was added in vanilla linux-3.10
|
||||
$(call define_if_matches, KERNEL_HAS_PDE_DATA, -F "PDE_DATA(const struct inode *)", proc_fs.h)
|
||||
|
||||
# Find out whether the kernel has i_uid_read
|
||||
#
|
||||
# Note: added to 3.5
|
||||
$(call define_if_matches, KERNEL_HAS_I_UID_READ, "i_uid_read", fs.h)
|
||||
|
||||
# Find out whether the kernel has atomic_open
|
||||
#
|
||||
# Note: added to 3.5
|
||||
$(call define_if_matches, KERNEL_HAS_ATOMIC_OPEN, "atomic_open", fs.h)
|
||||
|
||||
# Find out whether the kernel used umode_t
|
||||
#
|
||||
# Note: added to 3.3
|
||||
$(call define_if_matches, KERNEL_HAS_UMODE_T, -E "(\*mkdir).*umode_t", fs.h)
|
||||
|
||||
# Find out if the kernel has a file_inode() method.
|
||||
$(call define_if_matches, KERNEL_HAS_FILE_INODE, " file_inode(.*)", fs.h)
|
||||
|
||||
# Find out whether the kernel has a strnicmp function.
|
||||
#
|
||||
# Note: strnicmp was switched to strncasecmp in linux-4.0. strncasecmp existed
|
||||
# before, but was wrong, so we only use strncasecmp if strnicmp doesn't exist.
|
||||
$(call define_if_matches, KERNEL_HAS_STRNICMP, "strnicmp", string.h)
|
||||
|
||||
# Find out whether the kernel has BDI_CAP_MAP_COPY defined.
|
||||
$(call define_if_matches, KERNEL_HAS_BDI_CAP_MAP_COPY, "define BDI_CAP_MAP_COPY", backing-dev.h)
|
||||
|
||||
# Find out whether xattr_handler** s_xattr in super_block is const.
|
||||
$(call define_if_matches, KERNEL_HAS_CONST_XATTR_CONST_PTR_HANDLER, \
|
||||
-F "const struct xattr_handler * const *s_xattr;", fs.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_CONST_XATTR_HANDLER, \
|
||||
-F "const struct xattr_handler **s_xattr;", fs.h)
|
||||
|
||||
# Find out whether xattr_handler functions need a dentry* (otherwise they need an inode*).
|
||||
# Note: grepping for "(*set).struct..." instead of "(*set)(struct..." because make complains about
|
||||
# the missing ")" otherwise.
|
||||
$(call define_if_matches, KERNEL_HAS_DENTRY_XATTR_HANDLER, \
|
||||
"int (\*set).struct dentry \*dentry", xattr.h)
|
||||
|
||||
# address_space.assoc_mapping went away in vanilla 3.8, but SLES11 backports that change
|
||||
$(call define_if_matches, KERNEL_HAS_ADDRSPACE_ASSOC_MAPPING, -F "assoc_mapping", fs.h)
|
||||
|
||||
# current_umask() was added in 2.6.30
|
||||
$(call define_if_matches, KERNEL_HAS_CURRENT_UMASK, -F "current_umask", fs.h)
|
||||
|
||||
# super_operations.show_options was changed to struct dentry* in 3.3
|
||||
$(call define_if_matches, KERNEL_HAS_SHOW_OPTIONS_DENTRY, -F "int (*show_options)(struct seq_file *, struct dentry *);", fs.h)
|
||||
|
||||
# xattr handlers >=v4.4 also receive pointer to struct xattr_handler
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -s -F "int (*get)" ${KSRCDIR_PRUNED_HEAD}/include/linux/xattr.h \
|
||||
| grep -q -s -F "const struct xattr_handler *" \
|
||||
&& echo "-DKERNEL_HAS_XATTR_HANDLER_PTR_ARG -DKERNEL_HAS_DENTRY_XATTR_HANDLER")
|
||||
|
||||
# 4.5 introduces name in xattr_handler, which can be used instead of prefix
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA1 "struct xattr_handler {" ${KSRCDIR_PRUNED_HEAD}/include/linux/xattr.h \
|
||||
| grep -qsF "const char *name;" \
|
||||
&& echo "-DKERNEL_HAS_XATTR_HANDLER_NAME")
|
||||
|
||||
# locks_lock_inode_wait is used for flock since 4.4 (before flock_lock_file_wait was used)
|
||||
# since 6.3 locks_lock_inode_wait moved from file fs.h to filelock.h
|
||||
$(call define_if_matches, KERNEL_HAS_LOCKS_FILELOCK_INODE_WAIT, -F "static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)", filelock.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_LOCKS_LOCK_INODE_WAIT, -F "static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)", fs.h)
|
||||
|
||||
# get_link() replaces follow_link() in 4.5
|
||||
$(call define_if_matches, KERNEL_HAS_GET_LINK, -F "const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *);", fs.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_LOCK, -F "i_mmap_lock_read", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_RWSEM, -F "i_mmap_rwsem", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_MUTEX, -F "i_mmap_mutex", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_RBTREE, -P "struct rb_root\s+i_mmap", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_CACHED_RBTREE, -P "struct rb_root_cached\s+i_mmap", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_I_MMAP_NONLINEAR, -F "i_mmap_nonlinear", fs.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_INODE_LOCK, "static inline void inode_lock", fs.h)
|
||||
|
||||
#<linuy-4.8
|
||||
$(call define_if_matches, KERNEL_HAS_PAGE_ENDIO, \
|
||||
-F "void page_endio(struct page *page, int rw, int err);", pagemap.h)
|
||||
#>=linux-4.8
|
||||
$(call define_if_matches, KERNEL_HAS_PAGE_ENDIO, \
|
||||
-F "void page_endio(struct page *page, bool is_write, int err);", pagemap.h)
|
||||
|
||||
# kernels <= 2.7.27 use remove_suid, others use file_remove_suid.
|
||||
# except linux-3.10.0-514.el7, which uses file_remove_privs.
|
||||
$(call define_if_matches, KERNEL_HAS_FILE_REMOVE_SUID, \
|
||||
-F "int file_remove_suid(struct file *);", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FILE_REMOVE_PRIVS, \
|
||||
-F "int file_remove_privs(struct file *);", fs.h)
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA1 "sock_recvmsg" ${KSRCDIR_PRUNED_HEAD}/include/linux/net.h \
|
||||
| grep -qsF "size_t size" \
|
||||
&& echo "-DKERNEL_HAS_RECVMSG_SIZE")
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_MEMDUP_USER, "memdup_user", string.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FAULTATTR_DNAME, -F "struct dentry *dname", fault-inject.h)
|
||||
$(call define_if_matches, KERNEL_HAS_SYSTEM_UTSNAME, "system_utsname", utsname.h)
|
||||
$(call define_if_matches, KERNEL_HAS_SOCK_CREATE_KERN_NS, "sock_create_kern.struct net", net.h)
|
||||
$(call define_if_matches, KERNEL_HAS_SOCK_SENDMSG_NOLEN, "sock_sendmsg.*msg.;", net.h)
|
||||
$(call define_if_matches, KERNEL_HAS_IOV_ITER_INIT_DIR, "iov_iter_init.*direction", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_KVEC, "ITER_KVEC", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_IOV_ITER_TYPE, "iov_iter_type", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_BVEC, "ITER_BVEC", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_PIPE, "ITER_PIPE", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_IOV_ITER_IS_PIPE, "iov_iter_is_pipe", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_IS_IOVEC, "iter_is_iovec", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_IOV_ITER_IOVEC, "iov_iter_iovec", uio.h)
|
||||
# iov_iter_iovec removed from 6.4 kernel and used iter_iov_addr & iter_iov_len macro's
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_IOV_ADDR, "iter_iov_addr", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_GET_SB_NODEV, "get_sb_nodev", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_GENERIC_FILE_LLSEEK_UNLOCKED, "generic_file_llseek_unlocked", \
|
||||
fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_SET_NLINK, "set_nlink", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_DENTRY_PATH_RAW, "dentry_path_raw", dcache.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FSYNC_DENTRY, -P "(\*fsync).*dentry", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_FILE_SPLICE_WRITE, "iter_file_splice_write", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITER_GENERIC_FILE_SENDFILE, "generic_file_sendfile", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ITERATE_DIR, "iterate_dir", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ENCODE_FH_INODE, -P "\(\*encode_fh\).struct inode", exportfs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_D_DELETE_CONST_ARG, \
|
||||
-F "int (*d_delete)(const struct dentry *);", dcache.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FILE_F_VFSMNT, -P "struct vfsmount\s*\*f_vfsmnt", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_POSIX_ACL_XATTR_USERNS_ARG, \
|
||||
-P "posix_acl_from_xattr.struct user_namespace", posix_acl_xattr.h)
|
||||
$(call define_if_matches, KERNEL_HAS_D_MAKE_ROOT, d_make_root, dcache.h)
|
||||
$(call define_if_matches, KERNEL_HAS_GENERIC_WRITE_CHECKS_ITER, \
|
||||
-P "generic_write_checks.*iov_iter", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_INVALIDATEPAGE_RANGE, \
|
||||
-P "void \(\*invalidatepage\) \(struct page \*. unsigned int. unsigned int\);", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_PERMISSION_2, \
|
||||
-P "int \(\*permission\) \(struct inode \*. int\);", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_PERMISSION_FLAGS, \
|
||||
-P "int \(\*permission\) \(struct inode \*. int. unsigned int\);", fs.h)
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA5 "kmem_cache_create" ${KSRCDIR_PRUNED_HEAD}/include/linux/slab.h \
|
||||
| grep -qsF "void (*)(void *, struct kmem_cache *, unsigned long)" \
|
||||
&& echo "-DKERNEL_HAS_KMEMCACHE_CACHE_FLAGS_CTOR")
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA5 "kmem_cache_create" ${KSRCDIR_PRUNED_HEAD}/include/linux/slab.h \
|
||||
| grep -qsF "void (*)(struct kmem_cache *, void *)" \
|
||||
&& echo "-DKERNEL_HAS_KMEMCACHE_CACHE_CTOR")
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA5 "kmem_cache_create" ${KSRCDIR_PRUNED_HEAD}/include/linux/slab.h \
|
||||
| grep -qsxP "\s+void \(\*\)\(.*?\)," \
|
||||
&& echo "-DKERNEL_HAS_KMEMCACHE_DTOR")
|
||||
$(call define_if_matches, KERNEL_HAS_SB_BDI, -F "struct backing_dev_info *s_bdi", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_BDI_SETUP_AND_REGISTER, "bdi_setup_and_register", \
|
||||
backing-dev.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FOLLOW_LINK_COOKIE, \
|
||||
-P "const char \* \(\*follow_link\) \(struct dentry \*. void \*\*\);", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FSYNC_2, \
|
||||
-F "int (*fsync) (struct file *, int datasync);", fs.h)
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA20 "struct address_space {" ${KSRCDIR_PRUNED_HEAD}/include/linux/fs.h \
|
||||
| grep -qsP "struct backing_dev_info *backing_dev_info;" \
|
||||
&& echo "-DKERNEL_HAS_ADDRESS_SPACE_BDI")
|
||||
$(call define_if_matches, KERNEL_HAS_COPY_FROM_ITER, "copy_from_iter", uio.h)
|
||||
$(call define_if_matches, KERNEL_HAS_ALLOC_WORKQUEUE, "alloc_workqueue", workqueue.h)
|
||||
$(call define_if_matches, KERNEL_HAS_WQ_RESCUER, "WQ_RESCUER", workqueue.h)
|
||||
$(call define_if_matches, KERNEL_HAS_WAIT_QUEUE_ENTRY_T, "wait_queue_entry_t", wait.h)
|
||||
$(call define_if_matches, KERNEL_HAS_CURRENT_FS_TIME, "current_fs_time", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_64BIT_TIMESTAMPS, "struct timespec64 ia_atime;", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_SB_NODIRATIME, "SB_NODIRATIME", fs.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_GENERIC_GETXATTR, "generic_getxattr", xattr.h)
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sA1 "(*rename) " $(KSRCDIR_PRUNED_HEAD)/include/linux/fs.h \
|
||||
| grep -qsF "unsigned int" \
|
||||
&& echo "-DKERNEL_HAS_RENAME_FLAGS")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qsF "static inline ino_t parent_ino" $(KSRCDIR_PRUNED_HEAD)/include/linux/fs.h \
|
||||
&& echo "-DKERNEL_HAS_PARENT_INO")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -qsF "define SLAB_MEM_SPREAD" $(KSRCDIR_PRUNED_HEAD)/include/linux/slab.h \
|
||||
&& echo "-DKERNEL_HAS_SLAB_MEM_SPREAD")
|
||||
|
||||
$(call define_if_matches, KERNEL_ACCESS_OK_WANTS_TYPE, "define access_ok(type, addr, size)" \
|
||||
$(KSRCDIR_PRUNED_HEAD)/include/asm-generic/uaccess.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_SPIN_RELEASE_HAS_3_ARGUMENTS, "\#define spin_release(l, n, i)", lockdep.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_NEW_PDE_DATA, "pde_data", proc_fs.h)
|
||||
|
||||
# From linux-5.18, .readpages, .invalidatepage, .set_page_dirty, .launder_page
|
||||
# are replaced by.readahead, .invalidate_folio, .dirty_folio, launder_folio
|
||||
#$(call define_if_matches, KERNEL_HAS_READAHEAD, -F "void (*readahead)", fs.h)
|
||||
$(call define_if_matches, KERNEL_HAS_FOLIO, -F "bool (*dirty_folio)", fs.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_READ_FOLIO, -F "int (*read_folio)", fs.h)
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA1 "int (*writepage_t)" ${KSRCDIR_PRUNED_HEAD}/include/linux/writeback.h \
|
||||
| grep -qsF "struct folio *" \
|
||||
&& echo "-DKERNEL_WRITEPAGE_HAS_FOLIO")
|
||||
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA1 "int (*write_begin)" ${KSRCDIR_PRUNED_HEAD}/include/linux/fs.h \
|
||||
| grep -qsF "unsigned flags" \
|
||||
&& echo "-DKERNEL_WRITE_BEGIN_HAS_FLAGS")
|
||||
|
||||
# Matching: int posix_acl_chmod(struct user_namespace *, struct dentry *, umode_t)
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sF "int posix_acl_chmod" ${KSRCDIR_PRUNED_HEAD}/include/linux/posix_acl.h \
|
||||
| grep -qs "struct user_namespace\s*.*struct dentry" \
|
||||
&& echo "-DKERNEL_HAS_POSIX_ACL_CHMOD_NS_DENTRY")
|
||||
|
||||
# linux-6.0 has iov_iter_get_pages2
|
||||
$(call define_if_matches, KERNEL_HAS_IOV_ITER_GET_PAGES2, "iov_iter_get_pages2", uio.h)
|
||||
|
||||
$(call define_if_matches, KERNEL_HAS_GET_RANDOM_INT, "get_random_int", random.h)
|
||||
|
||||
# Detect if write_begin() uses struct folio**
|
||||
KERNEL_FEATURE_DETECTION += $(shell \
|
||||
grep -sFA2 "int (*write_begin)" ${KSRCDIR_PRUNED_HEAD}/include/linux/fs.h \
|
||||
| grep -qs "struct folio **" \
|
||||
&& echo "-DKERNEL_WRITE_BEGIN_USES_FOLIO")
|
||||
309
client_module/build/Makefile
Normal file
309
client_module/build/Makefile
Normal file
@@ -0,0 +1,309 @@
|
||||
|
||||
# This is the BeeGFS client makefile.
|
||||
# It creates the client kernel module (beegfs.ko).
|
||||
#
|
||||
# Use "make help" to find out about configuration options.
|
||||
#
|
||||
# Note: This is the Makefile for internal use, there is a separate Release.mk
|
||||
# file for release packages (to handle the closed source tree properly).
|
||||
|
||||
TARGET ?= beegfs
|
||||
|
||||
export TARGET
|
||||
export OFED_INCLUDE_PATH
|
||||
export BEEGFS_NO_RDMA
|
||||
|
||||
BEEGFS_DKMS_BUILD=0
|
||||
ifdef KERNELRELEASE
|
||||
BEEGFS_DKMS_BUILD=1
|
||||
endif
|
||||
|
||||
ifeq ($(BEEGFS_DKMS_BUILD),1)
|
||||
-include /etc/beegfs/beegfs-client-build.mk
|
||||
endif
|
||||
-include Version.mk
|
||||
|
||||
ifeq ($(obj),)
|
||||
BEEGFS_BUILDDIR := $(shell pwd)
|
||||
else
|
||||
BEEGFS_BUILDDIR := $(obj)
|
||||
endif
|
||||
|
||||
ifeq ($(KRELEASE),)
|
||||
KRELEASE := $(shell uname -r)
|
||||
endif
|
||||
|
||||
ifneq ($(BEEGFS_NO_RDMA),)
|
||||
BEEGFS_CFLAGS += -DBEEGFS_NO_RDMA
|
||||
else
|
||||
|
||||
$(info $$OFED_INCLUDE_PATH = [${OFED_INCLUDE_PATH}])
|
||||
|
||||
ifneq ($(OFED_INCLUDE_PATH),)
|
||||
BEEGFS_CFLAGS += -I$(OFED_INCLUDE_PATH)
|
||||
export KBUILD_EXTRA_SYMBOLS += $(OFED_INCLUDE_PATH)/../Module.symvers
|
||||
endif
|
||||
endif
|
||||
|
||||
# The following section deals with the auto-detection of the kernel
|
||||
# build directory (KDIR)
|
||||
|
||||
# Guess KDIR based on running kernel.
|
||||
# - "/usr/src/linux-headers-*" for Ubuntu
|
||||
# - "/usr/src/kernels/*" for RHEL
|
||||
# - "/lib/modules/*/build" for Debian, SLES
|
||||
ifeq ($(KDIR),)
|
||||
override KDIR = \
|
||||
/lib/modules/$(KRELEASE)/build \
|
||||
/lib/modules/default/build \
|
||||
/usr/src/linux-headers-$(KRELEASE) \
|
||||
/usr/src/linux-headers-default \
|
||||
/usr/src/kernels/$(KRELEASE) \
|
||||
/usr/src/kernels/default
|
||||
endif
|
||||
|
||||
# Prune the KDIR list down to paths that exist and have an
|
||||
# /include/linux/version.h file
|
||||
# Note: linux-3.7 moved version.h to generated/uapi/linux/version.h
|
||||
test_dir = $(shell [ -e $(dir)/include/linux/version.h -o \
|
||||
-e $(dir)/include/generated/uapi/linux/version.h ] && echo $(dir) )
|
||||
KDIR_PRUNED := $(foreach dir, $(KDIR), $(test_dir) )
|
||||
|
||||
# We use the first valid entry of the pruned KDIR list
|
||||
KDIR_PRUNED_HEAD := $(firstword $(KDIR_PRUNED) )
|
||||
|
||||
|
||||
# The following section deals with the auto-detection of the kernel
|
||||
# source path (KSRCDIR) which is required e.g. for KERNEL_FEATURE_DETECTION.
|
||||
|
||||
# Guess KSRCDIR based on KDIR
|
||||
# (This is usually KDIR or KDIR/../source, so you can specify multiple
|
||||
# directories here as a space-separated list)
|
||||
ifeq ($(KSRCDIR),)
|
||||
|
||||
# Note: "KSRCDIR += $(KDIR)/../source" is not working here
|
||||
# because of the symlink ".../build"), so we do it with substring
|
||||
# replacement
|
||||
|
||||
KSRCDIR := $(subst /build,/source, $(KDIR_PRUNED_HEAD) )
|
||||
KSRCDIR += $(KDIR)
|
||||
endif
|
||||
|
||||
# Prune the KSRCDIR list down to paths that exist and contain an
|
||||
# include/linux/fs.h file
|
||||
test_dir = $(shell [ -e $(dir)/include/linux/fs.h ] && echo $(dir) )
|
||||
KSRCDIR_PRUNED := $(foreach dir, $(KSRCDIR), $(test_dir) )
|
||||
|
||||
# We use the first valid entry of the pruned KSRCDIR list
|
||||
KSRCDIR_PRUNED_HEAD := $(firstword $(KSRCDIR_PRUNED) )
|
||||
|
||||
ifeq ($(BEEGFS_NO_RDMA),)
|
||||
# OFED
|
||||
ifneq ($(OFED_INCLUDE_PATH),)
|
||||
|
||||
BEEGFS_CFLAGS += -I$(OFED_INCLUDE_PATH)
|
||||
|
||||
module: $(OFED_INCLUDE_PATH)/rdma/rdma_cm.h
|
||||
$(OFED_INCLUDE_PATH)/rdma/rdma_cm.h:
|
||||
$(error OFED_INCLUDE_PATH not valid: $(OFED_INCLUDE_PATH))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Include kernel feature auto-detectors
|
||||
include KernelFeatureDetection.mk
|
||||
|
||||
KMOD_INST_DIR ?= $(DESTDIR)/lib/modules/$(KRELEASE)/updates/fs/beegfs
|
||||
|
||||
# Prepare CFLAGS:
|
||||
# (Note: "-Wsign-compare" included in "-Wextra", but must be explicit here,
|
||||
# because kernel Makefile adds "-Wno-sign-compare" by default. But we can't
|
||||
# make it permanent here, because it generates a lot of warnings from kernel
|
||||
# includes.)
|
||||
BEEGFS_CFLAGS := $(BUILD_ARCH) $(KERNEL_FEATURE_DETECTION) \
|
||||
-I$(BEEGFS_BUILDDIR)/../source \
|
||||
-I$(BEEGFS_BUILDDIR)/../include \
|
||||
-Wextra -Wno-sign-compare -Wno-empty-body -Wno-unused-parameter -Wno-missing-field-initializers \
|
||||
-DBEEGFS_MODULE_NAME_STR='\"$(TARGET)\"'
|
||||
|
||||
# Update 2022-12: BeeGFS module source code had already switched to -std=gnu99,
|
||||
# but now the kernel has caught up with us - kernel moved from gnu89 to
|
||||
# gnu11.
|
||||
# So we're switching from gnu99 to gnu11, to not break the build with the newer
|
||||
# kernels. We still need to specify this flag because that would break the
|
||||
# client module build with older kernels, where gnu89 is the default.
|
||||
BEEGFS_CFLAGS += -std=gnu11
|
||||
|
||||
ifeq ($(shell echo | gcc -Wtype-limits -E - >/dev/null 2>&1 && echo 1),1)
|
||||
BEEGFS_CFLAGS += -Wno-type-limits
|
||||
endif
|
||||
|
||||
# -O0 would be better, but is not allowed by kernel includes (will not work)
|
||||
BEEGFS_CFLAGS_DEBUG := -O1 -ggdb3 -rdynamic -fno-inline -DBEEGFS_DEBUG \
|
||||
-DLOG_DEBUG_MESSAGES -DDEBUG_REFCOUNT -DBEEGFS_LOG_CONN_ERRORS
|
||||
BEEGFS_CFLAGS_RELEASE := -Wuninitialized
|
||||
|
||||
ifeq ($(BEEGFS_DEBUG),)
|
||||
BEEGFS_CFLAGS += $(BEEGFS_CFLAGS_RELEASE)
|
||||
else
|
||||
BEEGFS_CFLAGS += $(BEEGFS_CFLAGS_DEBUG)
|
||||
endif
|
||||
|
||||
ifeq ($(BEEGFS_NO_RDMA),)
|
||||
# NVFS
|
||||
ifneq ($(NVFS_INCLUDE_PATH),)
|
||||
$(NVFS_INCLUDE_PATH)/nvfs-dma.h:
|
||||
$(error NVFS_INCLUDE_PATH missing nvfs-dma.h: $(NVFS_INCLUDE_PATH))
|
||||
$(NVFS_INCLUDE_PATH)/config-host.h:
|
||||
$(error NVFS_INCLUDE_PATH missing config-host.h: $(NVFS_INCLUDE_PATH))
|
||||
$(NVIDIA_INCLUDE_PATH)/nv-p2p.h:
|
||||
$(error NVIDIA_INCLUDE_PATH missing nv-p2p.h: $(NVIDIA_INCLUDE_PATH))
|
||||
module: $(NVFS_INCLUDE_PATH)/nvfs-dma.h $(NVFS_INCLUDE_PATH)/config-host.h \
|
||||
$(NVIDIA_INCLUDE_PATH)/nv-p2p.h
|
||||
|
||||
BEEGFS_CFLAGS += -DBEEGFS_NVFS
|
||||
BEEGFS_CFLAGS += -I$(NVFS_INCLUDE_PATH) -I$(NVIDIA_INCLUDE_PATH)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# if path to strip command was not given, use default
|
||||
# (alternative strip is important when cross-compiling)
|
||||
ifeq ($(STRIP),)
|
||||
STRIP=strip
|
||||
endif
|
||||
|
||||
BEEGFS_CFLAGS += '-DBEEGFS_VERSION=\"$(BEEGFS_VERSION)\"'
|
||||
|
||||
# Prepare RELEASE_PATH extension
|
||||
ifneq ($(RELEASE_PATH),)
|
||||
RELEASE_PATH_CLIENT := $(RELEASE_PATH)/client_module_$(shell echo '$(BEEGFS_VERSION)' | cut -d. -f1)
|
||||
endif
|
||||
|
||||
|
||||
all: module
|
||||
@ /bin/true
|
||||
|
||||
module: $(TARGET_ALL_DEPS)
|
||||
ifeq ($(KDIR_PRUNED_HEAD),)
|
||||
$(error Linux kernel build directory not found. Please check if\
|
||||
the kernel module development packages are installed for the current kernel\
|
||||
version. (RHEL: kernel-devel; SLES: kernel-default-devel; Debian: linux-headers))
|
||||
endif
|
||||
|
||||
ifeq ($(KSRCDIR_PRUNED_HEAD),)
|
||||
$(error Linux kernel source directory not found. Please check if\
|
||||
the kernel module development packages are installed for the current kernel\
|
||||
version. (RHEL: kernel-devel; SLES: kernel-default-devel; Debian: linux-headers))
|
||||
endif
|
||||
|
||||
@echo "Building beegfs client module"
|
||||
$(MAKE) -C $(KDIR_PRUNED_HEAD) "M=$(BEEGFS_BUILDDIR)/../source" \
|
||||
"EXTRA_CFLAGS=$(BEEGFS_CFLAGS) $(EXTRA_CFLAGS)" modules
|
||||
|
||||
@cp ../source/$(TARGET).ko .
|
||||
@ cp ${TARGET}.ko ${TARGET}-unstripped.ko
|
||||
@ ${STRIP} --strip-debug ${TARGET}.ko;
|
||||
|
||||
coccicheck:
|
||||
$(MAKE) -C $(KDIR_PRUNED_HEAD) "M=$(BEEGFS_BUILDDIR)" coccicheck MODE=report \
|
||||
M=$(BEEGFS_BUILDDIR)/../source KBUILD_EXTMOD="$(BEEGFS_BUILDDIR)/../source"
|
||||
|
||||
|
||||
include AutoRebuild.mk # adds auto_rebuild targets
|
||||
|
||||
prepare_release:
|
||||
ifeq ($(RELEASE_PATH),)
|
||||
$(error RELEASE_PATH not defined)
|
||||
endif
|
||||
|
||||
@ echo "Creating release directory:" $(RELEASE_PATH_CLIENT)
|
||||
mkdir --parents $(RELEASE_PATH_CLIENT)/build \
|
||||
$(RELEASE_PATH_CLIENT)/source \
|
||||
$(RELEASE_PATH_CLIENT)/include
|
||||
|
||||
@ echo "Storing beegfs version:" $(BEEGFS_VERSION)
|
||||
echo "BEEGFS_VERSION =" $(BEEGFS_VERSION) > $(RELEASE_PATH_CLIENT)/build/Version.mk
|
||||
|
||||
@ echo "Copying beegfs client release files to" $(RELEASE_PATH_CLIENT) "..."
|
||||
cp Makefile $(RELEASE_PATH_CLIENT)/build/Makefile
|
||||
cp KernelFeatureDetection.mk $(RELEASE_PATH_CLIENT)/build/
|
||||
cp AutoRebuild.mk $(RELEASE_PATH_CLIENT)/build/
|
||||
cp feature-detect.sh $(RELEASE_PATH_CLIENT)/build/
|
||||
cp ../source/Makefile $(RELEASE_PATH_CLIENT)/source/
|
||||
|
||||
find ../source -mount -name '*.h' -type f | \
|
||||
xargs -I ’{}’ cp --parents ’{}’ $(RELEASE_PATH_CLIENT)/build
|
||||
find ../source -mount -name '*.c' -type f | \
|
||||
xargs -I ’{}’ cp --parents ’{}’ $(RELEASE_PATH_CLIENT)/build
|
||||
find ../include -mount -name '*.h' -type f | \
|
||||
xargs -I ’{}’ cp --parents ’{}’ $(RELEASE_PATH_CLIENT)/build
|
||||
|
||||
# When used for development where the full BeeGFS source is available, this install target handles
|
||||
# ensuring the mount.beegfs script is installed. If the mount.script is not present in the source,
|
||||
# for example if the install target was invoked via the BeeGFS client service and AutoRebuild.mk, it
|
||||
# just checks the script already exists at /sbin/mount.beegfs since the script should have been
|
||||
# installed by the package manager. If it does not exist an error is returned as this is likely a
|
||||
# bug elsewhere related to installing the script, or somebody is trying to use this Makefile in an
|
||||
# unsupported/unexpected manner and further investigation is required.
|
||||
install:
|
||||
install -D -m 644 $(TARGET).ko $(KMOD_INST_DIR)/$(TARGET).ko
|
||||
@if [ -f dist/sbin/mount.beegfs ]; then \
|
||||
install -D -m 755 dist/sbin/mount.beegfs /sbin/mount.beegfs; \
|
||||
echo "Info: Installed mount script at /sbin/mount.beegfs."; \
|
||||
elif [ ! -f /sbin/mount.beegfs ]; then \
|
||||
echo "Error: mount.beegfs does not already exist at /sbin/mount.beegfs (this is likely a bug elsewhere)."; \
|
||||
exit 1; \
|
||||
fi
|
||||
depmod -a $(KRELEASE)
|
||||
|
||||
clean:
|
||||
rm -f *~ .${TARGET}??*
|
||||
rm -f .*.cmd *.mod.c *.mod.o *.o *.ko *.ko.unsigned
|
||||
rm -f ../source/Module*.symvers ../source/modules.order ../source/Module.markers
|
||||
rm -f Module*.symvers modules.order Module.markers
|
||||
rm -f $(AUTO_REBUILD_KVER_FILE)
|
||||
rm -rf .tmp_versions/
|
||||
find ../source/ -mount -name '*.o' -type f -delete
|
||||
find ../source/ -mount -name '.*.o.cmd' -type f -delete
|
||||
find ../source/ -mount -name '.*.o.d' -type f -delete
|
||||
find ../source/ -mount -name '*.gcno' -type f -delete
|
||||
|
||||
help:
|
||||
@echo "This makefile creates the kernel module: $(TARGET) (beegfs-client)"
|
||||
@echo ' '
|
||||
@echo 'client Arguments (required):'
|
||||
@echo ' RELEASE_PATH=<path> (Target: prepare_release)'
|
||||
@echo ' The path to the client release directory.'
|
||||
@echo ' '
|
||||
@echo 'client Arguments (optional):'
|
||||
@echo ' KRELEASE=<release>: Kernel release'
|
||||
@echo ' (The output of "uname -r" will be used if undefined.'
|
||||
@echo ' This option is useful when building for a kernel different'
|
||||
@echo ' from the one currently running (e.g. in a chroot).)'
|
||||
@echo ' KDIR=<path>: Kernel build directory.'
|
||||
@echo ' (Will be guessed based on running kernel or KRELEASE if undefined.)'
|
||||
@echo ' KSRCDIR=<path>: Kernel source directory containing the kernel include '
|
||||
@echo ' directory. (Will be guessed based on KDIR if undefined.)'
|
||||
@echo ' BEEGFS_DEBUG=1:'
|
||||
@echo ' Enables file sytem debug log messages etc.'
|
||||
@echo ' TARGET=<MODULE_NAME>'
|
||||
@echo ' Set a different module and file system name.'
|
||||
@echo ' '
|
||||
@echo 'Infiniband (RDMA) arguments (optional):'
|
||||
@echo ' OFED_INCLUDE_PATH=<path>:'
|
||||
@echo ' Path to OpenFabrics Enterpise Distribution kernel include directory, e.g.'
|
||||
@echo ' "/usr/src/openib/include". (If not defined, the standard kernel headers'
|
||||
@echo ' will be used.)'
|
||||
@echo ''
|
||||
@echo 'NVIDIA GPUDirect Storage (GDS) arguments (optional):'
|
||||
@echo ' NVFS_INCLUDE_PATH=<path>:'
|
||||
@echo ' Path to directory that contains nvfs-dma.h. If not defined, GDS support is'
|
||||
@echo ' disabled.'
|
||||
@echo ' NVIDIA_INCLUDE_PATH=<path>:'
|
||||
@echo ' Path to NVIDIA driver source. Required when NVFS_INCLUDE_PATH is specifed.'
|
||||
@echo ''
|
||||
@echo 'Targets:'
|
||||
@echo ' all (default) - build only'
|
||||
@echo ' install - install the kernel modules'
|
||||
@echo ' clean - delete previously compiled files'
|
||||
@echo ' prepare_release - build and copy files into the RELEASE_PATH directory'
|
||||
92
client_module/build/dist/etc/beegfs-client-autobuild.conf
vendored
Normal file
92
client_module/build/dist/etc/beegfs-client-autobuild.conf
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
# This is a config file for the automatic build process of BeeGFS client kernel
|
||||
# modules.
|
||||
# http://www.beegfs.com
|
||||
|
||||
|
||||
#
|
||||
# --- Section: [Notes] ---
|
||||
#
|
||||
|
||||
# General Notes
|
||||
# =============
|
||||
# To force a rebuild of the client modules:
|
||||
# $ /etc/init.d/beegfs-client rebuild
|
||||
#
|
||||
# To see a list of available build arguments:
|
||||
# $ make help -C /opt/beegfs/src/client/client_module_${BEEGFS_MAJOR_VERSION}/build
|
||||
#
|
||||
# Help example for BeeGFS 2015.03 release:
|
||||
# $ make help -C /opt/beegfs/src/client/client_module_2015.03/build
|
||||
|
||||
|
||||
# RDMA Support Notes
|
||||
# ==================
|
||||
# If you installed InfiniBand kernel modules from OpenFabrics OFED, then also
|
||||
# define the correspsonding header include path by adding
|
||||
# "OFED_INCLUDE_PATH=<path>" to the "buildArgs", where <path> usually is
|
||||
# "/usr/src/openib/include" or "/usr/src/ofa_kernel/default/include" for
|
||||
# Mellanox OFED.
|
||||
#
|
||||
# OFED headers are automatically detected even if OFED_INCLUDE_PATH is not
|
||||
# defined. To build the client without RDMA support, define BEEGFS_NO_RDMA=1.
|
||||
#
|
||||
|
||||
|
||||
# NVIDIA GPUDirect Storage Support Notes
|
||||
# ==================
|
||||
# If you want to build BeeGFS with NVIDIA GPUDirect Storage support, add
|
||||
# "NVFS_INCLUDE_PATH=<path>" to the "buildArgs" below, where path is the directory
|
||||
# that contains nvfs-dma.h. This is usually the nvidia-fs source directory:
|
||||
# /usr/src/nvidia-fs-VERSION.
|
||||
#
|
||||
# If config-host.h is not present in NVFS_INCLUDE_PATH, execute the configure
|
||||
# script. Example:
|
||||
# $ cd /usr/src/nvidia-fs-2.13.5
|
||||
# $ ./configure
|
||||
#
|
||||
# NVIDIA_INCLUDE_PATH must be defined and point to the NVIDIA driver source:
|
||||
# /usr/src/nvidia-VERSION/nvidia
|
||||
#
|
||||
# OFED_INCLUDE_PATH must be defined and point to Mellanox OFED.
|
||||
#
|
||||
|
||||
#
|
||||
# --- Section: [Build Settings] ---
|
||||
#
|
||||
|
||||
# Build Settings
|
||||
# ==============
|
||||
# These are the arguments for the client module "make" command.
|
||||
#
|
||||
# Note: Quotation marks and equal signs can be used without escape characters
|
||||
# here.
|
||||
#
|
||||
# Example1:
|
||||
# buildArgs=-j8
|
||||
#
|
||||
# Example2 (see "RDMA Support Notes" above):
|
||||
# buildArgs=-j8 OFED_INCLUDE_PATH=/usr/src/openib/include
|
||||
#
|
||||
# Example3 (see "NVIDIA GPUDirect Storage Support Notes" above):
|
||||
# buildArgs=-j8 OFED_INCLUDE_PATH=/usr/src/ofa_kernel/default/include \
|
||||
# NVFS_INCLUDE_PATH=/usr/src/nvidia-fs-2.13.5 \
|
||||
# NVIDIA_INCLUDE_PATH=/usr/src/nvidia-520.61.05/nvidia
|
||||
#
|
||||
# Default:
|
||||
# buildArgs=-j8
|
||||
|
||||
buildArgs=-j8
|
||||
|
||||
|
||||
# Turn Autobuild on/off
|
||||
# =====================
|
||||
# Controls whether modules will be built on "/etc/init.d/beegfs-client start".
|
||||
#
|
||||
# Note that even if autobuild is enabled here, the modules will only be built
|
||||
# if no beegfs kernel module for the current kernel version exists in
|
||||
# "/lib/modules/<kernel_version>/updates/".
|
||||
#
|
||||
# Default:
|
||||
# buildEnabled=true
|
||||
|
||||
buildEnabled=true
|
||||
19
client_module/build/dist/etc/beegfs-client-build.mk
vendored
Normal file
19
client_module/build/dist/etc/beegfs-client-build.mk
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# BeeGFS client module DKMS build configuration
|
||||
# This file is only used when building via DKMS.
|
||||
# The module needs to be rebuilt after this file has been changed.
|
||||
|
||||
# If using thirdparty OFED specify the path to the installation here.
|
||||
# Examples:
|
||||
#OFED_INCLUDE_PATH=/usr/src/ofa_kernel/default/include
|
||||
#OFED_INCLUDE_PATH=/usr/src/openib/include
|
||||
# To disable RDMA support, define BEEGFS_NO_RDMA
|
||||
#BEEGFS_NO_RDMA=1
|
||||
# If building nvidia-fs support, specify path to nvfs-dma.h.
|
||||
# This directory must also have config-host.h, which is created
|
||||
# by the nvidia-fs configure script.
|
||||
# Example:
|
||||
#NVFS_INCLUDE_PATH=/usr/src/nvidia-fs-2.13.5
|
||||
# If building nvidia-fs support, specify path to NVIDIA driver
|
||||
# source.
|
||||
# Example:
|
||||
#NVIDIA_INCLUDE_PATH=/usr/src/nvidia-520.61.05/nvidia
|
||||
37
client_module/build/dist/etc/beegfs-client-mount-hook.example
vendored
Executable file
37
client_module/build/dist/etc/beegfs-client-mount-hook.example
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash -e
|
||||
# BeeGFS client mount hook script
|
||||
|
||||
action="${1}"
|
||||
mountpoint="${2}"
|
||||
|
||||
# THIS IS AN EXAMPLE SCRIPT.
|
||||
# Copy and modify it, and remove the following line:
|
||||
exit 1
|
||||
|
||||
if [ ! -d "${mountpoint}" ]
|
||||
then
|
||||
echo "${0}: Mount point does not exist: ${mountpoint}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${action}" in
|
||||
|
||||
pre-mount)
|
||||
;;
|
||||
|
||||
post-mount)
|
||||
mount -o bind "${mountpoint}/foo" "${mountpoint}/bar"
|
||||
;;
|
||||
|
||||
pre-unmount)
|
||||
umount "${mountpoint}/bar"
|
||||
;;
|
||||
|
||||
post-unmount)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "${0}: Unrecognized option supplied to client mount hook: ${action}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
755
client_module/build/dist/etc/beegfs-client.conf
vendored
Normal file
755
client_module/build/dist/etc/beegfs-client.conf
vendored
Normal file
@@ -0,0 +1,755 @@
|
||||
# This is a config file for BeeGFS clients.
|
||||
# http://www.beegfs.com
|
||||
|
||||
|
||||
# --- [Table of Contents] ---
|
||||
#
|
||||
# 1) Settings
|
||||
# 2) Mount Options
|
||||
# 3) Basic Settings Documentation
|
||||
# 4) Advanced Settings Documentation
|
||||
|
||||
|
||||
#
|
||||
# --- Section 1.1: [Basic Settings] ---
|
||||
#
|
||||
|
||||
sysMgmtdHost =
|
||||
|
||||
|
||||
#
|
||||
# --- Section 1.2: [Advanced Settings] ---
|
||||
#
|
||||
|
||||
connAuthFile = /etc/beegfs/conn.auth
|
||||
connDisableAuthentication = false
|
||||
connClientPort = 8004
|
||||
connMgmtdPort = 8008
|
||||
connPortShift = 0
|
||||
|
||||
connCommRetrySecs = 600
|
||||
connFallbackExpirationSecs = 900
|
||||
connInterfacesFile =
|
||||
connRDMAInterfacesFile =
|
||||
connMaxInternodeNum = 12
|
||||
connMaxConcurrentAttempts = 0
|
||||
connNetFilterFile =
|
||||
|
||||
connUseRDMA = true
|
||||
connTCPFallbackEnabled = true
|
||||
connTCPRcvBufSize = 0
|
||||
connUDPRcvBufSize = 0
|
||||
connRDMABufNum = 70
|
||||
connRDMABufSize = 8192
|
||||
connRDMAFragmentSize = page
|
||||
connRDMATypeOfService = 0
|
||||
connTcpOnlyFilterFile =
|
||||
|
||||
logClientID = false
|
||||
logLevel = 3
|
||||
|
||||
quotaEnabled = false
|
||||
|
||||
sysCacheInvalidationVersion = true
|
||||
sysCreateHardlinksAsSymlinks = false
|
||||
sysMountSanityCheckMS = 11000
|
||||
sysSessionCheckOnClose = false
|
||||
sysSyncOnClose = false
|
||||
sysTargetOfflineTimeoutSecs = 900
|
||||
sysUpdateTargetStatesSecs = 30
|
||||
sysXAttrsEnabled = false
|
||||
|
||||
tuneFileCacheType = buffered
|
||||
tunePreferredMetaFile =
|
||||
tunePreferredStorageFile =
|
||||
tuneRemoteFSync = true
|
||||
tuneUseGlobalAppendLocks = false
|
||||
tuneUseGlobalFileLocks = false
|
||||
|
||||
|
||||
#
|
||||
# --- Section 1.3: [Enterprise Features] ---
|
||||
#
|
||||
# See end-user license agreement for definition and usage limitations of
|
||||
# enterprise features.
|
||||
#
|
||||
|
||||
sysACLsEnabled = false
|
||||
|
||||
|
||||
#
|
||||
# --- Section 2: [Mount Options] ---
|
||||
#
|
||||
|
||||
# Valid mount options are:
|
||||
# cfgFile, logLevel, connPortShift, connMgmtdPort,
|
||||
# sysMgmtdHost, sysMountSanityCheckMS, connInterfacesList.
|
||||
#
|
||||
# Use the mount option "cfgFile" to specify a different config file
|
||||
# for the beegfs client.
|
||||
# Example:
|
||||
# $ /bin/mount -t beegfs beegfs_nodev /beegfs -ocfgFile=/etc/anotherconfig.conf
|
||||
#
|
||||
# Use the mount option "connInterfacesList" to pass the list of interfaces names.
|
||||
# These interfaces names should be space-separated.
|
||||
# Example:
|
||||
# $ /bin/mount -t beegfs beegfs_nodev /beegfs \
|
||||
# -ocfgFile=/etc/anotherconfig.conf,connInterfacesList='ib0 eth0'
|
||||
#
|
||||
# Mount options override the corresponding config file values.
|
||||
# Example:
|
||||
# $ /bin/mount -ocfgFile=/etc/anotherconfig.conf,logLevel=3 ...
|
||||
|
||||
|
||||
#
|
||||
# --- Section 3: [Basic Settings Documentation] ---
|
||||
#
|
||||
|
||||
# [sysMgmtdHost]
|
||||
# Hostname (or IP) of the host running the management service.
|
||||
# (See also "connMgmtdPort".)
|
||||
# Default: <none>
|
||||
|
||||
|
||||
#
|
||||
# --- Section 4: [Advanced Settings Documentation] ---
|
||||
#
|
||||
|
||||
#
|
||||
# --- Section 4.1: [Connections & Communication] ---
|
||||
#
|
||||
|
||||
# [connAuthFile]
|
||||
# The path to a file that contains a shared secret for connection based
|
||||
# authentication. Only peers that use the same shared secret will be able to
|
||||
# connect.
|
||||
# Default: <none>
|
||||
|
||||
# [connDisableAuthentication]
|
||||
# If set to true, explicitly disables connection authentication and allow the
|
||||
# service to run without a connAuthFile. Running BeeGFS without connection
|
||||
# authentication is considered insecure and is not recommended.
|
||||
# Default: false
|
||||
|
||||
# [connClientPort]
|
||||
# The UDP port of the client.
|
||||
# Default: 8004
|
||||
|
||||
# [connMgmtdPort]
|
||||
# The UDP and TCP port of the management node.
|
||||
# Default: 8008
|
||||
|
||||
# [connPortShift]
|
||||
# Shifts all following UDP and TCP ports according to the specified value.
|
||||
# Intended to make port configuration easier in case you do not want to
|
||||
# configure each port individually.
|
||||
# Default: 0
|
||||
|
||||
# [connCommRetrySecs]
|
||||
# The time (in seconds) for retries in case a network communication fails
|
||||
# (e.g. if a server is down). After this time, the I/O operation will fail
|
||||
# and the calling process will receive an error.
|
||||
# Note: Set this value to 0 for infinite retries. In this case, a process
|
||||
# accessing the file system will block until the corresponding server
|
||||
# becomes available (or until it is interrupted by a signal).
|
||||
# Default: 600
|
||||
|
||||
# [connFallbackExpirationSecs]
|
||||
# The time in seconds after which a connection to a fallback interface expires.
|
||||
# When a fallback connection expires, the system will try to establish a new
|
||||
# connection to the other hosts primary interface (falling back to another
|
||||
# interface again if necessary).
|
||||
# Note: The priority of node interfaces can be configured using the
|
||||
# "connInterfacesFile" parameter.
|
||||
# Default: 900
|
||||
|
||||
# [connInterfacesFile]
|
||||
# The path to a text file that specifies the names of the interfaces, which
|
||||
# may be used for communication by other nodes. One interface per line. The
|
||||
# line number also defines the priority of an interface.
|
||||
# Example: "ib0" in the first line, "eth0" in the second line.
|
||||
# Values: This setting is optional. If unspecified, all available interfaces
|
||||
# will be published and priorities will be assigned automatically.
|
||||
# Note: This has no influence on outgoing connections. The information is sent
|
||||
# to other hosts to inform them about possible communication paths.
|
||||
# Default: <none>
|
||||
|
||||
# [connInterfacesList]
|
||||
# Comma-separated list of interface names. Performs the same function as
|
||||
# connInterfacesFile.
|
||||
# If use as the mount option "connInterfacesList" to pass the list of interfaces
|
||||
# names then it override the corresponding config file/list values..
|
||||
# The interfaces names should be space-separated.
|
||||
# Example:
|
||||
# $ /bin/mount -t beegfs beegfs_nodev /beegfs \
|
||||
# -ocfgFile=/etc/anotherconfig.conf,connInterfacesList='ib0 eth0'
|
||||
#
|
||||
# Default: <none>
|
||||
|
||||
# [connRDMAInterfacesFile]
|
||||
# The path to a text file that specifies the names of IPoIB interfaces, which
|
||||
# may be used for outbound RDMA communication with other nodes. One interface
|
||||
# per line. These interfaces must be RDMA-capable NICs.
|
||||
#
|
||||
# All storage and metadata servers must be IP-reachable from each specified
|
||||
# interface.
|
||||
#
|
||||
# Specifying interfaces in this file limits which RDMA NICs are used for outbound
|
||||
# RDMA. Specifying multiple interfaces allows the client to use multiple RDMA
|
||||
# interfaces for outbound communication.
|
||||
#
|
||||
# Example: "ib0" in the first line, "ib1" in the second line.
|
||||
# Values: This setting is optional. When none are specified, the client will use
|
||||
# the first client host interface that can reach the remote node via IPoIB,
|
||||
# as decided by rdma_cm. When multiple interfaces are specified, the client
|
||||
# round-robins creation of outbound RDMA connections across the specified
|
||||
# interfaces.
|
||||
# Default: <none>
|
||||
|
||||
# [connMaxInternodeNum]
|
||||
# The maximum number of simultaneous connections to the same node.
|
||||
# Default: 12
|
||||
|
||||
# [connMaxConcurrentAttempts]
|
||||
# The maximum number of simultaneous connection attempts. This may help in case
|
||||
# establishing new connections keeps failing and produces fallbacks.
|
||||
# It may happen particularly when using RDMA in an Omni-Path setup. If you
|
||||
# don't have failing connection attempts, tuning this option might still lead
|
||||
# to a faster connection process. This option is experimental, so there is no
|
||||
# experience with different values. Setting it to 0 disables it, which means
|
||||
# concurrent connection attempts are not limited.
|
||||
# Default: 0
|
||||
|
||||
# [connNetFilterFile]
|
||||
# The path to a text file that specifies allowed IP subnets, which may be used
|
||||
# for outgoing communication. One subnet per line in classless notation (IP
|
||||
# address and number of significant bits).
|
||||
# Example: "192.168.10.0/24" in the first line, "192.168.20.0/24" in the second
|
||||
# line.
|
||||
# This value is optional. If unspecified, all addresses are allowed for
|
||||
# outgoing communication.
|
||||
# Default: <none>
|
||||
|
||||
# [connUseRDMA]
|
||||
# Enables the use of Remote Direct Memory Access (RDMA) for InfiniBand or RoCE.
|
||||
# For this setting to be effective, OFED ibverbs support also has to be enabled
|
||||
# at compile time of the beegfs client modules (typically via
|
||||
# beegfs-client-autobuild.conf).
|
||||
# Default: true
|
||||
|
||||
# [connTCPFallbackEnabled]
|
||||
# Enables fallback from RDMA to TCP sockets when there is a problem connecting
|
||||
# via RDMA to a storage or meta node.
|
||||
# Default: true
|
||||
|
||||
# [connTCPRcvBufSize], [connUDPRcvBufSize]
|
||||
# Sets the size for TCP and UDP socket receive buffers (SO_RCVBUF). The maximum
|
||||
# allowed value is determined by sysctl net.core.rmem_max. This value is ignored
|
||||
# if it is less than the default value determined by net.core.rmem_default.
|
||||
# For legacy reasons, the default value 0 indicates that the buffer size is set
|
||||
# to connRDMABufNum * connRDMABufSize.
|
||||
# -1 indicates that the buffer size should be left at the system default.
|
||||
# Default: 0
|
||||
|
||||
# [connRDMABufNum], [connRDMABufSize], [connRDMAFragmentSize]
|
||||
# InfiniBand RDMA buffer settings.
|
||||
# connRDMABufSize is the maximum size of a buffer (in bytes) that will be sent
|
||||
# over the network; connRDMABufNum is the number of available buffers that can
|
||||
# be in flight for a single connection. These client settings are also applied
|
||||
# on the server side for each connection. Ideally, the largest, commonly used
|
||||
# filesytem chunksize should be < connRDMABufNum * connRDMABufSize to achieve
|
||||
# the best performance.
|
||||
#
|
||||
# The minimum usable value for connRDMABufNum is 3, which is required by the
|
||||
# BeeGFS RDMA protocol. Lower values will immediately result in communication
|
||||
# failures.
|
||||
#
|
||||
# connRDMAFragmentSize determines how contiguous memory is allocated per
|
||||
# buffer. If connRDMAFragmentSize=4096 and connRDMABufSize=8192, each buffer
|
||||
# is allocated in 2 regions of 4096 contiguous bytes. Less fragmentation
|
||||
# improves performance. The value "none" indicates that buffers will not be
|
||||
# fragmented, resulting in allocation of contiguous regions of
|
||||
# connRDMABufSize. The value "page" uses the Linux PAGE_SIZE as the
|
||||
# fragmentation value.
|
||||
# The reason for using fragmentation is that large allocations
|
||||
# are more likely to fail if there is a shortage of heap memory. The minimum
|
||||
# fragmentation value is PAGE_SIZE. Using larger values (or 0) should improve
|
||||
# performance and allows for larger values of connRDMABufSize.
|
||||
#
|
||||
# Note: RAM usage per connection is connRDMABufSize x connRDMABufNum x 2. Keep
|
||||
# resulting RAM usage (x connMaxInternodeNum x number_of_clients) on the
|
||||
# server in mind when increasing these values.
|
||||
# Default: 70, 8192, page
|
||||
|
||||
# [connRDMAMetaBufNum], [connRDMAMetaBufSize], [connRDMAMetaFragmentSize]
|
||||
# InfiniBand RDMA buffer settings for connections to beegfs-meta.
|
||||
# These settings behave in the same way as connRDMABufNum, connRDMABufSize
|
||||
# and connRDMAFragmentize except that they are used for connections to
|
||||
# beegfs-meta.
|
||||
# Metadata messages are usuallly small and do not require the large amount
|
||||
# of buffer space that is typically configured for connections to
|
||||
# beegfs-storage. One exception to this would be if large extended attributes
|
||||
# are added to files.
|
||||
# connRDMAMetaBufNum = "default" indicates that connRDMABufNum should be used.
|
||||
# connRDMAMetaBufSize = "default" indicates that connRDMABufSize should be used.
|
||||
# connRDMAMetaFragmentSize = "default" indicates that connRDMAFragmentSize
|
||||
# should be used.
|
||||
# The minimum value for connRDMAMetaBufNum is 3.
|
||||
# Default: default, default, default
|
||||
|
||||
# [connRDMATypeOfService]
|
||||
# InfiniBand provides the option to set a type of service for an application.
|
||||
# This type of service can be used by your subnet manager to provide Quality of
|
||||
# Service functionality (e.g. setting different service levels).
|
||||
# In openSM the service type will be mapped to the parameter qos-class, which
|
||||
# can be handled in your QoS configuration.
|
||||
# See
|
||||
# www.openfabrics.org/downloads/OFED/ofed-1.4/OFED-1.4-docs/
|
||||
# QoS_management_in_OpenSM.txt
|
||||
# for more information on how to configure openSM for QoS.
|
||||
# This parameter sets the type of service for all outgoing connections of this
|
||||
# daemon.
|
||||
# Default: 0 (Max: 255)
|
||||
|
||||
# [connRDMAKeyType]
|
||||
# In RDMA, an "rkey" is used to provide an access token for a peer to access
|
||||
# local memory regions that are registered for RDMA. Historically,
|
||||
# BeeGFS used either a "DMA key" or an "unsafe global rkey" depending upon
|
||||
# whether or not "unsafe global rkey" is supported by the operating system.
|
||||
# This is now selectable. "DMA key" is not supported on kernel >= 4.9
|
||||
# unless MOFED is installed. If an unsupported option is specified, there
|
||||
# will be warnings in syslog and RDMA connections will not be established.
|
||||
# Use of "unsafe global rkey" is preferred, but generates a syslog message
|
||||
# every time an RDMA connection is established: "enabling unsafe global rkey".
|
||||
# Neither option is considered "safe" because they both provide access
|
||||
# to all DMA mapped memory for a given connection. This technique is
|
||||
# used to provide better performance for small I/O requests.
|
||||
# "register" uses a memory registration per connection to provide an rkey.
|
||||
# "register" is not compatible with NVIDIA GPUDirect Storage.
|
||||
# Specify "dma" or "register" to squelch the syslog warning.
|
||||
# Values: "global" (unsafe global rkey), "dma" (DMA key), "register"
|
||||
# (memory registration)
|
||||
# Default: "global"
|
||||
|
||||
# [connTcpOnlyFilterFile]
|
||||
# The path to a text file that specifies IP address ranges to which no RDMA
|
||||
# connection should be established. This is useful e.g. for environments where
|
||||
# all hosts support RDMA, but some hosts cannot connect via RDMA to some other
|
||||
# hosts.
|
||||
# Example: "192.168.10.0/24" in the first line, "192.168.20.0/24" in the second
|
||||
# line.
|
||||
# Values: This setting is optional.
|
||||
# Default: <none>
|
||||
|
||||
# [connMessagingTimeouts]
|
||||
# These constants are used to set some of the connection timeouts for sending
|
||||
# and receiving data between services in the cluster. They used to be hard-coded
|
||||
# (CONN_LONG_TIMEOUT, CONN_MEDIUM_TIMEOUT and CONN_SHORT_TIMEOUT) but are now
|
||||
# made configurable for experimentation purposes.
|
||||
# This option takes three integer values of milliseconds, separated by a comma
|
||||
# in the order long, medium, short.
|
||||
# WARNING: This is an EXPERIMENTAL configuration option that should not be
|
||||
# changed in production environments unless properly tested and validated.
|
||||
# Some configurations can lead to service lockups and other subtle issues.
|
||||
# Please make sure that you know exactly what you are doing and properly
|
||||
# test any changes you make.
|
||||
# Default: 600000,90000,30000
|
||||
|
||||
# [connRDMATimeouts]
|
||||
# These constants are used to set some of the timeouts for sending and receiving
|
||||
# data between services in the cluster via RDMA. They used to be
|
||||
# hard-coded IBVSOCKET_CONN_TIMEOUT_MS, IBVSOCKET_COMPLETION_TIMEOUT_MS,
|
||||
# IBVSOCKET_FLOWCONTROL_ONSEND_TIMEOUT_MS,
|
||||
# IBVSOCKET_FLOWCONTROL_ONRECV_TIMEOUT_MS and a 10000 literal for poll timeout
|
||||
# but are now made configurable for experimentation purposes.
|
||||
# This option takes five integer values of milliseconds, separated by a comma
|
||||
# in the order connectMS, completionMS, flowSendMS, flowRecvMS and pollMS.
|
||||
# WARNING: This is an EXPERIMENTAL configuration option that should not be
|
||||
# changed in production environments unless properly tested and validated.
|
||||
# Some configurations can lead to service lockups and other subtle issues.
|
||||
# Please make sure that you know exactly what you are doing and properly
|
||||
# test any changes you make.
|
||||
# Default: 5000,300000,180000,180000,10000
|
||||
|
||||
|
||||
# --- Section 4.2: [Logging] ---
|
||||
#
|
||||
|
||||
# [logClientID]
|
||||
# Defines whether the ClientID should appear in each log line.
|
||||
# This is mainly helpful if BeeGFS is mounted multiple times on this machine.
|
||||
# Default: false
|
||||
|
||||
# [logLevel]
|
||||
# Defines the amount of log messages. The higher this level, the more detailed
|
||||
# the log messages will be.
|
||||
# Level 3 will print connection messages, level 4 will print syscall messages,
|
||||
# level 5 will print debug messages.
|
||||
# Note: Levels above 3 might decrease performance.
|
||||
# Default: 3 (Max: 5)
|
||||
|
||||
#
|
||||
# --- Section 4.3: [Quota Settings] ---
|
||||
#
|
||||
|
||||
# [quotaEnabled]
|
||||
# Enables user and group quota support by transferring extra user data to the
|
||||
# servers. This uses quota information of the underlying file systems on the
|
||||
# storage servers, which needs to be enabled by the server administrator.
|
||||
# Note: In the first implementation, only quota monitoring is available.
|
||||
# Note: Get quota information with "beegfs-ctl --getquota".
|
||||
# Note: If this option is true, performance might be slightly decreased due to
|
||||
# extra information tracking.
|
||||
# Default: false
|
||||
|
||||
|
||||
#
|
||||
# --- Section 4.4: [System Settings] ---
|
||||
#
|
||||
|
||||
# [sysCacheInvalidationVersion]
|
||||
#
|
||||
# Enable the client to invalidate its cache and reload the inode of a file when
|
||||
# the version parameter of the file on metadata changes due to internal metadata
|
||||
# operations such as stripe pattern change. This is done by comparing the
|
||||
# version parameters on client and metadata on the first lookup after internal
|
||||
# metadata changes. If the versions differ, the client invalidates the cache and
|
||||
# reloads the inode.
|
||||
# Note: If this option is set to true, performance may be decreased.
|
||||
# Default: true
|
||||
|
||||
# [sysCreateHardlinksAsSymlinks]
|
||||
# Create a symlink when an application tries to create a hardlink for files in
|
||||
# different directories.
|
||||
# Default: false
|
||||
|
||||
# [sysMountSanityCheckMS]
|
||||
# Perform some basic checks during mount (e.g. whether the client helper daemon
|
||||
# and storage servers are reachable). Mounting will fail if a problem is
|
||||
# detected.
|
||||
# Values: Set the time (in ms) you want to spend waiting for the servers
|
||||
# (especially the management daemon) to respond. Use 0 to disable all checks
|
||||
# and allow mounting even if no servers are reachable.
|
||||
# Default: 11000
|
||||
|
||||
# [sysSessionCheckOnClose]
|
||||
# Checks for a valid session on the storage servers when a file is closed. If
|
||||
# this option is set to true, a potential cache loss from a crash of a storage
|
||||
# server can be detected. This will be reported to the user application as a
|
||||
# close() error code.
|
||||
# Note: There is also a session check included in all read/write/fsync messages,
|
||||
# which is independent of this setting.
|
||||
# Note: If this option is set to true, more network messages are required on
|
||||
# close(), so performance will decreased.
|
||||
# Default: false
|
||||
|
||||
# [sysSessionChecksEnabled]
|
||||
# Enable session checks in read/write/fsync operations to be able to detect
|
||||
# server crashes that could have caused a loss of server side caches. Disabling
|
||||
# these checks is useful in certain system configurations to be able to cleanly
|
||||
# resume I/O after a server crash/unclean failover.
|
||||
# WARNING: Disabling session checks can lead to undetected cache loss and
|
||||
# therefore silent data corruption on the storage servers. Only disable the
|
||||
# checks if absolutely necessary and if there are measures in place to prevent
|
||||
# cache loss (synchronous mounts, battery backed caches) on the storage servers.
|
||||
# Default: true
|
||||
|
||||
# [sysSyncOnClose]
|
||||
# Sync file contents on close. If this option is set to true, the storage
|
||||
# servers will flush the write cache of a file to disk immediately when it is
|
||||
# closed by the application. If this option is set to false, the write cache
|
||||
# will be flushed to disk asynchronously after a few seconds.
|
||||
# Note: If this option is true, performance will be decreased.
|
||||
# Default: false
|
||||
|
||||
# [sysTargetOfflineTimeoutSecs]
|
||||
# Timeout until all storage targets and metadata nodes are considered offline
|
||||
# when no target state updates can be fetched from the management server.
|
||||
# If this value is 0, targets will never be set to offline due to an
|
||||
# unreachable management node and will stay in state probably-offline.
|
||||
# Note: This must be at least twice as large as the value of
|
||||
# sysTargetOfflineTimoutSecs in the server config files.
|
||||
# Values: time in seconds
|
||||
# Default: 900
|
||||
|
||||
# [sysUpdateTargetStatesSecs]
|
||||
# Interval in which the states of the storage targets are checked.
|
||||
# Note: This must be significantly shorter than the sysTargetOfflineTimeoutSecs
|
||||
# value set in the server (recommendation: maximum 1/3 of it).
|
||||
# Values: time in seconds
|
||||
# Default: 30
|
||||
|
||||
# [sysXAttrsEnabled]
|
||||
# Enable extended attributes (also know as EAs/xattrs).
|
||||
# Default: false
|
||||
|
||||
# [sysXAttrsCheckCapabilities]
|
||||
# Check inodes for existing "security.capability" extended attribute and
|
||||
# optionally cache to reduce metadata requests and increase write performance.
|
||||
# The Linux kernel uses a security mechanism that automatically removes
|
||||
# setuid/setgid bits and capabilities from files when they are changed. This is
|
||||
# done to prevent users from executing binaries with elevated privileges that
|
||||
# were changed after the privileges were originally set. That mechanism requires
|
||||
# that, by default, the kernel has to check each file for existing capabilities
|
||||
# on every write which leads to a large overhead in metadata RPCs to fetch the
|
||||
# "security.capability" extended attribute. To optimize this, Linux allows file
|
||||
# systems to set a flag (S_NOSEC) on the file, which short-circuits these
|
||||
# checks.
|
||||
# This configuration option configures the file system mount to allow the
|
||||
# client to either always check, check once and cache that flag after a first
|
||||
# lookup of the extended attribute returns an empty result, or set the flag on
|
||||
# inode creation and never check. The flag will automatically be cleared when
|
||||
# capabilities are modified on this client. It will, however, currently not
|
||||
# be cleared when a different client modifies capabilities or sets setuid/setgid
|
||||
# bits, which can lead to capabilities not being cleared, even after the file is
|
||||
# written to. If this is a concern, this option should be set to "always".
|
||||
# As long as BeeGFS is mounted using the "nosuid" mount option (which is
|
||||
# recommended and the default setting), elevating privileges via setuid/setgid
|
||||
# bits and capabilities is disabled and it is safe to set this option to "never".
|
||||
# Possible values:
|
||||
# always (always check for security xattr, never cache the result)
|
||||
# cache (check for security xattr once, then cache)
|
||||
# never (mark new inodes immediately, never check security xattr)
|
||||
# Default: never
|
||||
|
||||
# [sysBypassFileAccessCheckOnMeta]
|
||||
# Allow this client to bypass file access restrictions enforced by metadata
|
||||
# servers. When enabled, the client is permitted to open files even if access
|
||||
# restrictions are currently in place (e.g., file marked read-only,
|
||||
# write-locked, or fully restricted). This setting is primarily intended for
|
||||
# specialized clients in controlled environments, such as HSM (Hierarchical
|
||||
# Storage Management) systems that need to restore file data, or backup/recovery
|
||||
# tools that require access to otherwise locked files.
|
||||
# Note: This setting only affects metadata-level access checks and has no effect
|
||||
# on other security or permission mechanisms.
|
||||
# Default: false
|
||||
|
||||
|
||||
# [sysACLsEnabled]
|
||||
# Allow the creation and enforcement of Access Control Lists (ACLs).
|
||||
# Note: Only works if sysXAttrsEnabled=true.
|
||||
# Note: Requires at least Linux kernel version 3.2.
|
||||
# Note: Enabling this setting can affect metadata performance.
|
||||
# Default: false
|
||||
|
||||
# [sysFileEventLogMask]
|
||||
# Specifies which file system events shall be logged by the metadata servers. If
|
||||
# unset, this client doesn't send log events at all. This can either be "none"
|
||||
# or a comma separated list of event types to log. The following event types
|
||||
# (and any comma-separated combination) are possible:
|
||||
# "flush" (explicit data flushes on files), "close" (close writable file),
|
||||
# "trunc" (file truncation), "setattr" (set attributes),
|
||||
# "link-op" (create,mkdir,mknod,create symlink,create hardlink,rmdir,unlink, rename),
|
||||
# "read" (deprecated, see notes) or "open-read" (file opened in read-only mode),
|
||||
# "open-write" (file opened in write only mode),
|
||||
# "open-readwrite" (file opened for both read and write),
|
||||
# Note: If a client opens a file multiple times, "close" will only generate an
|
||||
# event if the last fd is closed. If events for each fd shall be generated,
|
||||
# "flush" needs to be used. However, "flush" might have a small performance
|
||||
# impact. Also note that "read" is deprecated for file opening in read-only mode,
|
||||
# but it is still allowed for backward compatibility. It is recommended to use
|
||||
# "open-read" instead of "read" for clarity and consistency.
|
||||
# Example: sysFileEventLogMask = close,trunc,setattr,link-op,open-read
|
||||
# Default: none
|
||||
|
||||
# [sysRenameEbusyAsXdev]
|
||||
# Changes the semantics of rename() to return an EXDEV error if a file could not
|
||||
# be moved because it is in use (instead of the default EBUSY). Applications and
|
||||
# tools like mv can handle EXDEV and fall back to copy/unlink for the files.
|
||||
# This is mostly useful for NFS exports, where files may not be closed by the
|
||||
# server until after the last open file handle has been closed by clients. This
|
||||
# can cause spurious EBUSY errors in clients that close a file and rename it
|
||||
# immediately afterwards.
|
||||
# Default: false
|
||||
|
||||
|
||||
#
|
||||
# --- Section 4.5: [Tuning] ---
|
||||
#
|
||||
|
||||
# [tuneFileCacheType]
|
||||
# Sets the file read/write cache type.
|
||||
# Values: "none" (disable client caching), "buffered" (use a pool of small
|
||||
# static buffers for write-back and read-ahead), "native" (use the kernel
|
||||
# pagecache), "paged" (experimental, deprecated).
|
||||
# Note: The cache protocols are currently non-coherent (but caches are
|
||||
# automatically flushed when a file is closed).
|
||||
# Note: When client and servers are running on the same machine, "paged" mode
|
||||
# contains the typical potential for memory allocation deadlocks (also known
|
||||
# from local NFS server mounts). So do not use "paged" mode for clients that
|
||||
# run on a metadata or storage server machine.
|
||||
# Default: buffered
|
||||
|
||||
# [tunePreferredMetaFile], [tunePreferredStorageFile]
|
||||
# Path to a text file that contains the numeric IDs of preferred storage targets
|
||||
# and metadata servers. These will be preferred when the client creates new file
|
||||
# system entries. This is useful e.g. to take advantage of data locality in the
|
||||
# case of multiple data centers. If unspecified, all available targets and
|
||||
# servers will be used equally.
|
||||
# Usage: One targetID per line for storage servers, one nodeID per line for
|
||||
# metadata servers.
|
||||
# Note: TargetIDs and nodeIDs can be queried with the beegfs-ctl tool.
|
||||
# Default: <none>
|
||||
|
||||
# [tuneRemoteFSync]
|
||||
# Controls whether fsync() syscalls from a user application should only be
|
||||
# executed on the client to transfer data from the client cache to server
|
||||
# cache (=false); or also on the servers to flush the server's cached file
|
||||
# data to the disks (=true).
|
||||
# Default: true
|
||||
|
||||
# [tuneUseGlobalAppendLocks]
|
||||
# Controls whether files opened in append mode should be protected by locks on
|
||||
# the local machine only (=false) or globally on the servers (=true).
|
||||
# Default: false
|
||||
|
||||
# [tuneUseGlobalFileLocks]
|
||||
# Controls whether application advisory file locks via flock() and fcntl()
|
||||
# should be checked for conflicts on the local machine only (=false) or
|
||||
# globally on the servers (=true).
|
||||
# Default: false
|
||||
|
||||
# [tuneCoherentBuffers]
|
||||
# Enables or disables coherence between the buffers used by
|
||||
# tuneFileCacheType=buffered and the page cache.
|
||||
# If a file is concurrently accessed via mmap() regions and read()/write()
|
||||
# system calls, the buffers used by tuneFileCacheType=buffered and the page
|
||||
# cache used by mmap() may go out of sync - changes made in an mmap()ed region
|
||||
# may not be visible to read() calls immediately, or changes made by write()
|
||||
# calls may not be immediately reflected in mmap()ed regions.
|
||||
# Many programs that use both methods of accessing a file assume that
|
||||
# read()/write() and mmap() present the same view of the file, if this is not
|
||||
# the case, those programs may not work correctly. Programs that have been
|
||||
# observed to misbehave with non-coherent buffers are, for example, git and
|
||||
# some in-memory database applications.
|
||||
# When this option is enabled, files that are currently mmap()ed will behave as
|
||||
# though they had been opened with tuneFileCacheType=none
|
||||
# Default: true
|
||||
|
||||
|
||||
#
|
||||
# --- Section 5: [Expert options]
|
||||
#
|
||||
|
||||
# [connUnmountRetries]
|
||||
# Retry communications during unmount.
|
||||
# If this option is set to `true` and a communication error occurs during
|
||||
# unmont, for example due to a transient network fault, the unsuccessful
|
||||
# communications will be retried normally. When set to `false` they will not be
|
||||
# retried; this leads to a quicker unmount, but resources allocated to current
|
||||
# client will not be freed for a few hours.
|
||||
# Default: true
|
||||
|
||||
# [tuneFileCacheBufSize]
|
||||
# When using buffered mode: maximum size of the (contiguous) data cache for an
|
||||
# open file.
|
||||
# When using native mode: threshold for direct operations. If a read() or
|
||||
# write() passes a buffer size larger than tuneFileCacheBufSize the client will
|
||||
# bypass the page cache and send/receive the data directly to/from the storage
|
||||
# servers.
|
||||
# Default: 524288 (512KiB)
|
||||
|
||||
# [tuneFileCacheBufNum]
|
||||
# When using buffered mode: maximum number of file caches to preallocate
|
||||
# for the mount. When a file is opened a cache is allocated, up to this number.
|
||||
# If the maximum number of caches is reached no cache is allocated and all
|
||||
# read/write operations for the file go to the storage servers directly.
|
||||
# Default: 4*(number of CPUs)
|
||||
|
||||
# [tunePageCacheValidityMS]
|
||||
# Maximum lifetime of cached data in the page cache.
|
||||
# In buffered mode the page cache is used for mmap(), in native mode the page
|
||||
# cache is used for all data. Data in the page cache that was not yet written
|
||||
# to the storage server is written after at most this time, data that was read
|
||||
# but not modified is discarded.
|
||||
# Default: 2000000000 (approx. 23 days)
|
||||
|
||||
# [tuneDirSubentryCacheValidityMS]
|
||||
# Validity time of directory attribute data, in milliseconds.
|
||||
# Attributes of directories (eg stat() data) that have been loaded from the
|
||||
# metadata servers are assumed to be valid for this amount of time without
|
||||
# requiring a refresh. Once the time has passed the next access will cause a
|
||||
# refresh.
|
||||
# Default: 1000
|
||||
|
||||
# [tuneFileSubentryCacheValidityMS]
|
||||
# Validity time of file attribute data, in milliseconds.
|
||||
# Attributes of files (eg stat() data) that have been loaded from the metadata
|
||||
# servers are assumed to be valid for this amount of time without requiring a
|
||||
# refresh. Once the time has passed the next access will cause a refresh.
|
||||
# Default: 0
|
||||
|
||||
# [tuneENOENTCacheValidityMS]
|
||||
# Validity time of the non-existing file in milliseconds.
|
||||
# A negative result of a stat call indicating "No such file or directory"
|
||||
# (ENOENT) is assumed to be valid for this amount of time without requiring a
|
||||
# new request to the meta server. Once the time has passed the next access will
|
||||
# cause a refresh.
|
||||
# Default: 0
|
||||
|
||||
# [tunePathBufSize]
|
||||
# Size of buffers used for constructing paths.
|
||||
# Whenever a full path must be constructed (eg for log messages) a preallocated
|
||||
# buffer of this size will be used.
|
||||
# Default: 4096
|
||||
|
||||
# [tunePathBufNum]
|
||||
# Number of path buffers for path construction.
|
||||
# Determines how many path buffers are preallocated during mount. If no buffers
|
||||
# are available for an operation the operation must wait for another thread to
|
||||
# free enough buffers.
|
||||
# Default: 8
|
||||
|
||||
# [tuneMsgBufSize]
|
||||
# Size of buffers used for messaging.
|
||||
# Messages sent and received by the client (except logging messages) use
|
||||
# buffers preallocated at mount time. Buffers are allocated with the size
|
||||
# given here.
|
||||
# Default: 65536
|
||||
|
||||
# [tuneMsgBufNum]
|
||||
# Number of message buffers.
|
||||
# During mount this many message buffers are preallocated. If an operation
|
||||
# requires communication with a server but all buffers are used, the operation
|
||||
# must wait until a buffer is released.
|
||||
# Default: 4*(number of CPUs) + 1
|
||||
|
||||
# [tuneRefreshOnGetAttr]
|
||||
# If set to `true`, file attributes will be loaded from the server on each call
|
||||
# to fstat(). When set to `false` a call to fstat() may return stale
|
||||
# information for files that are not currently open; this can happen mainly
|
||||
# when NFS exports are used.
|
||||
# Default: false
|
||||
|
||||
# [tuneInodeBlockBits]
|
||||
# Sets the block size of file on the mountpoint to 2**tuneInodeBlockBits.
|
||||
# Default: 19 (512KiB)
|
||||
|
||||
# [tuneEarlyCloseResponse]
|
||||
# Request close responses from the metadata server before the file is fully closed.
|
||||
# This may improve close() performance, but closed files may be accounted as
|
||||
# open for a short time after close() has returned. Files accounted as open
|
||||
# cannot be moved.
|
||||
# Default: false
|
||||
|
||||
# [tuneUseBufferedAppend]
|
||||
# Used only buffered mode. If set, writes to files opened with O_APPEND will be
|
||||
# cached. Ignored unless tuneUseGlobalAppendLocks is also set.
|
||||
# Default: true
|
||||
|
||||
# [tuneStatFsCacheSecs]
|
||||
# Validity time of statfs() results, in seconds.
|
||||
# Results of statfs(), once queried from the storage servers, will be cached
|
||||
# for this amount of time.
|
||||
# Default: 10
|
||||
|
||||
# [sysInodeIDStyle]
|
||||
# Sets the hash function used to compute inode numbers from metadata IDs.
|
||||
# The *32 options produce 32 bit inodes numbers, the *64 variants produce 64
|
||||
# bit inode numbers.
|
||||
# Possible values:
|
||||
# hash32
|
||||
# hash64
|
||||
# md4hash32
|
||||
# md4hash64
|
||||
# Default: md4hash64
|
||||
1
client_module/build/dist/etc/beegfs-mounts.conf
vendored
Normal file
1
client_module/build/dist/etc/beegfs-mounts.conf
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/mnt/beegfs /etc/beegfs/beegfs-client.conf
|
||||
26
client_module/build/dist/etc/default/beegfs-client
vendored
Normal file
26
client_module/build/dist/etc/default/beegfs-client
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# BeeGFS client service configuration.
|
||||
|
||||
# Set to "NO" to disable start of the BeeGFS client via the init script.
|
||||
START_SERVICE="YES"
|
||||
|
||||
# Set to "YES" if you want to start multiple clients with different
|
||||
# configuration files on this machine.
|
||||
#
|
||||
# Create a subdirectory with the ending ".d" in "/etc/beegfs/" for every config
|
||||
# file. The subdirectory name will be used to identify a particular client
|
||||
# instance for init script start/stop.
|
||||
#
|
||||
# Note: The original config file in /etc/beegfs will not be used when multi-mode
|
||||
# is enabled.
|
||||
#
|
||||
# Example: /etc/beegfs/scratch.d/beegfs-client.conf
|
||||
# $ /etc/init.d/beegfs-client start scratch
|
||||
MULTI_MODE="NO"
|
||||
|
||||
# Mount hook will be executed before any mount or unmount operation,
|
||||
# and additionally after the operation succeeded.
|
||||
# The first argument passed is either 'pre-mount', 'post-mount', 'pre-unmount',
|
||||
# or 'post-unmount'.
|
||||
# The second argument is the mount point. This can be useful to set up bind
|
||||
# mounts on top of a BeeGFS, for example.
|
||||
#MOUNT_HOOK=/etc/beegfs/beegfs-client-mount-hook.example
|
||||
439
client_module/build/dist/sbin/beegfs-client.init
vendored
Normal file
439
client_module/build/dist/sbin/beegfs-client.init
vendored
Normal file
@@ -0,0 +1,439 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NOTE: We expclicitly use "bash" here, as rc.status is not shell compliant
|
||||
# and will complain with the message below, if "/bin/sh" is given
|
||||
#
|
||||
# /etc/rc.status: line 43: test: -eq: unary operator expected
|
||||
# /etc/rc.status: line 44: test: -eq: unary operator expected
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: beegfs-client
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start: $network $local_fs $syslog $time beegfs-helperd beegfs-mgmtd beegfs-meta beegfs-storage openib openibd rdma opensmd opensm $named slapd autofs ypbind nscd nslcd sshd
|
||||
# Should-Stop: $network $local_fs $syslog $time beegfs-helperd beegfs-mgmtd beegfs-meta beegfs-storage openib openibd rdma opensmd opensm $named slapd autofs ypbind nscd nslcd sshd
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# chkconfig: 35 99 5
|
||||
# Short-Description: BeeGFS Client
|
||||
# Description: Start BeeGFS Client
|
||||
### END INIT INFO
|
||||
|
||||
SERVICE_NAME="BeeGFS Client"
|
||||
|
||||
# Check for missing binaries (stale symlinks should not happen)
|
||||
# Note: Special treatment of stop for LSB conformance
|
||||
CLIENT_MOD=beegfs
|
||||
|
||||
SYSCONFIG_FILE=/etc/default/beegfs-client
|
||||
BEEGFS_MOUNT_CONF="/etc/beegfs/beegfs-mounts.conf"
|
||||
FORCE_AUTO_BUILD="/var/lib/beegfs/client/force-auto-build"
|
||||
SUBSYS=/var/lock/subsys/beegfs-client
|
||||
|
||||
AUTOBUILD_CONF="/etc/beegfs/beegfs-client-autobuild.conf"
|
||||
AUTOBUILD_CONF_SAVED="/var/lib/beegfs/client/beegfs-client-autobuild.conf.old"
|
||||
|
||||
CLIENT_SRC_PATH="/opt/beegfs/src/client"
|
||||
|
||||
SELINUX_OPT=""
|
||||
|
||||
DEFAULT_FS_TYPE="beegfs"
|
||||
BUILD_FSTYPE_FILE="beegfs.fstype"
|
||||
|
||||
# we add "/usr/sbin" & co because "su" doesn't automatically add them
|
||||
# on some systems.
|
||||
EXTRA_PATH="/sbin:/usr/sbin/:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin"
|
||||
PATH="$EXTRA_PATH:$PATH"
|
||||
|
||||
# source function library
|
||||
. /etc/beegfs/lib/init-multi-mode.beegfs-client
|
||||
|
||||
# Return values acc. to LSB for all commands but status:
|
||||
# 0 - success
|
||||
# 1 - generic or unspecified error
|
||||
# 2 - invalid or excess argument(s)
|
||||
# 3 - unimplemented feature (e.g. "reload")
|
||||
# 4 - user had insufficient privileges
|
||||
# 5 - program is not installed
|
||||
# 6 - program is not configured
|
||||
# 7 - program is not running
|
||||
# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
|
||||
#
|
||||
# Note that starting an already running service, stopping
|
||||
# or restarting a not-running service as well as the restart
|
||||
# with force-reload (in case signaling is not supported) are
|
||||
# considered a success.
|
||||
|
||||
handle_selinux()
|
||||
{
|
||||
selinuxenabled 2>/dev/null || return
|
||||
|
||||
# we do not support SELINUX right now and it only causes trouble, so
|
||||
# we try to deactivate it
|
||||
SELINUX_OPT="fscontext=system_u:object_r:tmp_t:s0"
|
||||
|
||||
echo
|
||||
echo "WARNING: SELINUX IS ENABLED. BeeGFS might not work!"
|
||||
echo " Before you consider to contact BeeGFS support, please try to"
|
||||
echo " disable selinux (Usually in /etc/selinux/config)!"
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
rmmod_beegfs()
|
||||
{
|
||||
for module in `lsmod |egrep "^beegfs" | sed -e 's/\s.*$//g'`; do rmmod $module; done
|
||||
}
|
||||
|
||||
# Build beegfs. The autobuild will install modules to
|
||||
# /lib/modules/`uname -r`/updates/fs/beegfs_autobuild
|
||||
# if the build was successful and it will also run depmod.
|
||||
build_beegfs()
|
||||
{
|
||||
echo "- BeeGFS module autobuild"
|
||||
|
||||
mkdir -p `dirname $SUBSYS`
|
||||
|
||||
# locked section (to avoid build problems when this script is called from
|
||||
# multiple processes concurrently)
|
||||
(
|
||||
# (note: fd 16 is a more or less arbitrary number)
|
||||
flock 16 || echo "WARNING: flock for build failed (continuing without lock...)" >&2
|
||||
|
||||
|
||||
for dir in ${CLIENT_SRC_PATH}/*; do
|
||||
|
||||
set +e
|
||||
echo $dir | grep opentk >/dev/null 2>&1
|
||||
[ $? -ne 0 ] || continue # we ignore opentk
|
||||
|
||||
# ingore paths with missing Makfile
|
||||
[ -f ${dir}/build/Makefile ] || continue
|
||||
|
||||
|
||||
if [ -f ${dir}/build/${BUILD_FSTYPE_FILE} ]; then
|
||||
fstype=`cat ${dir}/build/${BUILD_FSTYPE_FILE}`
|
||||
TARGET_PARAM="TARGET=${fstype}"
|
||||
else
|
||||
TARGET_PARAM=""
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
MAKE_ARGS="KMOD_INST_DIR=/lib/modules/$(uname -r)/updates/fs/beegfs_autobuild"
|
||||
make -C ${dir}/build auto_rebuild_configured ${MAKE_ARGS} ${TARGET_PARAM} --silent
|
||||
make -C ${dir}/build clean ${MAKE_ARGS} --silent # always clean up
|
||||
|
||||
done
|
||||
|
||||
set -e # ensure -e here (continue conditions above didn't restore it)
|
||||
|
||||
install -D $AUTOBUILD_CONF $AUTOBUILD_CONF_SAVED
|
||||
) 16>$SUBSYS.init-autobuild
|
||||
|
||||
|
||||
# we do not want to delete the $FORCE_AUTO_BUILD file here yet,
|
||||
# as we do not test here, if the modules we just built will load at all
|
||||
}
|
||||
|
||||
# Test if the user updated the build config. If so, we touch
|
||||
# the $FORCE_AUTO_BUILD, which will trigger a rebuild
|
||||
test_updated_autobuild_conf()
|
||||
{
|
||||
set +e
|
||||
RC=0
|
||||
# diskless installations might not have those files
|
||||
if [ -e $AUTOBUILD_CONF -a -e $AUTOBUILD_CONF_SAVED ]; then
|
||||
diff $AUTOBUILD_CONF $AUTOBUILD_CONF_SAVED >/dev/null 2>&1
|
||||
RC=$?
|
||||
fi
|
||||
[ $RC -eq 0 ] || touch $FORCE_AUTO_BUILD
|
||||
set -e
|
||||
}
|
||||
|
||||
# Test and warn if user specified OFED_INCLUDE_PATH but appears to use in-tree
|
||||
# drivers or other way around.
|
||||
warn_on_ofed_mismatch()
|
||||
{
|
||||
set +e
|
||||
|
||||
modinfo ib_core > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# "modinfo ib_core" not working => cancel (because the user
|
||||
# might have special mechanisms to load ib modules).
|
||||
set -e
|
||||
return
|
||||
fi
|
||||
|
||||
# ibverbs enabled => check if include path set or not
|
||||
|
||||
grep '^buildArgs.*OFED_INCLUDE_PATH' $AUTOBUILD_CONF > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
# ofed include path specified => warn if in-tree modules used
|
||||
modinfo ib_core | grep 'filename:.*updates/' > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "WARNING: You probably should not specify OFED_INCLUDE_PATH in $AUTOBUILD_CONF"
|
||||
fi
|
||||
else
|
||||
# no ofed include path specified => warn if out-of-tree modules
|
||||
modinfo ib_core | grep 'filename:.*updates/' > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "WARNING: You probably need to specify" \
|
||||
"OFED_INCLUDE_PATH in $AUTOBUILD_CONF"
|
||||
fi
|
||||
fi
|
||||
|
||||
set -e
|
||||
}
|
||||
|
||||
source ${SYSCONFIG_FILE}
|
||||
if [ "${MULTI_MODE}" = "YES" -o "${MULTI_MODE}" = "yes" ]; then
|
||||
set +e
|
||||
init_multi_mode $1 $2
|
||||
exit $?
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
case "$1" in
|
||||
start)
|
||||
if [ -f "${SYSCONFIG_FILE}" ]; then
|
||||
if [ "${START_SERVICE}" = "NO" -o "${START_SERVICE}" = "no" ]; then
|
||||
echo "${SERVICE_NAME} not set to be started"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
set +e
|
||||
handle_selinux
|
||||
set -e
|
||||
|
||||
echo "Starting ${SERVICE_NAME}: "
|
||||
|
||||
test_updated_autobuild_conf
|
||||
|
||||
set +e
|
||||
echo "- Loading BeeGFS modules"
|
||||
if [ -f "$FORCE_AUTO_BUILD" ]; then
|
||||
# a new version was installed or the user updated the
|
||||
# auto-build config, so we force a rebuild
|
||||
rmmod_beegfs
|
||||
rc=1
|
||||
else
|
||||
modprobe $CLIENT_MOD
|
||||
rc=$?
|
||||
fi
|
||||
|
||||
if [ $rc -ne 0 ]; then
|
||||
set -e
|
||||
build_beegfs
|
||||
modprobe $CLIENT_MOD || (warn_on_ofed_mismatch && false)
|
||||
rm -f $FORCE_AUTO_BUILD
|
||||
fi
|
||||
set -e
|
||||
|
||||
echo "- Mounting directories from $BEEGFS_MOUNT_CONF"
|
||||
|
||||
mkdir -p `dirname $SUBSYS`
|
||||
touch $SUBSYS
|
||||
|
||||
OLDIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
file=`tr -d '\r' < $BEEGFS_MOUNT_CONF` # read all lines at once and remove CR from dos files
|
||||
for line in $file; do
|
||||
if [ -z "$line" ]; then
|
||||
continue # ignore empty line
|
||||
elif echo "$line" | grep -qs "^\s*#" ; then
|
||||
continue # ignore shell style comments
|
||||
fi
|
||||
|
||||
mnt=`echo $line | awk '{print $1}'`
|
||||
cfg=`echo $line | awk '{print $2}'`
|
||||
fstype=`echo $line | awk '{print $3}'`
|
||||
extra_mount_opts=`echo $line | awk '{print $4}'`
|
||||
|
||||
if [ -z "$mnt" -o -z "$cfg" ]; then
|
||||
echo "Invalid config line: \"$line\""
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "$fstype" ]; then
|
||||
fstype=${DEFAULT_FS_TYPE}
|
||||
fi
|
||||
|
||||
set +e
|
||||
|
||||
mount -t ${fstype} | grep "${mnt} " >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
# already mounted
|
||||
set -e
|
||||
continue
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# mkdir required for admon-based installation
|
||||
if [ ! -e ${mnt} ]; then
|
||||
mkdir -p ${mnt}
|
||||
fi
|
||||
|
||||
exec_mount_hook pre-mount "${mnt}"
|
||||
|
||||
mount -t ${fstype} beegfs_nodev ${mnt} \
|
||||
-ocfgFile=${cfg},_netdev,nosuid,${SELINUX_OPT},${extra_mount_opts}
|
||||
|
||||
exec_mount_hook post-mount "${mnt}"
|
||||
|
||||
done
|
||||
|
||||
RETVAL=$?
|
||||
IFS="$OLDIFS"
|
||||
;;
|
||||
stop)
|
||||
echo "Shutting down ${SERVICE_NAME}: "
|
||||
|
||||
RETVAL=$?
|
||||
echo "- Unmounting directories from $BEEGFS_MOUNT_CONF"
|
||||
OLDIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
file=`cat $BEEGFS_MOUNT_CONF` # we have to read all lines at once
|
||||
for line in $file; do
|
||||
if [ -z "$line" ]; then
|
||||
continue # ignore empty line
|
||||
elif echo "$line" | grep -qs "^\s*#" ; then
|
||||
continue # ignore shell style comments
|
||||
fi
|
||||
|
||||
mnt=`echo $line | awk '{print $1}'`
|
||||
cfg=`echo $line | awk '{print $2}'`
|
||||
if [ -z "$mnt" -o -z "$cfg" ]; then
|
||||
echo "Invalid config line: \"$line\""
|
||||
continue
|
||||
fi
|
||||
|
||||
exec_mount_hook pre-unmount "${mnt}"
|
||||
|
||||
set +e
|
||||
res=`umount ${mnt} 2>&1`
|
||||
if [ $? -ne 0 ]; then
|
||||
# umount failed, ignore the failure if not mounted at all
|
||||
echo $res | grep "not mounted" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# Is mounted, abort.
|
||||
echo "umount failed: $res"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
|
||||
exec_mount_hook post-unmount "${mnt}"
|
||||
|
||||
done
|
||||
IFS="$OLDIFS"
|
||||
|
||||
echo "- Unloading modules"
|
||||
set +e
|
||||
res=`rmmod_beegfs`
|
||||
if [ $? -ne 0 ]; then
|
||||
# rmmod failed, ignore it if the module is not loaded at all
|
||||
echo $res | grep "does not exist in" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# Is loaded, check if a BeeGFS is still mounted (all from the list are unmounted, so
|
||||
# it must be a BeeGFS, which was manually mounted)
|
||||
STILL_MOUNTED=$(mount -t beegfs | wc -l)
|
||||
if [ ${STILL_MOUNTED} -eq 0 ]; then
|
||||
# no more BeeGFS instances, no reason why rmmod should be failing, abort
|
||||
echo "rmmod failed: $res"
|
||||
exit 1
|
||||
else
|
||||
# BeeGFS instances mounted, so failure to rmmod is normal
|
||||
echo "WARNING: Unloading BeeGFS modules failed. There are still mounted BeeGFS" \
|
||||
"instances, which do not seem to be managed by the init-script mechanism" \
|
||||
"(beegfs-mounts.conf)."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
RETVAL=$?
|
||||
set -e
|
||||
|
||||
if [ $RETVAL -eq 0 ]; then rm -f $SUBSYS; fi
|
||||
# Remember status and be verbose
|
||||
;;
|
||||
restart)
|
||||
## Stop the service and regardless of whether it was
|
||||
## running or not, start it again.
|
||||
$0 stop
|
||||
$0 start
|
||||
RETVAL=$?
|
||||
# Remember status and be quiet
|
||||
;;
|
||||
rebuild)
|
||||
# Just rebuild modules. The user needs to call "restart" to make use
|
||||
# of those new modules.
|
||||
build_beegfs
|
||||
RETVAL=$?
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
rm -f $FORCE_AUTO_BUILD
|
||||
fi
|
||||
;;
|
||||
try-restart|condrestart)
|
||||
## Do a restart only if the service was active before.
|
||||
## Note: try-restart is now part of LSB (as of 1.9).
|
||||
## RH has a similar command named condrestart.
|
||||
set +e
|
||||
$0 status
|
||||
if test $? = 0
|
||||
then
|
||||
set -e
|
||||
$0 restart
|
||||
RETVAL=$?
|
||||
else
|
||||
set -e
|
||||
RETVAL=7
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
# Return value is slightly different for the status command:
|
||||
# 0 - service up and running
|
||||
# 1 - service dead, but /var/run/ pid file exists
|
||||
# 2 - service dead, but /var/lock/ lock file exists
|
||||
# 3 - service not running (unused)
|
||||
# 4 - service status unknown :-(
|
||||
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
|
||||
set +e
|
||||
|
||||
echo -n "Checking for service $SERVICE_NAME: "
|
||||
|
||||
lsmod | grep $CLIENT_MOD >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "is running..."
|
||||
|
||||
mount -t beegfs | grep beegfs >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
mount -t beegfs | cut "-d " -f1-3
|
||||
echo
|
||||
RETVAL=0
|
||||
else
|
||||
echo ">> No active beegfs mounts detected."
|
||||
echo
|
||||
RETVAL=4
|
||||
fi
|
||||
else
|
||||
echo "is stopped."
|
||||
echo
|
||||
RETVAL=3
|
||||
fi
|
||||
|
||||
set -e
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|rebuild|condrestart|try-restart}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
||||
|
||||
128
client_module/build/dist/sbin/beegfs-setup-client
vendored
Executable file
128
client_module/build/dist/sbin/beegfs-setup-client
vendored
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
|
||||
# License: BeeGFS EULA
|
||||
|
||||
# constant definitions
|
||||
# (for configurables see below)
|
||||
|
||||
DEFAULT_CFG_PATH="/etc/beegfs/beegfs-client.conf"
|
||||
MGMTD_CFG_KEY="sysMgmtdHost"
|
||||
QUOTA_ENABLED_CFG_KEY="quotaEnabled"
|
||||
|
||||
print_usage()
|
||||
{
|
||||
echo
|
||||
echo "DESCRIPTION: Initialize or update the beegfs-client config file."
|
||||
echo
|
||||
echo "USAGE: `basename $0` [options]"
|
||||
echo
|
||||
echo " Recommended Options:"
|
||||
echo
|
||||
echo " -m <host> - Hostname (or IP address) of management server."
|
||||
echo " (Will be stored in client config file.)"
|
||||
echo
|
||||
echo " Other Options:"
|
||||
echo
|
||||
echo " -C - Do not update client config file."
|
||||
echo
|
||||
echo " -c <path> - Path to client config file."
|
||||
echo " (Default: ${DEFAULT_CFG_PATH})"
|
||||
echo
|
||||
echo " -f - Force actions, ignore warnings."
|
||||
echo
|
||||
echo " -h - Print this help."
|
||||
echo
|
||||
echo " -q - Enable quota support in config file."
|
||||
echo " (Default: Quota support disabled)"
|
||||
echo
|
||||
echo "EXAMPLES:"
|
||||
echo " * Example 1) Set \"storage01\" as management daemon host in config file:"
|
||||
echo " $ `basename $0` -m storage01"
|
||||
echo
|
||||
}
|
||||
|
||||
# update config file (if enabled)
|
||||
update_config_file()
|
||||
{
|
||||
# check if config file is defined
|
||||
|
||||
if [ -z "${CFG_PATH}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Updating config file: ${CFG_PATH}"
|
||||
|
||||
if [ ! -f "${CFG_PATH}" ]; then
|
||||
echo " * ERROR: Config file not found: ${CFG_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${MGMTD_HOST}" ]; then
|
||||
echo " * Setting management host: ${MGMTD_HOST}"
|
||||
sed -i "s/\(^${MGMTD_CFG_KEY}.*=\).*/\1 ${MGMTD_HOST}/" ${CFG_PATH}
|
||||
fi
|
||||
|
||||
if [ -n "${QUOTA_ENABLED}" ]; then
|
||||
echo " * Setting quota enabled: ${QUOTA_ENABLED}"
|
||||
sed -i "s/\(^${QUOTA_ENABLED_CFG_KEY}.*=\).*/\1 ${QUOTA_ENABLED}/" ${CFG_PATH}
|
||||
fi
|
||||
}
|
||||
|
||||
################## end of function definitions ##############
|
||||
|
||||
|
||||
# configurable values and their defaults
|
||||
# (for constants see above)
|
||||
|
||||
CFG_PATH="$DEFAULT_CFG_PATH" # empty path means "don't update cfg file"
|
||||
FORCE_ACTIONS=""
|
||||
MGMTD_HOST=""
|
||||
QUOTA_ENABLED=""
|
||||
|
||||
# parse command line arguments
|
||||
# (see print_usage() for description of parameters)
|
||||
|
||||
while getopts "Cc:fhm:q" opt; do
|
||||
case $opt in
|
||||
C)
|
||||
CFG_PATH=""
|
||||
;;
|
||||
c)
|
||||
CFG_PATH="$OPTARG"
|
||||
;;
|
||||
f)
|
||||
FORCE_ACTIONS="1"
|
||||
;;
|
||||
h)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
m)
|
||||
MGMTD_HOST="$OPTARG"
|
||||
;;
|
||||
q)
|
||||
QUOTA_ENABLED="true"
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Invalid argument" >&2
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
set -e
|
||||
|
||||
# don't do anything if no arguments are provided
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# update config file
|
||||
|
||||
update_config_file
|
||||
|
||||
|
||||
echo "All done."
|
||||
94
client_module/build/dist/sbin/mount.beegfs
vendored
Executable file
94
client_module/build/dist/sbin/mount.beegfs
vendored
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# BeeGFS Client Mount Utility / External Mount Helper
|
||||
# If placed in /sbin, this script is called automatically by `mount` whenever a filesystem with type
|
||||
# `beegfs` is being mounted. It's main purpose is to do name resolution of the management hostname
|
||||
# as the kernel module can't do that by itself. The hostname is taken from either the mount option
|
||||
# string itself ('sysMgmtdHost=') or from the config file given by the mount options ('cfgFile=').
|
||||
|
||||
function usage() {
|
||||
echo "Usage: $(basename "$0") <fs_name> <directory> [-sfnv] [-o options]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
SPEC="$1"
|
||||
shift
|
||||
DIR="$1"
|
||||
shift
|
||||
|
||||
[[ -n "$SPEC" && -n "$DIR" ]] || usage
|
||||
|
||||
FLAGS=
|
||||
OPTIONS=
|
||||
|
||||
# Read in all possible flags (see `man mount 8`)
|
||||
while getopts 'hsfnvo:t:' FLAG; do
|
||||
case "$FLAG" in
|
||||
s|f|n|v)
|
||||
FLAGS+=("-$FLAG")
|
||||
;;
|
||||
o)
|
||||
OPTIONS="$OPTARG"
|
||||
;;
|
||||
h|*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# If there is a config file available and sysMgmtdHost is set, load the management hostname from the
|
||||
# config file
|
||||
CFG_FILE=$(echo "$OPTIONS" | grep -oP 'cfgFile=[^,]+' | cut -d= -f2)
|
||||
|
||||
if [[ -n "$CFG_FILE" ]]; then
|
||||
[[ -f "$CFG_FILE" ]] || {
|
||||
echo "Can not open config file '$CFG_FILE'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
H=$(grep -oP '^\s*sysMgmtdHost\s*=\s*\S+\s*$' "$CFG_FILE" | tr -d ' ' | cut -d= -f2)
|
||||
if [[ $H == *$'\n'* ]]; then
|
||||
echo "Multiple definitions of 'sysMgmtdHost' found in '$CFG_FILE'."
|
||||
exit 1
|
||||
elif [[ -n "$H" ]]; then
|
||||
HOST_NAME="$H"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If it has explicitly been set as a mount option, use that (overrides config file).
|
||||
HOST_NAME_OPTION=$(echo "$OPTIONS" | grep -oP 'sysMgmtdHost=[^,]+' | cut -d= -f2)
|
||||
if [[ -n "$HOST_NAME_OPTION" ]]; then
|
||||
HOST_NAME="$HOST_NAME_OPTION"
|
||||
fi
|
||||
|
||||
# A management host must be provided
|
||||
[[ -n "$HOST_NAME" ]] || {
|
||||
echo "Can not determine management host - neither through a mount option ('sysMgmtdHost') nor through \
|
||||
a client config file ('cfgFile')."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Resolve management address
|
||||
MGMTD_ADDR=$(getent ahostsv4 "$HOST_NAME" | cut -f1 -d' ' | head -n1)
|
||||
|
||||
# If resolve fails, error out
|
||||
[[ -n "$MGMTD_ADDR" ]] || {
|
||||
echo "Can not resolve management host address using hostname '$HOST_NAME'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# If the host argument was given, replace it with the resolved address, otherwise append
|
||||
if [[ -n "$HOST_NAME_OPTION" ]]; then
|
||||
# shellcheck disable=SC2001
|
||||
OPTIONS=$(echo "$OPTIONS" | sed "s/sysMgmtdHost=[^,]\\+/sysMgmtdHost=$MGMTD_ADDR/g")
|
||||
else
|
||||
OPTIONS="$OPTIONS,sysMgmtdHost=$MGMTD_ADDR"
|
||||
fi
|
||||
|
||||
# Take the part behind the "." as fstype (typically "beegfs"). This allows multiple mount utilities
|
||||
# and client modules being installed at the same time.
|
||||
FS_TYPE=$(basename "$0" | sed 's/^.*\.//')
|
||||
|
||||
set -ex
|
||||
mount --internal -t "$FS_TYPE" --source "$SPEC" --target "$DIR" ${FLAGS[*]} -o"$OPTIONS"
|
||||
21
client_module/build/dist/usr/lib/systemd/system/beegfs-client.service
vendored
Normal file
21
client_module/build/dist/usr/lib/systemd/system/beegfs-client.service
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Start BeeGFS Client
|
||||
Requires=network-online.target
|
||||
# We disable the wants service, because it spams the log files
|
||||
#Wants=local-fs.target time-sync.target beegfs-mgmtd.service \
|
||||
#beegfs-meta.service beegfs-storage.service openib.service openibd.service rdma.service \
|
||||
#opensmd.service opensm.service nss-lookup.target nss-user-lookup.target slapd.service \
|
||||
#autofs.service ypbind.service nscd.service nslcd.service sshd.service
|
||||
After=network-online.target local-fs.target time-sync.target \
|
||||
beegfs-mgmtd.service beegfs-meta.service beegfs-storage.service openib.service openibd.service \
|
||||
rdma.service opensmd.service opensm.service nss-lookup.target nss-user-lookup.target \
|
||||
slapd.service autofs.service ypbind.service nscd.service nslcd.service sshd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/opt/beegfs/sbin/beegfs-client start
|
||||
ExecStop=/opt/beegfs/sbin/beegfs-client stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
21
client_module/build/dist/usr/lib/systemd/system/beegfs-client@.service
vendored
Normal file
21
client_module/build/dist/usr/lib/systemd/system/beegfs-client@.service
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Start BeeGFS Client
|
||||
Requires=network-online.target
|
||||
# We disable the wants service, because it spams the log files
|
||||
#Wants=local-fs.target time-sync.target beegfs-mgmtd.service \
|
||||
#beegfs-meta.service beegfs-storage.service openib.service openibd.service rdma.service \
|
||||
#opensmd.service opensm.service nss-lookup.target nss-user-lookup.target slapd.service \
|
||||
#autofs.service ypbind.service nscd.service nslcd.service sshd.service
|
||||
After=network-online.target local-fs.target time-sync.target \
|
||||
beegfs-mgmtd.service beegfs-meta.service beegfs-storage.service openib.service openibd.service \
|
||||
rdma.service opensmd.service opensm.service nss-lookup.target nss-user-lookup.target \
|
||||
slapd.service autofs.service ypbind.service nscd.service nslcd.service sshd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/opt/beegfs/sbin/beegfs-client start %I
|
||||
ExecStop=/opt/beegfs/sbin/beegfs-client stop %I
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
478
client_module/build/feature-detect.sh
Executable file
478
client_module/build/feature-detect.sh
Executable file
@@ -0,0 +1,478 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# NOTE, we're using the argument array as part of this string here. As is
|
||||
# often the case in shell scripts (especially when used with Makefiles) the
|
||||
# quoting here is not correct in the sense that it can be broken for example
|
||||
# with arguments that contain spaces. But it is expected to work with our input
|
||||
# data.
|
||||
|
||||
CFLAGS="-D__KERNEL__ $LINUXINCLUDE $* -DKBUILD_BASENAME=\"beegfs\" -DKBUILD_MODNAME=\"beegfs\""
|
||||
|
||||
_generate_includes() {
|
||||
for i in "$@"; do
|
||||
echo "#include <$i>"
|
||||
done
|
||||
}
|
||||
|
||||
_marker_if_compiles() {
|
||||
local marker=$1
|
||||
shift
|
||||
|
||||
if $CC $CFLAGS -x c -o /dev/null -c - 2>/dev/null
|
||||
then
|
||||
echo -D$marker
|
||||
fi
|
||||
}
|
||||
|
||||
_check_type_input() {
|
||||
local tp=$1
|
||||
shift 1
|
||||
|
||||
_generate_includes "$@"
|
||||
|
||||
cat <<EOF
|
||||
void want_tp(void) {
|
||||
$tp name;
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
check_type() {
|
||||
local tp=$1
|
||||
local marker=$2
|
||||
shift 2
|
||||
|
||||
_check_type_input "$tp" "$@" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
_check_struct_field_input() {
|
||||
local field=$1
|
||||
shift 1
|
||||
|
||||
_generate_includes "$@"
|
||||
|
||||
cat <<EOF
|
||||
void want_symbol(void) {
|
||||
struct ${field%%::*} s;
|
||||
(void) (s.${field##*::});
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
check_struct_field() {
|
||||
local field=$1
|
||||
local marker=$2
|
||||
shift 2
|
||||
|
||||
_check_struct_field_input "$field" "$@" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
_check_struct_field_type_input() {
|
||||
local field=$1
|
||||
local ftype=$2
|
||||
shift 2
|
||||
|
||||
_generate_includes "$@"
|
||||
|
||||
cat <<EOF
|
||||
void want_symbol(void) {
|
||||
struct ${field%%::*} s;
|
||||
char predicate[
|
||||
2 * __builtin_types_compatible_p(__typeof(s.${field##*::}), $ftype) - 1
|
||||
];
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
check_struct_field_type() {
|
||||
local field=$1
|
||||
local ftype=$2
|
||||
local marker=$3
|
||||
shift 3
|
||||
|
||||
_check_struct_field_type_input "$field" "$ftype" "$@" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
_check_expr_type_input() {
|
||||
local name=$1
|
||||
local signature=$2
|
||||
shift 2
|
||||
|
||||
_generate_includes "$@"
|
||||
cat <<EOF
|
||||
void want_fn(void) {
|
||||
char predicate[
|
||||
2 * __builtin_types_compatible_p(__typeof($name), $signature) - 1
|
||||
];
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
check_expr_type() {
|
||||
local name=$1
|
||||
local signature=$2
|
||||
local marker=$3
|
||||
shift 3
|
||||
|
||||
_check_expr_type_input "$name" "$signature" "$@" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
check_function() {
|
||||
check_expr_type "$@"
|
||||
}
|
||||
|
||||
_check_symbol_input() {
|
||||
local name=$1
|
||||
shift
|
||||
|
||||
_generate_includes "$@"
|
||||
cat <<EOF
|
||||
__typeof__($name) predicate = $name;
|
||||
EOF
|
||||
}
|
||||
|
||||
check_header() {
|
||||
local header=$1
|
||||
local marker=$2
|
||||
shift 2
|
||||
|
||||
_generate_includes "$header" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
check_symbol() {
|
||||
local name=$1
|
||||
local marker=$2
|
||||
shift 2
|
||||
|
||||
_check_symbol_input "$name" "$@" | _marker_if_compiles "$marker"
|
||||
}
|
||||
|
||||
check_struct_field \
|
||||
inode::i_ctime \
|
||||
KERNEL_HAS_INODE_CTIME \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field \
|
||||
inode::i_mtime \
|
||||
KERNEL_HAS_INODE_MTIME \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field \
|
||||
dentry::d_subdirs \
|
||||
KERNEL_HAS_DENTRY_SUBDIRS \
|
||||
linux/dcache.h
|
||||
|
||||
check_function \
|
||||
generic_readlink "int (struct dentry *, char __user *, int)" \
|
||||
KERNEL_HAS_GENERIC_READLINK \
|
||||
linux/fs.h
|
||||
|
||||
check_header \
|
||||
linux/sched/signal.h \
|
||||
KERNEL_HAS_SCHED_SIG_H
|
||||
|
||||
check_header \
|
||||
linux/stdarg.h \
|
||||
KERNEL_HAS_LINUX_STDARG_H
|
||||
|
||||
check_header \
|
||||
linux/filelock.h \
|
||||
KERNEL_HAS_LINUX_FILELOCK_H
|
||||
|
||||
# cryptohash does not include linux/types.h, so the type comparison fails
|
||||
check_function \
|
||||
half_md4_transform "__u32 (__u32[4], __u32 const in[8])" \
|
||||
KERNEL_HAS_HALF_MD4_TRANSFORM \
|
||||
linux/types.h linux/cryptohash.h
|
||||
|
||||
check_function \
|
||||
vfs_getattr "int (const struct path *, struct kstat *, u32, unsigned int)" \
|
||||
KERNEL_HAS_STATX \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
kref_read "unsigned int (const struct kref*)" \
|
||||
KERNEL_HAS_KREF_READ \
|
||||
linux/kref.h
|
||||
|
||||
check_function \
|
||||
file_dentry "struct dentry* (const struct file *file)" \
|
||||
KERNEL_HAS_FILE_DENTRY \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
super_setup_bdi_name "int (struct super_block *sb, char *fmt, ...)" \
|
||||
KERNEL_HAS_SUPER_SETUP_BDI_NAME \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
have_submounts "int (struct dentry *parent)" \
|
||||
KERNEL_HAS_HAVE_SUBMOUNTS \
|
||||
linux/dcache.h
|
||||
|
||||
check_function \
|
||||
kernel_read "ssize_t (struct file *, void *, size_t, loff_t *)" \
|
||||
KERNEL_HAS_KERNEL_READ \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
skwq_has_sleeper "bool (struct socket_wq*)" \
|
||||
KERNEL_HAS_SKWQ_HAS_SLEEPER \
|
||||
net/sock.h
|
||||
|
||||
check_struct_field_type \
|
||||
sock::sk_data_ready "void (*)(struct sock*, int)" \
|
||||
KERNEL_HAS_SK_DATA_READY_2 \
|
||||
net/sock.h
|
||||
|
||||
check_struct_field \
|
||||
sock::sk_sleep \
|
||||
KERNEL_HAS_SK_SLEEP \
|
||||
net/sock.h
|
||||
|
||||
check_function \
|
||||
current_time "struct timespec64 (struct inode *)" \
|
||||
KERNEL_HAS_CURRENT_TIME_SPEC64 \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
sk_has_sleeper "int (struct sock*)" \
|
||||
KERNEL_HAS_SK_HAS_SLEEPER \
|
||||
net/sock.h
|
||||
|
||||
check_function \
|
||||
__wake_up_sync_key "void (struct wait_queue_head* , unsigned int, void*)" \
|
||||
KERNEL_WAKE_UP_SYNC_KEY_HAS_3_ARGUMENTS \
|
||||
linux/wait.h
|
||||
|
||||
check_expr_type \
|
||||
'get_fs()' "mm_segment_t" \
|
||||
KERNEL_HAS_GET_FS \
|
||||
linux/uaccess.h
|
||||
|
||||
check_function \
|
||||
iov_iter_kvec 'void (struct iov_iter *i, int direction, const struct kvec *iov, unsigned long nr_segs, size_t count)' \
|
||||
KERNEL_HAS_IOV_ITER_KVEC \
|
||||
linux/uio.h
|
||||
|
||||
# The iov_iter_kvec() function has the same API but differing behaviour
|
||||
# across Linux versions:
|
||||
#
|
||||
# Linux < 4.20 requires ITER_KVEC to be set in "direction"
|
||||
# Linux >= 4.20 issues a warning (including stacktrace) if it _is_ set.
|
||||
#
|
||||
# We can't detect this from the headers, only by looking at the source.
|
||||
# BUT: The source is not guaranteed to be available when building.
|
||||
#
|
||||
# We have tried to check for this "feature" by looking at the Linux version
|
||||
# as reported by the LINUX_VERSION_CODE macro.
|
||||
#
|
||||
# BUT: Some non-vanilla < 4.20 kernels have backported the >= 4.20
|
||||
# functionality to < 4.20 kernels. So relying on the version code doesn't
|
||||
# work either.
|
||||
#
|
||||
# What we're doing here now is our current best attempt to detect how the API
|
||||
# must be used. We're checking something that is not really related to the
|
||||
# actual function, but which seems to give the right results.
|
||||
check_function \
|
||||
iov_iter_is_kvec 'bool(const struct iov_iter *)' \
|
||||
KERNEL_HAS_IOV_ITER_KVEC_NO_TYPE_FLAG_IN_DIRECTION \
|
||||
linux/uio.h
|
||||
|
||||
# print_stack_trace() found on older Linux kernels < 5.2
|
||||
check_function \
|
||||
print_stack_trace 'void (struct stack_trace *trace, int spaces)' \
|
||||
KERNEL_HAS_PRINT_STACK_TRACE \
|
||||
linux/stacktrace.h
|
||||
|
||||
# Starting from kernel 5.2, print_stack_trace() is demoted to tools/ directory
|
||||
# so not available to us.
|
||||
# Starting from kernel 5.16 print_stack_trace() is removed completely, but
|
||||
# stack_trace_print() can be used instead.
|
||||
# Notably, the identifier stack_trace_print() existed even in older Linux
|
||||
# versions, but with a different signature and different functionality.
|
||||
check_function \
|
||||
stack_trace_print 'void (unsigned long *trace, unsigned int nr_entries, int spaces)' \
|
||||
KERNEL_HAS_STACK_TRACE_PRINT \
|
||||
linux/stacktrace.h \
|
||||
|
||||
check_type 'struct file_lock_core' KERNEL_HAS_FILE_LOCK_CORE linux/filelock.h
|
||||
|
||||
check_type 'struct proc_ops' KERNEL_HAS_PROC_OPS linux/proc_fs.h
|
||||
|
||||
check_type sockptr_t KERNEL_HAS_SOCKPTR_T linux/sockptr.h
|
||||
|
||||
check_function \
|
||||
sock_setsockopt 'int (struct socket *, int, int, sockptr_t, unsigned int)' \
|
||||
KERNEL_HAS_SOCK_SETSOCKOPT_SOCKPTR_T_PARAM \
|
||||
net/sock.h
|
||||
|
||||
check_type time64_t KERNEL_HAS_TIME64 linux/ktime.h
|
||||
check_function ktime_get_ts64 'void (struct timespec64 *)' KERNEL_HAS_KTIME_GET_TS64 linux/ktime.h
|
||||
check_function ktime_get_real_ts64 'void (struct timespec64 *)' KERNEL_HAS_KTIME_GET_REAL_TS64 linux/ktime.h
|
||||
check_function ktime_get_coarse_real_ts64 'void (struct timespec64 *)' KERNEL_HAS_KTIME_GET_COARSE_REAL_TS64 linux/ktime.h
|
||||
|
||||
# latest kernel from 6.3 changes moved to timekeeping.h
|
||||
check_function \
|
||||
ktime_get_ts64 "void (struct timespec64 *ts)" \
|
||||
KERNEL_HAS_KTIME_GET_TS64 \
|
||||
linux/timekeeping.h
|
||||
check_function \
|
||||
ktime_get_real_ts64 "void (struct timespec64 *tv)" \
|
||||
KERNEL_HAS_KTIME_GET_REAL_TS64 \
|
||||
linux/timekeeping.h
|
||||
check_function \
|
||||
ktime_get_coarse_real_ts64 "void (struct timespec64 *ts)" \
|
||||
KERNEL_HAS_KTIME_GET_COARSE_REAL_TS64 \
|
||||
linux/timekeeping.h
|
||||
|
||||
check_function \
|
||||
generic_file_splice_read "ssize_t (struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int)" \
|
||||
KERNEL_HAS_GENERIC_FILE_SPLICE_READ \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
generic_permission "int (struct inode *, int)" \
|
||||
KERNEL_HAS_GENERIC_PERMISSION_2 \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
generic_permission "int (struct inode *, int, int (*check_acl)(struct inode *, int)" \
|
||||
KERNEL_HAS_GENERIC_PERMISSION_4 \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
setattr_prepare "int (struct mnt_idmap *, struct dentry *, struct iattr *)" \
|
||||
KERNEL_HAS_SETATTR_PREPARE \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
setattr_prepare "int (struct dentry *dentry, struct iattr *attr)" \
|
||||
KERNEL_HAS_SETATTR_PREPARE \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
setattr_prepare "int (struct user_namespace *, struct dentry *, struct iattr *)" \
|
||||
KERNEL_HAS_SETATTR_PREPARE \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field \
|
||||
inode_operations::get_acl \
|
||||
KERNEL_HAS_GET_ACL \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::get_acl "struct posix_acl* (*)(struct mnt_idmap *, struct dentry *, int)" \
|
||||
KERNEL_HAS_POSIX_GET_ACL_IDMAP \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::get_acl "struct posix_acl* (*)(struct user_namespace *, struct dentry *, int)" \
|
||||
KERNEL_HAS_POSIX_GET_ACL_NS \
|
||||
linux/fs.h
|
||||
|
||||
check_symbol \
|
||||
"extern const struct xattr_handler posix_acl_default_xattr_handler;" \
|
||||
KERNEL_HAS_POSIX_ACL_DEFAULT_XATTR_HANDLER \
|
||||
linux/posix_acl_xattr.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::get_acl "struct posix_acl* (*)(struct inode *, int, bool)" \
|
||||
KERNEL_POSIX_GET_ACL_HAS_RCU \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::get_inode_acl "struct posix_acl* (*)(struct inode *, int, bool)" \
|
||||
KERNEL_HAS_GET_INODE_ACL \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field \
|
||||
inode_operations::set_acl \
|
||||
KERNEL_HAS_SET_ACL \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::set_acl "int (*)(struct user_namespace *, struct inode *, struct posix_acl *, int)" \
|
||||
KERNEL_HAS_SET_ACL_NS_INODE \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::set_acl "int (*)(struct mnt_idmap *, struct dentry *, struct posix_acl *, int)" \
|
||||
KERNEL_HAS_SET_ACL_DENTRY \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
inode_operations::set_acl "int (*)(struct user_namespace *, struct dentry *, struct posix_acl *, int)" \
|
||||
KERNEL_HAS_SET_ACL_DENTRY \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
vfs_create "int (struct user_namespace *, struct inode *, struct dentry *, umode_t, bool)" \
|
||||
KERNEL_HAS_USER_NS_MOUNTS \
|
||||
linux/fs.h
|
||||
|
||||
check_function \
|
||||
vfs_create "int (struct mnt_idmap *, struct inode *, struct dentry *, umode_t, bool)" \
|
||||
KERNEL_HAS_IDMAPPED_MOUNTS \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
file_operations::iterate "int (*)(struct file *, struct dir_context *)" \
|
||||
KERNEL_HAS_FOPS_ITERATE \
|
||||
linux/fs.h
|
||||
|
||||
check_struct_field_type \
|
||||
xattr_handler::set "int (*)(const struct xattr_handler *, struct dentry *, struct inode *, const char *, const void *, size_t, int)" \
|
||||
KERNEL_HAS_XATTR_HANDLERS_INODE_ARG \
|
||||
linux/xattr.h
|
||||
|
||||
check_struct_field_type \
|
||||
xattr_handler::set "int (*)(const struct xattr_handler *, struct user_namespace *, struct dentry *, struct inode *, const char *, const void *, size_t, int)" \
|
||||
KERNEL_HAS_XATTR_HANDLERS_INODE_ARG \
|
||||
linux/xattr.h
|
||||
|
||||
check_struct_field_type \
|
||||
xattr_handler::set "int (*)(const struct xattr_handler *, struct mnt_idmap *, struct dentry *, struct inode *, const char *, const void *, size_t, int)" \
|
||||
KERNEL_HAS_XATTR_HANDLERS_INODE_ARG \
|
||||
linux/xattr.h
|
||||
|
||||
check_struct_field \
|
||||
thread_info::cpu \
|
||||
KERNEL_HAS_CPU_IN_THREAD_INFO \
|
||||
linux/thread_info.h
|
||||
|
||||
check_function \
|
||||
generic_fillattr "void (struct mnt_idmap *, u32, struct inode *, struct kstat *)" \
|
||||
KERNEL_HAS_GENERIC_FILLATTR_REQUEST_MASK \
|
||||
linux/fs.h
|
||||
|
||||
|
||||
|
||||
# Kernel 6.5 introduced getters and setters for struct inode's ctime field
|
||||
|
||||
check_function \
|
||||
inode_get_ctime "struct timespec64 (const struct inode *inode)" \
|
||||
KERNEL_HAS_INODE_GET_SET_CTIME \
|
||||
linux/fs.h
|
||||
|
||||
# Kernel 6.6 introduced more getters and setters, also for atime and mtime
|
||||
|
||||
check_function \
|
||||
inode_get_mtime "struct timespec64 (const struct inode *inode)" \
|
||||
KERNEL_HAS_INODE_GET_SET_CTIME_MTIME_ATIME \
|
||||
linux/fs.h
|
||||
|
||||
# From Linux kernel 6.12 onward, unaligned.h has been moved from <asm/> to <linux/> include path
|
||||
|
||||
check_header \
|
||||
linux/unaligned.h \
|
||||
KERNEL_HAS_LINUX_UNALIGNED_H
|
||||
|
||||
# we have to communicate with the calling makefile somehow. since we can't really use the return
|
||||
# code of this script, we'll echo a special string at the end of our output for the caller to
|
||||
# detect and remove again.
|
||||
# this string has to be something that will, on its own, never be a valid compiler option. so let's
|
||||
# choose something really, really unlikely like
|
||||
echo "--~~success~~--"
|
||||
8
client_module/dkms.conf.in
Normal file
8
client_module/dkms.conf.in
Normal file
@@ -0,0 +1,8 @@
|
||||
PACKAGE_NAME="__NAME__"
|
||||
PACKAGE_VERSION="__VERSION__"
|
||||
BUILT_MODULE_NAME[0]="__MODNAME__"
|
||||
BUILT_MODULE_LOCATION[0]="build/"
|
||||
DEST_MODULE_LOCATION[0]="/kernel/fs/beegfs/"
|
||||
MAKE[0]="make -C build module 'KDIR=$kernel_source_dir' TARGET=__MODNAME__ BEEGFS_VERSION=__VERSION__"
|
||||
CLEAN="make -C build clean"
|
||||
AUTOINSTALL="yes"
|
||||
300
client_module/include/uapi/beegfs_client.h
Normal file
300
client_module/include/uapi/beegfs_client.h
Normal file
@@ -0,0 +1,300 @@
|
||||
#ifndef _BEEGFS_CLIENT_H_INCLUDED
|
||||
#define _BEEGFS_CLIENT_H_INCLUDED
|
||||
|
||||
#define BEEGFS_IOCTL_CFG_MAX_PATH 4096 // just an arbitrary value, has to be identical in user space
|
||||
#define BEEGFS_IOCTL_TEST_STRING "_FhGFS_" /* copied to user space by BEEGFS_IOC_TEST_IS_FHGFS to
|
||||
to confirm an FhGFS mount */
|
||||
#define BEEGFS_IOCTL_TEST_BUFLEN 6 /* note: char[6] is actually the wrong size for the
|
||||
BEEGFS_IOCTL_TEST_STRING that is exchanged, but that is no problem
|
||||
in this particular case and so we keep it for compatibility */
|
||||
#define BEEGFS_IOCTL_MOUNTID_BUFLEN 256
|
||||
#define BEEGFS_IOCTL_NODEALIAS_BUFLEN 256 // The alias (formerly string ID) buffer length.
|
||||
#define BEEGFS_IOCTL_NODETYPE_BUFLEN 16
|
||||
#define BEEGFS_IOCTL_FILENAME_MAXLEN 256 // max supported filename len (incl terminating zero)
|
||||
|
||||
// entryID string is made of three 32 bit values in hexadecimal form plus two dashes
|
||||
// (see common/toolkit/StorageTk.h)
|
||||
#define BEEGFS_IOCTL_ENTRYID_MAXLEN 26
|
||||
|
||||
// stripe pattern types
|
||||
#define BEEGFS_STRIPEPATTERN_INVALID 0
|
||||
#define BEEGFS_STRIPEPATTERN_RAID0 1
|
||||
#define BEEGFS_STRIPEPATTERN_RAID10 2
|
||||
#define BEEGFS_STRIPEPATTERN_BUDDYMIRROR 3
|
||||
|
||||
#define BEEGFS_IOCTL_PING_MAX_COUNT 10
|
||||
#define BEEGFS_IOCTL_PING_MAX_INTERVAL 2000
|
||||
#define BEEGFS_IOCTL_PING_NODE_BUFLEN 64
|
||||
#define BEEGFS_IOCTL_PING_SOCKTYPE_BUFLEN 8
|
||||
|
||||
/*
|
||||
* General notes:
|
||||
* - the _IOR() macro is for ioctls that read information, _IOW refers to ioctls that write or make
|
||||
* modifications (e.g. file creation).
|
||||
*
|
||||
* - _IOR(type, number, data_type) meanings:
|
||||
* - note: _IOR() encodes all three values (type, number, data_type size) into the request number
|
||||
* - type: 8 bit driver-specific number to identify the driver if there are multiple drivers
|
||||
* listening to the same fd (e.g. such as the TCP and IP layers).
|
||||
* - number: 8 bit integer command number, so different numbers for different routines.
|
||||
* - data_type: the data type (size) to be exchanged with the driver (though this number can
|
||||
* also rather be seen as a command number subversion, because the actual number given here is
|
||||
* not really exchanged unless the drivers' ioctl handler explicity does the exchange).
|
||||
*/
|
||||
|
||||
#define BEEGFS_IOCTYPE_ID 'f'
|
||||
|
||||
#define BEEGFS_IOCNUM_GETVERSION_OLD 1 // value from FS_IOC_GETVERSION in linux/fs.h
|
||||
#define BEEGFS_IOCNUM_GETVERSION 3
|
||||
#define BEEGFS_IOCNUM_GET_CFG_FILE 20
|
||||
#define BEEGFS_IOCNUM_CREATE_FILE 21
|
||||
#define BEEGFS_IOCNUM_TEST_IS_FHGFS 22
|
||||
#define BEEGFS_IOCNUM_TEST_IS_BEEGFS 22
|
||||
#define BEEGFS_IOCNUM_GET_RUNTIME_CFG_FILE 23
|
||||
#define BEEGFS_IOCNUM_GET_MOUNTID 24
|
||||
#define BEEGFS_IOCNUM_GET_STRIPEINFO 25
|
||||
#define BEEGFS_IOCNUM_GET_STRIPETARGET 26
|
||||
#define BEEGFS_IOCNUM_MKFILE_STRIPEHINTS 27
|
||||
#define BEEGFS_IOCNUM_CREATE_FILE_V2 28
|
||||
#define BEEGFS_IOCNUM_CREATE_FILE_V3 29
|
||||
#define BEEGFS_IOCNUM_GETINODEID 30
|
||||
#define BEEGFS_IOCNUM_GETENTRYINFO 31
|
||||
#define BEEGFS_IOCNUM_PINGNODE 32
|
||||
|
||||
#define BEEGFS_IOC_GETVERSION _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GETVERSION, long)
|
||||
#define BEEGFS_IOC32_GETVERSION _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GETVERSION, int)
|
||||
#define BEEGFS_IOC_GET_CFG_FILE _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_CFG_FILE, struct BeegfsIoctl_GetCfgFile_Arg)
|
||||
#define BEEGFS_IOC_CREATE_FILE _IOW( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_CREATE_FILE, struct BeegfsIoctl_MkFile_Arg)
|
||||
#define BEEGFS_IOC_CREATE_FILE_V2 _IOW( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_CREATE_FILE_V2, struct BeegfsIoctl_MkFileV2_Arg)
|
||||
#define BEEGFS_IOC_CREATE_FILE_V3 _IOW( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_CREATE_FILE_V3, struct BeegfsIoctl_MkFileV3_Arg)
|
||||
#define BEEGFS_IOC_TEST_IS_FHGFS _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_TEST_IS_FHGFS, char[BEEGFS_IOCTL_TEST_BUFLEN])
|
||||
#define BEEGFS_IOC_TEST_IS_BEEGFS _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_TEST_IS_BEEGFS, char[BEEGFS_IOCTL_TEST_BUFLEN])
|
||||
#define BEEGFS_IOC_GET_RUNTIME_CFG_FILE _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_RUNTIME_CFG_FILE, struct BeegfsIoctl_GetCfgFile_Arg)
|
||||
#define BEEGFS_IOC_GET_MOUNTID _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_MOUNTID, char[BEEGFS_IOCTL_MOUNTID_BUFLEN])
|
||||
#define BEEGFS_IOC_GET_STRIPEINFO _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_STRIPEINFO, struct BeegfsIoctl_GetStripeInfo_Arg)
|
||||
#define BEEGFS_IOC_GET_STRIPETARGET _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_STRIPETARGET, struct BeegfsIoctl_GetStripeTarget_Arg)
|
||||
#define BEEGFS_IOC_GET_STRIPETARGET_V2 _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GET_STRIPETARGET, struct BeegfsIoctl_GetStripeTargetV2_Arg)
|
||||
#define BEEGFS_IOC_MKFILE_STRIPEHINTS _IOW( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_MKFILE_STRIPEHINTS, struct BeegfsIoctl_MkFileWithStripeHints_Arg)
|
||||
#define BEEGFS_IOC_GETINODEID _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GETINODEID, struct BeegfsIoctl_GetInodeID_Arg)
|
||||
#define BEEGFS_IOC_GETENTRYINFO _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_GETENTRYINFO, struct BeegfsIoctl_GetEntryInfo_Arg)
|
||||
#define BEEGFS_IOC_PINGNODE _IOR( \
|
||||
BEEGFS_IOCTYPE_ID, BEEGFS_IOCNUM_PINGNODE, struct BeegfsIoctl_PingNode_Arg)
|
||||
|
||||
|
||||
/* used to return the client config file path using an IOCTL */
|
||||
struct BeegfsIoctl_GetCfgFile_Arg
|
||||
{
|
||||
char path[BEEGFS_IOCTL_CFG_MAX_PATH]; // (out-value) where the result path will be stored
|
||||
int length; /* (in-value) length of path buffer (unused, because it's
|
||||
after a fixed-size path buffer anyways) */
|
||||
};
|
||||
|
||||
/* used to pass information for file creation */
|
||||
struct BeegfsIoctl_MkFile_Arg
|
||||
{
|
||||
uint16_t ownerNodeID; // owner node of the parent dir
|
||||
|
||||
const char* parentParentEntryID; // entryID of the parent of the parent (=> the grandparentID)
|
||||
int parentParentEntryIDLen;
|
||||
|
||||
const char* parentEntryID; // entryID of the parent
|
||||
int parentEntryIDLen;
|
||||
|
||||
const char* parentName; // name of parent dir
|
||||
int parentNameLen;
|
||||
|
||||
// file information
|
||||
const char* entryName; // file name we want to create
|
||||
int entryNameLen;
|
||||
int fileType; // see linux/fs.h or man 3 readdir, DT_UNKNOWN, DT_FIFO, ...
|
||||
|
||||
const char* symlinkTo; // Only must be set for symlinks. The name a symlink is supposed to point to
|
||||
int symlinkToLen; // Length of the symlink name
|
||||
|
||||
int mode; // mode (permission) of the new file
|
||||
|
||||
// user ID and group only will be used, if the current user is root
|
||||
uid_t uid; // user ID
|
||||
gid_t gid; // group ID
|
||||
|
||||
int numTargets; // number of targets in prefTargets array (without final 0 element)
|
||||
uint16_t* prefTargets; // array of preferred targets (additional last element must be 0)
|
||||
int prefTargetsLen; // raw byte length of prefTargets array (including final 0 element)
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_MkFileV2_Arg
|
||||
{
|
||||
uint32_t ownerNodeID; // owner node/group of the parent dir
|
||||
|
||||
const char* parentParentEntryID; // entryID of the parent of the parent (=> the grandparentID)
|
||||
int parentParentEntryIDLen;
|
||||
|
||||
const char* parentEntryID; // entryID of the parent
|
||||
int parentEntryIDLen;
|
||||
int parentIsBuddyMirrored;
|
||||
|
||||
const char* parentName; // name of parent dir
|
||||
int parentNameLen;
|
||||
|
||||
// file information
|
||||
const char* entryName; // file name we want to create
|
||||
int entryNameLen;
|
||||
int fileType; // see linux/fs.h or man 3 readdir, DT_UNKNOWN, DT_FIFO, ...
|
||||
|
||||
char* symlinkTo; // Only must be set for symlinks. The name a symlink is supposed to point to
|
||||
int symlinkToLen; // Length of the symlink name
|
||||
|
||||
int mode; // mode (permission) of the new file
|
||||
|
||||
// user ID and group only will be used, if the current user is root
|
||||
uid_t uid; // user ID
|
||||
gid_t gid; // group ID
|
||||
|
||||
int numTargets; // number of targets in prefTargets array (without final 0 element)
|
||||
uint16_t* prefTargets; // array of preferred targets (additional last element must be 0)
|
||||
int prefTargetsLen; // raw byte length of prefTargets array (including final 0 element)
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_MkFileV3_Arg
|
||||
{
|
||||
uint32_t ownerNodeID; // owner node/group of the parent dir
|
||||
|
||||
const char* parentParentEntryID; // entryID of the parent of the parent (=> the grandparentID)
|
||||
int parentParentEntryIDLen;
|
||||
|
||||
const char* parentEntryID; // entryID of the parent
|
||||
int parentEntryIDLen;
|
||||
int parentIsBuddyMirrored;
|
||||
|
||||
const char* parentName; // name of parent dir
|
||||
int parentNameLen;
|
||||
|
||||
// file information
|
||||
const char* entryName; // file name we want to create
|
||||
int entryNameLen;
|
||||
int fileType; // see linux/fs.h or man 3 readdir, DT_UNKNOWN, DT_FIFO, ...
|
||||
|
||||
const char* symlinkTo; // Only must be set for symlinks. The name a symlink is supposed to point to
|
||||
int symlinkToLen; // Length of the symlink name
|
||||
|
||||
int mode; // mode (permission) of the new file
|
||||
|
||||
// user ID and group only will be used, if the current user is root
|
||||
uid_t uid; // user ID
|
||||
gid_t gid; // group ID
|
||||
|
||||
int numTargets; // number of targets in prefTargets array (without final 0 element)
|
||||
uint16_t* prefTargets; // array of preferred targets (additional last element must be 0)
|
||||
int prefTargetsLen; // raw byte length of prefTargets array (including final 0 element)
|
||||
|
||||
uint16_t storagePoolId; // if set, this is used to override the pool id of the parent dir
|
||||
};
|
||||
|
||||
/* used to get the stripe info of a file */
|
||||
struct BeegfsIoctl_GetStripeInfo_Arg
|
||||
{
|
||||
unsigned outPatternType; // (out-value) stripe pattern type (STRIPEPATTERN_...)
|
||||
unsigned outChunkSize; // (out-value) chunksize for striping
|
||||
uint16_t outNumTargets; // (out-value) number of stripe targets of given file
|
||||
};
|
||||
|
||||
/* used to get the stripe target of a file */
|
||||
struct BeegfsIoctl_GetStripeTarget_Arg
|
||||
{
|
||||
uint16_t targetIndex; // index of the target that should be queried (0-based)
|
||||
|
||||
uint16_t outTargetNumID; // (out-value) numeric ID of target with given index
|
||||
uint16_t outNodeNumID; // (out-value) numeric ID of node to which this target is mapped
|
||||
char outNodeAlias[BEEGFS_IOCTL_NODEALIAS_BUFLEN]; /* (out-value) alias (formerly string ID) of the node
|
||||
to which this target is mapped */
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_GetStripeTargetV2_Arg
|
||||
{
|
||||
/* inputs */
|
||||
uint32_t targetIndex;
|
||||
|
||||
/* outputs */
|
||||
uint32_t targetOrGroup; // target ID if the file is not buddy mirrored, otherwise mirror group ID
|
||||
|
||||
uint32_t primaryTarget; // target ID != 0 if buddy mirrored
|
||||
uint32_t secondaryTarget; // target ID != 0 if buddy mirrored
|
||||
|
||||
uint32_t primaryNodeID; // node ID of target (if unmirrored) or primary target (if mirrored)
|
||||
uint32_t secondaryNodeID; // node ID of secondary target, or 0 if unmirrored
|
||||
|
||||
char primaryNodeAlias[BEEGFS_IOCTL_NODEALIAS_BUFLEN];
|
||||
char secondaryNodeAlias[BEEGFS_IOCTL_NODEALIAS_BUFLEN];
|
||||
};
|
||||
|
||||
/* used to pass information for file creation with stripe hints */
|
||||
struct BeegfsIoctl_MkFileWithStripeHints_Arg
|
||||
{
|
||||
const char* filename; // file name we want to create
|
||||
unsigned mode; // mode (access permission) of the new file
|
||||
|
||||
unsigned numtargets; // number of desired targets, 0 for directory default
|
||||
unsigned chunksize; // in bytes, must be 2^n >= 64Ki, 0 for directory default
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_GetInodeID_Arg
|
||||
{
|
||||
// input
|
||||
char entryID[BEEGFS_IOCTL_ENTRYID_MAXLEN + 1];
|
||||
|
||||
// output
|
||||
uint64_t inodeID;
|
||||
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_GetEntryInfo_Arg
|
||||
{
|
||||
uint32_t ownerID;
|
||||
char parentEntryID[BEEGFS_IOCTL_ENTRYID_MAXLEN + 1];
|
||||
char entryID[BEEGFS_IOCTL_ENTRYID_MAXLEN + 1];
|
||||
int entryType;
|
||||
int featureFlags;
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_PingNode_Arg_Params
|
||||
{
|
||||
uint32_t nodeId;
|
||||
char nodeType[BEEGFS_IOCTL_NODETYPE_BUFLEN];
|
||||
unsigned count;
|
||||
unsigned interval;
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_PingNode_Arg_Results
|
||||
{
|
||||
char outNode[BEEGFS_IOCTL_PING_NODE_BUFLEN];
|
||||
unsigned outSuccess;
|
||||
unsigned outErrors;
|
||||
unsigned outTotalTime;
|
||||
unsigned outPingTime[BEEGFS_IOCTL_PING_MAX_COUNT];
|
||||
char outPingType[BEEGFS_IOCTL_PING_MAX_COUNT][BEEGFS_IOCTL_PING_SOCKTYPE_BUFLEN];
|
||||
};
|
||||
|
||||
struct BeegfsIoctl_PingNode_Arg
|
||||
{
|
||||
struct BeegfsIoctl_PingNode_Arg_Params params;
|
||||
struct BeegfsIoctl_PingNode_Arg_Results results;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
367
client_module/scripts/etc/beegfs/lib/init-multi-mode.beegfs-client
Executable file
367
client_module/scripts/etc/beegfs/lib/init-multi-mode.beegfs-client
Executable file
@@ -0,0 +1,367 @@
|
||||
#!/bin/sh
|
||||
|
||||
function exec_mount_hook()
|
||||
{
|
||||
if [ -n "$MOUNT_HOOK" ]
|
||||
then
|
||||
set +e
|
||||
/bin/sh -c "${MOUNT_HOOK} ${1} \"${2}\""
|
||||
set -e
|
||||
fi
|
||||
}
|
||||
|
||||
function init_multi_mode()
|
||||
{
|
||||
ACTION=$1
|
||||
CONFIG=$2
|
||||
ERROR=0
|
||||
|
||||
if [ -z $ACTION ]
|
||||
then
|
||||
echo "Usage: $0 {start|stop|status|restart|rebuild|condrestart|try-restart} [CONFIGURATION_NAME]"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [ -z $CONFIG ]
|
||||
then
|
||||
case "$ACTION" in
|
||||
rebuild)
|
||||
# Just rebuild modules. The user needs to call "restart" to make use
|
||||
# of those new modules.
|
||||
build_beegfs
|
||||
ERROR=$?
|
||||
if [ $ERROR -eq 0 ]; then
|
||||
rm -f $FORCE_AUTO_BUILD
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
do_central_loop stop
|
||||
do_central_loop start
|
||||
ERROR=$?
|
||||
;;
|
||||
try-restart|condrestart)
|
||||
## Do a restart only if the service was active before.
|
||||
## Note: try-restart is now part of LSB (as of 1.9).
|
||||
## RH has a similar command named condrestart.
|
||||
do_central_loop status
|
||||
if test $? = 0
|
||||
then
|
||||
$0 restart
|
||||
ERROR=$?
|
||||
else
|
||||
ERROR=1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
do_central_loop $ACTION
|
||||
ERROR=$?
|
||||
;;
|
||||
esac
|
||||
else
|
||||
BEEGFS_MOUNT_CONF="/etc/beegfs/${CONFIG}.d/beegfs-mounts.conf"
|
||||
|
||||
if [ -e "/etc/beegfs/${CONFIG}.d" ]
|
||||
then
|
||||
init_multi_mode_single_configuration $ACTION $CONFIG
|
||||
ERROR=$?
|
||||
else
|
||||
echo "Configuration folder /etc/beegfs/${CONFIG}.d doesn't exist."
|
||||
ERROR=1
|
||||
fi
|
||||
fi
|
||||
return $ERROR
|
||||
}
|
||||
|
||||
do_central_loop()
|
||||
{
|
||||
ACTION=$1
|
||||
LOOP_ERROR=0
|
||||
|
||||
for CONFIG_FOLDER in $( ls -d /etc/beegfs/*.d )
|
||||
do
|
||||
if [ -r ${CONFIG_FOLDER}/beegfs-client.conf ]
|
||||
then
|
||||
CONFIG=$( basename $CONFIG_FOLDER .d )
|
||||
BEEGFS_MOUNT_CONF="${CONFIG_FOLDER}/beegfs-mounts.conf"
|
||||
|
||||
init_multi_mode_single_configuration $ACTION $CONFIG
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
LOOP_ERROR=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
return $LOOP_ERROR
|
||||
}
|
||||
|
||||
function init_multi_mode_single_configuration()
|
||||
{
|
||||
ACTION=$1
|
||||
CONFIG=$2
|
||||
|
||||
if [ -z $ACTION ]
|
||||
then
|
||||
echo "Usage: $0 {start|stop|status|restart|rebuild|condrestart|try-restart} [CONFIGURATION_NAME]"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
case "$1" in
|
||||
start)
|
||||
if [ -f "${SYSCONFIG_FILE}" ]
|
||||
then
|
||||
source ${SYSCONFIG_FILE}
|
||||
if [ "${START_SERVICE}" = "NO" -o "${START_SERVICE}" = "no" ]
|
||||
then
|
||||
echo "BeeGFS Client not set to be started"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
handle_selinux
|
||||
|
||||
echo "Starting BeeGFS Client (${CONFIG}): "
|
||||
|
||||
test_updated_autobuild_conf
|
||||
set +e #methode test_updated_autobuild_conf set -e
|
||||
|
||||
echo "- Loading BeeGFS modules"
|
||||
if [ -f "$FORCE_AUTO_BUILD" ]; then
|
||||
# a new version was installed or the user updated the
|
||||
# auto-build config, so we force a rebuild
|
||||
rmmod $CLIENT_MOD 2>/dev/null
|
||||
rc=1
|
||||
else
|
||||
modprobe $CLIENT_MOD
|
||||
rc=$?
|
||||
fi
|
||||
|
||||
if [ $rc -ne 0 ]
|
||||
then
|
||||
set -e
|
||||
build_beegfs
|
||||
modprobe $CLIENT_MOD || (warn_on_ofed_mismatch && false)
|
||||
rm -f $FORCE_AUTO_BUILD
|
||||
set +e
|
||||
fi
|
||||
|
||||
echo "- Mounting directories from $BEEGFS_MOUNT_CONF"
|
||||
|
||||
mkdir -p /var/lock/subsys/ >/dev/null 2>&1
|
||||
touch $SUBSYS >/dev/null 2>&1
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Couldn't create lock file."
|
||||
return 1
|
||||
fi
|
||||
|
||||
OLDIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
if [ -r $BEEGFS_MOUNT_CONF ]
|
||||
then
|
||||
file=`tr -d '\r' < $BEEGFS_MOUNT_CONF` # read all lines at once and remove CR from dos files
|
||||
else
|
||||
echo "Couldn't read configuration file: $BEEGFS_MOUNT_CONF"
|
||||
IFS="$OLDIFS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
for line in $file; do
|
||||
if [ -z "$line" ]; then
|
||||
continue # ignore empty line
|
||||
elif echo "$line" | grep -qs "^\s*#" ; then
|
||||
continue # ignore shell style comments
|
||||
fi
|
||||
|
||||
mnt=`echo $line | awk '{print $1}'`
|
||||
cfg=`echo $line | awk '{print $2}'`
|
||||
extra_mount_opts=`echo $line | awk '{print $3}'`
|
||||
|
||||
if [ -z "$mnt" -o -z "$cfg" ]; then
|
||||
echo "Invalid config line: \"$line\""
|
||||
RETVAL=1
|
||||
continue
|
||||
fi
|
||||
|
||||
mount -t beegfs | grep "${mnt} " >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
# already mounted
|
||||
continue
|
||||
fi
|
||||
|
||||
# mkdir required for admon
|
||||
if [ ! -e ${mnt} ]
|
||||
then
|
||||
mkdir -p ${mnt}
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Couldn't create mountpoint folder: ${mnt}"
|
||||
RETVAL=1
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
exec_mount_hook pre-mount "${mnt}"
|
||||
|
||||
mount -t beegfs beegfs_${CONFIG} ${mnt} \
|
||||
-ocfgFile=${cfg},_netdev,${SELINUX_OPT},${extra_mount_opts}
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Couldn't mount ${mnt}."
|
||||
RETVAL=1
|
||||
continue
|
||||
fi
|
||||
|
||||
exec_mount_hook post-mount "${mnt}"
|
||||
|
||||
done
|
||||
|
||||
IFS="$OLDIFS"
|
||||
;;
|
||||
stop)
|
||||
echo "Shutting down BeeGFS Client (${CONFIG}): "
|
||||
|
||||
RETVAL=0
|
||||
echo "- Unmounting directories from $BEEGFS_MOUNT_CONF"
|
||||
|
||||
OLDIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
if [ -r $BEEGFS_MOUNT_CONF ]
|
||||
then
|
||||
file=`cat $BEEGFS_MOUNT_CONF` # we have to read all lines at once
|
||||
else
|
||||
echo "Couldn't read configuration file: $BEEGFS_MOUNT_CONF"
|
||||
IFS="$OLDIFS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
for line in $file
|
||||
do
|
||||
if [ -z "$line" ]; then
|
||||
continue # ignore empty line
|
||||
fi
|
||||
|
||||
mnt=`echo $line | awk '{print $1}'`
|
||||
cfg=`echo $line | awk '{print $2}'`
|
||||
if [ -z "$mnt" -o -z "$cfg" ]; then
|
||||
echo "Invalid config line: \"$line\""
|
||||
RETVAL=1
|
||||
continue
|
||||
fi
|
||||
|
||||
exec_mount_hook pre-unmount "${mnt}"
|
||||
|
||||
res=`umount ${mnt} 2>&1`
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
# umount failed, ignore the failure if not mounted at all
|
||||
echo $res | grep "not mounted" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# Is mounted, abort.
|
||||
echo "umount failed: $res"
|
||||
RETVAL=1
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
exec_mount_hook post-unmount "${mnt}"
|
||||
|
||||
done
|
||||
|
||||
IFS="$OLDIFS"
|
||||
|
||||
# tests if other beegfs mounts exists
|
||||
mount -t beegfs | grep beegfs >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "- Unloading modules"
|
||||
|
||||
res=`rmmod $CLIENT_MOD 2>&1`
|
||||
if [ $? -ne 0 ]; then
|
||||
# rmmod failed, ignore it if the module is not loaded at all
|
||||
echo $res | grep "does not exist in" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# Is loaded, abort
|
||||
echo "rmmod failed: $res"
|
||||
RETVAL=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $RETVAL -eq 0 ]; then rm -f $SUBSYS; fi
|
||||
# Remember status and be verbose
|
||||
;;
|
||||
status)
|
||||
# Return value is slightly different for the status command:
|
||||
# 0 - service up and running
|
||||
# 1 - service dead, but /var/run/ pid file exists
|
||||
# 2 - service dead, but /var/lock/ lock file exists
|
||||
# 3 - service not running (unused)
|
||||
# 4 - service status unknown :-(
|
||||
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
|
||||
|
||||
echo -n "Checking for service BeeGFS Client (${CONFIG}): "
|
||||
|
||||
lsmod | grep $CLIENT_MOD >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "is running..."
|
||||
mount -t beegfs | grep beegfs_${CONFIG} >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
mount -t beegfs | grep beegfs_${CONFIG} | cut "-d " -f1-3
|
||||
echo
|
||||
RETVAL=0
|
||||
else
|
||||
echo ">> No mounts for the configuration ${CONFIG} mounted."
|
||||
echo
|
||||
RETVAL=4
|
||||
fi
|
||||
else
|
||||
echo "is stopped."
|
||||
echo
|
||||
RETVAL=3
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
## Stop the service and regardless of whether it was
|
||||
## running or not, start it again.
|
||||
$0 stop ${CONFIG}
|
||||
$0 start ${CONFIG}
|
||||
RETVAL=$?
|
||||
# Remember status and be quiet
|
||||
;;
|
||||
rebuild)
|
||||
# Just rebuild modules. The user needs to call "restart" to make use
|
||||
# of those new modules.
|
||||
build_beegfs
|
||||
RETVAL=$?
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
rm -f $FORCE_AUTO_BUILD
|
||||
fi
|
||||
;;
|
||||
try-restart|condrestart)
|
||||
## Do a restart only if the service was active before.
|
||||
## Note: try-restart is now part of LSB (as of 1.9).
|
||||
## RH has a similar command named condrestart.
|
||||
$0 status ${CONFIG}
|
||||
if test $? = 0
|
||||
then
|
||||
$0 restart ${CONFIG}
|
||||
RETVAL=$?
|
||||
else
|
||||
RETVAL=7
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|rebuild|condrestart|try-restart} [CONFIGURATION_NAME]"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
return $RETVAL
|
||||
}
|
||||
199
client_module/source/Makefile
Normal file
199
client_module/source/Makefile
Normal file
@@ -0,0 +1,199 @@
|
||||
# NOTE(jstimpfle, 2022-04): I changed the interface of the feature-detect.sh
|
||||
# script to take some arguments explicitly from the command-line, as opposed to
|
||||
# implicitly from the environment.
|
||||
#
|
||||
# The reason is that we hit a case where there was a string literal in
|
||||
# KBUILD_CFLAGS (generated in Linux kernel Makefiles), and since this variable
|
||||
# is normally used as part of shell commands contained in Makefiles this
|
||||
# string literal is wrapped in a pair of single quotes,
|
||||
# like this '"string literal"'.
|
||||
|
||||
BEEGFS_FEATURE_DETECTION := $(shell $(dir $(lastword $(MAKEFILE_LIST)))/../build/feature-detect.sh $(KBUILD_CFLAGS) $(KBUILD_CPPFLAGS))
|
||||
|
||||
ifneq ($(lastword $(BEEGFS_FEATURE_DETECTION)),--~~success~~--)
|
||||
$(error feature detection reported an error)
|
||||
else
|
||||
BEEGFS_FEATURE_DETECTION := $(filter-out --~~success~~--,$(BEEGFS_FEATURE_DETECTION))
|
||||
$(info feature detection gives: $(BEEGFS_FEATURE_DETECTION))
|
||||
endif
|
||||
|
||||
# ccflags-y was introduced in 2.6.24, earlier kernels use EXTRA_CFLAGS for the same purpose
|
||||
ifeq ($(origin ccflags-y),file)
|
||||
ccflags-y += $(BEEGFS_FEATURE_DETECTION)
|
||||
else
|
||||
# the client makefile sets this already
|
||||
override EXTRA_CFLAGS += $(BEEGFS_FEATURE_DETECTION)
|
||||
endif
|
||||
|
||||
kernel-version = $(shell printf "%02d%02d" $(VERSION) $(PATCHLEVEL))
|
||||
kernel-if-version-or-later = $(shell [ $(kernel-version) -ge $(1) ] && echo $(2))
|
||||
|
||||
obj-m += ${TARGET}.o
|
||||
|
||||
SOURCES := \
|
||||
fault-inject/fault-inject.c \
|
||||
os/iov_iter.c \
|
||||
os/atomic64.c \
|
||||
os/OsCompat.c \
|
||||
os/OsDeps.c \
|
||||
net/message/NetMessageFactory.c \
|
||||
net/filesystem/FhgfsOpsCommKit.c \
|
||||
net/filesystem/FhgfsOpsRemoting.c \
|
||||
net/filesystem/FhgfsOpsCommKitVec.c \
|
||||
common/system/System.c \
|
||||
common/net/sock/Socket.c \
|
||||
common/net/sock/NicAddress.c \
|
||||
common/net/sock/NetworkInterfaceCard.c \
|
||||
common/net/sock/NicAddressList.c \
|
||||
common/net/sock/RDMASocket.c \
|
||||
common/net/sock/ibv/IBVSocket.c \
|
||||
common/net/sock/ibv/IBVBuffer.c \
|
||||
common/net/sock/ibv/No_IBVSocket.c \
|
||||
common/net/sock/StandardSocket.c \
|
||||
common/net/message/control/PeerInfoMsg.c \
|
||||
common/net/message/SimpleIntMsg.c \
|
||||
common/net/message/NetMessage.c \
|
||||
common/net/message/session/locking/FLockEntryMsg.c \
|
||||
common/net/message/session/locking/FLockAppendMsg.c \
|
||||
common/net/message/session/locking/LockGrantedMsgEx.c \
|
||||
common/net/message/session/locking/FLockRangeMsg.c \
|
||||
common/net/message/session/GetFileVersionRespMsg.c \
|
||||
common/net/message/session/rw/ReadLocalFileV2Msg.c \
|
||||
common/net/message/session/rw/ReadLocalFileRDMAMsg.c \
|
||||
common/net/message/session/rw/WriteLocalFileMsg.c \
|
||||
common/net/message/session/rw/WriteLocalFileRDMAMsg.c \
|
||||
common/net/message/session/FSyncLocalFileMsg.c \
|
||||
common/net/message/session/GetFileVersionMsg.c \
|
||||
common/net/message/session/opening/OpenFileMsg.c \
|
||||
common/net/message/session/opening/OpenFileRespMsg.c \
|
||||
common/net/message/session/opening/CloseFileMsg.c \
|
||||
common/net/message/session/BumpFileVersion.c \
|
||||
common/net/message/SimpleInt64Msg.c \
|
||||
common/net/message/SimpleUInt16Msg.c \
|
||||
common/net/message/SimpleStringMsg.c \
|
||||
common/net/message/SimpleIntStringMsg.c \
|
||||
common/net/message/nodes/RegisterNodeMsg.c \
|
||||
common/net/message/nodes/RegisterNodeRespMsg.c \
|
||||
common/net/message/nodes/HeartbeatRequestMsgEx.c \
|
||||
common/net/message/nodes/MapTargetsMsgEx.c \
|
||||
common/net/message/nodes/GetTargetMappingsRespMsg.c \
|
||||
common/net/message/nodes/HeartbeatMsgEx.c \
|
||||
common/net/message/nodes/RemoveNodeMsgEx.c \
|
||||
common/net/message/nodes/GetStatesAndBuddyGroupsMsg.c \
|
||||
common/net/message/nodes/GetStatesAndBuddyGroupsRespMsg.c \
|
||||
common/net/message/nodes/RefreshTargetStatesMsgEx.c \
|
||||
common/net/message/nodes/GetNodesRespMsg.c \
|
||||
common/net/message/nodes/SetMirrorBuddyGroupMsgEx.c \
|
||||
common/net/message/SimpleMsg.c \
|
||||
common/net/message/storage/moving/RenameMsg.c \
|
||||
common/net/message/storage/StatStoragePathRespMsg.c \
|
||||
common/net/message/storage/creating/HardlinkMsg.c \
|
||||
common/net/message/storage/creating/MkFileMsg.c \
|
||||
common/net/message/storage/creating/MkDirMsg.c \
|
||||
common/net/message/storage/creating/UnlinkFileMsg.c \
|
||||
common/net/message/storage/creating/MkDirRespMsg.c \
|
||||
common/net/message/storage/creating/RmDirMsg.c \
|
||||
common/net/message/storage/creating/MkFileRespMsg.c \
|
||||
common/net/message/storage/attribs/StatRespMsg.c \
|
||||
common/net/message/storage/attribs/ListXAttrRespMsg.c \
|
||||
common/net/message/storage/attribs/SetAttrMsg.c \
|
||||
common/net/message/storage/attribs/ListXAttrMsg.c \
|
||||
common/net/message/storage/attribs/RefreshEntryInfoMsg.c \
|
||||
common/net/message/storage/attribs/StatMsg.c \
|
||||
common/net/message/storage/attribs/GetXAttrRespMsg.c \
|
||||
common/net/message/storage/attribs/GetXAttrMsg.c \
|
||||
common/net/message/storage/attribs/RemoveXAttrMsg.c \
|
||||
common/net/message/storage/attribs/SetXAttrMsg.c \
|
||||
common/net/message/storage/lookup/LookupIntentRespMsg.c \
|
||||
common/net/message/storage/lookup/LookupIntentMsg.c \
|
||||
common/net/message/storage/TruncFileMsg.c \
|
||||
common/net/message/storage/listing/ListDirFromOffsetRespMsg.c \
|
||||
common/net/message/storage/listing/ListDirFromOffsetMsg.c \
|
||||
common/threading/Thread.c \
|
||||
common/toolkit/Serialization.c \
|
||||
common/toolkit/MessagingTk.c \
|
||||
common/toolkit/HashTk.c \
|
||||
common/toolkit/ackstore/WaitAckMap.c \
|
||||
common/toolkit/ackstore/AcknowledgmentStore.c \
|
||||
common/toolkit/ackstore/AckStoreMap.c \
|
||||
common/toolkit/Random.c \
|
||||
common/toolkit/tree/IntMap.c \
|
||||
common/toolkit/tree/StrCpyMap.c \
|
||||
common/toolkit/tree/PointerRBTree.c \
|
||||
common/toolkit/NodesTk.c \
|
||||
common/toolkit/SocketTk.c \
|
||||
common/toolkit/MetadataTk.c \
|
||||
common/toolkit/StringTk.c \
|
||||
common/toolkit/ListTk.c \
|
||||
common/Types.c \
|
||||
common/nodes/Node.c \
|
||||
common/nodes/TargetMapper.c \
|
||||
common/nodes/MirrorBuddyGroup.c \
|
||||
common/nodes/NumNodeID.c \
|
||||
common/nodes/TargetStateStore.c \
|
||||
common/nodes/NodeTree.c \
|
||||
common/nodes/MirrorBuddyGroupMapper.c \
|
||||
common/nodes/NodeConnPool.c \
|
||||
common/storage/StorageErrors.c \
|
||||
common/storage/StatData.c \
|
||||
common/storage/striping/BuddyMirrorPattern.c \
|
||||
common/storage/striping/SimplePattern.c \
|
||||
common/storage/striping/StripePattern.c \
|
||||
common/storage/striping/Raid10Pattern.c \
|
||||
common/storage/striping/Raid0Pattern.c \
|
||||
common/storage/PathInfo.c \
|
||||
common/storage/RdmaInfo.c \
|
||||
common/storage/Nvfs.c \
|
||||
common/storage/EntryInfo.c \
|
||||
common/storage/StoragePoolId.c \
|
||||
common/storage/FileEvent.c \
|
||||
program/Main.c \
|
||||
toolkit/FhgfsChunkPageVec.c \
|
||||
toolkit/StatFsCache.c \
|
||||
toolkit/NoAllocBufferStore.c \
|
||||
toolkit/InodeRefStore.c \
|
||||
toolkit/BitStore.c \
|
||||
components/DatagramListener.c \
|
||||
components/InternodeSyncer.c \
|
||||
components/Flusher.c \
|
||||
components/worker/RWPagesWork.c \
|
||||
components/AckManager.c \
|
||||
nodes/NodeStoreEx.c \
|
||||
filesystem/ProcFs.c \
|
||||
filesystem/FhgfsOpsPages.c \
|
||||
filesystem/FhgfsOpsFile.c \
|
||||
filesystem/FhgfsOpsInode.c \
|
||||
filesystem/FhgfsOpsFileNative.c \
|
||||
filesystem/FhgfsInode.c \
|
||||
filesystem/helper/IoctlHelper.c \
|
||||
filesystem/FsFileInfo.c \
|
||||
filesystem/ProcFsHelper.c \
|
||||
filesystem/FhgfsOpsSuper.c \
|
||||
filesystem/FhgfsOps_versions.c \
|
||||
filesystem/FhgfsXAttrHandlers.c \
|
||||
filesystem/FhgfsOpsDir.c \
|
||||
filesystem/FhgfsOpsIoctl.c \
|
||||
filesystem/FhgfsOpsExport.c \
|
||||
filesystem/FhgfsOpsHelper.c \
|
||||
app/App.c \
|
||||
app/log/Logger.c \
|
||||
app/config/MountConfig.c \
|
||||
app/config/Config.c
|
||||
|
||||
${TARGET}-y := $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
ifdef BEEGFS_NO_RDMA
|
||||
ccflags-y += -DBEEGFS_NO_RDMA
|
||||
endif
|
||||
|
||||
ifneq ($(OFED_INCLUDE_PATH),)
|
||||
|
||||
# RHEL/CentOS 8 + MLNX 4.7 requires extra flags (bug?)
|
||||
ccflags-y += $(call kernel-if-version-or-later, 0418, -DHAVE_BITS_H)
|
||||
|
||||
NOSTDINC_FLAGS+=-I$(OFED_INCLUDE_PATH) -I$(OFED_INCLUDE_PATH)/uapi
|
||||
ifeq ($(shell [ -f $(OFED_INCLUDE_PATH)/linux/compat-2.6.h ] && echo 1),1)
|
||||
ccflags-y += -include $(OFED_INCLUDE_PATH)/linux/compat-2.6.h
|
||||
endif
|
||||
|
||||
endif
|
||||
1010
client_module/source/app/App.c
Normal file
1010
client_module/source/app/App.c
Normal file
File diff suppressed because it is too large
Load Diff
436
client_module/source/app/App.h
Normal file
436
client_module/source/app/App.h
Normal file
@@ -0,0 +1,436 @@
|
||||
#ifndef APP_H_
|
||||
#define APP_H_
|
||||
|
||||
#include <app/config/MountConfig.h>
|
||||
#include <common/toolkit/list/PointerListIter.h>
|
||||
#include <common/toolkit/list/StrCpyListIter.h>
|
||||
#include <common/toolkit/list/UInt16ListIter.h>
|
||||
#include <common/net/sock/NicAddressList.h>
|
||||
#include <common/threading/AtomicInt.h>
|
||||
#include <common/threading/Mutex.h>
|
||||
#include <common/threading/Thread.h>
|
||||
#include <common/Common.h>
|
||||
#include <toolkit/BitStore.h>
|
||||
|
||||
|
||||
// program return codes
|
||||
#define APPCODE_NO_ERROR 0
|
||||
#define APPCODE_PROGRAM_ERROR 1
|
||||
#define APPCODE_INVALID_CONFIG 2
|
||||
#define APPCODE_INITIALIZATION_ERROR 3
|
||||
#define APPCODE_RUNTIME_ERROR 4
|
||||
|
||||
// forward declarations
|
||||
struct Config;
|
||||
struct Logger;
|
||||
struct DatagramListener;
|
||||
struct InternodeSyncer;
|
||||
struct AckManager;
|
||||
struct Flusher;
|
||||
struct Node;
|
||||
struct NodeStoreEx;
|
||||
struct TargetMapper;
|
||||
struct MirrorBuddyGroupMapper;
|
||||
struct TargetStateStore;
|
||||
struct NoAllocBufferStore;
|
||||
struct AcknowledgmentStore;
|
||||
struct NetFilter;
|
||||
struct InodeRefStore;
|
||||
struct StatFsCache;
|
||||
|
||||
|
||||
|
||||
struct App;
|
||||
typedef struct App App;
|
||||
|
||||
|
||||
extern void App_init(App* this, MountConfig* mountConfig);
|
||||
extern void App_uninit(App* this);
|
||||
|
||||
extern int App_run(App* this);
|
||||
extern void App_stop(App* this);
|
||||
|
||||
extern bool __App_initDataObjects(App* this, MountConfig* mountConfig);
|
||||
extern bool __App_initInodeOperations(App* this);
|
||||
extern bool __App_initLocalNodeInfo(App* this);
|
||||
extern bool __App_initComponents(App* this);
|
||||
extern void __App_startComponents(App* this);
|
||||
extern void __App_stopComponents(App* this);
|
||||
extern void __App_joinComponents(App* this);
|
||||
extern void __App_waitForComponentTermination(App* this, Thread* component);
|
||||
|
||||
extern void __App_logInfos(App* this);
|
||||
|
||||
extern bool __App_mountServerCheck(App* this);
|
||||
|
||||
extern bool App_findAllowedInterfaces(App* this, NicAddressList* nicList);
|
||||
extern void App_findAllowedRDMAInterfaces(App* this, NicAddressList* nicList, NicAddressList* rdmaNicList);
|
||||
|
||||
// external getters & setters
|
||||
extern const char* App_getVersionStr(void);
|
||||
extern void App_updateLocalInterfaces(App* app, NicAddressList* nicList);
|
||||
extern char* App_cloneFsUUID(App* this);
|
||||
extern void App_updateFsUUID(App* this, const char* fsUUID);
|
||||
extern void App_cloneLocalNicList(App* this, NicAddressList* nicList);
|
||||
extern void App_cloneLocalRDMANicList(App* this, NicAddressList* rdmaNicList);
|
||||
|
||||
// inliners
|
||||
static inline struct Logger* App_getLogger(App* this);
|
||||
static inline struct Config* App_getConfig(App* this);
|
||||
static inline struct MountConfig* App_getMountConfig(App* this);
|
||||
static inline struct NetFilter* App_getNetFilter(App* this);
|
||||
static inline struct NetFilter* App_getTcpOnlyFilter(App* this);
|
||||
static inline NicAddressList* App_getLocalRDMANicListLocked(App* this);
|
||||
/**
|
||||
* Called when access to the nicList is required but doesn't
|
||||
* want the overhead of a clone operation. This locks the internel nicListMutex.
|
||||
* App_unlockNicList must later be invoked.
|
||||
*/
|
||||
static inline void App_lockNicList(App* this);
|
||||
/**
|
||||
* Release the lock on nicListMutex acquired by App_lockNicList.
|
||||
*/
|
||||
static inline void App_unlockNicList(App* this);
|
||||
static inline UInt16List* App_getPreferredStorageTargets(App* this);
|
||||
static inline UInt16List* App_getPreferredMetaNodes(App* this);
|
||||
static inline struct Node* App_getLocalNode(App* this);
|
||||
static inline struct NodeStoreEx* App_getMgmtNodes(App* this);
|
||||
static inline struct NodeStoreEx* App_getMetaNodes(App* this);
|
||||
static inline struct NodeStoreEx* App_getStorageNodes(App* this);
|
||||
static inline struct TargetMapper* App_getTargetMapper(App* this);
|
||||
static inline struct MirrorBuddyGroupMapper* App_getStorageBuddyGroupMapper(App* this);
|
||||
static inline struct MirrorBuddyGroupMapper* App_getMetaBuddyGroupMapper(App* this);
|
||||
static inline struct TargetStateStore* App_getTargetStateStore(App* this);
|
||||
static inline struct TargetStateStore* App_getMetaStateStore(App* this);
|
||||
static inline struct NoAllocBufferStore* App_getCacheBufStore(App* this);
|
||||
static inline struct NoAllocBufferStore* App_getPathBufStore(App* this);
|
||||
static inline struct NoAllocBufferStore* App_getMsgBufStore(App* this);
|
||||
static inline struct AcknowledgmentStore* App_getAckStore(App* this);
|
||||
static inline struct InodeRefStore* App_getInodeRefStore(App* this);
|
||||
static inline struct StatFsCache* App_getStatFsCache(App* this);
|
||||
static inline struct DatagramListener* App_getDatagramListener(App* this);
|
||||
static inline struct InternodeSyncer* App_getInternodeSyncer(App* this);
|
||||
static inline struct AckManager* App_getAckManager(App* this);
|
||||
static inline AtomicInt* App_getLockAckAtomicCounter(App* this);
|
||||
static inline bool App_getConnRetriesEnabled(App* this);
|
||||
static inline void App_setConnRetriesEnabled(App* this, bool connRetriesEnabled);
|
||||
static inline bool App_getNetBenchModeEnabled(App* this);
|
||||
static inline void App_setNetBenchModeEnabled(App* this, bool netBenchModeEnabled);
|
||||
|
||||
static inline struct inode_operations* App_getFileInodeOps(App* this);
|
||||
static inline struct inode_operations* App_getSymlinkInodeOps(App* this);
|
||||
static inline struct inode_operations* App_getDirInodeOps(App* this);
|
||||
static inline struct inode_operations* App_getSpecialInodeOps(App* this);
|
||||
|
||||
#ifdef BEEGFS_DEBUG
|
||||
static inline size_t App_getNumRPCs(App* this);
|
||||
static inline void App_incNumRPCs(App* this);
|
||||
static inline size_t App_getNumRemoteReads(App* this);
|
||||
static inline void App_incNumRemoteReads(App* this);
|
||||
static inline size_t App_getNumRemoteWrites(App* this);
|
||||
static inline void App_incNumRemoteWrites(App* this);
|
||||
#endif // BEEGFS_DEBUG
|
||||
|
||||
|
||||
struct App
|
||||
{
|
||||
int appResult;
|
||||
MountConfig* mountConfig;
|
||||
|
||||
struct Config* cfg;
|
||||
struct Logger* logger;
|
||||
const char* fsUUID;
|
||||
Mutex fsUUIDMutex;
|
||||
|
||||
struct NetFilter* netFilter; // empty filter means "all nets allowed"
|
||||
struct NetFilter* tcpOnlyFilter; // for IPs which allow only plain TCP (no RDMA etc)
|
||||
StrCpyList allowedInterfaces; // empty list means "all interfaces accepted"
|
||||
StrCpyList allowedRDMAInterfaces; // empty list means "all interfaces eligible"
|
||||
UInt16List preferredMetaNodes; // empty list means "no preferred nodes => use any"
|
||||
UInt16List preferredStorageTargets; // empty list means "no preferred nodes => use any"
|
||||
// rdmaNicList contains the addresses of specific RDMA NICs to use for outbound RDMA.
|
||||
// This is only populated when the configuration specifies a list of interfaces. If this
|
||||
// list is empty, any RDMA NIC on the client may be used for outbound RDMA.
|
||||
// allowedRDMAInterfaces contains the interface names used to populate this list.
|
||||
NicAddressList rdmaNicList;
|
||||
Mutex nicListMutex;
|
||||
|
||||
struct Node* localNode;
|
||||
struct NodeStoreEx* mgmtNodes;
|
||||
struct NodeStoreEx* metaNodes;
|
||||
struct NodeStoreEx* storageNodes;
|
||||
|
||||
struct TargetMapper* targetMapper;
|
||||
struct MirrorBuddyGroupMapper* storageBuddyGroupMapper;
|
||||
struct MirrorBuddyGroupMapper* metaBuddyGroupMapper;
|
||||
struct TargetStateStore* targetStateStore; // map storage targets IDs to a state
|
||||
struct TargetStateStore* metaStateStore; // map mds targets (i.e. nodeIDs) to a state
|
||||
|
||||
struct NoAllocBufferStore* cacheBufStore; // for buffered cache mode
|
||||
struct NoAllocBufferStore* pathBufStore; // for dentry path lookups
|
||||
struct NoAllocBufferStore* msgBufStore; // for MessagingTk request/response
|
||||
struct AcknowledgmentStore* ackStore;
|
||||
struct InodeRefStore* inodeRefStore;
|
||||
struct StatFsCache* statfsCache;
|
||||
|
||||
struct DatagramListener* dgramListener;
|
||||
struct InternodeSyncer* internodeSyncer;
|
||||
struct AckManager* ackManager;
|
||||
struct Flusher* flusher;
|
||||
|
||||
AtomicInt lockAckAtomicCounter; // used by remoting to generate unique lockAckIDs
|
||||
volatile bool connRetriesEnabled; // changed at umount and via procfs
|
||||
bool netBenchModeEnabled; // changed via procfs to disable server-side disk read/write
|
||||
|
||||
// Inode operations. Since the members of the structs depend on runtime config opts, we need
|
||||
// one copy of each struct per App object.
|
||||
struct inode_operations* fileInodeOps;
|
||||
struct inode_operations* symlinkInodeOps;
|
||||
struct inode_operations* dirInodeOps;
|
||||
struct inode_operations* specialInodeOps;
|
||||
|
||||
#ifdef BEEGFS_DEBUG
|
||||
Mutex debugCounterMutex; // this is the closed tree, so we don't have atomics here (but doesn't
|
||||
// matter since this is debug info and not performance critical)
|
||||
|
||||
size_t numRPCs;
|
||||
size_t numRemoteReads;
|
||||
size_t numRemoteWrites;
|
||||
#endif // BEEGFS_DEBUG
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct Logger* App_getLogger(App* this)
|
||||
{
|
||||
return this->logger;
|
||||
}
|
||||
|
||||
struct Config* App_getConfig(App* this)
|
||||
{
|
||||
return this->cfg;
|
||||
}
|
||||
|
||||
struct MountConfig* App_getMountConfig(App* this)
|
||||
{
|
||||
return this->mountConfig;
|
||||
}
|
||||
|
||||
struct NetFilter* App_getNetFilter(App* this)
|
||||
{
|
||||
return this->netFilter;
|
||||
}
|
||||
|
||||
struct NetFilter* App_getTcpOnlyFilter(App* this)
|
||||
{
|
||||
return this->tcpOnlyFilter;
|
||||
}
|
||||
|
||||
UInt16List* App_getPreferredMetaNodes(App* this)
|
||||
{
|
||||
return &this->preferredMetaNodes;
|
||||
}
|
||||
|
||||
UInt16List* App_getPreferredStorageTargets(App* this)
|
||||
{
|
||||
return &this->preferredStorageTargets;
|
||||
}
|
||||
|
||||
void App_lockNicList(App* this)
|
||||
{
|
||||
Mutex_lock(&this->nicListMutex); // L O C K
|
||||
}
|
||||
|
||||
void App_unlockNicList(App* this)
|
||||
{
|
||||
Mutex_unlock(&this->nicListMutex); // U N L O C K
|
||||
}
|
||||
|
||||
NicAddressList* App_getLocalRDMANicListLocked(App* this)
|
||||
{
|
||||
return &this->rdmaNicList;
|
||||
}
|
||||
|
||||
struct Node* App_getLocalNode(App* this)
|
||||
{
|
||||
return this->localNode;
|
||||
}
|
||||
|
||||
struct NodeStoreEx* App_getMgmtNodes(App* this)
|
||||
{
|
||||
return this->mgmtNodes;
|
||||
}
|
||||
|
||||
struct NodeStoreEx* App_getMetaNodes(App* this)
|
||||
{
|
||||
return this->metaNodes;
|
||||
}
|
||||
|
||||
struct NodeStoreEx* App_getStorageNodes(App* this)
|
||||
{
|
||||
return this->storageNodes;
|
||||
}
|
||||
|
||||
struct TargetMapper* App_getTargetMapper(App* this)
|
||||
{
|
||||
return this->targetMapper;
|
||||
}
|
||||
|
||||
struct MirrorBuddyGroupMapper* App_getStorageBuddyGroupMapper(App* this)
|
||||
{
|
||||
return this->storageBuddyGroupMapper;
|
||||
}
|
||||
|
||||
struct MirrorBuddyGroupMapper* App_getMetaBuddyGroupMapper(App* this)
|
||||
{
|
||||
return this->metaBuddyGroupMapper;
|
||||
}
|
||||
|
||||
struct TargetStateStore* App_getTargetStateStore(App* this)
|
||||
{
|
||||
return this->targetStateStore;
|
||||
}
|
||||
|
||||
struct TargetStateStore* App_getMetaStateStore(App* this)
|
||||
{
|
||||
return this->metaStateStore;
|
||||
}
|
||||
|
||||
struct NoAllocBufferStore* App_getCacheBufStore(App* this)
|
||||
{
|
||||
return this->cacheBufStore;
|
||||
}
|
||||
|
||||
struct NoAllocBufferStore* App_getPathBufStore(App* this)
|
||||
{
|
||||
return this->pathBufStore;
|
||||
}
|
||||
|
||||
struct NoAllocBufferStore* App_getMsgBufStore(App* this)
|
||||
{
|
||||
return this->msgBufStore;
|
||||
}
|
||||
|
||||
struct AcknowledgmentStore* App_getAckStore(App* this)
|
||||
{
|
||||
return this->ackStore;
|
||||
}
|
||||
|
||||
struct InodeRefStore* App_getInodeRefStore(App* this)
|
||||
{
|
||||
return this->inodeRefStore;
|
||||
}
|
||||
|
||||
struct StatFsCache* App_getStatFsCache(App* this)
|
||||
{
|
||||
return this->statfsCache;
|
||||
}
|
||||
|
||||
struct DatagramListener* App_getDatagramListener(App* this)
|
||||
{
|
||||
return this->dgramListener;
|
||||
}
|
||||
|
||||
struct InternodeSyncer* App_getInternodeSyncer(App* this)
|
||||
{
|
||||
return this->internodeSyncer;
|
||||
}
|
||||
|
||||
struct AckManager* App_getAckManager(App* this)
|
||||
{
|
||||
return this->ackManager;
|
||||
}
|
||||
|
||||
AtomicInt* App_getLockAckAtomicCounter(App* this)
|
||||
{
|
||||
return &this->lockAckAtomicCounter;
|
||||
}
|
||||
|
||||
bool App_getConnRetriesEnabled(App* this)
|
||||
{
|
||||
return this->connRetriesEnabled;
|
||||
}
|
||||
|
||||
void App_setConnRetriesEnabled(App* this, bool connRetriesEnabled)
|
||||
{
|
||||
this->connRetriesEnabled = connRetriesEnabled;
|
||||
}
|
||||
|
||||
bool App_getNetBenchModeEnabled(App* this)
|
||||
{
|
||||
return this->netBenchModeEnabled;
|
||||
}
|
||||
|
||||
void App_setNetBenchModeEnabled(App* this, bool netBenchModeEnabled)
|
||||
{
|
||||
this->netBenchModeEnabled = netBenchModeEnabled;
|
||||
}
|
||||
|
||||
struct inode_operations* App_getFileInodeOps(App* this)
|
||||
{
|
||||
return this->fileInodeOps;
|
||||
}
|
||||
|
||||
struct inode_operations* App_getSymlinkInodeOps(App* this)
|
||||
{
|
||||
return this->symlinkInodeOps;
|
||||
}
|
||||
|
||||
struct inode_operations* App_getDirInodeOps(App* this)
|
||||
{
|
||||
return this->dirInodeOps;
|
||||
}
|
||||
|
||||
struct inode_operations* App_getSpecialInodeOps(App* this)
|
||||
{
|
||||
return this->specialInodeOps;
|
||||
}
|
||||
|
||||
#ifdef BEEGFS_DEBUG
|
||||
|
||||
size_t App_getNumRPCs(App* this)
|
||||
{
|
||||
return this->numRPCs;
|
||||
}
|
||||
|
||||
void App_incNumRPCs(App* this)
|
||||
{
|
||||
Mutex_lock(&this->debugCounterMutex);
|
||||
this->numRPCs++;
|
||||
Mutex_unlock(&this->debugCounterMutex);
|
||||
}
|
||||
|
||||
size_t App_getNumRemoteReads(App* this)
|
||||
{
|
||||
return this->numRemoteReads;
|
||||
}
|
||||
|
||||
void App_incNumRemoteReads(App* this)
|
||||
{
|
||||
Mutex_lock(&this->debugCounterMutex);
|
||||
this->numRemoteReads++;
|
||||
Mutex_unlock(&this->debugCounterMutex);
|
||||
}
|
||||
|
||||
size_t App_getNumRemoteWrites(App* this)
|
||||
{
|
||||
return this->numRemoteWrites;
|
||||
}
|
||||
|
||||
void App_incNumRemoteWrites(App* this)
|
||||
{
|
||||
Mutex_lock(&this->debugCounterMutex);
|
||||
this->numRemoteWrites++;
|
||||
Mutex_unlock(&this->debugCounterMutex);
|
||||
}
|
||||
|
||||
#else // BEEGFS_DEBUG
|
||||
|
||||
#define App_incNumRPCs(this)
|
||||
#define App_incNumRemoteReads(this)
|
||||
#define App_incNumRemoteWrites(this)
|
||||
|
||||
#endif // BEEGFS_DEBUG
|
||||
|
||||
|
||||
#endif /*APP_H_*/
|
||||
1557
client_module/source/app/config/Config.c
Normal file
1557
client_module/source/app/config/Config.c
Normal file
File diff suppressed because it is too large
Load Diff
758
client_module/source/app/config/Config.h
Normal file
758
client_module/source/app/config/Config.h
Normal file
@@ -0,0 +1,758 @@
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <common/toolkit/list/StrCpyListIter.h>
|
||||
#include <common/toolkit/list/UInt16ListIter.h>
|
||||
#include <common/toolkit/tree/StrCpyMap.h>
|
||||
#include <common/toolkit/tree/StrCpyMapIter.h>
|
||||
#include <common/toolkit/StringTk.h>
|
||||
#include <app/config/MountConfig.h>
|
||||
|
||||
|
||||
struct Config;
|
||||
typedef struct Config Config;
|
||||
|
||||
enum FileCacheType;
|
||||
typedef enum FileCacheType FileCacheType;
|
||||
|
||||
enum InodeIDStyle;
|
||||
typedef enum InodeIDStyle InodeIDStyle;
|
||||
|
||||
enum RDMAKeyType;
|
||||
typedef enum RDMAKeyType RDMAKeyType;
|
||||
|
||||
enum CheckCapabilities;
|
||||
typedef enum CheckCapabilities CheckCapabilities;
|
||||
|
||||
enum EventLogMask
|
||||
{
|
||||
EventLogMask_NONE = 0,
|
||||
EventLogMask_FLUSH = 1,
|
||||
EventLogMask_TRUNC = 2,
|
||||
EventLogMask_SETATTR = 4,
|
||||
EventLogMask_CLOSE = 8,
|
||||
EventLogMask_LINK_OP = 16,
|
||||
EventLogMask_OPEN_READ = 32,
|
||||
EventLogMask_OPEN_WRITE = 64,
|
||||
EventLogMask_OPEN_READ_WRITE = 128
|
||||
};
|
||||
|
||||
|
||||
extern __must_check bool Config_init(Config* this, MountConfig* mountConfig);
|
||||
extern Config* Config_construct(MountConfig* mountConfig);
|
||||
extern void Config_uninit(Config* this);
|
||||
extern void Config_destruct(Config* this);
|
||||
|
||||
extern bool _Config_initConfig(Config* this, MountConfig* mountConfig);
|
||||
extern StrCpyMapIter _Config_eraseFromConfigMap(Config* this, StrCpyMapIter* iter);
|
||||
extern void _Config_loadDefaults(Config* this);
|
||||
extern bool _Config_applyConfigMap(Config* this);
|
||||
extern void _Config_configMapRedefine(Config* this, char* keyStr, const char* valueStr);
|
||||
extern void __Config_addLineToConfigMap(Config* this, char* line);
|
||||
|
||||
extern void __Config_loadFromMountConfig(Config* this, MountConfig* mountConfig);
|
||||
extern bool __Config_loadFromFile(struct Config* this, const char* filename);
|
||||
extern bool Config_loadStringListFile(const char* filename,
|
||||
StrCpyList* outList);
|
||||
extern bool Config_loadUInt16ListFile(struct Config* this, const char* filename,
|
||||
UInt16List* outList);
|
||||
|
||||
extern bool __Config_initImplicitVals(Config* this);
|
||||
extern void __Config_initConnNumCommRetries(Config* this);
|
||||
extern void __Config_initTuneFileCacheTypeNum(Config* this);
|
||||
void __Config_initSysInodeIDStyleNum(Config* this);
|
||||
bool __Config_initConnAuthHash(Config* this, char* connAuthFile, uint64_t* outConnAuthHash);
|
||||
void __Config_initConnRDMAKeyTypeNum(Config* this);
|
||||
|
||||
// conversion
|
||||
const char* Config_fileCacheTypeNumToStr(FileCacheType cacheType);
|
||||
const char* Config_inodeIDStyleNumToStr(InodeIDStyle inodeIDStyle);
|
||||
const char* Config_eventLogMaskToStr(enum EventLogMask mask);
|
||||
const char* Config_rdmaKeyTypeNumToStr(RDMAKeyType keyType);
|
||||
const char* Config_checkCapabilitiesTypeToStr(CheckCapabilities checkCapabilities);
|
||||
|
||||
// getters & setters
|
||||
static inline char* Config_getCfgFile(Config* this);
|
||||
static inline int Config_getLogLevel(Config* this);
|
||||
static inline bool Config_getLogClientID(Config* this);
|
||||
static inline bool Config_getConnUseRDMA(Config* this);
|
||||
static inline bool Config_getConnTCPFallbackEnabled(Config* this);
|
||||
static inline int Config_getConnClientPort(Config* this);
|
||||
static inline int Config_getConnMgmtdPort(Config* this);
|
||||
static inline int Config_getConnMgmtdGrpcPort(Config* this);
|
||||
static inline void Config_setConnMgmtdGrpcPort(Config* this, int port);
|
||||
static inline unsigned Config_getConnMaxInternodeNum(Config* this);
|
||||
static inline char* Config_getConnInterfacesFile(Config* this);
|
||||
static inline char* Config_getConnInterfacesList(Config* this);
|
||||
static inline char* Config_getConnRDMAInterfacesFile(Config* this);
|
||||
static inline unsigned Config_getConnFallbackExpirationSecs(Config* this);
|
||||
static inline unsigned Config_getConnNumCommRetries(Config* this);
|
||||
static inline unsigned Config_getConnCommRetrySecs(Config* this);
|
||||
static inline bool Config_getConnUnmountRetries(Config* this);
|
||||
static inline int Config_getConnTCPRcvBufSize(Config* this);
|
||||
static inline int Config_getConnUDPRcvBufSize(Config* this);
|
||||
static inline unsigned Config_getConnRDMABufSize(Config* this);
|
||||
static inline unsigned Config_getConnRDMAFragmentSize(Config* this);
|
||||
static inline unsigned Config_getConnRDMABufNum(Config* this);
|
||||
static inline unsigned Config_getConnRDMAMetaBufSize(Config* this);
|
||||
static inline unsigned Config_getConnRDMAMetaBufNum(Config* this);
|
||||
static inline unsigned Config_getConnRDMAMetaFragmentSize(Config* this);
|
||||
static inline char* Config_getConnRDMAKeyType(Config* this);
|
||||
static inline RDMAKeyType Config_getConnRDMAKeyTypeNum(Config* this);
|
||||
static inline int Config_getConnRDMATypeOfService(Config* this);
|
||||
static inline unsigned Config_getRemapConnectionFailureStatus(Config* this);
|
||||
static inline void Config_setRemapConnectionFailureStatus(Config* this, unsigned status);
|
||||
static inline char* Config_getConnNetFilterFile(Config* this);
|
||||
static inline unsigned Config_getConnMaxConcurrentAttempts(Config* this);
|
||||
static inline char* Config_getConnAuthFile(Config* this);
|
||||
static inline bool Config_getConnDisableAuthentication(Config* this);
|
||||
static inline uint64_t Config_getConnAuthHash(Config* this);
|
||||
static inline char* Config_getConnTcpOnlyFilterFile(Config* this);
|
||||
static inline char* Config_getTunePreferredMetaFile(Config* this);
|
||||
static inline char* Config_getTunePreferredStorageFile(Config* this);
|
||||
static inline char* Config_getTuneFileCacheType(Config* this);
|
||||
static inline FileCacheType Config_getTuneFileCacheTypeNum(Config* this);
|
||||
static inline int Config_getTuneFileCacheBufSize(Config* this);
|
||||
static inline int Config_getTuneFileCacheBufNum(Config* this);
|
||||
static inline int Config_getTunePathBufSize(Config* this);
|
||||
static inline int Config_getTunePathBufNum(Config* this);
|
||||
static inline int Config_getTuneMsgBufSize(Config* this);
|
||||
static inline int Config_getTuneMsgBufNum(Config* this);
|
||||
static inline unsigned Config_getTunePageCacheValidityMS(Config* this);
|
||||
static inline unsigned Config_getTuneDirSubentryCacheValidityMS(Config* this);
|
||||
static inline unsigned Config_getTuneFileSubentryCacheValidityMS(Config* this);
|
||||
static inline unsigned Config_getTuneENOENTCacheValidityMS(Config* this);
|
||||
static inline bool Config_getTuneRemoteFSync(Config* this);
|
||||
static inline bool Config_getTuneUseGlobalFileLocks(Config* this);
|
||||
static inline bool Config_getTuneRefreshOnGetAttr(Config* this);
|
||||
static inline void Config_setTuneRefreshOnGetAttr(Config* this);
|
||||
static inline unsigned Config_getTuneInodeBlockBits(Config* this);
|
||||
static inline unsigned Config_getTuneInodeBlockSize(Config* this);
|
||||
static inline bool Config_getTuneEarlyCloseResponse(Config* this);
|
||||
static inline bool Config_getTuneUseGlobalAppendLocks(Config* this);
|
||||
static inline bool Config_getTuneUseBufferedAppend(Config* this);
|
||||
static inline unsigned Config_getTuneStatFsCacheSecs(Config* this);
|
||||
static inline bool Config_getTuneCoherentBuffers(Config* this);
|
||||
|
||||
static inline char* Config_getSysMgmtdHost(Config* this);
|
||||
static inline char* Config_getSysInodeIDStyle(Config* this);
|
||||
static inline InodeIDStyle Config_getSysInodeIDStyleNum(Config* this);
|
||||
static inline bool Config_getSysCacheInvalidationVersion(Config* this);
|
||||
static inline bool Config_getSysCreateHardlinksAsSymlinks(Config* this);
|
||||
static inline unsigned Config_getSysMountSanityCheckMS(Config* this);
|
||||
static inline bool Config_getSysSyncOnClose(Config* this);
|
||||
static inline bool Config_getSysSessionCheckOnClose(Config* this);
|
||||
static inline bool Config_getSysSessionChecksEnabled(Config* this);
|
||||
static inline unsigned Config_getSysUpdateTargetStatesSecs(Config* this);
|
||||
static inline unsigned Config_getSysTargetOfflineTimeoutSecs(Config* this);
|
||||
static inline bool Config_getSysXAttrsEnabled(Config* this);
|
||||
static inline CheckCapabilities Config_getSysXAttrsCheckCapabilities (Config* this);
|
||||
static inline bool Config_getSysACLsEnabled(Config* this);
|
||||
static inline bool Config_getSysXAttrsImplicitlyEnabled(Config* this);
|
||||
static inline bool Config_getSysBypassFileAccessCheckOnMeta(Config* this);
|
||||
|
||||
static inline bool Config_getQuotaEnabled(Config* this);
|
||||
static inline char* Config_getConnMessagingTimeouts(Config* this);
|
||||
static inline char* Config_getConnRDMATimeouts(Config* this);
|
||||
static inline int Config_getConnRDMATimeoutConnect(Config* this);
|
||||
static inline int Config_getConnRDMATimeoutCompletion(Config* this);
|
||||
static inline int Config_getConnRDMATimeoutFlowSend(Config* this);
|
||||
static inline int Config_getConnRDMATimeoutFlowRecv(Config* this);
|
||||
static inline int Config_getConnRDMATimeoutPoll(Config* this);
|
||||
|
||||
|
||||
enum FileCacheType
|
||||
{ FILECACHETYPE_None = 0, FILECACHETYPE_Buffered = 1, FILECACHETYPE_Paged = 2,
|
||||
FILECACHETYPE_Native = 3};
|
||||
|
||||
|
||||
#define INODEIDSTYLE_HASH32HSIEH_STR "hash32"
|
||||
#define INODEIDSTYLE_HASH64HSIEH_STR "hash64"
|
||||
#define INODEIDSTYLE_HASH32MD4_STR "md4hash32"
|
||||
#define INODEIDSTYLE_HASH64MD4_STR "md4hash64"
|
||||
#define INODEIDSTYLE_DEFAULT INODEIDSTYLE_HASH64MD4_STR
|
||||
|
||||
enum InodeIDStyle
|
||||
{
|
||||
INODEIDSTYLE_Hash32Hsieh = 0, // hsieh32
|
||||
INODEIDSTYLE_Hash32MD4, // half-md4
|
||||
INODEIDSTYLE_Hash64HSieh, // hsieh32
|
||||
INODEIDSTYLE_Hash64MD4 // half-md4
|
||||
};
|
||||
#define INODEIDSTYLE_Default INODEIDSTYLE_Hash64MD4
|
||||
|
||||
#define RDMAKEYTYPE_UNSAFE_GLOBAL_STR "global"
|
||||
#define RDMAKEYTYPE_UNSAFE_DMA_STR "dma"
|
||||
#define RDMAKEYTYPE_REGISTER_STR "register"
|
||||
|
||||
enum RDMAKeyType
|
||||
{
|
||||
RDMAKEYTYPE_UnsafeGlobal = 0,
|
||||
RDMAKEYTYPE_UnsafeDMA,
|
||||
RDMAKEYTYPE_Register
|
||||
};
|
||||
|
||||
#define CHECKCAPABILITIES_ALWAYS_STR "always"
|
||||
#define CHECKCAPABILITIES_CACHE_STR "cache"
|
||||
#define CHECKCAPABILITIES_NEVER_STR "never"
|
||||
|
||||
enum CheckCapabilities
|
||||
{
|
||||
CHECKCAPABILITIES_Always = 0,
|
||||
CHECKCAPABILITIES_Cache,
|
||||
CHECKCAPABILITIES_Never
|
||||
};
|
||||
|
||||
struct Config
|
||||
{
|
||||
// configurables
|
||||
char* cfgFile;
|
||||
|
||||
int logLevel;
|
||||
bool logClientID;
|
||||
|
||||
int connPortShift; // shifts all UDP and TCP ports
|
||||
int connClientPort;
|
||||
int connMgmtdPort;
|
||||
int connMgmtdGrpcPort; // pulled from mgmtd and not meant to be configured by the user
|
||||
bool connUseRDMA;
|
||||
bool connTCPFallbackEnabled;
|
||||
unsigned connMaxInternodeNum;
|
||||
char* connInterfacesFile;
|
||||
char* connInterfacesList;
|
||||
char* connRDMAInterfacesFile;
|
||||
unsigned connFallbackExpirationSecs;
|
||||
unsigned connNumCommRetries; // auto-computed from connCommRetrySecs
|
||||
unsigned connCommRetrySecs;
|
||||
bool connUnmountRetries;
|
||||
int connTCPRcvBufSize;
|
||||
int connUDPRcvBufSize;
|
||||
int connRDMABufSize;
|
||||
int connRDMAFragmentSize;
|
||||
int connRDMABufNum;
|
||||
int connRDMAMetaBufSize;
|
||||
int connRDMAMetaFragmentSize;
|
||||
int connRDMAMetaBufNum;
|
||||
int connRDMATypeOfService;
|
||||
char* connRDMAKeyType;
|
||||
RDMAKeyType connRDMAKeyTypeNum;
|
||||
char* connNetFilterFile; // allowed IP addresses (all IPs allowed, if empty)
|
||||
unsigned connMaxConcurrentAttempts;
|
||||
char* connAuthFile;
|
||||
bool connDisableAuthentication;
|
||||
uint64_t connAuthHash; // implicitly set based on hash of connAuthFile contents
|
||||
char* connTcpOnlyFilterFile; // allow only plain TCP (no RDMA etc) to these IPs
|
||||
|
||||
char* connMessagingTimeouts;
|
||||
int connMsgLongTimeout;
|
||||
int connMsgMediumTimeout;
|
||||
int connMsgShortTimeout; // connection (response) timeouts in ms
|
||||
// note: be careful here, because servers not
|
||||
// responding for >30secs under high load is nothing
|
||||
// unusual, so never use connMsgShortTimeout for
|
||||
// IO-related operations.
|
||||
char* connRDMATimeouts;
|
||||
int connRDMATimeoutConnect;
|
||||
int connRDMATimeoutCompletion;
|
||||
int connRDMATimeoutFlowSend;
|
||||
int connRDMATimeoutFlowRecv;
|
||||
int connRDMATimeoutPoll;
|
||||
|
||||
char* tunePreferredMetaFile;
|
||||
char* tunePreferredStorageFile;
|
||||
char* tuneFileCacheType;
|
||||
FileCacheType tuneFileCacheTypeNum; // auto-generated based on tuneFileCacheType
|
||||
int tuneFileCacheBufSize;
|
||||
int tuneFileCacheBufNum; // 0 means automatic setting
|
||||
unsigned tunePageCacheValidityMS;
|
||||
unsigned tuneDirSubentryCacheValidityMS;
|
||||
unsigned tuneFileSubentryCacheValidityMS;
|
||||
unsigned tuneENOENTCacheValidityMS;
|
||||
int tunePathBufSize;
|
||||
int tunePathBufNum;
|
||||
int tuneMsgBufSize;
|
||||
int tuneMsgBufNum; // 0 means automatic setting
|
||||
bool tuneRemoteFSync;
|
||||
bool tuneUseGlobalFileLocks; // false means local flock/fcntl locks
|
||||
bool tuneRefreshOnGetAttr; // false means don't refresh on getattr
|
||||
unsigned tuneInodeBlockBits; // bitshift for optimal io size seen by stat() (2^n)
|
||||
unsigned tuneInodeBlockSize; // auto-generated based on tuneInodeBlockBits
|
||||
bool tuneEarlyCloseResponse; // don't wait for chunk files close result
|
||||
bool tuneUseGlobalAppendLocks; // false means local append locks
|
||||
bool tuneUseBufferedAppend; // false disables buffering of append writes
|
||||
unsigned tuneStatFsCacheSecs; // 0 disables caching of free space info from servers
|
||||
bool tuneCoherentBuffers; // try to keep buffer cache and page cache coherent
|
||||
|
||||
char* sysMgmtdHost;
|
||||
char* sysInodeIDStyle;
|
||||
InodeIDStyle sysInodeIDStyleNum; // auto-generated based on sysInodeIDStyle
|
||||
bool sysCacheInvalidationVersion;
|
||||
bool sysCreateHardlinksAsSymlinks;
|
||||
unsigned sysMountSanityCheckMS;
|
||||
bool sysSyncOnClose;
|
||||
bool sysSessionCheckOnClose;
|
||||
bool sysSessionChecksEnabled;
|
||||
unsigned sysUpdateTargetStatesSecs;
|
||||
unsigned sysTargetOfflineTimeoutSecs;
|
||||
|
||||
bool sysXAttrsEnabled;
|
||||
CheckCapabilities sysXAttrsCheckCapabilities;
|
||||
bool sysACLsEnabled;
|
||||
bool sysXAttrsImplicitlyEnabled; // True when XAttrs have not been enabled in the config file
|
||||
// but have been enabled by __Config_initImplicitVals
|
||||
// because ACLs are enabled in the config and XAs are needed
|
||||
// to store the ACLs.
|
||||
bool sysBypassFileAccessCheckOnMeta; // bypass file access check on meta server
|
||||
|
||||
bool quotaEnabled;
|
||||
enum EventLogMask eventLogMask;
|
||||
|
||||
/* workaround for rename of closed files on nfs */
|
||||
bool sysRenameEbusyAsXdev;
|
||||
|
||||
|
||||
// internals
|
||||
StrCpyMap configMap;
|
||||
|
||||
// testing
|
||||
unsigned remapConnectionFailureStatus;
|
||||
};
|
||||
|
||||
char* Config_getCfgFile(Config* this)
|
||||
{
|
||||
return this->cfgFile;
|
||||
}
|
||||
|
||||
int Config_getLogLevel(Config* this)
|
||||
{
|
||||
return this->logLevel;
|
||||
}
|
||||
|
||||
bool Config_getLogClientID(Config* this)
|
||||
{
|
||||
return this->logClientID;
|
||||
}
|
||||
|
||||
int Config_getConnClientPort(Config* this)
|
||||
{
|
||||
return this->connClientPort ? (this->connClientPort + this->connPortShift) : 0;
|
||||
}
|
||||
|
||||
int Config_getConnMgmtdPort(Config* this)
|
||||
{
|
||||
return this->connMgmtdPort ? (this->connMgmtdPort + this->connPortShift) : 0;
|
||||
}
|
||||
|
||||
int Config_getConnMgmtdGrpcPort(Config* this)
|
||||
{
|
||||
// not adding port shift here because connMgmtdGrpcPort is pulled from mgmtd and already shifted
|
||||
return this->connMgmtdGrpcPort ? this->connMgmtdGrpcPort : 0;
|
||||
}
|
||||
|
||||
void Config_setConnMgmtdGrpcPort(Config* this, int port)
|
||||
{
|
||||
this->connMgmtdGrpcPort = port;
|
||||
}
|
||||
|
||||
bool Config_getConnUseRDMA(Config* this)
|
||||
{
|
||||
return this->connUseRDMA;
|
||||
}
|
||||
|
||||
bool Config_getConnTCPFallbackEnabled(Config* this)
|
||||
{
|
||||
return this->connTCPFallbackEnabled;
|
||||
}
|
||||
|
||||
unsigned Config_getConnMaxInternodeNum(Config* this)
|
||||
{
|
||||
return this->connMaxInternodeNum;
|
||||
}
|
||||
|
||||
char* Config_getConnInterfacesFile(Config* this)
|
||||
{
|
||||
return this->connInterfacesFile;
|
||||
}
|
||||
|
||||
char* Config_getConnInterfacesList(Config* this)
|
||||
{
|
||||
return this->connInterfacesList;
|
||||
}
|
||||
|
||||
char* Config_getConnRDMAInterfacesFile(Config* this)
|
||||
{
|
||||
return this->connRDMAInterfacesFile;
|
||||
}
|
||||
|
||||
unsigned Config_getConnFallbackExpirationSecs(Config* this)
|
||||
{
|
||||
return this->connFallbackExpirationSecs;
|
||||
}
|
||||
|
||||
unsigned Config_getConnNumCommRetries(Config* this)
|
||||
{
|
||||
return this->connNumCommRetries;
|
||||
}
|
||||
|
||||
unsigned Config_getConnCommRetrySecs(Config* this)
|
||||
{
|
||||
return this->connCommRetrySecs;
|
||||
}
|
||||
|
||||
bool Config_getConnUnmountRetries(Config* this)
|
||||
{
|
||||
return this->connUnmountRetries;
|
||||
}
|
||||
|
||||
int Config_getConnTCPRcvBufSize(Config* this)
|
||||
{
|
||||
return this->connTCPRcvBufSize;
|
||||
}
|
||||
|
||||
int Config_getConnUDPRcvBufSize(Config* this)
|
||||
{
|
||||
return this->connUDPRcvBufSize;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMABufSize(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMABufSize;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMAFragmentSize(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMAFragmentSize;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMABufNum(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMABufNum;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMAMetaBufSize(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMAMetaBufSize;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMAMetaFragmentSize(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMAMetaFragmentSize;
|
||||
}
|
||||
|
||||
unsigned Config_getConnRDMAMetaBufNum(Config* this)
|
||||
{
|
||||
return (unsigned) this->connRDMAMetaBufNum;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATypeOfService(Config* this)
|
||||
{
|
||||
return this->connRDMATypeOfService;
|
||||
}
|
||||
|
||||
char* Config_getConnRDMAKeyType(Config* this)
|
||||
{
|
||||
return this->connRDMAKeyType;
|
||||
}
|
||||
|
||||
RDMAKeyType Config_getConnRDMAKeyTypeNum(Config* this)
|
||||
{
|
||||
return this->connRDMAKeyTypeNum;
|
||||
}
|
||||
|
||||
unsigned Config_getRemapConnectionFailureStatus(Config* this)
|
||||
{
|
||||
return this->remapConnectionFailureStatus;
|
||||
}
|
||||
|
||||
void Config_setRemapConnectionFailureStatus(Config* this, unsigned status)
|
||||
{
|
||||
this->remapConnectionFailureStatus = status;
|
||||
}
|
||||
|
||||
char* Config_getConnNetFilterFile(Config* this)
|
||||
{
|
||||
return this->connNetFilterFile;
|
||||
}
|
||||
|
||||
unsigned Config_getConnMaxConcurrentAttempts(Config* this)
|
||||
{
|
||||
return this->connMaxConcurrentAttempts;
|
||||
}
|
||||
|
||||
char* Config_getConnAuthFile(Config* this)
|
||||
{
|
||||
return this->connAuthFile;
|
||||
}
|
||||
|
||||
bool Config_getConnDisableAuthentication(Config* this)
|
||||
{
|
||||
return this->connDisableAuthentication;
|
||||
}
|
||||
|
||||
uint64_t Config_getConnAuthHash(Config* this)
|
||||
{
|
||||
return this->connAuthHash;
|
||||
}
|
||||
|
||||
char* Config_getConnTcpOnlyFilterFile(Config* this)
|
||||
{
|
||||
return this->connTcpOnlyFilterFile;
|
||||
}
|
||||
|
||||
char* Config_getTunePreferredMetaFile(Config* this)
|
||||
{
|
||||
return this->tunePreferredMetaFile;
|
||||
}
|
||||
|
||||
char* Config_getTunePreferredStorageFile(Config* this)
|
||||
{
|
||||
return this->tunePreferredStorageFile;
|
||||
}
|
||||
|
||||
char* Config_getTuneFileCacheType(Config* this)
|
||||
{
|
||||
return this->tuneFileCacheType;
|
||||
}
|
||||
|
||||
FileCacheType Config_getTuneFileCacheTypeNum(Config* this)
|
||||
{
|
||||
return this->tuneFileCacheTypeNum;
|
||||
}
|
||||
|
||||
int Config_getTuneFileCacheBufSize(Config* this)
|
||||
{
|
||||
return this->tuneFileCacheBufSize;
|
||||
}
|
||||
|
||||
int Config_getTuneFileCacheBufNum(Config* this)
|
||||
{
|
||||
return this->tuneFileCacheBufNum;
|
||||
}
|
||||
|
||||
int Config_getTunePathBufSize(Config* this)
|
||||
{
|
||||
return this->tunePathBufSize;
|
||||
}
|
||||
|
||||
int Config_getTunePathBufNum(Config* this)
|
||||
{
|
||||
return this->tunePathBufNum;
|
||||
}
|
||||
|
||||
int Config_getTuneMsgBufSize(Config* this)
|
||||
{
|
||||
return this->tuneMsgBufSize;
|
||||
}
|
||||
|
||||
int Config_getTuneMsgBufNum(Config* this)
|
||||
{
|
||||
return this->tuneMsgBufNum;
|
||||
}
|
||||
|
||||
unsigned Config_getTunePageCacheValidityMS(Config* this)
|
||||
{
|
||||
return this->tunePageCacheValidityMS;
|
||||
}
|
||||
|
||||
unsigned Config_getTuneDirSubentryCacheValidityMS(Config* this)
|
||||
{
|
||||
return this->tuneDirSubentryCacheValidityMS;
|
||||
}
|
||||
|
||||
unsigned Config_getTuneFileSubentryCacheValidityMS(Config* this)
|
||||
{
|
||||
return this->tuneFileSubentryCacheValidityMS;
|
||||
}
|
||||
|
||||
unsigned Config_getTuneENOENTCacheValidityMS(Config* this)
|
||||
{
|
||||
return this->tuneENOENTCacheValidityMS;
|
||||
}
|
||||
|
||||
bool Config_getTuneRemoteFSync(Config* this)
|
||||
{
|
||||
return this->tuneRemoteFSync;
|
||||
}
|
||||
|
||||
bool Config_getTuneUseGlobalFileLocks(Config* this)
|
||||
{
|
||||
return this->tuneUseGlobalFileLocks;
|
||||
}
|
||||
|
||||
bool Config_getTuneRefreshOnGetAttr(Config* this)
|
||||
{
|
||||
return this->tuneRefreshOnGetAttr;
|
||||
}
|
||||
|
||||
bool Config_getTuneCoherentBuffers(Config* this)
|
||||
{
|
||||
return this->tuneCoherentBuffers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special function to automatically enable TuneRefreshOnGetAttr, e.g. for NFS exports.
|
||||
*
|
||||
* Note: We do not use any locks here assuming the right value will propate to all cores rather
|
||||
* soon.
|
||||
*/
|
||||
void Config_setTuneRefreshOnGetAttr(Config* this)
|
||||
{
|
||||
this->tuneRefreshOnGetAttr = true;
|
||||
|
||||
// do a memory barrier, so that other CPUs get the new value as soon as possible
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
|
||||
unsigned Config_getTuneInodeBlockBits(Config* this)
|
||||
{
|
||||
return this->tuneInodeBlockBits;
|
||||
}
|
||||
|
||||
unsigned Config_getTuneInodeBlockSize(Config* this)
|
||||
{
|
||||
return this->tuneInodeBlockSize;
|
||||
}
|
||||
|
||||
bool Config_getTuneEarlyCloseResponse(Config* this)
|
||||
{
|
||||
return this->tuneEarlyCloseResponse;
|
||||
}
|
||||
|
||||
bool Config_getTuneUseGlobalAppendLocks(Config* this)
|
||||
{
|
||||
return this->tuneUseGlobalAppendLocks;
|
||||
}
|
||||
|
||||
bool Config_getTuneUseBufferedAppend(Config* this)
|
||||
{
|
||||
return this->tuneUseBufferedAppend;
|
||||
}
|
||||
|
||||
unsigned Config_getTuneStatFsCacheSecs(Config* this)
|
||||
{
|
||||
return this->tuneStatFsCacheSecs;
|
||||
}
|
||||
|
||||
char* Config_getSysMgmtdHost(Config* this)
|
||||
{
|
||||
return this->sysMgmtdHost;
|
||||
}
|
||||
|
||||
char* Config_getSysInodeIDStyle(Config* this)
|
||||
{
|
||||
return this->sysInodeIDStyle;
|
||||
}
|
||||
|
||||
InodeIDStyle Config_getSysInodeIDStyleNum(Config* this)
|
||||
{
|
||||
return this->sysInodeIDStyleNum;
|
||||
}
|
||||
|
||||
bool Config_getSysCacheInvalidationVersion(Config* this)
|
||||
{
|
||||
return this->sysCacheInvalidationVersion;
|
||||
}
|
||||
|
||||
bool Config_getSysCreateHardlinksAsSymlinks(Config* this)
|
||||
{
|
||||
return this->sysCreateHardlinksAsSymlinks;
|
||||
}
|
||||
|
||||
unsigned Config_getSysMountSanityCheckMS(Config* this)
|
||||
{
|
||||
return this->sysMountSanityCheckMS;
|
||||
}
|
||||
|
||||
bool Config_getSysSyncOnClose(Config* this)
|
||||
{
|
||||
return this->sysSyncOnClose;
|
||||
}
|
||||
|
||||
bool Config_getSysSessionCheckOnClose(Config* this)
|
||||
{
|
||||
return this->sysSessionCheckOnClose;
|
||||
}
|
||||
|
||||
bool Config_getSysSessionChecksEnabled(Config* this)
|
||||
{
|
||||
return this->sysSessionChecksEnabled;
|
||||
}
|
||||
|
||||
unsigned Config_getSysUpdateTargetStatesSecs(Config* this)
|
||||
{
|
||||
return this->sysUpdateTargetStatesSecs;
|
||||
}
|
||||
|
||||
unsigned Config_getSysTargetOfflineTimeoutSecs(Config* this)
|
||||
{
|
||||
return this->sysTargetOfflineTimeoutSecs;
|
||||
}
|
||||
|
||||
bool Config_getSysXAttrsEnabled(Config* this)
|
||||
{
|
||||
return this->sysXAttrsEnabled;
|
||||
}
|
||||
|
||||
CheckCapabilities Config_getSysXAttrsCheckCapabilities(Config* this)
|
||||
{
|
||||
return this->sysXAttrsCheckCapabilities;
|
||||
}
|
||||
|
||||
bool Config_getSysACLsEnabled(Config* this)
|
||||
{
|
||||
return this->sysACLsEnabled;
|
||||
}
|
||||
|
||||
bool Config_getSysXAttrsImplicitlyEnabled(Config* this)
|
||||
{
|
||||
return this->sysXAttrsImplicitlyEnabled;
|
||||
}
|
||||
|
||||
bool Config_getSysBypassFileAccessCheckOnMeta(Config* this)
|
||||
{
|
||||
return this->sysBypassFileAccessCheckOnMeta;
|
||||
}
|
||||
|
||||
bool Config_getQuotaEnabled(Config* this)
|
||||
{
|
||||
return this->quotaEnabled;
|
||||
}
|
||||
|
||||
char* Config_getConnMessagingTimeouts(Config* this)
|
||||
{
|
||||
return this->connMessagingTimeouts;
|
||||
}
|
||||
|
||||
char* Config_getConnRDMATimeouts(Config* this)
|
||||
{
|
||||
return this->connRDMATimeouts;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATimeoutConnect(Config* this)
|
||||
{
|
||||
return this->connRDMATimeoutConnect;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATimeoutCompletion(Config* this)
|
||||
{
|
||||
return this->connRDMATimeoutCompletion;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATimeoutFlowSend(Config* this)
|
||||
{
|
||||
return this->connRDMATimeoutFlowSend;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATimeoutFlowRecv(Config* this)
|
||||
{
|
||||
return this->connRDMATimeoutFlowRecv;
|
||||
}
|
||||
|
||||
int Config_getConnRDMATimeoutPoll(Config* this)
|
||||
{
|
||||
return this->connRDMATimeoutPoll;
|
||||
}
|
||||
|
||||
#endif /*CONFIG_H_*/
|
||||
238
client_module/source/app/config/MountConfig.c
Normal file
238
client_module/source/app/config/MountConfig.c
Normal file
@@ -0,0 +1,238 @@
|
||||
#include <app/config/MountConfig.h>
|
||||
#include <common/toolkit/list/StrCpyList.h>
|
||||
#include <common/toolkit/list/StrCpyListIter.h>
|
||||
#include <common/Common.h>
|
||||
|
||||
#include <linux/parser.h>
|
||||
|
||||
|
||||
enum {
|
||||
/* Mount options that take string arguments */
|
||||
Opt_cfgFile,
|
||||
Opt_logStdFile,
|
||||
Opt_sysMgmtdHost,
|
||||
Opt_tunePreferredMetaFile,
|
||||
Opt_tunePreferredStorageFile,
|
||||
|
||||
Opt_connInterfacesList,
|
||||
Opt_connAuthFile,
|
||||
Opt_connDisableAuthentication,
|
||||
|
||||
/* Mount options that take integer arguments */
|
||||
Opt_logLevel,
|
||||
Opt_connPortShift,
|
||||
Opt_connMgmtdPort,
|
||||
Opt_sysMountSanityCheckMS,
|
||||
|
||||
/* Mount options that take no arguments */
|
||||
Opt_grpid,
|
||||
|
||||
Opt_err
|
||||
};
|
||||
|
||||
|
||||
static match_table_t fhgfs_mount_option_tokens =
|
||||
{
|
||||
/* Mount options that take string arguments */
|
||||
{ Opt_cfgFile, "cfgFile=%s" },
|
||||
{ Opt_logStdFile, "logStdFile=%s" },
|
||||
{ Opt_sysMgmtdHost, "sysMgmtdHost=%s" },
|
||||
{ Opt_tunePreferredMetaFile, "tunePreferredMetaFile=%s" },
|
||||
{ Opt_tunePreferredStorageFile, "tunePreferredStorageFile=%s" },
|
||||
|
||||
{ Opt_connInterfacesList, "connInterfacesList=%s" },
|
||||
{ Opt_connAuthFile, "connAuthFile=%s" },
|
||||
{ Opt_connDisableAuthentication, "connDisableAuthentication=%s" },
|
||||
|
||||
/* Mount options that take integer arguments */
|
||||
{ Opt_logLevel, "logLevel=%d" },
|
||||
{ Opt_connPortShift, "connPortShift=%d" },
|
||||
{ Opt_connMgmtdPort, "connMgmtdPort=%u" },
|
||||
{ Opt_sysMountSanityCheckMS, "sysMountSanityCheckMS=%u" },
|
||||
|
||||
{ Opt_grpid, "grpid" },
|
||||
|
||||
{ Opt_err, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool MountConfig_parseFromRawOptions(MountConfig* this, char* mountOptions)
|
||||
{
|
||||
char* currentOption;
|
||||
|
||||
if(!mountOptions)
|
||||
{
|
||||
printk_fhgfs_debug(KERN_INFO, "Mount options = <none>\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
printk_fhgfs_debug(KERN_INFO, "Mount options = '%s'\n", mountOptions);
|
||||
|
||||
while( (currentOption = strsep(&mountOptions, ",") ) != NULL)
|
||||
{
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
int tokenID;
|
||||
|
||||
if(!*currentOption)
|
||||
continue; // skip empty string
|
||||
|
||||
tokenID = match_token(currentOption, fhgfs_mount_option_tokens, args);
|
||||
|
||||
switch(tokenID)
|
||||
{
|
||||
/* Mount options that take STRING arguments */
|
||||
|
||||
case Opt_cfgFile:
|
||||
{
|
||||
SAFE_KFREE(this->cfgFile);
|
||||
|
||||
this->cfgFile = match_strdup(args);// (string kalloc'ed => needs kfree later)
|
||||
} break;
|
||||
|
||||
case Opt_logStdFile:
|
||||
{
|
||||
SAFE_KFREE(this->logStdFile);
|
||||
|
||||
this->logStdFile = match_strdup(args); // (string kalloc'ed => needs kfree later)
|
||||
} break;
|
||||
|
||||
case Opt_sysMgmtdHost:
|
||||
{
|
||||
SAFE_KFREE(this->sysMgmtdHost);
|
||||
|
||||
this->sysMgmtdHost = match_strdup(args); // (string kalloc'ed => needs kfree later)
|
||||
} break;
|
||||
|
||||
case Opt_tunePreferredMetaFile:
|
||||
{
|
||||
SAFE_KFREE(this->tunePreferredMetaFile);
|
||||
|
||||
this->tunePreferredMetaFile = match_strdup(args); // (string kalloc'ed => needs kfree later)
|
||||
} break;
|
||||
|
||||
case Opt_tunePreferredStorageFile:
|
||||
{
|
||||
SAFE_KFREE(this->tunePreferredStorageFile);
|
||||
|
||||
this->tunePreferredStorageFile = match_strdup(args); // (string kalloc'ed => needs kfree later)
|
||||
} break;
|
||||
|
||||
case Opt_connInterfacesList:
|
||||
{
|
||||
SAFE_KFREE(this->connInterfacesList);
|
||||
|
||||
this->connInterfacesList = match_strdup(args);
|
||||
} break;
|
||||
|
||||
case Opt_connAuthFile:
|
||||
{
|
||||
SAFE_KFREE(this->connAuthFile);
|
||||
|
||||
this->connAuthFile = match_strdup(args);
|
||||
} break;
|
||||
|
||||
case Opt_connDisableAuthentication:
|
||||
{
|
||||
SAFE_KFREE(this->connDisableAuthentication);
|
||||
|
||||
this->connDisableAuthentication = match_strdup(args);
|
||||
} break;
|
||||
|
||||
/* Mount options that take INTEGER arguments */
|
||||
|
||||
case Opt_logLevel:
|
||||
{
|
||||
if(match_int(args, &this->logLevel) )
|
||||
goto err_exit_invalid_option;
|
||||
|
||||
this->logLevelDefined = true;
|
||||
} break;
|
||||
|
||||
case Opt_connPortShift:
|
||||
{
|
||||
if(match_int(args, &this->connPortShift) )
|
||||
goto err_exit_invalid_option;
|
||||
|
||||
this->connPortShiftDefined = true;
|
||||
} break;
|
||||
|
||||
case Opt_connMgmtdPort:
|
||||
{
|
||||
if(match_int(args, &this->connMgmtdPort) )
|
||||
goto err_exit_invalid_option;
|
||||
|
||||
this->connMgmtdPortDefined = true;
|
||||
} break;
|
||||
|
||||
case Opt_sysMountSanityCheckMS:
|
||||
{
|
||||
if(match_int(args, &this->sysMountSanityCheckMS) )
|
||||
goto err_exit_invalid_option;
|
||||
|
||||
this->sysMountSanityCheckMSDefined = true;
|
||||
} break;
|
||||
|
||||
case Opt_grpid:
|
||||
this->grpid = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto err_exit_unknown_option;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
err_exit_unknown_option:
|
||||
printk_fhgfs(KERN_WARNING, "Unknown mount option: '%s'\n", currentOption);
|
||||
return false;
|
||||
|
||||
err_exit_invalid_option:
|
||||
printk_fhgfs(KERN_WARNING, "Invalid mount option: '%s'\n", currentOption);
|
||||
return false;
|
||||
}
|
||||
|
||||
void MountConfig_showOptions(MountConfig* this, struct seq_file* sf)
|
||||
{
|
||||
if (this->cfgFile)
|
||||
seq_printf(sf, ",cfgFile=%s", this->cfgFile);
|
||||
|
||||
if (this->logStdFile)
|
||||
seq_printf(sf, ",logStdFile=%s", this->logStdFile);
|
||||
|
||||
if (this->sysMgmtdHost)
|
||||
seq_printf(sf, ",sysMgmtdHost=%s", this->sysMgmtdHost);
|
||||
|
||||
if (this->tunePreferredMetaFile)
|
||||
seq_printf(sf, ",tunePreferredMetaFile=%s", this->tunePreferredMetaFile);
|
||||
|
||||
if (this->tunePreferredStorageFile)
|
||||
seq_printf(sf, ",tunePreferredStorageFile=%s", this->tunePreferredStorageFile);
|
||||
|
||||
if (this->connInterfacesList)
|
||||
seq_printf(sf, ",connInterfacesList=%s", this->connInterfacesList);
|
||||
|
||||
if (this->connAuthFile)
|
||||
seq_printf(sf, ",connAuthFile=%s", this->connInterfacesList);
|
||||
|
||||
if (this->connDisableAuthentication)
|
||||
seq_printf(sf, ",connDisableAuthentication=%s", this->connInterfacesList);
|
||||
|
||||
if (this->logLevelDefined)
|
||||
seq_printf(sf, ",logLevel=%d", this->logLevel);
|
||||
|
||||
if (this->connPortShiftDefined)
|
||||
seq_printf(sf, ",connPortShift=%d", this->connPortShift);
|
||||
|
||||
if (this->connMgmtdPortDefined)
|
||||
seq_printf(sf, ",connMgmtdPort=%u", this->connMgmtdPort);
|
||||
|
||||
if (this->sysMountSanityCheckMSDefined)
|
||||
seq_printf(sf, ",sysMountSanityCheckMS=%u", this->sysMountSanityCheckMS);
|
||||
|
||||
if (this->grpid)
|
||||
seq_printf(sf, ",grpid");
|
||||
}
|
||||
80
client_module/source/app/config/MountConfig.h
Normal file
80
client_module/source/app/config/MountConfig.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef OPEN_MOUNTCONFIG_H_
|
||||
#define OPEN_MOUNTCONFIG_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
struct MountConfig;
|
||||
typedef struct MountConfig MountConfig;
|
||||
|
||||
|
||||
static inline void MountConfig_init(MountConfig* this);
|
||||
static inline MountConfig* MountConfig_construct(void);
|
||||
static inline void MountConfig_uninit(MountConfig* this);
|
||||
static inline void MountConfig_destruct(MountConfig* this);
|
||||
|
||||
extern bool MountConfig_parseFromRawOptions(MountConfig* this, char* mountOptions);
|
||||
extern void MountConfig_showOptions(MountConfig* this, struct seq_file* sf);
|
||||
|
||||
|
||||
struct MountConfig
|
||||
{
|
||||
char* cfgFile;
|
||||
char* logStdFile;
|
||||
char* sysMgmtdHost;
|
||||
char* tunePreferredMetaFile;
|
||||
char* tunePreferredStorageFile;
|
||||
|
||||
bool logLevelDefined; // true if the value has been specified
|
||||
bool connPortShiftDefined; // true if the value has been specified
|
||||
bool connMgmtdPortDefined; // true if the value has been specified
|
||||
bool sysMountSanityCheckMSDefined; // true if the value has been specified
|
||||
|
||||
int logLevel;
|
||||
unsigned connPortShift;
|
||||
unsigned connMgmtdPort;
|
||||
unsigned sysMountSanityCheckMS;
|
||||
char* connInterfacesList;
|
||||
char* connAuthFile;
|
||||
char* connDisableAuthentication;
|
||||
|
||||
bool grpid;
|
||||
};
|
||||
|
||||
|
||||
void MountConfig_init(MountConfig* this)
|
||||
{
|
||||
memset(this, 0, sizeof(*this) );
|
||||
}
|
||||
|
||||
struct MountConfig* MountConfig_construct(void)
|
||||
{
|
||||
struct MountConfig* this = (MountConfig*)os_kmalloc(sizeof(*this) );
|
||||
|
||||
MountConfig_init(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void MountConfig_uninit(MountConfig* this)
|
||||
{
|
||||
SAFE_KFREE(this->cfgFile);
|
||||
SAFE_KFREE(this->logStdFile);
|
||||
SAFE_KFREE(this->sysMgmtdHost);
|
||||
SAFE_KFREE(this->tunePreferredMetaFile);
|
||||
SAFE_KFREE(this->tunePreferredStorageFile);
|
||||
SAFE_KFREE(this->connInterfacesList);
|
||||
SAFE_KFREE(this->connAuthFile);
|
||||
SAFE_KFREE(this->connDisableAuthentication);
|
||||
}
|
||||
|
||||
void MountConfig_destruct(MountConfig* this)
|
||||
{
|
||||
MountConfig_uninit(this);
|
||||
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
|
||||
#endif /*OPEN_MOUNTCONFIG_H_*/
|
||||
331
client_module/source/app/log/Logger.c
Normal file
331
client_module/source/app/log/Logger.c
Normal file
@@ -0,0 +1,331 @@
|
||||
#include <common/threading/Thread.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <common/nodes/Node.h>
|
||||
#include <filesystem/FhgfsOpsSuper.h>
|
||||
#include <filesystem/FhgfsInode.h>
|
||||
#include <toolkit/NoAllocBufferStore.h>
|
||||
#include "Logger.h"
|
||||
|
||||
|
||||
#define LOG_TOPIC_GENERAL_STR "general"
|
||||
#define LOG_TOPIC_CONN_STR "conn"
|
||||
#define LOG_TOPIC_COMMKIT_STR "commkit"
|
||||
#define LOG_TOPIC_UNKNOWN_STR "<unknown>" /* for unknown/invalid log topics */
|
||||
|
||||
|
||||
|
||||
void Logger_init(Logger* this, App* app, Config* cfg)
|
||||
{
|
||||
int i;
|
||||
|
||||
this->app = app;
|
||||
|
||||
for(i=0; i < LogTopic_LAST; i++)
|
||||
this->logLevels[i] = Config_getLogLevel(cfg);
|
||||
|
||||
this->logFormattedBuf = (char*)os_kmalloc(LOGGER_LOGBUF_SIZE);
|
||||
this->logContextBuf = (char*)os_kmalloc(LOGGER_LOGBUF_SIZE);
|
||||
|
||||
this->clientID = NULL;
|
||||
|
||||
Mutex_init(&this->outputMutex);
|
||||
|
||||
|
||||
// Note: The follwing guys exist to avoid deadlocks that would occur when log messages are
|
||||
// created (by the same thread) while we're already trying to send a log message to the
|
||||
// helper daemon (e.g. the messages of the NodeConnPool). Such messages will be discarded.
|
||||
this->currentOutputPID = LOGGER_PID_NOCURRENTOUTPUT;
|
||||
Mutex_init(&this->multiLockMutex);
|
||||
}
|
||||
|
||||
Logger* Logger_construct(App* app, Config* cfg)
|
||||
{
|
||||
Logger* this = (Logger*)os_kmalloc(sizeof(Logger) );
|
||||
|
||||
Logger_init(this, app, cfg);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Logger_uninit(Logger* this)
|
||||
{
|
||||
SAFE_KFREE(this->clientID);
|
||||
|
||||
SAFE_KFREE(this->logContextBuf);
|
||||
SAFE_KFREE(this->logFormattedBuf);
|
||||
|
||||
Mutex_uninit(&this->multiLockMutex);
|
||||
Mutex_uninit(&this->outputMutex);
|
||||
}
|
||||
|
||||
void Logger_destruct(Logger* this)
|
||||
{
|
||||
Logger_uninit(this);
|
||||
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just print a log message with formatting similar to printk().
|
||||
*
|
||||
* @param level LogLevel_... value
|
||||
* @param context the context from which this msg was printed (e.g. the calling function).
|
||||
* @param msg the log message with formatting, e.g. "%s".
|
||||
*/
|
||||
void Logger_logFormatted(Logger* this, LogLevel level, const char* context, const char* msgFormat,
|
||||
...)
|
||||
{
|
||||
// note: cannot be inlined because of variable arg list
|
||||
|
||||
va_list ap;
|
||||
|
||||
if(level > this->logLevels[LogTopic_GENERAL])
|
||||
return;
|
||||
|
||||
va_start(ap, msgFormat);
|
||||
|
||||
__Logger_logTopFormattedGranted(this, LogTopic_GENERAL, level, context, msgFormat, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger_logTopFormatted(Logger* this, LogTopic logTopic, LogLevel level, const char* context,
|
||||
const char* msgFormat, ...)
|
||||
{
|
||||
// note: cannot be inlined because of variable arg list
|
||||
|
||||
va_list ap;
|
||||
|
||||
if(level > this->logLevels[logTopic])
|
||||
return;
|
||||
|
||||
va_start(ap, msgFormat);
|
||||
|
||||
__Logger_logTopFormattedGranted(this, logTopic, level, context, msgFormat, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log with EntryID
|
||||
*
|
||||
* Note: This takes an EntryInfo read-lock. Must be used only if there is no risk of deadlock.
|
||||
*/
|
||||
void Logger_logTopFormattedWithEntryID(struct inode* inode, LogTopic logTopic, LogLevel level,
|
||||
const char* logContext, const char* msgFormat, ...)
|
||||
{
|
||||
char* newMsg;
|
||||
App* app = FhgfsOps_getApp(inode->i_sb);
|
||||
Logger* log = App_getLogger(app);
|
||||
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
|
||||
const EntryInfo* entryInfo = FhgfsInode_getEntryInfo(fhgfsInode);
|
||||
va_list ap;
|
||||
|
||||
FhgfsInode_entryInfoReadLock(fhgfsInode); // L O C K entryInfo
|
||||
|
||||
va_start(ap, msgFormat);
|
||||
|
||||
newMsg = os_kmalloc(LOGGER_LOGBUF_SIZE);
|
||||
if (newMsg)
|
||||
snprintf(newMsg, LOGGER_LOGBUF_SIZE, "entryID: %s %s ", EntryInfo_getEntryID(entryInfo),
|
||||
msgFormat);
|
||||
else // malloc failed. Likely an out memory situation, we still try to print msgFormat
|
||||
newMsg = (char*)msgFormat;
|
||||
|
||||
Logger_logTopFormattedVA(log, logTopic, level, logContext, newMsg, ap);
|
||||
va_end(ap);
|
||||
|
||||
FhgfsInode_entryInfoReadUnlock(fhgfsInode); // U N L O C K entryInfo
|
||||
|
||||
if(newMsg != msgFormat)
|
||||
kfree(newMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Just print a log message. Similar to Logger_logFormatted(), but take a va_list already
|
||||
*/
|
||||
void Logger_logFormattedVA(Logger* this, LogLevel level, const char* context, const char* msgFormat,
|
||||
va_list ap)
|
||||
{
|
||||
if(level > this->logLevels[LogTopic_GENERAL])
|
||||
return;
|
||||
|
||||
__Logger_logTopFormattedGranted(this, LogTopic_GENERAL, level, context, msgFormat, ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just print a log message. Similar to Logger_logTopFormatted(), but take a va_list already
|
||||
*/
|
||||
void Logger_logTopFormattedVA(Logger* this, LogTopic logTopic, LogLevel level, const char* context,
|
||||
const char* msgFormat, va_list ap)
|
||||
{
|
||||
if(level > this->logLevels[logTopic])
|
||||
return;
|
||||
|
||||
__Logger_logTopFormattedGranted(this, logTopic, level, context, msgFormat, ap);
|
||||
}
|
||||
|
||||
void Logger_logErrFormatted(Logger* this, const char* context, const char* msgFormat, ...)
|
||||
{
|
||||
// note: cannot be inlined because of variable arg list
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msgFormat);
|
||||
|
||||
__Logger_logTopFormattedGranted(this, LogTopic_GENERAL, Log_ERR, context, msgFormat, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger_logTopErrFormatted(Logger* this, LogTopic logTopic, const char* context,
|
||||
const char* msgFormat, ...)
|
||||
{
|
||||
// note: cannot be inlined because of variable arg list
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msgFormat);
|
||||
|
||||
__Logger_logTopFormattedGranted(this, logTopic, Log_ERR, context, msgFormat, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to the standard log.
|
||||
*
|
||||
* @param level log level (Log_... value)
|
||||
* @param msg the message
|
||||
*/
|
||||
void __Logger_logTopFormattedGranted(Logger* this, LogTopic logTopic, LogLevel level,
|
||||
const char* context, const char* msgFormat, va_list args)
|
||||
{
|
||||
if(__Logger_checkThreadMultiLock(this) )
|
||||
{
|
||||
// this thread is already trying to log a message. trying to lock outputMutex would deadlock.
|
||||
// => discard this message
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Mutex_lock(&this->outputMutex);
|
||||
|
||||
__Logger_setCurrentOutputPID(this, current->pid); // grab currentOutputPID
|
||||
|
||||
|
||||
// evaluate msgFormat
|
||||
vsnprintf(this->logFormattedBuf, LOGGER_LOGBUF_SIZE, msgFormat, args);
|
||||
|
||||
// extend context
|
||||
if(this->clientID)
|
||||
snprintf(this->logContextBuf, LOGGER_LOGBUF_SIZE, "%s: %s", this->clientID, context);
|
||||
else
|
||||
snprintf(this->logContextBuf, LOGGER_LOGBUF_SIZE, "%s", context);
|
||||
|
||||
printk_fhgfs(KERN_INFO, "%s: %s\n", this->logContextBuf, this->logFormattedBuf);
|
||||
|
||||
__Logger_setCurrentOutputPID(this, LOGGER_PID_NOCURRENTOUTPUT); // release currentOutputPID
|
||||
|
||||
Mutex_unlock(&this->outputMutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note: Call this before locking the outputMutex (because it exists to avoid dead-locking).
|
||||
*
|
||||
* @return true if the currentOutputPID is set to the current thread and logging cannot continue;
|
||||
*/
|
||||
bool __Logger_checkThreadMultiLock(Logger* this)
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
Mutex_lock(&this->multiLockMutex);
|
||||
|
||||
if(this->currentOutputPID == current->pid)
|
||||
{ // we alread own the outputPID (=> we already own the outputMutex)
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
Mutex_unlock(&this->multiLockMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Call this only after the thread owns the outputMutex to avoid "stealing".
|
||||
*/
|
||||
void __Logger_setCurrentOutputPID(Logger* this, pid_t pid)
|
||||
{
|
||||
Mutex_lock(&this->multiLockMutex);
|
||||
|
||||
this->currentOutputPID = pid;
|
||||
|
||||
Mutex_unlock(&this->multiLockMutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a pointer to the static string representation of a log topic (or "<unknown>" for unknown/
|
||||
* invalid log topic numbers.
|
||||
*/
|
||||
const char* Logger_getLogTopicStr(LogTopic logTopic)
|
||||
{
|
||||
switch(logTopic)
|
||||
{
|
||||
case LogTopic_GENERAL:
|
||||
return LOG_TOPIC_GENERAL_STR;
|
||||
|
||||
case LogTopic_CONN:
|
||||
return LOG_TOPIC_CONN_STR;
|
||||
|
||||
case LogTopic_COMMKIT:
|
||||
return LOG_TOPIC_COMMKIT_STR;
|
||||
|
||||
default:
|
||||
return LOG_TOPIC_UNKNOWN_STR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the log topic number from a string (not case-sensitive).
|
||||
*
|
||||
* @return false if string didn't match any known log topic.
|
||||
*/
|
||||
bool Logger_getLogTopicFromStr(const char* logTopicStr, LogTopic* outLogTopic)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < LogTopic_LAST; i++)
|
||||
{
|
||||
const char* currentLogTopicStr = Logger_getLogTopicStr( (LogTopic)i);
|
||||
|
||||
if(!strcasecmp(logTopicStr, currentLogTopicStr))
|
||||
{
|
||||
*outLogTopic = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// (note: we carefully set outLogTopic to "general" to not risk leaving it undefined)
|
||||
*outLogTopic = LogTopic_GENERAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to retrieve the level of LogTopic_GENERAL in old code.
|
||||
* New code should use _getLogTopicLevel() instead.
|
||||
*/
|
||||
LogLevel Logger_getLogLevel(Logger* this)
|
||||
{
|
||||
return this->logLevels[LogTopic_GENERAL];
|
||||
}
|
||||
|
||||
LogLevel Logger_getLogTopicLevel(Logger* this, LogTopic logTopic)
|
||||
{
|
||||
return this->logLevels[logTopic];
|
||||
}
|
||||
|
||||
244
client_module/source/app/log/Logger.h
Normal file
244
client_module/source/app/log/Logger.h
Normal file
@@ -0,0 +1,244 @@
|
||||
#ifndef LOGGER_H_
|
||||
#define LOGGER_H_
|
||||
|
||||
#include <app/config/Config.h>
|
||||
#include <app/App.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/toolkit/StringTk.h>
|
||||
#include <common/toolkit/Time.h>
|
||||
#include <common/threading/Mutex.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/Common.h>
|
||||
|
||||
|
||||
#define LOGGER_LOGBUF_SIZE 1000 /* max log message length */
|
||||
#define LOGGER_PID_NOCURRENTOUTPUT 0 /* pid value if outputMutex not locked */
|
||||
|
||||
|
||||
#ifdef LOG_DEBUG_MESSAGES
|
||||
|
||||
#define LOG_DEBUG(logger, level, contextStr, msgStr) \
|
||||
do { Logger_log(logger, level, contextStr, msgStr); } while(0)
|
||||
|
||||
#define LOG_DEBUG_TOP(logger, logTopic, level, contextStr, msgStr) \
|
||||
do { Logger_logTop(logger, logTopic, level, contextStr, msgStr); } while(0)
|
||||
|
||||
#define LOG_DEBUG_FORMATTED(logger, level, contextStr, msgStr, ...) \
|
||||
do { Logger_logFormatted(logger, level, contextStr, msgStr, ## __VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_DEBUG_TOP_FORMATTED(logger, logTopic, level, contextStr, msgStr, ...) \
|
||||
do { Logger_logTopFormatted(logger, logTopic, level, contextStr, msgStr, ## __VA_ARGS__); } \
|
||||
while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define LOG_DEBUG(logger, level, contextStr, msgStr)
|
||||
#define LOG_DEBUG_TOP(logger, logTopic, level, contextStr, msgStr)
|
||||
#define LOG_DEBUG_FORMATTED(logger, level, contextStr, msgStr, ...)
|
||||
#define LOG_DEBUG_TOP_FORMATTED(logger, logTopic, level, contextStr, msgStr, ...)
|
||||
|
||||
#endif // LOG_DEBUG_MESSAGES
|
||||
|
||||
#define Logger_logFormattedWithEntryID(inode, level, logContext, msgFormat, ...) \
|
||||
Logger_logTopFormattedWithEntryID(inode, LogTopic_GENERAL, level, logContext, msgFormat, \
|
||||
##__VA_ARGS__)
|
||||
|
||||
// forward declarations...
|
||||
|
||||
struct Logger;
|
||||
typedef struct Logger Logger;
|
||||
|
||||
struct Node;
|
||||
|
||||
enum LogLevel;
|
||||
typedef enum LogLevel LogLevel;
|
||||
enum LogTopic;
|
||||
typedef enum LogTopic LogTopic;
|
||||
|
||||
|
||||
|
||||
extern void Logger_init(Logger* this, App* app, Config* cfg);
|
||||
extern Logger* Logger_construct(App* app, Config* cfg);
|
||||
extern void Logger_uninit(Logger* this);
|
||||
extern void Logger_destruct(Logger* this);
|
||||
|
||||
__attribute__((format(printf, 4, 5)))
|
||||
extern void Logger_logFormatted(Logger* this, LogLevel level, const char* context,
|
||||
const char* msgFormat, ...);
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
extern void Logger_logTopFormattedWithEntryID(struct inode* inode, LogTopic logTopic,
|
||||
LogLevel level, const char* logContext, const char* msgFormat, ...);
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
extern void Logger_logTopFormatted(Logger* this, LogTopic logTopic, LogLevel level,
|
||||
const char* context, const char* msgFormat, ...);
|
||||
extern void Logger_logFormattedVA(Logger* this, LogLevel level, const char* context,
|
||||
const char* msgFormat, va_list ap);
|
||||
extern void Logger_logTopFormattedVA(Logger* this, LogTopic logTopic, LogLevel level,
|
||||
const char* context, const char* msgFormat, va_list ap);
|
||||
__attribute__((format(printf, 3, 4)))
|
||||
extern void Logger_logErrFormatted(Logger* this, const char* context, const char* msgFormat, ...);
|
||||
__attribute__((format(printf, 4, 5)))
|
||||
extern void Logger_logTopErrFormatted(Logger* this, LogTopic logTopic, const char* context,
|
||||
const char* msgFormat, ...);
|
||||
|
||||
extern LogLevel Logger_getLogLevel(Logger* this);
|
||||
extern LogLevel Logger_getLogTopicLevel(Logger* this, LogTopic logTopic);
|
||||
|
||||
extern void __Logger_logTopFormattedGranted(Logger* this, LogTopic logTopic, LogLevel level,
|
||||
const char* context, const char* msgFormat, va_list args);
|
||||
|
||||
extern bool __Logger_checkThreadMultiLock(Logger* this);
|
||||
extern void __Logger_setCurrentOutputPID(Logger* this, pid_t pid);
|
||||
|
||||
|
||||
// static
|
||||
extern const char* Logger_getLogTopicStr(LogTopic logTopic);
|
||||
extern bool Logger_getLogTopicFromStr(const char* logTopicStr, LogTopic* logTopic);
|
||||
|
||||
// getters & setters
|
||||
static inline void Logger_setClientID(Logger* this, const char* clientID);
|
||||
static inline void Logger_setAllLogLevels(Logger* this, LogLevel logLevel);
|
||||
static inline void Logger_setLogTopicLevel(Logger* this, LogTopic logTopic, LogLevel logLevel);
|
||||
|
||||
// inliners
|
||||
static inline void Logger_log(Logger* this, LogLevel level, const char* context, const char* msg);
|
||||
static inline void Logger_logTop(Logger* this, LogTopic logTopic, LogLevel level,
|
||||
const char* context, const char* msg);
|
||||
static inline void Logger_logErr(Logger* this, const char* context, const char* msg);
|
||||
static inline void Logger_logTopErr(Logger* this, LogTopic logTopic, const char* context,
|
||||
const char* msg);
|
||||
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
LOG_NOTHING=-1,
|
||||
Log_ERR=0, /* system error */
|
||||
Log_CRITICAL=1, /* something the users should definitely know about */
|
||||
Log_WARNING=2, /* things that indicate or are related to a problem */
|
||||
Log_NOTICE=3, /* things that could help finding problems */
|
||||
Log_DEBUG=4, /* things that are only useful during debugging, often logged with LOG_DEBUG() */
|
||||
Log_SPAM=5 /* things that are typically too detailed even during normal debugging,
|
||||
very often with LOG_DEBUG() */
|
||||
};
|
||||
|
||||
/**
|
||||
* Note: When you add a new log topic, you must also update these places:
|
||||
* 1) Logger_getLogTopicStr()
|
||||
* 2) ProcFsHelper_{read/write}_logLevels()
|
||||
*/
|
||||
enum LogTopic
|
||||
{
|
||||
LogTopic_GENERAL=0, /* everything that is not assigned to a more specific log topic */
|
||||
LogTopic_CONN, /* connects and disconnects */
|
||||
LogTopic_COMMKIT, /* CommKitVec */
|
||||
|
||||
LogTopic_LAST /* not valid, just exists to define the LogLevelsArray size */
|
||||
};
|
||||
|
||||
typedef signed char LogTopicLevels[LogTopic_LAST]; /* array for per-topic log levels, see LogTopic/
|
||||
LogLevel. Note: Type is actually type LogLevel, but we use char here because we also allow
|
||||
"-1" to disable a level. */
|
||||
|
||||
|
||||
/**
|
||||
* This is the general logger class.
|
||||
*/
|
||||
struct Logger
|
||||
{
|
||||
// configurables
|
||||
LogTopicLevels logLevels; // per-topic log levels
|
||||
|
||||
// internals
|
||||
App* app;
|
||||
|
||||
Mutex outputMutex;
|
||||
|
||||
Mutex multiLockMutex; // to avoid multiple locking of the outputMutex by the same thread
|
||||
pid_t currentOutputPID; // pid of outputMutex holder (see LOGGER_PID_NOCURRENTOUTPUT)
|
||||
|
||||
char* logFormattedBuf; // for logging functions with variable argument list
|
||||
char* logContextBuf; // for extended context logging
|
||||
|
||||
char* clientID; // only set if clientID logging is enabled
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Note: Copies the clientID.
|
||||
*/
|
||||
void Logger_setClientID(Logger* this, const char* clientID)
|
||||
{
|
||||
SAFE_KFREE(this->clientID); // free old clientID
|
||||
|
||||
this->clientID = StringTk_strDup(clientID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This is intended to be used during app destruction to disable logging by setting the levels
|
||||
* to "-1".
|
||||
*
|
||||
* @param logLevel LogLevel_... or "-1" to disable.
|
||||
*/
|
||||
void Logger_setAllLogLevels(Logger* this, LogLevel logLevel)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < LogTopic_LAST; i++)
|
||||
this->logLevels[i] = logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param logLevel LogLevel_... or "-1" to disable.
|
||||
*/
|
||||
void Logger_setLogTopicLevel(Logger* this, LogTopic logTopic, LogLevel logLevel)
|
||||
{
|
||||
this->logLevels[logTopic] = logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log msg for LogTopic_GENERAL.
|
||||
*
|
||||
* @param level LogLevel_... value
|
||||
* @param context the context from which this msg was printed (e.g. the calling function).
|
||||
* @param msg the log message
|
||||
*/
|
||||
void Logger_log(Logger* this, LogLevel level, const char* context, const char* msg)
|
||||
{
|
||||
Logger_logFormatted(this, level, context, "%s", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log msg for a certain log topic.
|
||||
*
|
||||
* @param level LogLevel_... value
|
||||
* @param context the context from which this msg was printed (e.g. the calling function).
|
||||
* @param msg the log message
|
||||
*/
|
||||
void Logger_logTop(Logger* this, LogTopic logTopic, LogLevel level, const char* context,
|
||||
const char* msg)
|
||||
{
|
||||
Logger_logTopFormatted(this, logTopic, level, context, "%s", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error msg for LogTopic_GENERAL.
|
||||
*/
|
||||
void Logger_logErr(Logger* this, const char* context, const char* msg)
|
||||
{
|
||||
Logger_logErrFormatted(this, context, "%s", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error msg for a certain log topic.
|
||||
*/
|
||||
void Logger_logTopErr(Logger* this, LogTopic logTopic, const char* context, const char* msg)
|
||||
{
|
||||
Logger_logTopErrFormatted(this, logTopic, context, "%s", msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*LOGGER_H_*/
|
||||
490
client_module/source/common/Common.h
Normal file
490
client_module/source/common/Common.h
Normal file
@@ -0,0 +1,490 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched.h> /* for TASK_COMM_LEN */
|
||||
#include <linux/string.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#ifdef KERNEL_HAS_LINUX_FILELOCK_H
|
||||
#include <linux/filelock.h>
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_HAS_LINUX_STDARG_H
|
||||
#include <linux/stdarg.h>
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/cred.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#ifdef KERNEL_HAS_SCHED_SIG_H
|
||||
#include <linux/sched/signal.h>
|
||||
#endif
|
||||
|
||||
#include <common/FhgfsTypes.h>
|
||||
#include <os/OsDeps.h>
|
||||
|
||||
/**
|
||||
* NOTE: These timeouts can now be overridden by the connMessagingTimeouts
|
||||
* option in the configuration file. If that option is unset or set to <=0, we
|
||||
* still default to these constants.
|
||||
*/
|
||||
#define CONN_LONG_TIMEOUT 600000
|
||||
#define CONN_MEDIUM_TIMEOUT 90000
|
||||
#define CONN_SHORT_TIMEOUT 30000
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) \
|
||||
( ( (a) < (b) ) ? (a) : (b) )
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) \
|
||||
( ( (a) < (b) ) ? (b) : (a) )
|
||||
#endif
|
||||
|
||||
#define SAFE_VFREE(p) \
|
||||
do{ if(p) {vfree(p); (p)=NULL;} } while(0)
|
||||
|
||||
#define SAFE_VFREE_NOSET(p) \
|
||||
do{ if(p) vfree(p); } while(0)
|
||||
|
||||
#define SAFE_KFREE(p) \
|
||||
do{ if(p) {kfree(p); (p)=NULL;} } while(0)
|
||||
|
||||
#define SAFE_KFREE_NOSET(p) \
|
||||
do{ if(p) kfree(p); } while(0)
|
||||
|
||||
#define SAFE_DESTRUCT(p, destructor) \
|
||||
do{if(p) {destructor(p); (p)=NULL;} } while(0)
|
||||
|
||||
#define SAFE_DESTRUCT_NOSET(p, destructor) \
|
||||
do{if(p) destructor(p); } while(0)
|
||||
|
||||
|
||||
// typically used for optional out-args
|
||||
#define SAFE_ASSIGN(destPointer, sourceValue) \
|
||||
do{ if(destPointer) {*(destPointer) = (sourceValue);} } while(0)
|
||||
|
||||
|
||||
// module name
|
||||
|
||||
#ifndef BEEGFS_MODULE_NAME_STR
|
||||
#define BEEGFS_MODULE_NAME_STR "beegfs"
|
||||
#endif
|
||||
|
||||
#define BEEGFS_THREAD_NAME_PREFIX_STR BEEGFS_MODULE_NAME_STR "_"
|
||||
|
||||
// a printk-version that adds the module name and comm name
|
||||
#define printk_fhgfs(levelStr, fmtStr, ...) \
|
||||
printk(levelStr BEEGFS_MODULE_NAME_STR ": " "%s(%u): " fmtStr, current->comm, \
|
||||
(unsigned)current->pid, ## __VA_ARGS__)
|
||||
|
||||
// for interrupt handling routines (does not print "current")
|
||||
#define printk_fhgfs_ir(levelStr, fmtStr, ...) \
|
||||
printk(levelStr BEEGFS_MODULE_NAME_STR ": " fmtStr, ## __VA_ARGS__)
|
||||
|
||||
|
||||
// dumps stack in case of a buggy condition
|
||||
#define BEEGFS_BUG_ON(condition, msgStr) \
|
||||
do { \
|
||||
if(unlikely(condition) ) { \
|
||||
printk_fhgfs(KERN_ERR, "%s:%d: BUG: %s (dumping stack...)\n", \
|
||||
__func__, __LINE__, msgStr); \
|
||||
dump_stack(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
|
||||
#ifdef LOG_DEBUG_MESSAGES
|
||||
|
||||
#define printk_fhgfs_debug(levelStr, fmtStr, ...) \
|
||||
printk(levelStr BEEGFS_MODULE_NAME_STR ": " "%s(%u): " fmtStr, current->comm, \
|
||||
(unsigned)current->pid, ## __VA_ARGS__)
|
||||
|
||||
|
||||
#define printk_fhgfs_ir_debug(levelStr, fmtStr, ...) \
|
||||
printk_fhgfs_ir(levelStr, fmtStr, ## __VA_ARGS__)
|
||||
|
||||
#define BEEGFS_BUG_ON_DEBUG(condition, msgStr) BEEGFS_BUG_ON(condition, msgStr)
|
||||
|
||||
#else // !LOG_DEBUG_MESSAGES
|
||||
|
||||
#define printk_fhgfs_debug(levelStr, fmtStr, ...) \
|
||||
do { /* nothing */ } while(0)
|
||||
|
||||
#define printk_fhgfs_ir_debug(levelStr, fmtStr, ...) \
|
||||
do { /* nothing */ } while(0)
|
||||
|
||||
#define BEEGFS_BUG_ON_DEBUG(condition, msgStr) \
|
||||
do { /* nothing */ } while(0)
|
||||
|
||||
#endif // LOG_DEBUG_MESSAGES
|
||||
|
||||
#ifdef BEEGFS_OPENTK_LOG_CONN_ERRORS
|
||||
#define printk_fhgfs_connerr(levelStr, fmtStr, ...) \
|
||||
printk_fhgfs(levelStr, fmtStr, ## __VA_ARGS__)
|
||||
#else
|
||||
#define printk_fhgfs_connerr(levelStr, fmtStr, ...) /* logging of conn errors disabled */
|
||||
#endif // BEEGFS_OPENTK_LOG_CONN_ERRORS
|
||||
|
||||
|
||||
// this macro mutes warnings about unused variables
|
||||
#define IGNORE_UNUSED_VARIABLE(a) do{ if( ((long)a)==1) {} } while(0)
|
||||
|
||||
// this macro mutes warnings about unsused variables that are only used in debug build
|
||||
#ifdef BEEGFS_DEBUG
|
||||
#define IGNORE_UNUSED_DEBUG_VARIABLE(a) do{ /* do nothing */ } while(0)
|
||||
#else
|
||||
#define IGNORE_UNUSED_DEBUG_VARIABLE(a) do{ if( ((long)a)==1) {} } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/* set_fs() / get_fs() macro hackery.
|
||||
*
|
||||
* set_fs() and get_fs() have disappeared with Linux kernel 5.10.
|
||||
* For older kernels, we employ some macros to make their use less of a hassle.
|
||||
*/
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
#define BEEGFS_CONCAT_(x, y) x ## y
|
||||
#define BEEGFS_CONCAT(x, y) BEEGFS_CONCAT_(x, y)
|
||||
#define BEEGFS_UNIQUE_NAME(prefix) BEEGFS_CONCAT(prefix, __LINE__)
|
||||
|
||||
|
||||
// Lifted from Linux 5.10
|
||||
#if __has_attribute(__fallthrough__)
|
||||
#define BEEGFS_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
#else
|
||||
#define BEEGFS_FALLTHROUGH do {} while (0) /* FALLTHROUGH */
|
||||
#endif
|
||||
|
||||
|
||||
/* Preprocessor hack to add statements that are executed on scope cleanup.
|
||||
* A for-loop that runs exactly 1 time is misused to execute the cleanup
|
||||
* statement. An assertion ensures that we didn't break from the inner loop,
|
||||
* to ensure the cleanup statement is executed. */
|
||||
|
||||
#define BEEGFS_FOR_SCOPE_(begin_stmt, end_stmt, name) \
|
||||
for (int name = 0; !name; ({BUG_ON(!name);})) \
|
||||
for (begin_stmt; !name++; end_stmt)
|
||||
|
||||
#define BEEGFS_FOR_SCOPE(begin_stmt, end_stmt) \
|
||||
BEEGFS_FOR_SCOPE_(begin_stmt, end_stmt, BEEGFS_UNIQUE_NAME(scope))
|
||||
|
||||
#ifdef KERNEL_HAS_GET_FS
|
||||
|
||||
static inline mm_segment_t BEEGFS_BEGIN_PROCESS_CONTEXT(void)
|
||||
{
|
||||
mm_segment_t out = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline void BEEGFS_END_PROCESS_CONTEXT(mm_segment_t *backup)
|
||||
{
|
||||
set_fs(*backup);
|
||||
}
|
||||
|
||||
#define WITH_PROCESS_CONTEXT \
|
||||
BEEGFS_FOR_SCOPE( \
|
||||
mm_segment_t segment = BEEGFS_BEGIN_PROCESS_CONTEXT(), \
|
||||
BEEGFS_END_PROCESS_CONTEXT(&segment))
|
||||
|
||||
#else
|
||||
|
||||
#define WITH_PROCESS_CONTEXT
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// in 4.13 wait_queue_t got renamed to wait_queue_entry_t
|
||||
#if defined(KERNEL_HAS_WAIT_QUEUE_ENTRY_T)
|
||||
typedef wait_queue_entry_t wait_queue_t;
|
||||
#endif
|
||||
|
||||
#if defined(KERNEL_HAS_64BIT_TIMESTAMPS)
|
||||
static inline struct timespec64 current_fs_time(struct super_block *sb)
|
||||
{
|
||||
struct timespec64 now;
|
||||
#if defined(KERNEL_HAS_KTIME_GET_COARSE_REAL_TS64)
|
||||
ktime_get_coarse_real_ts64(&now);
|
||||
return now;
|
||||
#elif defined(KERNEL_HAS_KTIME_GET_REAL_TS64)
|
||||
ktime_get_real_ts64(&now);
|
||||
return timespec64_trunc(now, sb->s_time_gran);
|
||||
#else
|
||||
now = current_kernel_time64();
|
||||
return timespec64_trunc(now, sb->s_time_gran);
|
||||
#endif
|
||||
}
|
||||
#elif !defined(KERNEL_HAS_CURRENT_FS_TIME)
|
||||
static inline struct timespec current_fs_time(struct super_block *sb)
|
||||
{
|
||||
struct timespec now = current_kernel_time();
|
||||
return timespec_trunc(now, sb->s_time_gran);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Defined by <linux/include/linux/uidgid.h> and already included by one of the headers, so
|
||||
* no KernelFeatureDetection.mk detection required.
|
||||
* Note: Not in OsCompat.h, as OsCompat depends on Common.h. */
|
||||
#ifndef _LINUX_UIDGID_H
|
||||
typedef unsigned kuid_t;
|
||||
typedef unsigned kgid_t;
|
||||
|
||||
#define from_kuid(a, b) (b)
|
||||
#define from_kgid(a, b) (b)
|
||||
#define make_kuid(a, b) (b)
|
||||
#define make_kgid(a, b) (b)
|
||||
#endif
|
||||
|
||||
#ifndef swap
|
||||
#define swap(a, b) do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
|
||||
#endif
|
||||
|
||||
#undef BEEGFS_RDMA
|
||||
#ifndef BEEGFS_NO_RDMA
|
||||
#if defined(CONFIG_INFINIBAND) || defined(CONFIG_INFINIBAND_MODULE)
|
||||
#define BEEGFS_RDMA 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline unsigned FhgfsCommon_getCurrentUserID(void);
|
||||
static inline unsigned FhgfsCommon_getCurrentGroupID(void);
|
||||
|
||||
|
||||
unsigned FhgfsCommon_getCurrentUserID(void)
|
||||
{
|
||||
return from_kuid(&init_user_ns, current_fsuid());
|
||||
}
|
||||
|
||||
unsigned FhgfsCommon_getCurrentGroupID(void)
|
||||
{
|
||||
return from_kgid(&init_user_ns, current_fsgid());
|
||||
}
|
||||
|
||||
// Helper function for getting file pointer
|
||||
static inline struct file * FhgfsCommon_getFileLock(struct file_lock *fileLock)
|
||||
{
|
||||
#if defined(KERNEL_HAS_FILE_LOCK_CORE)
|
||||
return fileLock->c.flc_file;
|
||||
#else
|
||||
return fileLock->fl_file;
|
||||
#endif
|
||||
}
|
||||
// Helper function to get PID from file lock
|
||||
static inline pid_t FhgfsCommon_getFileLockPID(struct file_lock *fileLock)
|
||||
{
|
||||
#if defined(KERNEL_HAS_FILE_LOCK_CORE)
|
||||
return fileLock->c.flc_pid;
|
||||
#else
|
||||
return fileLock->fl_pid;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function to get lock type
|
||||
static inline unsigned char FhgfsCommon_getFileLockType(struct file_lock *flock)
|
||||
{
|
||||
#if defined(KERNEL_HAS_FILE_LOCK_CORE)
|
||||
return flock->c.flc_type;
|
||||
#else
|
||||
return flock->fl_type;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function to get lock flags
|
||||
static inline unsigned int FhgfsCommon_getFileLockFlags(struct file_lock *fileLock)
|
||||
{
|
||||
#if defined(KERNEL_HAS_FILE_LOCK_CORE)
|
||||
return fileLock->c.flc_flags;
|
||||
#else
|
||||
return fileLock->fl_flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debug definitions:
|
||||
* - LOG_DEBUG_MESSAGES: Enables logging of some extra debug messages that will not be
|
||||
* available otherwise.
|
||||
* - DEBUG_REFCOUNT: Enables debugging of ObjectReferencer::refCount. Error messages will
|
||||
* be logged if refCount is less than zero.
|
||||
*/
|
||||
|
||||
/**
|
||||
* BEEGFS_KFREE_LIST() - destroys and kfree()s all element of a list, leaving an empty list
|
||||
*
|
||||
* expands to ``BEEGFS_KFREE_LIST_DTOR(List, ElemType, Member, (void))``, ie no destructor is
|
||||
* called.
|
||||
*/
|
||||
#define BEEGFS_KFREE_LIST(List, ElemType, Member) \
|
||||
BEEGFS_KFREE_LIST_DTOR(List, ElemType, Member, (void))
|
||||
/**
|
||||
* BEEGFS_KFREE_LIST_DTOR() - destroys and kfree()s all element of a list, leaving an empty list
|
||||
* @List the &struct list_head to free
|
||||
* @ElemType type of elements contained in the list
|
||||
* @Member name of the &struct list_head in @ElemType that links to the next element of the list
|
||||
* @Dtor for each element of the list, ``Dtor(entry)`` is evaluated before the entry is freed
|
||||
*/
|
||||
#define BEEGFS_KFREE_LIST_DTOR(List, ElemType, Member, Dtor) \
|
||||
do { \
|
||||
ElemType* entry; \
|
||||
ElemType* n; \
|
||||
list_for_each_entry_safe(entry, n, List, Member) \
|
||||
{ \
|
||||
Dtor(entry); \
|
||||
kfree(entry); \
|
||||
} \
|
||||
INIT_LIST_HEAD(List); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Generic key comparison function for integer types and pointers, to be used by the
|
||||
* RBTREE_FUNCTIONS as KeyCmp.
|
||||
*/
|
||||
#define BEEGFS_RB_KEYCMP_LT_INTEGRAL(lhs, rhs) \
|
||||
( lhs < rhs ? -1 : (lhs == rhs ? 0 : 1) )
|
||||
|
||||
/**
|
||||
* BEEGFS_KFREE_RBTREE() - destroys and kfree()s all elements an rbtree
|
||||
*
|
||||
* expands to ``BEEGFS_KFREE_RBTREE_DTOR(TreeRoot, ElemType, Member, (void))``, ie no destructor is
|
||||
* called.
|
||||
*/
|
||||
#define BEEGFS_KFREE_RBTREE(TreeRoot, ElemType, Member) \
|
||||
BEEGFS_KFREE_RBTREE_DTOR(TreeRoot, ElemType, Member, (void))
|
||||
/**
|
||||
* BEEGFS_KFREE_RBTREE_DTOR() - destroys and kfree()s all elements an rbtree, leaving an empty tree
|
||||
* @TreeRoot &struct rb_root to free
|
||||
* @ElemType type of elements contained in the tree
|
||||
* @Member name of the &struct rb_node in @ElemType that links to further entries in the tree
|
||||
* @Dtor for each element of the tree, ``Dtor(elem)`` is evaluated before the entry is freed
|
||||
*/
|
||||
#define BEEGFS_KFREE_RBTREE_DTOR(TreeRoot, ElemType, Member, Dtor) \
|
||||
do { \
|
||||
ElemType* pos; \
|
||||
ElemType* n; \
|
||||
rbtree_postorder_for_each_entry_safe(pos, n, TreeRoot, Member) \
|
||||
{ \
|
||||
Dtor(pos); \
|
||||
kfree(pos); \
|
||||
} \
|
||||
*(TreeRoot) = RB_ROOT; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* BEEGFS_RBTREE_FUNCTIONS() - defines a default set of rbtree functions
|
||||
* @Access access modifier of generated functions
|
||||
* @NS namespace prefix for all defined functions
|
||||
* @RootTy type of the struct that contains the tree we are building functions for
|
||||
* @RootNode name of the &struct rb_root of our tree in @RootTy
|
||||
* @KeyTy type of the trees sort key
|
||||
* @ElemTy type of the tree element. must contain a field of type @KeyTy
|
||||
* @ElemKey name of the key member in @ElemTy (must be of type @KeyTy)
|
||||
* @ElemNode node of the &struct rb_node of our tree in @ElemTy
|
||||
* @KeyCmp function or macro used to compare to @KeyTy values for tree ordering
|
||||
*
|
||||
* This macro declares a number of functions with names prefixed by @NS:
|
||||
*
|
||||
* * ``Access ElemTy* NS##_find(const RootTy*, KeyTy key)`` finds the @ElemTy with key ``key`` and
|
||||
* returns it. If none exists, %NULL is returned.
|
||||
* * ``Access bool NS##_insert(RootTy*, ElemTy* data)`` inserts the element ``data`` into the tree
|
||||
* if no element with the same key exists and return %true. If an element with the same key does
|
||||
* exist, returns %false.
|
||||
* * ``Access ElemTy* NS##_insertOrReplace(RootTy*, ElemTy* data)`` inserts ``data`` into the tree
|
||||
* if no element with the same key exists or replaced the existing item with the same key. If no
|
||||
* item existed %NULL is returned, otherwise the pointer to the previous element is returned.
|
||||
* This is analogous to how std::map::operator[] works in C++.
|
||||
* * ``access void NS##_erase(RootTy*, ElemTy* data)`` removes ``data`` from the tree. ``data`` is
|
||||
* not freed or otherwise processed, this function only removes the item and rebalances the tree
|
||||
* if necessary.
|
||||
*/
|
||||
#define BEEGFS_RBTREE_FUNCTIONS(Access, NS, RootTy, RootNode, KeyTy, ElemTy, ElemKey, ElemNode, \
|
||||
KeyCmp) \
|
||||
__attribute__((unused)) \
|
||||
Access ElemTy* NS##_find(const RootTy* root, KeyTy key) \
|
||||
{ \
|
||||
struct rb_node* node = root->RootNode.rb_node; \
|
||||
while (node) \
|
||||
{ \
|
||||
ElemTy* data = rb_entry(node, ElemTy, ElemNode); \
|
||||
int cmp = KeyCmp(key, data->ElemKey); \
|
||||
\
|
||||
if (cmp < 0) \
|
||||
node = node->rb_left; \
|
||||
else if (cmp > 0) \
|
||||
node = node->rb_right; \
|
||||
else \
|
||||
return data; \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
__attribute__((unused)) \
|
||||
Access bool NS##_insert(RootTy* root, ElemTy* data) \
|
||||
{ \
|
||||
struct rb_node** new = &root->RootNode.rb_node; \
|
||||
struct rb_node* parent = NULL; \
|
||||
while (*new) \
|
||||
{ \
|
||||
ElemTy* cur = container_of(*new, ElemTy, ElemNode); \
|
||||
int cmp = KeyCmp(data->ElemKey, cur->ElemKey); \
|
||||
\
|
||||
parent = *new; \
|
||||
if (cmp < 0) \
|
||||
new = &(*new)->rb_left; \
|
||||
else if (cmp > 0) \
|
||||
new = &(*new)->rb_right; \
|
||||
else \
|
||||
return false; \
|
||||
} \
|
||||
rb_link_node(&data->ElemNode, parent, new); \
|
||||
rb_insert_color(&data->ElemNode, &root->RootNode); \
|
||||
return true; \
|
||||
} \
|
||||
__attribute__((unused)) \
|
||||
Access ElemTy* NS##_insertOrReplace(RootTy* root, ElemTy* data) \
|
||||
{ \
|
||||
ElemTy* existing; \
|
||||
if (NS##_insert(root, data)) \
|
||||
return NULL; \
|
||||
\
|
||||
existing = NS##_find(root, data->ElemKey); \
|
||||
rb_replace_node(&existing->ElemNode, &data->ElemNode, &root->RootNode); \
|
||||
return existing; \
|
||||
} \
|
||||
__attribute__((unused)) \
|
||||
Access void NS##_erase(RootTy* root, ElemTy* data) \
|
||||
{ \
|
||||
rb_erase(&data->ElemNode, &root->RootNode); \
|
||||
}
|
||||
|
||||
#define BEEGFS_RBTREE_FOR_EACH_ENTRY(Pos, Root, Node) \
|
||||
for (Pos = rb_entry_safe(rb_first(Root), typeof(*Pos), Node); \
|
||||
Pos; \
|
||||
Pos = rb_entry_safe(rb_next(&Pos->Node), typeof(*Pos), Node))
|
||||
|
||||
/* version number of both the network protocol and the on-disk data structures that are versioned.
|
||||
* must be kept in sync with userspace. */
|
||||
#define BEEGFS_DATA_VERSION ((uint32_t)0)
|
||||
|
||||
#endif /*COMMON_H_*/
|
||||
35
client_module/source/common/FhgfsTypes.h
Normal file
35
client_module/source/common/FhgfsTypes.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef OPEN_FHGFSTYPES_H_
|
||||
#define OPEN_FHGFSTYPES_H_
|
||||
|
||||
#include <linux/in.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <common/toolkit/Time.h>
|
||||
|
||||
struct fhgfs_sockaddr_in
|
||||
{
|
||||
struct in_addr addr;
|
||||
__be16 port;
|
||||
};
|
||||
typedef struct fhgfs_sockaddr_in fhgfs_sockaddr_in;
|
||||
|
||||
|
||||
|
||||
struct fhgfs_stat
|
||||
{
|
||||
umode_t mode;
|
||||
unsigned int nlink;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
loff_t size;
|
||||
uint64_t blocks;
|
||||
Time atime;
|
||||
Time mtime;
|
||||
Time ctime; // attrib change time (not creation time)
|
||||
unsigned int metaVersion;
|
||||
};
|
||||
typedef struct fhgfs_stat fhgfs_stat;
|
||||
|
||||
|
||||
|
||||
#endif /* OPEN_FHGFSTYPES_H_ */
|
||||
30
client_module/source/common/Types.c
Normal file
30
client_module/source/common/Types.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "Types.h"
|
||||
|
||||
SERDES_DEFINE_SERIALIZERS_SIMPLE(, TargetMapping, struct TargetMapping,
|
||||
(targetID, , Serialization, UShort),
|
||||
(nodeID, &, NumNodeID, ))
|
||||
SERDES_DEFINE_LIST_SERIALIZERS(, TargetMappingList, struct TargetMapping,
|
||||
TargetMapping, (void), _list, false)
|
||||
|
||||
|
||||
SERDES_DEFINE_SERIALIZERS_SIMPLE(, TargetPoolMapping, struct TargetPoolMapping,
|
||||
(targetID, , Serialization, UShort),
|
||||
(poolID, &, StoragePoolId, ))
|
||||
SERDES_DEFINE_LIST_SERIALIZERS(, TargetPoolMappingList, struct TargetPoolMapping,
|
||||
TargetPoolMapping, (void), _list, false)
|
||||
|
||||
|
||||
SERDES_DEFINE_SERIALIZERS_SIMPLE(, BuddyGroupMapping, struct BuddyGroupMapping,
|
||||
(groupID, , Serialization, UShort),
|
||||
(primaryTargetID, , Serialization, UShort),
|
||||
(secondaryTargetID, , Serialization, UShort))
|
||||
SERDES_DEFINE_LIST_SERIALIZERS(, BuddyGroupMappingList, struct BuddyGroupMapping,
|
||||
BuddyGroupMapping, (void), _list, false)
|
||||
|
||||
|
||||
SERDES_DEFINE_SERIALIZERS_SIMPLE(, TargetStateMapping, struct TargetStateMapping,
|
||||
(targetID, , Serialization, UShort),
|
||||
(reachabilityState, , TargetReachabilityState, ),
|
||||
(consistencyState, , TargetConsistencyState, ))
|
||||
SERDES_DEFINE_LIST_SERIALIZERS(, TargetStateMappingList, struct TargetStateMapping,
|
||||
TargetStateMapping, (void), _list, false)
|
||||
105
client_module/source/common/Types.h
Normal file
105
client_module/source/common/Types.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#ifndef BEEGFS_TYPES_H_
|
||||
#define BEEGFS_TYPES_H_
|
||||
|
||||
#include <common/storage/StoragePoolId.h>
|
||||
#include <common/toolkit/Serialization.h>
|
||||
|
||||
struct TargetMapping
|
||||
{
|
||||
uint16_t targetID;
|
||||
NumNodeID nodeID;
|
||||
|
||||
/* private: */
|
||||
union {
|
||||
struct rb_node _node; /* for use by TargetMapper */
|
||||
struct list_head _list; /* for use by de/serialized lists */
|
||||
};
|
||||
};
|
||||
|
||||
SERDES_DECLARE_SERIALIZERS(TargetMapping, struct TargetMapping)
|
||||
SERDES_DECLARE_LIST_SERIALIZERS(TargetMappingList, struct TargetMapping)
|
||||
|
||||
/* make sure to keep this in sync with TargetState in common lib */
|
||||
enum TargetReachabilityState
|
||||
{
|
||||
TargetReachabilityState_ONLINE,
|
||||
TargetReachabilityState_POFFLINE, // probably offline
|
||||
TargetReachabilityState_OFFLINE
|
||||
};
|
||||
|
||||
typedef enum TargetReachabilityState TargetReachabilityState;
|
||||
|
||||
SERDES_DEFINE_ENUM_SERIALIZERS(TargetReachabilityState, enum TargetReachabilityState,
|
||||
uint8_t, UInt8)
|
||||
|
||||
enum TargetConsistencyState
|
||||
{
|
||||
TargetConsistencyState_GOOD,
|
||||
TargetConsistencyState_NEEDS_RESYNC,
|
||||
TargetConsistencyState_BAD
|
||||
};
|
||||
|
||||
typedef enum TargetConsistencyState TargetConsistencyState;
|
||||
|
||||
SERDES_DEFINE_ENUM_SERIALIZERS(TargetConsistencyState, enum TargetConsistencyState, uint8_t, UInt8)
|
||||
|
||||
struct CombinedTargetState
|
||||
{
|
||||
TargetReachabilityState reachabilityState;
|
||||
TargetConsistencyState consistencyState;
|
||||
};
|
||||
|
||||
typedef struct CombinedTargetState CombinedTargetState;
|
||||
|
||||
struct TargetStateInfo
|
||||
{
|
||||
uint16_t targetID;
|
||||
struct CombinedTargetState state;
|
||||
|
||||
/* private */
|
||||
struct rb_node _node;
|
||||
};
|
||||
|
||||
typedef struct TargetStateInfo TargetStateInfo;
|
||||
|
||||
struct TargetPoolMapping
|
||||
{
|
||||
uint16_t targetID;
|
||||
StoragePoolId poolID;
|
||||
|
||||
/* private: */
|
||||
struct list_head _list; /* for de/serialized lists */
|
||||
};
|
||||
|
||||
SERDES_DECLARE_SERIALIZERS(TargetPoolMapping, struct TargetPoolMapping)
|
||||
SERDES_DECLARE_LIST_SERIALIZERS(TargetPoolMappingList, struct TargetPoolMapping)
|
||||
|
||||
|
||||
struct BuddyGroupMapping
|
||||
{
|
||||
uint16_t groupID;
|
||||
uint16_t primaryTargetID;
|
||||
uint16_t secondaryTargetID;
|
||||
|
||||
/* private: */
|
||||
struct list_head _list; /* for de/serialized lists */
|
||||
};
|
||||
|
||||
SERDES_DECLARE_SERIALIZERS(BuddyGroupMapping, struct BuddyGroupMapping)
|
||||
SERDES_DECLARE_LIST_SERIALIZERS(BuddyGroupMappingList, struct BuddyGroupMapping)
|
||||
|
||||
|
||||
struct TargetStateMapping
|
||||
{
|
||||
uint16_t targetID;
|
||||
TargetReachabilityState reachabilityState;
|
||||
TargetConsistencyState consistencyState;
|
||||
|
||||
/* private: */
|
||||
struct list_head _list; /* for de/serialized lists */
|
||||
};
|
||||
|
||||
SERDES_DECLARE_SERIALIZERS(TargetStateMapping, struct TargetStateMapping)
|
||||
SERDES_DECLARE_LIST_SERIALIZERS(TargetStateMappingList, struct TargetStateMapping)
|
||||
|
||||
#endif
|
||||
149
client_module/source/common/net/message/NetMessage.c
Normal file
149
client_module/source/common/net/message/NetMessage.c
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "NetMessage.h"
|
||||
|
||||
/**
|
||||
* Processes this message.
|
||||
*
|
||||
* Note: Some messages might be received over a datagram socket, so the response
|
||||
* must be atomic (=> only a single sendto()-call)
|
||||
*
|
||||
* @param fromAddr must be NULL for stream sockets
|
||||
* @return false on error
|
||||
*/
|
||||
bool NetMessage_processIncoming(NetMessage* this, struct App* app,
|
||||
fhgfs_sockaddr_in* fromAddr, struct Socket* sock, char* respBuf, size_t bufLen)
|
||||
{
|
||||
// Note: Has to be implemented appropriately by derived classes.
|
||||
// Empty implementation provided here for invalid messages and other messages
|
||||
// that don't require this way of processing (e.g. some response messages).
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all feature flags that are supported by this message. Defaults to "none", so this
|
||||
* method needs to be overridden by derived messages that actually support header feature
|
||||
* flags.
|
||||
*
|
||||
* @return combination of all supported feature flags
|
||||
*/
|
||||
unsigned NetMessage_getSupportedHeaderFeatureFlagsMask(NetMessage* this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the (common) header part of a message from a buffer.
|
||||
*
|
||||
* Note: Message type will be set to NETMSGTYPE_Invalid if deserialization fails.
|
||||
*/
|
||||
void __NetMessage_deserializeHeader(DeserializeCtx* ctx, NetMessageHeader* outHeader)
|
||||
{
|
||||
size_t totalLength = ctx->length;
|
||||
uint64_t prefix = 0;
|
||||
// check min buffer length
|
||||
|
||||
if(unlikely(ctx->length < NETMSG_HEADER_LENGTH) )
|
||||
{
|
||||
outHeader->msgType = NETMSGTYPE_Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
// message length
|
||||
Serialization_deserializeUInt(ctx, &outHeader->msgLength);
|
||||
|
||||
// verify contained msg length
|
||||
if(unlikely(outHeader->msgLength != totalLength) )
|
||||
{
|
||||
outHeader->msgType = NETMSGTYPE_Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
// feature flags
|
||||
Serialization_deserializeUShort(ctx, &outHeader->msgFeatureFlags);
|
||||
Serialization_deserializeUInt8(ctx, &outHeader->msgCompatFeatureFlags);
|
||||
Serialization_deserializeUInt8(ctx, &outHeader->msgFlags);
|
||||
|
||||
// check message prefix
|
||||
Serialization_deserializeUInt64(ctx, &prefix);
|
||||
if (prefix != NETMSG_PREFIX)
|
||||
{
|
||||
outHeader->msgType = NETMSGTYPE_Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
if (outHeader->msgFlags & ~(MSGHDRFLAG_BUDDYMIRROR_SECOND | MSGHDRFLAG_IS_SELECTIVE_ACK |
|
||||
MSGHDRFLAG_HAS_SEQUENCE_NO))
|
||||
{
|
||||
outHeader->msgType = NETMSGTYPE_Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
// message type
|
||||
Serialization_deserializeUShort(ctx, &outHeader->msgType);
|
||||
|
||||
// targetID
|
||||
Serialization_deserializeUShort(ctx, &outHeader->msgTargetID);
|
||||
|
||||
// userID
|
||||
Serialization_deserializeUInt(ctx, &outHeader->msgUserID);
|
||||
|
||||
Serialization_deserializeUInt64(ctx, &outHeader->msgSequence);
|
||||
Serialization_deserializeUInt64(ctx, &outHeader->msgSequenceDone);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes the (common) header part of a message to a buffer.
|
||||
*
|
||||
* Note the min required size for the buf parameter! Message-specific data can be stored
|
||||
* from &buf[NETMSG_HEADER_LENGTH] on.
|
||||
* The msg->msgPrefix field is ignored and will always be stored correctly in the buffer.
|
||||
*
|
||||
* @param buf min size is NETMSG_HEADER_LENGTH
|
||||
* @return false on error (e.g. bufLen too small), true otherwise
|
||||
*/
|
||||
void __NetMessage_serializeHeader(NetMessage* this, SerializeCtx* ctx, bool zeroLengthField)
|
||||
{
|
||||
// message length
|
||||
Serialization_serializeUInt(ctx, zeroLengthField ? 0 : NetMessage_getMsgLength(this) );
|
||||
|
||||
// feature flags
|
||||
Serialization_serializeUShort(ctx, this->msgHeader.msgFeatureFlags);
|
||||
Serialization_serializeChar(ctx, this->msgHeader.msgCompatFeatureFlags);
|
||||
Serialization_serializeChar(ctx, this->msgHeader.msgFlags);
|
||||
|
||||
// message prefix
|
||||
Serialization_serializeUInt64(ctx, NETMSG_PREFIX);
|
||||
|
||||
// message type
|
||||
Serialization_serializeUShort(ctx, this->msgHeader.msgType);
|
||||
|
||||
// targetID
|
||||
Serialization_serializeUShort(ctx, this->msgHeader.msgTargetID);
|
||||
|
||||
// userID
|
||||
Serialization_serializeUInt(ctx, this->msgHeader.msgUserID);
|
||||
|
||||
Serialization_serializeUInt64(ctx, this->msgHeader.msgSequence);
|
||||
Serialization_serializeUInt64(ctx, this->msgHeader.msgSequenceDone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function for deserialize pointers
|
||||
*/
|
||||
bool _NetMessage_deserializeDummy(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
printk_fhgfs(KERN_INFO, "Bug: Deserialize function called, although it should not\n");
|
||||
dump_stack();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function for serialize pointers
|
||||
*/
|
||||
void _NetMessage_serializeDummy(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
printk_fhgfs(KERN_INFO, "Bug: Serialize function called, although it should not\n");
|
||||
dump_stack();
|
||||
}
|
||||
259
client_module/source/common/net/message/NetMessage.h
Normal file
259
client_module/source/common/net/message/NetMessage.h
Normal file
@@ -0,0 +1,259 @@
|
||||
#ifndef NETMESSAGE_H_
|
||||
#define NETMESSAGE_H_
|
||||
|
||||
#include <common/net/sock/NetworkInterfaceCard.h>
|
||||
#include <common/net/sock/Socket.h>
|
||||
#include <common/toolkit/Serialization.h>
|
||||
#include <common/Common.h>
|
||||
#include "NetMessageTypes.h"
|
||||
|
||||
/**
|
||||
* Note: This "class" is not meant to be instantiated directly (consider it to be abstract).
|
||||
* It contains some "virtual" methods, as you can see in the struct NetMessage. Only the virtual
|
||||
* Method processIncoming(..) has a default implementation.
|
||||
* Derived classes have a destructor with a NetMessage-Pointer (instead of the real type)
|
||||
* because of the generic virtual destructor signature.
|
||||
* Derived classes normally have two constructors: One has no arguments and is used for
|
||||
* deserialization. The other one is the standard constructor.
|
||||
*/
|
||||
|
||||
// common message constants
|
||||
// ========================
|
||||
#define NETMSG_PREFIX ((0x42474653ULL << 32) + BEEGFS_DATA_VERSION)
|
||||
#define NETMSG_MIN_LENGTH NETMSG_HEADER_LENGTH
|
||||
#define NETMSG_HEADER_LENGTH 40 /* length of the header (see struct NetMessageHeader) */
|
||||
#define NETMSG_MAX_MSG_SIZE 65536 // 64kB
|
||||
#define NETMSG_MAX_PAYLOAD_SIZE ((unsigned)(NETMSG_MAX_MSG_SIZE - NETMSG_HEADER_LENGTH))
|
||||
|
||||
#define NETMSG_DEFAULT_USERID (~0) // non-zero to avoid mixing up with root userID
|
||||
|
||||
|
||||
// forward declaration
|
||||
struct App;
|
||||
|
||||
|
||||
struct NetMessageHeader;
|
||||
typedef struct NetMessageHeader NetMessageHeader;
|
||||
struct NetMessage;
|
||||
typedef struct NetMessage NetMessage;
|
||||
|
||||
struct NetMessageOps;
|
||||
|
||||
static inline void NETMESSAGE_FREE(NetMessage* this);
|
||||
|
||||
static inline void NetMessage_init(NetMessage* this, unsigned short msgType,
|
||||
const struct NetMessageOps* ops);
|
||||
|
||||
extern void __NetMessage_deserializeHeader(DeserializeCtx* ctx, struct NetMessageHeader* outHeader);
|
||||
extern void __NetMessage_serializeHeader(NetMessage* this, SerializeCtx* ctx, bool zeroLengthField);
|
||||
|
||||
extern void _NetMessage_serializeDummy(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool _NetMessage_deserializeDummy(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
|
||||
static inline unsigned NetMessage_extractMsgLengthFromBuf(const char* recvBuf);
|
||||
static inline bool NetMessage_serialize(NetMessage* this, char* buf, size_t bufLen);
|
||||
static inline bool NetMessage_checkHeaderFeatureFlagsCompat(NetMessage* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool NetMessage_processIncoming(NetMessage* this, struct App* app,
|
||||
fhgfs_sockaddr_in* fromAddr, struct Socket* sock, char* respBuf, size_t bufLen);
|
||||
extern unsigned NetMessage_getSupportedHeaderFeatureFlagsMask(NetMessage* this);
|
||||
|
||||
// getters & setters
|
||||
static inline unsigned short NetMessage_getMsgType(NetMessage* this);
|
||||
static inline unsigned NetMessage_getMsgHeaderFeatureFlags(NetMessage* this);
|
||||
static inline bool NetMessage_isMsgHeaderFeatureFlagSet(NetMessage* this, unsigned flag);
|
||||
static inline void NetMessage_addMsgHeaderFeatureFlag(NetMessage* this, unsigned flag);
|
||||
static inline unsigned NetMessage_getMsgLength(NetMessage* this);
|
||||
static inline void NetMessage_setMsgHeaderUserID(NetMessage* this, unsigned userID);
|
||||
static inline void NetMessage_setMsgHeaderTargetID(NetMessage* this, uint16_t userID);
|
||||
|
||||
static inline void _NetMessage_setMsgType(NetMessage* this, unsigned short msgType);
|
||||
|
||||
|
||||
#define MSGHDRFLAG_BUDDYMIRROR_SECOND (0x01)
|
||||
#define MSGHDRFLAG_IS_SELECTIVE_ACK (0x02)
|
||||
#define MSGHDRFLAG_HAS_SEQUENCE_NO (0x04)
|
||||
|
||||
struct NetMessageHeader
|
||||
{
|
||||
unsigned msgLength; // in bytes
|
||||
uint16_t msgFeatureFlags; // feature flags for derived messages (depend on msgType)
|
||||
uint8_t msgCompatFeatureFlags; /* for derived messages, similar to msgFeatureFlags, but
|
||||
"compat" because there is no check whether receiver
|
||||
understands these flags, so they might be ignored. */
|
||||
uint8_t msgFlags;
|
||||
// char* msgPrefix; // NETMSG_PREFIX_STR (8 bytes)
|
||||
unsigned short msgType; // the type of payload, defined as NETMSGTYPE_x
|
||||
uint16_t msgTargetID; // targetID (not groupID) for per-target workers on storage server
|
||||
unsigned msgUserID; // system user ID for per-user msg queues, stats etc.
|
||||
uint64_t msgSequence; // for retries, 0 if not present
|
||||
uint64_t msgSequenceDone; // a sequence number that has been fully processed, or 0
|
||||
};
|
||||
|
||||
struct NetMessageOps
|
||||
{
|
||||
void (*serializePayload) (NetMessage* this, SerializeCtx* ctx);
|
||||
bool (*deserializePayload) (NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
bool (*processIncoming) (NetMessage* this, struct App* app, fhgfs_sockaddr_in* fromAddr,
|
||||
struct Socket* sock, char* respBuf, size_t bufLen);
|
||||
unsigned (*getSupportedHeaderFeatureFlagsMask) (NetMessage* this);
|
||||
|
||||
void (*release)(NetMessage* this);
|
||||
|
||||
|
||||
// not strictly operations, but these are common to all messages and do not warrant their own
|
||||
// functions
|
||||
bool supportsSequenceNumbers;
|
||||
};
|
||||
|
||||
struct NetMessage
|
||||
{
|
||||
struct NetMessageHeader msgHeader;
|
||||
|
||||
const struct NetMessageOps* ops;
|
||||
};
|
||||
|
||||
|
||||
void NetMessage_init(NetMessage* this, unsigned short msgType, const struct NetMessageOps* ops)
|
||||
{
|
||||
memset(this, 0, sizeof(*this) ); // clear function pointers etc.
|
||||
|
||||
// this->msgLength = 0; // zero'ed by memset
|
||||
// this->msgFeatureFlags = 0; // zero'ed by memset
|
||||
|
||||
this->msgHeader.msgType = msgType;
|
||||
|
||||
// needs to be set to actual ID by some async flushers etc
|
||||
this->msgHeader.msgUserID = FhgfsCommon_getCurrentUserID();
|
||||
|
||||
// this->msgTargetID = 0; // zero'ed by memset
|
||||
|
||||
this->ops = ops;
|
||||
}
|
||||
|
||||
#define NETMESSAGE_CONSTRUCT(TYPE) \
|
||||
({ \
|
||||
TYPE* msg = os_kmalloc(sizeof(TYPE)); \
|
||||
TYPE##_init(msg); \
|
||||
(NetMessage*)msg; \
|
||||
})
|
||||
|
||||
static inline void NETMESSAGE_FREE(NetMessage* msg)
|
||||
{
|
||||
if (msg->ops->release)
|
||||
msg->ops->release(msg);
|
||||
|
||||
kfree(msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* recvBuf must be at least NETMSG_MIN_LENGTH long
|
||||
*/
|
||||
unsigned NetMessage_extractMsgLengthFromBuf(const char* recvBuf)
|
||||
{
|
||||
unsigned msgLength;
|
||||
DeserializeCtx ctx = { recvBuf, sizeof(msgLength) };
|
||||
|
||||
Serialization_deserializeUInt(&ctx, &msgLength);
|
||||
|
||||
return msgLength;
|
||||
}
|
||||
|
||||
bool NetMessage_serialize(NetMessage* this, char* buf, size_t bufLen)
|
||||
{
|
||||
SerializeCtx ctx = {
|
||||
.data = buf,
|
||||
};
|
||||
|
||||
if(unlikely(bufLen < NetMessage_getMsgLength(this) ) )
|
||||
return false;
|
||||
|
||||
__NetMessage_serializeHeader(this, &ctx, false);
|
||||
this->ops->serializePayload(this, &ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the msg sender has set an incompatible feature flag.
|
||||
*
|
||||
* @return false if an incompatible feature flag was set
|
||||
*/
|
||||
bool NetMessage_checkHeaderFeatureFlagsCompat(NetMessage* this)
|
||||
{
|
||||
unsigned unsupportedFlags = ~(this->ops->getSupportedHeaderFeatureFlagsMask(this) );
|
||||
if(unlikely(this->msgHeader.msgFeatureFlags & unsupportedFlags) )
|
||||
return false; // an unsupported flag was set
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned short NetMessage_getMsgType(NetMessage* this)
|
||||
{
|
||||
return this->msgHeader.msgType;
|
||||
}
|
||||
|
||||
unsigned NetMessage_getMsgHeaderFeatureFlags(NetMessage* this)
|
||||
{
|
||||
return this->msgHeader.msgFeatureFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test flag. (For convenience and readability.)
|
||||
*
|
||||
* @return true if given flag is set.
|
||||
*/
|
||||
bool NetMessage_isMsgHeaderFeatureFlagSet(NetMessage* this, unsigned flag)
|
||||
{
|
||||
return (this->msgHeader.msgFeatureFlags & flag) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another flag without clearing the previously set flags.
|
||||
*
|
||||
* Note: The receiver will reject this message if it doesn't know the given feature flag.
|
||||
*/
|
||||
void NetMessage_addMsgHeaderFeatureFlag(NetMessage* this, unsigned flag)
|
||||
{
|
||||
this->msgHeader.msgFeatureFlags |= flag;
|
||||
}
|
||||
|
||||
unsigned NetMessage_getMsgLength(NetMessage* this)
|
||||
{
|
||||
if(!this->msgHeader.msgLength)
|
||||
{
|
||||
SerializeCtx ctx = { NULL, 0 };
|
||||
|
||||
__NetMessage_serializeHeader(this, &ctx, true);
|
||||
this->ops->serializePayload(this, &ctx);
|
||||
|
||||
this->msgHeader.msgLength = ctx.length;
|
||||
}
|
||||
|
||||
return this->msgHeader.msgLength;
|
||||
}
|
||||
|
||||
void NetMessage_setMsgHeaderUserID(NetMessage* this, unsigned userID)
|
||||
{
|
||||
this->msgHeader.msgUserID = userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param targetID this has to be an actual targetID (not a groupID).
|
||||
*/
|
||||
void NetMessage_setMsgHeaderTargetID(NetMessage* this, uint16_t targetID)
|
||||
{
|
||||
this->msgHeader.msgTargetID = targetID;
|
||||
}
|
||||
|
||||
void _NetMessage_setMsgType(NetMessage* this, unsigned short msgType)
|
||||
{
|
||||
this->msgHeader.msgType = msgType;
|
||||
}
|
||||
|
||||
|
||||
#endif /*NETMESSAGE_H_*/
|
||||
273
client_module/source/common/net/message/NetMessageTypes.h
Normal file
273
client_module/source/common/net/message/NetMessageTypes.h
Normal file
@@ -0,0 +1,273 @@
|
||||
#ifndef NETMESSAGETYPES_H_
|
||||
#define NETMESSAGETYPES_H_
|
||||
|
||||
/* This file MUST be kept in sync with the corresponding fhgfs_common file!
|
||||
See fhgfs_common/source/common/net/message/NetMessageTypes.h */
|
||||
|
||||
// invalid messages
|
||||
#define NETMSGTYPE_Invalid 0
|
||||
|
||||
// nodes messages
|
||||
#define NETMSGTYPE_RemoveNode 1013
|
||||
#define NETMSGTYPE_RemoveNodeResp 1014
|
||||
#define NETMSGTYPE_GetNodes 1017
|
||||
#define NETMSGTYPE_GetNodesResp 1018
|
||||
#define NETMSGTYPE_HeartbeatRequest 1019
|
||||
#define NETMSGTYPE_Heartbeat 1020
|
||||
#define NETMSGTYPE_GetNodeCapacityPools 1021
|
||||
#define NETMSGTYPE_GetNodeCapacityPoolsResp 1022
|
||||
#define NETMSGTYPE_MapTargets 1023
|
||||
#define NETMSGTYPE_MapTargetsResp 1024
|
||||
#define NETMSGTYPE_GetTargetMappings 1025
|
||||
#define NETMSGTYPE_GetTargetMappingsResp 1026
|
||||
#define NETMSGTYPE_UnmapTarget 1027
|
||||
#define NETMSGTYPE_UnmapTargetResp 1028
|
||||
#define NETMSGTYPE_GenericDebug 1029
|
||||
#define NETMSGTYPE_GenericDebugResp 1030
|
||||
#define NETMSGTYPE_GetClientStats 1031
|
||||
#define NETMSGTYPE_GetClientStatsResp 1032
|
||||
#define NETMSGTYPE_RefreshCapacityPools 1035
|
||||
#define NETMSGTYPE_StorageBenchControlMsg 1037
|
||||
#define NETMSGTYPE_StorageBenchControlMsgResp 1038
|
||||
#define NETMSGTYPE_RegisterNode 1039
|
||||
#define NETMSGTYPE_RegisterNodeResp 1040
|
||||
#define NETMSGTYPE_RegisterTarget 1041
|
||||
#define NETMSGTYPE_RegisterTargetResp 1042
|
||||
#define NETMSGTYPE_SetMirrorBuddyGroup 1045
|
||||
#define NETMSGTYPE_SetMirrorBuddyGroupResp 1046
|
||||
#define NETMSGTYPE_GetMirrorBuddyGroups 1047
|
||||
#define NETMSGTYPE_GetMirrorBuddyGroupsResp 1048
|
||||
#define NETMSGTYPE_GetTargetStates 1049
|
||||
#define NETMSGTYPE_GetTargetStatesResp 1050
|
||||
#define NETMSGTYPE_RefreshTargetStates 1051
|
||||
#define NETMSGTYPE_GetStatesAndBuddyGroups 1053
|
||||
#define NETMSGTYPE_GetStatesAndBuddyGroupsResp 1054
|
||||
#define NETMSGTYPE_SetTargetConsistencyStates 1055
|
||||
#define NETMSGTYPE_SetTargetConsistencyStatesResp 1056
|
||||
#define NETMSGTYPE_ChangeTargetConsistencyStates 1057
|
||||
#define NETMSGTYPE_ChangeTargetConsistencyStatesResp 1058
|
||||
#define NETMSGTYPE_PublishCapacities 1059
|
||||
#define NETMSGTYPE_RemoveBuddyGroup 1060
|
||||
#define NETMSGTYPE_RemoveBuddyGroupResp 1061
|
||||
#define NETMSGTYPE_GetTargetConsistencyStates 1062
|
||||
#define NETMSGTYPE_GetTargetConsistencyStatesResp 1063
|
||||
|
||||
|
||||
// storage messages
|
||||
#define NETMSGTYPE_MkDir 2001
|
||||
#define NETMSGTYPE_MkDirResp 2002
|
||||
#define NETMSGTYPE_RmDir 2003
|
||||
#define NETMSGTYPE_RmDirResp 2004
|
||||
#define NETMSGTYPE_MkFile 2005
|
||||
#define NETMSGTYPE_MkFileResp 2006
|
||||
#define NETMSGTYPE_UnlinkFile 2007
|
||||
#define NETMSGTYPE_UnlinkFileResp 2008
|
||||
#define NETMSGTYPE_UnlinkLocalFile 2011
|
||||
#define NETMSGTYPE_UnlinkLocalFileResp 2012
|
||||
#define NETMSGTYPE_Stat 2015
|
||||
#define NETMSGTYPE_StatResp 2016
|
||||
#define NETMSGTYPE_GetChunkFileAttribs 2017
|
||||
#define NETMSGTYPE_GetChunkFileAttribsResp 2018
|
||||
#define NETMSGTYPE_TruncFile 2019
|
||||
#define NETMSGTYPE_TruncFileResp 2020
|
||||
#define NETMSGTYPE_TruncLocalFile 2021
|
||||
#define NETMSGTYPE_TruncLocalFileResp 2022
|
||||
#define NETMSGTYPE_Rename 2023
|
||||
#define NETMSGTYPE_RenameResp 2024
|
||||
#define NETMSGTYPE_SetAttr 2025
|
||||
#define NETMSGTYPE_SetAttrResp 2026
|
||||
#define NETMSGTYPE_ListDirFromOffset 2029
|
||||
#define NETMSGTYPE_ListDirFromOffsetResp 2030
|
||||
#define NETMSGTYPE_StatStoragePath 2031
|
||||
#define NETMSGTYPE_StatStoragePathResp 2032
|
||||
#define NETMSGTYPE_SetLocalAttr 2033
|
||||
#define NETMSGTYPE_SetLocalAttrResp 2034
|
||||
#define NETMSGTYPE_FindOwner 2035
|
||||
#define NETMSGTYPE_FindOwnerResp 2036
|
||||
#define NETMSGTYPE_MkLocalDir 2037
|
||||
#define NETMSGTYPE_MkLocalDirResp 2038
|
||||
#define NETMSGTYPE_RmLocalDir 2039
|
||||
#define NETMSGTYPE_RmLocalDirResp 2040
|
||||
#define NETMSGTYPE_MovingFileInsert 2041
|
||||
#define NETMSGTYPE_MovingFileInsertResp 2042
|
||||
#define NETMSGTYPE_MovingDirInsert 2043
|
||||
#define NETMSGTYPE_MovingDirInsertResp 2044
|
||||
#define NETMSGTYPE_GetEntryInfo 2045
|
||||
#define NETMSGTYPE_GetEntryInfoResp 2046
|
||||
#define NETMSGTYPE_SetDirPattern 2047
|
||||
#define NETMSGTYPE_SetDirPatternResp 2048
|
||||
#define NETMSGTYPE_GetHighResStats 2051
|
||||
#define NETMSGTYPE_GetHighResStatsResp 2052
|
||||
#define NETMSGTYPE_MkFileWithPattern 2053
|
||||
#define NETMSGTYPE_MkFileWithPatternResp 2054
|
||||
#define NETMSGTYPE_RefreshEntryInfo 2055
|
||||
#define NETMSGTYPE_RefreshEntryInfoResp 2056
|
||||
#define NETMSGTYPE_RmDirEntry 2057
|
||||
#define NETMSGTYPE_RmDirEntryResp 2058
|
||||
#define NETMSGTYPE_LookupIntent 2059
|
||||
#define NETMSGTYPE_LookupIntentResp 2060
|
||||
#define NETMSGTYPE_FindLinkOwner 2063
|
||||
#define NETMSGTYPE_FindLinkOwnerResp 2064
|
||||
#define NETMSGTYPE_MirrorMetadata 2067
|
||||
#define NETMSGTYPE_MirrorMetadataResp 2068
|
||||
#define NETMSGTYPE_SetMetadataMirroring 2069
|
||||
#define NETMSGTYPE_SetMetadataMirroringResp 2070
|
||||
#define NETMSGTYPE_Hardlink 2071
|
||||
#define NETMSGTYPE_HardlinkResp 2072
|
||||
#define NETMSGTYPE_SetQuota 2075
|
||||
#define NETMSGTYPE_SetQuotaResp 2076
|
||||
#define NETMSGTYPE_SetExceededQuota 2077
|
||||
#define NETMSGTYPE_SetExceededQuotaResp 2078
|
||||
#define NETMSGTYPE_RequestExceededQuota 2079
|
||||
#define NETMSGTYPE_RequestExceededQuotaResp 2080
|
||||
#define NETMSGTYPE_UpdateDirParent 2081
|
||||
#define NETMSGTYPE_UpdateDirParentResp 2082
|
||||
#define NETMSGTYPE_ResyncLocalFile 2083
|
||||
#define NETMSGTYPE_ResyncLocalFileResp 2084
|
||||
#define NETMSGTYPE_StartStorageTargetResync 2085
|
||||
#define NETMSGTYPE_StartStorageTargetResyncResp 2086
|
||||
#define NETMSGTYPE_StorageResyncStarted 2087
|
||||
#define NETMSGTYPE_StorageResyncStartedResp 2088
|
||||
#define NETMSGTYPE_ListChunkDirIncremental 2089
|
||||
#define NETMSGTYPE_ListChunkDirIncrementalResp 2090
|
||||
#define NETMSGTYPE_RmChunkPaths 2091
|
||||
#define NETMSGTYPE_RmChunkPathsResp 2092
|
||||
#define NETMSGTYPE_GetStorageResyncStats 2093
|
||||
#define NETMSGTYPE_GetStorageResyncStatsResp 2094
|
||||
#define NETMSGTYPE_SetLastBuddyCommOverride 2095
|
||||
#define NETMSGTYPE_SetLastBuddyCommOverrideResp 2096
|
||||
#define NETMSGTYPE_GetQuotaInfo 2097
|
||||
#define NETMSGTYPE_GetQuotaInfoResp 2098
|
||||
#define NETMSGTYPE_SetStorageTargetInfo 2099
|
||||
#define NETMSGTYPE_SetStorageTargetInfoResp 2100
|
||||
#define NETMSGTYPE_ListXAttr 2101
|
||||
#define NETMSGTYPE_ListXAttrResp 2102
|
||||
#define NETMSGTYPE_GetXAttr 2103
|
||||
#define NETMSGTYPE_GetXAttrResp 2104
|
||||
#define NETMSGTYPE_RemoveXAttr 2105
|
||||
#define NETMSGTYPE_RemoveXAttrResp 2106
|
||||
#define NETMSGTYPE_SetXAttr 2107
|
||||
#define NETMSGTYPE_SetXAttrResp 2108
|
||||
#define NETMSGTYPE_GetDefaultQuota 2109
|
||||
#define NETMSGTYPE_GetDefaultQuotaResp 2110
|
||||
#define NETMSGTYPE_SetDefaultQuota 2111
|
||||
#define NETMSGTYPE_SetDefaultQuotaResp 2112
|
||||
#define NETMSGTYPE_ResyncSessionStore 2113
|
||||
#define NETMSGTYPE_ResyncSessionStoreResp 2114
|
||||
#define NETMSGTYPE_ResyncRawInodes 2115
|
||||
#define NETMSGTYPE_ResyncRawInodesResp 2116
|
||||
#define NETMSGTYPE_GetMetaResyncStats 2117
|
||||
#define NETMSGTYPE_GetMetaResyncStatsResp 2118
|
||||
#define NETMSGTYPE_MoveFileInode 2119
|
||||
#define NETMSGTYPE_MoveFileInodeResp 2120
|
||||
#define NETMSGTYPE_UnlinkLocalFileInode 2121
|
||||
#define NETMSGTYPE_UnlinkLocalFileInodeResp 2122
|
||||
#define NETMSGTYPE_SetFilePattern 2123
|
||||
#define NETMSGTYPE_SetFilePatternResp 2124
|
||||
#define NETMSGTYPE_CpChunkPaths 2125
|
||||
#define NETMSGTYPE_CpChunkPathsResp 2126
|
||||
#define NETMSGTYPE_ChunkBalance 2127
|
||||
#define NETMSGTYPE_ChunkBalanceResp 2128
|
||||
#define NETMSGTYPE_StripePatternUpdate 2129
|
||||
#define NETMSGTYPE_StripePatternUpdateResp 2130
|
||||
#define NETMSGTYPE_SetFileState 2131
|
||||
#define NETMSGTYPE_SetFileStateResp 2132
|
||||
|
||||
// session messages
|
||||
#define NETMSGTYPE_OpenFile 3001
|
||||
#define NETMSGTYPE_OpenFileResp 3002
|
||||
#define NETMSGTYPE_CloseFile 3003
|
||||
#define NETMSGTYPE_CloseFileResp 3004
|
||||
#define NETMSGTYPE_OpenLocalFile 3005
|
||||
#define NETMSGTYPE_OpenLocalFileResp 3006
|
||||
#define NETMSGTYPE_CloseChunkFile 3007
|
||||
#define NETMSGTYPE_CloseChunkFileResp 3008
|
||||
#define NETMSGTYPE_WriteLocalFile 3009
|
||||
#define NETMSGTYPE_WriteLocalFileResp 3010
|
||||
#define NETMSGTYPE_FSyncLocalFile 3013
|
||||
#define NETMSGTYPE_FSyncLocalFileResp 3014
|
||||
#define NETMSGTYPE_ReadLocalFileV2 3019
|
||||
#define NETMSGTYPE_RefreshSession 3021
|
||||
#define NETMSGTYPE_RefreshSessionResp 3022
|
||||
#define NETMSGTYPE_LockGranted 3023
|
||||
#define NETMSGTYPE_FLockEntry 3025
|
||||
#define NETMSGTYPE_FLockEntryResp 3026
|
||||
#define NETMSGTYPE_FLockRange 3027
|
||||
#define NETMSGTYPE_FLockRangeResp 3028
|
||||
#define NETMSGTYPE_FLockAppend 3029
|
||||
#define NETMSGTYPE_FLockAppendResp 3030
|
||||
#define NETMSGTYPE_AckNotify 3031
|
||||
#define NETMSGTYPE_AckNotifyResp 3032
|
||||
#define NETMSGTYPE_BumpFileVersion 3033
|
||||
#define NETMSGTYPE_BumpFileVersionResp 3034
|
||||
#define NETMSGTYPE_GetFileVersion 3035
|
||||
#define NETMSGTYPE_GetFileVersionResp 3036
|
||||
#ifdef BEEGFS_NVFS
|
||||
#define NETMSGTYPE_WriteLocalFileRDMA 3037
|
||||
#define NETMSGTYPE_WriteLocalFileRDMAResp 3038
|
||||
#define NETMSGTYPE_ReadLocalFileRDMA 3039
|
||||
#define NETMSGTYPE_ReadLocalFileRDMAResp 3040
|
||||
#endif
|
||||
|
||||
// control messages
|
||||
#define NETMSGTYPE_SetChannelDirect 4001
|
||||
#define NETMSGTYPE_Ack 4003
|
||||
#define NETMSGTYPE_Dummy 4005
|
||||
#define NETMSGTYPE_AuthenticateChannel 4007
|
||||
#define NETMSGTYPE_GenericResponse 4009
|
||||
#define NETMSGTYPE_PeerInfo 4011
|
||||
|
||||
// mon messages
|
||||
#define NETMSGTYPE_GetNodesFromRootMetaNode 6001
|
||||
#define NETMSGTYPE_SendNodesList 6002
|
||||
#define NETMSGTYPE_RequestMetaData 6003
|
||||
#define NETMSGTYPE_RequestStorageData 6004
|
||||
#define NETMSGTYPE_RequestMetaDataResp 6005
|
||||
#define NETMSGTYPE_RequestStorageDataResp 6006
|
||||
|
||||
// fsck messages
|
||||
#define NETMSGTYPE_RetrieveDirEntries 7001
|
||||
#define NETMSGTYPE_RetrieveDirEntriesResp 7002
|
||||
#define NETMSGTYPE_RetrieveInodes 7003
|
||||
#define NETMSGTYPE_RetrieveInodesResp 7004
|
||||
#define NETMSGTYPE_RetrieveChunks 7005
|
||||
#define NETMSGTYPE_RetrieveChunksResp 7006
|
||||
#define NETMSGTYPE_RetrieveFsIDs 7007
|
||||
#define NETMSGTYPE_RetrieveFsIDsResp 7008
|
||||
#define NETMSGTYPE_DeleteDirEntries 7009
|
||||
#define NETMSGTYPE_DeleteDirEntriesResp 7010
|
||||
#define NETMSGTYPE_CreateDefDirInodes 7011
|
||||
#define NETMSGTYPE_CreateDefDirInodesResp 7012
|
||||
#define NETMSGTYPE_FixInodeOwnersInDentry 7013
|
||||
#define NETMSGTYPE_FixInodeOwnersInDentryResp 7014
|
||||
#define NETMSGTYPE_FixInodeOwners 7015
|
||||
#define NETMSGTYPE_FixInodeOwnersResp 7016
|
||||
#define NETMSGTYPE_LinkToLostAndFound 7017
|
||||
#define NETMSGTYPE_LinkToLostAndFoundResp 7018
|
||||
#define NETMSGTYPE_DeleteChunks 7019
|
||||
#define NETMSGTYPE_DeleteChunksResp 7020
|
||||
#define NETMSGTYPE_CreateEmptyContDirs 7021
|
||||
#define NETMSGTYPE_CreateEmptyContDirsResp 7022
|
||||
#define NETMSGTYPE_UpdateFileAttribs 7023
|
||||
#define NETMSGTYPE_UpdateFileAttribsResp 7024
|
||||
#define NETMSGTYPE_UpdateDirAttribs 7025
|
||||
#define NETMSGTYPE_UpdateDirAttribsResp 7026
|
||||
#define NETMSGTYPE_RemoveInodes 7027
|
||||
#define NETMSGTYPE_RemoveInodesResp 7028
|
||||
#define NETMSGTYPE_RecreateFsIDs 7031
|
||||
#define NETMSGTYPE_RecreateFsIDsResp 7032
|
||||
#define NETMSGTYPE_RecreateDentries 7033
|
||||
#define NETMSGTYPE_RecreateDentriesResp 7034
|
||||
#define NETMSGTYPE_FsckModificationEvent 7035
|
||||
#define NETMSGTYPE_FsckSetEventLogging 7036
|
||||
#define NETMSGTYPE_FsckSetEventLoggingResp 7037
|
||||
#define NETMSGTYPE_FetchFsckChunkList 7038
|
||||
#define NETMSGTYPE_FetchFsckChunkListResp 7039
|
||||
#define NETMSGTYPE_AdjustChunkPermissions 7040
|
||||
#define NETMSGTYPE_AdjustChunkPermissionsResp 7041
|
||||
#define NETMSGTYPE_MoveChunkFile 7042
|
||||
#define NETMSGTYPE_MoveChunkFileResp 7043
|
||||
#define NETMSGTYPE_CheckAndRepairDupInode 7044
|
||||
#define NETMSGTYPE_CheckAndRepairDupInodeResp 7045
|
||||
|
||||
#endif /*NETMESSAGETYPES_H_*/
|
||||
22
client_module/source/common/net/message/SimpleInt64Msg.c
Normal file
22
client_module/source/common/net/message/SimpleInt64Msg.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "SimpleInt64Msg.h"
|
||||
|
||||
const struct NetMessageOps SimpleInt64Msg_Ops = {
|
||||
.serializePayload = SimpleInt64Msg_serializePayload,
|
||||
.deserializePayload = SimpleInt64Msg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleInt64Msg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
SimpleInt64Msg* thisCast = (SimpleInt64Msg*)this;
|
||||
|
||||
Serialization_serializeInt64(ctx, thisCast->value);
|
||||
}
|
||||
|
||||
bool SimpleInt64Msg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
SimpleInt64Msg* thisCast = (SimpleInt64Msg*)this;
|
||||
|
||||
return Serialization_deserializeInt64(ctx, &thisCast->value);
|
||||
}
|
||||
46
client_module/source/common/net/message/SimpleInt64Msg.h
Normal file
46
client_module/source/common/net/message/SimpleInt64Msg.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef SIMPLEINT64MSG_H_
|
||||
#define SIMPLEINT64MSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
struct SimpleInt64Msg;
|
||||
typedef struct SimpleInt64Msg SimpleInt64Msg;
|
||||
|
||||
static inline void SimpleInt64Msg_init(SimpleInt64Msg* this, unsigned short msgType);
|
||||
static inline void SimpleInt64Msg_initFromValue(SimpleInt64Msg* this, unsigned short msgType,
|
||||
int64_t value);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleInt64Msg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleInt64Msg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline int64_t SimpleInt64Msg_getValue(SimpleInt64Msg* this);
|
||||
|
||||
struct SimpleInt64Msg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleInt64Msg_Ops;
|
||||
|
||||
void SimpleInt64Msg_init(SimpleInt64Msg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleInt64Msg_Ops);
|
||||
}
|
||||
|
||||
void SimpleInt64Msg_initFromValue(SimpleInt64Msg* this, unsigned short msgType, int64_t value)
|
||||
{
|
||||
SimpleInt64Msg_init(this, msgType);
|
||||
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
int64_t SimpleInt64Msg_getValue(SimpleInt64Msg* this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
#endif /*SIMPLEINT64MSG_H_*/
|
||||
22
client_module/source/common/net/message/SimpleIntMsg.c
Normal file
22
client_module/source/common/net/message/SimpleIntMsg.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "SimpleIntMsg.h"
|
||||
|
||||
const struct NetMessageOps SimpleIntMsg_Ops = {
|
||||
.serializePayload = SimpleIntMsg_serializePayload,
|
||||
.deserializePayload = SimpleIntMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleIntMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
SimpleIntMsg* thisCast = (SimpleIntMsg*)this;
|
||||
|
||||
Serialization_serializeInt(ctx, thisCast->value);
|
||||
}
|
||||
|
||||
bool SimpleIntMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
SimpleIntMsg* thisCast = (SimpleIntMsg*)this;
|
||||
|
||||
return Serialization_deserializeInt(ctx, &thisCast->value);
|
||||
}
|
||||
48
client_module/source/common/net/message/SimpleIntMsg.h
Normal file
48
client_module/source/common/net/message/SimpleIntMsg.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef SIMPLEINTMSG_H_
|
||||
#define SIMPLEINTMSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
struct SimpleIntMsg;
|
||||
typedef struct SimpleIntMsg SimpleIntMsg;
|
||||
|
||||
static inline void SimpleIntMsg_init(SimpleIntMsg* this, unsigned short msgType);
|
||||
static inline void SimpleIntMsg_initFromValue(SimpleIntMsg* this, unsigned short msgType,
|
||||
int value);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleIntMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleIntMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline int SimpleIntMsg_getValue(SimpleIntMsg* this);
|
||||
|
||||
|
||||
struct SimpleIntMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleIntMsg_Ops;
|
||||
|
||||
void SimpleIntMsg_init(SimpleIntMsg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleIntMsg_Ops);
|
||||
}
|
||||
|
||||
void SimpleIntMsg_initFromValue(SimpleIntMsg* this, unsigned short msgType, int value)
|
||||
{
|
||||
SimpleIntMsg_init(this, msgType);
|
||||
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
int SimpleIntMsg_getValue(SimpleIntMsg* this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
|
||||
#endif /*SIMPLEINTMSG_H_*/
|
||||
31
client_module/source/common/net/message/SimpleIntStringMsg.c
Normal file
31
client_module/source/common/net/message/SimpleIntStringMsg.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "SimpleIntStringMsg.h"
|
||||
|
||||
const struct NetMessageOps SimpleIntStringMsg_Ops = {
|
||||
.serializePayload = SimpleIntStringMsg_serializePayload,
|
||||
.deserializePayload = SimpleIntStringMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleIntStringMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
SimpleIntStringMsg* thisCast = (SimpleIntStringMsg*)this;
|
||||
|
||||
Serialization_serializeInt(ctx, thisCast->intValue);
|
||||
Serialization_serializeStr(ctx, thisCast->strValueLen, thisCast->strValue);
|
||||
}
|
||||
|
||||
bool SimpleIntStringMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
SimpleIntStringMsg* thisCast = (SimpleIntStringMsg*)this;
|
||||
|
||||
// intValue
|
||||
if(!Serialization_deserializeInt(ctx, &thisCast->intValue) )
|
||||
return false;
|
||||
|
||||
// strValue
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->strValueLen, &thisCast->strValue) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
69
client_module/source/common/net/message/SimpleIntStringMsg.h
Normal file
69
client_module/source/common/net/message/SimpleIntStringMsg.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef SIMPLEINTSTRINGMSG_H_
|
||||
#define SIMPLEINTSTRINGMSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
struct SimpleIntStringMsg;
|
||||
typedef struct SimpleIntStringMsg SimpleIntStringMsg;
|
||||
|
||||
static inline void SimpleIntStringMsg_init(SimpleIntStringMsg* this, unsigned short msgType);
|
||||
static inline void SimpleIntStringMsg_initFromValue(SimpleIntStringMsg* this, unsigned short msgType,
|
||||
int intValue, const char* strValue);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleIntStringMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleIntStringMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline int SimpleIntStringMsg_getIntValue(SimpleIntStringMsg* this);
|
||||
static inline const char* SimpleIntStringMsg_getStrValue(SimpleIntStringMsg* this);
|
||||
|
||||
|
||||
/**
|
||||
* Simple message containing an integer value and a string (e.g. int error code and human-readable
|
||||
* explantion with more details as string).
|
||||
*/
|
||||
struct SimpleIntStringMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
int intValue;
|
||||
|
||||
const char* strValue;
|
||||
unsigned strValueLen;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleIntStringMsg_Ops;
|
||||
|
||||
void SimpleIntStringMsg_init(SimpleIntStringMsg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleIntStringMsg_Ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param strValue just a reference, so don't free or modify it while this msg is used.
|
||||
*/
|
||||
void SimpleIntStringMsg_initFromValue(SimpleIntStringMsg* this, unsigned short msgType,
|
||||
int intValue, const char* strValue)
|
||||
{
|
||||
SimpleIntStringMsg_init(this, msgType);
|
||||
|
||||
this->intValue = intValue;
|
||||
|
||||
this->strValue = strValue;
|
||||
this->strValueLen = strlen(strValue);
|
||||
}
|
||||
|
||||
int SimpleIntStringMsg_getIntValue(SimpleIntStringMsg* this)
|
||||
{
|
||||
return this->intValue;
|
||||
}
|
||||
|
||||
const char* SimpleIntStringMsg_getStrValue(SimpleIntStringMsg* this)
|
||||
{
|
||||
return this->strValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* SIMPLEINTSTRINGMSG_H_ */
|
||||
19
client_module/source/common/net/message/SimpleMsg.c
Normal file
19
client_module/source/common/net/message/SimpleMsg.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "SimpleMsg.h"
|
||||
|
||||
const struct NetMessageOps SimpleMsg_Ops = {
|
||||
.serializePayload = SimpleMsg_serializePayload,
|
||||
.deserializePayload = SimpleMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
// nothing to be done here for simple messages
|
||||
}
|
||||
|
||||
bool SimpleMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
// nothing to be done here for simple messages
|
||||
return true;
|
||||
}
|
||||
33
client_module/source/common/net/message/SimpleMsg.h
Normal file
33
client_module/source/common/net/message/SimpleMsg.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef SIMPLEMSG_H_
|
||||
#define SIMPLEMSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
/**
|
||||
* Note: Simple messages are defined by the header (resp. the msgType) only and
|
||||
* require no additional data
|
||||
*/
|
||||
|
||||
struct SimpleMsg;
|
||||
typedef struct SimpleMsg SimpleMsg;
|
||||
|
||||
static inline void SimpleMsg_init(SimpleMsg* this, unsigned short msgType);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
|
||||
struct SimpleMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleMsg_Ops;
|
||||
|
||||
void SimpleMsg_init(SimpleMsg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleMsg_Ops);
|
||||
}
|
||||
|
||||
#endif /*SIMPLEMSG_H_*/
|
||||
22
client_module/source/common/net/message/SimpleStringMsg.c
Normal file
22
client_module/source/common/net/message/SimpleStringMsg.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "SimpleStringMsg.h"
|
||||
|
||||
const struct NetMessageOps SimpleStringMsg_Ops = {
|
||||
.serializePayload = SimpleStringMsg_serializePayload,
|
||||
.deserializePayload = SimpleStringMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleStringMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
SimpleStringMsg* thisCast = (SimpleStringMsg*)this;
|
||||
|
||||
Serialization_serializeStr(ctx, thisCast->valueLen, thisCast->value);
|
||||
}
|
||||
|
||||
bool SimpleStringMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
SimpleStringMsg* thisCast = (SimpleStringMsg*)this;
|
||||
|
||||
return Serialization_deserializeStr(ctx, &thisCast->valueLen, &thisCast->value);
|
||||
}
|
||||
48
client_module/source/common/net/message/SimpleStringMsg.h
Normal file
48
client_module/source/common/net/message/SimpleStringMsg.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef SIMPLESTRINGMSG_H_
|
||||
#define SIMPLESTRINGMSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
struct SimpleStringMsg;
|
||||
typedef struct SimpleStringMsg SimpleStringMsg;
|
||||
|
||||
static inline void SimpleStringMsg_init(SimpleStringMsg* this, unsigned short msgType);
|
||||
static inline void SimpleStringMsg_initFromValue(SimpleStringMsg* this, unsigned short msgType,
|
||||
const char* value);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleStringMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleStringMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline const char* SimpleStringMsg_getValue(SimpleStringMsg* this);
|
||||
|
||||
struct SimpleStringMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
const char* value;
|
||||
unsigned valueLen;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleStringMsg_Ops;
|
||||
|
||||
void SimpleStringMsg_init(SimpleStringMsg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleStringMsg_Ops);
|
||||
}
|
||||
|
||||
void SimpleStringMsg_initFromValue(SimpleStringMsg* this, unsigned short msgType, const char* value)
|
||||
{
|
||||
SimpleStringMsg_init(this, msgType);
|
||||
|
||||
this->value = value;
|
||||
this->valueLen = strlen(value);
|
||||
}
|
||||
|
||||
const char* SimpleStringMsg_getValue(SimpleStringMsg* this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
#endif /* SIMPLESTRINGMSG_H_ */
|
||||
22
client_module/source/common/net/message/SimpleUInt16Msg.c
Normal file
22
client_module/source/common/net/message/SimpleUInt16Msg.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "SimpleUInt16Msg.h"
|
||||
|
||||
const struct NetMessageOps SimpleUInt16Msg_Ops = {
|
||||
.serializePayload = SimpleUInt16Msg_serializePayload,
|
||||
.deserializePayload = SimpleUInt16Msg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void SimpleUInt16Msg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
SimpleUInt16Msg* thisCast = (SimpleUInt16Msg*)this;
|
||||
|
||||
Serialization_serializeUShort(ctx, thisCast->value);
|
||||
}
|
||||
|
||||
bool SimpleUInt16Msg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
SimpleUInt16Msg* thisCast = (SimpleUInt16Msg*)this;
|
||||
|
||||
return Serialization_deserializeUShort(ctx, &thisCast->value);
|
||||
}
|
||||
48
client_module/source/common/net/message/SimpleUInt16Msg.h
Normal file
48
client_module/source/common/net/message/SimpleUInt16Msg.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef SIMPLEUINT16MSG_H_
|
||||
#define SIMPLEUINT16MSG_H_
|
||||
|
||||
#include "NetMessage.h"
|
||||
|
||||
struct SimpleUInt16Msg;
|
||||
typedef struct SimpleUInt16Msg SimpleUInt16Msg;
|
||||
|
||||
static inline void SimpleUInt16Msg_init(SimpleUInt16Msg* this, unsigned short msgType);
|
||||
static inline void SimpleUInt16Msg_initFromValue(SimpleUInt16Msg* this, unsigned short msgType,
|
||||
uint16_t value);
|
||||
|
||||
// virtual functions
|
||||
extern void SimpleUInt16Msg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool SimpleUInt16Msg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline uint16_t SimpleUInt16Msg_getValue(SimpleUInt16Msg* this);
|
||||
|
||||
|
||||
struct SimpleUInt16Msg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
uint16_t value;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps SimpleUInt16Msg_Ops;
|
||||
|
||||
void SimpleUInt16Msg_init(SimpleUInt16Msg* this, unsigned short msgType)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, msgType, &SimpleUInt16Msg_Ops);
|
||||
}
|
||||
|
||||
void SimpleUInt16Msg_initFromValue(SimpleUInt16Msg* this, unsigned short msgType, uint16_t value)
|
||||
{
|
||||
SimpleUInt16Msg_init(this, msgType);
|
||||
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
uint16_t SimpleUInt16Msg_getValue(SimpleUInt16Msg* this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SIMPLEUINT16MSG_H_ */
|
||||
40
client_module/source/common/net/message/control/AckMsgEx.h
Normal file
40
client_module/source/common/net/message/control/AckMsgEx.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef ACKMSGEX_H_
|
||||
#define ACKMSGEX_H_
|
||||
|
||||
#include "../SimpleStringMsg.h"
|
||||
|
||||
|
||||
struct AckMsgEx;
|
||||
typedef struct AckMsgEx AckMsgEx;
|
||||
|
||||
static inline void AckMsgEx_init(AckMsgEx* this);
|
||||
static inline void AckMsgEx_initFromValue(AckMsgEx* this,
|
||||
const char* value);
|
||||
|
||||
// getters & setters
|
||||
static inline const char* AckMsgEx_getValue(AckMsgEx* this);
|
||||
|
||||
|
||||
struct AckMsgEx
|
||||
{
|
||||
SimpleStringMsg simpleStringMsg;
|
||||
};
|
||||
|
||||
|
||||
void AckMsgEx_init(AckMsgEx* this)
|
||||
{
|
||||
SimpleStringMsg_init( (SimpleStringMsg*)this, NETMSGTYPE_Ack);
|
||||
}
|
||||
|
||||
void AckMsgEx_initFromValue(AckMsgEx* this, const char* value)
|
||||
{
|
||||
SimpleStringMsg_initFromValue( (SimpleStringMsg*)this, NETMSGTYPE_Ack, value);
|
||||
}
|
||||
|
||||
const char* AckMsgEx_getValue(AckMsgEx* this)
|
||||
{
|
||||
return SimpleStringMsg_getValue( (SimpleStringMsg*)this);
|
||||
}
|
||||
|
||||
|
||||
#endif /* ACKMSGEX_H_ */
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef AUTHENTICATECHANNELMSG_H_
|
||||
#define AUTHENTICATECHANNELMSG_H_
|
||||
|
||||
#include <common/net/message/SimpleInt64Msg.h>
|
||||
|
||||
|
||||
struct AuthenticateChannelMsg;
|
||||
typedef struct AuthenticateChannelMsg AuthenticateChannelMsg;
|
||||
|
||||
|
||||
static inline void AuthenticateChannelMsg_init(AuthenticateChannelMsg* this);
|
||||
static inline void AuthenticateChannelMsg_initFromValue(AuthenticateChannelMsg* this,
|
||||
uint64_t authHash);
|
||||
|
||||
|
||||
struct AuthenticateChannelMsg
|
||||
{
|
||||
SimpleInt64Msg simpleInt64Msg;
|
||||
};
|
||||
|
||||
|
||||
void AuthenticateChannelMsg_init(AuthenticateChannelMsg* this)
|
||||
{
|
||||
SimpleInt64Msg_init( (SimpleInt64Msg*)this, NETMSGTYPE_AuthenticateChannel);
|
||||
}
|
||||
|
||||
void AuthenticateChannelMsg_initFromValue(AuthenticateChannelMsg* this, uint64_t authHash)
|
||||
{
|
||||
SimpleInt64Msg_initFromValue( (SimpleInt64Msg*)this, NETMSGTYPE_AuthenticateChannel, authHash);
|
||||
}
|
||||
|
||||
#endif /* AUTHENTICATECHANNELMSG_H_ */
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef GENERICRESPONSEMSG_H_
|
||||
#define GENERICRESPONSEMSG_H_
|
||||
|
||||
#include <common/net/message/SimpleIntStringMsg.h>
|
||||
|
||||
|
||||
/**
|
||||
* Note: Remember to keep this in sync with userspace common lib.
|
||||
*/
|
||||
enum GenericRespMsgCode
|
||||
{
|
||||
GenericRespMsgCode_TRYAGAIN = 0, /* requestor shall try again in a few seconds */
|
||||
GenericRespMsgCode_INDIRECTCOMMERR = 1, /* indirect communication error and requestor should
|
||||
try again (e.g. msg forwarding to other server failed) */
|
||||
GenericRespMsgCode_NEWSEQNOBASE = 2, /* client has restarted its seq# sequence. server provides
|
||||
the new starting seq#. */
|
||||
};
|
||||
typedef enum GenericRespMsgCode GenericRespMsgCode;
|
||||
|
||||
|
||||
struct GenericResponseMsg;
|
||||
typedef struct GenericResponseMsg GenericResponseMsg;
|
||||
|
||||
|
||||
static inline void GenericResponseMsg_init(GenericResponseMsg* this);
|
||||
|
||||
// getters & setters
|
||||
static inline GenericRespMsgCode GenericResponseMsg_getControlCode(GenericResponseMsg* this);
|
||||
static inline const char* GenericResponseMsg_getLogStr(GenericResponseMsg* this);
|
||||
|
||||
|
||||
/**
|
||||
* A generic response that can be sent as a reply to any message. This special control message will
|
||||
* be handled internally by the requestors MessageTk::requestResponse...() method.
|
||||
*
|
||||
* This is intended to submit internal information (like asking for a communication retry) to the
|
||||
* requestors MessageTk through the control code. So the MessageTk caller on the requestor side
|
||||
* will never actually see this GenericResponseMsg.
|
||||
*
|
||||
* The message string is intended to provide additional human-readable information like why this
|
||||
* control code was submitted instead of the actually expected response msg.
|
||||
*/
|
||||
struct GenericResponseMsg
|
||||
{
|
||||
SimpleIntStringMsg simpleIntStringMsg;
|
||||
};
|
||||
|
||||
|
||||
void GenericResponseMsg_init(GenericResponseMsg* this)
|
||||
{
|
||||
SimpleIntStringMsg_init( (SimpleIntStringMsg*)this, NETMSGTYPE_GenericResponse);
|
||||
}
|
||||
|
||||
GenericRespMsgCode GenericResponseMsg_getControlCode(GenericResponseMsg* this)
|
||||
{
|
||||
return (GenericRespMsgCode)SimpleIntStringMsg_getIntValue( (SimpleIntStringMsg*)this);
|
||||
}
|
||||
|
||||
const char* GenericResponseMsg_getLogStr(GenericResponseMsg* this)
|
||||
{
|
||||
return SimpleIntStringMsg_getStrValue( (SimpleIntStringMsg*)this);
|
||||
}
|
||||
|
||||
|
||||
#endif /* GENERICRESPONSEMSG_H_ */
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "PeerInfoMsg.h"
|
||||
|
||||
static void PeerInfoMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
PeerInfoMsg* thisCast = (PeerInfoMsg*)this;
|
||||
|
||||
Serialization_serializeUInt(ctx, thisCast->type);
|
||||
NumNodeID_serialize(ctx, &thisCast->id);
|
||||
}
|
||||
|
||||
static bool PeerInfoMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
PeerInfoMsg* thisCast = (PeerInfoMsg*)this;
|
||||
|
||||
unsigned type = 0;
|
||||
bool result =
|
||||
Serialization_deserializeUInt(ctx, &type)
|
||||
&& NumNodeID_deserialize(ctx, &thisCast->id);
|
||||
|
||||
thisCast->type = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
const struct NetMessageOps PeerInfoMsg_Ops = {
|
||||
.serializePayload = PeerInfoMsg_serializePayload,
|
||||
.deserializePayload = PeerInfoMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef COMMON_NET_MESSAGE_CONTROL_PEERINFOMSG_H
|
||||
#define COMMON_NET_MESSAGE_CONTROL_PEERINFOMSG_H
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/nodes/Node.h>
|
||||
|
||||
struct PeerInfoMsg;
|
||||
typedef struct PeerInfoMsg PeerInfoMsg;
|
||||
|
||||
struct PeerInfoMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
NodeType type;
|
||||
NumNodeID id;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps PeerInfoMsg_Ops;
|
||||
|
||||
static inline void PeerInfoMsg_init(PeerInfoMsg* this, NodeType type, NumNodeID id)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_PeerInfo, &PeerInfoMsg_Ops);
|
||||
|
||||
this->type = type;
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef SETCHANNELDIRECTMSG_H_
|
||||
#define SETCHANNELDIRECTMSG_H_
|
||||
|
||||
#include <common/net/message/SimpleIntMsg.h>
|
||||
|
||||
|
||||
struct SetChannelDirectMsg;
|
||||
typedef struct SetChannelDirectMsg SetChannelDirectMsg;
|
||||
|
||||
static inline void SetChannelDirectMsg_init(SetChannelDirectMsg* this);
|
||||
static inline void SetChannelDirectMsg_initFromValue(SetChannelDirectMsg* this, int value);
|
||||
|
||||
struct SetChannelDirectMsg
|
||||
{
|
||||
SimpleIntMsg simpleIntMsg;
|
||||
};
|
||||
|
||||
|
||||
void SetChannelDirectMsg_init(SetChannelDirectMsg* this)
|
||||
{
|
||||
SimpleIntMsg_init( (SimpleIntMsg*)this, NETMSGTYPE_SetChannelDirect);
|
||||
}
|
||||
|
||||
void SetChannelDirectMsg_initFromValue(SetChannelDirectMsg* this, int value)
|
||||
{
|
||||
SimpleIntMsg_initFromValue( (SimpleIntMsg*)this, NETMSGTYPE_SetChannelDirect, value);
|
||||
}
|
||||
|
||||
#endif /*SETCHANNELDIRECTMSG_H_*/
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <app/App.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include "GetHostByNameMsg.h"
|
||||
|
||||
const struct NetMessageOps GetHostByNameMsg_Ops = {
|
||||
.serializePayload = GetHostByNameMsg_serializePayload,
|
||||
.deserializePayload = GetHostByNameMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void GetHostByNameMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
GetHostByNameMsg* thisCast = (GetHostByNameMsg*)this;
|
||||
|
||||
// hostname
|
||||
Serialization_serializeStr(ctx, thisCast->hostnameLen, thisCast->hostname);
|
||||
}
|
||||
|
||||
bool GetHostByNameMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetHostByNameMsg* thisCast = (GetHostByNameMsg*)this;
|
||||
|
||||
// hostname
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->hostnameLen, &thisCast->hostname) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef GETHOSTBYNAMEMSG_H_
|
||||
#define GETHOSTBYNAMEMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
|
||||
|
||||
struct GetHostByNameMsg;
|
||||
typedef struct GetHostByNameMsg GetHostByNameMsg;
|
||||
|
||||
static inline void GetHostByNameMsg_init(GetHostByNameMsg* this);
|
||||
static inline void GetHostByNameMsg_initFromHostname(GetHostByNameMsg* this,
|
||||
const char* hostname);
|
||||
|
||||
// virtual functions
|
||||
extern void GetHostByNameMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool GetHostByNameMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
struct GetHostByNameMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
unsigned hostnameLen;
|
||||
const char* hostname;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps GetHostByNameMsg_Ops;
|
||||
|
||||
void GetHostByNameMsg_init(GetHostByNameMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetHostByName, &GetHostByNameMsg_Ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hostname just a reference, so do not free it as long as you use this object!
|
||||
*/
|
||||
void GetHostByNameMsg_initFromHostname(GetHostByNameMsg* this,
|
||||
const char* hostname)
|
||||
{
|
||||
GetHostByNameMsg_init(this);
|
||||
|
||||
this->hostname = hostname;
|
||||
this->hostnameLen = strlen(hostname);
|
||||
}
|
||||
|
||||
#endif /*GETHOSTBYNAMEMSG_H_*/
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <app/App.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include "GetHostByNameRespMsg.h"
|
||||
|
||||
const struct NetMessageOps GetHostByNameRespMsg_Ops = {
|
||||
.serializePayload = _NetMessage_serializeDummy,
|
||||
.deserializePayload = GetHostByNameRespMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
bool GetHostByNameRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetHostByNameRespMsg* thisCast = (GetHostByNameRespMsg*)this;
|
||||
|
||||
// hostAddr
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->hostAddrLen, &thisCast->hostAddr) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef GETHOSTBYNAMERESPMSG_H_
|
||||
#define GETHOSTBYNAMERESPMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
|
||||
|
||||
struct GetHostByNameRespMsg;
|
||||
typedef struct GetHostByNameRespMsg GetHostByNameRespMsg;
|
||||
|
||||
static inline void GetHostByNameRespMsg_init(GetHostByNameRespMsg* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool GetHostByNameRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// getters & setters
|
||||
static inline const char* GetHostByNameRespMsg_getHostAddr(GetHostByNameRespMsg* this);
|
||||
|
||||
|
||||
struct GetHostByNameRespMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
unsigned hostAddrLen;
|
||||
const char* hostAddr;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps GetHostByNameRespMsg_Ops;
|
||||
|
||||
void GetHostByNameRespMsg_init(GetHostByNameRespMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetHostByNameResp, &GetHostByNameRespMsg_Ops);
|
||||
}
|
||||
|
||||
const char* GetHostByNameRespMsg_getHostAddr(GetHostByNameRespMsg* this)
|
||||
{
|
||||
return this->hostAddr;
|
||||
}
|
||||
|
||||
#endif /*GETHOSTBYNAMERESPMSG_H_*/
|
||||
61
client_module/source/common/net/message/helperd/LogMsg.c
Normal file
61
client_module/source/common/net/message/helperd/LogMsg.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <app/App.h>
|
||||
#include <common/nodes/Node.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include <common/toolkit/ListTk.h>
|
||||
#include <nodes/NodeStoreEx.h>
|
||||
#include "LogMsg.h"
|
||||
|
||||
|
||||
const struct NetMessageOps LogMsg_Ops = {
|
||||
.serializePayload = LogMsg_serializePayload,
|
||||
.deserializePayload = LogMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void LogMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
LogMsg* thisCast = (LogMsg*)this;
|
||||
|
||||
// level
|
||||
Serialization_serializeInt(ctx, thisCast->level);
|
||||
|
||||
// threadID
|
||||
Serialization_serializeInt(ctx, thisCast->threadID);
|
||||
|
||||
// threadName
|
||||
Serialization_serializeStr(ctx, thisCast->threadNameLen, thisCast->threadName);
|
||||
|
||||
// context
|
||||
Serialization_serializeStr(ctx, thisCast->contextLen, thisCast->context);
|
||||
|
||||
// logMsg
|
||||
Serialization_serializeStr(ctx, thisCast->logMsgLen, thisCast->logMsg);
|
||||
}
|
||||
|
||||
bool LogMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
LogMsg* thisCast = (LogMsg*)this;
|
||||
|
||||
// level
|
||||
if(!Serialization_deserializeInt(ctx, &thisCast->level) )
|
||||
return false;
|
||||
|
||||
// threadID
|
||||
if(!Serialization_deserializeInt(ctx, &thisCast->threadID) )
|
||||
return false;
|
||||
|
||||
// threadName
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->threadNameLen, &thisCast->threadName) )
|
||||
return false;
|
||||
|
||||
// context
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->contextLen, &thisCast->context) )
|
||||
return false;
|
||||
|
||||
// logMsg
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->logMsgLen, &thisCast->logMsg) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
62
client_module/source/common/net/message/helperd/LogMsg.h
Normal file
62
client_module/source/common/net/message/helperd/LogMsg.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef LOGMSG_H_
|
||||
#define LOGMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
|
||||
|
||||
struct LogMsg;
|
||||
typedef struct LogMsg LogMsg;
|
||||
|
||||
static inline void LogMsg_init(LogMsg* this);
|
||||
static inline void LogMsg_initFromEntry(LogMsg* this, int level,
|
||||
int threadID, const char* threadName, const char* context, const char* logMsg);
|
||||
|
||||
// virtual functions
|
||||
extern void LogMsg_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool LogMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
|
||||
struct LogMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
int level;
|
||||
int threadID;
|
||||
unsigned threadNameLen;
|
||||
const char* threadName;
|
||||
unsigned contextLen;
|
||||
const char* context;
|
||||
unsigned logMsgLen;
|
||||
const char* logMsg;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps LogMsg_Ops;
|
||||
|
||||
void LogMsg_init(LogMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_Log, &LogMsg_Ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context just a reference, so do not free it as long as you use this object!
|
||||
* @param logMsg just a reference, so do not free it as long as you use this object!
|
||||
*/
|
||||
void LogMsg_initFromEntry(LogMsg* this, int level, int threadID, const char* threadName,
|
||||
const char* context, const char* logMsg)
|
||||
{
|
||||
LogMsg_init(this);
|
||||
|
||||
this->level = level;
|
||||
this->threadID = threadID;
|
||||
|
||||
this->threadName = threadName;
|
||||
this->threadNameLen = strlen(threadName);
|
||||
|
||||
this->context = context;
|
||||
this->contextLen = strlen(context);
|
||||
|
||||
this->logMsg = logMsg;
|
||||
this->logMsgLen = strlen(logMsg);
|
||||
}
|
||||
|
||||
#endif /*LOGMSG_H_*/
|
||||
32
client_module/source/common/net/message/helperd/LogRespMsg.h
Normal file
32
client_module/source/common/net/message/helperd/LogRespMsg.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef LOGRESPMSG_H_
|
||||
#define LOGRESPMSG_H_
|
||||
|
||||
#include <common/net/message/SimpleIntMsg.h>
|
||||
|
||||
|
||||
struct LogRespMsg;
|
||||
typedef struct LogRespMsg LogRespMsg;
|
||||
|
||||
static inline void LogRespMsg_init(LogRespMsg* this);
|
||||
|
||||
// getters & setters
|
||||
static inline int LogRespMsg_getValue(LogRespMsg* this);
|
||||
|
||||
struct LogRespMsg
|
||||
{
|
||||
SimpleIntMsg simpleIntMsg;
|
||||
};
|
||||
|
||||
|
||||
void LogRespMsg_init(LogRespMsg* this)
|
||||
{
|
||||
SimpleIntMsg_init( (SimpleIntMsg*)this, NETMSGTYPE_LogResp);
|
||||
}
|
||||
|
||||
int LogRespMsg_getValue(LogRespMsg* this)
|
||||
{
|
||||
return SimpleIntMsg_getValue( (SimpleIntMsg*)this);
|
||||
}
|
||||
|
||||
|
||||
#endif /*LOGRESPMSG_H_*/
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef GETMIRRORBUDDYGROUPSMSG_H
|
||||
#define GETMIRRORBUDDYGROUPSMSG_H
|
||||
|
||||
#include <common/net/message/SimpleIntMsg.h>
|
||||
|
||||
struct GetMirrorBuddyGroupsMsg;
|
||||
typedef struct GetMirrorBuddyGroupsMsg GetMirrorBuddyGroupsMsg;
|
||||
|
||||
static inline void GetMirrorBuddyGroupsMsg_init(GetMirrorBuddyGroupsMsg* this, NodeType nodeType);
|
||||
|
||||
struct GetMirrorBuddyGroupsMsg
|
||||
{
|
||||
SimpleIntMsg simpleIntMsg;
|
||||
};
|
||||
|
||||
void GetMirrorBuddyGroupsMsg_init(GetMirrorBuddyGroupsMsg* this, NodeType nodeType)
|
||||
{
|
||||
SimpleIntMsg_initFromValue( (SimpleIntMsg*)this, NETMSGTYPE_GetMirrorBuddyGroups, nodeType);
|
||||
}
|
||||
|
||||
#endif /* GETMIRRORBUDDYGROUPSMSG_H */
|
||||
32
client_module/source/common/net/message/nodes/GetNodesMsg.h
Normal file
32
client_module/source/common/net/message/nodes/GetNodesMsg.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef GETNODESMSG_H_
|
||||
#define GETNODESMSG_H_
|
||||
|
||||
#include <common/net/message/SimpleIntMsg.h>
|
||||
|
||||
|
||||
struct GetNodesMsg;
|
||||
typedef struct GetNodesMsg GetNodesMsg;
|
||||
|
||||
static inline void GetNodesMsg_init(GetNodesMsg* this);
|
||||
static inline void GetNodesMsg_initFromValue(GetNodesMsg* this, int nodeType);
|
||||
|
||||
struct GetNodesMsg
|
||||
{
|
||||
SimpleIntMsg simpleIntMsg;
|
||||
};
|
||||
|
||||
|
||||
void GetNodesMsg_init(GetNodesMsg* this)
|
||||
{
|
||||
SimpleIntMsg_init( (SimpleIntMsg*)this, NETMSGTYPE_GetNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeType NODETYPE_...
|
||||
*/
|
||||
void GetNodesMsg_initFromValue(GetNodesMsg* this, int nodeType)
|
||||
{
|
||||
SimpleIntMsg_initFromValue( (SimpleIntMsg*)this, NETMSGTYPE_GetNodes, nodeType);
|
||||
}
|
||||
|
||||
#endif /* GETNODESMSG_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "GetNodesRespMsg.h"
|
||||
|
||||
const struct NetMessageOps GetNodesRespMsg_Ops = {
|
||||
.serializePayload = _NetMessage_serializeDummy,
|
||||
.deserializePayload = GetNodesRespMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
|
||||
bool GetNodesRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetNodesRespMsg* thisCast = (GetNodesRespMsg*)this;
|
||||
|
||||
// nodeList
|
||||
if(!Serialization_deserializeNodeListPreprocess(ctx, &thisCast->rawNodeList) )
|
||||
return false;
|
||||
|
||||
// rootNumID
|
||||
if(!NumNodeID_deserialize(ctx, &thisCast->rootNumID) )
|
||||
return false;
|
||||
|
||||
// rootIsBuddyMirrored
|
||||
if(!Serialization_deserializeBool(ctx, &thisCast->rootIsBuddyMirrored) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef GETNODESRESPMSG_H_
|
||||
#define GETNODESRESPMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/nodes/NodeList.h>
|
||||
|
||||
/*
|
||||
* note: serialization not implemented
|
||||
*/
|
||||
struct GetNodesRespMsg;
|
||||
typedef struct GetNodesRespMsg GetNodesRespMsg;
|
||||
|
||||
static inline void GetNodesRespMsg_init(GetNodesRespMsg* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool GetNodesRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
// inliners
|
||||
static inline void GetNodesRespMsg_parseNodeList(App* app, GetNodesRespMsg* this,
|
||||
NodeList* outNodeList);
|
||||
|
||||
// getters & setters
|
||||
static inline NumNodeID GetNodesRespMsg_getRootNumID(GetNodesRespMsg* this);
|
||||
static inline bool GetNodesRespMsg_getRootIsBuddyMirrored(GetNodesRespMsg* this);
|
||||
|
||||
|
||||
struct GetNodesRespMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
NumNodeID rootNumID;
|
||||
bool rootIsBuddyMirrored;
|
||||
|
||||
// for deserialization
|
||||
RawList rawNodeList;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps GetNodesRespMsg_Ops;
|
||||
|
||||
void GetNodesRespMsg_init(GetNodesRespMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetNodesResp, &GetNodesRespMsg_Ops);
|
||||
|
||||
this->rootNumID = (NumNodeID){0};
|
||||
}
|
||||
|
||||
void GetNodesRespMsg_parseNodeList(App* app, GetNodesRespMsg* this, NodeList* outNodeList)
|
||||
{
|
||||
Serialization_deserializeNodeList(app, &this->rawNodeList, outNodeList);
|
||||
}
|
||||
|
||||
NumNodeID GetNodesRespMsg_getRootNumID(GetNodesRespMsg* this)
|
||||
{
|
||||
return this->rootNumID;
|
||||
}
|
||||
|
||||
bool GetNodesRespMsg_getRootIsBuddyMirrored(GetNodesRespMsg* this)
|
||||
{
|
||||
return this->rootIsBuddyMirrored;
|
||||
}
|
||||
|
||||
#endif /* GETNODESRESPMSG_H_ */
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "GetStatesAndBuddyGroupsMsg.h"
|
||||
|
||||
static void GetStatesAndBuddyGroupsMsg_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
GetStatesAndBuddyGroupsMsg* thisCast = (GetStatesAndBuddyGroupsMsg*)this;
|
||||
|
||||
Serialization_serializeInt(ctx, thisCast->nodeType);
|
||||
NumNodeID_serialize(ctx, &thisCast->requestedByClientID);
|
||||
}
|
||||
|
||||
static bool GetStatesAndBuddyGroupsMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetStatesAndBuddyGroupsMsg* thisCast = (GetStatesAndBuddyGroupsMsg*)this;
|
||||
|
||||
bool result =
|
||||
Serialization_deserializeInt(ctx, (int32_t*)&thisCast->nodeType)
|
||||
&& NumNodeID_deserialize(ctx, &thisCast->requestedByClientID);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const struct NetMessageOps GetStatesAndBuddyGroupsMsg_Ops = {
|
||||
.serializePayload = GetStatesAndBuddyGroupsMsg_serializePayload,
|
||||
.deserializePayload = GetStatesAndBuddyGroupsMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef GETSTATESANDBUDDYGROUPSMSG_H_
|
||||
#define GETSTATESANDBUDDYGROUPSMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include "common/nodes/NumNodeID.h"
|
||||
#include <common/nodes/Node.h>
|
||||
|
||||
struct GetStatesAndBuddyGroupsMsg;
|
||||
typedef struct GetStatesAndBuddyGroupsMsg GetStatesAndBuddyGroupsMsg;
|
||||
|
||||
|
||||
static inline void GetStatesAndBuddyGroupsMsg_init(GetStatesAndBuddyGroupsMsg* this,
|
||||
NodeType nodeType, NumNodeID requestedByClientID);
|
||||
|
||||
|
||||
struct GetStatesAndBuddyGroupsMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
NodeType nodeType;
|
||||
NumNodeID requestedByClientID;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps GetStatesAndBuddyGroupsMsg_Ops;
|
||||
|
||||
void GetStatesAndBuddyGroupsMsg_init(GetStatesAndBuddyGroupsMsg* this, NodeType nodeType, NumNodeID requestedByClientID)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetStatesAndBuddyGroups, &GetStatesAndBuddyGroupsMsg_Ops);
|
||||
|
||||
this->nodeType = nodeType;
|
||||
this->requestedByClientID = requestedByClientID;
|
||||
}
|
||||
|
||||
#endif /* GETSTATESANDBUDDYGROUPSMSG_H_ */
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "GetStatesAndBuddyGroupsRespMsg.h"
|
||||
|
||||
static void GetStatesAndBuddyGroupsRespMsg_release(NetMessage* msg)
|
||||
{
|
||||
GetStatesAndBuddyGroupsRespMsg* this = container_of(msg, struct GetStatesAndBuddyGroupsRespMsg,
|
||||
netMessage);
|
||||
|
||||
BEEGFS_KFREE_LIST(&this->groups, struct BuddyGroupMapping, _list);
|
||||
BEEGFS_KFREE_LIST(&this->states, struct TargetStateMapping, _list);
|
||||
}
|
||||
|
||||
const struct NetMessageOps GetStatesAndBuddyGroupsRespMsg_Ops = {
|
||||
.serializePayload = _NetMessage_serializeDummy,
|
||||
.deserializePayload = GetStatesAndBuddyGroupsRespMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
.release = GetStatesAndBuddyGroupsRespMsg_release,
|
||||
};
|
||||
|
||||
bool GetStatesAndBuddyGroupsRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetStatesAndBuddyGroupsRespMsg* thisCast = (GetStatesAndBuddyGroupsRespMsg*)this;
|
||||
|
||||
if (!BuddyGroupMappingList_deserialize(ctx, &thisCast->groups))
|
||||
return false;
|
||||
|
||||
if (!TargetStateMappingList_deserialize(ctx, &thisCast->states))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef GETSTATESANDBUDDYGROUPSRESPMSG_H_
|
||||
#define GETSTATESANDBUDDYGROUPSRESPMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/Types.h>
|
||||
|
||||
|
||||
struct GetStatesAndBuddyGroupsRespMsg;
|
||||
typedef struct GetStatesAndBuddyGroupsRespMsg GetStatesAndBuddyGroupsRespMsg;
|
||||
|
||||
static inline void GetStatesAndBuddyGroupsRespMsg_init(GetStatesAndBuddyGroupsRespMsg* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool GetStatesAndBuddyGroupsRespMsg_deserializePayload(NetMessage* this,
|
||||
DeserializeCtx* ctx);
|
||||
|
||||
/**
|
||||
* This message carries two maps:
|
||||
* 1) buddyGroupID -> primaryTarget, secondaryTarget
|
||||
* 2) targetID -> targetReachabilityState, targetConsistencyState
|
||||
*
|
||||
* Note: This message can only be received/deserialized (send/serialization not implemented).
|
||||
*/
|
||||
struct GetStatesAndBuddyGroupsRespMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
struct list_head groups; /* struct BuddyGroupMapping */
|
||||
struct list_head states; /* struct TargetStateMapping */
|
||||
};
|
||||
extern const struct NetMessageOps GetStatesAndBuddyGroupsRespMsg_Ops;
|
||||
|
||||
void GetStatesAndBuddyGroupsRespMsg_init(GetStatesAndBuddyGroupsRespMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetStatesAndBuddyGroupsResp,
|
||||
&GetStatesAndBuddyGroupsRespMsg_Ops);
|
||||
|
||||
INIT_LIST_HEAD(&this->groups);
|
||||
INIT_LIST_HEAD(&this->states);
|
||||
}
|
||||
|
||||
#endif /* GETSTATESANDBUDDYGROUPSRESPMSG_H_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef GETTARGETMAPPINGSMSG_H_
|
||||
#define GETTARGETMAPPINGSMSG_H_
|
||||
|
||||
#include "../SimpleMsg.h"
|
||||
|
||||
|
||||
struct GetTargetMappingsMsg;
|
||||
typedef struct GetTargetMappingsMsg GetTargetMappingsMsg;
|
||||
|
||||
static inline void GetTargetMappingsMsg_init(GetTargetMappingsMsg* this);
|
||||
|
||||
|
||||
struct GetTargetMappingsMsg
|
||||
{
|
||||
SimpleMsg simpleMsg;
|
||||
};
|
||||
|
||||
|
||||
void GetTargetMappingsMsg_init(GetTargetMappingsMsg* this)
|
||||
{
|
||||
SimpleMsg_init( (SimpleMsg*)this, NETMSGTYPE_GetTargetMappings);
|
||||
}
|
||||
|
||||
#endif /* GETTARGETMAPPINGSMSG_H_ */
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "GetTargetMappingsRespMsg.h"
|
||||
|
||||
#include <common/nodes/TargetMapper.h>
|
||||
|
||||
static void GetTargetMappingsRespMsg_release(NetMessage* this)
|
||||
{
|
||||
GetTargetMappingsRespMsg* thisCast = (GetTargetMappingsRespMsg*)this;
|
||||
|
||||
BEEGFS_KFREE_LIST(&thisCast->mappings, struct TargetMapping, _list);
|
||||
}
|
||||
|
||||
bool GetTargetMappingsRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
GetTargetMappingsRespMsg* thisCast = (GetTargetMappingsRespMsg*)this;
|
||||
|
||||
if (!TargetMappingList_deserialize(ctx, &thisCast->mappings))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct NetMessageOps GetTargetMappingsRespMsg_Ops = {
|
||||
.serializePayload = _NetMessage_serializeDummy,
|
||||
.deserializePayload = GetTargetMappingsRespMsg_deserializePayload,
|
||||
.processIncoming = NetMessage_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
.release = GetTargetMappingsRespMsg_release,
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef GETTARGETMAPPINGSRESPMSG_H_
|
||||
#define GETTARGETMAPPINGSRESPMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/Common.h>
|
||||
|
||||
/**
|
||||
* Note: This message can only be received/deserialized (send/serialization not implemented)
|
||||
*/
|
||||
|
||||
|
||||
struct GetTargetMappingsRespMsg;
|
||||
typedef struct GetTargetMappingsRespMsg GetTargetMappingsRespMsg;
|
||||
|
||||
static inline void GetTargetMappingsRespMsg_init(GetTargetMappingsRespMsg* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool GetTargetMappingsRespMsg_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
|
||||
|
||||
struct GetTargetMappingsRespMsg
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
struct list_head mappings; /* TargetMapping */
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps GetTargetMappingsRespMsg_Ops;
|
||||
|
||||
void GetTargetMappingsRespMsg_init(GetTargetMappingsRespMsg* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_GetTargetMappingsResp,
|
||||
&GetTargetMappingsRespMsg_Ops);
|
||||
|
||||
INIT_LIST_HEAD(&this->mappings);
|
||||
}
|
||||
|
||||
#endif /* GETTARGETMAPPINGSRESPMSG_H_ */
|
||||
257
client_module/source/common/net/message/nodes/HeartbeatMsgEx.c
Normal file
257
client_module/source/common/net/message/nodes/HeartbeatMsgEx.c
Normal file
@@ -0,0 +1,257 @@
|
||||
#include <app/App.h>
|
||||
#include <common/nodes/Node.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include <common/net/msghelpers/MsgHelperAck.h>
|
||||
#include <common/toolkit/ListTk.h>
|
||||
#include <nodes/NodeStoreEx.h>
|
||||
#include <app/config/Config.h>
|
||||
#include "HeartbeatMsgEx.h"
|
||||
|
||||
const struct NetMessageOps HeartbeatMsgEx_Ops = {
|
||||
.serializePayload = HeartbeatMsgEx_serializePayload,
|
||||
.deserializePayload = HeartbeatMsgEx_deserializePayload,
|
||||
.processIncoming = __HeartbeatMsgEx_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
void HeartbeatMsgEx_serializePayload(NetMessage* this, SerializeCtx* ctx)
|
||||
{
|
||||
HeartbeatMsgEx* thisCast = (HeartbeatMsgEx*)this;
|
||||
|
||||
// instanceVersion
|
||||
Serialization_serializeUInt64(ctx, thisCast->instanceVersion);
|
||||
|
||||
// nicListVersion
|
||||
Serialization_serializeUInt64(ctx, thisCast->nicListVersion);
|
||||
|
||||
// nodeType
|
||||
Serialization_serializeInt(ctx, thisCast->nodeType);
|
||||
|
||||
// nodeID
|
||||
Serialization_serializeStr(ctx, thisCast->nodeIDLen, thisCast->nodeID);
|
||||
|
||||
// ackID
|
||||
Serialization_serializeStrAlign4(ctx, thisCast->ackIDLen, thisCast->ackID);
|
||||
|
||||
// nodeNumID
|
||||
NumNodeID_serialize(ctx, &thisCast->nodeNumID);
|
||||
|
||||
// rootNumID
|
||||
NumNodeID_serialize(ctx, &thisCast->rootNumID);
|
||||
|
||||
// rootIsBuddyMirrored
|
||||
Serialization_serializeBool(ctx, thisCast->rootIsBuddyMirrored);
|
||||
|
||||
// portUDP
|
||||
Serialization_serializeUShort(ctx, thisCast->portUDP);
|
||||
|
||||
// portTCP
|
||||
Serialization_serializeUShort(ctx, thisCast->portTCP);
|
||||
|
||||
// nicList
|
||||
Serialization_serializeNicList(ctx, thisCast->nicList);
|
||||
|
||||
// machineUUID
|
||||
Serialization_serializeStr(ctx, thisCast->machineUUIDLen, thisCast->machineUUID);
|
||||
}
|
||||
|
||||
bool HeartbeatMsgEx_deserializePayload(NetMessage* this, DeserializeCtx* ctx)
|
||||
{
|
||||
HeartbeatMsgEx* thisCast = (HeartbeatMsgEx*)this;
|
||||
|
||||
// instanceVersion
|
||||
if(!Serialization_deserializeUInt64(ctx, &thisCast->instanceVersion) )
|
||||
return false;
|
||||
|
||||
// nicListVersion
|
||||
if(!Serialization_deserializeUInt64(ctx, &thisCast->nicListVersion) )
|
||||
return false;
|
||||
|
||||
// nodeType
|
||||
if(!Serialization_deserializeInt(ctx, &thisCast->nodeType) )
|
||||
return false;
|
||||
|
||||
// nodeID
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->nodeIDLen, &thisCast->nodeID) )
|
||||
return false;
|
||||
|
||||
// ackID
|
||||
if(!Serialization_deserializeStrAlign4(ctx, &thisCast->ackIDLen, &thisCast->ackID) )
|
||||
return false;
|
||||
|
||||
// nodeNumID
|
||||
if(!NumNodeID_deserialize(ctx, &thisCast->nodeNumID) )
|
||||
return false;
|
||||
|
||||
// rootNumID
|
||||
if(!NumNodeID_deserialize(ctx, &thisCast->rootNumID) )
|
||||
return false;
|
||||
|
||||
// rootIsBuddyMirrored
|
||||
if(!Serialization_deserializeBool(ctx, &thisCast->rootIsBuddyMirrored) )
|
||||
return false;
|
||||
|
||||
// portUDP
|
||||
if(!Serialization_deserializeUShort(ctx, &thisCast->portUDP) )
|
||||
return false;
|
||||
|
||||
// portTCP
|
||||
if(!Serialization_deserializeUShort(ctx, &thisCast->portTCP) )
|
||||
return false;
|
||||
|
||||
// nicList
|
||||
if(!Serialization_deserializeNicListPreprocess(ctx, &thisCast->rawNicList) )
|
||||
return false;
|
||||
|
||||
// machineUUID
|
||||
if(!Serialization_deserializeStr(ctx, &thisCast->machineUUIDLen, &thisCast->machineUUID) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __HeartbeatMsgEx_processIncoming(NetMessage* this, struct App* app,
|
||||
fhgfs_sockaddr_in* fromAddr, struct Socket* sock, char* respBuf, size_t bufLen)
|
||||
{
|
||||
Logger* log = App_getLogger(app);
|
||||
const char* logContext = "Heartbeat incoming";
|
||||
|
||||
HeartbeatMsgEx* thisCast = (HeartbeatMsgEx*)this;
|
||||
|
||||
NicAddressList nicList;
|
||||
Node* node;
|
||||
NodeConnPool* connPool;
|
||||
Node* localNode;
|
||||
NicAddressList localNicList;
|
||||
NicListCapabilities localNicCaps;
|
||||
NodeStoreEx* nodes = NULL;
|
||||
bool isNodeNew;
|
||||
NumNodeID nodeNumID;
|
||||
int nodeType;
|
||||
|
||||
// check if nodeNumID is set
|
||||
nodeNumID = HeartbeatMsgEx_getNodeNumID(thisCast);
|
||||
if(NumNodeID_isZero(&nodeNumID))
|
||||
{ // shouldn't happen: this node would need to register first to get a nodeNumID assigned
|
||||
Logger_logFormatted(log, Log_WARNING, logContext,
|
||||
"Rejecting heartbeat of node without numeric ID: %s (Type: %s)",
|
||||
HeartbeatMsgEx_getNodeID(thisCast),
|
||||
Node_nodeTypeToStr(HeartbeatMsgEx_getNodeType(thisCast) ) );
|
||||
|
||||
goto ack_resp;
|
||||
}
|
||||
|
||||
// find the corresponding node store for this node type
|
||||
|
||||
nodeType = HeartbeatMsgEx_getNodeType(thisCast);
|
||||
switch(nodeType)
|
||||
{
|
||||
case NODETYPE_Meta:
|
||||
nodes = App_getMetaNodes(app); break;
|
||||
|
||||
case NODETYPE_Storage:
|
||||
nodes = App_getStorageNodes(app); break;
|
||||
|
||||
case NODETYPE_Mgmt:
|
||||
nodes = App_getMgmtNodes(app); break;
|
||||
|
||||
default:
|
||||
{
|
||||
const char* nodeID = HeartbeatMsgEx_getNodeID(thisCast);
|
||||
|
||||
Logger_logErrFormatted(log, logContext, "Invalid node type: %d (%s); ID: %s",
|
||||
nodeType, Node_nodeTypeToStr(nodeType), nodeID);
|
||||
|
||||
goto ack_resp;
|
||||
} break;
|
||||
}
|
||||
|
||||
// construct node
|
||||
|
||||
NicAddressList_init(&nicList);
|
||||
|
||||
HeartbeatMsgEx_parseNicList(thisCast, &nicList);
|
||||
|
||||
App_lockNicList(app);
|
||||
node = Node_construct(app,
|
||||
HeartbeatMsgEx_getNodeID(thisCast), HeartbeatMsgEx_getNodeNumID(thisCast),
|
||||
HeartbeatMsgEx_getPortUDP(thisCast), HeartbeatMsgEx_getPortTCP(thisCast), &nicList,
|
||||
nodeType == NODETYPE_Meta || nodeType == NODETYPE_Storage? App_getLocalRDMANicListLocked(app) : NULL);
|
||||
// (will belong to the NodeStore => no destruct() required)
|
||||
App_unlockNicList(app);
|
||||
|
||||
Node_setNodeAliasAndType(node, NULL, nodeType);
|
||||
|
||||
// set local nic capabilities
|
||||
|
||||
localNode = App_getLocalNode(app);
|
||||
Node_cloneNicList(localNode, &localNicList);
|
||||
connPool = Node_getConnPool(node);
|
||||
|
||||
NIC_supportedCapabilities(&localNicList, &localNicCaps);
|
||||
NodeConnPool_setLocalNicCaps(connPool, &localNicCaps);
|
||||
|
||||
// add node to store (or update it)
|
||||
|
||||
isNodeNew = NodeStoreEx_addOrUpdateNode(nodes, &node);
|
||||
if(isNodeNew)
|
||||
{
|
||||
bool supportsRDMA = NIC_supportsRDMA(&nicList);
|
||||
|
||||
Logger_logFormatted(log, Log_WARNING, logContext,
|
||||
"New node: %s %s [ID: %hu]; %s",
|
||||
Node_nodeTypeToStr(nodeType),
|
||||
HeartbeatMsgEx_getNodeID(thisCast),
|
||||
HeartbeatMsgEx_getNodeNumID(thisCast).value,
|
||||
(supportsRDMA ? "RDMA; " : "") );
|
||||
}
|
||||
|
||||
__HeartbeatMsgEx_processIncomingRoot(thisCast, app);
|
||||
|
||||
ack_resp:
|
||||
// send ack
|
||||
MsgHelperAck_respondToAckRequest(app, HeartbeatMsgEx_getAckID(thisCast), fromAddr, sock,
|
||||
respBuf, bufLen);
|
||||
|
||||
// clean-up
|
||||
ListTk_kfreeNicAddressListElems(&nicList);
|
||||
NicAddressList_uninit(&nicList);
|
||||
ListTk_kfreeNicAddressListElems(&localNicList);
|
||||
NicAddressList_uninit(&localNicList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the contained root information.
|
||||
*/
|
||||
void __HeartbeatMsgEx_processIncomingRoot(HeartbeatMsgEx* this, App* app)
|
||||
{
|
||||
Logger* log = App_getLogger(app);
|
||||
const char* logContext = "Heartbeat incoming (root)";
|
||||
|
||||
NodeStoreEx* metaNodes;
|
||||
bool setRootRes;
|
||||
NodeOrGroup rootOwner = this->rootIsBuddyMirrored
|
||||
? NodeOrGroup_fromGroup(this->rootNumID.value)
|
||||
: NodeOrGroup_fromNode(this->rootNumID);
|
||||
NumNodeID rootNumID = HeartbeatMsgEx_getRootNumID(this);
|
||||
|
||||
// check whether root info is defined
|
||||
if( (HeartbeatMsgEx_getNodeType(this) != NODETYPE_Meta) || (NumNodeID_isZero(&rootNumID)))
|
||||
return;
|
||||
|
||||
// try to apply the contained root info
|
||||
|
||||
metaNodes = App_getMetaNodes(app);
|
||||
|
||||
setRootRes = NodeStoreEx_setRootOwner(metaNodes, rootOwner, false);
|
||||
|
||||
if(setRootRes)
|
||||
{ // found the very first root
|
||||
Logger_logFormatted(log, Log_CRITICAL, logContext, "Root (by Heartbeat): %hu",
|
||||
HeartbeatMsgEx_getRootNumID(this).value );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
152
client_module/source/common/net/message/nodes/HeartbeatMsgEx.h
Normal file
152
client_module/source/common/net/message/nodes/HeartbeatMsgEx.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef HEARTBEATMSG_H_
|
||||
#define HEARTBEATMSG_H_
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/sock/NetworkInterfaceCard.h>
|
||||
|
||||
|
||||
struct HeartbeatMsgEx;
|
||||
typedef struct HeartbeatMsgEx HeartbeatMsgEx;
|
||||
|
||||
static inline void HeartbeatMsgEx_init(HeartbeatMsgEx* this);
|
||||
static inline void HeartbeatMsgEx_initFromNodeData(HeartbeatMsgEx* this,
|
||||
const char* nodeID, NumNodeID nodeNumID, int nodeType, NicAddressList* nicList);
|
||||
|
||||
extern void __HeartbeatMsgEx_processIncomingRoot(HeartbeatMsgEx* this, struct App* app);
|
||||
|
||||
// virtual functions
|
||||
extern void HeartbeatMsgEx_serializePayload(NetMessage* this, SerializeCtx* ctx);
|
||||
extern bool HeartbeatMsgEx_deserializePayload(NetMessage* this, DeserializeCtx* ctx);
|
||||
extern bool __HeartbeatMsgEx_processIncoming(NetMessage* this, struct App* app,
|
||||
fhgfs_sockaddr_in* fromAddr, struct Socket* sock, char* respBuf, size_t bufLen);
|
||||
|
||||
// inliners
|
||||
static inline void HeartbeatMsgEx_parseNicList(HeartbeatMsgEx* this,
|
||||
NicAddressList* outNicList);
|
||||
|
||||
// getters & setters
|
||||
static inline const char* HeartbeatMsgEx_getNodeID(HeartbeatMsgEx* this);
|
||||
static inline NumNodeID HeartbeatMsgEx_getNodeNumID(HeartbeatMsgEx* this);
|
||||
static inline int HeartbeatMsgEx_getNodeType(HeartbeatMsgEx* this);
|
||||
static inline NumNodeID HeartbeatMsgEx_getRootNumID(HeartbeatMsgEx* this);
|
||||
static inline const char* HeartbeatMsgEx_getAckID(HeartbeatMsgEx* this);
|
||||
static inline void HeartbeatMsgEx_setPorts(HeartbeatMsgEx* this,
|
||||
uint16_t portUDP, uint16_t portTCP);
|
||||
static inline uint16_t HeartbeatMsgEx_getPortUDP(HeartbeatMsgEx* this);
|
||||
static inline uint16_t HeartbeatMsgEx_getPortTCP(HeartbeatMsgEx* this);
|
||||
|
||||
|
||||
struct HeartbeatMsgEx
|
||||
{
|
||||
NetMessage netMessage;
|
||||
|
||||
unsigned nodeIDLen;
|
||||
const char* nodeID;
|
||||
int nodeType;
|
||||
NumNodeID nodeNumID;
|
||||
NumNodeID rootNumID; // 0 means unknown/undefined
|
||||
bool rootIsBuddyMirrored;
|
||||
uint64_t instanceVersion; // not used currently
|
||||
uint64_t nicListVersion; // not used currently
|
||||
uint16_t portUDP; // 0 means "undefined"
|
||||
uint16_t portTCP; // 0 means "undefined"
|
||||
unsigned ackIDLen;
|
||||
const char* ackID;
|
||||
const char* machineUUID;
|
||||
unsigned machineUUIDLen;
|
||||
|
||||
// for serialization
|
||||
NicAddressList* nicList; // not owned by this object
|
||||
|
||||
// for deserialization
|
||||
RawList rawNicList;
|
||||
};
|
||||
|
||||
extern const struct NetMessageOps HeartbeatMsgEx_Ops;
|
||||
|
||||
void HeartbeatMsgEx_init(HeartbeatMsgEx* this)
|
||||
{
|
||||
NetMessage_init(&this->netMessage, NETMSGTYPE_Heartbeat, &HeartbeatMsgEx_Ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeID just a reference, so do not free it as long as you use this object
|
||||
* @param nicList just a reference, so do not free it as long as you use this object
|
||||
*/
|
||||
void HeartbeatMsgEx_initFromNodeData(HeartbeatMsgEx* this,
|
||||
const char* nodeID, NumNodeID nodeNumID, int nodeType, NicAddressList* nicList)
|
||||
{
|
||||
HeartbeatMsgEx_init(this);
|
||||
|
||||
this->nodeID = nodeID;
|
||||
this->nodeIDLen = strlen(nodeID);
|
||||
this->nodeNumID = nodeNumID;
|
||||
|
||||
this->nodeType = nodeType;
|
||||
|
||||
this->rootNumID = (NumNodeID){0}; // 0 means undefined/unknown
|
||||
this->rootIsBuddyMirrored = false;
|
||||
|
||||
this->instanceVersion = 0; // reserverd for future use
|
||||
|
||||
this->nicListVersion = 0; // reserverd for future use
|
||||
this->nicList = nicList;
|
||||
|
||||
this->portUDP = 0; // 0 means "undefined"
|
||||
this->portTCP = 0; // 0 means "undefined"
|
||||
|
||||
this->ackID = "";
|
||||
this->ackIDLen = 0;
|
||||
|
||||
this->machineUUID = ""; // not currently needed on the client
|
||||
this->machineUUIDLen = 0;
|
||||
}
|
||||
|
||||
void HeartbeatMsgEx_parseNicList(HeartbeatMsgEx* this, NicAddressList* outNicList)
|
||||
{
|
||||
Serialization_deserializeNicList(&this->rawNicList, outNicList);
|
||||
}
|
||||
|
||||
const char* HeartbeatMsgEx_getNodeID(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->nodeID;
|
||||
}
|
||||
|
||||
NumNodeID HeartbeatMsgEx_getNodeNumID(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->nodeNumID;
|
||||
}
|
||||
|
||||
int HeartbeatMsgEx_getNodeType(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->nodeType;
|
||||
}
|
||||
|
||||
NumNodeID HeartbeatMsgEx_getRootNumID(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->rootNumID;
|
||||
}
|
||||
|
||||
const char* HeartbeatMsgEx_getAckID(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->ackID;
|
||||
}
|
||||
|
||||
void HeartbeatMsgEx_setPorts(HeartbeatMsgEx* this, uint16_t portUDP, uint16_t portTCP)
|
||||
{
|
||||
this->portUDP = portUDP;
|
||||
this->portTCP = portTCP;
|
||||
}
|
||||
|
||||
uint16_t HeartbeatMsgEx_getPortUDP(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->portUDP;
|
||||
}
|
||||
|
||||
uint16_t HeartbeatMsgEx_getPortTCP(HeartbeatMsgEx* this)
|
||||
{
|
||||
return this->portTCP;
|
||||
}
|
||||
|
||||
|
||||
#endif /*HEARTBEATMSG_H_*/
|
||||
@@ -0,0 +1,65 @@
|
||||
#include <common/nodes/Node.h>
|
||||
#include <components/DatagramListener.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include <app/App.h>
|
||||
#include "HeartbeatMsgEx.h"
|
||||
#include "HeartbeatRequestMsgEx.h"
|
||||
|
||||
|
||||
const struct NetMessageOps HeartbeatRequestMsgEx_Ops = {
|
||||
.serializePayload = SimpleMsg_serializePayload,
|
||||
.deserializePayload = SimpleMsg_deserializePayload,
|
||||
.processIncoming = __HeartbeatRequestMsgEx_processIncoming,
|
||||
.getSupportedHeaderFeatureFlagsMask = NetMessage_getSupportedHeaderFeatureFlagsMask,
|
||||
};
|
||||
|
||||
bool __HeartbeatRequestMsgEx_processIncoming(NetMessage* this, struct App* app,
|
||||
fhgfs_sockaddr_in* fromAddr, struct Socket* sock, char* respBuf, size_t bufLen)
|
||||
{
|
||||
Logger* log = App_getLogger(app);
|
||||
const char* logContext = "HeartbeatRequest incoming";
|
||||
|
||||
Config* cfg = App_getConfig(app);
|
||||
Node* localNode = App_getLocalNode(app);
|
||||
NodeString alias;
|
||||
NumNodeID localNodeNumID = Node_getNumID(localNode);
|
||||
NicAddressList nicList;
|
||||
|
||||
HeartbeatMsgEx hbMsg;
|
||||
unsigned respLen;
|
||||
bool serializeRes;
|
||||
ssize_t sendRes;
|
||||
|
||||
Node_cloneNicList(localNode, &nicList);
|
||||
Node_copyAlias(localNode, &alias);
|
||||
HeartbeatMsgEx_initFromNodeData(&hbMsg, alias.buf, localNodeNumID, NODETYPE_Client, &nicList);
|
||||
HeartbeatMsgEx_setPorts(&hbMsg, Config_getConnClientPort(cfg), 0);
|
||||
|
||||
respLen = NetMessage_getMsgLength( (NetMessage*)&hbMsg);
|
||||
serializeRes = NetMessage_serialize( (NetMessage*)&hbMsg, respBuf, bufLen);
|
||||
if(unlikely(!serializeRes) )
|
||||
{
|
||||
Logger_logErrFormatted(log, logContext, "Unable to serialize response");
|
||||
goto err_uninit;
|
||||
}
|
||||
|
||||
if(fromAddr)
|
||||
{ // datagram => sync via dgramLis send method
|
||||
DatagramListener* dgramLis = App_getDatagramListener(app);
|
||||
sendRes = DatagramListener_sendto_kernel(dgramLis, respBuf, respLen, 0, fromAddr);
|
||||
}
|
||||
else
|
||||
sendRes = Socket_sendto_kernel(sock, respBuf, respLen, 0, NULL);
|
||||
|
||||
if(unlikely(sendRes <= 0) )
|
||||
Logger_logErrFormatted(log, logContext, "Send error. ErrCode: %lld", (long long)sendRes);
|
||||
|
||||
err_uninit:
|
||||
|
||||
ListTk_kfreeNicAddressListElems(&nicList);
|
||||
NicAddressList_uninit(&nicList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user