Loading CMake/FindSyscall_intercept.cmake 0 → 100644 +69 −0 Original line number Diff line number Diff line ################################################################################ # Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain # # Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany # # # # This software was partially supported by the # # EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). # # # # This software was partially supported by the # # ADA-FS project under the SPPEXA project funded by the DFG. # # # # This file is part of GekkoFS. # # # # GekkoFS is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # GekkoFS is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. # # # # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ find_package(PkgConfig) pkg_check_modules(PC_Syscall_intercept QUIET libsyscall_intercept) find_path(Syscall_intercept_INCLUDE_DIR NAMES libsyscall_intercept_hook_point.h PATHS ${PC_Syscall_intercept_INCLUDE_DIRS} ) find_library(Syscall_intercept_LIBRARY NAMES syscall_intercept PATHS ${PC_Syscall_intercept_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Syscall_intercept DEFAULT_MSG Syscall_intercept_INCLUDE_DIR Syscall_intercept_LIBRARY ) if (Syscall_intercept_FOUND) set(Syscall_intercept_LIBRARIES ${Syscall_intercept_LIBRARY}) set(Syscall_intercept_INCLUDE_DIRS ${Syscall_intercept_INCLUDE_DIR}) set(Syscall_intercept_DEFINITIONS ${PC_Syscall_intercept_CFLAGS_OTHER}) if (NOT TARGET Syscall_intercept::Syscall_intercept) add_library(Syscall_intercept::Syscall_intercept UNKNOWN IMPORTED) set_target_properties(Syscall_intercept::Syscall_intercept PROPERTIES IMPORTED_LOCATION "${Syscall_intercept_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${PC_Syscall_intercept_CFLAGS_OTHER}" INTERFACE_INCLUDE_DIRECTORIES "${Syscall_intercept_INCLUDE_DIR}" ) endif () endif () mark_as_advanced( Syscall_intercept_INCLUDE_DIR Syscall_intercept_LIBRARY ) CMakeLists.txt 0 → 100644 +68 −0 Original line number Diff line number Diff line cmake_minimum_required(VERSION 3.13) project( "eval" VERSION 1.0 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) include(CheckCXXSourceCompiles) include(CMakeDependentOption) include(GNUInstallDirs) include(FeatureSummary) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build: Debug Release Memcheck" FORCE) ENDIF (NOT CMAKE_BUILD_TYPE) message(STATUS "[${PROJECT_NAME}] Build type: ${CMAKE_BUILD_TYPE}") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) message(STATUS "[${PROJECT_NAME}] Checking for syscall_intercept") find_package(Syscall_intercept REQUIRED) set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") include_directories( ${INCLUDE_DIR} ${CMAKE_BINARY_DIR}/include /usr/include ) add_library(eval_intercept SHARED) add_executable(opendevnull) target_sources(eval_intercept PRIVATE src/eval.cpp ) target_sources(opendevnull PRIVATE src/opendevnull.cpp ) target_link_libraries( eval_intercept Syscall_intercept::Syscall_intercept ) install( TARGETS eval_intercept LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install( TARGETS opendevnull LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) src/eval.cpp 0 → 100644 +64 −0 Original line number Diff line number Diff line #include <fcntl.h> #include <libsyscall_intercept_hook_point.h> #include <sys/syscall.h> #include <sys/types.h> void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); } inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { switch (syscall_number) { #ifdef SYS_open case SYS_open: *result = hook_openat(AT_FDCWD, reinterpret_cast<char *>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); break; #endif case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char *>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in // hook_forwarded_syscall()) return 1; } return 0; } int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *syscall_return_value) { int was_hooked = 1; if (syscall_number == SYS_openat) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); return was_hooked; } void start_interception() { // Set up the callback function pointer intercept_hook_point = hook_guard_wrapper; } void stop_interception() { // Reset callback function pointer intercept_hook_point = nullptr; } No newline at end of file src/opendevnull.cpp 0 → 100644 +40 −0 Original line number Diff line number Diff line #include <fcntl.h> #include <iostream> #include <sys/syscall.h> #include <unistd.h> int main() { // measure time to run in microseconds struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // open /dev/null 100000 times for (int j = 0; j < 1000; j++) { for (int i = 0; i < 100000; i++) { int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); close(fd); } } clock_gettime(CLOCK_MONOTONIC, &end); double time_taken = (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3; std::cout << "Time taken: " << time_taken << " microseconds" << std::endl; // mean of the time for a syscall (10000000) std::cout << "Mean time taken: " << time_taken / 10000000.0 << " microseconds" << std::endl; // Calculate single syscall () clock_gettime(CLOCK_MONOTONIC, &start); int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); close(fd); clock_gettime(CLOCK_MONOTONIC, &end); std::cout << "Time taken for single syscall: " << (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3 << " microseconds" << std::endl; return 0; } No newline at end of file Loading
CMake/FindSyscall_intercept.cmake 0 → 100644 +69 −0 Original line number Diff line number Diff line ################################################################################ # Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain # # Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany # # # # This software was partially supported by the # # EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). # # # # This software was partially supported by the # # ADA-FS project under the SPPEXA project funded by the DFG. # # # # This file is part of GekkoFS. # # # # GekkoFS is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # GekkoFS is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. # # # # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ find_package(PkgConfig) pkg_check_modules(PC_Syscall_intercept QUIET libsyscall_intercept) find_path(Syscall_intercept_INCLUDE_DIR NAMES libsyscall_intercept_hook_point.h PATHS ${PC_Syscall_intercept_INCLUDE_DIRS} ) find_library(Syscall_intercept_LIBRARY NAMES syscall_intercept PATHS ${PC_Syscall_intercept_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Syscall_intercept DEFAULT_MSG Syscall_intercept_INCLUDE_DIR Syscall_intercept_LIBRARY ) if (Syscall_intercept_FOUND) set(Syscall_intercept_LIBRARIES ${Syscall_intercept_LIBRARY}) set(Syscall_intercept_INCLUDE_DIRS ${Syscall_intercept_INCLUDE_DIR}) set(Syscall_intercept_DEFINITIONS ${PC_Syscall_intercept_CFLAGS_OTHER}) if (NOT TARGET Syscall_intercept::Syscall_intercept) add_library(Syscall_intercept::Syscall_intercept UNKNOWN IMPORTED) set_target_properties(Syscall_intercept::Syscall_intercept PROPERTIES IMPORTED_LOCATION "${Syscall_intercept_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${PC_Syscall_intercept_CFLAGS_OTHER}" INTERFACE_INCLUDE_DIRECTORIES "${Syscall_intercept_INCLUDE_DIR}" ) endif () endif () mark_as_advanced( Syscall_intercept_INCLUDE_DIR Syscall_intercept_LIBRARY )
CMakeLists.txt 0 → 100644 +68 −0 Original line number Diff line number Diff line cmake_minimum_required(VERSION 3.13) project( "eval" VERSION 1.0 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) include(CheckCXXSourceCompiles) include(CMakeDependentOption) include(GNUInstallDirs) include(FeatureSummary) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build: Debug Release Memcheck" FORCE) ENDIF (NOT CMAKE_BUILD_TYPE) message(STATUS "[${PROJECT_NAME}] Build type: ${CMAKE_BUILD_TYPE}") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) message(STATUS "[${PROJECT_NAME}] Checking for syscall_intercept") find_package(Syscall_intercept REQUIRED) set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") include_directories( ${INCLUDE_DIR} ${CMAKE_BINARY_DIR}/include /usr/include ) add_library(eval_intercept SHARED) add_executable(opendevnull) target_sources(eval_intercept PRIVATE src/eval.cpp ) target_sources(opendevnull PRIVATE src/opendevnull.cpp ) target_link_libraries( eval_intercept Syscall_intercept::Syscall_intercept ) install( TARGETS eval_intercept LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install( TARGETS opendevnull LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} )
src/eval.cpp 0 → 100644 +64 −0 Original line number Diff line number Diff line #include <fcntl.h> #include <libsyscall_intercept_hook_point.h> #include <sys/syscall.h> #include <sys/types.h> void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); } inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { switch (syscall_number) { #ifdef SYS_open case SYS_open: *result = hook_openat(AT_FDCWD, reinterpret_cast<char *>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); break; #endif case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char *>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in // hook_forwarded_syscall()) return 1; } return 0; } int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *syscall_return_value) { int was_hooked = 1; if (syscall_number == SYS_openat) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); return was_hooked; } void start_interception() { // Set up the callback function pointer intercept_hook_point = hook_guard_wrapper; } void stop_interception() { // Reset callback function pointer intercept_hook_point = nullptr; } No newline at end of file
src/opendevnull.cpp 0 → 100644 +40 −0 Original line number Diff line number Diff line #include <fcntl.h> #include <iostream> #include <sys/syscall.h> #include <unistd.h> int main() { // measure time to run in microseconds struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // open /dev/null 100000 times for (int j = 0; j < 1000; j++) { for (int i = 0; i < 100000; i++) { int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); close(fd); } } clock_gettime(CLOCK_MONOTONIC, &end); double time_taken = (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3; std::cout << "Time taken: " << time_taken << " microseconds" << std::endl; // mean of the time for a syscall (10000000) std::cout << "Mean time taken: " << time_taken / 10000000.0 << " microseconds" << std::endl; // Calculate single syscall () clock_gettime(CLOCK_MONOTONIC, &start); int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); close(fd); clock_gettime(CLOCK_MONOTONIC, &end); std::cout << "Time taken for single syscall: " << (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3 << " microseconds" << std::endl; return 0; } No newline at end of file