Skip to content

Commit 0f4b3ff

Browse files
committed
add overlaybd-resize tool for userspace ext4 resize on overlaybd images
1 parent 79981d3 commit 0f4b3ff

9 files changed

Lines changed: 600 additions & 2 deletions

File tree

CMake/Finde2fs.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ if(NOT ORIGIN_EXT2FS)
44
FetchContent_Declare(
55
e2fsprogs
66
GIT_REPOSITORY https://github.com/data-accelerator/e2fsprogs.git
7-
GIT_TAG b4cf6c751196a12b1df9a269d8e0b516b99fe6a7
7+
GIT_TAG 404deb95e6b0ed0ceb0148d289977e65bee7f8d0
88
)
99
FetchContent_GetProperties(e2fsprogs)
1010

1111
if(NOT TARGET libext2fs_build)
1212
FetchContent_MakeAvailable(e2fsprogs)
1313
set(LIBEXT2FS_INSTALL_DIR ${e2fsprogs_SOURCE_DIR}/build/libext2fs CACHE STRING "")
14+
set(E2FS_RESIZE_DIR ${e2fsprogs_SOURCE_DIR}/build/resize CACHE STRING "path to e2fsprogs resize build dir")
15+
set(E2FS_INSTALL_LIB_DIR ${e2fsprogs_SOURCE_DIR}/build/v1.47.0-opt/lib CACHE STRING "path to e2fsprogs install-libs output")
1416

1517
add_custom_command(
1618
OUTPUT ${LIBEXT2FS_INSTALL_DIR}/lib

CMake/Findphoton.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
include(FetchContent)
22
set(FETCHCONTENT_QUIET false)
33
set(PHOTON_ENABLE_EXTFS ON)
4+
set(PHOTON_ENABLE_RESIZE ON)
5+
add_definitions(-DPHOTON_ENABLE_RESIZE)
46

57
FetchContent_Declare(
68
photon
79
GIT_REPOSITORY https://github.com/alibaba/PhotonLibOS.git
8-
GIT_TAG v0.6.17
10+
GIT_TAG 0178d14499d8639759a81e32ad58da5226df5e9b
911
)
1012

1113
if(BUILD_TESTING)

src/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ target_link_libraries(overlaybd_image_lib
3636
add_executable(overlaybd-tcmu
3737
main.cpp
3838
)
39+
if (PHOTON_ENABLE_RESIZE AND NOT ORIGIN_EXT2FS)
40+
set_source_files_properties(
41+
${E2FS_RESIZE_DIR}/resize2fs.o
42+
${E2FS_RESIZE_DIR}/extent.o
43+
${E2FS_RESIZE_DIR}/resource_track.o
44+
PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
45+
target_sources(overlaybd-tcmu PRIVATE
46+
${E2FS_RESIZE_DIR}/resize2fs.o
47+
${E2FS_RESIZE_DIR}/extent.o
48+
${E2FS_RESIZE_DIR}/resource_track.o
49+
)
50+
endif()
3951
target_include_directories(overlaybd-tcmu PUBLIC
4052
${TCMU_INCLUDE_DIR}
4153
${CURL_INCLUDE_DIRS}
@@ -53,6 +65,10 @@ target_link_libraries(overlaybd-tcmu
5365
${OPENSSL_CRYPTO_LIBRARY}
5466
${AIO_LIBRARIES}
5567
)
68+
if (PHOTON_ENABLE_RESIZE AND NOT ORIGIN_EXT2FS)
69+
target_link_libraries(overlaybd-tcmu ${E2FS_LIBRARIES})
70+
add_dependencies(overlaybd-tcmu libext2fs_build)
71+
endif()
5672

5773
install(TARGETS overlaybd-tcmu DESTINATION /opt/overlaybd/bin)
5874
install(FILES example_config/overlaybd-tcmu.service DESTINATION /opt/overlaybd/)

src/image_file.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
#include "overlaybd/gzip/gz.h"
3737
#include "overlaybd/gzindex/gzfile.h"
3838
#include "overlaybd/tar/tar_file.h"
39+
#ifdef PHOTON_ENABLE_RESIZE
40+
#include <photon/fs/extfs/extfs.h>
41+
#endif
3942

4043
#define PARALLEL_LOAD_INDEX 32
4144
using namespace photon::fs;
@@ -614,3 +617,53 @@ int ImageFile::create_snapshot(const char *new_config_path) {
614617

615618
return 0;
616619
}
620+
621+
int ImageFile::resize(uint64_t target_size, bool resize_fs, int flags) {
622+
if (read_only) {
623+
LOG_ERROR_RETURN(EROFS, -1, "cannot resize a read-only image (no upper layer)");
624+
}
625+
626+
auto rw = (LSMT::IFileRW *)m_file;
627+
struct stat st;
628+
m_file->fstat(&st);
629+
uint64_t current = (uint64_t)st.st_size;
630+
631+
if (target_size == current && !resize_fs) {
632+
LOG_INFO("vsize already equals target (` bytes), nothing to do", target_size);
633+
return 0;
634+
}
635+
636+
if (target_size > current) {
637+
// Expand: grow block device first, then filesystem
638+
if (rw->update_vsize(target_size) != 0) {
639+
LOG_ERROR_RETURN(0, -1, "failed to update vsize for expand");
640+
}
641+
}
642+
643+
if (resize_fs) {
644+
#ifdef PHOTON_ENABLE_RESIZE
645+
if (photon::fs::resize_extfs(m_file, target_size, flags) != 0) {
646+
if (target_size >= current) {
647+
LOG_ERROR("resize_extfs failed. "
648+
"Re-run to retry or use e2fsck to recover.");
649+
} else {
650+
LOG_ERROR("resize_extfs failed during shrink.");
651+
}
652+
return -1;
653+
}
654+
#else
655+
LOG_ERROR_RETURN(ENOSYS, -1, "resize_fs not supported (built without PHOTON_ENABLE_RESIZE)");
656+
#endif
657+
}
658+
659+
if (target_size < current) {
660+
// Shrink: update vsize after filesystem is shrunk
661+
if (rw->update_vsize(target_size) != 0) {
662+
LOG_ERROR("filesystem resized but failed to update vsize. Re-run to retry.");
663+
return -1;
664+
}
665+
}
666+
667+
LOG_INFO("resize done: ` -> ` bytes", current, target_size);
668+
return 0;
669+
}

src/image_file.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ class ImageFile : public photon::fs::ForwardFile {
121121

122122
int create_snapshot(const char *new_config_path);
123123

124+
// Resize the block device (and optionally the ext4 filesystem).
125+
// target_size: new block device size in bytes.
126+
// resize_fs: if true, also resize the ext4 filesystem to match.
127+
// flags: passed to resize_extfs (e.g. 0x3f for verbose progress).
128+
int resize(uint64_t target_size, bool resize_fs = false, int flags = 0);
129+
124130
private:
125131
Prefetcher *m_prefetcher = nullptr;
126132
ImageConfigNS::ImageConfig conf;

src/test/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,28 @@ add_test(
4949
NAME trace_test
5050
COMMAND ${EXECUTABLE_OUTPUT_PATH}/trace_test
5151
)
52+
53+
if (PHOTON_ENABLE_RESIZE AND NOT ORIGIN_EXT2FS)
54+
set_source_files_properties(
55+
${E2FS_RESIZE_DIR}/resize2fs.o
56+
${E2FS_RESIZE_DIR}/extent.o
57+
${E2FS_RESIZE_DIR}/resource_track.o
58+
PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
59+
add_executable(resize_test
60+
resize_test.cpp
61+
${E2FS_RESIZE_DIR}/resize2fs.o
62+
${E2FS_RESIZE_DIR}/extent.o
63+
${E2FS_RESIZE_DIR}/resource_track.o
64+
)
65+
target_include_directories(resize_test PUBLIC
66+
${PHOTON_INCLUDE_DIR}
67+
${E2FS_INCLUDE_DIRS}
68+
${E2FS_RESIZE_DIR}
69+
)
70+
target_link_libraries(resize_test gtest pthread photon_static ${E2FS_LIBRARIES} ${E2FS_INSTALL_LIB_DIR}/libcom_err.a)
71+
add_dependencies(resize_test libext2fs_build)
72+
add_test(
73+
NAME resize_test
74+
COMMAND ${EXECUTABLE_OUTPUT_PATH}/resize_test
75+
)
76+
endif()

0 commit comments

Comments
 (0)