Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CMake/Finde2fs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ if(NOT ORIGIN_EXT2FS)
FetchContent_Declare(
e2fsprogs
GIT_REPOSITORY https://github.com/data-accelerator/e2fsprogs.git
GIT_TAG b4cf6c751196a12b1df9a269d8e0b516b99fe6a7
GIT_TAG 404deb95e6b0ed0ceb0148d289977e65bee7f8d0
)
FetchContent_GetProperties(e2fsprogs)

if(NOT TARGET libext2fs_build)
FetchContent_MakeAvailable(e2fsprogs)
set(LIBEXT2FS_INSTALL_DIR ${e2fsprogs_SOURCE_DIR}/build/libext2fs 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")

add_custom_command(
OUTPUT ${LIBEXT2FS_INSTALL_DIR}/lib
Expand All @@ -22,7 +24,8 @@ if(NOT ORIGIN_EXT2FS)

set(E2FS_FOUND yes)
set(E2FS_LIBRARY ${LIBEXT2FS_INSTALL_DIR}/lib/libext2fs.so)
set(E2FS_LIBRARIES ${E2FS_LIBRARY})
set(E2FS_COM_ERR_LIBRARY ${e2fsprogs_SOURCE_DIR}/build/lib/libcom_err.a)
set(E2FS_LIBRARIES ${E2FS_LIBRARY} ${E2FS_COM_ERR_LIBRARY})
set(E2FS_INCLUDE_DIR ${LIBEXT2FS_INSTALL_DIR}/include)
set(E2FS_INCLUDE_DIRS ${E2FS_INCLUDE_DIR})

Expand Down
4 changes: 3 additions & 1 deletion CMake/Findphoton.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
include(FetchContent)
set(FETCHCONTENT_QUIET false)
set(PHOTON_ENABLE_EXTFS ON)
set(PHOTON_ENABLE_RESIZE ON)
add_definitions(-DPHOTON_ENABLE_RESIZE)
Comment on lines 3 to +5

FetchContent_Declare(
photon
GIT_REPOSITORY https://github.com/alibaba/PhotonLibOS.git
GIT_TAG v0.6.17
GIT_TAG 0178d14499d8639759a81e32ad58da5226df5e9b
)

if(BUILD_TESTING)
Expand Down
12 changes: 12 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ target_link_libraries(overlaybd_image_lib
${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
)
Expand Down
59 changes: 59 additions & 0 deletions src/image_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#include "overlaybd/gzip/gz.h"
#include "overlaybd/gzindex/gzfile.h"
#include "overlaybd/tar/tar_file.h"
#ifdef PHOTON_ENABLE_RESIZE
#include <photon/fs/extfs/extfs.h>
#endif

#define PARALLEL_LOAD_INDEX 32
using namespace photon::fs;
Expand Down Expand Up @@ -614,3 +617,59 @@ int ImageFile::create_snapshot(const char *new_config_path) {

return 0;
}

int ImageFile::resize(uint64_t target_size, bool resize_fs) {
if (read_only) {
LOG_ERROR_RETURN(EROFS, -1, "cannot resize a read-only image (no upper layer)");
}

auto rw = (LSMT::IFileRW *)m_file;
struct stat st;
if (m_file->fstat(&st) != 0) {
LOG_ERRNO_RETURN(0, -1, "fstat failed");
}
uint64_t current = (uint64_t)st.st_size;

if (target_size == current && !resize_fs) {
LOG_INFO("vsize already equals target (` bytes), nothing to do", target_size);
return 0;
}

if (target_size > current) {
// Expand: grow block device first, then filesystem
if (rw->update_vsize(target_size) != 0) {
LOG_ERROR_RETURN(0, -1, "failed to update vsize for expand");
}
}

if (resize_fs) {
#ifdef PHOTON_ENABLE_RESIZE
if (photon::fs::resize_extfs(m_file, target_size, 0) != 0) {
if (target_size >= current) {
LOG_ERROR("resize_extfs failed. "
"Re-run to retry or use e2fsck to recover.");
} else {
LOG_ERROR("resize_extfs failed during shrink.");
}
return -1;
}
#else
LOG_ERROR_RETURN(ENOSYS, -1, "resize_fs not supported (built without PHOTON_ENABLE_RESIZE)");
#endif
}

if (target_size < current) {
// Shrink: shrinking without resizing the filesystem is unsafe.
if (!resize_fs) {
LOG_ERROR_RETURN(EINVAL, -1, "cannot shrink without resizing filesystem");
}
// Shrink: update vsize after filesystem is shrunk
if (rw->update_vsize(target_size) != 0) {
LOG_ERROR("filesystem resized but failed to update vsize. Re-run to retry.");
return -1;
}
}

LOG_INFO("resize done: ` -> ` bytes", current, target_size);
return 0;
}
5 changes: 5 additions & 0 deletions src/image_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class ImageFile : public photon::fs::ForwardFile {

int create_snapshot(const char *new_config_path);

// Resize the block device (and optionally the ext4 filesystem).
// target_size: new block device size in bytes.
// resize_fs: if true, also resize the ext4 filesystem to match.
int resize(uint64_t target_size, bool resize_fs = false);

private:
Prefetcher *m_prefetcher = nullptr;
ImageConfigNS::ImageConfig conf;
Expand Down
25 changes: 25 additions & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,28 @@ 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()
Loading
Loading