summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt122
-rw-r--r--LOCKS80
-rw-r--r--README.md113
-rw-r--r--cmake/Build.cmake27
-rw-r--r--cmake/GenerateBuild.cmake10
-rw-r--r--cmake/GenerateVersion.cmake38
-rw-r--r--cmake/InstallVersionFile.cmake.in8
-rw-r--r--cmake/KernelVersion.cmake12
-rw-r--r--cmake/ProjectVersion.cmake28
-rw-r--r--cmake/Version.cmake80
-rw-r--r--conf/CMakeLists.txt13
-rw-r--r--conf/README.server35
-rw-r--r--conf/rpc.acl1
-rw-r--r--conf/server.conf1
-rw-r--r--inc/dnbd3/build.h.in10
-rw-r--r--inc/dnbd3/version.h.in4
-rw-r--r--src/bench/CMakeLists.txt3
-rw-r--r--src/bench/main.c2
-rw-r--r--src/client/CMakeLists.txt3
-rw-r--r--src/client/client.c4
-rw-r--r--src/fuse/CMakeLists.txt3
-rw-r--r--src/fuse/main.c2
-rw-r--r--src/kernel/CMakeLists.txt2
-rw-r--r--src/kernel/dnbd3_main.c4
-rw-r--r--src/server/CMakeLists.txt5
-rw-r--r--src/server/rpc.c5
-rw-r--r--src/server/server.c9
27 files changed, 405 insertions, 219 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f2485de..dae49c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ set(CMAKE_CONFIGURATION_TYPES Debug Release)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
message(STATUS "Build type is not set. Defaulting to ${CMAKE_BUILD_TYPE} build!")
-endif()
+endif(NOT CMAKE_BUILD_TYPE)
# search for required packages
find_package(Git)
@@ -43,8 +43,12 @@ if(NOT FUSE_FOUND)
message(FATAL_ERROR "No Fuse found, can't build dnbd3 project!")
endif(NOT FUSE_FOUND)
+# include project version and build type related macros
+include(Version)
+include(Build)
+
# check for system and enable or disable built of Linux kernel module
-if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
+if(DNBD3_KERNEL_MODULE AND UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
# set Linux kernel directories
set(KERNEL_BUILD_DIR "/lib/modules/${CMAKE_SYSTEM_VERSION}/build"
CACHE PATH "Path to Linux kernel modules to compile against")
@@ -55,25 +59,34 @@ if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
message(STATUS "Path to Linux kernel modules to compile against is " ${KERNEL_BUILD_DIR})
message(STATUS "Path to install Linux kernel modules is " ${KERNEL_INSTALL_DIR})
- # include Linux kernel version related macros
- include(KernelVersion)
-else(UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
+ # get the Linux kernel version
+ get_kernel_version(LINUX_KERNEL_VERSION ${KERNEL_BUILD_DIR})
+else(DNBD3_KERNEL_MODULE AND UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
# disable build of the dnbd3 Linux kernel module on a system other than Linux, eg. FreeBSD
message(STATUS "Detected BSD System: Disable build of the dnbd3 Linux kernel module")
set(DNBD3_KERNEL_MODULE OFF)
-endif(UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
-
-# include project version related macros
-include(ProjectVersion)
+endif(DNBD3_KERNEL_MODULE AND UNIX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
# set include directories
-set(PROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)
-set(PROJECT_INCLUDE_TMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/inc)
+set(PROJECT_GEN_DIR ${CMAKE_BINARY_DIR}/generated)
+set(PROJECT_INCLUDE_DIR_PREFIX inc)
+set(PROJECT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/${PROJECT_INCLUDE_DIR_PREFIX})
+set(PROJECT_INCLUDE_GEN_DIR ${PROJECT_GEN_DIR}/${PROJECT_INCLUDE_DIR_PREFIX})
include_directories(${PROJECT_INCLUDE_DIR})
# generate project version C header file from template
# exposes dnbd3-generate-version and dnbd3-version target
-gen_project_version(${PROJECT_INCLUDE_DIR}/dnbd3/version.h.in ${PROJECT_INCLUDE_TMP_DIR}/dnbd3/version.h)
+set(INCLUDE_VERSION_HEADER ${PROJECT_INCLUDE_DIR}/dnbd3/version.h)
+set(INCLUDE_VERSION_HEADER_TEMPLATE ${PROJECT_INCLUDE_DIR}/dnbd3/version.h.in)
+set(INCLUDE_VERSION_HEADER_GENERATE ${PROJECT_INCLUDE_GEN_DIR}/dnbd3/version.h)
+set(INCLUDE_VERSION_HEADER_GENERATE_PREFIX ${PROJECT_INCLUDE_DIR_PREFIX}/dnbd3)
+gen_project_version(${INCLUDE_VERSION_HEADER} ${INCLUDE_VERSION_HEADER_TEMPLATE} ${INCLUDE_VERSION_HEADER_GENERATE})
+
+# generate project build tpye C header file from template
+# exposes dnbd3-generate-build and dnbd3-build target
+set(INCLUDE_BUILD_HEADER_TEMPLATE ${PROJECT_INCLUDE_DIR}/dnbd3/build.h.in)
+set(INCLUDE_BUILD_HEADER_GENERATE ${PROJECT_INCLUDE_GEN_DIR}/dnbd3/build.h)
+gen_build_type(${INCLUDE_BUILD_HEADER_TEMPLATE} ${INCLUDE_BUILD_HEADER_GENERATE})
# add compile option to handle files greater than 2GB on a 32bit system
add_definitions(-D_FILE_OFFSET_BITS=64)
@@ -98,12 +111,89 @@ if(DNBD3_RELEASE_HARDEN AND CMAKE_BUILD_TYPE MATCHES "Release")
message(STATUS "Set compilation of DNBD3 with hardened code options - done")
else(DNBD3_RELEASE_HARDEN AND CMAKE_BUILD_TYPE MATCHES "Release")
# print status message of disabled configuration
- message(STATUS "Disabled compilation of DNBD3 with hardened code options - done")
+ message(STATUS "Disabled compilation of dnbd3 with hardened code options - done")
endif(DNBD3_RELEASE_HARDEN AND CMAKE_BUILD_TYPE MATCHES "Release")
+# define packaging if Release build is enabled
+if(CMAKE_BUILD_TYPE MATCHES Release)
+ # get version source package or Git repository
+ get_repository_version(REPOSITORY_VERSION ${INCLUDE_VERSION_HEADER} ${CMAKE_BUILD_TYPE})
+
+ # define project version
+ if(LINUX_KERNEL_VERSION)
+ set(REPOSITORY_VERSION_FULL ${REPOSITORY_VERSION}-${LINUX_KERNEL_VERSION})
+ else(LINUX_KERNEL_VERSION)
+ set(REPOSITORY_VERSION_FULL ${REPOSITORY_VERSION})
+ endif(LINUX_KERNEL_VERSION)
+
+ set(CPACK_GENERATOR "DEB;RPM;TGZ")
+ set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
+ set(CPACK_MONOLITHIC_INSTALL True)
+ set(CPACK_PACKAGE_VERSION ${REPOSITORY_VERSION})
+ set(CPACK_PACKAGE_VERSION_FULL ${REPOSITORY_VERSION_FULL})
+ set(CPACK_PACKAGE_SECTION admin)
+ set(CPACK_PACKAGE_VENDOR "University of Freiburg")
+ set(CPACK_PACKAGE_CONTACT "Christian Rößler <christian.roessler@rz.uni-freiburg.de>")
+ set(CPACK_PACKAGE_HOMEPAGE_URL "https://git.openslx.org/dnbd3.git/")
+ set(CPACK_PACKAGE_CHECKSUM SHA256)
+ set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}_${REPOSITORY_VERSION_FULL}_${CMAKE_SYSTEM_PROCESSOR})
+ set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_source)
+ set(CPACK_STRIP_FILES True)
+ set(CPACK_PACKAGE_RELOCATABLE False)
+ set(CPACK_SET_DESTDIR True)
+ set(CMAKE_INSTALL_PREFIX "/usr")
+ set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
+ set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/COPYING)
+ set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
+
+ # set DEB generator specific packaging options
+ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libfuse2, libjansson")
+ if(DNBD3_KERNEL_MODULE)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/package/deb/postinst "depmod -a\n")
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/package/deb/postrm "depmod -a\n")
+ set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CMAKE_CURRENT_BINARY_DIR}/package/deb/postinst
+ ${CMAKE_CURRENT_BINARY_DIR}/package/deb/postrm)
+ endif(DNBD3_KERNEL_MODULE)
+
+ # set RPM generator specific packaging options
+ set(CPACK_RPM_PACKAGE_REQUIRES "glibc, fuse-libs, jansson")
+ set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib"
+ "/lib/modules"
+ "/lib/modules/${CMAKE_SYSTEM_VERSION}"
+ "/lib/modules/${CMAKE_SYSTEM_VERSION}/extra"
+ "/etc")
+ if(DNBD3_KERNEL_MODULE)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/package/rpm/post "depmod -a\n")
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/package/rpm/postun "depmod -a\n")
+ set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_CURRENT_BINARY_DIR}/package/rpm/post)
+ set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_CURRENT_BINARY_DIR}/package/rpm/postun)
+ endif(DNBD3_KERNEL_MODULE)
+
+ # configure source packaging
+ set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
+ set(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR}" "/"
+ "${PROJECT_GEN_DIR}" "/")
+ set(CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;.gitignore$;.*~;version.h.in$")
+
+ # generate install script for CPack to install generated files
+ configure_file(${PROJECT_MODULES_DIR}/InstallVersionFile.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/package/InstallVersionFile.cmake)
+
+ # set CPack install script
+ set(CPACK_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/package/InstallVersionFile.cmake)
+
+ # include CPack functionality
+ include(CPack)
+
+ # create custom target to build package source
+ add_custom_target(source
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package_source
+ DEPENDS dnbd3-generate-version
+ VERBATIM
+ USES_TERMINAL)
+endif(CMAKE_BUILD_TYPE MATCHES Release)
+
# add all dnbd3 related projects from the source code directory
add_subdirectory(src)
-# install config files into sample directory
-file(GLOB DNBD3_CONF_FILES "${CMAKE_CURRENT_SOURCE_DIR}/conf/*")
-install(FILES ${DNBD3_CONF_FILES} DESTINATION /etc/dnbd3-server/sample)
+# add configuration files for packaging purposes
+add_subdirectory(conf)
diff --git a/LOCKS b/LOCKS
deleted file mode 100644
index 77e44a8..0000000
--- a/LOCKS
+++ /dev/null
@@ -1,80 +0,0 @@
-Some notes about locking in dnbd3
-
-The order of aquiring multiple locks is
-VERY IMPORTANT, as you'll produce a possible deadlock
-if you do it in the wrong order.
-Take very good care of locking order if you have lots
-of functions that call each other. You might lose
-track of what's going on. ;)
-
-===== FUSE =====
-mutexInit
-newAltLock
-altLock
-connection.sendMutex
-requests.lock
-
-===== SERVER =====
-This is a list of used locks, in the order they
-have to be aquired if you must hold multiple locks.
-Note this list might be out of date, take a look at the
-defines in lock.h for the effective order.
-reloadLock
-remoteCloneLock
-_clients_lock
-_clients[].lock
-integrityQueueLock
-_images_lock
-_images[].lock
-uplink.queueLock
-altServersLock
-client.sendMutex
-uplink.rttLock
-uplink.sendMutex
-aclLock
-
-If you need to lock multiple clients/images/... at once,
-lock the client with the lowest array index first.
-
-If the program logic would require to aquire the
-locks in a different order, you HAVE TO rework the
-code.
-For example, if you hold the lock for client 10 and
-you need to look up some other client. You MUST NOT
-simply fetch the _clients_lock now and then iterate
-over the clients until you find the one you need,
-as it violates the above order to first lock on the
-clients array and then the clients lock.
-Instead, you need to release client 10's lock,
-then lock on _clients_lock and iterate over the
-clients. Now you check if you either encounter
-the client you originally held the lock on, or
-the client you are looking for. You immediately
-lock on those two. You can then release the
-_clients_lock and work with both clients.
-pseudo code:
-
-// client10 is assumed to be a pointer to
-// a client, which happens to be at index 10
-lock (client10->lock);
-....
-// oh, i need another client
-unlock(client10->lock);
-lock(_clients_lock);
-client clientA = NULL, clientB = NULL;
-for (i = 0; i < _num_clients; ++i) {
- if (client[i] == client10) {
- clientA = client[i];
- lock(clientA.lock);
- } else if (client[i].something == <whatever>) {
- clientB = client[i];
- lock(clientB.lock);
- }
-}
-unlock(_clients_lock);
-if (clientA && clientB) { // Make sure we actually found both!
- // DO something important with both clients
-}
-if (clientA) unlock(clientA.lock);
-if (clientB) unlock(clientB.lock);
-
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..07dd090
--- /dev/null
+++ b/README.md
@@ -0,0 +1,113 @@
+## Configuration of _dnbd3-server_
+The dnbd3-server is started according to the following command line call.
+
+```shell
+dnbd3-server -c <CONFIG_DIR>
+```
+
+An operation of the dnbd3-server requires a configuration directory to provide proper functionality. The configuration directory should contain two configuration files, namely the _alt-servers_ and the _server.conf_ file.
+
+
+## Configuration file _alt-servers_
+The _alt-servers_ configuration file specifies the list of known alt-servers for the dnbd3-server. The configuration in the file is specified the INI file format as shown in the following.
+
+```ini
+[Address]
+comment=Whatever
+for=purpose # where purpose is either "client" or "replication"
+namespace=some/path/
+```
+
+All fields in an INI section are optional. If the `for` key is missing, the dnbd3-server will be used for replication and will be propagated to clients that request a list of alt servers. The `namespace` key can be specified multiple times per INI section. If this key is missing, the server will be used for all image names. Otherwise, it will only be used for images which's name starts with one of the given strings.
+
+If the dnbd3-server is not running in proxy mode, this file won't do much.
+
+
+## Configuration file _server.conf_
+The _server.conf_ file is the main configuration file of the dnbd3-server. The configuration in the file is specified the INI file format as shown in the following.
+
+```ini
+[dnbd3]
+basePath=/srv/openslx/dnbd3 # virtual root of image files
+serverPenalty=1234 # artificial acceptance delay for incoming server connections (µs)
+clientPenalty=2345 # artificial acceptance delay for incoming client connection (µs)
+isProxy=true # enable proxy mode - will try to replicate from alt-servers if a client requests unknown image
+uplinkTimeout=1250 # r/w timeout for connections to uplink servers
+```
+
+
+## Development notes
+
+### Resource locking in dnbd3
+The order of aquiring multiple locks is very important, as you'll produce a possible deadlock if you do it in the wrong order. Take very good care of locking order if you have lots of functions that call each other. You might lose track of what's going on.
+
+
+#### dnbd3-fuse
+This is a list of used locks, in the order they have to be aquired if you must hold multiple locks.
+
+```
+mutexInit
+newAltLock
+altLock
+connection.sendMutex
+requests.lock
+```
+
+
+#### dnbd3-server
+This is a list of used locks, in the order they have to be aquired if you must hold multiple locks. Take a look at the lock priority defines in _src/server/locks.h_ for the effective order.
+
+```
+reloadLock
+loadLock
+remoteCloneLock
+_clients_lock
+_clients[].lock
+integrityQueueLock
+imageListLock
+_images[].lock
+uplink.queueLock
+altServersLock
+client.sendMutex
+uplink.rttLock
+uplink.sendMutex
+aclLock
+initLock
+dirLock
+```
+
+If you need to lock multiple clients or images or etc at once, lock the client with the lowest array index first.
+
+If the program logic would require to aquire the locks in a different order, you have to rework the code. For example, if you hold the lock for client 10 and you need to look up some other client. You must not simply fetch the _clients_lock now and then iterate over the clients until you find the one you need, as it violates the above order to first lock on the clients array and then the clients lock. Instead, you need to release client 10's lock, then lock on _clients_lock and iterate over the clients. Now you check if you either encounter the client you originally held the lock on, or the client you are looking for. You immediately lock on those two. You can then release the _clients_lock and work with both clients.
+This described implementation advice is visualized in the following pseudo C code.
+
+```C
+/* client10 is assumed to be a pointer to a client, which happens to be at index 10 */
+lock (client10->lock);
+/* ... */
+/* we need another client */
+unlock(client10->lock);
+
+lock(_clients_lock);
+client clientA = NULL, clientB = NULL;
+for (i = 0; i < _num_clients; ++i) {
+ if (client[i] == client10) {
+ clientA = client[i];
+ lock(clientA.lock);
+ } else if (client[i].something == <whatever>) {
+ clientB = client[i];
+ lock(clientB.lock);
+ }
+}
+unlock(_clients_lock);
+
+if (clientA && clientB) {
+ /* make sure we actually found both */
+ /* do something important with both clients */
+}
+
+if (clientA)
+ unlock(clientA.lock);
+if (clientB)
+ unlock(clientB.lock);
+```
diff --git a/cmake/Build.cmake b/cmake/Build.cmake
new file mode 100644
index 0000000..a7f4c07
--- /dev/null
+++ b/cmake/Build.cmake
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
+#
+
+macro(gen_build_type BUILD_INPUT_FILE_TEMPLATE BUILD_OUTPUT_FILE)
+ get_filename_component(BUILD_OUTPUT_FILENAME ${BUILD_OUTPUT_FILE} NAME)
+ # command that will trigger a rebuild of build.h every time
+ add_custom_command(OUTPUT regenerate-build-file
+ COMMAND ${CMAKE_COMMAND} -E sleep 0
+ COMMENT "Trigger generating ${BUILD_OUTPUT_FILENAME}")
+
+ # call the GenerateBuild.cmake file to generate the build.h file
+ add_custom_command(OUTPUT ${BUILD_OUTPUT_FILE}
+ COMMAND ${CMAKE_COMMAND} -D BUILD_INPUT_FILE_TEMPLATE=${BUILD_INPUT_FILE_TEMPLATE}
+ -D BUILD_OUTPUT_FILE=${BUILD_OUTPUT_FILE}
+ -D BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -P ${PROJECT_MODULES_DIR}/GenerateBuild.cmake
+ COMMENT "Generating ${BUILD_OUTPUT_FILENAME}"
+ DEPENDS regenerate-build-file)
+ add_custom_target(dnbd3-generate-build DEPENDS ${BUILD_OUTPUT_FILE})
+
+ # create target to expose project build type
+ add_library(dnbd3-build INTERFACE)
+ target_include_directories(dnbd3-build INTERFACE ${PROJECT_INCLUDE_GEN_DIR})
+ add_dependencies(dnbd3-build dnbd3-generate-build)
+endmacro(gen_build_type BUILD_INPUT_FILE_TEMPLATE BUILD_OUTPUT_FILE)
diff --git a/cmake/GenerateBuild.cmake b/cmake/GenerateBuild.cmake
new file mode 100644
index 0000000..020eb84
--- /dev/null
+++ b/cmake/GenerateBuild.cmake
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
+#
+
+# set current build type of the project
+set(DNBD3_BUILD ${BUILD_TYPE})
+
+# write dnbd3 build type into a new C source file based on the specified build file template
+configure_file(${BUILD_INPUT_FILE_TEMPLATE} ${BUILD_OUTPUT_FILE})
diff --git a/cmake/GenerateVersion.cmake b/cmake/GenerateVersion.cmake
index 4dfdaa8..8574ba7 100644
--- a/cmake/GenerateVersion.cmake
+++ b/cmake/GenerateVersion.cmake
@@ -3,32 +3,18 @@
# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
#
-# get Git short hash and tag of latest repository commit
-execute_process(COMMAND git describe HEAD
- OUTPUT_VARIABLE DNBD3_BUILD_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-if(DNBD3_BUILD_VERSION STREQUAL "")
- set(DNBD3_BUILD_VERSION "unknown")
-endif(DNBD3_BUILD_VERSION STREQUAL "")
+# set CMake module path to include version macros
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ ${VERSION_MODULE_PATH})
-# get status of Git repository
-execute_process(COMMAND git status --porcelain
- OUTPUT_VARIABLE DNBD3_GIT_STATUS
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+# include version macros
+include(Version)
-# check if Git repository is dirty
-if(NOT DNBD3_GIT_STATUS STREQUAL "")
- # the Git repository is dirty, thus extend the version information
- set(DNBD3_BUILD_VERSION "${DNBD3_BUILD_VERSION}-modified")
+# get Git version of Git repository
+get_repository_version(DNBD3_VERSION ${VERSION_INPUT_FILE} ${VERSION_BUILD_TYPE})
- # print a message in Release build configuration to warn about the dirty repository
- if(VERSION_BUILD_TYPE MATCHES "Release")
- message(WARNING "This dnbd3 Git repository is dirty! Please commit or revert all changes for a ${VERSION_BUILD_TYPE} build!")
- endif(VERSION_BUILD_TYPE MATCHES "Release")
-endif(NOT DNBD3_GIT_STATUS STREQUAL "")
-
-# set current build type of the project
-set(DNBD3_BUILD_TYPE ${VERSION_BUILD_TYPE})
-
-# write dnbd3 version into a new C source file based on the specified version template
-configure_file(${VERSION_INPUT_FILE} ${VERSION_OUTPUT_FILE})
+# generate version header if header does not exists
+if(NOT EXISTS ${VERSION_INPUT_FILE})
+ # write dnbd3 version into a new C source file based on the specified version template
+ configure_file(${VERSION_INPUT_FILE_TEMPLATE} ${VERSION_OUTPUT_FILE})
+endif(NOT EXISTS ${VERSION_INPUT_FILE})
diff --git a/cmake/InstallVersionFile.cmake.in b/cmake/InstallVersionFile.cmake.in
new file mode 100644
index 0000000..8121c25
--- /dev/null
+++ b/cmake/InstallVersionFile.cmake.in
@@ -0,0 +1,8 @@
+#
+# AUTOGENERATED: DO NOT EDIT THIS FILE
+#
+
+if(CPACK_SOURCE_INSTALLED_DIRECTORIES AND EXISTS "@INCLUDE_VERSION_HEADER_GENERATE@")
+ file(INSTALL "@INCLUDE_VERSION_HEADER_GENERATE@"
+ DESTINATION "@INCLUDE_VERSION_HEADER_GENERATE_PREFIX@")
+endif(CPACK_SOURCE_INSTALLED_DIRECTORIES AND EXISTS "@INCLUDE_VERSION_HEADER_GENERATE@")
diff --git a/cmake/KernelVersion.cmake b/cmake/KernelVersion.cmake
deleted file mode 100644
index 1ded072..0000000
--- a/cmake/KernelVersion.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
-#
-
-# get Linux kernel version from KERNEL_BUILD_DIR string
-macro(get_kernel_version LINUX_KERNEL_VERSION KERNEL_BUILD_DIR)
- string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" LINUX_KERNEL_VERSION ${KERNEL_BUILD_DIR})
- if(LINUX_KERNEL_VERSION STREQUAL "")
- set(LINUX_KERNEL_VERSION "unknown")
- endif(LINUX_KERNEL_VERSION STREQUAL "")
-endmacro(get_kernel_version LINUX_KERNEL_VERSION KERNEL_BUILD_DIR)
diff --git a/cmake/ProjectVersion.cmake b/cmake/ProjectVersion.cmake
deleted file mode 100644
index 8b7160c..0000000
--- a/cmake/ProjectVersion.cmake
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
-#
-
-macro(gen_project_version VERSION_INPUT_FILE VERSION_OUTPUT_FILE)
- get_filename_component(VERSION_OUTPUT_FILENAME ${VERSION_OUTPUT_FILE} NAME)
- # command that will trigger a rebuild of version.c every time
- add_custom_command(OUTPUT regenerate-version-file
- COMMAND ${CMAKE_COMMAND} -E sleep 0
- COMMENT "Trigger generating ${VERSION_OUTPUT_FILENAME}")
-
- # call the GenerateVersion.cmake file to generate the version.c file
- add_custom_command(OUTPUT ${VERSION_OUTPUT_FILE}
- COMMAND ${CMAKE_COMMAND} -D VERSION_INPUT_FILE=${VERSION_INPUT_FILE}
- -D VERSION_OUTPUT_FILE=${VERSION_OUTPUT_FILE}
- -D VERSION_BUILD_TYPE=${CMAKE_BUILD_TYPE}
- -P ${PROJECT_MODULES_DIR}/GenerateVersion.cmake
- COMMENT "Generating ${VERSION_OUTPUT_FILENAME}"
- DEPENDS regenerate-version-file)
- add_custom_target(dnbd3-generate-version DEPENDS ${VERSION_OUTPUT_FILE})
-
- # create target to expose project version
- add_library(dnbd3-version INTERFACE)
- target_include_directories(dnbd3-version INTERFACE ${PROJECT_INCLUDE_TMP_DIR})
- add_dependencies(dnbd3-version dnbd3-generate-version)
-
-endmacro(gen_project_version VERSION_INPUT_FILE VERSION_OUTPUT_FILE)
diff --git a/cmake/Version.cmake b/cmake/Version.cmake
new file mode 100644
index 0000000..939007e
--- /dev/null
+++ b/cmake/Version.cmake
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020 Manuel Bentele <development@manuel-bentele.de>
+#
+
+macro(gen_project_version VERSION_INPUT_FILE VERSION_INPUT_FILE_TEMPLATE VERSION_OUTPUT_FILE)
+ get_filename_component(VERSION_OUTPUT_FILENAME ${VERSION_OUTPUT_FILE} NAME)
+ # command that will trigger a rebuild of version.h every time
+ add_custom_command(OUTPUT regenerate-version-file
+ COMMAND ${CMAKE_COMMAND} -E sleep 0
+ COMMENT "Trigger generating ${VERSION_OUTPUT_FILENAME}")
+
+ # call the GenerateVersion.cmake file to generate the version.c file
+ add_custom_command(OUTPUT ${VERSION_OUTPUT_FILE}
+ COMMAND ${CMAKE_COMMAND} -D VERSION_MODULE_PATH=${PROJECT_MODULES_DIR}
+ -D VERSION_INPUT_FILE=${VERSION_INPUT_FILE}
+ -D VERSION_INPUT_FILE_TEMPLATE=${VERSION_INPUT_FILE_TEMPLATE}
+ -D VERSION_OUTPUT_FILE=${VERSION_OUTPUT_FILE}
+ -D VERSION_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -P ${PROJECT_MODULES_DIR}/GenerateVersion.cmake
+ COMMENT "Generating ${VERSION_OUTPUT_FILENAME}"
+ DEPENDS regenerate-version-file)
+ add_custom_target(dnbd3-generate-version DEPENDS ${VERSION_OUTPUT_FILE})
+
+ # create target to expose project version
+ add_library(dnbd3-version INTERFACE)
+ target_include_directories(dnbd3-version INTERFACE ${PROJECT_INCLUDE_GEN_DIR})
+ add_dependencies(dnbd3-version dnbd3-generate-version)
+endmacro(gen_project_version VERSION_INPUT_FILE VERSION_INPUT_FILE_TEMPLATE VERSION_OUTPUT_FILE)
+
+# macro to get Linux kernel version from KERNEL_BUILD_DIR string
+macro(get_kernel_version LINUX_KERNEL_VERSION KERNEL_BUILD_DIR)
+ string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" LINUX_KERNEL_VERSION ${KERNEL_BUILD_DIR})
+ if(LINUX_KERNEL_VERSION STREQUAL "")
+ set(LINUX_KERNEL_VERSION "unknown")
+ endif(LINUX_KERNEL_VERSION STREQUAL "")
+endmacro(get_kernel_version LINUX_KERNEL_VERSION KERNEL_BUILD_DIR)
+
+# macro to get Git version information
+macro(get_repository_version REPOSITORY_VERSION VERSION_HEADER_FILE VERSION_BUILD_TYPE)
+ # check if generated version header from source package is available
+ if(EXISTS ${VERSION_HEADER_FILE})
+ # get version information from the generated version header of the source package
+ file(READ ${VERSION_HEADER_FILE} GIT_VERSION)
+ string(REGEX MATCH "\"(([0-9]+:)?[0-9][A-Za-z0-9.+~-]*)\"" GIT_VERSION ${GIT_VERSION})
+ set(GIT_VERSION "${CMAKE_MATCH_1}")
+ else(EXISTS ${VERSION_HEADER_FILE})
+ # get detailed Git version information from Git repository
+ execute_process(COMMAND git describe HEAD
+ OUTPUT_VARIABLE GIT_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # remove the first letter of the version to satisfy packaging rules
+ string(REGEX MATCH "([0-9]+:)?[0-9][A-Za-z0-9.+~-]*" GIT_VERSION ${GIT_VERSION})
+
+ # overwrite version from Git if version is unknown
+ if(GIT_VERSION STREQUAL "")
+ set(GIT_VERSION "unknown")
+ endif(GIT_VERSION STREQUAL "")
+
+ # get status of Git repository
+ execute_process(COMMAND git status --porcelain
+ OUTPUT_VARIABLE GIT_STATUS
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # check if Git repository is dirty
+ if(NOT GIT_STATUS STREQUAL "")
+ # the Git repository is dirty, thus extend the version information
+ set(GIT_VERSION "${GIT_VERSION}-modified")
+
+ # print a message in Release build configuration to warn about the dirty repository
+ if(${VERSION_BUILD_TYPE} MATCHES "Release")
+ message(WARNING "This dnbd3 Git repository is dirty! Please commit or revert all changes for a ${VERSION_BUILD_TYPE} build!")
+ endif(${VERSION_BUILD_TYPE} MATCHES "Release")
+ endif(NOT GIT_STATUS STREQUAL "")
+ endif(EXISTS ${VERSION_HEADER_FILE})
+
+ # return version to caller
+ set(${REPOSITORY_VERSION} ${GIT_VERSION})
+endmacro(get_repository_version)
diff --git a/conf/CMakeLists.txt b/conf/CMakeLists.txt
new file mode 100644
index 0000000..1b888e6
--- /dev/null
+++ b/conf/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.10)
+
+# set the project name
+project(dnbd3-conf)
+
+# define all configuration files
+set(DNBD3_CONF_FILES ${CMAKE_CURRENT_SOURCE_DIR}/alt-servers
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpc.acl
+ ${CMAKE_CURRENT_SOURCE_DIR}/server.conf)
+
+# install configuration files into sample directory
+install(FILES ${DNBD3_CONF_FILES} DESTINATION /etc/dnbd3-server/sample
+ COMPONENT server)
diff --git a/conf/README.server b/conf/README.server
deleted file mode 100644
index 08be09f..0000000
--- a/conf/README.server
+++ /dev/null
@@ -1,35 +0,0 @@
-Configuration for dnbd3-server
-
-The server requires a config directory.
-Start it like so: ./dnbd3-server -c ./my-config/
-
-There are two files in that dir
-
-== alt-servers ==
-List of known alt-servers for this server.
-INI Format:
-[Address]
-comment=Whatever
-for=client | replication
-namespace=some/path/
-
-All fields in a section are optional. If the "for" key is missing, the server
-will be used for replication and will be sent to clients that request a list
-of alt servers.
-The namespace key can be specified multiple times per section. If it is missing,
-the server will be used for all image names; otherwise, it will only be used
-for images which's name starts with one of the given strings.
-
-If you're not running in proxy mode, this file won't do much for you
-
-== server.conf ==
-
-Main configuration file. Ini format.
-
-[dnbd3]
-basePath=/srv/openslx/dnbd3 # virtual root of image files
-serverPenalty=1234 # artificial acceptance delay for incoming server connections (µs)
-clientPenalty=2345 # artificial acceptance delay for incoming client connection (µs)
-isProxy=true # enable proxy mode - will try to replicate from alt-servers if a client requests unknown image
-uplinkTimeout=1250 # r/w timeout for connections to uplink servers
-
diff --git a/conf/rpc.acl b/conf/rpc.acl
index 5167ae3..b2c2c44 100644
--- a/conf/rpc.acl
+++ b/conf/rpc.acl
@@ -2,4 +2,3 @@
127.0.0.0/8 ALL
# Some info reading for another machine
132.230.8.113 STATS CLIENT_LIST IMAGE_LIST
-
diff --git a/conf/server.conf b/conf/server.conf
index d9d4094..5f0b2a0 100644
--- a/conf/server.conf
+++ b/conf/server.conf
@@ -69,4 +69,3 @@ consoleMask=ERROR WARNING MINOR INFO
;
; Whether timestamps should be output to console too (or just to file if false)
consoleTimestamps=false
-
diff --git a/inc/dnbd3/build.h.in b/inc/dnbd3/build.h.in
new file mode 100644
index 0000000..80537ea
--- /dev/null
+++ b/inc/dnbd3/build.h.in
@@ -0,0 +1,10 @@
+/*
+ * AUTOGENERATED: DO NOT EDIT THIS FILE
+ */
+
+#ifndef BUILD_H_
+#define BUILD_H_
+
+#define DNBD3_BUILD "@DNBD3_BUILD@"
+
+#endif /* BUILD_H_ */
diff --git a/inc/dnbd3/version.h.in b/inc/dnbd3/version.h.in
index cdeed20..94bd2c4 100644
--- a/inc/dnbd3/version.h.in
+++ b/inc/dnbd3/version.h.in
@@ -1,10 +1,10 @@
/*
* AUTOGENERATED: DO NOT EDIT THIS FILE
*/
+
#ifndef VERSION_H_
#define VERSION_H_
-#define DNBD3_BUILD_VERSION "@DNBD3_BUILD_VERSION@"
-#define DNBD3_BUILD_TYPE "@DNBD3_BUILD_TYPE@"
+#define DNBD3_VERSION "@DNBD3_VERSION@"
#endif /* VERSION_H_ */
diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt
index 57aad92..59a5ef8 100644
--- a/src/bench/CMakeLists.txt
+++ b/src/bench/CMakeLists.txt
@@ -10,4 +10,5 @@ add_executable(dnbd3-bench ${CMAKE_CURRENT_SOURCE_DIR}/connection.c
${CMAKE_CURRENT_SOURCE_DIR}/helper.c
${CMAKE_CURRENT_SOURCE_DIR}/main.c)
target_link_libraries(dnbd3-bench dnbd3-version dnbd3-shared ${CMAKE_THREAD_LIBS_INIT})
-install(TARGETS dnbd3-bench RUNTIME DESTINATION bin)
+install(TARGETS dnbd3-bench RUNTIME DESTINATION bin
+ COMPONENT bench)
diff --git a/src/bench/main.c b/src/bench/main.c
index 1a59747..d195e26 100644
--- a/src/bench/main.c
+++ b/src/bench/main.c
@@ -20,7 +20,7 @@
static void printUsage(char *argv0, int exitCode)
{
- printf( "Version: %s\n", DNBD3_BUILD_VERSION );
+ printf( "Version: %s\n", DNBD3_VERSION );
printf( "Usage: %s [--debug] --host <serverAddress(es)> --image <imageName> [--rid revision]\n", argv0 );
printf( "Or: %s [-d] -h <serverAddress(es)> -i <imageName> [-r revision]\n", argv0 );
printf( " -h --host List of space separated hosts to use\n" );
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
index 4cc1212..c219740 100644
--- a/src/client/CMakeLists.txt
+++ b/src/client/CMakeLists.txt
@@ -11,4 +11,5 @@ add_definitions(-D_GNU_SOURCE)
add_executable(dnbd3-client ${CMAKE_CURRENT_SOURCE_DIR}/client.c)
target_link_libraries(dnbd3-client dnbd3-version dnbd3-shared)
-install(TARGETS dnbd3-client RUNTIME DESTINATION bin)
+install(TARGETS dnbd3-client RUNTIME DESTINATION bin
+ COMPONENT kernel)
diff --git a/src/client/client.c b/src/client/client.c
index 69cc00f..e433160 100644
--- a/src/client/client.c
+++ b/src/client/client.c
@@ -644,7 +644,7 @@ static int dnbd3_daemon_send(int argc, char **argv)
static void dnbd3_print_help(char *argv_0)
{
- printf( "Version: %s\n", DNBD3_BUILD_VERSION );
+ printf( "Version: %s\n", DNBD3_VERSION );
printf( "\nUsage: %s\n"
"\t-h <host> -i <image name> [-r <rid>] -d <device> [-a <KB>] || -c -d <device>\n\n", argv_0 );
printf( "Start the DNBD3 client.\n" );
@@ -666,6 +666,6 @@ static void dnbd3_print_help(char *argv_0)
void dnbd3_print_version()
{
- printf( "dnbd3-client version: %s\n", DNBD3_BUILD_VERSION );
+ printf( "dnbd3-client version: %s\n", DNBD3_VERSION );
exit( EXIT_SUCCESS );
}
diff --git a/src/fuse/CMakeLists.txt b/src/fuse/CMakeLists.txt
index 1c107ed..4944a87 100644
--- a/src/fuse/CMakeLists.txt
+++ b/src/fuse/CMakeLists.txt
@@ -11,4 +11,5 @@ add_executable(dnbd3-fuse ${CMAKE_CURRENT_SOURCE_DIR}/connection.c
${CMAKE_CURRENT_SOURCE_DIR}/main.c)
target_include_directories(dnbd3-fuse PRIVATE ${FUSE_INCLUDE_DIRS})
target_link_libraries(dnbd3-fuse dnbd3-version dnbd3-shared ${FUSE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
-install(TARGETS dnbd3-fuse RUNTIME DESTINATION bin)
+install(TARGETS dnbd3-fuse RUNTIME DESTINATION bin
+ COMPONENT fuse)
diff --git a/src/fuse/main.c b/src/fuse/main.c
index 2a851a7..8963e6d 100644
--- a/src/fuse/main.c
+++ b/src/fuse/main.c
@@ -273,7 +273,7 @@ static struct fuse_lowlevel_ops image_oper = {
static void printVersion()
{
char *arg[] = { "foo", "-V" };
- printf( "dnbd3-fuse version: %s\n", DNBD3_BUILD_VERSION );
+ printf( "dnbd3-fuse version: %s\n", DNBD3_VERSION );
printf( "Protocol version: %d\n", (int)PROTOCOL_VERSION );
struct fuse_args args = FUSE_ARGS_INIT( 2, arg );
fuse_parse_cmdline( &args, NULL, NULL, NULL );
diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt
index bf1eb3a..213098e 100644
--- a/src/kernel/CMakeLists.txt
+++ b/src/kernel/CMakeLists.txt
@@ -7,7 +7,7 @@ project(dnbd3-kernel-module)
include(Kernel)
# set C flags for a Linux kernel module
-set(KERNEL_C_FLAGS "-DDNBD3_KERNEL_MODULE -I ${PROJECT_INCLUDE_TMP_DIR}"
+set(KERNEL_C_FLAGS "-DDNBD3_KERNEL_MODULE -I ${PROJECT_INCLUDE_GEN_DIR}"
CACHE STRING "C flags to be used for building the dnbd3 kernel module")
# set C flags for the debug mode of a Linux kernel module
set(KERNEL_C_FLAGS_DEBUG "-g -DDEBUG"
diff --git a/src/kernel/dnbd3_main.c b/src/kernel/dnbd3_main.c
index 353e8d2..7056d31 100644
--- a/src/kernel/dnbd3_main.c
+++ b/src/kernel/dnbd3_main.c
@@ -49,7 +49,7 @@ static int __init dnbd3_init(void)
return -EIO;
}
- pr_info("kernel module in version %s loaded\n", DNBD3_BUILD_VERSION);
+ pr_info("kernel module in version %s loaded\n", DNBD3_VERSION);
pr_debug("machine type %s\n", DNBD3_ENDIAN_MODE);
// add MAX_NUMBER_DEVICES devices
@@ -87,7 +87,7 @@ module_exit(dnbd3_exit);
MODULE_DESCRIPTION("Distributed Network Block Device 3");
MODULE_LICENSE("GPL");
-MODULE_VERSION(DNBD3_BUILD_VERSION);
+MODULE_VERSION(DNBD3_VERSION);
module_param(max_devs, int, 0444);
MODULE_PARM_DESC(max_devs, "number of network block devices to initialize (default: 8)");
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index aa981f6..de2a550 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -54,7 +54,7 @@ add_executable(dnbd3-server ${CMAKE_CURRENT_SOURCE_DIR}/altservers.c
${CMAKE_CURRENT_SOURCE_DIR}/uplink.c
${CMAKE_CURRENT_SOURCE_DIR}/urldecode.c)
target_include_directories(dnbd3-server PRIVATE ${JANSSON_INCLUDE_DIR})
-target_link_libraries(dnbd3-server dnbd3-version dnbd3-shared ${CMAKE_THREAD_LIBS_INIT} ${JANSSON_LIBRARIES})
+target_link_libraries(dnbd3-server dnbd3-version dnbd3-build dnbd3-shared ${CMAKE_THREAD_LIBS_INIT} ${JANSSON_LIBRARIES})
if(DNBD3_SERVER_FUSE)
# include Fuse headers and link with Fuse library
@@ -78,4 +78,5 @@ if(DNBD3_SERVER_DEBUG_THREADS)
target_compile_options(dnbd3-server DNBD3_SERVER_DEBUG_THREADS)
endif(DNBD3_SERVER_DEBUG_THREADS)
-install(TARGETS dnbd3-server RUNTIME DESTINATION bin)
+install(TARGETS dnbd3-server RUNTIME DESTINATION bin
+ COMPONENT server)
diff --git a/src/server/rpc.c b/src/server/rpc.c
index c8da951..f2877fa 100644
--- a/src/server/rpc.c
+++ b/src/server/rpc.c
@@ -7,6 +7,7 @@
#include "altservers.h"
#include <dnbd3/shared/sockhelper.h>
#include <dnbd3/version.h>
+#include <dnbd3/build.h>
#include "fileutil.h"
#include "picohttpparser/picohttpparser.h"
#include "urldecode.h"
@@ -311,8 +312,8 @@ static bool handleStatus(int sock, int permissions, struct field *fields, size_t
"runId", randomRunId );
}
if ( version ) {
- json_object_set_new( statisticsJson, "version", json_string( DNBD3_BUILD_VERSION ) );
- json_object_set_new( statisticsJson, "build", json_string( DNBD3_BUILD_TYPE ) );
+ json_object_set_new( statisticsJson, "version", json_string( DNBD3_VERSION ) );
+ json_object_set_new( statisticsJson, "build", json_string( DNBD3_BUILD ) );
}
if ( space ) {
uint64_t spaceTotal = 0, spaceAvail = 0;
diff --git a/src/server/server.c b/src/server/server.c
index 0ee51c4..c9a0a92 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -32,6 +32,7 @@
#include "fuse.h"
#include <dnbd3/version.h>
+#include <dnbd3/build.h>
#include <dnbd3/shared/sockhelper.h>
#include <dnbd3/shared/timing.h>
@@ -105,7 +106,7 @@ static void queueJobInternal(job_t *job);
*/
void dnbd3_printHelp(char *argv_0)
{
- printf( "Version: %s\n\n", DNBD3_BUILD_VERSION );
+ printf( "Version: %s\n\n", DNBD3_VERSION );
printf( "Usage: %s [OPTIONS]...\n", argv_0 );
printf( "Start the DNBD3 server\n" );
printf( "-c or --config Configuration directory (default /etc/dnbd3-server/)\n" );
@@ -130,7 +131,7 @@ void dnbd3_printHelp(char *argv_0)
*/
void dnbd3_printVersion()
{
- printf( "dnbd3-server version: %s\n", DNBD3_BUILD_VERSION );
+ printf( "dnbd3-server version: %s\n", DNBD3_VERSION );
exit( 0 );
}
@@ -371,8 +372,8 @@ int main(int argc, char *argv[])
}
logadd( LOG_INFO, "DNBD3 server starting...." );
logadd( LOG_INFO, "Machine type: " DNBD3_ENDIAN_MODE );
- logadd( LOG_INFO, "Build Type: %s", DNBD3_BUILD_TYPE );
- logadd( LOG_INFO, "Version: %s", DNBD3_BUILD_VERSION );
+ logadd( LOG_INFO, "Build Type: %s", DNBD3_BUILD );
+ logadd( LOG_INFO, "Version: %s", DNBD3_VERSION );
if ( altservers_load() < 0 ) {
logadd( LOG_WARNING, "Could not load alt-servers. Does the file exist in %s?", _configDir );