From bca44949df14e662d22f0d97813fba418bb26493 Mon Sep 17 00:00:00 2001 From: "zhuangbowei.zbw" Date: Thu, 6 Aug 2026 14:54:58 +0800 Subject: [PATCH 1/5] fix build on centos 7 where SOL_NETLINK is not exported by glibc Signed-off-by: zhuangbowei.zbw --- src/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index e151dd38..d98c53ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,12 @@ #include #include +// glibc did not export SOL_NETLINK until 2.24, while the value is a fixed part +// of the kernel ABI. Define it for the older toolchains, e.g. on CentOS 7. +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + class TCMUDevLoop; #define MAX_OPEN_FD 1048576 From b4cedaccab08ba768848e13b082cf3f44614a1b6 Mon Sep 17 00:00:00 2001 From: "zhuangbowei.zbw" Date: Wed, 9 Sep 2026 13:21:08 +0800 Subject: [PATCH 2/5] build: rework the cmake build Signed-off-by: zhuangbowei.zbw --- CMake/FindCURL.cmake | 7 +- CMake/FindOpenSSL.cmake | 7 +- CMake/FindRapidJSON.cmake | 33 +- CMake/Findaio.cmake | 9 + CMake/Finde2fs.cmake | 83 ++- CMake/Finderofsutils.cmake | 62 ++ CMake/Findgflags.cmake | 16 + CMake/Findgtest.cmake | 27 + CMake/Findliburing.cmake | 4 +- CMake/Findphoton.cmake | 196 ++++-- CMake/Findtcmu.cmake | 53 +- CMake/Findublksrv.cmake | 4 +- CMake/Findyamlcpp.cmake | 25 + CMake/Findzstd.cmake | 17 + CMakeLists.txt | 611 +++++++++++++++--- baselayers/CMakeLists.txt | 9 - src/CMakeLists.txt | 83 --- src/overlaybd/CMakeLists.txt | 28 - src/overlaybd/gzindex/CMakeLists.txt | 9 - src/overlaybd/gzindex/test/CMakeLists.txt | 15 - src/overlaybd/gzip/CMakeLists.txt | 11 - src/overlaybd/gzip_cache/CMakeLists.txt | 10 - src/overlaybd/lsmt/CMakeLists.txt | 10 - src/overlaybd/lsmt/test/CMakeLists.txt | 15 - src/overlaybd/registryfs/CMakeLists.txt | 10 - src/overlaybd/stream_convertor/CMakeLists.txt | 18 - src/overlaybd/tar/CMakeLists.txt | 13 - src/overlaybd/tar/erofs/CMakeLists.txt | 45 -- src/overlaybd/tar/erofs/test/CMakeLists.txt | 37 -- src/overlaybd/tar/test/CMakeLists.txt | 15 - src/overlaybd/zfile/CMakeLists.txt | 72 --- src/overlaybd/zfile/test/CMakeLists.txt | 15 - src/overlaybd/zfile/thirdparty/CMakeLists.txt | 23 - src/overlaybd/zstd/CMakeLists.txt | 9 - src/test/CMakeLists.txt | 76 --- src/tools/CMakeLists.txt | 54 -- src/ublk/CMakeLists.txt | 55 -- src/ublk/test/CMakeLists.txt | 24 - test/CMakeLists.txt | 80 +++ 39 files changed, 1033 insertions(+), 857 deletions(-) create mode 100644 CMake/Finderofsutils.cmake create mode 100644 CMake/Findgflags.cmake create mode 100644 CMake/Findgtest.cmake create mode 100644 CMake/Findyamlcpp.cmake create mode 100644 CMake/Findzstd.cmake delete mode 100644 baselayers/CMakeLists.txt delete mode 100644 src/CMakeLists.txt delete mode 100644 src/overlaybd/CMakeLists.txt delete mode 100644 src/overlaybd/gzindex/CMakeLists.txt delete mode 100644 src/overlaybd/gzindex/test/CMakeLists.txt delete mode 100644 src/overlaybd/gzip/CMakeLists.txt delete mode 100644 src/overlaybd/gzip_cache/CMakeLists.txt delete mode 100644 src/overlaybd/lsmt/CMakeLists.txt delete mode 100644 src/overlaybd/lsmt/test/CMakeLists.txt delete mode 100644 src/overlaybd/registryfs/CMakeLists.txt delete mode 100644 src/overlaybd/stream_convertor/CMakeLists.txt delete mode 100644 src/overlaybd/tar/CMakeLists.txt delete mode 100644 src/overlaybd/tar/erofs/CMakeLists.txt delete mode 100644 src/overlaybd/tar/erofs/test/CMakeLists.txt delete mode 100644 src/overlaybd/tar/test/CMakeLists.txt delete mode 100644 src/overlaybd/zfile/CMakeLists.txt delete mode 100644 src/overlaybd/zfile/test/CMakeLists.txt delete mode 100644 src/overlaybd/zfile/thirdparty/CMakeLists.txt delete mode 100644 src/overlaybd/zstd/CMakeLists.txt delete mode 100644 src/test/CMakeLists.txt delete mode 100644 src/tools/CMakeLists.txt delete mode 100644 src/ublk/CMakeLists.txt delete mode 100644 src/ublk/test/CMakeLists.txt create mode 100644 test/CMakeLists.txt diff --git a/CMake/FindCURL.cmake b/CMake/FindCURL.cmake index 041bd5e2..2577fbab 100644 --- a/CMake/FindCURL.cmake +++ b/CMake/FindCURL.cmake @@ -3,10 +3,9 @@ include(FetchContent) if(${BUILD_CURL_FROM_SOURCE}) message("Add and build standalone libcurl") include(FetchContent) - FetchContent_Declare( - curl_bundle - GIT_REPOSITORY https://github.com/curl/curl.git - GIT_TAG curl-7_42_1 + FetchContent_Declare(curl_bundle + GIT_REPOSITORY ${DEPENDENCY_CURL_REPOSITORY} + GIT_TAG ${DEPENDENCY_CURL_TAG} GIT_PROGRESS 1) FetchContent_GetProperties(curl_bundle) diff --git a/CMake/FindOpenSSL.cmake b/CMake/FindOpenSSL.cmake index dbe1d545..0b49b403 100644 --- a/CMake/FindOpenSSL.cmake +++ b/CMake/FindOpenSSL.cmake @@ -5,10 +5,9 @@ if(${BUILD_CURL_FROM_SOURCE}) include(FetchContent) # make openssl into bundle - FetchContent_Declare( - openssl102 - GIT_REPOSITORY https://github.com/openssl/openssl.git - GIT_TAG OpenSSL_1_0_2-stable + FetchContent_Declare(openssl102 + GIT_REPOSITORY ${DEPENDENCY_OPENSSL_REPOSITORY} + GIT_TAG ${DEPENDENCY_OPENSSL_TAG} GIT_PROGRESS 1) FetchContent_GetProperties(openssl102) diff --git a/CMake/FindRapidJSON.cmake b/CMake/FindRapidJSON.cmake index f142f5cf..e411b368 100644 --- a/CMake/FindRapidJSON.cmake +++ b/CMake/FindRapidJSON.cmake @@ -1,19 +1,30 @@ -find_package(PkgConfig) -if (PKG_CONFIG_FOUND) - pkg_check_modules(RAPIDJSON RapidJSON) -endif() +include(FetchContent) +include(FindPackageHandleStandardArgs) -if (NOT RAPIDJSON_FOUND) +if(DEPENDENCY_RAPIDJSON_REPOSITORY) if (NOT rapidjson_POPULATED) - FetchContent_Populate( - rapidjson - GIT_REPOSITORY https://github.com/Tencent/rapidjson.git - GIT_TAG 80b6d1c83402a5785c486603c5611923159d0894 - GIT_SUBMODULES "" - ) + # header only, no need to build it + FetchContent_Populate( + rapidjson + GIT_REPOSITORY ${DEPENDENCY_RAPIDJSON_REPOSITORY} + GIT_TAG ${DEPENDENCY_RAPIDJSON_TAG} + GIT_SUBMODULES "" + ) endif() FetchContent_GetProperties(rapidjson) set(RAPIDJSON_INCLUDE_DIRS "${rapidjson_SOURCE_DIR}/include") + set(RapidJSON_FOUND yes) +else() + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(RAPIDJSON RapidJSON) + endif() + + if (NOT RAPIDJSON_FOUND) + find_path(RAPIDJSON_INCLUDE_DIRS rapidjson/document.h) + find_package_handle_standard_args(RapidJSON DEFAULT_MSG + RAPIDJSON_INCLUDE_DIRS) + endif() endif() add_definitions("-DRAPIDJSON_HAS_STDSTRING=1") diff --git a/CMake/Findaio.cmake b/CMake/Findaio.cmake index eca99351..3f13ebe9 100644 --- a/CMake/Findaio.cmake +++ b/CMake/Findaio.cmake @@ -5,4 +5,13 @@ find_library(AIO_LIBRARIES aio) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(aio DEFAULT_MSG AIO_LIBRARIES AIO_INCLUDE_DIR) +if(AIO_FOUND AND NOT TARGET AIO::aio) + add_library(AIO::aio UNKNOWN IMPORTED) + set_target_properties( + AIO::aio + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${AIO_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${AIO_INCLUDE_DIR}") +endif() + mark_as_advanced(AIO_INCLUDE_DIR AIO_LIBRARIES) \ No newline at end of file diff --git a/CMake/Finde2fs.cmake b/CMake/Finde2fs.cmake index 5b71e0c1..920a08ae 100644 --- a/CMake/Finde2fs.cmake +++ b/CMake/Finde2fs.cmake @@ -1,18 +1,16 @@ -include(FindPackageHandleStandardArgs) - -if(NOT ORIGIN_EXT2FS) +if(DEPENDENCY_E2FSPROGS_REPOSITORY) message("Add and build standalone libext2fs") include(FetchContent) - FetchContent_Declare( - e2fsprogs - GIT_REPOSITORY https://github.com/data-accelerator/e2fsprogs.git - GIT_TAG 404deb95e6b0ed0ceb0148d289977e65bee7f8d0 + + FetchContent_Declare(e2fsprogs + GIT_REPOSITORY ${DEPENDENCY_E2FSPROGS_REPOSITORY} + GIT_TAG ${DEPENDENCY_E2FSPROGS_TAG} ) FetchContent_GetProperties(e2fsprogs) if(NOT TARGET libext2fs_build) FetchContent_MakeAvailable(e2fsprogs) - set(LIBEXT2FS_INSTALL_DIR ${e2fsprogs_SOURCE_DIR}/build/libext2fs CACHE STRING "") + set(LIBEXT2FS_INSTALL_DIR ${e2fsprogs_SOURCE_DIR}/build/v1.47.0-opt CACHE STRING "") set(E2FS_RESIZE_DIR ${e2fsprogs_SOURCE_DIR}/build/resize CACHE STRING "path to e2fsprogs resize build dir") set(E2FS_INSTALL_LIB_DIR ${LIBEXT2FS_INSTALL_DIR}/lib CACHE STRING "path to e2fsprogs install-libs output") @@ -23,6 +21,8 @@ if(NOT ORIGIN_EXT2FS) # line, so setting CFLAGS via the environment is ignored -- we patch # build.sh in place instead. `-std=gnu11` is supported by every # compiler used across the release matrix (GCC 8+). + # + # build.sh also picks its own compiler, hence CC from the environment. add_custom_command( OUTPUT ${LIBEXT2FS_INSTALL_DIR}/lib BYPRODUCTS @@ -40,20 +40,71 @@ if(NOT ORIGIN_EXT2FS) set(E2FS_FOUND yes) set(E2FS_LIBRARY ${LIBEXT2FS_INSTALL_DIR}/lib/libext2fs.so) set(E2FS_COM_ERR_LIBRARY ${e2fsprogs_SOURCE_DIR}/build/lib/libcom_err.a) + # E2FS_LIBRARIES is what photon's own build consumes, overlaybd links the + # imported targets below instead. set(E2FS_LIBRARIES ${E2FS_LIBRARY} ${E2FS_COM_ERR_LIBRARY}) set(E2FS_INCLUDE_DIR ${LIBEXT2FS_INSTALL_DIR}/include) set(E2FS_INCLUDE_DIRS ${E2FS_INCLUDE_DIR}) - if(NOT TARGET libext2fs) - add_library(libext2fs UNKNOWN IMPORTED) - endif() - add_dependencies(libext2fs libext2fs_build) - + # The libraries and headers only appear once libext2fs_build has run, but + # imported targets validate INTERFACE_INCLUDE_DIRECTORIES at configure time. + file(MAKE_DIRECTORY ${E2FS_INCLUDE_DIR}) else() find_path(E2FS_INCLUDE_DIRS ext2fs/ext2fs.h) - find_library(E2FS_LIBRARIES ext2fs) + + # libext2fs is LGPL, so it is linked dynamically no matter what: restore the + # normal suffix list for this lookup, which FULL_STATIC would otherwise + # narrow down to the archive. The build from source above does the same, by + # naming libext2fs.so directly. + set(_e2fs_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVE}) + find_library(E2FS_LIBRARY ext2fs) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_e2fs_suffixes}) + + find_library(E2FS_COM_ERR_LIBRARY com_err) + set(E2FS_LIBRARIES ${E2FS_LIBRARY}) + + find_package_handle_standard_args(e2fs DEFAULT_MSG E2FS_LIBRARY + E2FS_INCLUDE_DIRS) endif() -find_package_handle_standard_args(e2fs DEFAULT_MSG E2FS_LIBRARIES E2FS_INCLUDE_DIRS) +if(E2FS_FOUND) + if(E2FS_COM_ERR_LIBRARY AND NOT TARGET E2FSPROGS::libcom_err) + add_library(E2FSPROGS::libcom_err UNKNOWN IMPORTED) + set_target_properties( + E2FSPROGS::libcom_err + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${E2FS_COM_ERR_LIBRARY}") + if(DEPENDENCY_E2FSPROGS_REPOSITORY) + add_dependencies(E2FSPROGS::libcom_err libext2fs_build) + endif() + endif() + + if(NOT TARGET E2FSPROGS::libext2fs) + add_library(E2FSPROGS::libext2fs UNKNOWN IMPORTED) + set_target_properties( + E2FSPROGS::libext2fs + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${E2FS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${E2FS_INCLUDE_DIRS}") + # libext2fs calls into com_err, which therefore has to follow it. + if(TARGET E2FSPROGS::libcom_err) + set_property(TARGET E2FSPROGS::libext2fs PROPERTY + INTERFACE_LINK_LIBRARIES E2FSPROGS::libcom_err) + endif() + if(DEPENDENCY_E2FSPROGS_REPOSITORY) + add_dependencies(E2FSPROGS::libext2fs libext2fs_build) + endif() + endif() + + # photon's extfs.cpp/mkfs.cpp live inside the photon archive and reference + # the ext2fs_* symbols. An executable that links libext2fs directly gets it + # placed ahead of the transitively-pulled photon archive, and the + # --as-needed default on modern toolchains then drops libext2fs.so before + # those references are seen, leaving them undefined. Linking it through this + # list keeps it wherever CMake orders it; every consumer of libext2fs goes + # through photon's extfs, so keeping it unconditionally is correct. + set(E2FS_LIBEXT2FS_LINK -Wl,--no-as-needed E2FSPROGS::libext2fs -Wl,--as-needed) +endif() -mark_as_advanced(E2FS_INCLUDE_DIRS E2FS_LIBRARIES) +mark_as_advanced(E2FS_INCLUDE_DIRS E2FS_LIBRARY E2FS_COM_ERR_LIBRARY) diff --git a/CMake/Finderofsutils.cmake b/CMake/Finderofsutils.cmake new file mode 100644 index 00000000..ddd77d77 --- /dev/null +++ b/CMake/Finderofsutils.cmake @@ -0,0 +1,62 @@ +include(FetchContent) +include(FindPackageHandleStandardArgs) + +if(DEPENDENCY_EROFS_UTILS_REPOSITORY) + FetchContent_Declare(erofs-utils + GIT_REPOSITORY ${DEPENDENCY_EROFS_UTILS_REPOSITORY} + GIT_TAG ${DEPENDENCY_EROFS_UTILS_TAG} + ) + FetchContent_GetProperties(erofs-utils) + if(NOT erofs-utils_POPULATED) + FetchContent_Populate(erofs-utils) + endif() + + set(EROFS_LIB_INCLUDE_DIR "${erofs-utils_SOURCE_DIR}/include/" CACHE PATH "erofs-utils include path.") + set(EROFS_CONFIG_FILE "${erofs-utils_SOURCE_DIR}/config.h" CACHE PATH "erofs-utils config file.") + set(EROFS_LIB_STATIC "${erofs-utils_SOURCE_DIR}/lib/.libs/liberofs.a" CACHE PATH "erofs-utils static lib.") + + # liberofs.a and config.h are produced at build time; make sure the include + # dir exists at configure time so EROFS::utils' INTERFACE_INCLUDE_DIRECTORIES + # passes CMake's imported-target path validation. + file(MAKE_DIRECTORY ${EROFS_LIB_INCLUDE_DIR}) + + # build erofs-utils with its own autotools at build time (not configure time) + if(NOT TARGET liberofs_build) + add_custom_command( + OUTPUT ${EROFS_LIB_STATIC} + WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} + COMMAND ./autogen.sh && + ./configure --disable-lz4 --disable-lzma --without-libzstd + --without-uuid --disable-multithreading && + make) + add_custom_target(liberofs_build DEPENDS ${EROFS_LIB_STATIC}) + endif() + + set(erofsutils_FOUND yes) + if(NOT TARGET EROFS::utils) + add_library(EROFS::utils STATIC IMPORTED) + endif() + add_dependencies(EROFS::utils liberofs_build) +else() + find_path(EROFS_LIB_INCLUDE_DIR erofs/tar.h) + find_library(EROFS_LIB_STATIC erofs) + # config.h is generated by erofs-utils' own configure and force-included as + # a compile option below, so a local installation has to provide it as well + find_file(EROFS_CONFIG_FILE erofs/config.h) + + find_package_handle_standard_args(erofsutils DEFAULT_MSG EROFS_LIB_STATIC + EROFS_LIB_INCLUDE_DIR EROFS_CONFIG_FILE) + + if(erofsutils_FOUND AND NOT TARGET EROFS::utils) + add_library(EROFS::utils STATIC IMPORTED) + endif() +endif() + +if(TARGET EROFS::utils) + set_target_properties( + EROFS::utils + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${EROFS_LIB_STATIC}" + INTERFACE_INCLUDE_DIRECTORIES "${EROFS_LIB_INCLUDE_DIR}" + INTERFACE_COMPILE_OPTIONS "-include${EROFS_CONFIG_FILE}") +endif() diff --git a/CMake/Findgflags.cmake b/CMake/Findgflags.cmake new file mode 100644 index 00000000..8a5497d2 --- /dev/null +++ b/CMake/Findgflags.cmake @@ -0,0 +1,16 @@ +find_path(GFLAGS_INCLUDE_DIRS gflags/gflags.h) + +find_library(GFLAGS_LIBRARIES gflags) + +find_package_handle_standard_args(gflags DEFAULT_MSG GFLAGS_LIBRARIES + GFLAGS_INCLUDE_DIRS) + +if(gflags_FOUND AND NOT TARGET GFLAGS::gflags) + add_library(GFLAGS::gflags UNKNOWN IMPORTED) + set_target_properties( + GFLAGS::gflags + PROPERTIES IMPORTED_LOCATION "${GFLAGS_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${GFLAGS_INCLUDE_DIRS}") +endif() + +mark_as_advanced(GFLAGS_INCLUDE_DIRS GFLAGS_LIBRARIES) diff --git a/CMake/Findgtest.cmake b/CMake/Findgtest.cmake new file mode 100644 index 00000000..9afd92f2 --- /dev/null +++ b/CMake/Findgtest.cmake @@ -0,0 +1,27 @@ +find_path(GTEST_INCLUDE_DIRS gtest/gtest.h) + +find_library(GTEST_LIBRARIES gtest) + +# gtest_main is only needed by the tests that do not bring their own main() +find_library(GTEST_MAIN_LIBRARIES gtest_main) + +find_package_handle_standard_args(gtest DEFAULT_MSG GTEST_LIBRARIES + GTEST_MAIN_LIBRARIES GTEST_INCLUDE_DIRS) + +if(gtest_FOUND AND NOT TARGET GTEST::gtest) + add_library(GTEST::gtest UNKNOWN IMPORTED) + set_target_properties( + GTEST::gtest + PROPERTIES IMPORTED_LOCATION "${GTEST_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}") +endif() + +if(gtest_FOUND AND NOT TARGET GTEST::gtest_main) + add_library(GTEST::gtest_main UNKNOWN IMPORTED) + set_target_properties( + GTEST::gtest_main + PROPERTIES IMPORTED_LOCATION "${GTEST_MAIN_LIBRARIES}" + INTERFACE_LINK_LIBRARIES GTEST::gtest) +endif() + +mark_as_advanced(GTEST_INCLUDE_DIRS GTEST_LIBRARIES GTEST_MAIN_LIBRARIES) diff --git a/CMake/Findliburing.cmake b/CMake/Findliburing.cmake index b7498840..a1ea171c 100644 --- a/CMake/Findliburing.cmake +++ b/CMake/Findliburing.cmake @@ -15,8 +15,8 @@ endif() FetchContent_Declare( liburing - GIT_REPOSITORY https://github.com/axboe/liburing.git - GIT_TAG liburing-2.8 + GIT_REPOSITORY ${DEPENDENCY_LIBURING_REPOSITORY} + GIT_TAG ${DEPENDENCY_LIBURING_TAG} ) # download only, no add_subdirectory (liburing is a plain Makefile project) diff --git a/CMake/Findphoton.cmake b/CMake/Findphoton.cmake index b71c32a9..653aac99 100644 --- a/CMake/Findphoton.cmake +++ b/CMake/Findphoton.cmake @@ -1,72 +1,154 @@ include(FetchContent) +include(FindPackageHandleStandardArgs) set(FETCHCONTENT_QUIET false) -set(PHOTON_ENABLE_EXTFS ON CACHE BOOL "Build Photon extfs support" FORCE) -set(PHOTON_BUILD_OCF_CACHE ON CACHE BOOL "Build Photon OCF cache support" FORCE) + +# PHOTON_ENABLE_RESIZE is also consumed by our own sources, so define it +# regardless of where photon comes from. A locally installed photon is then +# expected to provide extfs and resize as well. +set(PHOTON_ENABLE_EXTFS ON) if(NOT ORIGIN_EXT2FS) - set(PHOTON_ENABLE_RESIZE ON CACHE BOOL "Build Photon extfs resize support" FORCE) + set(PHOTON_ENABLE_RESIZE ON) add_definitions(-DPHOTON_ENABLE_RESIZE) -else() - set(PHOTON_ENABLE_RESIZE OFF CACHE BOOL "Build Photon extfs resize support" FORCE) endif() -FetchContent_Declare( - photon - GIT_REPOSITORY https://github.com/alibaba/PhotonLibOS.git - GIT_TAG v0.9.6 -) +# The OCF cache backend is part of photon, and so is the OCF checkout it needs. +set(PHOTON_BUILD_OCF_CACHE ON) + +if(DEPENDENCY_PHOTON_REPOSITORY) + FetchContent_Declare(photon + GIT_REPOSITORY ${DEPENDENCY_PHOTON_REPOSITORY} + GIT_TAG ${DEPENDENCY_PHOTON_TAG} + ) + + if(BUILD_TESTING) + set(BUILD_TESTING 0) + FetchContent_MakeAvailable(photon) + set(BUILD_TESTING 1) + else() + FetchContent_MakeAvailable(photon) + endif() + + # overlaybd links the archives below, libphoton.so is not consumed at all. + # Keep it out of the default target: under FULL_STATIC its dependencies are + # looked up as archives, which the system copies are commonly not built as + # PIC and hence unusable in a shared library. + if(TARGET photon_shared) + set_target_properties(photon_shared PROPERTIES EXCLUDE_FROM_ALL on) + endif() + + # photon_obj is only defined by photon's own build + if (BUILD_CURL_FROM_SOURCE) + find_package(OpenSSL REQUIRED) + find_package(CURL REQUIRED) + add_dependencies(photon_obj CURL::libcurl OpenSSL::SSL OpenSSL::Crypto) + endif() + + if(NOT ORIGIN_EXT2FS) + add_dependencies(photon_obj libext2fs_build) + endif() + + # photon's ocf targets include , which its own build resolves + # through a symlink pointing inside photon's build tree. That layout only + # exists when photon is built standalone, so provide the same include + # layout for the OCF checkout fetched as part of this build. + FetchContent_GetProperties(ocf_lib SOURCE_DIR OCF_SOURCE_DIR) + set(OCF_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/ocf-include) + file(MAKE_DIRECTORY ${OCF_INCLUDE_DIR}) + file(CREATE_LINK ${OCF_SOURCE_DIR}/inc ${OCF_INCLUDE_DIR}/ocf SYMBOLIC) + target_include_directories(ocf_lib PUBLIC ${OCF_INCLUDE_DIR}) + target_include_directories(ocf_cache_lib PUBLIC ${OCF_INCLUDE_DIR}) -if(BUILD_TESTING) - set(BUILD_TESTING 0) - FetchContent_MakeAvailable(photon) - set(BUILD_TESTING 1) + # Consume photon as plain archives rather than through its photon_static + # target: the latter also propagates photon's own third-party dependencies, + # whose declaration (which libraries, in which order) is an implementation + # detail that has changed between photon versions. overlaybd brings those + # dependencies itself, see the external_lib target in the top-level + # CMakeLists.txt. + set(PHOTON_INCLUDE_DIR ${photon_SOURCE_DIR}/include/) + set(PHOTON_LIBRARY ${photon_BINARY_DIR}/output/libphoton_sole.a) + set(PHOTON_EASY_WEAK_LIBRARY ${photon_BINARY_DIR}/output/libeasy_weak.a) + set(PHOTON_OCF_LIBRARY ${photon_BINARY_DIR}/output/libocf_cache_lib.a) + set(PHOTON_OCF_CORE_LIBRARY ${photon_BINARY_DIR}/output/libocf_lib.a) + set(photon_FOUND yes) else() - FetchContent_MakeAvailable(photon) + # A locally installed photon has no photon_BINARY_DIR, look the archives up + # instead. photon_sole is photon's own archive and the one paired with the + # separate weak-symbol archives; libphoton.a is the merged one, which already + # bundles them and is used as a fallback. + find_path(PHOTON_INCLUDE_DIR photon/photon.h) + find_library(PHOTON_LIBRARY NAMES photon_sole photon) + find_library(PHOTON_EASY_WEAK_LIBRARY NAMES easy_weak) + find_library(PHOTON_OCF_LIBRARY NAMES ocf_cache_lib) + find_library(PHOTON_OCF_CORE_LIBRARY NAMES ocf_lib) + + find_package_handle_standard_args(photon DEFAULT_MSG PHOTON_LIBRARY + PHOTON_INCLUDE_DIR) endif() -# Photon v0.9.5 exposes the OCF headers as , while the OCF checkout -# contains them directly in its inc/ directory. When Photon is consumed via -# FetchContent that include layout is not created, so make it explicit for the -# embedded OCF target. -if(TARGET ocf_lib AND NOT TARGET photon_cache_lib) - FetchContent_GetProperties(ocf_lib SOURCE_DIR PHOTON_OCF_SOURCE_DIR) - set(PHOTON_OCF_INCLUDE_DIR ${CMAKE_BINARY_DIR}/photon-ocf-include) - file(MAKE_DIRECTORY ${PHOTON_OCF_INCLUDE_DIR}) - file(REMOVE ${PHOTON_OCF_INCLUDE_DIR}/ocf) - file(CREATE_LINK ${PHOTON_OCF_SOURCE_DIR}/inc ${PHOTON_OCF_INCLUDE_DIR}/ocf SYMBOLIC) - target_include_directories(ocf_lib PUBLIC ${PHOTON_OCF_INCLUDE_DIR}) - - # The OCF cache target declares its environment adapter but omits the - # implementations from its source list when embedded as a dependency. - target_sources(ocf_cache_lib PRIVATE - ${photon_SOURCE_DIR}/fs/cache/ocf_cache/photon_bindings/env/ocf_env.cpp - ${photon_SOURCE_DIR}/fs/cache/ocf_cache/photon_bindings/env/utils_mpool.cpp - ) +if(photon_FOUND) + if(NOT TARGET PHOTON::photonlib) + add_library(PHOTON::photonlib STATIC IMPORTED) + set_target_properties( + PHOTON::photonlib + PROPERTIES IMPORTED_LOCATION "${PHOTON_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${PHOTON_INCLUDE_DIR}") + endif() - # These archives have circular static dependencies. Keep the rescan group - # on the consumer side so that cache users link reliably on GNU ld. - add_library(photon_cache_lib INTERFACE) - target_link_libraries(photon_cache_lib INTERFACE - "-Wl,--start-group" - "$" - "$" - "$" - "-Wl,--end-group" - ) - # Photon users do not all depend on OverlayBD's gzip-cache target. Export - # the OCF rescan group from photon_static itself so tools such as - # overlaybd-commit receive the required OCF environment implementation. - target_link_libraries(photon_static INTERFACE photon_cache_lib) -endif() + # The OCF cache backend is shipped as archives of its own rather than being + # merged into photon's, and comes first on the link line: it is what provides + # new_ocf_cached_fs(), and it needs photon in turn. libocf_lib.a and + # libocf_cache_lib.a refer to each other (the latter provides the OCF + # environment adapter), hence the group. + if(PHOTON_OCF_LIBRARY) + if(NOT TARGET PHOTON::ocf_cache) + add_library(PHOTON::ocf_cache STATIC IMPORTED) + set_target_properties( + PHOTON::ocf_cache + PROPERTIES IMPORTED_LOCATION "${PHOTON_OCF_LIBRARY}") + add_library(PHOTON::ocf STATIC IMPORTED) + set_target_properties( + PHOTON::ocf + PROPERTIES IMPORTED_LOCATION "${PHOTON_OCF_CORE_LIBRARY}") + endif() + set(PHOTON_ARCHIVES -Wl,--start-group PHOTON::ocf_cache PHOTON::ocf + -Wl,--end-group) + endif() -if (BUILD_CURL_FROM_SOURCE) - find_package(OpenSSL REQUIRED) - find_package(CURL REQUIRED) - add_dependencies(photon_obj CURL::libcurl OpenSSL::SSL OpenSSL::Crypto) -endif() + list(APPEND PHOTON_ARCHIVES PHOTON::photonlib) -if(NOT ORIGIN_EXT2FS) - add_dependencies(photon_obj libext2fs) -endif() + # Absent when a locally installed photon only ships the merged libphoton.a. + if(PHOTON_EASY_WEAK_LIBRARY) + if(NOT TARGET PHOTON::easy_weak) + add_library(PHOTON::easy_weak STATIC IMPORTED) + set_target_properties( + PHOTON::easy_weak + PROPERTIES IMPORTED_LOCATION "${PHOTON_EASY_WEAK_LIBRARY}") + endif() + list(APPEND PHOTON_ARCHIVES PHOTON::easy_weak) + endif() -set(PHOTON_INCLUDE_DIR ${photon_SOURCE_DIR}/include/) + # The weak overrides have to follow the archive referring to them on the link + # line, hence the aggregate rather than a plain list at every call site. + if(NOT TARGET PHOTON::photon) + add_library(PHOTON::photon INTERFACE IMPORTED) + set_target_properties( + PHOTON::photon + PROPERTIES INTERFACE_LINK_LIBRARIES "${PHOTON_ARCHIVES}" + INTERFACE_INCLUDE_DIRECTORIES "${PHOTON_INCLUDE_DIR}") + endif() + + # When photon is built here, the archives above only exist once its own + # targets have run. The dependency is followed through the aggregate, so + # everything linking PHOTON::photon waits for them. + if(DEPENDENCY_PHOTON_REPOSITORY) + add_dependencies(PHOTON::photonlib photon_static) + if(TARGET PHOTON::easy_weak) + add_dependencies(PHOTON::easy_weak easy_weak) + endif() + if(TARGET PHOTON::ocf_cache) + add_dependencies(PHOTON::ocf_cache ocf_cache_lib) + add_dependencies(PHOTON::ocf ocf_lib) + endif() + endif() +endif() diff --git a/CMake/Findtcmu.cmake b/CMake/Findtcmu.cmake index 92d6ec65..30fe4ec9 100644 --- a/CMake/Findtcmu.cmake +++ b/CMake/Findtcmu.cmake @@ -1,17 +1,48 @@ include(FetchContent) +include(FindPackageHandleStandardArgs) set(FETCHCONTENT_QUIET false) -FetchContent_Declare( - tcmu - GIT_REPOSITORY https://github.com/data-accelerator/photon-libtcmu.git - GIT_TAG 813fd65361bb2f348726b9c41478a44211847614 -) +if(DEPENDENCY_TCMU_REPOSITORY) + FetchContent_Declare(tcmu + GIT_REPOSITORY ${DEPENDENCY_TCMU_REPOSITORY} + GIT_TAG ${DEPENDENCY_TCMU_TAG} + ) -if(BUILD_TESTING) - set(BUILD_TESTING 0) - FetchContent_MakeAvailable(tcmu) - set(BUILD_TESTING 1) + # tcmu itself links against libnl, which is only available as a shared + # library on the target systems. Restore the normal suffix list while it + # configures itself and its own dependencies, then switch back. + set(_tcmu_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVE}) + + if(BUILD_TESTING) + set(BUILD_TESTING 0) + FetchContent_MakeAvailable(tcmu) + set(BUILD_TESTING 1) + else() + FetchContent_MakeAvailable(tcmu) + endif() + set(TCMU_INCLUDE_DIR ${tcmu_SOURCE_DIR}/) + set(tcmu_FOUND yes) + + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_tcmu_suffixes}) else() - FetchContent_MakeAvailable(tcmu) + find_path(TCMU_INCLUDE_DIR libtcmu.h) + find_library(TCMU_LIBRARY tcmu) + + find_package_handle_standard_args(tcmu DEFAULT_MSG TCMU_LIBRARY + TCMU_INCLUDE_DIR) +endif() + +if(tcmu_FOUND AND NOT TARGET TCMU::tcmu) + if(DEPENDENCY_TCMU_REPOSITORY) + # tcmu_static is defined by tcmu's own build + add_library(TCMU::tcmu ALIAS tcmu_static) + else() + add_library(TCMU::tcmu STATIC IMPORTED) + set_target_properties( + TCMU::tcmu + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${TCMU_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${TCMU_INCLUDE_DIR}") + endif() endif() -set(TCMU_INCLUDE_DIR ${tcmu_SOURCE_DIR}/) diff --git a/CMake/Findublksrv.cmake b/CMake/Findublksrv.cmake index d8a4ae31..a92e0b0f 100644 --- a/CMake/Findublksrv.cmake +++ b/CMake/Findublksrv.cmake @@ -24,8 +24,8 @@ endif() FetchContent_Declare( ublksrv - GIT_REPOSITORY https://github.com/ublk-org/ublksrv.git - GIT_TAG f6c643952d1cdc7f6460630638fe6b5454ca1c4d # v1.7 + GIT_REPOSITORY ${DEPENDENCY_UBLKSRV_REPOSITORY} + GIT_TAG ${DEPENDENCY_UBLKSRV_TAG} ) FetchContent_GetProperties(ublksrv) diff --git a/CMake/Findyamlcpp.cmake b/CMake/Findyamlcpp.cmake new file mode 100644 index 00000000..ad1518d4 --- /dev/null +++ b/CMake/Findyamlcpp.cmake @@ -0,0 +1,25 @@ +include(FetchContent) +include(FindPackageHandleStandardArgs) + +if(DEPENDENCY_YAML_CPP_REPOSITORY) + FetchContent_Declare(yaml-cpp + GIT_REPOSITORY ${DEPENDENCY_YAML_CPP_REPOSITORY} + GIT_TAG ${DEPENDENCY_YAML_CPP_TAG} + ) + FetchContent_MakeAvailable(yaml-cpp) + set(yamlcpp_FOUND yes) +else() + find_path(YAMLCPP_INCLUDE_DIRS yaml-cpp/yaml.h) + find_library(YAMLCPP_LIBRARIES yaml-cpp) + + find_package_handle_standard_args(yamlcpp DEFAULT_MSG YAMLCPP_LIBRARIES + YAMLCPP_INCLUDE_DIRS) + + if(yamlcpp_FOUND AND NOT TARGET yaml-cpp) + add_library(yaml-cpp UNKNOWN IMPORTED) + set_target_properties( + yaml-cpp + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${YAMLCPP_INCLUDE_DIRS}" + IMPORTED_LOCATION "${YAMLCPP_LIBRARIES}") + endif() +endif() diff --git a/CMake/Findzstd.cmake b/CMake/Findzstd.cmake new file mode 100644 index 00000000..5f5ca477 --- /dev/null +++ b/CMake/Findzstd.cmake @@ -0,0 +1,17 @@ +find_path(ZSTD_INCLUDE_DIRS zstd.h) + +find_library(ZSTD_LIBRARIES zstd) + +find_package_handle_standard_args(zstd DEFAULT_MSG ZSTD_LIBRARIES + ZSTD_INCLUDE_DIRS) + +if(zstd_FOUND AND NOT TARGET ZSTD::zstd) + add_library(ZSTD::zstd UNKNOWN IMPORTED) + set_target_properties( + ZSTD::zstd + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${ZSTD_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${ZSTD_INCLUDE_DIRS}") +endif() + +mark_as_advanced(ZSTD_INCLUDE_DIRS ZSTD_LIBRARIES) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73b5ff7b..382e3734 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,134 +1,557 @@ cmake_minimum_required(VERSION 3.14) project( - overlaybd - LANGUAGES C CXX + overlaybd + LANGUAGES C CXX ) -enable_language(C) + +#--------------------------------------------------------------------- +# Options +#--------------------------------------------------------------------- +# Off by default: it makes every dependency below be looked up as an archive, +# which the system copies shipped by most distributions are not usable as (not +# built as PIC, or relying on the transitive dependencies that only their .pc +# file names). Turning it on is for the deployments that need self-contained +# binaries and bring static dependencies to match. +option(FULL_STATIC "make all binary output depends only libc dynamic libs" off) +option(BUILD_CURL_FROM_SOURCE "Compile static libcurl" off) +option(BUILD_STREAM_CONVERTOR "Build the stream convertor" on) +option(ORIGIN_EXT2FS "Use original libext2fs" off) +option(ENABLE_QAT "Build the QAT compression backend" off) +option(ENABLE_DSA "Build the DSA crc32 backend (requires the DML submodule)" off) +option(ENABLE_ISAL "Build the ISA-L crc32 backend (requires the isa-l submodule)" off) + +set(OBD_VER "overlaybd/0.0.0-undefined" CACHE STRING "Overlaybd version") + +#--------------------------------------------------------------------- +# ublk frontend +# +# ublk_drv landed in mainline Linux 6.0, and building the frontend also needs +# autotools for ublksrv, so it is only on by default where the kernel can drive +# it. Force it either way with -DBUILD_UBLK_FRONTEND=on|off. +#--------------------------------------------------------------------- +set(UBLK_KERNEL_SUPPORTED off) +set(UBLK_SUPPORT_REASON "not detected") + +# modinfo resolves ublk_drv for the running kernel whether it is loaded or not +find_program(MODINFO_EXECUTABLE modinfo PATHS /sbin /usr/sbin /bin /usr/bin) +if(MODINFO_EXECUTABLE) + execute_process( + COMMAND ${MODINFO_EXECUTABLE} -F filename ublk_drv + OUTPUT_VARIABLE UBLK_DRV_PATH ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE UBLK_MODINFO_RESULT) + if(UBLK_MODINFO_RESULT EQUAL 0 AND UBLK_DRV_PATH) + set(UBLK_KERNEL_SUPPORTED on) + set(UBLK_SUPPORT_REASON "ublk_drv module ${UBLK_DRV_PATH}") + endif() +endif() + +# fall back to the module shipped for the running kernel +if(NOT UBLK_KERNEL_SUPPORTED) + execute_process(COMMAND uname -r OUTPUT_VARIABLE UBLK_KERNEL_RELEASE + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(UBLK_KERNEL_RELEASE) + file(GLOB UBLK_DRV_KO + "/lib/modules/${UBLK_KERNEL_RELEASE}/kernel/drivers/block/ublk_drv.ko*") + if(UBLK_DRV_KO) + set(UBLK_KERNEL_SUPPORTED on) + set(UBLK_SUPPORT_REASON "ublk_drv module ${UBLK_DRV_KO}") + endif() + endif() +endif() + +# fall back to the uapi header, installed by kernel-headers 6.0 and later +if(NOT UBLK_KERNEL_SUPPORTED) + find_path(UBLK_CMD_HEADER NAMES linux/ublk_cmd.h) + if(UBLK_CMD_HEADER) + set(UBLK_KERNEL_SUPPORTED on) + set(UBLK_SUPPORT_REASON "uapi header ${UBLK_CMD_HEADER}/linux/ublk_cmd.h") + endif() +endif() + +option(BUILD_UBLK_FRONTEND "Build the ublk frontend (overlaybd-ublk); auto-detected from kernel ublk support, requires autotools" ${UBLK_KERNEL_SUPPORTED}) +if(BUILD_UBLK_FRONTEND) + message(STATUS "ublk frontend: ON (kernel ublk support: ${UBLK_SUPPORT_REASON})") +else() + message(STATUS "ublk frontend: OFF (kernel ublk support: ${UBLK_SUPPORT_REASON};" + " force with -DBUILD_UBLK_FRONTEND=on)") +endif() + +#--------------------------------------------------------------------- +# Toolchain +#--------------------------------------------------------------------- +if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|aarch64|arm64)$") + message(FATAL_ERROR "Unknown CPU architecture ${CMAKE_SYSTEM_PROCESSOR}") +endif() + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED on) +set(CMAKE_POSITION_INDEPENDENT_CODE on) # -fpic +set(CMAKE_EXPORT_COMPILE_COMMANDS on) set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -g") -if (NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) AND NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) AND NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL arm64)) - message(FATAL_ERROR "Unknown CPU architecture ${CMAKE_SYSTEM_PROCESSOR}") -endif () +add_compile_options(-Wall -Werror=sign-compare) +add_definitions(-DOVERLAYBD_VER=${OBD_VER}) + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") + # +crc also covers what crc32_lib below needs on this architecture + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crc -fsigned-char\ + -fno-stack-protector -fomit-frame-pointer") +endif() + +set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc ${CMAKE_CXX_STANDARD_LIBRARIES}") +find_library(STATIC_LIBSTDCXX libstdc++.a PATHS /usr/lib/gcc/*/*) +if(STATIC_LIBSTDCXX) + set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libstdc++ ${CMAKE_CXX_STANDARD_LIBRARIES}") +endif() -option(OBD_VER "Overlaybd version" "overlaybd/0.0.0-undefined") +# Kept under the source tree: the CI jobs and the packaging scripts expect the +# binaries at build/output regardless of where cmake was invoked from. +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/output") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/output") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/output") -set(LIBRARY_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/build/output") -set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/build/output") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") +include(FindPackageHandleStandardArgs) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMake") +# Prefer static archives for everything we link. Findtcmu.cmake and +# Finde2fs.cmake temporarily restore the saved list, for libnl and libext2fs +# respectively. +set(CMAKE_FIND_LIBRARY_SUFFIXES_SAVE ${CMAKE_FIND_LIBRARY_SUFFIXES}) +if(FULL_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic -Wall -Werror=sign-compare") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic -Wall -Werror=sign-compare -DOVERLAYBD_VER=${OBD_VER}") +#--------------------------------------------------------------------- +# Sources of the dependencies +# +# For each dependency, setting DEPENDENCY__REPOSITORY selects where to +# fetch and build it from, at DEPENDENCY__TAG. Setting the repository to +# empty selects the locally installed one instead, which is then looked up with +# the usual find_path()/find_library() (honoring CMAKE_PREFIX_PATH etc.), e.g. +# +# cmake -DDEPENDENCY_PHOTON_REPOSITORY= -DCMAKE_PREFIX_PATH=/path/to/deps ... +# +# Note that a locally installed dependency is used as is: it is the caller's +# responsibility to make sure it is compatible, since the tag below is then +# neither used nor checked. +#--------------------------------------------------------------------- +set(DEPENDENCY_PHOTON_REPOSITORY "https://github.com/alibaba/PhotonLibOS.git" + CACHE STRING "repository of photon, empty to use the local installation") +set(DEPENDENCY_PHOTON_TAG "v0.9.6" + CACHE STRING "tag/commit of photon") -if ((CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) OR (CMAKE_SYSTEM_PROCESSOR STREQUAL arm64)) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crc -fsigned-char -fno-stack-protector -fomit-frame-pointer") -endif () +set(DEPENDENCY_TCMU_REPOSITORY "https://github.com/data-accelerator/photon-libtcmu.git" + CACHE STRING "repository of photon-libtcmu, empty to use the local installation") +set(DEPENDENCY_TCMU_TAG "813fd65361bb2f348726b9c41478a44211847614" + CACHE STRING "tag/commit of photon-libtcmu") -set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc ${CMAKE_CXX_STANDARD_LIBRARIES}") -find_library(STATIC_LIBSTDC++ libstdc++.a PATHS /usr/lib/gcc/*/*) -if(NOT ${STATIC_LIBSTDC++} STREQUAL "STATIC_LIBSTDC++-NOTFOUND") - set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libstdc++ ${CMAKE_CXX_STANDARD_LIBRARIES}") +set(DEPENDENCY_E2FSPROGS_REPOSITORY "https://github.com/data-accelerator/e2fsprogs.git" + CACHE STRING "repository of e2fsprogs, empty to use the local installation") +set(DEPENDENCY_E2FSPROGS_TAG "404deb95e6b0ed0ceb0148d289977e65bee7f8d0" + CACHE STRING "tag/commit of e2fsprogs") + +set(DEPENDENCY_EROFS_UTILS_REPOSITORY "https://github.com/erofs/erofs-utils.git" + CACHE STRING "repository of erofs-utils, empty to use the local installation") +set(DEPENDENCY_EROFS_UTILS_TAG "eec6f7a2755dfccc8f655aa37cf6f26db9164e60" + CACHE STRING "tag/commit of erofs-utils") + +set(DEPENDENCY_RAPIDJSON_REPOSITORY "https://github.com/Tencent/rapidjson.git" + CACHE STRING "repository of rapidjson, empty to use the local installation") +set(DEPENDENCY_RAPIDJSON_TAG "80b6d1c83402a5785c486603c5611923159d0894" + CACHE STRING "tag/commit of rapidjson") + +# 0.9.0 includes the missing include (PR #1310) required to build with +# GCC 15 (C23 default), e.g. on Azure Linux 4.0. +set(DEPENDENCY_YAML_CPP_REPOSITORY "https://github.com/jbeder/yaml-cpp.git" + CACHE STRING "repository of yaml-cpp, empty to use the local installation") +set(DEPENDENCY_YAML_CPP_TAG "yaml-cpp-0.9.0" + CACHE STRING "tag/commit of yaml-cpp") + +# liburing and ublksrv have no local-installation path: distro liburing is +# commonly missing or older than the 2.2 ublksrv needs, and ublksrv's autotools +# build wants the liburing source tree anyway. Both are always built here. +set(DEPENDENCY_LIBURING_REPOSITORY "https://github.com/axboe/liburing.git" + CACHE STRING "repository of liburing") +set(DEPENDENCY_LIBURING_TAG "liburing-2.8" + CACHE STRING "tag/commit of liburing") + +set(DEPENDENCY_UBLKSRV_REPOSITORY "https://github.com/ublk-org/ublksrv.git" + CACHE STRING "repository of ublksrv") +set(DEPENDENCY_UBLKSRV_TAG "f6c643952d1cdc7f6460630638fe6b5454ca1c4d" # v1.7 + CACHE STRING "tag/commit of ublksrv") + +# curl and openssl default to the local installation, as building them from +# source is only needed for fully static binaries. BUILD_CURL_FROM_SOURCE below +# fills in the repositories known to work for that. +set(DEPENDENCY_CURL_REPOSITORY "" + CACHE STRING "repository of curl, empty to use the local installation") +set(DEPENDENCY_CURL_TAG "curl-7_42_1" + CACHE STRING "tag/commit of curl") + +set(DEPENDENCY_OPENSSL_REPOSITORY "" + CACHE STRING "repository of openssl, empty to use the local installation") +set(DEPENDENCY_OPENSSL_TAG "OpenSSL_1_0_2-stable" + CACHE STRING "tag/commit of openssl") + +# ORIGIN_EXT2FS and BUILD_CURL_FROM_SOURCE predate the variables above and are +# kept as shortcuts for them. They are also still consumed on their own, so keep +# both forms in sync. +if(ORIGIN_EXT2FS) + set(DEPENDENCY_E2FSPROGS_REPOSITORY "") +elseif(NOT DEPENDENCY_E2FSPROGS_REPOSITORY) + set(ORIGIN_EXT2FS on) +endif() +if(BUILD_CURL_FROM_SOURCE) + if(NOT DEPENDENCY_CURL_REPOSITORY) + set(DEPENDENCY_CURL_REPOSITORY "https://github.com/curl/curl.git") + endif() + if(NOT DEPENDENCY_OPENSSL_REPOSITORY) + set(DEPENDENCY_OPENSSL_REPOSITORY "https://github.com/openssl/openssl.git") + endif() +elseif(DEPENDENCY_CURL_REPOSITORY OR DEPENDENCY_OPENSSL_REPOSITORY) + set(BUILD_CURL_FROM_SOURCE on) endif() -find_library(LIBZSTD libzstd.a PATHS /usr/lib/x86_64-linux-gnu/* /usr/lib64/*) -if(${LIBZSTD} STREQUAL "LIBZSTD-NOTFOUND") - message("libzstd.a not found, try to find shared library") - find_library(LIBZSTD libzstd.so PATHS /usr/lib/x86_64-linux-gnu/* /usr/lib64/*) +#--------------------------------------------------------------------- +# External dependencies +#--------------------------------------------------------------------- +# e2fs is looked up before photon: photon's own build looks it up as well, and +# photon_obj is ordered after the libext2fs build declared by this call. +find_package(e2fs REQUIRED) # E2FSPROGS::libext2fs E2FSPROGS::libcom_err +find_package(photon REQUIRED) # PHOTON::photon +find_package(tcmu REQUIRED) # TCMU::tcmu +find_package(CURL REQUIRED) # CURL::libcurl +find_package(OpenSSL REQUIRED) # OpenSSL::SSL OpenSSL::Crypto +find_package(ZLIB REQUIRED) # ZLIB::ZLIB +find_package(aio REQUIRED) # AIO::aio +find_package(zstd REQUIRED) # ZSTD::zstd +find_package(erofsutils REQUIRED) # EROFS::utils +find_package(RapidJSON REQUIRED) # (header only) RAPIDJSON_INCLUDE_DIRS +if(BUILD_STREAM_CONVERTOR) + find_package(yamlcpp REQUIRED) # yaml-cpp +endif() +if(BUILD_UBLK_FRONTEND) + find_package(liburing REQUIRED) # liburing_static + find_package(ublksrv REQUIRED) # libublksrv_static endif() -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED on) -set(ENABLE_MIMIC_VDSO off) +# Everything overlaybd links besides its own libraries, declared once here +# instead of being spelled out by every target. +# +# photon and overlaybd share these: photon references curl, openssl, zlib and +# libaio, and overlaybd uses openssl and zlib on its own as well. They are all +# static in the default configuration, so their relative order on the link line +# matters -- a single list is what keeps that order right, in particular +# libcurl.a needing openssl and zlib to follow it. +# +# Dependencies only some of the binaries need are deliberately not part of this, +# E2FSPROGS::libext2fs in particular: it is linked by the targets that go +# through photon's extfs support, so that the ones that do not are not tied to +# libext2fs.so at runtime. +add_library(external_lib INTERFACE) +target_include_directories(external_lib INTERFACE ${RAPIDJSON_INCLUDE_DIRS}) +target_link_libraries(external_lib INTERFACE + PHOTON::photon + CURL::libcurl + OpenSSL::SSL + OpenSSL::Crypto + ZLIB::ZLIB + AIO::aio + pthread + rt + dl + resolv +) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # photon needs libgcc for the hidden __cpu_model symbol + target_link_libraries(external_lib INTERFACE gcc) +endif() -option(BUILD_CURL_FROM_SOURCE "Compile static libcurl" off) -option(BUILD_STREAM_CONVERTOR "Build the stream convertor" on) -option(ORIGIN_EXT2FS "Use original libext2fs" off) -# --- ublk kernel-support detection ----------------------------------------- -# The ublk userspace block driver (ublk_drv) landed in mainline Linux 6.0. -# Default BUILD_UBLK_FRONTEND to ON only when the running kernel can drive -# ublk, so a bare `cmake ..` does not attempt the ublk build (and its -# autotools + liburing + ublksrv fetch) on kernels without ublk. It can still -# be forced either way with -DBUILD_UBLK_FRONTEND=on|off. -set(UBLK_KERNEL_SUPPORTED OFF) -set(UBLK_SUPPORT_REASON "not detected") +#--------------------------------------------------------------------- +# overlaybd libraries +#--------------------------------------------------------------------- +add_library(checksum_lib STATIC src/tools/sha256file.cpp) +target_link_libraries(checksum_lib PUBLIC external_lib) -# (a) preferred: modinfo resolves ublk_drv for the running kernel (loaded or not) -find_program(MODINFO_EXECUTABLE modinfo PATHS /sbin /usr/sbin /bin /usr/bin) -if(MODINFO_EXECUTABLE) - execute_process( - COMMAND ${MODINFO_EXECUTABLE} -F filename ublk_drv - OUTPUT_VARIABLE _ublk_drv_path ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _ublk_modinfo_rc) - if(_ublk_modinfo_rc EQUAL 0 AND _ublk_drv_path) - set(UBLK_KERNEL_SUPPORTED ON) - set(UBLK_SUPPORT_REASON "ublk_drv module ${_ublk_drv_path}") - endif() +add_library(registryfs_lib STATIC + src/overlaybd/registryfs/registryfs.cpp + src/overlaybd/registryfs/registryfs_v2.cpp +) +target_link_libraries(registryfs_lib PUBLIC external_lib) + +add_library(lsmt_lib STATIC + src/overlaybd/lsmt/file.cpp + src/overlaybd/lsmt/index.cpp +) +target_link_libraries(lsmt_lib PUBLIC external_lib) + +# crc32c.cpp is the only source built for a specific ISA extension, hence its +# own library rather than compile options on zfile_lib as a whole. It is also +# the only one compiled as C++17: the DML headers behind the DSA backend use +# `if constexpr` and the `_v` type traits, which are C++17-only. Everything +# else stays on the CMAKE_CXX_STANDARD set above. +add_library(crc32_lib STATIC src/overlaybd/zfile/crc32/crc32c.cpp) +set_target_properties(crc32_lib PROPERTIES CXX_STANDARD 17) +target_link_libraries(crc32_lib PUBLIC external_lib) +if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) + target_compile_options(crc32_lib PUBLIC -msse4.2 -mcrc32) endif() -# (b) fallback: the module file ships under /lib/modules/$(uname -r) -if(NOT UBLK_KERNEL_SUPPORTED) - execute_process(COMMAND uname -r OUTPUT_VARIABLE _ublk_krel - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(_ublk_krel) - file(GLOB _ublk_drv_ko "/lib/modules/${_ublk_krel}/kernel/drivers/block/ublk_drv.ko*") - if(_ublk_drv_ko) - set(UBLK_KERNEL_SUPPORTED ON) - set(UBLK_SUPPORT_REASON "ublk_drv module ${_ublk_drv_ko}") +add_library(zfile_lib STATIC + src/overlaybd/zfile/compressor.cpp + src/overlaybd/zfile/zfile.cpp + src/overlaybd/zfile/lz4/lz4.c +) +target_link_libraries(zfile_lib PUBLIC external_lib crc32_lib ZSTD::zstd) + +add_library(zstd_lib STATIC src/overlaybd/zstd/zstdfile.cpp) +target_link_libraries(zstd_lib PUBLIC external_lib ZSTD::zstd) + +add_library(gzip_lib STATIC src/overlaybd/gzip/gz.cpp) +target_link_libraries(gzip_lib PUBLIC external_lib checksum_lib) + +add_library(gzindex_lib STATIC + src/overlaybd/gzindex/gzfile.cpp + src/overlaybd/gzindex/gzip_index_create.cpp +) +target_link_libraries(gzindex_lib PUBLIC external_lib) + +# The generic cache layers live in photon, only the gzip one is ours +add_library(gzip_cache_lib STATIC src/overlaybd/gzip_cache/cached_fs.cpp) +target_link_libraries(gzip_cache_lib PUBLIC external_lib gzindex_lib) + +# EROFS::utils propagates its include dir and the "-include config.h" compile +# option, and orders erofs_lib after the erofs-utils build +add_library(erofs_lib STATIC + src/overlaybd/tar/erofs/erofs_common.cpp + src/overlaybd/tar/erofs/erofs_fs.cpp + src/overlaybd/tar/erofs/liberofs.cpp +) +target_link_libraries(erofs_lib PUBLIC external_lib PRIVATE EROFS::utils) + +add_library(tar_lib STATIC + src/overlaybd/tar/header.cpp + src/overlaybd/tar/libtar.cpp + src/overlaybd/tar/tar_file.cpp + src/overlaybd/tar/whiteout.cpp +) +target_link_libraries(tar_lib PUBLIC external_lib PRIVATE erofs_lib) + +#--------------------------------------------------------------------- +# Optional acceleration backends +#--------------------------------------------------------------------- +if(ENABLE_QAT) + find_path(QAT_INCLUDE_DIR NAMES qat/cpa.h PATHS /usr/include/qat /usr/local/include/qat) + find_library(QAT_LIBRARY NAMES qat) + find_library(USDM_LIBRARY NAMES usdm) + if(NOT (QAT_INCLUDE_DIR AND QAT_LIBRARY AND USDM_LIBRARY)) + message(FATAL_ERROR "ENABLE_QAT=on but the QAT headers/libraries were not found") endif() - endif() + target_sources(zfile_lib PRIVATE src/overlaybd/zfile/lz4/lz4-qat.cpp) + target_compile_definitions(zfile_lib PUBLIC ENABLE_QAT) + target_include_directories(zfile_lib PUBLIC ${QAT_INCLUDE_DIR}) + target_link_libraries(zfile_lib PUBLIC ${QAT_LIBRARY} ${USDM_LIBRARY} pci) endif() -# (c) fallback: the ublk uapi header is installed (kernel-headers >= 6.0) -if(NOT UBLK_KERNEL_SUPPORTED) - find_path(UBLK_CMD_HEADER NAMES linux/ublk_cmd.h) - if(UBLK_CMD_HEADER) - set(UBLK_KERNEL_SUPPORTED ON) - set(UBLK_SUPPORT_REASON "uapi header ${UBLK_CMD_HEADER}/linux/ublk_cmd.h") - endif() +# DML and isa-l bring their own autotools/cmake builds, driven here at build +# time and consumed from the output directory they are told to install into. +if(ENABLE_DSA OR ENABLE_ISAL) + set(THIRDPARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/overlaybd/zfile/thirdparty") + add_custom_target(thirdparty_lib) + target_link_directories(crc32_lib PUBLIC ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + target_include_directories(crc32_lib PUBLIC ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/include) + add_dependencies(crc32_lib thirdparty_lib) +endif() +if(ENABLE_DSA) + add_custom_command(TARGET thirdparty_lib + WORKING_DIRECTORY ${THIRDPARTY_DIR}/DML + COMMAND git checkout 5a2956362d7b1c65d8aee753938ae9bf5cf0b7fd + COMMAND rm -rf build && mkdir build + COMMAND cd build && cmake -DCMAKE_INSTALL_PREFIX=dmldir .. && cmake --build . --target install + COMMAND cd build/dmldir && find ./ -name "libdml*.a" | xargs -i cp {} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ + COMMAND cp -r build/dmldir/include ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ + ) + target_compile_definitions(crc32_lib PUBLIC ENABLE_DSA) + target_link_libraries(crc32_lib PUBLIC pci dmlhl) +endif() +if(ENABLE_ISAL) + add_custom_command(TARGET thirdparty_lib + WORKING_DIRECTORY ${THIRDPARTY_DIR}/isa-l + COMMAND git checkout ad8dce15c6d3f0c7f3d1b486d9c649ed39223b45 + COMMAND ./autogen.sh && ./configure && make + COMMAND cp .libs/libisal.a ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ + COMMAND mkdir -p ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/include + COMMAND cp include/crc.h ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/include/ + ) + target_compile_definitions(crc32_lib PUBLIC ENABLE_ISAL) + target_compile_options(crc32_lib PUBLIC -mavx512f) + target_link_libraries(crc32_lib PUBLIC isal) endif() -# Building the frontend additionally requires autotools on the build machine. -option(BUILD_UBLK_FRONTEND "Build the ublk frontend (overlaybd-ublk); auto-detected from kernel ublk support, requires autotools" ${UBLK_KERNEL_SUPPORTED}) +# overlaybd_lib - the aggregate every binary links against +add_library(overlaybd_lib INTERFACE) +target_link_libraries(overlaybd_lib INTERFACE + external_lib + registryfs_lib + lsmt_lib + zfile_lib + zstd_lib + gzip_cache_lib + tar_lib + gzip_lib + gzindex_lib +) -if(BUILD_UBLK_FRONTEND) - message(STATUS "ublk frontend: ON (kernel ublk support: ${UBLK_SUPPORT_REASON})") -else() - message(STATUS "ublk frontend: OFF (kernel ublk support: ${UBLK_SUPPORT_REASON}; force with -DBUILD_UBLK_FRONTEND=on)") +add_library(overlaybd_image_lib STATIC + src/image_file.cpp + src/image_service.cpp + src/switch_file.cpp + src/bk_download.cpp + src/prefetch.cpp + src/api_server.cpp + src/tools/comm_func.cpp +) +target_link_libraries(overlaybd_image_lib PUBLIC + overlaybd_lib + checksum_lib + # image_file.cpp, prefetch.cpp and comm_func.cpp go through photon's extfs + E2FSPROGS::libext2fs +) + +# Propagate the resize .o files to all consumers of overlaybd_image_lib. These +# provide the resize_fs() symbol needed by photon's resize_extfs(). +if(NOT ORIGIN_EXT2FS) + set_source_files_properties( + ${E2FS_RESIZE_DIR}/resize2fs.o + ${E2FS_RESIZE_DIR}/extent.o + ${E2FS_RESIZE_DIR}/resource_track.o + PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE) + target_link_libraries(overlaybd_image_lib PUBLIC + ${E2FS_RESIZE_DIR}/resize2fs.o + ${E2FS_RESIZE_DIR}/extent.o + ${E2FS_RESIZE_DIR}/resource_track.o + ) + add_dependencies(overlaybd_image_lib libext2fs_build) endif() -find_package(e2fs REQUIRED) -find_package(photon REQUIRED) -find_package(tcmu REQUIRED) +#--------------------------------------------------------------------- +# Executables +#--------------------------------------------------------------------- +add_executable(overlaybd-tcmu src/main.cpp) +target_include_directories(overlaybd-tcmu PRIVATE ${TCMU_INCLUDE_DIR}) +target_link_libraries(overlaybd-tcmu overlaybd_image_lib TCMU::tcmu) -if(BUILD_UBLK_FRONTEND) - find_package(liburing REQUIRED) - find_package(ublksrv REQUIRED) +add_executable(overlaybd-commit src/tools/overlaybd-commit.cpp) +target_link_libraries(overlaybd-commit overlaybd_image_lib) + +add_executable(overlaybd-merge src/tools/overlaybd-merge.cpp) +target_link_libraries(overlaybd-merge overlaybd_image_lib) + +# overlaybd-create.cpp goes through photon's extfs, the other tools reach it +# through overlaybd_image_lib +add_executable(overlaybd-create src/tools/overlaybd-create.cpp) +target_link_libraries(overlaybd-create overlaybd_lib ${E2FS_LIBEXT2FS_LINK}) + +add_executable(overlaybd-zfile src/tools/overlaybd-zfile.cpp) +target_link_libraries(overlaybd-zfile overlaybd_lib) + +add_executable(overlaybd-apply src/tools/overlaybd-apply.cpp src/tools/qcow2converter.cpp) +target_link_libraries(overlaybd-apply overlaybd_image_lib) + +add_executable(turboOCI-apply src/tools/turboOCI-apply.cpp) +target_link_libraries(turboOCI-apply overlaybd_image_lib) + +set(OVERLAYBD_TOOLS + overlaybd-commit + overlaybd-merge + overlaybd-create + overlaybd-zfile + overlaybd-apply + turboOCI-apply +) + +# overlaybd-resize: userspace ext4 resize for overlaybd images, only available +# with the libext2fs built here +if(NOT ORIGIN_EXT2FS) + add_executable(overlaybd-resize src/tools/overlaybd-resize.cpp) + target_link_libraries(overlaybd-resize overlaybd_image_lib) + list(APPEND OVERLAYBD_TOOLS overlaybd-resize) endif() if(BUILD_STREAM_CONVERTOR) - find_package(yaml-cpp) - if (NOT yaml-cpp_FOUND) - FetchContent_Declare( - yaml-cpp - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git - # 0.9.0 includes the missing include (PR #1310) required - # to build with GCC 15 (C23 default), e.g. on Azure Linux 4.0. - GIT_TAG yaml-cpp-0.9.0 - ) - FetchContent_MakeAvailable(yaml-cpp) - endif() + add_executable(overlaybd-streamConv src/overlaybd/stream_convertor/stream_conv.cpp) + target_link_libraries(overlaybd-streamConv + external_lib tar_lib gzip_lib gzindex_lib yaml-cpp) endif() -if(BUILD_TESTING) - enable_testing() - include(CTest) +# The tools are installed next to the libraries they may load at runtime. +set_target_properties(${OVERLAYBD_TOOLS} PROPERTIES + INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/../lib64") + +#--------------------------------------------------------------------- +# ublk frontend +# +# overlaybd-ublk serves a single device per process, overlaybd-ublkd serves +# all of them from one. libublksrv_static propagates its include dirs and +# liburing, so neither is spelled out here. +#--------------------------------------------------------------------- +if(BUILD_UBLK_FRONTEND) + add_library(ublk_frontend_lib STATIC + src/ublk/blkdev_hygiene.cpp + src/ublk/cli.cpp + src/ublk/config_patch.cpp + src/ublk/io_dispatch.cpp + src/ublk/pool_placeholder.cpp + src/ublk/ublk_device.cpp + src/ublk/ublkd_protocol.cpp + ) + target_link_libraries(ublk_frontend_lib PUBLIC overlaybd_image_lib libublksrv_static) + + add_executable(overlaybd-ublk src/ublk/main.cpp) + target_link_libraries(overlaybd-ublk ublk_frontend_lib) + + add_executable(overlaybd-ublkd src/ublk/ublkd_main.cpp) + target_link_libraries(overlaybd-ublkd ublk_frontend_lib) endif() -add_subdirectory(src) +#--------------------------------------------------------------------- +# baselayer - the empty ext4 image the tools start from +#--------------------------------------------------------------------- +add_custom_command( + OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ext4_64 + COMMAND tar -zxvf ${CMAKE_CURRENT_SOURCE_DIR}/baselayers/ext4_64.tar.gz + -C ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + VERBATIM +) +add_custom_target(baselayer ALL DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ext4_64) -add_subdirectory(baselayers) +#--------------------------------------------------------------------- +# Install +#--------------------------------------------------------------------- +install(TARGETS overlaybd-tcmu DESTINATION /opt/overlaybd/bin) +install(TARGETS ${OVERLAYBD_TOOLS} DESTINATION /opt/overlaybd/bin) +install(FILES src/example_config/overlaybd-tcmu.service DESTINATION /opt/overlaybd/) +if(BUILD_UBLK_FRONTEND) + install(TARGETS overlaybd-ublk overlaybd-ublkd DESTINATION /opt/overlaybd/bin) + install(FILES src/example_config/overlaybd-ublkd.service DESTINATION /opt/overlaybd/) +endif() +install(FILES src/example_config/cred.json DESTINATION /opt/overlaybd/) +install(FILES src/example_config/overlaybd.json DESTINATION /etc/overlaybd/) +install(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ext4_64 DESTINATION /opt/overlaybd/baselayers) +if(NOT ORIGIN_EXT2FS) + install(DIRECTORY ${LIBEXT2FS_INSTALL_DIR}/lib DESTINATION /opt/overlaybd/ USE_SOURCE_PERMISSIONS) +endif() -include(CMake/pack.cmake) +include(pack) + +#--------------------------------------------------------------------- +# Unit tests +#--------------------------------------------------------------------- +if(BUILD_TESTING) + enable_testing() + include(CTest) + add_subdirectory(test) +endif() diff --git a/baselayers/CMakeLists.txt b/baselayers/CMakeLists.txt deleted file mode 100644 index 7e7d7f54..00000000 --- a/baselayers/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_custom_command( - OUTPUT ${EXECUTABLE_OUTPUT_PATH}/ext4_64 - COMMAND tar -zxvf ${CMAKE_CURRENT_LIST_DIR}/ext4_64.tar.gz -C ${EXECUTABLE_OUTPUT_PATH} - VERBATIM -) - -add_custom_target(baselayer ALL DEPENDS ${EXECUTABLE_OUTPUT_PATH}/ext4_64) - -install(FILES ${EXECUTABLE_OUTPUT_PATH}/ext4_64 DESTINATION /opt/overlaybd/baselayers) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 552a3481..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -find_package(CURL REQUIRED) -find_package(OpenSSL REQUIRED) -find_package(aio REQUIRED) -find_package(RapidJSON REQUIRED MODULE) - -link_libraries(rt pthread resolv) - -add_subdirectory(overlaybd) - -add_library(overlaybd_image_lib - image_file.cpp - image_service.cpp - switch_file.cpp - bk_download.cpp - prefetch.cpp - tools/sha256file.cpp - tools/comm_func.cpp - api_server.cpp -) -target_include_directories(overlaybd_image_lib PUBLIC - ${CURL_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} - ${PHOTON_INCLUDE_DIR} -) - -target_link_libraries(overlaybd_image_lib - photon_static - overlaybd_lib - ${CURL_LIBRARIES} - ${OPENSSL_SSL_LIBRARY} - ${OPENSSL_CRYPTO_LIBRARY} - ${AIO_LIBRARIES} -) - -# Propagate resize .o files to all consumers of overlaybd_image_lib. -# These provide the resize_fs() symbol needed by photon's resize_extfs(). -if (NOT ORIGIN_EXT2FS) - target_link_libraries(overlaybd_image_lib - ${E2FS_RESIZE_DIR}/resize2fs.o - ${E2FS_RESIZE_DIR}/extent.o - ${E2FS_RESIZE_DIR}/resource_track.o - ${E2FS_LIBRARIES} - ) - add_dependencies(overlaybd_image_lib libext2fs_build) -endif() - -add_executable(overlaybd-tcmu - main.cpp -) -target_include_directories(overlaybd-tcmu PUBLIC - ${TCMU_INCLUDE_DIR} - ${CURL_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} - ${PHOTON_INCLUDE_DIR} -) -target_link_libraries(overlaybd-tcmu - photon_static - overlaybd_lib - overlaybd_image_lib - tcmu_static - ${CURL_LIBRARIES} - ${OPENSSL_SSL_LIBRARY} - ${OPENSSL_CRYPTO_LIBRARY} - ${AIO_LIBRARIES} -) - -install(TARGETS overlaybd-tcmu DESTINATION /opt/overlaybd/bin) -install(FILES example_config/overlaybd-tcmu.service DESTINATION /opt/overlaybd/) -install(FILES example_config/overlaybd.json DESTINATION /etc/overlaybd/) -install(FILES example_config/cred.json DESTINATION /opt/overlaybd/) -if (NOT ORIGIN_EXT2FS) - install(DIRECTORY ${LIBEXT2FS_INSTALL_DIR}/lib DESTINATION /opt/overlaybd/ USE_SOURCE_PERMISSIONS) -endif() - -add_subdirectory(tools) -if (BUILD_UBLK_FRONTEND) - add_subdirectory(ublk) -endif () -if (BUILD_TESTING) - add_subdirectory(test) -endif () diff --git a/src/overlaybd/CMakeLists.txt b/src/overlaybd/CMakeLists.txt deleted file mode 100644 index 1efc09ce..00000000 --- a/src/overlaybd/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -add_subdirectory(registryfs) -add_subdirectory(lsmt) -add_subdirectory(zfile) -add_subdirectory(zstd) -add_subdirectory(gzip_cache) -add_subdirectory(tar) -add_subdirectory(gzip) -add_subdirectory(gzindex) - -if(BUILD_STREAM_CONVERTOR) - add_subdirectory(stream_convertor) -endif() - -add_library(overlaybd_lib INTERFACE) -target_include_directories(overlaybd_lib INTERFACE - ${PHOTON_INCLUDE_DIR} -) -target_link_libraries(overlaybd_lib INTERFACE - photon_static - registryfs_lib - lsmt_lib - zfile_lib - zstd_lib - gzip_cache_lib - tar_lib - gzip_lib - gzindex_lib -) diff --git a/src/overlaybd/gzindex/CMakeLists.txt b/src/overlaybd/gzindex/CMakeLists.txt deleted file mode 100644 index 0ccd496f..00000000 --- a/src/overlaybd/gzindex/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -file(GLOB SOURCE_TAR "*.cpp") -add_library(gzindex_lib STATIC ${SOURCE_TAR}) - -target_include_directories(gzindex_lib PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(gzindex_lib photon_static) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() diff --git a/src/overlaybd/gzindex/test/CMakeLists.txt b/src/overlaybd/gzindex/test/CMakeLists.txt deleted file mode 100644 index 4aebd196..00000000 --- a/src/overlaybd/gzindex/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -add_executable(gzindex_test test.cpp) -target_include_directories(gzindex_test PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(gzindex_test gtest gtest_main gflags pthread photon_static - gzindex_lib gzip_lib gzip_cache_lib photon_cache_lib checksum_lib) - -add_test( - NAME gzindex_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/gzindex_test -) diff --git a/src/overlaybd/gzip/CMakeLists.txt b/src/overlaybd/gzip/CMakeLists.txt deleted file mode 100644 index b5555c87..00000000 --- a/src/overlaybd/gzip/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -file(GLOB SOURCE_GZIP "*.cpp") - -add_library(gzip_lib STATIC ${SOURCE_GZIP}) -target_include_directories(gzip_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) -target_link_libraries(gzip_lib photon_static checksum_lib) - -# if(BUILD_TESTING) -# add_subdirectory(test) -# endif() diff --git a/src/overlaybd/gzip_cache/CMakeLists.txt b/src/overlaybd/gzip_cache/CMakeLists.txt deleted file mode 100644 index 3a87fdde..00000000 --- a/src/overlaybd/gzip_cache/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -file(GLOB SRC_FRONTEND "*.cpp") - -add_library(gzip_cache_lib STATIC ${SRC_FRONTEND}) -target_link_libraries(gzip_cache_lib - gzindex_lib - photon_static -) -target_include_directories(gzip_cache_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) diff --git a/src/overlaybd/lsmt/CMakeLists.txt b/src/overlaybd/lsmt/CMakeLists.txt deleted file mode 100644 index 24d5e5b1..00000000 --- a/src/overlaybd/lsmt/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -file(GLOB SOURCE_LSMT "*.cpp") - -add_library(lsmt_lib STATIC ${SOURCE_LSMT}) -target_include_directories(lsmt_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() diff --git a/src/overlaybd/lsmt/test/CMakeLists.txt b/src/overlaybd/lsmt/test/CMakeLists.txt deleted file mode 100644 index 8e28ef6b..00000000 --- a/src/overlaybd/lsmt/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -add_executable(lsmt_test test.cpp) -target_include_directories(lsmt_test PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(lsmt_test gtest gtest_main gflags pthread photon_static overlaybd_lib) - -add_test( - NAME lsmt_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/lsmt_test -) - diff --git a/src/overlaybd/registryfs/CMakeLists.txt b/src/overlaybd/registryfs/CMakeLists.txt deleted file mode 100644 index a7f59e16..00000000 --- a/src/overlaybd/registryfs/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -file(GLOB SOURCE_REGISTRYFS "*.cpp") - -find_package(CURL REQUIRED) - -add_library(registryfs_lib STATIC ${SOURCE_REGISTRYFS}) -target_include_directories(registryfs_lib PUBLIC - ${CURL_INCLUDE_DIRS} - ${RAPIDJSON_INCLUDE_DIRS} - ${PHOTON_INCLUDE_DIR} -) diff --git a/src/overlaybd/stream_convertor/CMakeLists.txt b/src/overlaybd/stream_convertor/CMakeLists.txt deleted file mode 100644 index 19f1acd1..00000000 --- a/src/overlaybd/stream_convertor/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -file(GLOB SOURCE_SERV "*.cpp") - -add_executable(overlaybd-streamConv ${SOURCE_SERV}) -target_include_directories(overlaybd-streamConv PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) -target_link_libraries(overlaybd-streamConv - photon_static - gzip_lib - gzindex_lib - tar_lib - yaml-cpp -) - -# if(BUILD_TESTING) -# add_subdirectory(test) -# endif() diff --git a/src/overlaybd/tar/CMakeLists.txt b/src/overlaybd/tar/CMakeLists.txt deleted file mode 100644 index a3eb8ed0..00000000 --- a/src/overlaybd/tar/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -file(GLOB SOURCE_TAR "*.cpp") - -add_library(tar_lib STATIC ${SOURCE_TAR}) -target_include_directories(tar_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() - -add_subdirectory(erofs) -target_link_libraries(tar_lib PRIVATE erofs_lib) \ No newline at end of file diff --git a/src/overlaybd/tar/erofs/CMakeLists.txt b/src/overlaybd/tar/erofs/CMakeLists.txt deleted file mode 100644 index 57d5b762..00000000 --- a/src/overlaybd/tar/erofs/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -include(FetchContent) - -FetchContent_Declare( - erofs-utils - GIT_REPOSITORY https://github.com/erofs/erofs-utils.git - GIT_TAG eec6f7a2755dfccc8f655aa37cf6f26db9164e60 -) - -FetchContent_MakeAvailable(erofs-utils) - -execute_process( - COMMAND ./autogen.sh - WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} -) -execute_process( - COMMAND ./configure --disable-lz4 --disable-lzma --without-libzstd --without-uuid --disable-multithreading - WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} -) -execute_process( - COMMAND make - WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} -) - -set(EROFS_LIB_INCLUDE_DIR "${erofs-utils_SOURCE_DIR}/include/" CACHE PATH "erofs-utils include path.") -set(EROFS_CONFIG_FILE "${erofs-utils_SOURCE_DIR}/config.h" CACHE PATH "erofs-utils config file.") -set(EROFS_LIB_STATIC "${erofs-utils_SOURCE_DIR}/lib/.libs/liberofs.a" CACHE PATH "erofs-utils static lib.") - -file(GLOB EROFS_SOURCE "*.cpp") - -add_library(erofs_lib STATIC ${EROFS_SOURCE}) - -target_include_directories(erofs_lib PRIVATE - ${PHOTON_INCLUDE_DIR} -) - -target_include_directories(erofs_lib PRIVATE - ${EROFS_LIB_INCLUDE_DIR} -) - -target_compile_options(erofs_lib PRIVATE "-include${EROFS_CONFIG_FILE}") -target_link_libraries(erofs_lib PRIVATE ${EROFS_LIB_STATIC}) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() diff --git a/src/overlaybd/tar/erofs/test/CMakeLists.txt b/src/overlaybd/tar/erofs/test/CMakeLists.txt deleted file mode 100644 index 0c10f34d..00000000 --- a/src/overlaybd/tar/erofs/test/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -# erofs simple test -add_executable(erofs_simple_test erofs_simple.cpp) -target_include_directories(erofs_simple_test PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(erofs_simple_test gtest gtest_main pthread photon_static - tar_lib lsmt_lib gzip_lib gzindex_lib checksum_lib overlaybd_image_lib) - -target_include_directories(erofs_simple_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) - -add_test( - NAME erofs_simple_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/erofs_simple_test -) - -# erofs stress test -add_executable(erofs_stress_test erofs_stress.cpp erofs_stress_base.cpp) -target_include_directories(erofs_stress_test PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(erofs_stress_test gtest gtest_main pthread photon_static - tar_lib lsmt_lib gzip_lib gzindex_lib checksum_lib overlaybd_image_lib) - -target_include_directories(erofs_stress_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) - -add_test( - NAME erofs_stress_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/erofs_stress_test -) diff --git a/src/overlaybd/tar/test/CMakeLists.txt b/src/overlaybd/tar/test/CMakeLists.txt deleted file mode 100644 index 21499419..00000000 --- a/src/overlaybd/tar/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -add_executable(untar_test test.cpp) -target_include_directories(untar_test PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(untar_test gtest gtest_main pthread photon_static - tar_lib lsmt_lib gzip_lib gzindex_lib checksum_lib) - -add_test( - NAME untar_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/untar_test -) diff --git a/src/overlaybd/zfile/CMakeLists.txt b/src/overlaybd/zfile/CMakeLists.txt deleted file mode 100644 index 7422d5c2..00000000 --- a/src/overlaybd/zfile/CMakeLists.txt +++ /dev/null @@ -1,72 +0,0 @@ -file(GLOB SOURCE_ZFILE "*.cpp") -file(GLOB SOURCE_LZ4 "lz4/*.c" "lz4/*.cpp") -file(GLOB SOURCE_CRC32 "crc32/crc32c.cpp") - -set (CMAKE_CXX_STANDARD 17) -add_library(crc32_lib STATIC ${SOURCE_CRC32}) -target_include_directories(crc32_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) - -if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) - target_compile_options(crc32_lib PUBLIC -msse4.2 -mcrc32) -else() - if (NOT CMAKE_CXX_FLAGS MATCHES "-march=|-mcpu=") - check_cxx_compiler_flag(-mcpu=native COMPILER_HAS_NATIVE_FLAG) - if (COMPILER_HAS_NATIVE_FLAG) - target_compile_options(crc32_lib PRIVATE -mcpu=native) - else () - target_compile_options(crc32_lib PRIVATE -mcpu=generic+crc) - endif () - endif () -endif() - -if(ENABLE_DSA OR ENABLE_ISAL) - add_subdirectory(thirdparty) - add_dependencies(crc32_lib thirdparty_lib) - target_link_directories(crc32_lib PUBLIC ${LIBRARY_OUTPUT_PATH}) - target_include_directories(crc32_lib PUBLIC ${LIBRARY_OUTPUT_PATH}/include) - if(ENABLE_DSA) - target_link_libraries(crc32_lib -lpci -ldmlhl -ldl) - target_compile_definitions(crc32_lib PUBLIC -DENABLE_DSA) - endif() - if(ENABLE_ISAL) - target_compile_options(crc32_lib PUBLIC -mavx512f) - target_compile_definitions(crc32_lib PUBLIC -DENABLE_ISAL) - target_link_libraries(crc32_lib -lisal) - endif() -endif() -set (CMAKE_CXX_STANDARD 14) - -# ---- QAT auto-detection ---- -if (ENABLE_QAT) - find_path(QAT_INCLUDE_DIR NAMES qat/cpa.h - PATHS /usr/include/qat /usr/local/include/qat) - find_library(QAT_LIBRARY NAMES qat) - find_library(USDM_LIBRARY NAMES usdm) - if (QAT_INCLUDE_DIR AND QAT_LIBRARY AND USDM_LIBRARY) - message(STATUS "QAT acceleration: ENABLED (include=${QAT_INCLUDE_DIR})") - else() - message(WARNING "ENABLE_QAT=ON but QAT headers/libs not found; disabling QAT") - set(ENABLE_QAT OFF) - endif() -endif() -if (NOT ENABLE_QAT) - # When QAT is off, exclude lz4-qat.cpp so we don't need QAT headers at all - list(REMOVE_ITEM SOURCE_LZ4 "${CMAKE_CURRENT_SOURCE_DIR}/lz4/lz4-qat.cpp") - message(STATUS "QAT acceleration: DISABLED") -endif() -# -------------------------------- - -add_library(zfile_lib STATIC ${SOURCE_ZFILE} ${SOURCE_LZ4}) -target_link_libraries(zfile_lib photon_static crc32_lib ${LIBZSTD}) - -if (ENABLE_QAT) - target_compile_definitions(zfile_lib PUBLIC -DENABLE_QAT) - target_include_directories(zfile_lib PUBLIC ${QAT_INCLUDE_DIR}) - target_link_libraries(zfile_lib ${QAT_LIBRARY} ${USDM_LIBRARY} -lpci -lpthread) -endif() - -if (BUILD_TESTING) - add_subdirectory(test) -endif () diff --git a/src/overlaybd/zfile/test/CMakeLists.txt b/src/overlaybd/zfile/test/CMakeLists.txt deleted file mode 100644 index 4303a6d8..00000000 --- a/src/overlaybd/zfile/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ - -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -add_executable(zfile_test ./test.cpp) - -target_link_libraries(zfile_test gtest gtest_main gflags pthread photon_static overlaybd_lib) -target_include_directories(zfile_test PUBLIC ${PHOTON_INCLUDE_DIR}) -add_test( - NAME zfile_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/zfile_test -) \ No newline at end of file diff --git a/src/overlaybd/zfile/thirdparty/CMakeLists.txt b/src/overlaybd/zfile/thirdparty/CMakeLists.txt deleted file mode 100644 index 4dec6f2a..00000000 --- a/src/overlaybd/zfile/thirdparty/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_custom_target(thirdparty_lib) -set(THIRDPARTY_PATH "${CMAKE_SOURCE_DIR}/src/overlaybd/zfile/thirdparty") - -if(ENABLE_DSA) - add_custom_command(TARGET thirdparty_lib - COMMAND cd ${THIRDPARTY_PATH}/DML && git checkout 5a2956362d7b1c65d8aee753938ae9bf5cf0b7fd - COMMAND cd ${THIRDPARTY_PATH}/DML && rm -rf build && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=dmldir .. - COMMAND cd ${THIRDPARTY_PATH}/DML/build && cmake --build . --target install - COMMAND cd ${THIRDPARTY_PATH}/DML/build/dmldir && find ./ -name "libdml*.a" | xargs -i cp {} ${LIBRARY_OUTPUT_PATH}/; - COMMAND cp -r ${THIRDPARTY_PATH}/DML/build/dmldir/include ${LIBRARY_OUTPUT_PATH}/ - ) -endif() - -if(ENABLE_ISAL) - add_custom_command(TARGET thirdparty_lib - COMMAND cd ${THIRDPARTY_PATH}/isa-l && git checkout ad8dce15c6d3f0c7f3d1b486d9c649ed39223b45 - COMMAND cd ${THIRDPARTY_PATH}/isa-l && ./autogen.sh - COMMAND cd ${THIRDPARTY_PATH}/isa-l && ./configure - COMMAND cd ${THIRDPARTY_PATH}/isa-l && make - COMMAND cp -r ${THIRDPARTY_PATH}/isa-l/.libs/libisal.a ${LIBRARY_OUTPUT_PATH}/ - COMMAND mkdir -p ${LIBRARY_OUTPUT_PATH}/include && cp ${THIRDPARTY_PATH}/isa-l/include/crc.h ${LIBRARY_OUTPUT_PATH}/include/ - ) -endif() \ No newline at end of file diff --git a/src/overlaybd/zstd/CMakeLists.txt b/src/overlaybd/zstd/CMakeLists.txt deleted file mode 100644 index 68535cd4..00000000 --- a/src/overlaybd/zstd/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -file(GLOB SOURCE_ZSTD "*.cpp") - -add_library(zstd_lib STATIC ${SOURCE_ZSTD}) - -target_include_directories(zstd_lib PUBLIC - ${PHOTON_INCLUDE_DIR} -) - -target_link_libraries(zstd_lib photon_static ${LIBZSTD}) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt deleted file mode 100644 index 7fa107e5..00000000 --- a/src/test/CMakeLists.txt +++ /dev/null @@ -1,76 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -add_executable(image_service_test image_service_test.cpp) -target_include_directories(image_service_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) -target_link_libraries(image_service_test gtest gtest_main gflags pthread photon_static overlaybd_lib overlaybd_image_lib) - -add_test( - NAME image_service_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/image_service_test -) - - -add_executable(simple_credsrv_test simple_credsrv_test.cpp) -add_test( - NAME simple_credsrv_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/simple_credsrv_test -) -target_link_libraries(simple_credsrv_test -overlaybd_image_lib -photon_static -rt -resolv -aio -pthread -gtest -) - -target_include_directories(simple_credsrv_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} - $ENV{GTEST}/googletest/include -) - -add_executable(trace_test trace_test.cpp ../tools/comm_func.cpp) -target_include_directories(trace_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) -target_link_libraries(trace_test gtest gtest_main gflags pthread photon_static overlaybd_lib overlaybd_image_lib) - -add_test( - NAME trace_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/trace_test -) - -if (NOT ORIGIN_EXT2FS) - set_source_files_properties( - ${E2FS_RESIZE_DIR}/resize2fs.o - ${E2FS_RESIZE_DIR}/extent.o - ${E2FS_RESIZE_DIR}/resource_track.o - PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE) - add_executable(resize_test - resize_test.cpp - ${E2FS_RESIZE_DIR}/resize2fs.o - ${E2FS_RESIZE_DIR}/extent.o - ${E2FS_RESIZE_DIR}/resource_track.o - ) - target_include_directories(resize_test PUBLIC - ${PHOTON_INCLUDE_DIR} - ${E2FS_INCLUDE_DIRS} - ${E2FS_RESIZE_DIR} - ) - target_link_libraries(resize_test gtest pthread photon_static ${E2FS_LIBRARIES}) - add_dependencies(resize_test libext2fs_build) - add_test( - NAME resize_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/resize_test - ) -endif() diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt deleted file mode 100644 index 43c13733..00000000 --- a/src/tools/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -add_executable(overlaybd-commit overlaybd-commit.cpp) -target_include_directories(overlaybd-commit PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(overlaybd-commit photon_static overlaybd_image_lib) - -add_executable(overlaybd-merge overlaybd-merge.cpp) -target_include_directories(overlaybd-merge PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(overlaybd-merge photon_static overlaybd_image_lib) - - -add_executable(overlaybd-create overlaybd-create.cpp) -target_include_directories(overlaybd-create PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(overlaybd-create photon_static overlaybd_lib) -set_target_properties(overlaybd-create PROPERTIES INSTALL_RPATH "/opt/overlaybd/lib") - -add_executable(overlaybd-zfile overlaybd-zfile.cpp) -target_include_directories(overlaybd-zfile PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(overlaybd-zfile photon_static overlaybd_lib) - -add_executable(overlaybd-apply overlaybd-apply.cpp qcow2converter.cpp) -target_include_directories(overlaybd-apply PUBLIC ${PHOTON_INCLUDE_DIR} ${RAPIDJSON_INCLUDE_DIRS}) -target_link_libraries(overlaybd-apply photon_static overlaybd_lib overlaybd_image_lib checksum_lib z) -set_target_properties(overlaybd-apply PROPERTIES INSTALL_RPATH "/opt/overlaybd/lib") - -add_executable(turboOCI-apply turboOCI-apply.cpp) -target_include_directories(turboOCI-apply PUBLIC ${PHOTON_INCLUDE_DIR} ${RAPIDJSON_INCLUDE_DIRS}) -target_link_libraries(turboOCI-apply photon_static overlaybd_lib overlaybd_image_lib) -set_target_properties(turboOCI-apply PROPERTIES INSTALL_RPATH "/opt/overlaybd/lib") - -add_library(checksum_lib sha256file.cpp) -target_include_directories(checksum_lib PUBLIC ${PHOTON_INCLUDE_DIR}) -target_link_libraries(checksum_lib photon_static) - -# overlaybd-resize: userspace ext4 resize for overlaybd images -if (NOT ORIGIN_EXT2FS) - add_executable(overlaybd-resize overlaybd-resize.cpp) - target_include_directories(overlaybd-resize PUBLIC ${PHOTON_INCLUDE_DIR}) - target_link_libraries(overlaybd-resize photon_static overlaybd_image_lib) - set_target_properties(overlaybd-resize PROPERTIES INSTALL_RPATH "/opt/overlaybd/lib") -endif() - -install(TARGETS - overlaybd-commit - overlaybd-create - overlaybd-zfile - overlaybd-apply - overlaybd-merge - - turboOCI-apply - DESTINATION /opt/overlaybd/bin -) - -if (NOT ORIGIN_EXT2FS) - install(TARGETS overlaybd-resize DESTINATION /opt/overlaybd/bin) -endif() diff --git a/src/ublk/CMakeLists.txt b/src/ublk/CMakeLists.txt deleted file mode 100644 index f6c65f99..00000000 --- a/src/ublk/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -# overlaybd-ublk: the ublk block device frontend (one process serves one device) -# Entered only when BUILD_UBLK_FRONTEND=on - -add_library(ublk_frontend_lib - io_dispatch.cpp - ublk_device.cpp - cli.cpp - config_patch.cpp - ublkd_protocol.cpp - pool_placeholder.cpp - blkdev_hygiene.cpp -) -target_include_directories(ublk_frontend_lib PUBLIC - ${PHOTON_INCLUDE_DIR} - ${RAPIDJSON_INCLUDE_DIRS} -) -target_link_libraries(ublk_frontend_lib - photon_static - overlaybd_image_lib - libublksrv_static # IMPORTED target; include dirs and liburing propagate via INTERFACE -) - -add_executable(overlaybd-ublk main.cpp) -target_link_libraries(overlaybd-ublk - ublk_frontend_lib - photon_static - overlaybd_image_lib - libublksrv_static - ${CURL_LIBRARIES} - ${OPENSSL_SSL_LIBRARY} - ${OPENSSL_CRYPTO_LIBRARY} - ${AIO_LIBRARIES} -) - -install(TARGETS overlaybd-ublk DESTINATION /opt/overlaybd/bin) - -# overlaybd-ublkd: daemon mode, all devices in one process -add_executable(overlaybd-ublkd ublkd_main.cpp) -target_link_libraries(overlaybd-ublkd - ublk_frontend_lib - photon_static - overlaybd_image_lib - libublksrv_static - ${CURL_LIBRARIES} - ${OPENSSL_SSL_LIBRARY} - ${OPENSSL_CRYPTO_LIBRARY} - ${AIO_LIBRARIES} -) -install(TARGETS overlaybd-ublkd DESTINATION /opt/overlaybd/bin) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../example_config/overlaybd-ublkd.service - DESTINATION /opt/overlaybd/) - -if (BUILD_TESTING) - add_subdirectory(test) -endif () diff --git a/src/ublk/test/CMakeLists.txt b/src/ublk/test/CMakeLists.txt deleted file mode 100644 index 10e5935e..00000000 --- a/src/ublk/test/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -include_directories($ENV{GFLAGS}/include) -link_directories($ENV{GFLAGS}/lib) - -include_directories($ENV{GTEST}/googletest/include) -link_directories($ENV{GTEST}/lib) - -# Compile only the sources under test instead of linking ublk_frontend_lib: -# io_dispatch/cli are pure logic decoupled from the event loop, so the tests -# need neither a ublk-capable kernel nor photon -add_executable(ublk_dispatch_test - ublk_dispatch_test.cpp - ../io_dispatch.cpp - ../cli.cpp - ../config_patch.cpp - ../ublkd_protocol.cpp -) -target_include_directories(ublk_dispatch_test PUBLIC - ${UBLKSRV_INCLUDE_DIRS} ${LIBURING_INCLUDE_DIRS} ${RAPIDJSON_INCLUDE_DIRS}) -target_link_libraries(ublk_dispatch_test gtest gtest_main pthread) - -add_test( - NAME ublk_dispatch_test - COMMAND ${EXECUTABLE_OUTPUT_PATH}/ublk_dispatch_test -) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..19464500 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,80 @@ +find_package(gtest REQUIRED) # GTEST::gtest +find_package(gflags REQUIRED) # GFLAGS::gflags + +set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) + +# Every test brings its own main(), gtest_main is deliberately not linked. +function(overlaybd_add_test name) + add_executable(${name} ${ARGN}) + target_link_libraries(${name} PRIVATE GTEST::gtest) + add_test(NAME ${name} COMMAND ${name}) +endfunction() + +overlaybd_add_test(lsmt_test ${SRC_DIR}/overlaybd/lsmt/test/test.cpp) +target_link_libraries(lsmt_test PRIVATE overlaybd_lib GFLAGS::gflags) + +overlaybd_add_test(zfile_test ${SRC_DIR}/overlaybd/zfile/test/test.cpp) +target_link_libraries(zfile_test PRIVATE overlaybd_lib GFLAGS::gflags) + +overlaybd_add_test(gzindex_test ${SRC_DIR}/overlaybd/gzindex/test/test.cpp) +target_link_libraries(gzindex_test PRIVATE gzindex_lib gzip_lib gzip_cache_lib checksum_lib) + +# test.cpp goes through photon's extfs +overlaybd_add_test(untar_test ${SRC_DIR}/overlaybd/tar/test/test.cpp) +target_link_libraries(untar_test PRIVATE + tar_lib lsmt_lib gzip_lib gzindex_lib checksum_lib ${E2FS_LIBEXT2FS_LINK}) + +overlaybd_add_test(erofs_simple_test ${SRC_DIR}/overlaybd/tar/erofs/test/erofs_simple.cpp) +target_link_libraries(erofs_simple_test PRIVATE overlaybd_image_lib) + +overlaybd_add_test(erofs_stress_test + ${SRC_DIR}/overlaybd/tar/erofs/test/erofs_stress.cpp + ${SRC_DIR}/overlaybd/tar/erofs/test/erofs_stress_base.cpp) +target_link_libraries(erofs_stress_test PRIVATE overlaybd_image_lib) + +overlaybd_add_test(image_service_test ${SRC_DIR}/test/image_service_test.cpp) +target_link_libraries(image_service_test PRIVATE overlaybd_image_lib) + +overlaybd_add_test(simple_credsrv_test ${SRC_DIR}/test/simple_credsrv_test.cpp) +target_link_libraries(simple_credsrv_test PRIVATE overlaybd_image_lib) + +overlaybd_add_test(trace_test ${SRC_DIR}/test/trace_test.cpp) +target_link_libraries(trace_test PRIVATE overlaybd_image_lib) + +# ublk_dispatch_test compiles the sources under test instead of linking +# ublk_frontend_lib: io_dispatch/cli are pure logic decoupled from the event +# loop, so the test needs neither a ublk-capable kernel nor photon. It is also +# the only test without its own main(), hence gtest_main. +if(BUILD_UBLK_FRONTEND) + overlaybd_add_test(ublk_dispatch_test + ${SRC_DIR}/ublk/test/ublk_dispatch_test.cpp + ${SRC_DIR}/ublk/cli.cpp + ${SRC_DIR}/ublk/config_patch.cpp + ${SRC_DIR}/ublk/io_dispatch.cpp + ${SRC_DIR}/ublk/ublkd_protocol.cpp) + target_include_directories(ublk_dispatch_test PRIVATE + ${UBLKSRV_INCLUDE_DIRS} ${LIBURING_INCLUDE_DIRS} ${RAPIDJSON_INCLUDE_DIRS}) + target_link_libraries(ublk_dispatch_test PRIVATE GTEST::gtest_main pthread) +endif() + +# resize_test drives resize2fs directly, so it needs the objects that +# overlaybd_image_lib only re-exports for photon's resize_extfs() +if(NOT ORIGIN_EXT2FS) + # These .o files are produced by the libext2fs_build step, so they are + # absent at configure time. The GENERATED/EXTERNAL_OBJECT properties are + # directory-scoped, hence set again here rather than inherited from the + # top-level CMakeLists.txt. + set_source_files_properties( + ${E2FS_RESIZE_DIR}/resize2fs.o + ${E2FS_RESIZE_DIR}/extent.o + ${E2FS_RESIZE_DIR}/resource_track.o + PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE) + overlaybd_add_test(resize_test + ${SRC_DIR}/test/resize_test.cpp + ${E2FS_RESIZE_DIR}/resize2fs.o + ${E2FS_RESIZE_DIR}/extent.o + ${E2FS_RESIZE_DIR}/resource_track.o) + target_include_directories(resize_test PRIVATE ${E2FS_INCLUDE_DIRS} ${E2FS_RESIZE_DIR}) + target_link_libraries(resize_test PRIVATE external_lib ${E2FS_LIBEXT2FS_LINK}) + add_dependencies(resize_test libext2fs_build) +endif() From 1af00e0d8e58e065850cf15e8df4004d048d4326 Mon Sep 17 00:00:00 2001 From: "zhuangbowei.zbw" Date: Mon, 7 Sep 2026 15:41:43 +0800 Subject: [PATCH 3/5] build: make the ocf cache backend optional Signed-off-by: zhuangbowei.zbw --- CMake/Findphoton.cmake | 38 +++++++++++++++++++++++--------------- CMakeLists.txt | 4 ++++ src/image_service.cpp | 7 +++++++ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/CMake/Findphoton.cmake b/CMake/Findphoton.cmake index 653aac99..59b56a45 100644 --- a/CMake/Findphoton.cmake +++ b/CMake/Findphoton.cmake @@ -13,7 +13,9 @@ if(NOT ORIGIN_EXT2FS) endif() # The OCF cache backend is part of photon, and so is the OCF checkout it needs. -set(PHOTON_BUILD_OCF_CACHE ON) +if(ENABLE_OCF_CACHE) + set(PHOTON_BUILD_OCF_CACHE ON) +endif() if(DEPENDENCY_PHOTON_REPOSITORY) FetchContent_Declare(photon @@ -48,16 +50,18 @@ if(DEPENDENCY_PHOTON_REPOSITORY) add_dependencies(photon_obj libext2fs_build) endif() - # photon's ocf targets include , which its own build resolves - # through a symlink pointing inside photon's build tree. That layout only - # exists when photon is built standalone, so provide the same include - # layout for the OCF checkout fetched as part of this build. - FetchContent_GetProperties(ocf_lib SOURCE_DIR OCF_SOURCE_DIR) - set(OCF_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/ocf-include) - file(MAKE_DIRECTORY ${OCF_INCLUDE_DIR}) - file(CREATE_LINK ${OCF_SOURCE_DIR}/inc ${OCF_INCLUDE_DIR}/ocf SYMBOLIC) - target_include_directories(ocf_lib PUBLIC ${OCF_INCLUDE_DIR}) - target_include_directories(ocf_cache_lib PUBLIC ${OCF_INCLUDE_DIR}) + if(ENABLE_OCF_CACHE) + # photon's ocf targets include , which its own build resolves + # through a symlink pointing inside photon's build tree. That layout only + # exists when photon is built standalone, so provide the same include + # layout for the OCF checkout fetched as part of this build. + FetchContent_GetProperties(ocf_lib SOURCE_DIR OCF_SOURCE_DIR) + set(OCF_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/ocf-include) + file(MAKE_DIRECTORY ${OCF_INCLUDE_DIR}) + file(CREATE_LINK ${OCF_SOURCE_DIR}/inc ${OCF_INCLUDE_DIR}/ocf SYMBOLIC) + target_include_directories(ocf_lib PUBLIC ${OCF_INCLUDE_DIR}) + target_include_directories(ocf_cache_lib PUBLIC ${OCF_INCLUDE_DIR}) + endif() # Consume photon as plain archives rather than through its photon_static # target: the latter also propagates photon's own third-party dependencies, @@ -68,8 +72,10 @@ if(DEPENDENCY_PHOTON_REPOSITORY) set(PHOTON_INCLUDE_DIR ${photon_SOURCE_DIR}/include/) set(PHOTON_LIBRARY ${photon_BINARY_DIR}/output/libphoton_sole.a) set(PHOTON_EASY_WEAK_LIBRARY ${photon_BINARY_DIR}/output/libeasy_weak.a) - set(PHOTON_OCF_LIBRARY ${photon_BINARY_DIR}/output/libocf_cache_lib.a) - set(PHOTON_OCF_CORE_LIBRARY ${photon_BINARY_DIR}/output/libocf_lib.a) + if(ENABLE_OCF_CACHE) + set(PHOTON_OCF_LIBRARY ${photon_BINARY_DIR}/output/libocf_cache_lib.a) + set(PHOTON_OCF_CORE_LIBRARY ${photon_BINARY_DIR}/output/libocf_lib.a) + endif() set(photon_FOUND yes) else() # A locally installed photon has no photon_BINARY_DIR, look the archives up @@ -79,8 +85,10 @@ else() find_path(PHOTON_INCLUDE_DIR photon/photon.h) find_library(PHOTON_LIBRARY NAMES photon_sole photon) find_library(PHOTON_EASY_WEAK_LIBRARY NAMES easy_weak) - find_library(PHOTON_OCF_LIBRARY NAMES ocf_cache_lib) - find_library(PHOTON_OCF_CORE_LIBRARY NAMES ocf_lib) + if(ENABLE_OCF_CACHE) + find_library(PHOTON_OCF_LIBRARY NAMES ocf_cache_lib) + find_library(PHOTON_OCF_CORE_LIBRARY NAMES ocf_lib) + endif() find_package_handle_standard_args(photon DEFAULT_MSG PHOTON_LIBRARY PHOTON_INCLUDE_DIR) diff --git a/CMakeLists.txt b/CMakeLists.txt index 382e3734..ffa7e397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ option(FULL_STATIC "make all binary output depends only libc dynamic libs" off) option(BUILD_CURL_FROM_SOURCE "Compile static libcurl" off) option(BUILD_STREAM_CONVERTOR "Build the stream convertor" on) option(ORIGIN_EXT2FS "Use original libext2fs" off) +option(ENABLE_OCF_CACHE "Build the OCF cache backend" on) option(ENABLE_QAT "Build the QAT compression backend" off) option(ENABLE_DSA "Build the DSA crc32 backend (requires the DML submodule)" off) option(ENABLE_ISAL "Build the ISA-L crc32 backend (requires the isa-l submodule)" off) @@ -420,6 +421,9 @@ target_link_libraries(overlaybd_image_lib PUBLIC # image_file.cpp, prefetch.cpp and comm_func.cpp go through photon's extfs E2FSPROGS::libext2fs ) +if(ENABLE_OCF_CACHE) + target_compile_definitions(overlaybd_image_lib PRIVATE ENABLE_OCF_CACHE) +endif() # Propagate the resize .o files to all consumers of overlaybd_image_lib. These # provide the resize_fs() symbol needed by photon's resize_extfs(). diff --git a/src/image_service.cpp b/src/image_service.cpp index 5b63937d..a5b2ef63 100644 --- a/src/image_service.cpp +++ b/src/image_service.cpp @@ -423,6 +423,11 @@ int ImageService::init() { if (cache_type != "file" && cache_type != "ocf" && cache_type != "download") { LOG_ERROR_RETURN(0, -1, "unknown cache type: `", cache_type); } +#ifndef ENABLE_OCF_CACHE + if (cache_type == "ocf") { + LOG_ERROR_RETURN(0, -1, "'ocf' cache is disabled in this build (ENABLE_OCF_CACHE=off)"); + } +#endif LOG_INFO("cache config: ", VALUE(cache_type), VALUE(cache_dir), VALUE(cache_size_GB), VALUE(refill_size)); @@ -477,6 +482,7 @@ int ImageService::init() { (uint64_t)1048576 * 1024, global_fs.io_alloc, 0, {nullptr, &cache_fn_trans_sha256}); } else if (cache_type == "ocf") { +#ifdef ENABLE_OCF_CACHE auto namespace_dir = std::string(cache_dir + "/namespace"); if (::access(namespace_dir.c_str(), F_OK) != 0 && ::mkdir(namespace_dir.c_str(), 0755) != 0) { LOG_ERRNO_RETURN(0, -1, "failed to create namespace_dir"); @@ -505,6 +511,7 @@ int ImageService::init() { global_fs.cached_fs = photon::fs::new_ocf_cached_fs( global_fs.srcfs, namespace_fs, block_size, refill_size, media_file, reload_media, global_fs.io_alloc); +#endif } else if (cache_type == "download") { global_fs.cached_fs = photon::fs::new_persistent_cached_fs( global_fs.srcfs, 4096, refill_size, global_fs.io_alloc); From b72abb9d4c41551c5c3c50170577d12947723c30 Mon Sep 17 00:00:00 2001 From: "zhuangbowei.zbw" Date: Thu, 10 Sep 2026 15:55:01 +0800 Subject: [PATCH 4/5] use photon::sha256 instead of OpenSSL SHA256_* Signed-off-by: zhuangbowei.zbw --- src/bk_download.cpp | 1 - src/overlaybd/registryfs/registryfs_v2.cpp | 11 ++++----- src/tools/comm_func.cpp | 1 - src/tools/sha256file.cpp | 27 +++++++--------------- 4 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/bk_download.cpp b/src/bk_download.cpp index 72e3e70e..d6153407 100644 --- a/src/bk_download.cpp +++ b/src/bk_download.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include "switch_file.h" diff --git a/src/overlaybd/registryfs/registryfs_v2.cpp b/src/overlaybd/registryfs/registryfs_v2.cpp index ca08322b..d78213bc 100644 --- a/src/overlaybd/registryfs/registryfs_v2.cpp +++ b/src/overlaybd/registryfs/registryfs_v2.cpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include @@ -548,7 +548,7 @@ IFileSystem *new_registryfs_v2(PasswordCB callback, const char *caFile, uint64_t class RegistryUploader : public VirtualFile { public: photon::semaphore m_sem, m_init_sem; - SHA256_CTX m_sha256_ctx = {0}; + photon::sha256 m_sha256; std::string m_sha256sum; std::thread m_upload_th; IFile *m_local_file; @@ -570,7 +570,6 @@ class RegistryUploader : public VirtualFile { m_timeout(timeout), m_tls_ctx(ctx) { if (upload_bs != -1) m_upload_chunk_size = upload_bs; - SHA256_Init(&m_sha256_ctx); } int init() { @@ -594,7 +593,7 @@ class RegistryUploader : public VirtualFile { } // calc sha256 result unsigned char sha[32]; - SHA256_Final(sha, &m_sha256_ctx); + m_sha256.finalize(sha); char res[SHA256_DIGEST_LENGTH * 2]; for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) sprintf(res + (i * 2), "%02x", sha[i]); @@ -634,9 +633,7 @@ class RegistryUploader : public VirtualFile { if (rc < 0) { LOG_ERRNO_RETURN(0, -1, "failed to write local file", VALUE(rc)); } - if (rc > 0 && SHA256_Update(&m_sha256_ctx, buf, rc) < 0) { - LOG_ERRNO_RETURN(0, -1, "sha256 calculate error"); - } + if (rc > 0) m_sha256.update(buf, rc); m_write_pos += rc; m_sem.signal(1); return rc; diff --git a/src/tools/comm_func.cpp b/src/tools/comm_func.cpp index 3c44ccc3..759709e1 100644 --- a/src/tools/comm_func.cpp +++ b/src/tools/comm_func.cpp @@ -16,7 +16,6 @@ #include "comm_func.h" #include "../overlaybd/tar/tar_file.h" -#include #include #include #include diff --git a/src/tools/sha256file.cpp b/src/tools/sha256file.cpp index 47ad7979..c1210cf9 100644 --- a/src/tools/sha256file.cpp +++ b/src/tools/sha256file.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "sha256file.h" #include #include @@ -13,12 +13,11 @@ using namespace std; class SHA256CheckedFile: public SHA256File { public: IFile *m_file; - SHA256_CTX ctx = {0}; + photon::sha256 m_sha256; size_t total_read = 0; bool m_ownership = false; SHA256CheckedFile(IFile *file, bool ownership): m_file(file), m_ownership(ownership) { - SHA256_Init(&ctx); } ~SHA256CheckedFile() { if (m_ownership) delete m_file; @@ -28,10 +27,7 @@ class SHA256CheckedFile: public SHA256File { } ssize_t read(void *buf, size_t count) override { auto rc = m_file->read(buf, count); - if (rc > 0 && SHA256_Update(&ctx, buf, rc) < 0) { - LOG_ERROR("sha256 calculate error"); - return -1; - } + if (rc > 0) m_sha256.update(buf, rc); return rc; } off_t lseek(off_t offset, int whence) override { @@ -45,15 +41,12 @@ class SHA256CheckedFile: public SHA256File { // if (rc == 64*1024) { // LOG_WARN("too much trailing data"); // } - if (rc > 0 && SHA256_Update(&ctx, buf, rc) < 0) { - LOG_ERROR("sha256 calculate error"); - return ""; - } + m_sha256.update(buf, rc); rc = m_file->read(buf, 64*1024); } // calc sha256 result unsigned char sha[32]; - SHA256_Final(sha, &ctx); + m_sha256.finalize(sha); char res[SHA256_DIGEST_LENGTH * 2]; for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) sprintf(res + (i * 2), "%02x", sha[i]); @@ -86,8 +79,7 @@ string sha256sum(const char *fn) { LOG_ERROR("failed to stat `", fn); return ""; } - SHA256_CTX ctx = {0}; - SHA256_Init(&ctx); + photon::sha256 digest; __attribute__((aligned(ALIGNMENT_4K))) char buffer[65536]; unsigned char sha[32]; ssize_t recv = 0; @@ -97,12 +89,9 @@ string sha256sum(const char *fn) { LOG_ERROR("io error: `", fn); return ""; } - if (SHA256_Update(&ctx, buffer, recv) < 0) { - LOG_ERROR("sha256 calculate error: `", fn); - return ""; - } + digest.update(buffer, recv); } - SHA256_Final(sha, &ctx); + digest.finalize(sha); char res[SHA256_DIGEST_LENGTH * 2 + 1]; for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) sprintf(res + (i * 2), "%02x", sha[i]); From 02dfb0da0cac6f093e010934347c7b5641a15e81 Mon Sep 17 00:00:00 2001 From: "zhuangbowei.zbw" Date: Mon, 7 Sep 2026 15:41:43 +0800 Subject: [PATCH 5/5] fix compiler warnings and build with -Wall -Werror Signed-off-by: zhuangbowei.zbw --- CMakeLists.txt | 7 ++++++- src/image_file.h | 2 +- src/image_service.cpp | 7 +++---- src/overlaybd/config_util.h | 4 ++-- src/overlaybd/gzindex/gzip_index_create.cpp | 2 +- src/overlaybd/lsmt/test/lsmt-filetest.h | 1 - src/overlaybd/lsmt/test/test.cpp | 3 --- src/overlaybd/tar/libtar.h | 10 ++++++---- src/overlaybd/tar/tar_file.cpp | 14 +++++++------- src/overlaybd/zfile/zfile.cpp | 4 ++-- src/test/image_service_test.cpp | 14 ++++++++------ src/ublk/ublk_device.cpp | 11 +++++++++-- src/ublk/ublk_device.h | 4 ++++ src/ublk/ublkd_main.cpp | 12 ++++++------ 14 files changed, 55 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ffa7e397..6572bf4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS on) set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -g") -add_compile_options(-Wall -Werror=sign-compare) add_definitions(-DOVERLAYBD_VER=${OBD_VER}) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") @@ -273,7 +272,13 @@ endif() #--------------------------------------------------------------------- # overlaybd libraries +# +# Warnings are errors for the code that follows, i.e. ours. The call is +# deliberately placed after the find_package()es above, so that the +# dependencies they add as subprojects keep their own warning settings. #--------------------------------------------------------------------- +add_compile_options(-Wall -Werror) + add_library(checksum_lib STATIC src/tools/sha256file.cpp) target_link_libraries(checksum_lib PUBLIC external_lib) diff --git a/src/image_file.h b/src/image_file.h index d391ac78..851699ea 100644 --- a/src/image_file.h +++ b/src/image_file.h @@ -43,7 +43,7 @@ static std::string LEGACY_COMMIT_FILE_NAME = ".commit"; class ImageFile : public photon::fs::ForwardFile { public: ImageFile(ImageConfigNS::ImageConfig &_conf, ImageService &is, const std::string &dev_id, const char *_config_path) - : ForwardFile(nullptr), image_service(is), m_lower_file(nullptr), config_path(_config_path) { + : ForwardFile(nullptr), config_path(_config_path), image_service(is), m_lower_file(nullptr) { conf.CopyFrom(_conf, conf.GetAllocator()); m_exception = ""; if(image_service.register_image_file(dev_id, this) != 0) { // register itself diff --git a/src/image_service.cpp b/src/image_service.cpp index a5b2ef63..b7885e34 100644 --- a/src/image_service.cpp +++ b/src/image_service.cpp @@ -407,7 +407,7 @@ int ImageService::init() { } std::string cache_type, cache_dir; - uint32_t cache_size_GB, refill_size, block_size; + uint32_t cache_size_GB, refill_size; if (global_conf.cacheConfig().cacheType().empty()) { cache_type = global_conf.cacheType(); cache_dir = global_conf.registryCacheDir(); @@ -418,7 +418,6 @@ int ImageService::init() { cache_size_GB = global_conf.cacheConfig().cacheSizeGB(); } refill_size = global_conf.cacheConfig().refillSize(); - block_size = global_conf.cacheConfig().blockSize(); if (cache_type != "file" && cache_type != "ocf" && cache_type != "download") { LOG_ERROR_RETURN(0, -1, "unknown cache type: `", cache_type); @@ -509,8 +508,8 @@ int ImageService::init() { global_fs.media_file = media_file; global_fs.cached_fs = photon::fs::new_ocf_cached_fs( - global_fs.srcfs, namespace_fs, block_size, refill_size, media_file, reload_media, - global_fs.io_alloc); + global_fs.srcfs, namespace_fs, global_conf.cacheConfig().blockSize(), refill_size, + media_file, reload_media, global_fs.io_alloc); #endif } else if (cache_type == "download") { global_fs.cached_fs = photon::fs::new_persistent_cached_fs( diff --git a/src/overlaybd/config_util.h b/src/overlaybd/config_util.h index 4b2b4191..dbfdd3e5 100644 --- a/src/overlaybd/config_util.h +++ b/src/overlaybd/config_util.h @@ -137,9 +137,9 @@ GetResult(Document *j, const char (&path)[N]) { Value *val = GetValueByPointer(*j, path); Document ret; if (!val) - return std::move(ret); + return ret; ret.CopyFrom(*val, ret.GetAllocator()); - return std::move(ret); + return ret; } template diff --git a/src/overlaybd/gzindex/gzip_index_create.cpp b/src/overlaybd/gzindex/gzip_index_create.cpp index 8bec915f..192e97f2 100644 --- a/src/overlaybd/gzindex/gzip_index_create.cpp +++ b/src/overlaybd/gzindex/gzip_index_create.cpp @@ -41,7 +41,7 @@ class IndexFilterRecorder { explicit IndexFilterRecorder(IndexFileHeader* h, INDEX *index, photon::fs::IFile* index_file):h_(h),index_(index),index_file_(index_file) { buf_ = new unsigned char[DEFLATE_BLOCK_UNCOMPRESS_MAX_SIZE]; - memset(&last_, 0, sizeof(last_)); + last_ = {}; } virtual ~IndexFilterRecorder(){ delete []buf_; diff --git a/src/overlaybd/lsmt/test/lsmt-filetest.h b/src/overlaybd/lsmt/test/lsmt-filetest.h index a6f4a874..fbfe66c4 100644 --- a/src/overlaybd/lsmt/test/lsmt-filetest.h +++ b/src/overlaybd/lsmt/test/lsmt-filetest.h @@ -457,7 +457,6 @@ class FileTest3 : public FileTest2 { IFile *create_commit_layer(int i = 0, int io_engine = 0, bool compress = false, bool verify = false, RWType rw_type = RWType::Append) { auto file = create_a_layer(rw_type); - IFile *as = nullptr; IFile *dst = nullptr; auto dst_filename = layer_name.back(); if (compress) { diff --git a/src/overlaybd/lsmt/test/test.cpp b/src/overlaybd/lsmt/test/test.cpp index a6920a3f..e9ad8114 100644 --- a/src/overlaybd/lsmt/test/test.cpp +++ b/src/overlaybd/lsmt/test/test.cpp @@ -804,9 +804,7 @@ TEST_F(FileTest2, commit_zfile) { reset_verify_file(); auto *file = create_file(); - auto fn_c0 = "commit0"; auto fn_c1 = "commit1"; - auto fcommit0 = lfs->open(fn_c0, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); auto fcommit1 = lfs->open(fn_c1, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); CompressOptions opt; opt.verify = 1; @@ -820,7 +818,6 @@ TEST_F(FileTest2, commit_zfile) { fstream_zfile->close(); file->close(); LOG_INFO("verify commit file from StreamingZFile"); - // zfile_compress(fcommit1, fcommit0, &zfile_args); auto zfile = ZFile::zfile_open_ro(fcommit1); file = (IFileRW *)::open_file_ro(zfile); // file = (IFileRW*)open_file_ro(fn_c1); diff --git a/src/overlaybd/tar/libtar.h b/src/overlaybd/tar/libtar.h index 705c511e..998d712e 100644 --- a/src/overlaybd/tar/libtar.h +++ b/src/overlaybd/tar/libtar.h @@ -52,10 +52,11 @@ static size_t oct_to_size(char *oct) { size_t i; return sscanf(oct, "%zo", &i) == 1 ? i : 0; } -#define int_to_oct(num, oct, octlen) \ + +#define int_to_oct(num, oct, octlen) \ snprintf((oct), (octlen), "%*lo ", (octlen)-2, (unsigned long)(num)) -static void int_to_oct_nonull(int num, char *oct, size_t octlen) { +static inline void int_to_oct_nonull(int num, char *oct, size_t octlen) { snprintf(oct, octlen, "%*lo", (int)(octlen - 1), (unsigned long)num); oct[octlen - 1] = ' '; } @@ -82,8 +83,8 @@ class TarHeader { char devminor[8]; char prefix[155]; char padding[12]; - char *gnu_longname = nullptr; - char *gnu_longlink = nullptr; + char *gnu_longname; + char *gnu_longlink; mode_t get_mode(); gid_t get_gid(); @@ -151,6 +152,7 @@ class TarCore { TarCore(photon::fs::IFile *file, int options, uint64_t fs_blocksize = FS_BLOCKSIZE) : file(file), options(options), fs_blocksize(fs_blocksize) { fs_blockmask = ~(fs_blocksize - 1); + memset(&header, 0, sizeof(header)); } virtual ~TarCore() { if (th_pathname != nullptr) diff --git a/src/overlaybd/tar/tar_file.cpp b/src/overlaybd/tar/tar_file.cpp index b027b2a1..6863d730 100644 --- a/src/overlaybd/tar/tar_file.cpp +++ b/src/overlaybd/tar/tar_file.cpp @@ -191,8 +191,8 @@ class TarFile : public ForwardFile_Ownership { auto record = format_pax_record("size", to_string(size)); LOG_DEBUG(VALUE(record.c_str()), VALUE(record.size())); int_to_oct_nonull(record.size(), th_buf->size, 12); // size - strncpy(th_buf->version, TVERSION, TVERSLEN); // version - strncpy(th_buf->magic, TMAGIC, TMAGLEN); // magic + memcpy(th_buf->version, TVERSION, TVERSLEN); // version + memcpy(th_buf->magic, TMAGIC, TMAGLEN); // magic int_to_oct(th_buf->crc_calc(), th_buf->chksum, 8); // checksum memcpy(buf + T_BLOCKSIZE, record.c_str(), record.size()); // tar header, 1 block @@ -208,7 +208,7 @@ class TarFile : public ForwardFile_Ownership { if (gr != NULL) strlcpy(th_buf->gname, gr->gr_name, sizeof(th_buf->gname)); // gname int_to_oct(0, th_buf->gid, 8); // gid - int_to_oct(s.st_mode, th_buf->mode, 8); // mode + int_to_oct(s.st_mode&0777777, th_buf->mode, 8); // mode #ifndef NO_TIMESTAMP int_to_oct_nonull(s.st_mtime, th_buf->mtime, 12); // mtime #else @@ -216,8 +216,8 @@ class TarFile : public ForwardFile_Ownership { #endif int_to_oct_nonull(0, th_buf->size, 12); // size snprintf(th_buf->name, 100, "%.100s", "overlaybd.commit"); // name - strncpy(th_buf->version, TVERSION, TVERSLEN); // version - strncpy(th_buf->magic, TMAGIC, TMAGLEN); // magic + memcpy(th_buf->version, TVERSION, TVERSLEN); // version + memcpy(th_buf->magic, TMAGIC, TMAGLEN); // magic int_to_oct(th_buf->crc_calc(), th_buf->chksum, 8); // checksum // write header m_file->pwrite(buf, 3 * T_BLOCKSIZE, 0); @@ -245,8 +245,8 @@ class TarFile : public ForwardFile_Ownership { // tar header, 1 block th_buf = (TarHeader *)(buf + 2 * T_BLOCKSIZE); snprintf(th_buf->name, 100, "%.100s", "overlaybd.new"); // name - strncpy(th_buf->version, TVERSION_EMPTY, TVERSLEN); // version - strncpy(th_buf->magic, TMAGIC_EMPTY, TMAGLEN); // magic + memcpy(th_buf->version, TVERSION_EMPTY, TVERSLEN); // version + memcpy(th_buf->magic, TMAGIC_EMPTY, TMAGLEN); // magic int_to_oct_nonull(0, th_buf->size, 12); // size // write header return (m_file->pwrite(buf, 3 * T_BLOCKSIZE, 0) == 3 * T_BLOCKSIZE); diff --git a/src/overlaybd/zfile/zfile.cpp b/src/overlaybd/zfile/zfile.cpp index e250d079..687a08c7 100644 --- a/src/overlaybd/zfile/zfile.cpp +++ b/src/overlaybd/zfile/zfile.cpp @@ -1011,11 +1011,11 @@ class ZFileBuilderMP : public ZFileBuilderBase { for (off_t i = 0; i < (ssize_t)count; i += m_opt.block_size) { if (i + m_opt.block_size > (ssize_t)count) { - copy(ctx, buf+i, count-i, 0); + copy(ctx, (const char *)buf + i, count-i, 0); reserved_size = count - i; break; } - copy(ctx, buf+i, m_opt.block_size, 0); + copy(ctx, (const char *)buf + i, m_opt.block_size, 0); ctx->start_compress(m_opt.block_size); cur_id = (cur_id+1)%m_workers; ctx = workers[cur_id]; diff --git a/src/test/image_service_test.cpp b/src/test/image_service_test.cpp index 5bb04552..b4f0147e 100644 --- a/src/test/image_service_test.cpp +++ b/src/test/image_service_test.cpp @@ -37,7 +37,7 @@ #include "../tools/comm_func.h" #include "../overlaybd/lsmt/file.h" -char *test_ua = nullptr; +const char *test_ua = nullptr; photon::net::ISocketServer *new_server(std::string ip, uint16_t port) { auto server = photon::net::new_tcp_socket_server(); @@ -319,12 +319,12 @@ TEST_F(HTTPServerTest, http_server) { } #define PREADV_SINGLE(file, buf, count, offset) ({ \ - struct iovec iov = { .iov_base = (void *)buf, .iov_len = count }; \ + struct iovec iov = { .iov_base = (void *)buf, .iov_len = (size_t)(count) }; \ (file)->preadv(&iov, 1, offset); \ }) #define PWRITEV_SINGLE(file, buf, count, offset) ({ \ - struct iovec iov = { .iov_base = (void *)buf, .iov_len = count }; \ + struct iovec iov = { .iov_base = (void *)buf, .iov_len = (size_t)(count) }; \ (file)->pwritev(&iov, 1, offset); \ }) @@ -367,7 +367,7 @@ class CreateSnapshotTest : public DevIDRegisterTest { srand(154574045); } - void create_file_rw(char *data_name, char *index_name, bool sparse = false) { + void create_file_rw(const char *data_name, const char *index_name, bool sparse = false) { auto fdata = photon::fs::open_localfile_adaptor(data_name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); auto findex = photon::fs::open_localfile_adaptor(index_name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); LSMT::LayerInfo args(fdata, findex); @@ -432,8 +432,9 @@ TEST_F(CreateSnapshotTest, create_snapshot) { EXPECT_EQ(ret, len); for(auto i = 0; i < len; i++) { EXPECT_EQ(buf0[i], buf1[i]); - if(i >= len / 4 && i < len / 2 + len / 4) + if (i >= len / 4 && i < len / 2 + len / 4) { EXPECT_EQ(buf0[i], buf[i - len / 4]); + } } delete imgfile0; @@ -491,8 +492,9 @@ TEST_F(CreateSnapshotTest, create_snapshot_sparse) { EXPECT_EQ(ret, len); for(auto i = 0; i < len; i++) { EXPECT_EQ(buf0[i], buf1[i]); - if(i >= len / 4 && i < len / 2 + len / 4) + if (i >= len / 4 && i < len / 2 + len / 4) { EXPECT_EQ(buf0[i], buf[i - len / 4]); + } } delete imgfile0; diff --git a/src/ublk/ublk_device.cpp b/src/ublk/ublk_device.cpp index b1b756e7..445e00f8 100644 --- a/src/ublk/ublk_device.cpp +++ b/src/ublk/ublk_device.cpp @@ -113,6 +113,10 @@ ImageFileTarget *ublk_make_image_target(ImageFile *file) { return new ImageFileTarget(file); } +void ublk_free_image_target(ImageFileTarget *target) { + delete target; +} + void UblkDevice::stop() { stop_requested_ = true; // lifecycle stays ours: teardown may self-DEL if (ctrl_dev_ != nullptr) @@ -558,7 +562,8 @@ int UblkDevice::claim_instance(const std::string &image_root, const std::string int UblkDevice::setup_cache_root(const UblkDeviceOpts &opts, std::string &cache_root) { char resolved[PATH_MAX]; if (realpath(opts.image_config_path.c_str(), resolved) == nullptr) { - last_error_ = "image config " + opts.image_config_path + ": " + strerror(errno); + last_error_ = "image config " + opts.image_config_path + ": " + + std::string(strerror(errno)); fprintf(stderr, "overlaybd-ublk: %s\n", last_error_.c_str()); return -1; } @@ -778,7 +783,9 @@ static int ublk_raw_ctrl(uint32_t cmd_op, int dev_id, uint64_t data0, void *buf, memset(sqe, 0, 128); // SQE128 slot sqe->fd = cfd; sqe->opcode = IORING_OP_URING_CMD; - *(uint32_t *)&sqe->off = cmd_op; // ublksrv_set_sqe_cmd_op equivalent + // ublksrv_set_sqe_cmd_op equivalent, through memcpy to stay within the + // aliasing rules + memcpy(&sqe->off, &cmd_op, sizeof(cmd_op)); struct ublksrv_ctrl_cmd *cmd = (struct ublksrv_ctrl_cmd *)&sqe->addr3; cmd->dev_id = dev_id; cmd->queue_id = (uint16_t)-1; diff --git a/src/ublk/ublk_device.h b/src/ublk/ublk_device.h index dbacf738..1aed52a4 100644 --- a/src/ublk/ublk_device.h +++ b/src/ublk/ublk_device.h @@ -93,6 +93,10 @@ class ImageFileTarget; // lives in ublk_device.cpp, so hot-swap callers need this factory. Caller // owns the result and hands it to UblkDevice::swap_image(). ImageFileTarget *ublk_make_image_target(ImageFile *file); +// Releases a target, be it one ublk_make_image_target() returned or the one +// swap_image() hands back. Needed because the type is only complete in +// ublk_device.cpp, and deleting an incomplete type is undefined. +void ublk_free_image_target(ImageFileTarget *target); struct ublksrv_ctrl_dev; struct ublksrv_dev; namespace photon { diff --git a/src/ublk/ublkd_main.cpp b/src/ublk/ublkd_main.cpp index 716873fb..f824df1b 100644 --- a/src/ublk/ublkd_main.cpp +++ b/src/ublk/ublkd_main.cpp @@ -186,7 +186,7 @@ class UblkdServer : public photon::net::http::HTTPHandler { if (realpath(areq.config.c_str(), resolved) == nullptr) { code = 400; msg = ublkd_msg_error("image config " + areq.config + ": " + - strerror(errno)); + std::string(strerror(errno))); return; } if (!adds_in_flight_.insert(resolved).second) { @@ -325,7 +325,7 @@ class UblkdServer : public photon::net::http::HTTPHandler { if (realpath(areq.config.c_str(), resolved) == nullptr) { code = 400; msg = ublkd_msg_error("image config " + areq.config + ": " + - strerror(errno)); + std::string(strerror(errno))); return; } // shared leases only when the feature is enabled; otherwise the @@ -513,7 +513,7 @@ class UblkdServer : public photon::net::http::HTTPHandler { ImageFileTarget *old_target = nullptr; auto *new_target = ublk_make_image_target(real); if (cand->swap_image(real, new_target, &old_file, &old_target) != 0) { - delete new_target; + ublk_free_image_target(new_target); // a device we cannot swap is not trustworthy: drop it int slot = it->slot; pool_idle_.erase(it); @@ -526,7 +526,7 @@ class UblkdServer : public photon::net::http::HTTPHandler { } *slot_out = it->slot; pool_idle_.erase(it); - delete old_target; + ublk_free_image_target(old_target); delete old_file; // placeholder image released return cand; } @@ -557,12 +557,12 @@ class UblkdServer : public photon::net::http::HTTPHandler { auto *ph_target = ublk_make_image_target(ph); UblkDevice *dev = entry.dev.release(); if (dev->swap_image(ph, ph_target, &old_file, &old_target) != 0) { - delete ph_target; + ublk_free_image_target(ph_target); delete ph; entry.dev.reset(dev); // give it back so the caller tears it down return false; } - delete old_target; + ublk_free_image_target(old_target); delete old_file; // the tenant's image pool_idle_.push_back({dev, entry.pool_slot}); return true;