├── .circleci └── config.yml ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── Bug_report.yml │ └── Feature_request.yml ├── dependabot.yml └── workflows │ ├── build-other-archs.yml │ ├── build.yml │ └── codespell.yml ├── .gitignore ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE.LIB ├── LICENSE.md ├── README.md ├── cmake └── cmake_uninstall.cmake.in ├── doc ├── README-upstream-kernel.md ├── Something-wrong-with-snapshots-for-Linux.md ├── Something-wrong-with-snapshots-for-Linux_ru.md ├── blksnap.8 ├── blksnap.md ├── blksnap_ru.md └── tests │ ├── boundary.md │ ├── boundary_ru.md │ ├── corrupt.md │ ├── corrupt_ru.md │ ├── diff_storage.md │ └── diff_storage_ru.md ├── include ├── LICENSE.md ├── blksnap │ ├── Cbt.h │ ├── OpenFileHolder.h │ ├── Sector.h │ ├── Service.h │ ├── Session.h │ ├── Snapshot.h │ ├── SnapshotId.h │ └── Tracker.h └── linux │ ├── blk-filter.h │ └── blksnap.h ├── lib ├── LICENSE.md └── blksnap │ ├── .clang-format │ ├── CMakeLists.txt │ ├── Cbt.cpp │ ├── OpenFileHolder.cpp │ ├── Service.cpp │ ├── Session.cpp │ ├── Snapshot.cpp │ └── Tracker.cpp ├── patches ├── blk-filter_2_v5.9.patch ├── blk_interposer_v5.9.patch ├── blksnap_lk6.1-rc1.patch ├── lk5.15 │ └── 0001-add-bdev_filter.patch ├── lk5.16 │ ├── 0000-cover-letter.patch │ ├── 0001-block-blk_filter-enable-block-device-filters.patch │ ├── 0002-blk_snap-allow-to-create-non-persistent-snapshots-of.patch │ ├── 0002-block-blksnap-header-file-of-the-module-interface.patch │ ├── 0003-block-blksnap-module-management-interface-functions.patch │ ├── 0004-block-blksnap-init-and-exit-functions.patch │ ├── 0005-block-blksnap-interaction-with-sysfs.patch │ ├── 0006-block-blksnap-attaching-and-detaching-the-filter-and.patch │ ├── 0007-block-blksnap-map-of-change-block-tracking.patch │ ├── 0008-block-blksnap-big-buffer-in-the-form-of-an-array-of-.patch │ ├── 0009-block-blksnap-minimum-data-storage-unit-of-the-origi.patch │ ├── 0010-block-blksnap-buffer-in-memory-for-the-minimum-data-.patch │ ├── 0011-block-blksnap-functions-and-structures-for-performin.patch │ ├── 0012-block-blksnap-storage-for-storing-difference-blocks.patch │ ├── 0013-block-blksnap-event-queue-from-the-difference-storag.patch │ ├── 0014-block-blksnap-owner-of-information-about-overwritten.patch │ ├── 0015-block-blksnap-snapshot-image-block-device.patch │ ├── 0016-block-blksnap-snapshot.patch │ ├── 0017-block-blksnap-debugging-mechanism-for-monitoring-mem.patch │ ├── 0018-block-blksnap-Kconfig.patch │ ├── 0019-block-blksnap-Makefile.patch │ ├── 0020-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch │ └── description ├── lk6.1-rc3 │ ├── v1-0000-cover-letter.patch │ ├── v1-0001-block-bdev_filter-enable-block-device-filters.patch │ ├── v1-0002-block-blksnap-header-file-of-the-module-interface.patch │ ├── v1-0003-block-blksnap-module-management-interface-functio.patch │ ├── v1-0004-block-blksnap-init-and-exit-functions.patch │ ├── v1-0005-block-blksnap-interaction-with-sysfs.patch │ ├── v1-0006-block-blksnap-attaching-and-detaching-the-filter-.patch │ ├── v1-0007-block-blksnap-map-of-change-block-tracking.patch │ ├── v1-0008-block-blksnap-minimum-data-storage-unit-of-the-or.patch │ ├── v1-0009-lock-blksnap-buffer-in-memory-for-the-minimum-dat.patch │ ├── v1-0010-block-blksnap-functions-and-structures-for-perfor.patch │ ├── v1-0011-block-blksnap-storage-for-storing-difference-bloc.patch │ ├── v1-0012-lock-blksnap-event-queue-from-the-difference-stor.patch │ ├── v1-0013-block-blksnap-owner-of-information-about-overwrit.patch │ ├── v1-0014-block-blksnap-snapshot-image-block-device.patch │ ├── v1-0015-block-blksnap-snapshot.patch │ ├── v1-0016-block-blksnap-Kconfig-and-Makefile.patch │ └── v1-0017-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch ├── lk6.1-rc8-v2 │ ├── v2-0000-cover-letter.patch │ ├── v2-0001-block-blkfilter-documentation-for-Block-Device-Fi.patch │ ├── v2-0002-block-blkfilter-Block-Device-Filtering-Mechanism.patch │ ├── v2-0003-block-blksnap-documentation-for-Block-Devices-Sna.patch │ ├── v2-0004-block-blksnap-header-file-of-the-module-interface.patch │ ├── v2-0005-block-blksnap-module-management-interface-functio.patch │ ├── v2-0006-block-blksnap-init-and-exit-functions.patch │ ├── v2-0007-block-blksnap-interaction-with-sysfs.patch │ ├── v2-0008-block-blksnap-attaching-and-detaching-the-filter-.patch │ ├── v2-0009-block-blksnap-map-of-change-block-tracking.patch │ ├── v2-0010-block-blksnap-minimum-data-storage-unit-of-the-or.patch │ ├── v2-0011-block-blksnap-buffer-in-memory-for-the-minimum-da.patch │ ├── v2-0012-block-blksnap-functions-and-structures-for-perfor.patch │ ├── v2-0013-block-blksnap-storage-for-storing-difference-bloc.patch │ ├── v2-0014-block-blksnap-event-queue-from-the-difference-sto.patch │ ├── v2-0015-block-blksnap-owner-of-information-about-overwrit.patch │ ├── v2-0016-block-blksnap-snapshot-image-block-device.patch │ ├── v2-0017-block-blksnap-snapshot.patch │ ├── v2-0018-block-blksnap-Kconfig-and-Makefile.patch │ ├── v2-0019-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch │ └── v2-0020-block-blksnap-adds-a-maintainer-for-new-files.patch ├── lk6.1-rc8-v5 │ ├── v2-0000-cover-letter.patch │ ├── v2-0001-documentation-blkfilter-Block-Device-Filtering-Me.patch │ ├── v2-0002-block-blkfilter-Block-Device-Filtering-Mechanism.patch │ ├── v2-0003-documentation-capability-fix-Generic-Block-Device.patch │ ├── v2-0004-documentation-blksnap-Block-Devices-Snapshots-Mod.patch │ ├── v2-0005-block-blksnap-header-file-of-the-module-interface.patch │ ├── v2-0006-block-blksnap-module-management-interface-functio.patch │ ├── v2-0007-block-blksnap-init-and-exit-functions.patch │ ├── v2-0008-block-blksnap-interaction-with-sysfs.patch │ ├── v2-0009-block-blksnap-attaching-and-detaching-the-filter-.patch │ ├── v2-0010-block-blksnap-map-of-change-block-tracking.patch │ ├── v2-0011-block-blksnap-minimum-data-storage-unit-of-the-or.patch │ ├── v2-0012-block-blksnap-buffer-in-memory-for-the-minimum-da.patch │ ├── v2-0013-block-blksnap-functions-and-structures-for-perfor.patch │ ├── v2-0014-block-blksnap-storage-for-storing-difference-bloc.patch │ ├── v2-0015-block-blksnap-event-queue-from-the-difference-sto.patch │ ├── v2-0016-block-blksnap-owner-of-information-about-overwrit.patch │ ├── v2-0017-block-blksnap-snapshot-image-block-device.patch │ ├── v2-0018-block-blksnap-snapshot.patch │ ├── v2-0019-block-blksnap-Kconfig-and-Makefile.patch │ ├── v2-0020-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch │ └── v2-0021-block-blksnap-adds-a-maintainer-for-new-files.patch ├── lk6.1-rc8 │ ├── v2-0000-cover-letter.patch │ ├── v2-0001-block-blkfilter-documentation-for-Block-Device-Fi.patch │ ├── v2-0002-block-blkfilter-Block-Device-Filtering-Mechanism.patch │ ├── v2-0003-block-blksnap-documentation-for-Block-Devices-Sna.patch │ ├── v2-0004-block-blksnap-header-file-of-the-module-interface.patch │ ├── v2-0005-block-blksnap-module-management-interface-functio.patch │ ├── v2-0006-block-blksnap-init-and-exit-functions.patch │ ├── v2-0007-block-blksnap-interaction-with-sysfs.patch │ ├── v2-0008-block-blksnap-attaching-and-detaching-the-filter-.patch │ ├── v2-0009-block-blksnap-map-of-change-block-tracking.patch │ ├── v2-0010-block-blksnap-minimum-data-storage-unit-of-the-or.patch │ ├── v2-0011-block-blksnap-buffer-in-memory-for-the-minimum-da.patch │ ├── v2-0012-block-blksnap-functions-and-structures-for-perfor.patch │ ├── v2-0013-block-blksnap-storage-for-storing-difference-bloc.patch │ ├── v2-0014-block-blksnap-event-queue-from-the-difference-sto.patch │ ├── v2-0015-block-blksnap-owner-of-information-about-overwrit.patch │ ├── v2-0016-block-blksnap-snapshot-image-block-device.patch │ ├── v2-0017-block-blksnap-snapshot.patch │ ├── v2-0018-block-blksnap-Kconfig-and-Makefile.patch │ ├── v2-0019-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch │ └── v2-0020-block-blksnap-adds-a-maintainer-for-new-files.patch ├── lk6.15 │ ├── 0001-the-block-device-filtering-mechanism.patch │ ├── 0002-the-block-devices-snapshots-module-blksnap.patch │ └── 0003-use-u64_to_user_ptr-instead-cast-to-pointer-from-int.patch ├── lk6.3-rc4-v2 │ ├── send_patch.sh │ ├── v3-0000-cover-letter.patch │ ├── v3-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v3-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v3-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v3-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v3-0005-blksnap-module-management-interface-functions.patch │ ├── v3-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v3-0007-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v3-0008-blksnap-difference-storage.patch │ ├── v3-0009-blksnap-event-queue-from-the-difference-storage.patch │ ├── v3-0010-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v3-0011-blksnap-Kconfig-and-Makefile.patch ├── lk6.3-rc4 │ ├── v3-0000-cover-letter.patch │ ├── v3-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v3-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v3-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v3-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v3-0005-blksnap-module-management-interface-functions.patch │ ├── v3-0006-blksnap-attaching-and-detaching-the-filter-and-ha.patch │ ├── v3-0007-blksnap-map-of-change-block-tracking.patch │ ├── v3-0008-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v3-0009-blksnap-buffer-in-memory-for-the-minimum-data-sto.patch │ ├── v3-0010-blksnap-storage-for-storing-difference-blocks.patch │ ├── v3-0011-blksnap-event-queue-from-the-difference-storage.patch │ ├── v3-0012-blksnap-owner-of-information-about-overwritten-bl.patch │ ├── v3-0013-blksnap-snapshot-image-block-device.patch │ ├── v3-0014-blksnap-snapshot.patch │ └── v3-0015-blksnap-Kconfig-and-Makefile.patch ├── lk6.4-rc4-v2 │ ├── v4-0000-cover-letter.patch │ ├── v4-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v4-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v4-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v4-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v4-0005-blksnap-module-management-interface-functions.patch │ ├── v4-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v4-0007-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v4-0008-blksnap-difference-storage.patch │ ├── v4-0009-blksnap-event-queue-from-the-difference-storage.patch │ ├── v4-0010-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v4-0011-blksnap-Kconfig-and-Makefile.patch ├── lk6.4-rc4-v3 │ ├── v4-0000-cover-letter.patch │ ├── v4-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v4-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v4-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v4-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v4-0005-blksnap-module-management-interface-functions.patch │ ├── v4-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v4-0007-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v4-0008-blksnap-difference-storage.patch │ ├── v4-0009-blksnap-event-queue-from-the-difference-storage.patch │ ├── v4-0010-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v4-0011-blksnap-Kconfig-and-Makefile.patch ├── lk6.4-rc4 │ ├── v4-0000-cover-letter.patch │ ├── v4-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v4-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v4-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v4-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v4-0005-blksnap-module-management-interface-functions.patch │ ├── v4-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v4-0007-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v4-0008-blksnap-difference-storage.patch │ ├── v4-0009-blksnap-event-queue-from-the-difference-storage.patch │ ├── v4-0010-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v4-0011-blksnap-Kconfig-and-Makefile.patch ├── lk6.5-block │ ├── v5-0000-cover-letter.patch │ ├── v5-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v5-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v5-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v5-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v5-0005-blksnap-module-management-interface-functions.patch │ ├── v5-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v5-0007-blksnap-minimum-data-storage-unit-of-the-original.patch │ ├── v5-0008-blksnap-difference-storage.patch │ ├── v5-0009-blksnap-event-queue-from-the-difference-storage.patch │ ├── v5-0010-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v5-0011-blksnap-Kconfig-and-Makefile.patch ├── lk6.7-rc1-v2 │ ├── v6-0000-cover-letter.patch │ ├── v6-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v6-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v6-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v6-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v6-0005-blksnap-module-management-interface-functions.patch │ ├── v6-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v6-0007-blksnap-difference-storage-and-chunk.patch │ ├── v6-0008-blksnap-event-queue-from-the-difference-storage.patch │ ├── v6-0009-blksnap-snapshot-and-snapshot-image-block-device.patch │ ├── v6-0010-blksnap-Kconfig-and-Makefile.patch │ └── v6-0011-blksnap-prevents-using-devices-with-data-integrit.patch ├── lk6.7-rc1 │ ├── v6-0000-cover-letter.patch │ ├── v6-0001-documentation-Block-Device-Filtering-Mechanism.patch │ ├── v6-0002-block-Block-Device-Filtering-Mechanism.patch │ ├── v6-0003-documentation-Block-Devices-Snapshots-Module.patch │ ├── v6-0004-blksnap-header-file-of-the-module-interface.patch │ ├── v6-0005-blksnap-module-management-interface-functions.patch │ ├── v6-0006-blksnap-handling-and-tracking-I-O-units.patch │ ├── v6-0007-blksnap-difference-storage-and-chunk.patch │ ├── v6-0008-blksnap-event-queue-from-the-difference-storage.patch │ ├── v6-0009-blksnap-snapshot-and-snapshot-image-block-device.patch │ └── v6-0010-blksnap-Kconfig-and-Makefile.patch ├── lk6.8-rc1 │ ├── v7-0000-cover-letter.patch │ ├── v7-0001-documentation-filtering-and-snapshots-of-a-block-.patch │ ├── v7-0002-block-filtering-of-a-block-devices.patch │ ├── v7-0003-block-header-file-of-the-blksnap-module-interface.patch │ ├── v7-0004-block-module-management-interface-functions.patch │ ├── v7-0005-block-handling-and-tracking-I-O-units.patch │ ├── v7-0006-block-difference-storage-implementation.patch │ ├── v7-0007-block-snapshot-and-snapshot-image-block-device.patch │ └── v7-0008-block-Kconfig-Makefile-and-MAINTAINERS-files.patch ├── lk6.8-rc3 │ ├── v7-0000-cover-letter.patch │ ├── v7-0001-documentation-filtering-and-snapshots-of-a-block-.patch │ ├── v7-0002-block-filtering-of-a-block-devices.patch │ ├── v7-0003-block-header-file-of-the-blksnap-module-interface.patch │ ├── v7-0004-block-module-management-interface-functions.patch │ ├── v7-0005-block-handling-and-tracking-I-O-units.patch │ ├── v7-0006-block-difference-storage-implementation.patch │ ├── v7-0007-block-snapshot-and-snapshot-image-block-device.patch │ └── v7-0008-block-Kconfig-Makefile-and-MAINTAINERS-files.patch └── lk6.9 │ ├── 0001-the-block-device-filtering-mechanism.patch │ └── 0002-the-block-devices-snapshots-module-blksnap.patch ├── pkg └── deb │ ├── blksnap │ ├── blksnap-dev.install │ ├── blksnap-tests.install │ ├── blksnap-tools.install │ ├── blksnap-tools.manpages │ ├── compat │ ├── control │ ├── copyright │ ├── rules │ └── source │ │ └── format │ └── build-blksnap.sh ├── tests ├── 1000-simple.sh ├── 1100-loop_diff_storage.sh ├── 1200-tmpfs_diff_storage.sh ├── 1300-tmpfile_diff_storage.sh ├── 1400-simple.sh ├── 2000-stretch.sh ├── 2100-overflow.sh ├── 3000-cbt.sh ├── 4000-diff_storage.sh ├── 5000-pullout.sh ├── 6000-snapimage_write.sh ├── 6100-snapimage_write.sh ├── 7000-destroy.sh ├── 8000-inline-encryption.sh ├── all.sh ├── blksnap.sh ├── cpp │ ├── .clang-format │ ├── CMakeLists.txt │ ├── TestSector.cpp │ ├── TestSector.h │ ├── boundary.cpp │ ├── cbt.cpp │ ├── corrupt.cpp │ ├── diff_storage.cpp │ ├── helpers │ │ ├── AlignedBuffer.hpp │ │ ├── BlockDevice.cpp │ │ ├── BlockDevice.h │ │ ├── CMakeLists.txt │ │ ├── CheckSumHelper.cpp │ │ ├── CheckSumHelper.h │ │ ├── Device.h │ │ ├── FsHelper.cpp │ │ ├── FsHelper.h │ │ ├── Log.cpp │ │ ├── Log.h │ │ ├── LoopDevice.cpp │ │ ├── LoopDevice.h │ │ ├── MountPoint.cpp │ │ ├── MountPoint.h │ │ ├── RandomHelper.cpp │ │ ├── RandomHelper.h │ │ ├── Uuid.cpp │ │ └── Uuid.h │ └── performance.cpp ├── fio │ ├── 1000-sequental_read.sh │ ├── 1010-sequental_read_4k.sh │ ├── 1100-random_read.sh │ ├── 1110-random_read_4k.sh │ ├── 2000-cow.sh │ └── blksnap.fio ├── functions.sh ├── make_loop_dev.sh ├── manual.sh ├── mod_2000-stretch.sh ├── perf-cow.sh ├── perf-snapshot_read.sh └── unload.sh └── tools └── blksnap ├── .clang-format ├── CMakeLists.txt └── main.cpp /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Use the latest 2.1 version of CircleCI pipeline process engine. 2 | # See: https://circleci.com/docs/2.0/configuration-reference 3 | version: 2.1 4 | 5 | shared: &shared 6 | steps: 7 | - checkout 8 | - run: 9 | name: Prepare environment 10 | command: | 11 | echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 12 | apt-get update 13 | apt-get dist-upgrade -y 14 | - run: 15 | name: Install dependencies 16 | command: | 17 | apt-get install -y g++ cmake uuid-dev libboost-program-options-dev libboost-filesystem-dev libssl-dev debhelper 18 | - run: 19 | name: Build dev, tools and tests packages 20 | working_directory: pkg/deb 21 | command: ./build-blksnap.sh 22 | - run: 23 | name: Save generate packages as artifacts 24 | working_directory: .. 25 | command: | 26 | mkdir /tmp/artifacts 27 | mv *.deb /tmp/artifacts 28 | - store_artifacts: 29 | path: /tmp/artifacts 30 | 31 | jobs: 32 | debian10: 33 | <<: *shared 34 | docker: 35 | - image: library/debian:buster 36 | debian11: 37 | <<: *shared 38 | docker: 39 | - image: library/debian:bullseye 40 | debian12: 41 | <<: *shared 42 | docker: 43 | - image: library/debian:bookworm 44 | ubuntu1404: 45 | <<: *shared 46 | docker: 47 | - image: library/ubuntu:trusty 48 | ubuntu1604: 49 | <<: *shared 50 | docker: 51 | - image: library/ubuntu:xenial 52 | ubuntu1804: 53 | <<: *shared 54 | docker: 55 | - image: library/ubuntu:bionic 56 | ubuntu2004: 57 | <<: *shared 58 | docker: 59 | - image: library/ubuntu:focal 60 | ubuntu2204: 61 | <<: *shared 62 | docker: 63 | - image: library/ubuntu:jammy 64 | ubuntu2310: 65 | <<: *shared 66 | docker: 67 | - image: library/ubuntu:mantic 68 | 69 | workflows: 70 | build-deb: 71 | jobs: 72 | - debian10 73 | - debian11 74 | - debian12 75 | - ubuntu2004 76 | - ubuntu2204 77 | - ubuntu2310 78 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [{utils,lib,include}/**.{cpp,c,h}] 7 | indent_style = space 8 | indent_size=4 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.yml: -------------------------------------------------------------------------------- 1 | name: "Report bug" 2 | description: "Create a bug report to help this project improve" 3 | labels: ["bug"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ### Thank you for contributing to this project! 9 | Before create a new bug report please search and check there isn't a duplicate already present. 10 | - type: input 11 | id: distribution 12 | validations: 13 | required: true 14 | attributes: 15 | label: Distribution 16 | description: Provide the distribution and its version 17 | value: For example Debian 11, Ubuntu 22.04, Fedora 37 etc... 18 | - type: input 19 | id: architecture 20 | validations: 21 | required: true 22 | attributes: 23 | label: Architecture 24 | description: Provide the architecture 25 | value: For example amd64, armhf, arm64 etc... 26 | - type: input 27 | id: kernel-version 28 | validations: 29 | required: true 30 | attributes: 31 | label: Kernel version 32 | description: | 33 | Provide the kernel version used, if from distribution also the package version. 34 | Can be useful "uname -a" output 35 | value: For example 5.15 from ubuntu package 5.15.0-56.62~20.04.1 36 | - type: input 37 | id: blksnap-version 38 | validations: 39 | required: true 40 | attributes: 41 | label: Blksnap version 42 | description: | 43 | Provide the blksnap version used (git commit used for build) 44 | Please specify if you are used external kernel module (built from module/ 45 | or with dkms packages) or the patch for upstream. In the case of the upstream 46 | one specify the version of the patch or the git branch/commit used 47 | value: For example commit 7a83f90 and kernel module from same commit 48 | - type: textarea 49 | id: bug-description 50 | validations: 51 | required: true 52 | attributes: 53 | label: Bug description 54 | description: | 55 | Provide a description of the bug you're found. 56 | Please don't expect anyone to guess everything but give enough information. 57 | - type: textarea 58 | id: reproduce 59 | attributes: 60 | label: Steps to reproduce 61 | description: Describe the steps to reproduce the bug (when possible). 62 | - type: textarea 63 | id: expected-behavior 64 | attributes: 65 | label: Expected behavior 66 | description: Describe what you expected to happen instead. 67 | - type: textarea 68 | id: additional-info 69 | attributes: 70 | label: Additional information 71 | description: Add any additional information related to the issue here. 72 | 73 | 74 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest a new feature or an improvement for this project 3 | labels: ["enhancement"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ### Thank you for contributing to this project! 9 | Before please search and check there isn't a duplicate already present. 10 | - type: textarea 11 | id: description 12 | validations: 13 | required: true 14 | attributes: 15 | label: Description 16 | description: | 17 | Provide a description of a feature request or an improvement that you want suggest. 18 | - type: textarea 19 | id: usage-tips 20 | validations: 21 | required: true 22 | attributes: 23 | label: Usage tips 24 | description: | 25 | Please keep this notes for other contributors 26 | value: | 27 | * Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are interested into this. 28 | * Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this. 29 | * Subscribe to receive notifications on status change and new comments, you can do also without add comment. 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/build-other-archs.yml: -------------------------------------------------------------------------------- 1 | name: Test build on other archs 2 | 3 | on: 4 | push: 5 | branches: 6 | - "*" 7 | paths: 8 | - "include/**" 9 | - "lib/**" 10 | - "tests/**" 11 | - "tools/**" 12 | pull_request: 13 | branches: 14 | - "*" 15 | paths: 16 | - "include/**" 17 | - "lib/**" 18 | - "tests/**" 19 | - "tools/**" 20 | workflow_dispatch: 21 | 22 | jobs: 23 | build_job: 24 | # The host should always be linux 25 | runs-on: ubuntu-22.04 26 | name: ${{ matrix.arch }} 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | include: 32 | - arch: aarch64 33 | - arch: ppc64le 34 | - arch: s390x 35 | - arch: armv7 36 | steps: 37 | - uses: actions/checkout@v4 38 | - uses: uraimo/run-on-arch-action@v3 39 | name: Build 40 | id: build 41 | with: 42 | arch: ${{ matrix.arch }} 43 | distro: bullseye 44 | 45 | # Not required, but speeds up builds 46 | githubToken: ${{ github.token }} 47 | 48 | # The shell to run commands with in the container 49 | shell: /bin/sh 50 | 51 | # Install some dependencies in the container. This speeds up builds if 52 | # you are also using githubToken. Any dependencies installed here will 53 | # be part of the container image that gets cached, so subsequent 54 | # builds don't have to re-install them. The image layer is cached 55 | # publicly in your project's package repository, so it is vital that 56 | # no secrets are present in the container state or logs. 57 | install: | 58 | apt-get update -q -y 59 | apt-get install -q -y g++ cmake uuid-dev libboost-program-options-dev libboost-filesystem-dev libssl-dev 60 | 61 | # Build blksnap-dev, blksnap-tools and blksnap-tests 62 | run: | 63 | cmake . 64 | make 65 | 66 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - "*" 7 | paths-ignore: 8 | - "README.md" 9 | - "doc/**" 10 | - "patches/**" 11 | pull_request: 12 | branches: 13 | - "*" 14 | paths-ignore: 15 | - "README.md" 16 | - "doc/**" 17 | - "patches/**" 18 | workflow_dispatch: 19 | 20 | jobs: 21 | amd64: 22 | runs-on: ubuntu-latest 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | name: [Ubuntu-20, Ubuntu-22, Debian-10, Debian-11, Debian-12, Debian-Testing, Debian-Experimental] 27 | cpp_compiler: [g++] 28 | include: 29 | - name: Ubuntu-20 30 | # Uses gcc 9.3.0, clang 10.0.0, cmake 3.16.3 31 | image: "ubuntu:20.04" 32 | ubuntu: 20 33 | - name: Ubuntu-22 34 | # Uses gcc 12.2.0, clang 15.0.7, cmake 3.24.2 35 | image: "ubuntu:22.04" 36 | ubuntu: 22 37 | - name: Debian-10 38 | # Uses gcc 8.3.0, clang 7.0.1, cmake 3.13.4 39 | image: "debian:buster" 40 | - name: Debian-11 41 | # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 42 | image: "debian:bullseye" 43 | - name: Debian-11 44 | image: "debian:bullseye" 45 | c_compiler: clang 46 | cpp_compiler: clang++ 47 | - name: Debian-12 48 | # Uses gcc 12.2.0, clang 15.0.6, cmake 3.25.1 49 | image: "debian:bookworm" 50 | - name: Debian-12 51 | image: "debian:bookworm" 52 | c_compiler: clang 53 | cpp_compiler: clang++ 54 | - name: Debian-Testing 55 | image: "debian:testing" 56 | - name: Debian-Testing 57 | image: "debian:testing" 58 | c_compiler: clang 59 | cpp_compiler: clang++ 60 | - name: Debian-Experimental 61 | image: "debian:experimental" 62 | - name: Debian-Experimental 63 | image: "debian:experimental" 64 | c_compiler: clang 65 | cpp_compiler: clang++ 66 | container: 67 | image: ${{ matrix.image }} 68 | env: 69 | LANG: en_US.UTF-8 70 | BUILD_TYPE: ${{ matrix.build_type }} 71 | CC: ${{ matrix.c_compiler }} 72 | CXX: ${{ matrix.cpp_compiler }} 73 | WITH_PROJ: ON 74 | APT_LISTCHANGES_FRONTEND: none 75 | DEBIAN_FRONTEND: noninteractive 76 | steps: 77 | - name: Install packages required 78 | shell: bash 79 | run: | 80 | apt-get update -qq 81 | apt-get install -yq \ 82 | clang \ 83 | cmake \ 84 | g++ \ 85 | uuid-dev \ 86 | libboost-program-options-dev \ 87 | libboost-filesystem-dev \ 88 | libssl-dev 89 | - uses: actions/checkout@v4 90 | - name: Build blksnap-dev, blksnap-tools and blksnap-tests 91 | working-directory: . 92 | run: | 93 | cmake . 94 | make 95 | -------------------------------------------------------------------------------- /.github/workflows/codespell.yml: -------------------------------------------------------------------------------- 1 | name: codespell 2 | on: [pull_request] 3 | 4 | jobs: 5 | codespell: 6 | name: check 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout code 10 | uses: actions/checkout@v4 11 | - name: codespell 12 | uses: codespell-project/actions-codespell@v2 13 | with: 14 | only_warn: 1 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.github 3 | !.gitignore 4 | !.editorconfig 5 | !.clang-format 6 | !.circleci 7 | cmake* 8 | CMakeCache.txt 9 | CMakeFiles 10 | Makefile 11 | obj-*-linux-gnu 12 | debian/ 13 | /build/ 14 | /lib/blksnap/bin/ 15 | /tools/blksnap/bin/ 16 | /tests/cpp/bin/ 17 | /tests/test_* 18 | /tests/veeam/ 19 | *.o 20 | *.a 21 | *.so 22 | *.ko 23 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0+ 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | project(blksnap) 5 | 6 | set(CMAKE_CXX_STANDARD 14) 7 | 8 | add_subdirectory(${CMAKE_SOURCE_DIR}/lib/blksnap) 9 | add_subdirectory(${CMAKE_SOURCE_DIR}/tools/blksnap) 10 | add_subdirectory(${CMAKE_SOURCE_DIR}/tests/cpp) 11 | 12 | if(EXISTS ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in) 13 | configure_file(${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in 14 | ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake @ONLY 15 | ) 16 | add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") 17 | endif() 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Reporting issues 2 | 3 | Report any issue found can help to solve it, many issues can be related to a 4 | specific hardware, software and/or a combination of them and/or 5 | unexpected cases and not always can be spotted by developers, testers and 6 | automatic testing systems. 7 | 8 | ## Documentation 9 | 10 | Documentation is important part for any developer and user to make easy and faster 11 | use the software, testing it, contributing to code etc... 12 | Any contribute, also small can help, there are many thing that need improvements, 13 | the README, the docs describing the project, the features, how to use it, the 14 | kernel documentation, comments in source code etc... 15 | 16 | ## Testing 17 | 18 | Testing is important to have a quality software, see related part in [README](README.md#tests) 19 | and the [README](https://github.com/veeam/blksnap/blob/master/doc/README-upstream-kernel.md) related to upstream kernel integration 20 | for some information. 21 | 22 | ## Contributing to Source Code 23 | 24 | Thanks to contribute of many developers, is possible to 25 | make the software better. Any contribution is useful, even if only small fixes. 26 | In order to have a quality software any code changes should be tested before submit. 27 | 28 | ### Coding style 29 | 30 | Kernel module and kernel patches for upstream must follow [upstream kernel code style](https://docs.kernel.org/process/coding-style.html). 31 | 32 | ### License 33 | 34 | Any source file should have [SPDX License Identifier](https://spdx.dev/ids/) in the header as comment. 35 | 36 | Kernel module and patches for upstream: `SPDX-License-Identifier: GPL-2.0-only` 37 | 38 | Tools and tests: `SPDX-License-Identifier: GPL-2.0-or-later` 39 | 40 | Library and include: `SPDX-License-Identifier: LGPL-3.0-or-later` 41 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 3 | endif() 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 9 | if(EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E rm -f \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if("${rm_retval}" STREQUAL 0) 16 | else() 17 | message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 18 | endif() 19 | else() 20 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 21 | endif() 22 | endforeach() -------------------------------------------------------------------------------- /doc/tests/corrupt.md: -------------------------------------------------------------------------------- 1 | # Test corrupt 2 | 3 | ## Purpose of the test 4 | The test is designed to detect data distortions on the snapshot image of a block device. 5 | There are several main reasons why the snapshot image may contain incorrect data: 6 | * tracking does not work, that is, requests are not handled; 7 | * the COW algorithm does not work correctly, that is, already modified data gets into the change store; 8 | * errors in addressing data blocks. 9 | 10 | ## Testing methodology 11 | The data of a certain pattern is recorded on the block device before the snapshot is created and after. 12 | After the snapshot is created, the data is checked on the snapshot image. It should only contain data recorded before the snapshot was created. 13 | The pattern has a sector size and is a header and random data. 14 | The header contains the checksum of the sector, the sequence number of the record, the offset of the sector from the beginning of the block device in the sectors, and the time of recording the sector. 15 | The fact that the sector was recorded before the snapshot was created is checked by the sequence number of the record and the recording time. 16 | The correct location of the sector is checked by its offset from the beginning of the block device. 17 | The integrity of the sector is controlled by a checksum. 18 | 19 | ## Algorithm 20 | 1. The entire original block device is filled with a pattern. 21 | 2. Further actions are performed in the main test cycle. 22 | 3. Create a snapshot of a block device. 23 | 4. A full check is made that the snapshot image contains correct data. 24 | 5. The first few (3) sectors are overwritten (the file system superblock update is simulated during mounting). 25 | 6. In the loop, data is recorded on the original block device and data is checked on the snapshot. 26 | * A random number of sectors of the original block device is recorded. 27 | * Overwrite the first sector again on the original block device. 28 | * A complete re-check of the correctness of the data on the snapshot image is performed. 29 | * If data corruption has been detected on the snapshot image, then the first few dozen damages are logged. 30 | 7. A message about the success of the cycle is displayed. 31 | 8. The snapshot is released 32 | 9. If successful, the verification cycle is repeated until the time allocated for testing has passed. 33 | -------------------------------------------------------------------------------- /doc/tests/corrupt_ru.md: -------------------------------------------------------------------------------- 1 | # Тест corrupt 2 | 3 | ## Назначение 4 | Тест предназначен для выявления искажений данных на образе снапшота блочного устройства. 5 | Несколько основных причин, по которым образ снапшота может содержать неверные данные: 6 | * не работает трекинг, то есть запросы не перехватываются; 7 | * неверно работает алгоритм COW, то есть в хранилище изменений попадают уже изменённые данные; 8 | * ошибки в адресации блоков данных. 9 | 10 | ## Методика тестирования 11 | На блочное устройство производится запись данных определённого паттерна до создания снапшота и после. 12 | После создания снапшота производится проверка данных на образе снапшота. На нём должны быть только данные, записанные до создания снапшота. 13 | Паттерн имеет размер сектора и представляет собой заголовок и данные случайного характера. 14 | В заголовке контрольная сумма сектора, порядковый номер записи, смещение сектора от начала блочного устройства в секторах, и время записи сектора. 15 | Тот факт что сектор был записан до создания снапшота проверяется по порядковому номеру записи и времени записи. 16 | Корректное расположение сектора проверяется по его его смещению от начала блочного устройства. 17 | Целостность сектора контролируется контрольной суммой. 18 | 19 | ## Алгоритм 20 | 1. Производится заполнение всего оригинального блочного устройства паттерном. 21 | 2. Далее действия выполняются в основном тестовом цикле. 22 | 3. Создатся снапшот блочного утсройства. 23 | 4. Производится полная проверка, что образ снапшота содержит корректные данные. 24 | 5. Перезаписывается несколько (3) первых сектора (имитируется обновление суперблока файловой системы при монтировании). 25 | 6. В цикле производится запись данных на оригинальное блочное утсройство и проверка данных на снапшоте. 26 | * Произодится запись случайного количества секторов оригинального блочного устройства. 27 | * Снова перезапись первого сектора на оригинальном блочном устройстве. 28 | * Выполняется повторная полная проверка корректности данных на образе снапшота. 29 | * Если были выявлены повреждения данных на образе снапшота, то первые несколько десятков повреждений логируются. 30 | 7. Выводится сообщение об успешности цикла. 31 | 8. Снапшот освобождается 32 | 9. В случае успеха цикл проверки повторяется, пока не пройдёт выделенное для тестирования время. 33 | -------------------------------------------------------------------------------- /doc/tests/diff_storage.md: -------------------------------------------------------------------------------- 1 | # Test diff_duration 2 | 3 | ## Purpose of the test 4 | The test is designed to detect data distortions on the original block device on which the change storage (diff storage) is located. 5 | Changes are written to the repository directly to disk, and areas are allocated as files on the file system. 6 | Thus, if the algorithm for writing changes to the repository fails, the metadata of the file system can be damaged or the data of neighboring files can be damaged. 7 | 8 | ## Testing methodology 9 | The blocks are checked using the same pattern as for the corrupt test. 10 | If there is an error writing to the DiffSt area, blocks with the incorrect field "sector offset from the beginning of the block device in sectors" should appear in the WR areas. 11 | The space of a block device is randomly divided into two approximately identical sets of ranges. 12 | We get the writable areas (WR) and the areas given over to the change repository (DiffSt), replacing one another. 13 | 14 | +----+--------+----+--------+-- ... --+--------+ 15 | | WR | DiffSt | WR | DiffSt | | DiffSt | 16 | +----+--------+----+--------+-- ... --+--------+ 17 | 18 | When creating a snapshot, DiffSt areas are passed to the module to store snapshot changes in them. 19 | An entry is made to the original device, which causes the COW algorithm to work, which copies the overwritten data from the WR area to the diffstat area. 20 | Verification is performed by checking the correctness of the data in the snapshot image. 21 | If, when writing in the DiffSt area, a record occurs in the WR area, then when reading the snapshot image when reading from the WR zone, the read blocks will not pass the check by the value of the sector offset. 22 | 23 | ## Algorithm 24 | 1. The entire original block device is filled with a pattern. 25 | 2. The entire contents of the block device are checked. 26 | 3. Further actions are performed in the main test cycle. 27 | 4. A set of random numbers is generated, WR and DiffSt regions are formed from them. 28 | 5. A snapshot is created, the DiffSt areas are passed to the module to store the snapshot changes. 29 | 6. Random ranges bounded by WR regions are generated and overwritten on the original block device. 30 | 7. The snapshot image is checked, limited by the WR area. 31 | 8. An error message is displayed if a block with an incorrect pattern is detected, and the test is completed. 32 | 8. Upon successful completion of the test, the snapshot is released, and the DiffSt area is overwritten with correct data. 33 | 9. If successful, the verification cycle is repeated until the time allocated for testing has passed. 34 | 35 | Nuance! 36 | A feature has been implemented in the veeamsnap module that allows you to always read zeros when reading areas allocated for storing snapshot changes. 37 | In the case of blksnap, this feature has not been implemented (at least not yet), so when the snapshot image is fully read, the data copied by the COW algorithm will be read from the DiffSt regions, that is, some garbage. It's not a big deal if bitlooker works correctly. And in the absence of bitlooker, the backup size may grow. With the stretch algorithm, it is insignificant. But with common it can be significant. 38 | -------------------------------------------------------------------------------- /doc/tests/diff_storage_ru.md: -------------------------------------------------------------------------------- 1 | # Тест diff_duration 2 | 3 | ## Назначение 4 | Тест предназначен для выявления искажений данных на оригинальном блочном устройстве, на котором расположено хранилище изменений (diff storage). 5 | Запись в хранилище изменений производится непосредственно на диск, а выделяются области в виде файлов на файловой системе. 6 | Таким образом при ошибке алгоритма записи в хранилище изменений можно повредить метаданные файловой системы или повредить данные соседних файлов. 7 | 8 | ## Методика тестирования 9 | Проверка блоков производится с использованием того же паттерна, что и для теста corrupt. 10 | При ошибке записи в область DiffSt, в областях WR должны появлятся блоки с неверным полем "смещение сектора от начала блочного устройства в секторах". 11 | Пространство блочного устройства разделяется случайным образом на два примерно одинаковых множества диапазонов. 12 | Получаем области доступные для записи (WR) и области, отданные под хранилище изменений (DiffSt), сменяющие один другой. 13 | 14 | +----+--------+----+--------+-- ... --+--------+ 15 | | WR | DiffSt | WR | DiffSt | | DiffSt | 16 | +----+--------+----+--------+-- ... --+--------+ 17 | 18 | При создании снапшота области DiffSt передаются модулю для хранения в них изменений снапшота. 19 | Производится запись в оригинальное устройство, что вызывает работу алгоритма COW, который копирует перезапиываемый данные из области WR в области DiffSt. 20 | Проверка выполняется с помощью проверки корректности данных в образе снапшота. 21 | Если при записи в области DiffSt произойдёт запись в области WR, то при чтении образа снапшота при чтении из зоны WR, считанные блоки не пройдут проверку по значению смещения сектора. 22 | 23 | ## Алгоритм 24 | 1. Производится заполнение всего оригинального блочного устройства паттерном. 25 | 2. Проверяется всё содержимое блочного устройства. 26 | 3. Далее действия выполняются в основном тестовом цикле. 27 | 4. Генерируется множество случайных чисел, из них формируются области WR и DiffSt. 28 | 5. Создаётся снапшот, области DiffSt передаются модулю для храниения изменений снапшота. 29 | 6. Призводится генерация и перезапись случайных диапазонов, ограниченных областями WR, на оригинальном блочном устройстве. 30 | 7. Производится проверка образа снапшота, ограниченная областью WR. 31 | 8. Выводится сообщение об ошибках, если выявляется блок с неверным паттерном, а тест завершается. 32 | 8. При успешном прохождении теста, производится освобождение снапшота, а область DiffSt перезаписывается корректными данными. 33 | 9. В случае успеха цикл проверки повторяется, пока не пройдёт выделенное для тестирования время. 34 | 35 | Нюанс! 36 | В модуле veeamsnap была реализована фича, позволяющая при чтении областей, выделенных для хранения изменений снапшота, читать всегда нули. 37 | В случае blksnap эта фича не была реализована (по крайней мере пока), поэтому при полном чтении образа снапшота из областей DiffSt будут считываться скопированнные алгоритмом COW данные, то есть некий мусор. Это не страшно, если корректно работает bitlooker. А при отсутствии bitlooker-а может вырасти размер бэкапа. При stretch алгоритме - незначительно. А вот при common -это может оказаться значительно. 38 | -------------------------------------------------------------------------------- /include/blksnap/Cbt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | /* 21 | * The hi-level abstraction for the blksnap kernel module. 22 | * Allows to receive data from CBT. 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | namespace blksnap 29 | { 30 | struct SCbtInfo 31 | { 32 | SCbtInfo() 33 | {}; 34 | SCbtInfo(const uint32_t inBlockSize, const uint32_t inBlockCount, 35 | const uint64_t inDeviceCapacity, const uuid_t& inGenerationId, 36 | const uint8_t inSnapNumber) 37 | : blockSize(inBlockSize) 38 | , blockCount(inBlockCount) 39 | , deviceCapacity(inDeviceCapacity) 40 | , snapNumber(inSnapNumber) 41 | { 42 | uuid_copy(generationId, inGenerationId); 43 | }; 44 | ~SCbtInfo(){}; 45 | 46 | unsigned int blockSize; 47 | unsigned int blockCount; 48 | unsigned long long deviceCapacity; 49 | uuid_t generationId; 50 | uint8_t snapNumber; 51 | }; 52 | 53 | struct SCbtData 54 | { 55 | SCbtData(size_t blockCount) 56 | { 57 | vec.resize(blockCount); 58 | }; 59 | ~SCbtData(){}; 60 | 61 | std::vector vec; 62 | }; 63 | 64 | struct ICbt 65 | { 66 | virtual ~ICbt() = default; 67 | 68 | virtual std::string GetImage() = 0; 69 | virtual int GetError() = 0; 70 | virtual std::shared_ptr GetCbtInfo() = 0; 71 | virtual std::shared_ptr GetCbtData() = 0; 72 | 73 | static std::shared_ptr Create(const std::string& original); 74 | }; 75 | 76 | } 77 | -------------------------------------------------------------------------------- /include/blksnap/OpenFileHolder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include 22 | 23 | namespace blksnap 24 | { 25 | class COpenFileHolder 26 | { 27 | public: 28 | COpenFileHolder(const std::string& filename, int flags, int mode = 0); 29 | ~COpenFileHolder(); 30 | int Get(); 31 | 32 | private: 33 | int m_fd; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /include/blksnap/Sector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #ifndef SECTOR_SHIFT 22 | # define SECTOR_SHIFT 9 23 | #endif 24 | #ifndef SECTOR_SIZE 25 | # define SECTOR_SIZE (1 << SECTOR_SHIFT) 26 | #endif 27 | #include 28 | #include 29 | 30 | namespace blksnap 31 | { 32 | typedef unsigned long long sector_t; 33 | 34 | struct SRange 35 | { 36 | sector_t sector; 37 | sector_t count; 38 | 39 | SRange(sector_t inSector, sector_t inCount) 40 | : sector(inSector) 41 | , count(inCount) {}; 42 | SRange() 43 | : SRange(0,0) {}; 44 | }; 45 | struct SStorageRanges 46 | { 47 | std::string device; 48 | std::vector ranges; 49 | 50 | SStorageRanges() {}; 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /include/blksnap/Service.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | /* 21 | * The hi-level abstraction for the blksnap kernel module. 22 | * Allows to show module kernel version. 23 | */ 24 | #include 25 | #include 26 | #include "SnapshotId.h" 27 | #include "OpenFileHolder.h" 28 | 29 | namespace blksnap 30 | { 31 | class CService 32 | { 33 | public: 34 | CService(); 35 | ~CService() {}; 36 | 37 | void Collect(std::vector& ids); 38 | void Version(unsigned short& major, unsigned short& minor, unsigned short& revision, unsigned short& build); 39 | 40 | private: 41 | COpenFileHolder m_ctl; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /include/blksnap/Session.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | /* 21 | * The hi-level abstraction for the blksnap kernel module. 22 | * Allows to create snapshot session. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include "Sector.h" 28 | 29 | namespace blksnap 30 | { 31 | struct ISession 32 | { 33 | virtual ~ISession() = default; 34 | 35 | virtual bool GetError(std::string& errorMessage) = 0; 36 | 37 | static std::shared_ptr Create( 38 | const std::vector& devices, 39 | const std::string& diffStorageFilePath, 40 | const unsigned long long limit); 41 | }; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /include/blksnap/Snapshot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | /* 21 | * The low-level abstraction over ioctl for the blksnap kernel module. 22 | * Allows to interact with the module with minimal overhead and maximum 23 | * flexibility. Uses structures that are directly passed to the kernel module. 24 | */ 25 | 26 | #include 27 | #include 28 | #include "Sector.h" 29 | #include "SnapshotId.h" 30 | #include "OpenFileHolder.h" 31 | #include 32 | 33 | namespace blksnap 34 | { 35 | struct SBlksnapEventCorrupted 36 | { 37 | unsigned int origDevIdMj; 38 | unsigned int origDevIdMn; 39 | int errorCode; 40 | }; 41 | 42 | struct SBlksnapEventNoSpace 43 | { 44 | unsigned long long requestedSectors; 45 | }; 46 | 47 | struct SBlksnapEvent 48 | { 49 | unsigned int code; 50 | long long time; 51 | union 52 | { 53 | struct SBlksnapEventCorrupted corrupted; 54 | struct SBlksnapEventNoSpace noSpace; 55 | }; 56 | }; 57 | 58 | class CSnapshot 59 | { 60 | public: 61 | static std::shared_ptr Create(const std::string& filePath, const unsigned long long limit); 62 | static std::shared_ptr Open(const CSnapshotId& id); 63 | 64 | public: 65 | virtual ~CSnapshot() {}; 66 | 67 | void Take(); 68 | void Destroy(); 69 | bool WaitEvent(unsigned int timeoutMs, SBlksnapEvent& ev); 70 | 71 | const CSnapshotId& Id() const 72 | { 73 | return m_id; 74 | } 75 | private: 76 | CSnapshot(const CSnapshotId& id, const std::shared_ptr& ctl); 77 | 78 | CSnapshotId m_id; 79 | std::shared_ptr m_ctl; 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /include/blksnap/SnapshotId.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace blksnap 26 | { 27 | class CSnapshotId 28 | { 29 | public: 30 | CSnapshotId() 31 | { 32 | uuid_clear(m_id); 33 | }; 34 | CSnapshotId(const uuid_t& id) 35 | { 36 | uuid_copy(m_id, id); 37 | }; 38 | CSnapshotId(const unsigned char buf[16]) 39 | { 40 | memcpy(m_id, buf, sizeof(uuid_t)); 41 | }; 42 | CSnapshotId(const std::string& idStr) 43 | { 44 | uuid_parse(idStr.c_str(), m_id); 45 | }; 46 | 47 | void FromString(const std::string& idStr) 48 | { 49 | uuid_parse(idStr.c_str(), m_id); 50 | }; 51 | const uuid_t& Get() const 52 | { 53 | return m_id; 54 | }; 55 | std::string ToString() const 56 | { 57 | char idStr[64]; 58 | 59 | uuid_unparse(m_id, idStr); 60 | 61 | return std::string(idStr); 62 | }; 63 | private: 64 | uuid_t m_id; 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /include/blksnap/Tracker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #pragma once 20 | /* 21 | * The low-level abstraction over ioctl for the blksnap kernel module. 22 | * Allows to interact with the module with minimal overhead and maximum 23 | * flexibility. Uses structures that are directly passed to the kernel module. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "Sector.h" 32 | #include 33 | #include 34 | 35 | namespace blksnap 36 | { 37 | class CTracker 38 | { 39 | public: 40 | CTracker(const std::string& devicePath); 41 | ~CTracker(); 42 | 43 | bool Attach(); 44 | void Detach(); 45 | 46 | void CbtInfo(struct blksnap_cbtinfo& cbtInfo); 47 | void ReadCbtMap(unsigned int offset, unsigned int length, uint8_t* buff); 48 | void MarkDirtyBlock(std::vector& ranges); 49 | void SnapshotAdd(const uuid_t& id); 50 | void SnapshotInfo(struct blksnap_snapshotinfo& snapshotinfo); 51 | 52 | private: 53 | int m_fd; 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /include/linux/blk-filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #ifndef _UAPI_LINUX_BLK_FILTER_H 20 | #define _UAPI_LINUX_BLK_FILTER_H 21 | 22 | #include 23 | #include 24 | 25 | #ifndef BLKFILTER_ATTACH 26 | 27 | /* 130-136 are used by zoned block device ioctls (uapi/linux/blkzoned.h) */ 28 | /* 137-141 are used by blk-crypto ioctls (uapi/linux/blk-crypto.h) */ 29 | #define BLKFILTER_ATTACH _IOWR(0x12, 142, struct blkfilter_attach) 30 | #define BLKFILTER_DETACH _IOWR(0x12, 143, struct blkfilter_detach) 31 | #define BLKFILTER_CTL _IOWR(0x12, 144, struct blkfilter_ctl) 32 | 33 | #define BLKFILTER_NAME_LENGTH 32 34 | 35 | /** 36 | * struct blkfilter_attach - parameter for BLKFILTER_ATTACH ioctl. 37 | * 38 | * @name: Name of block device filter. 39 | * @opt: Userspace buffer with options. 40 | * @optlen: Size of data at @opt. 41 | */ 42 | struct blkfilter_attach { 43 | __u8 name[BLKFILTER_NAME_LENGTH]; 44 | __u64 opt; 45 | __u32 optlen; 46 | }; 47 | 48 | /** 49 | * struct blkfilter_detach - parameter for BLKFILTER_DETACH ioctl. 50 | * ioctl. 51 | * 52 | * @name: Name of block device filter. 53 | */ 54 | struct blkfilter_detach { 55 | __u8 name[BLKFILTER_NAME_LENGTH]; 56 | }; 57 | 58 | /** 59 | * struct blkfilter_ctl - parameter for BLKFILTER ioctl 60 | * 61 | * @name: Name of block device filter. 62 | * @cmd: Command code opcode (BLKFILTER_CMD_*) 63 | * @optlen: Size of data at @opt 64 | * @opt: userspace buffer with options 65 | */ 66 | struct blkfilter_ctl { 67 | __u8 name[BLKFILTER_NAME_LENGTH]; 68 | __u32 cmd; 69 | __u32 optlen; 70 | __u64 opt; 71 | }; 72 | 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /lib/blksnap/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # https://clang.llvm.org/docs/ClangFormatStyleOptions.html 3 | BasedOnStyle: WebKit 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlines: Left 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: false 9 | AllowShortBlocksOnASingleLine: false 10 | AllowShortCaseLabelsOnASingleLine: false 11 | AllowShortFunctionsOnASingleLine: None 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: None 15 | AlwaysBreakAfterReturnType: None 16 | AlwaysBreakBeforeMultilineStrings: false 17 | AlwaysBreakTemplateDeclarations: Yes 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BreakBeforeBinaryOperators: All 21 | BreakBeforeBraces: Custom 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: true 25 | AfterEnum: true 26 | AfterFunction: true 27 | AfterNamespace: true 28 | AfterObjCDeclaration: true 29 | AfterStruct: true 30 | AfterUnion: true 31 | AfterExternBlock: true 32 | BeforeCatch: true 33 | BeforeElse: true 34 | IndentBraces: false 35 | SplitEmptyFunction: true 36 | SplitEmptyRecord: false 37 | SplitEmptyNamespace: false 38 | BreakBeforeTernaryOperators: true 39 | BreakConstructorInitializers: BeforeComma 40 | BreakInheritanceList: BeforeComma 41 | BreakStringLiterals: false 42 | ColumnLimit: 120 43 | CommentPragmas: '^ IWYU pragma:' 44 | CompactNamespaces: false 45 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 46 | ConstructorInitializerIndentWidth: 4 47 | ContinuationIndentWidth: 2 48 | Cpp11BracedListStyle: true 49 | DerivePointerAlignment: false 50 | DisableFormat: false 51 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 52 | IncludeCategories: 53 | - Regex: '^".*_config.h"$' 54 | Priority: -2 55 | - Regex: '^"(stdafx|PrecompiledHeader)' 56 | Priority: -1 57 | - Regex: '^<([a-zA-Z0-9_]+.*)>$' 58 | Priority: 1 59 | - Regex: '^<([.]+.*)>$' 60 | Priority: 2 61 | - Regex: '.*' 62 | Priority: 3 63 | IncludeBlocks: Regroup 64 | IndentCaseLabels: false 65 | IndentPPDirectives: AfterHash 66 | IndentWidth: 4 67 | IndentWrappedFunctionNames: true 68 | KeepEmptyLinesAtTheStartOfBlocks: false 69 | Language: Cpp 70 | MaxEmptyLinesToKeep: 1 71 | NamespaceIndentation: All 72 | PointerAlignment: Left 73 | SortIncludes: true 74 | SpaceAfterCStyleCast: false 75 | SpaceAfterTemplateKeyword: false 76 | SpaceBeforeAssignmentOperators: true 77 | SpaceBeforeCpp11BracedList: false 78 | SpaceBeforeCtorInitializerColon: true 79 | SpaceBeforeInheritanceColon: true 80 | SpaceBeforeParens: ControlStatements 81 | SpaceBeforeRangeBasedForLoopColon: true 82 | SpaceInEmptyParentheses: false 83 | SpacesBeforeTrailingComments: 1 84 | SpacesInAngles: false 85 | SpacesInCStyleCastParentheses: false 86 | SpacesInContainerLiterals: false 87 | SpacesInParentheses: false 88 | SpacesInSquareBrackets: false 89 | TabWidth: 4 90 | UseTab: Never 91 | ... 92 | -------------------------------------------------------------------------------- /lib/blksnap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 Veeam Software Group GmbH 3 | # 4 | # This file is part of libblksnap 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | # FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | # details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | cmake_minimum_required(VERSION 3.5) 20 | project(blksnap-dev) 21 | 22 | set(CMAKE_CXX_STANDARD 14) 23 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -pthread") 24 | 25 | set(Boost_USE_STATIC_LIBS ON) 26 | FIND_PACKAGE( Boost COMPONENTS filesystem REQUIRED) 27 | 28 | FIND_LIBRARY(LIBUUID_LIBRARY libuuid.so REQUIRED) 29 | if (NOT LIBUUID_LIBRARY) 30 | message(FATAL_ERROR "libuuid not found. please install uuid-dev or libuuid-devel package.") 31 | endif () 32 | 33 | set(SOURCE_FILES 34 | OpenFileHolder.cpp 35 | Snapshot.cpp 36 | Tracker.cpp 37 | Cbt.cpp 38 | Service.cpp 39 | Session.cpp 40 | ) 41 | 42 | add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES}) 43 | set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "blksnap") 44 | 45 | target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) 46 | 47 | install(TARGETS ${PROJECT_NAME} DESTINATION /usr/lib) 48 | 49 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../include/blksnap 50 | DESTINATION /usr/include/blksnap 51 | FILES_MATCHING PATTERN "*.h") 52 | -------------------------------------------------------------------------------- /lib/blksnap/Cbt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace blksnap; 27 | 28 | class CCbt : public ICbt 29 | { 30 | public: 31 | CCbt(const std::string& devicePath) 32 | : m_ctl(devicePath) 33 | {}; 34 | ~CCbt() override 35 | {}; 36 | 37 | std::string GetImage() override 38 | { 39 | struct blksnap_snapshotinfo snapshotinfo; 40 | 41 | m_ctl.SnapshotInfo(snapshotinfo); 42 | 43 | std::string name("/dev/"); 44 | for (int inx = 0; (inx < IMAGE_DISK_NAME_LEN) && (snapshotinfo.image[inx] != '\0'); inx++) 45 | name += static_cast(snapshotinfo.image[inx]); 46 | 47 | return name; 48 | } 49 | 50 | int GetError() override 51 | { 52 | struct blksnap_snapshotinfo snapshotinfo; 53 | 54 | m_ctl.SnapshotInfo(snapshotinfo); 55 | return snapshotinfo.error_code; 56 | }; 57 | 58 | std::shared_ptr GetCbtInfo() override 59 | { 60 | struct blksnap_cbtinfo cbtInfo; 61 | 62 | m_ctl.CbtInfo(cbtInfo); 63 | 64 | return std::make_shared( 65 | cbtInfo.block_size, 66 | cbtInfo.block_count, 67 | cbtInfo.device_capacity, 68 | cbtInfo.generation_id.b, 69 | cbtInfo.changes_number); 70 | }; 71 | 72 | std::shared_ptr GetCbtData() override 73 | { 74 | struct blksnap_cbtinfo cbtInfo; 75 | m_ctl.CbtInfo(cbtInfo); 76 | 77 | auto ptrCbtMap = std::make_shared(cbtInfo.block_count); 78 | m_ctl.ReadCbtMap(0, ptrCbtMap->vec.size(), ptrCbtMap->vec.data()); 79 | 80 | return ptrCbtMap; 81 | }; 82 | private: 83 | CTracker m_ctl; 84 | }; 85 | 86 | std::shared_ptr ICbt::Create(const std::string& devicePath) 87 | { 88 | return std::make_shared(devicePath); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /lib/blksnap/OpenFileHolder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | using namespace blksnap; 30 | 31 | COpenFileHolder::COpenFileHolder(const std::string& filename, int flags, int mode/* = 0 */) 32 | { 33 | int fd = mode ? ::open(filename.c_str(), flags, mode) : ::open(filename.c_str(), flags); 34 | if (fd < 0) 35 | throw std::system_error(errno, std::generic_category(), 36 | "Cannot open file [" + filename + "]"); 37 | m_fd = fd; 38 | }; 39 | COpenFileHolder::~COpenFileHolder() 40 | { 41 | ::close(m_fd); 42 | }; 43 | 44 | int COpenFileHolder::Get() 45 | { 46 | return m_fd; 47 | }; 48 | -------------------------------------------------------------------------------- /lib/blksnap/Service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Veeam Software Group GmbH 3 | * 4 | * This file is part of libblksnap 5 | * 6 | * This program is free software: you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License as published by the Free 8 | * Software Foundation, either version 3 of the License, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | static const char* blksnap_filename = "/dev/" BLKSNAP_CTL; 34 | 35 | using namespace blksnap; 36 | 37 | CService::CService() 38 | : m_ctl(blksnap_filename, O_RDWR) 39 | { } 40 | 41 | void CService::Version(unsigned short& major, unsigned short& minor, unsigned short& revision, unsigned short& build) 42 | { 43 | struct blksnap_version version = {}; 44 | 45 | if (::ioctl(m_ctl.Get(), IOCTL_BLKSNAP_VERSION, &version)) 46 | throw std::system_error(errno, std::generic_category(), 47 | "Failed to get version."); 48 | 49 | major = version.major; 50 | minor = version.minor; 51 | revision = version.revision; 52 | build = version.build; 53 | } 54 | 55 | void CService::Collect(std::vector& ids) 56 | { 57 | struct blksnap_snapshot_collect param = {0}; 58 | 59 | ids.clear(); 60 | if (::ioctl(m_ctl.Get(), IOCTL_BLKSNAP_SNAPSHOT_COLLECT, ¶m)) 61 | throw std::system_error(errno, std::generic_category(), 62 | "Failed to get list of active snapshots."); 63 | 64 | if (param.count == 0) 65 | return; 66 | 67 | std::vector id_array(param.count); 68 | param.ids = (__u64)id_array.data(); 69 | 70 | if (::ioctl(m_ctl.Get(), IOCTL_BLKSNAP_SNAPSHOT_COLLECT, ¶m)) 71 | throw std::system_error(errno, std::generic_category(), 72 | "Failed to get list of snapshots."); 73 | 74 | for (size_t inx = 0; inx < param.count; inx++) 75 | ids.emplace_back(id_array[inx].b); 76 | } 77 | -------------------------------------------------------------------------------- /patches/lk5.16/0005-block-blksnap-interaction-with-sysfs.patch: -------------------------------------------------------------------------------- 1 | From 21a489cdd00348472963f897f7d9b0d03b6ae867 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 29 Mar 2022 13:01:19 +0200 4 | Subject: [PATCH 05/20] block, blksnap: interaction with sysfs 5 | 6 | Provides creation of a class file /sys/class/blksnap and a 7 | device file /dev/blksnap for module management. 8 | 9 | Signed-off-by: Sergei Shtepa 10 | --- 11 | drivers/block/blksnap/sysfs.c | 81 +++++++++++++++++++++++++++++++++++ 12 | drivers/block/blksnap/sysfs.h | 5 +++ 13 | 2 files changed, 86 insertions(+) 14 | create mode 100644 drivers/block/blksnap/sysfs.c 15 | create mode 100644 drivers/block/blksnap/sysfs.h 16 | 17 | diff --git a/drivers/block/blksnap/sysfs.c b/drivers/block/blksnap/sysfs.c 18 | new file mode 100644 19 | index 000000000000..32a34609d106 20 | --- /dev/null 21 | +++ b/drivers/block/blksnap/sysfs.c 22 | @@ -0,0 +1,81 @@ 23 | +// SPDX-License-Identifier: GPL-2.0 24 | +#define pr_fmt(fmt) KBUILD_MODNAME "-sysfs: " fmt 25 | +#include 26 | +#include 27 | +#include 28 | +#include 29 | +#ifdef CONFIG_BLK_SNAP_DEBUG_MEMORY_LEAK 30 | +#include "memory_checker.h" 31 | +#endif 32 | +#include "sysfs.h" 33 | +#include "ctrl.h" 34 | + 35 | +static ssize_t major_show(struct class *class, struct class_attribute *attr, 36 | + char *buf) 37 | +{ 38 | + sprintf(buf, "%d", get_blk_snap_major()); 39 | + return strlen(buf); 40 | +} 41 | + 42 | +/* Declare class_attr_major */ 43 | +CLASS_ATTR_RO(major); 44 | + 45 | +static struct class *blk_snap_class; 46 | + 47 | +static struct device *blk_snap_device; 48 | + 49 | +int sysfs_init(void) 50 | +{ 51 | + struct device *dev; 52 | + int res; 53 | + 54 | + blk_snap_class = class_create(THIS_MODULE, BLK_SNAP_MODULE_NAME); 55 | + if (IS_ERR(blk_snap_class)) { 56 | + res = PTR_ERR(blk_snap_class); 57 | + 58 | + pr_err("Bad class create. errno=%d\n", abs(res)); 59 | + return res; 60 | + } 61 | + 62 | + pr_info("Create 'major' sysfs attribute\n"); 63 | + res = class_create_file(blk_snap_class, &class_attr_major); 64 | + if (res) { 65 | + pr_err("Failed to create 'major' sysfs file\n"); 66 | + 67 | + class_destroy(blk_snap_class); 68 | + blk_snap_class = NULL; 69 | + return res; 70 | + } 71 | + 72 | + dev = device_create(blk_snap_class, NULL, 73 | + MKDEV(get_blk_snap_major(), 0), NULL, 74 | + BLK_SNAP_MODULE_NAME); 75 | + if (IS_ERR(dev)) { 76 | + res = PTR_ERR(dev); 77 | + pr_err("Failed to create device, errno=%d\n", abs(res)); 78 | + 79 | + class_remove_file(blk_snap_class, &class_attr_major); 80 | + class_destroy(blk_snap_class); 81 | + blk_snap_class = NULL; 82 | + return res; 83 | + } 84 | + 85 | + blk_snap_device = dev; 86 | + return res; 87 | +} 88 | + 89 | +void sysfs_done(void) 90 | +{ 91 | + pr_info("Cleanup sysfs\n"); 92 | + 93 | + if (blk_snap_device) { 94 | + device_unregister(blk_snap_device); 95 | + blk_snap_device = NULL; 96 | + } 97 | + 98 | + if (blk_snap_class != NULL) { 99 | + class_remove_file(blk_snap_class, &class_attr_major); 100 | + class_destroy(blk_snap_class); 101 | + blk_snap_class = NULL; 102 | + } 103 | +} 104 | diff --git a/drivers/block/blksnap/sysfs.h b/drivers/block/blksnap/sysfs.h 105 | new file mode 100644 106 | index 000000000000..b41c301fe33b 107 | --- /dev/null 108 | +++ b/drivers/block/blksnap/sysfs.h 109 | @@ -0,0 +1,5 @@ 110 | +/* SPDX-License-Identifier: GPL-2.0 */ 111 | +#pragma once 112 | + 113 | +int sysfs_init(void); 114 | +void sysfs_done(void); 115 | -- 116 | 2.20.1 117 | 118 | -------------------------------------------------------------------------------- /patches/lk5.16/0019-block-blksnap-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 8a52a7356c07402ddb044ed293974ad202a1cad1 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 29 Mar 2022 13:37:59 +0200 4 | Subject: [PATCH 19/20] block, blksnap: Makefile 5 | 6 | Allows to build a module. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/Makefile | 20 ++++++++++++++++++++ 11 | 1 file changed, 20 insertions(+) 12 | create mode 100644 drivers/block/blksnap/Makefile 13 | 14 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 15 | new file mode 100644 16 | index 000000000000..18b6b9e8f944 17 | --- /dev/null 18 | +++ b/drivers/block/blksnap/Makefile 19 | @@ -0,0 +1,20 @@ 20 | +# SPDX-License-Identifier: GPL-2.0 21 | +KERNEL_MODULE_NAME := blksnap 22 | + 23 | +$(KERNEL_MODULE_NAME)-y += big_buffer.o 24 | +$(KERNEL_MODULE_NAME)-y += cbt_map.o 25 | +$(KERNEL_MODULE_NAME)-y += chunk.o 26 | +$(KERNEL_MODULE_NAME)-y += ctrl.o 27 | +$(KERNEL_MODULE_NAME)-y += diff_io.o 28 | +$(KERNEL_MODULE_NAME)-y += diff_area.o 29 | +$(KERNEL_MODULE_NAME)-y += diff_buffer.o 30 | +$(KERNEL_MODULE_NAME)-y += diff_storage.o 31 | +$(KERNEL_MODULE_NAME)-y += event_queue.o 32 | +$(KERNEL_MODULE_NAME)-y += main.o 33 | +$(KERNEL_MODULE_NAME)-y += snapimage.o 34 | +$(KERNEL_MODULE_NAME)-y += snapshot.o 35 | +$(KERNEL_MODULE_NAME)-y += sysfs.o 36 | +$(KERNEL_MODULE_NAME)-y += tracker.o 37 | +$(KERNEL_MODULE_NAME)-y += memory_checker.o 38 | + 39 | +obj-m += $(KERNEL_MODULE_NAME).o 40 | -- 41 | 2.20.1 42 | 43 | -------------------------------------------------------------------------------- /patches/lk5.16/0020-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch: -------------------------------------------------------------------------------- 1 | From 38a1ddf004ee422defbc5da17fe9b2ac1f9028d3 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 29 Mar 2022 13:41:20 +0200 4 | Subject: [PATCH 20/20] block, blksnap: adds a blksnap to the kernel tree. 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | drivers/block/Kconfig | 4 +++- 9 | drivers/block/Makefile | 3 ++- 10 | 2 files changed, 5 insertions(+), 2 deletions(-) 11 | 12 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 13 | index 519b6d38d4df..f4b80bda3a47 100644 14 | --- a/drivers/block/Kconfig 15 | +++ b/drivers/block/Kconfig 16 | @@ -236,7 +236,7 @@ config BLK_DEV_SX8 17 | tristate "Promise SATA SX8 support" 18 | depends on PCI 19 | help 20 | - Saying Y or M here will enable support for the 21 | + Saying Y or M here will enable support for the 22 | Promise SATA SX8 controllers. 23 | 24 | Use devices /dev/sx8/$N and /dev/sx8/$Np$M. 25 | @@ -394,4 +394,6 @@ config BLK_DEV_RBD 26 | 27 | source "drivers/block/rnbd/Kconfig" 28 | 29 | +source "drivers/block/blksnap/Kconfig" 30 | + 31 | endif # BLK_DEV 32 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 33 | index 934a9c7c3a7c..4fa5478d9f7a 100644 34 | --- a/drivers/block/Makefile 35 | +++ b/drivers/block/Makefile 36 | @@ -4,7 +4,7 @@ 37 | # 38 | # 12 June 2000, Christoph Hellwig 39 | # Rewritten to use lists instead of if-statements. 40 | -# 41 | +# 42 | 43 | # needed for trace events 44 | ccflags-y += -I$(src) 45 | @@ -38,5 +38,6 @@ obj-$(CONFIG_ZRAM) += zram/ 46 | obj-$(CONFIG_BLK_DEV_RNBD) += rnbd/ 47 | 48 | obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 49 | +obj-$(CONFIG_BLK_SNAP) += blksnap/ 50 | 51 | swim_mod-y := swim.o swim_asm.o 52 | -- 53 | 2.20.1 54 | 55 | -------------------------------------------------------------------------------- /patches/lk6.1-rc3/v1-0005-block-blksnap-interaction-with-sysfs.patch: -------------------------------------------------------------------------------- 1 | From f3a0a7665482e254d378513bf8ab4b0c8f4308ee Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 1 Nov 2022 14:18:29 +0100 4 | Subject: [PATCH v1 05/17] block, blksnap: interaction with sysfs 5 | 6 | Provides creation of a class file /sys/class/blksnap and a device file 7 | /dev/blksnap for module management. 8 | 9 | Signed-off-by: Sergei Shtepa 10 | --- 11 | drivers/block/blksnap/sysfs.c | 79 +++++++++++++++++++++++++++++++++++ 12 | drivers/block/blksnap/sysfs.h | 7 ++++ 13 | 2 files changed, 86 insertions(+) 14 | create mode 100644 drivers/block/blksnap/sysfs.c 15 | create mode 100644 drivers/block/blksnap/sysfs.h 16 | 17 | diff --git a/drivers/block/blksnap/sysfs.c b/drivers/block/blksnap/sysfs.c 18 | new file mode 100644 19 | index 000000000000..fd20336a14c7 20 | --- /dev/null 21 | +++ b/drivers/block/blksnap/sysfs.c 22 | @@ -0,0 +1,79 @@ 23 | +// SPDX-License-Identifier: GPL-2.0 24 | +#define pr_fmt(fmt) KBUILD_MODNAME "-sysfs: " fmt 25 | +#include 26 | +#include 27 | +#include 28 | +#include 29 | +#include 30 | +#include "sysfs.h" 31 | +#include "ctrl.h" 32 | + 33 | +static ssize_t major_show(struct class *class, struct class_attribute *attr, 34 | + char *buf) 35 | +{ 36 | + sprintf(buf, "%d", get_blk_snap_major()); 37 | + return strlen(buf); 38 | +} 39 | + 40 | +/* Declare class_attr_major */ 41 | +CLASS_ATTR_RO(major); 42 | + 43 | +static struct class *blk_snap_class; 44 | + 45 | +static struct device *blk_snap_device; 46 | + 47 | +int sysfs_init(void) 48 | +{ 49 | + struct device *dev; 50 | + int res; 51 | + 52 | + blk_snap_class = class_create(THIS_MODULE, THIS_MODULE->name); 53 | + if (IS_ERR(blk_snap_class)) { 54 | + res = PTR_ERR(blk_snap_class); 55 | + 56 | + pr_err("Bad class create. errno=%d\n", abs(res)); 57 | + return res; 58 | + } 59 | + 60 | + pr_info("Create 'major' sysfs attribute\n"); 61 | + res = class_create_file(blk_snap_class, &class_attr_major); 62 | + if (res) { 63 | + pr_err("Failed to create 'major' sysfs file\n"); 64 | + 65 | + class_destroy(blk_snap_class); 66 | + blk_snap_class = NULL; 67 | + return res; 68 | + } 69 | + 70 | + dev = device_create(blk_snap_class, NULL, 71 | + MKDEV(get_blk_snap_major(), 0), NULL, 72 | + THIS_MODULE->name); 73 | + if (IS_ERR(dev)) { 74 | + res = PTR_ERR(dev); 75 | + pr_err("Failed to create device, errno=%d\n", abs(res)); 76 | + 77 | + class_remove_file(blk_snap_class, &class_attr_major); 78 | + class_destroy(blk_snap_class); 79 | + blk_snap_class = NULL; 80 | + return res; 81 | + } 82 | + 83 | + blk_snap_device = dev; 84 | + return res; 85 | +} 86 | + 87 | +void sysfs_done(void) 88 | +{ 89 | + pr_info("Cleanup sysfs\n"); 90 | + 91 | + if (blk_snap_device) { 92 | + device_unregister(blk_snap_device); 93 | + blk_snap_device = NULL; 94 | + } 95 | + 96 | + if (blk_snap_class != NULL) { 97 | + class_remove_file(blk_snap_class, &class_attr_major); 98 | + class_destroy(blk_snap_class); 99 | + blk_snap_class = NULL; 100 | + } 101 | +} 102 | diff --git a/drivers/block/blksnap/sysfs.h b/drivers/block/blksnap/sysfs.h 103 | new file mode 100644 104 | index 000000000000..66ce9d1509af 105 | --- /dev/null 106 | +++ b/drivers/block/blksnap/sysfs.h 107 | @@ -0,0 +1,7 @@ 108 | +/* SPDX-License-Identifier: GPL-2.0 */ 109 | +#ifndef __BLK_SNAP_SYSFS_H 110 | +#define __BLK_SNAP_SYSFS_H 111 | + 112 | +int sysfs_init(void); 113 | +void sysfs_done(void); 114 | +#endif /* __BLK_SNAP_SYSFS_H */ 115 | -- 116 | 2.20.1 117 | 118 | -------------------------------------------------------------------------------- /patches/lk6.1-rc3/v1-0016-block-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From a4bf4a1e0fdf20db275e7ee8f4e6c2c6837b9c26 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 1 Nov 2022 14:31:50 +0100 4 | Subject: [PATCH v1 16/17] block, blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 11 | drivers/block/blksnap/Makefile | 18 ++++++++++++++++++ 12 | 2 files changed, 30 insertions(+) 13 | create mode 100644 drivers/block/blksnap/Kconfig 14 | create mode 100644 drivers/block/blksnap/Makefile 15 | 16 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 17 | new file mode 100644 18 | index 000000000000..3a6ecb5fc13d 19 | --- /dev/null 20 | +++ b/drivers/block/blksnap/Kconfig 21 | @@ -0,0 +1,12 @@ 22 | +# SPDX-License-Identifier: GPL-2.0 23 | +# 24 | +# Block device snapshot module configuration 25 | +# 26 | + 27 | +config BLK_SNAP 28 | + tristate "Module for snapshots of block devices." 29 | + help 30 | + Allow to create snapshots and track block changes for block devices. 31 | + Designed for creating backups for a simple block devices. Snapshots 32 | + are temporary and are released then backup is completed. Change block 33 | + tracking allows to create incremental or differential backups. 34 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 35 | new file mode 100644 36 | index 000000000000..b196b17f9d9d 37 | --- /dev/null 38 | +++ b/drivers/block/blksnap/Makefile 39 | @@ -0,0 +1,18 @@ 40 | +# SPDX-License-Identifier: GPL-2.0 41 | + 42 | +blksnap-y := \ 43 | + cbt_map.o \ 44 | + chunk.o \ 45 | + ctrl.o \ 46 | + diff_io.o \ 47 | + diff_area.o \ 48 | + diff_buffer.o \ 49 | + diff_storage.o \ 50 | + event_queue.o \ 51 | + main.o \ 52 | + snapimage.o \ 53 | + snapshot.o \ 54 | + sysfs.o \ 55 | + tracker.o 56 | + 57 | +obj-$(CONFIG_BLK_SNAP) += blksnap.o 58 | -- 59 | 2.20.1 60 | 61 | -------------------------------------------------------------------------------- /patches/lk6.1-rc3/v1-0017-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch: -------------------------------------------------------------------------------- 1 | From 17454216e5a89d24cd4dd67eeb375678bc5f4712 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 1 Nov 2022 14:32:10 +0100 4 | Subject: [PATCH v1 17/17] block, blksnap: adds a blksnap to the kernel tree 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | drivers/block/Kconfig | 2 ++ 9 | drivers/block/Makefile | 2 ++ 10 | 2 files changed, 4 insertions(+) 11 | 12 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 13 | index db1b4b202646..882b3dd0264d 100644 14 | --- a/drivers/block/Kconfig 15 | +++ b/drivers/block/Kconfig 16 | @@ -410,4 +410,6 @@ config BLK_DEV_UBLK 17 | 18 | source "drivers/block/rnbd/Kconfig" 19 | 20 | +source "drivers/block/blksnap/Kconfig" 21 | + 22 | endif # BLK_DEV 23 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 24 | index 101612cba303..8414c47960c2 100644 25 | --- a/drivers/block/Makefile 26 | +++ b/drivers/block/Makefile 27 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 28 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 29 | 30 | swim_mod-y := swim.o swim_asm.o 31 | + 32 | +obj-$(CONFIG_BLK_SNAP) += blksnap/ 33 | -- 34 | 2.20.1 35 | 36 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v2/v2-0001-block-blkfilter-documentation-for-Block-Device-Fi.patch: -------------------------------------------------------------------------------- 1 | From f46386feab9dfa8f0c66398fad8c88627a97dbc4 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Dec 2022 17:42:34 +0100 4 | Subject: [PATCH v2 01/20] block, blkfilter: documentation for Block Device 5 | Filtering Mechanism 6 | 7 | The document contains: 8 | * Describes the purpose of the mechanism 9 | * A little historical background on the capabilities of handling I/O 10 | units of the Linux kernel 11 | * Brief description of the design 12 | 13 | Signed-off-by: Sergei Shtepa 14 | --- 15 | Documentation/block/blkfilter.rst | 39 +++++++++++++++++++++++++++++++ 16 | Documentation/block/index.rst | 1 + 17 | 2 files changed, 40 insertions(+) 18 | create mode 100644 Documentation/block/blkfilter.rst 19 | 20 | diff --git a/Documentation/block/blkfilter.rst b/Documentation/block/blkfilter.rst 21 | new file mode 100644 22 | index 000000000000..15b07a31b889 23 | --- /dev/null 24 | +++ b/Documentation/block/blkfilter.rst 25 | @@ -0,0 +1,39 @@ 26 | +.. SPDX-License-Identifier: GPL-2.0 27 | + 28 | +================================ 29 | +Block Device Filtering Mechanism 30 | +================================ 31 | + 32 | +The block device filtering mechanism is an API that allows to attach block 33 | +device filters. Block device filters allow perform additional processing 34 | +for I/O units. 35 | + 36 | +Introduction 37 | +============ 38 | + 39 | +The idea of handling I/O units on block devices is not new. Back in the 40 | +2.6 kernel, there was an undocumented possibility of handling I/O units 41 | +by substituting the make_request_fn() function, which belonged to the 42 | +request_queue structure. But no kernel module used this feature, and it 43 | +was eliminated in the 5.10 kernel. 44 | + 45 | +The block device filtering mechanism returns the ability to handle I/O units. 46 | +It is possible to safely attach one filter to a block device "on the fly" 47 | +without changing the structure of block devices. 48 | + 49 | +Design 50 | +====== 51 | + 52 | +The block device filtering mechanism provides functions for attaching and 53 | +detaching the filter. The filter is a structure with a reference counter 54 | +and callback functions. 55 | + 56 | +The submit_bio_cb() callback function is called for each I/O unit for a block 57 | +device, providing I/O unit filtering. Depending on the result of filtering 58 | +the I/O unit, it can either be passed for subsequent processing by the block 59 | +layer, or skipped. 60 | + 61 | +The link counter allows to control the filter lifetime. When the reference 62 | +count is reduced to zero, the detach_cb() callback function is called to 63 | +release the filter. This allows the filter to be released when the block 64 | +device is disconnected. 65 | diff --git a/Documentation/block/index.rst b/Documentation/block/index.rst 66 | index c4c73db748a8..bef6de22d651 100644 67 | --- a/Documentation/block/index.rst 68 | +++ b/Documentation/block/index.rst 69 | @@ -10,6 +10,7 @@ Block 70 | bfq-iosched 71 | biovecs 72 | blk-mq 73 | + blkfilter 74 | capability 75 | cmdline-partition 76 | data-integrity 77 | -- 78 | 2.20.1 79 | 80 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v2/v2-0007-block-blksnap-interaction-with-sysfs.patch: -------------------------------------------------------------------------------- 1 | From b448b0db20437f860549adaa3f3c2c7a66079a85 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Dec 2022 18:01:05 +0100 4 | Subject: [PATCH v2 07/20] block, blksnap: interaction with sysfs 5 | 6 | Provides creation of a class file /sys/class/blksnap and a device file 7 | /dev/blksnap for module management. 8 | 9 | Signed-off-by: Sergei Shtepa 10 | --- 11 | drivers/block/blksnap/sysfs.c | 80 +++++++++++++++++++++++++++++++++++ 12 | drivers/block/blksnap/sysfs.h | 7 +++ 13 | 2 files changed, 87 insertions(+) 14 | create mode 100644 drivers/block/blksnap/sysfs.c 15 | create mode 100644 drivers/block/blksnap/sysfs.h 16 | 17 | diff --git a/drivers/block/blksnap/sysfs.c b/drivers/block/blksnap/sysfs.c 18 | new file mode 100644 19 | index 000000000000..6f53c4217d6c 20 | --- /dev/null 21 | +++ b/drivers/block/blksnap/sysfs.c 22 | @@ -0,0 +1,80 @@ 23 | +// SPDX-License-Identifier: GPL-2.0 24 | +#define pr_fmt(fmt) KBUILD_MODNAME "-sysfs: " fmt 25 | + 26 | +#include 27 | +#include 28 | +#include 29 | +#include 30 | +#include 31 | +#include "sysfs.h" 32 | +#include "ctrl.h" 33 | + 34 | +static ssize_t major_show(struct class *class, struct class_attribute *attr, 35 | + char *buf) 36 | +{ 37 | + sprintf(buf, "%d", get_blk_snap_major()); 38 | + return strlen(buf); 39 | +} 40 | + 41 | +/* Declare class_attr_major */ 42 | +CLASS_ATTR_RO(major); 43 | + 44 | +static struct class *blk_snap_class; 45 | + 46 | +static struct device *blk_snap_device; 47 | + 48 | +int sysfs_initialize(void) 49 | +{ 50 | + struct device *dev; 51 | + int res; 52 | + 53 | + blk_snap_class = class_create(THIS_MODULE, THIS_MODULE->name); 54 | + if (IS_ERR(blk_snap_class)) { 55 | + res = PTR_ERR(blk_snap_class); 56 | + 57 | + pr_err("Bad class create. errno=%d\n", abs(res)); 58 | + return res; 59 | + } 60 | + 61 | + pr_info("Create 'major' sysfs attribute\n"); 62 | + res = class_create_file(blk_snap_class, &class_attr_major); 63 | + if (res) { 64 | + pr_err("Failed to create 'major' sysfs file\n"); 65 | + 66 | + class_destroy(blk_snap_class); 67 | + blk_snap_class = NULL; 68 | + return res; 69 | + } 70 | + 71 | + dev = device_create(blk_snap_class, NULL, 72 | + MKDEV(get_blk_snap_major(), 0), NULL, 73 | + THIS_MODULE->name); 74 | + if (IS_ERR(dev)) { 75 | + res = PTR_ERR(dev); 76 | + pr_err("Failed to create device, errno=%d\n", abs(res)); 77 | + 78 | + class_remove_file(blk_snap_class, &class_attr_major); 79 | + class_destroy(blk_snap_class); 80 | + blk_snap_class = NULL; 81 | + return res; 82 | + } 83 | + 84 | + blk_snap_device = dev; 85 | + return res; 86 | +} 87 | + 88 | +void sysfs_finalize(void) 89 | +{ 90 | + pr_info("Cleanup sysfs\n"); 91 | + 92 | + if (blk_snap_device) { 93 | + device_unregister(blk_snap_device); 94 | + blk_snap_device = NULL; 95 | + } 96 | + 97 | + if (blk_snap_class != NULL) { 98 | + class_remove_file(blk_snap_class, &class_attr_major); 99 | + class_destroy(blk_snap_class); 100 | + blk_snap_class = NULL; 101 | + } 102 | +} 103 | diff --git a/drivers/block/blksnap/sysfs.h b/drivers/block/blksnap/sysfs.h 104 | new file mode 100644 105 | index 000000000000..5fc200d36789 106 | --- /dev/null 107 | +++ b/drivers/block/blksnap/sysfs.h 108 | @@ -0,0 +1,7 @@ 109 | +/* SPDX-License-Identifier: GPL-2.0 */ 110 | +#ifndef __BLK_SNAP_SYSFS_H 111 | +#define __BLK_SNAP_SYSFS_H 112 | + 113 | +int sysfs_initialize(void); 114 | +void sysfs_finalize(void); 115 | +#endif /* __BLK_SNAP_SYSFS_H */ 116 | -- 117 | 2.20.1 118 | 119 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v2/v2-0018-block-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 8e0639b1220f0718d4a59fbe8af8a1616d4506c5 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Dec 2022 18:05:44 +0100 4 | Subject: [PATCH v2 18/20] block, blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 11 | drivers/block/blksnap/Makefile | 18 ++++++++++++++++++ 12 | 2 files changed, 30 insertions(+) 13 | create mode 100644 drivers/block/blksnap/Kconfig 14 | create mode 100644 drivers/block/blksnap/Makefile 15 | 16 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 17 | new file mode 100644 18 | index 000000000000..2f726fd3295a 19 | --- /dev/null 20 | +++ b/drivers/block/blksnap/Kconfig 21 | @@ -0,0 +1,12 @@ 22 | +# SPDX-License-Identifier: GPL-2.0 23 | +# 24 | +# Block device snapshot module configuration 25 | +# 26 | + 27 | +config BLK_SNAP 28 | + tristate "Block Devices Snapshots Module (blksnap)" 29 | + help 30 | + Allow to create snapshots and track block changes for block devices. 31 | + Designed for creating backups for simple block devices. Snapshots are 32 | + temporary and are released then backup is completed. Change block 33 | + tracking allows to create incremental or differential backups. 34 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 35 | new file mode 100644 36 | index 000000000000..b196b17f9d9d 37 | --- /dev/null 38 | +++ b/drivers/block/blksnap/Makefile 39 | @@ -0,0 +1,18 @@ 40 | +# SPDX-License-Identifier: GPL-2.0 41 | + 42 | +blksnap-y := \ 43 | + cbt_map.o \ 44 | + chunk.o \ 45 | + ctrl.o \ 46 | + diff_io.o \ 47 | + diff_area.o \ 48 | + diff_buffer.o \ 49 | + diff_storage.o \ 50 | + event_queue.o \ 51 | + main.o \ 52 | + snapimage.o \ 53 | + snapshot.o \ 54 | + sysfs.o \ 55 | + tracker.o 56 | + 57 | +obj-$(CONFIG_BLK_SNAP) += blksnap.o 58 | -- 59 | 2.20.1 60 | 61 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v2/v2-0019-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch: -------------------------------------------------------------------------------- 1 | From 6565f236ff578b261d75785f1382fd97e74104e8 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Dec 2022 18:06:09 +0100 4 | Subject: [PATCH v2 19/20] block, blksnap: adds a blksnap to the kernel tree 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | drivers/block/Kconfig | 2 ++ 9 | drivers/block/Makefile | 2 ++ 10 | 2 files changed, 4 insertions(+) 11 | 12 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 13 | index a41145d52de9..81304bfdc30c 100644 14 | --- a/drivers/block/Kconfig 15 | +++ b/drivers/block/Kconfig 16 | @@ -416,4 +416,6 @@ config BLK_DEV_UBLK 17 | 18 | source "drivers/block/rnbd/Kconfig" 19 | 20 | +source "drivers/block/blksnap/Kconfig" 21 | + 22 | endif # BLK_DEV 23 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 24 | index 101612cba303..8414c47960c2 100644 25 | --- a/drivers/block/Makefile 26 | +++ b/drivers/block/Makefile 27 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 28 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 29 | 30 | swim_mod-y := swim.o swim_asm.o 31 | + 32 | +obj-$(CONFIG_BLK_SNAP) += blksnap/ 33 | -- 34 | 2.20.1 35 | 36 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v2/v2-0020-block-blksnap-adds-a-maintainer-for-new-files.patch: -------------------------------------------------------------------------------- 1 | From e092ccef2b4d76ba66ba4b8221997a76a7883c76 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Dec 2022 18:06:38 +0100 4 | Subject: [PATCH v2 20/20] block, blksnap: adds a maintainer for new files 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | MAINTAINERS | 14 ++++++++++++++ 9 | 1 file changed, 14 insertions(+) 10 | 11 | diff --git a/MAINTAINERS b/MAINTAINERS 12 | index 1daadaa4d48b..d54c6e59a965 100644 13 | --- a/MAINTAINERS 14 | +++ b/MAINTAINERS 15 | @@ -3655,6 +3655,20 @@ M: Jan-Simon Moeller 16 | S: Maintained 17 | F: drivers/leds/leds-blinkm.c 18 | 19 | +BLOCK DEVICE FILTERING MECHANISM 20 | +M: sergei.shtepa@veeam.com 21 | +L: linux-block@vger.kernel.org 22 | +S: Supported 23 | +F: Documentation/block/blkfilter.rst 24 | + 25 | +BLOCK DEVICE SNAPSHOTS MODULE 26 | +M: sergei.shtepa@veeam.com 27 | +L: linux-block@vger.kernel.org 28 | +S: Supported 29 | +F: Documentation/block/blksnap.rst 30 | +F: drivers/block/blksnap/* 31 | +F: include/uapi/linux/blksnap.h 32 | + 33 | BLOCK LAYER 34 | M: Jens Axboe 35 | L: linux-block@vger.kernel.org 36 | -- 37 | 2.20.1 38 | 39 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0001-documentation-blkfilter-Block-Device-Filtering-Me.patch: -------------------------------------------------------------------------------- 1 | From 9cedfe237f478dffa7e7fe39c5ed69830791a65a Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:08:26 +0100 4 | Subject: [PATCH v2 01/21] documentation, blkfilter: Block Device Filtering 5 | Mechanism 6 | 7 | The document contains: 8 | * Describes the purpose of the mechanism 9 | * A little historical background on the capabilities of handling I/O 10 | units of the Linux kernel 11 | * Brief description of the design 12 | * Reference to interface description 13 | 14 | Signed-off-by: Sergei Shtepa 15 | --- 16 | Documentation/block/blkfilter.rst | 50 +++++++++++++++++++++++++++++++ 17 | Documentation/block/index.rst | 1 + 18 | 2 files changed, 51 insertions(+) 19 | create mode 100644 Documentation/block/blkfilter.rst 20 | 21 | diff --git a/Documentation/block/blkfilter.rst b/Documentation/block/blkfilter.rst 22 | new file mode 100644 23 | index 000000000000..3482e16c1964 24 | --- /dev/null 25 | +++ b/Documentation/block/blkfilter.rst 26 | @@ -0,0 +1,50 @@ 27 | +.. SPDX-License-Identifier: GPL-2.0 28 | + 29 | +================================ 30 | +Block Device Filtering Mechanism 31 | +================================ 32 | + 33 | +The block device filtering mechanism is an API that allows to attach block 34 | +device filters. Block device filters allow perform additional processing 35 | +for I/O units. 36 | + 37 | +Introduction 38 | +============ 39 | + 40 | +The idea of handling I/O units on block devices is not new. Back in the 41 | +2.6 kernel, there was an undocumented possibility of handling I/O units 42 | +by substituting the make_request_fn() function, which belonged to the 43 | +request_queue structure. But no kernel module used this feature, and it 44 | +was eliminated in the 5.10 kernel. 45 | + 46 | +The block device filtering mechanism returns the ability to handle I/O units. 47 | +It is possible to safely attach filter to a block device "on the fly" without 48 | +changing the structure of block devices. 49 | + 50 | +It supports attaching one filter to one block device, because there is only 51 | +one filter implementation in the kernel. 52 | +See Documentation/block/blksnap.rst. 53 | + 54 | +Design 55 | +====== 56 | + 57 | +The block device filtering mechanism provides functions for attaching and 58 | +detaching the filter. The filter is a structure with a reference counter 59 | +and callback functions. 60 | + 61 | +The submit_bio_cb() callback function is called for each I/O unit for a block 62 | +device, providing I/O unit filtering. Depending on the result of filtering 63 | +the I/O unit, it can either be passed for subsequent processing by the block 64 | +layer, or skipped. 65 | + 66 | +The reference counter allows to control the filter lifetime. When the reference 67 | +count is reduced to zero, the release_cb() callback function is called to 68 | +release the filter. This allows the filter to be released when the block 69 | +device is disconnected. 70 | + 71 | +Interface description 72 | +===================== 73 | +.. kernel-doc:: include/linux/blkdev.h 74 | + :functions: bdev_filter_operations bdev_filter bdev_filter_init bdev_filter_get bdev_filter_put 75 | +.. kernel-doc:: block/bdev.c 76 | + :functions: bdev_filter_attach bdev_filter_detach 77 | diff --git a/Documentation/block/index.rst b/Documentation/block/index.rst 78 | index c4c73db748a8..bef6de22d651 100644 79 | --- a/Documentation/block/index.rst 80 | +++ b/Documentation/block/index.rst 81 | @@ -10,6 +10,7 @@ Block 82 | bfq-iosched 83 | biovecs 84 | blk-mq 85 | + blkfilter 86 | capability 87 | cmdline-partition 88 | data-integrity 89 | -- 90 | 2.20.1 91 | 92 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0003-documentation-capability-fix-Generic-Block-Device.patch: -------------------------------------------------------------------------------- 1 | From 9d684c0b2f0068274cc7eb85222f45dba5b561b4 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:09:25 +0100 4 | Subject: [PATCH v2 03/21] documentation, capability: fix Generic Block Device 5 | Capability 6 | 7 | When adding documentation for blkfilter, new lines of documentation 8 | appeared in the file include/linux/blkdev.h. To preserve the appearance 9 | of this document, the required sections and function descriptions were 10 | explicitly specified. 11 | 12 | Signed-off-by: Sergei Shtepa 13 | --- 14 | Documentation/block/capability.rst | 3 +++ 15 | 1 file changed, 3 insertions(+) 16 | 17 | diff --git a/Documentation/block/capability.rst b/Documentation/block/capability.rst 18 | index 2ae7f064736a..8fad791980bb 100644 19 | --- a/Documentation/block/capability.rst 20 | +++ b/Documentation/block/capability.rst 21 | @@ -8,3 +8,6 @@ This file documents the sysfs file ``block//capability``. 22 | capabilities a specific block device supports: 23 | 24 | .. kernel-doc:: include/linux/blkdev.h 25 | + :DOC: genhd capability flags 26 | +.. kernel-doc:: include/linux/blkdev.h 27 | + :functions: disk_openers blk_alloc_disk bio_end_io_acct 28 | -- 29 | 2.20.1 30 | 31 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0008-block-blksnap-interaction-with-sysfs.patch: -------------------------------------------------------------------------------- 1 | From ead977c10414b3cb1df368f6041dfa083436374d Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:12:10 +0100 4 | Subject: [PATCH v2 08/21] block, blksnap: interaction with sysfs 5 | 6 | Provides creation of a class file /sys/class/blksnap and a device file 7 | /dev/blksnap for module management. 8 | 9 | Signed-off-by: Sergei Shtepa 10 | --- 11 | drivers/block/blksnap/sysfs.c | 80 +++++++++++++++++++++++++++++++++++ 12 | drivers/block/blksnap/sysfs.h | 7 +++ 13 | 2 files changed, 87 insertions(+) 14 | create mode 100644 drivers/block/blksnap/sysfs.c 15 | create mode 100644 drivers/block/blksnap/sysfs.h 16 | 17 | diff --git a/drivers/block/blksnap/sysfs.c b/drivers/block/blksnap/sysfs.c 18 | new file mode 100644 19 | index 000000000000..6f53c4217d6c 20 | --- /dev/null 21 | +++ b/drivers/block/blksnap/sysfs.c 22 | @@ -0,0 +1,80 @@ 23 | +// SPDX-License-Identifier: GPL-2.0 24 | +#define pr_fmt(fmt) KBUILD_MODNAME "-sysfs: " fmt 25 | + 26 | +#include 27 | +#include 28 | +#include 29 | +#include 30 | +#include 31 | +#include "sysfs.h" 32 | +#include "ctrl.h" 33 | + 34 | +static ssize_t major_show(struct class *class, struct class_attribute *attr, 35 | + char *buf) 36 | +{ 37 | + sprintf(buf, "%d", get_blk_snap_major()); 38 | + return strlen(buf); 39 | +} 40 | + 41 | +/* Declare class_attr_major */ 42 | +CLASS_ATTR_RO(major); 43 | + 44 | +static struct class *blk_snap_class; 45 | + 46 | +static struct device *blk_snap_device; 47 | + 48 | +int sysfs_initialize(void) 49 | +{ 50 | + struct device *dev; 51 | + int res; 52 | + 53 | + blk_snap_class = class_create(THIS_MODULE, THIS_MODULE->name); 54 | + if (IS_ERR(blk_snap_class)) { 55 | + res = PTR_ERR(blk_snap_class); 56 | + 57 | + pr_err("Bad class create. errno=%d\n", abs(res)); 58 | + return res; 59 | + } 60 | + 61 | + pr_info("Create 'major' sysfs attribute\n"); 62 | + res = class_create_file(blk_snap_class, &class_attr_major); 63 | + if (res) { 64 | + pr_err("Failed to create 'major' sysfs file\n"); 65 | + 66 | + class_destroy(blk_snap_class); 67 | + blk_snap_class = NULL; 68 | + return res; 69 | + } 70 | + 71 | + dev = device_create(blk_snap_class, NULL, 72 | + MKDEV(get_blk_snap_major(), 0), NULL, 73 | + THIS_MODULE->name); 74 | + if (IS_ERR(dev)) { 75 | + res = PTR_ERR(dev); 76 | + pr_err("Failed to create device, errno=%d\n", abs(res)); 77 | + 78 | + class_remove_file(blk_snap_class, &class_attr_major); 79 | + class_destroy(blk_snap_class); 80 | + blk_snap_class = NULL; 81 | + return res; 82 | + } 83 | + 84 | + blk_snap_device = dev; 85 | + return res; 86 | +} 87 | + 88 | +void sysfs_finalize(void) 89 | +{ 90 | + pr_info("Cleanup sysfs\n"); 91 | + 92 | + if (blk_snap_device) { 93 | + device_unregister(blk_snap_device); 94 | + blk_snap_device = NULL; 95 | + } 96 | + 97 | + if (blk_snap_class != NULL) { 98 | + class_remove_file(blk_snap_class, &class_attr_major); 99 | + class_destroy(blk_snap_class); 100 | + blk_snap_class = NULL; 101 | + } 102 | +} 103 | diff --git a/drivers/block/blksnap/sysfs.h b/drivers/block/blksnap/sysfs.h 104 | new file mode 100644 105 | index 000000000000..5fc200d36789 106 | --- /dev/null 107 | +++ b/drivers/block/blksnap/sysfs.h 108 | @@ -0,0 +1,7 @@ 109 | +/* SPDX-License-Identifier: GPL-2.0 */ 110 | +#ifndef __BLK_SNAP_SYSFS_H 111 | +#define __BLK_SNAP_SYSFS_H 112 | + 113 | +int sysfs_initialize(void); 114 | +void sysfs_finalize(void); 115 | +#endif /* __BLK_SNAP_SYSFS_H */ 116 | -- 117 | 2.20.1 118 | 119 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0019-block-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 5656aaf06936a3a4c8d86856ee14168b761ad6e5 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:18:21 +0100 4 | Subject: [PATCH v2 19/21] block, blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 11 | drivers/block/blksnap/Makefile | 18 ++++++++++++++++++ 12 | 2 files changed, 30 insertions(+) 13 | create mode 100644 drivers/block/blksnap/Kconfig 14 | create mode 100644 drivers/block/blksnap/Makefile 15 | 16 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 17 | new file mode 100644 18 | index 000000000000..2f726fd3295a 19 | --- /dev/null 20 | +++ b/drivers/block/blksnap/Kconfig 21 | @@ -0,0 +1,12 @@ 22 | +# SPDX-License-Identifier: GPL-2.0 23 | +# 24 | +# Block device snapshot module configuration 25 | +# 26 | + 27 | +config BLK_SNAP 28 | + tristate "Block Devices Snapshots Module (blksnap)" 29 | + help 30 | + Allow to create snapshots and track block changes for block devices. 31 | + Designed for creating backups for simple block devices. Snapshots are 32 | + temporary and are released then backup is completed. Change block 33 | + tracking allows to create incremental or differential backups. 34 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 35 | new file mode 100644 36 | index 000000000000..b196b17f9d9d 37 | --- /dev/null 38 | +++ b/drivers/block/blksnap/Makefile 39 | @@ -0,0 +1,18 @@ 40 | +# SPDX-License-Identifier: GPL-2.0 41 | + 42 | +blksnap-y := \ 43 | + cbt_map.o \ 44 | + chunk.o \ 45 | + ctrl.o \ 46 | + diff_io.o \ 47 | + diff_area.o \ 48 | + diff_buffer.o \ 49 | + diff_storage.o \ 50 | + event_queue.o \ 51 | + main.o \ 52 | + snapimage.o \ 53 | + snapshot.o \ 54 | + sysfs.o \ 55 | + tracker.o 56 | + 57 | +obj-$(CONFIG_BLK_SNAP) += blksnap.o 58 | -- 59 | 2.20.1 60 | 61 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0020-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch: -------------------------------------------------------------------------------- 1 | From 0786279b120fc6cffb512768926cd4a2942c9b7f Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:18:48 +0100 4 | Subject: [PATCH v2 20/21] block, blksnap: adds a blksnap to the kernel tree 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | drivers/block/Kconfig | 2 ++ 9 | drivers/block/Makefile | 2 ++ 10 | 2 files changed, 4 insertions(+) 11 | 12 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 13 | index a41145d52de9..81304bfdc30c 100644 14 | --- a/drivers/block/Kconfig 15 | +++ b/drivers/block/Kconfig 16 | @@ -416,4 +416,6 @@ config BLK_DEV_UBLK 17 | 18 | source "drivers/block/rnbd/Kconfig" 19 | 20 | +source "drivers/block/blksnap/Kconfig" 21 | + 22 | endif # BLK_DEV 23 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 24 | index 101612cba303..8414c47960c2 100644 25 | --- a/drivers/block/Makefile 26 | +++ b/drivers/block/Makefile 27 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 28 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 29 | 30 | swim_mod-y := swim.o swim_asm.o 31 | + 32 | +obj-$(CONFIG_BLK_SNAP) += blksnap/ 33 | -- 34 | 2.20.1 35 | 36 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8-v5/v2-0021-block-blksnap-adds-a-maintainer-for-new-files.patch: -------------------------------------------------------------------------------- 1 | From f9d7e1235e8e2e1823f740a9db024bd25b0d3a77 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Dec 2022 15:19:32 +0100 4 | Subject: [PATCH v2 21/21] block, blksnap: adds a maintainer for new files 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | MAINTAINERS | 14 ++++++++++++++ 9 | 1 file changed, 14 insertions(+) 10 | 11 | diff --git a/MAINTAINERS b/MAINTAINERS 12 | index 1daadaa4d48b..d54c6e59a965 100644 13 | --- a/MAINTAINERS 14 | +++ b/MAINTAINERS 15 | @@ -3655,6 +3655,20 @@ M: Jan-Simon Moeller 16 | S: Maintained 17 | F: drivers/leds/leds-blinkm.c 18 | 19 | +BLOCK DEVICE FILTERING MECHANISM 20 | +M: sergei.shtepa@veeam.com 21 | +L: linux-block@vger.kernel.org 22 | +S: Supported 23 | +F: Documentation/block/blkfilter.rst 24 | + 25 | +BLOCK DEVICE SNAPSHOTS MODULE 26 | +M: sergei.shtepa@veeam.com 27 | +L: linux-block@vger.kernel.org 28 | +S: Supported 29 | +F: Documentation/block/blksnap.rst 30 | +F: drivers/block/blksnap/* 31 | +F: include/uapi/linux/blksnap.h 32 | + 33 | BLOCK LAYER 34 | M: Jens Axboe 35 | L: linux-block@vger.kernel.org 36 | -- 37 | 2.20.1 38 | 39 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8/v2-0001-block-blkfilter-documentation-for-Block-Device-Fi.patch: -------------------------------------------------------------------------------- 1 | From a92c44207af8065f3f0d14bd01fd57209a04fa9b Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 6 Dec 2022 16:18:44 +0100 4 | Subject: [PATCH v2 01/20] block, blkfilter: documentation for Block Device 5 | Filtering Mechanism 6 | 7 | The document contains: 8 | * Describes the purpose of the mechanism 9 | * A little historical background on the capabilities of handling I/O 10 | units of the Linux kernel 11 | * Brief description of the design 12 | 13 | Signed-off-by: Sergei Shtepa 14 | --- 15 | Documentation/block/blkfilter.rst | 39 +++++++++++++++++++++++++++++++ 16 | 1 file changed, 39 insertions(+) 17 | create mode 100644 Documentation/block/blkfilter.rst 18 | 19 | diff --git a/Documentation/block/blkfilter.rst b/Documentation/block/blkfilter.rst 20 | new file mode 100644 21 | index 000000000000..15b07a31b889 22 | --- /dev/null 23 | +++ b/Documentation/block/blkfilter.rst 24 | @@ -0,0 +1,39 @@ 25 | +.. SPDX-License-Identifier: GPL-2.0 26 | + 27 | +================================ 28 | +Block Device Filtering Mechanism 29 | +================================ 30 | + 31 | +The block device filtering mechanism is an API that allows to attach block 32 | +device filters. Block device filters allow perform additional processing 33 | +for I/O units. 34 | + 35 | +Introduction 36 | +============ 37 | + 38 | +The idea of handling I/O units on block devices is not new. Back in the 39 | +2.6 kernel, there was an undocumented possibility of handling I/O units 40 | +by substituting the make_request_fn() function, which belonged to the 41 | +request_queue structure. But no kernel module used this feature, and it 42 | +was eliminated in the 5.10 kernel. 43 | + 44 | +The block device filtering mechanism returns the ability to handle I/O units. 45 | +It is possible to safely attach one filter to a block device "on the fly" 46 | +without changing the structure of block devices. 47 | + 48 | +Design 49 | +====== 50 | + 51 | +The block device filtering mechanism provides functions for attaching and 52 | +detaching the filter. The filter is a structure with a reference counter 53 | +and callback functions. 54 | + 55 | +The submit_bio_cb() callback function is called for each I/O unit for a block 56 | +device, providing I/O unit filtering. Depending on the result of filtering 57 | +the I/O unit, it can either be passed for subsequent processing by the block 58 | +layer, or skipped. 59 | + 60 | +The link counter allows to control the filter lifetime. When the reference 61 | +count is reduced to zero, the detach_cb() callback function is called to 62 | +release the filter. This allows the filter to be released when the block 63 | +device is disconnected. 64 | -- 65 | 2.20.1 66 | 67 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8/v2-0018-block-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 2e7e73fc91172e36310200ded897d8186a3de157 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 6 Dec 2022 16:45:36 +0100 4 | Subject: [PATCH v2 18/20] block, blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 11 | drivers/block/blksnap/Makefile | 18 ++++++++++++++++++ 12 | 2 files changed, 30 insertions(+) 13 | create mode 100644 drivers/block/blksnap/Kconfig 14 | create mode 100644 drivers/block/blksnap/Makefile 15 | 16 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 17 | new file mode 100644 18 | index 000000000000..317a7d13382e 19 | --- /dev/null 20 | +++ b/drivers/block/blksnap/Kconfig 21 | @@ -0,0 +1,12 @@ 22 | +# SPDX-License-Identifier: GPL-2.0 23 | +# 24 | +# Block device snapshot module configuration 25 | +# 26 | + 27 | +config BLK_SNAP 28 | + tristate "Module for snapshots of block devices." 29 | + help 30 | + Allow to create snapshots and track block changes for block devices. 31 | + Designed for creating backups for simple block devices. Snapshots are 32 | + temporary and are released then backup is completed. Change block 33 | + tracking allows to create incremental or differential backups. 34 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 35 | new file mode 100644 36 | index 000000000000..b196b17f9d9d 37 | --- /dev/null 38 | +++ b/drivers/block/blksnap/Makefile 39 | @@ -0,0 +1,18 @@ 40 | +# SPDX-License-Identifier: GPL-2.0 41 | + 42 | +blksnap-y := \ 43 | + cbt_map.o \ 44 | + chunk.o \ 45 | + ctrl.o \ 46 | + diff_io.o \ 47 | + diff_area.o \ 48 | + diff_buffer.o \ 49 | + diff_storage.o \ 50 | + event_queue.o \ 51 | + main.o \ 52 | + snapimage.o \ 53 | + snapshot.o \ 54 | + sysfs.o \ 55 | + tracker.o 56 | + 57 | +obj-$(CONFIG_BLK_SNAP) += blksnap.o 58 | -- 59 | 2.20.1 60 | 61 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8/v2-0019-block-blksnap-adds-a-blksnap-to-the-kernel-tree.patch: -------------------------------------------------------------------------------- 1 | From 4f5317038d90a3c94042a62b5ae3d5cca91c7e04 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 6 Dec 2022 16:46:28 +0100 4 | Subject: [PATCH v2 19/20] block, blksnap: adds a blksnap to the kernel tree 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | drivers/block/Kconfig | 2 ++ 9 | drivers/block/Makefile | 2 ++ 10 | 2 files changed, 4 insertions(+) 11 | 12 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 13 | index a41145d52de9..81304bfdc30c 100644 14 | --- a/drivers/block/Kconfig 15 | +++ b/drivers/block/Kconfig 16 | @@ -416,4 +416,6 @@ config BLK_DEV_UBLK 17 | 18 | source "drivers/block/rnbd/Kconfig" 19 | 20 | +source "drivers/block/blksnap/Kconfig" 21 | + 22 | endif # BLK_DEV 23 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 24 | index 101612cba303..8414c47960c2 100644 25 | --- a/drivers/block/Makefile 26 | +++ b/drivers/block/Makefile 27 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 28 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 29 | 30 | swim_mod-y := swim.o swim_asm.o 31 | + 32 | +obj-$(CONFIG_BLK_SNAP) += blksnap/ 33 | -- 34 | 2.20.1 35 | 36 | -------------------------------------------------------------------------------- /patches/lk6.1-rc8/v2-0020-block-blksnap-adds-a-maintainer-for-new-files.patch: -------------------------------------------------------------------------------- 1 | From 72dbe65ad90e64cab13a684342080bc69f3a34de Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 6 Dec 2022 16:49:16 +0100 4 | Subject: [PATCH v2 20/20] block, blksnap: adds a maintainer for new files 5 | 6 | Signed-off-by: Sergei Shtepa 7 | --- 8 | MAINTAINERS | 14 ++++++++++++++ 9 | 1 file changed, 14 insertions(+) 10 | 11 | diff --git a/MAINTAINERS b/MAINTAINERS 12 | index 1daadaa4d48b..9580bff5bade 100644 13 | --- a/MAINTAINERS 14 | +++ b/MAINTAINERS 15 | @@ -3655,6 +3655,20 @@ M: Jan-Simon Moeller 16 | S: Maintained 17 | F: drivers/leds/leds-blinkm.c 18 | 19 | +BLOCK DEVICE FILTERING MECHANISM 20 | +M: sergei.shtepa@veeam.com 21 | +L: linux-block@vger.kernel.org 22 | +S: Supported 23 | +F: Documentation/block/blkfiter.rst 24 | + 25 | +BLOCK DEVICE SNAPSHOTS MODULE 26 | +M: sergei.shtepa@veeam.com 27 | +L: linux-block@vger.kernel.org 28 | +S: Supported 29 | +F: Documentation/block/blksnap.rst 30 | +F: drivers/block/blksnap/* 31 | +F: include/uapi/linux/blksnap.h 32 | + 33 | BLOCK LAYER 34 | M: Jens Axboe 35 | L: linux-block@vger.kernel.org 36 | -- 37 | 2.20.1 38 | 39 | -------------------------------------------------------------------------------- /patches/lk6.15/0003-use-u64_to_user_ptr-instead-cast-to-pointer-from-int.patch: -------------------------------------------------------------------------------- 1 | From ee58ffbc504a1e82264ff9508f3a2990666a4e34 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 May 2025 09:28:18 +0200 4 | Subject: [PATCH 3/3] use u64_to_user_ptr() instead cast to pointer from 5 | integer 6 | 7 | https://github.com/veeam/blksnap/issues/2#issuecomment-2862638281 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/blksnap/main.c | 2 +- 11 | 1 file changed, 1 insertion(+), 1 deletion(-) 12 | 13 | diff --git a/drivers/block/blksnap/main.c b/drivers/block/blksnap/main.c 14 | index 4e034d412c42..ed29bbde1dba 100644 15 | --- a/drivers/block/blksnap/main.c 16 | +++ b/drivers/block/blksnap/main.c 17 | @@ -185,7 +185,7 @@ static int ioctl_snapshot_create(struct blksnap_snapshot_create __user *uarg) 18 | pr_err("Unable to create snapshot: invalid user buffer\n"); 19 | return -ENODATA; 20 | } 21 | - fname = strndup_user((const char __user *)karg.diff_storage_filename, 22 | + fname = strndup_user(u64_to_user_ptr(karg.diff_storage_filename), 23 | PATH_MAX); 24 | if (IS_ERR(fname)) 25 | return PTR_ERR(fname); 26 | -- 27 | 2.43.0 28 | 29 | -------------------------------------------------------------------------------- /patches/lk6.3-rc4-v2/send_patch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | cat ./v3-* | grep --color='auto' -P -n '[^\x00-\x7F]' 4 | 5 | git send-email --smtp-ssl-cert-path ~/Downloads/prgmbx02.pem \ 6 | --to=axboe@kernel.dk \ 7 | --to=hch@infradead.org \ 8 | --to=corbet@lwn.net \ 9 | --to=snitzer@kernel.org \ 10 | --cc=viro@zeniv.linux.org.uk \ 11 | --cc=brauner@kernel.org \ 12 | --cc=willy@infradead.org \ 13 | --cc=kch@nvidia.com \ 14 | --cc=martin.petersen@oracle.com \ 15 | --cc=vkoul@kernel.org \ 16 | --cc=ming.lei@redhat.com \ 17 | --cc=gregkh@linuxfoundation.org \ 18 | --cc=linux-block@vger.kernel.org \ 19 | --cc=linux-doc@vger.kernel.org \ 20 | --cc=linux-kernel@vger.kernel.org \ 21 | --cc=linux-fsdevel@vger.kernel.org \ 22 | --cc=sergei.shtepa@veeam.com \ 23 | ./v3-0000* ./v3-0001* ./v3-0002* ./v3-0003* ./v3-0004* ./v3-0005* ./v3-0006* ./v3-0007* ./v3-0008* ./v3-0009* ./v3-0010* ./v3-0011* 24 | -------------------------------------------------------------------------------- /patches/lk6.3-rc4-v2/v3-0011-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From dcef3a2c27f2bc9158c1031d9ebb524923e27bba Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Tue, 4 Apr 2023 15:45:23 +0200 4 | Subject: [PATCH v3 11/11] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Co-developed-by: Christoph Hellwig 9 | Signed-off-by: Christoph Hellwig 10 | Signed-off-by: Sergei Shtepa 11 | --- 12 | drivers/block/Kconfig | 2 ++ 13 | drivers/block/Makefile | 2 ++ 14 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 15 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 16 | 4 files changed, 31 insertions(+) 17 | create mode 100644 drivers/block/blksnap/Kconfig 18 | create mode 100644 drivers/block/blksnap/Makefile 19 | 20 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 21 | index f79f20430ef7..5fc38a7ed822 100644 22 | --- a/drivers/block/Kconfig 23 | +++ b/drivers/block/Kconfig 24 | @@ -387,4 +387,6 @@ config BLK_DEV_UBLK 25 | 26 | source "drivers/block/rnbd/Kconfig" 27 | 28 | +source "drivers/block/blksnap/Kconfig" 29 | + 30 | endif # BLK_DEV 31 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 32 | index 101612cba303..9a2a9a56a247 100644 33 | --- a/drivers/block/Makefile 34 | +++ b/drivers/block/Makefile 35 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 36 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 37 | 38 | swim_mod-y := swim.o swim_asm.o 39 | + 40 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 41 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 42 | new file mode 100644 43 | index 000000000000..14081359847b 44 | --- /dev/null 45 | +++ b/drivers/block/blksnap/Kconfig 46 | @@ -0,0 +1,12 @@ 47 | +# SPDX-License-Identifier: GPL-2.0 48 | +# 49 | +# Block device snapshot module configuration 50 | +# 51 | + 52 | +config BLKSNAP 53 | + tristate "Block Devices Snapshots Module (blksnap)" 54 | + help 55 | + Allow to create snapshots and track block changes for block devices. 56 | + Designed for creating backups for simple block devices. Snapshots are 57 | + temporary and are released then backup is completed. Change block 58 | + tracking allows to create incremental or differential backups. 59 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 60 | new file mode 100644 61 | index 000000000000..8d528b95579a 62 | --- /dev/null 63 | +++ b/drivers/block/blksnap/Makefile 64 | @@ -0,0 +1,15 @@ 65 | +# SPDX-License-Identifier: GPL-2.0 66 | + 67 | +blksnap-y := \ 68 | + cbt_map.o \ 69 | + chunk.o \ 70 | + diff_area.o \ 71 | + diff_buffer.o \ 72 | + diff_storage.o \ 73 | + event_queue.o \ 74 | + main.o \ 75 | + snapimage.o \ 76 | + snapshot.o \ 77 | + tracker.o 78 | + 79 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 80 | -- 81 | 2.20.1 82 | 83 | -------------------------------------------------------------------------------- /patches/lk6.3-rc4/v3-0015-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 6bb473d188db3c78dd4a23a3cc1f11b38cf1e683 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Thu, 30 Mar 2023 14:19:01 +0200 4 | Subject: [PATCH v3 15/15] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Signed-off-by: Sergei Shtepa 9 | --- 10 | drivers/block/Kconfig | 2 ++ 11 | drivers/block/Makefile | 2 ++ 12 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 13 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 14 | 4 files changed, 31 insertions(+) 15 | create mode 100644 drivers/block/blksnap/Kconfig 16 | create mode 100644 drivers/block/blksnap/Makefile 17 | 18 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 19 | index f79f20430ef7..5fc38a7ed822 100644 20 | --- a/drivers/block/Kconfig 21 | +++ b/drivers/block/Kconfig 22 | @@ -387,4 +387,6 @@ config BLK_DEV_UBLK 23 | 24 | source "drivers/block/rnbd/Kconfig" 25 | 26 | +source "drivers/block/blksnap/Kconfig" 27 | + 28 | endif # BLK_DEV 29 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 30 | index 101612cba303..9a2a9a56a247 100644 31 | --- a/drivers/block/Makefile 32 | +++ b/drivers/block/Makefile 33 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 34 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 35 | 36 | swim_mod-y := swim.o swim_asm.o 37 | + 38 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 39 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 40 | new file mode 100644 41 | index 000000000000..14081359847b 42 | --- /dev/null 43 | +++ b/drivers/block/blksnap/Kconfig 44 | @@ -0,0 +1,12 @@ 45 | +# SPDX-License-Identifier: GPL-2.0 46 | +# 47 | +# Block device snapshot module configuration 48 | +# 49 | + 50 | +config BLKSNAP 51 | + tristate "Block Devices Snapshots Module (blksnap)" 52 | + help 53 | + Allow to create snapshots and track block changes for block devices. 54 | + Designed for creating backups for simple block devices. Snapshots are 55 | + temporary and are released then backup is completed. Change block 56 | + tracking allows to create incremental or differential backups. 57 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 58 | new file mode 100644 59 | index 000000000000..8d528b95579a 60 | --- /dev/null 61 | +++ b/drivers/block/blksnap/Makefile 62 | @@ -0,0 +1,15 @@ 63 | +# SPDX-License-Identifier: GPL-2.0 64 | + 65 | +blksnap-y := \ 66 | + cbt_map.o \ 67 | + chunk.o \ 68 | + diff_area.o \ 69 | + diff_buffer.o \ 70 | + diff_storage.o \ 71 | + event_queue.o \ 72 | + main.o \ 73 | + snapimage.o \ 74 | + snapshot.o \ 75 | + tracker.o 76 | + 77 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 78 | -- 79 | 2.20.1 80 | 81 | -------------------------------------------------------------------------------- /patches/lk6.4-rc4-v2/v4-0011-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 32b8674e7d2a8fb23f07e87d6de03bee474d12bf Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Wed, 7 Jun 2023 16:46:13 +0200 4 | Subject: [PATCH v4 11/11] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Co-developed-by: Christoph Hellwig 9 | Signed-off-by: Christoph Hellwig 10 | Signed-off-by: Sergei Shtepa 11 | --- 12 | drivers/block/Kconfig | 2 ++ 13 | drivers/block/Makefile | 2 ++ 14 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 15 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 16 | 4 files changed, 31 insertions(+) 17 | create mode 100644 drivers/block/blksnap/Kconfig 18 | create mode 100644 drivers/block/blksnap/Makefile 19 | 20 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 21 | index 5b9d4aaebb81..74d2d55526a3 100644 22 | --- a/drivers/block/Kconfig 23 | +++ b/drivers/block/Kconfig 24 | @@ -404,4 +404,6 @@ config BLKDEV_UBLK_LEGACY_OPCODES 25 | 26 | source "drivers/block/rnbd/Kconfig" 27 | 28 | +source "drivers/block/blksnap/Kconfig" 29 | + 30 | endif # BLK_DEV 31 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 32 | index 101612cba303..9a2a9a56a247 100644 33 | --- a/drivers/block/Makefile 34 | +++ b/drivers/block/Makefile 35 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 36 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 37 | 38 | swim_mod-y := swim.o swim_asm.o 39 | + 40 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 41 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 42 | new file mode 100644 43 | index 000000000000..14081359847b 44 | --- /dev/null 45 | +++ b/drivers/block/blksnap/Kconfig 46 | @@ -0,0 +1,12 @@ 47 | +# SPDX-License-Identifier: GPL-2.0 48 | +# 49 | +# Block device snapshot module configuration 50 | +# 51 | + 52 | +config BLKSNAP 53 | + tristate "Block Devices Snapshots Module (blksnap)" 54 | + help 55 | + Allow to create snapshots and track block changes for block devices. 56 | + Designed for creating backups for simple block devices. Snapshots are 57 | + temporary and are released then backup is completed. Change block 58 | + tracking allows to create incremental or differential backups. 59 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 60 | new file mode 100644 61 | index 000000000000..8d528b95579a 62 | --- /dev/null 63 | +++ b/drivers/block/blksnap/Makefile 64 | @@ -0,0 +1,15 @@ 65 | +# SPDX-License-Identifier: GPL-2.0 66 | + 67 | +blksnap-y := \ 68 | + cbt_map.o \ 69 | + chunk.o \ 70 | + diff_area.o \ 71 | + diff_buffer.o \ 72 | + diff_storage.o \ 73 | + event_queue.o \ 74 | + main.o \ 75 | + snapimage.o \ 76 | + snapshot.o \ 77 | + tracker.o 78 | + 79 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 80 | -- 81 | 2.20.1 82 | 83 | -------------------------------------------------------------------------------- /patches/lk6.4-rc4-v3/v4-0011-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 1963bd0052225d83b48d4b2752f640ee126620a6 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Fri, 9 Jun 2023 11:07:01 +0200 4 | Subject: [PATCH v4 11/11] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Co-developed-by: Christoph Hellwig 9 | Signed-off-by: Christoph Hellwig 10 | Signed-off-by: Sergei Shtepa 11 | --- 12 | drivers/block/Kconfig | 2 ++ 13 | drivers/block/Makefile | 2 ++ 14 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 15 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 16 | 4 files changed, 31 insertions(+) 17 | create mode 100644 drivers/block/blksnap/Kconfig 18 | create mode 100644 drivers/block/blksnap/Makefile 19 | 20 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 21 | index 5b9d4aaebb81..74d2d55526a3 100644 22 | --- a/drivers/block/Kconfig 23 | +++ b/drivers/block/Kconfig 24 | @@ -404,4 +404,6 @@ config BLKDEV_UBLK_LEGACY_OPCODES 25 | 26 | source "drivers/block/rnbd/Kconfig" 27 | 28 | +source "drivers/block/blksnap/Kconfig" 29 | + 30 | endif # BLK_DEV 31 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 32 | index 101612cba303..9a2a9a56a247 100644 33 | --- a/drivers/block/Makefile 34 | +++ b/drivers/block/Makefile 35 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 36 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 37 | 38 | swim_mod-y := swim.o swim_asm.o 39 | + 40 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 41 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 42 | new file mode 100644 43 | index 000000000000..14081359847b 44 | --- /dev/null 45 | +++ b/drivers/block/blksnap/Kconfig 46 | @@ -0,0 +1,12 @@ 47 | +# SPDX-License-Identifier: GPL-2.0 48 | +# 49 | +# Block device snapshot module configuration 50 | +# 51 | + 52 | +config BLKSNAP 53 | + tristate "Block Devices Snapshots Module (blksnap)" 54 | + help 55 | + Allow to create snapshots and track block changes for block devices. 56 | + Designed for creating backups for simple block devices. Snapshots are 57 | + temporary and are released then backup is completed. Change block 58 | + tracking allows to create incremental or differential backups. 59 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 60 | new file mode 100644 61 | index 000000000000..8d528b95579a 62 | --- /dev/null 63 | +++ b/drivers/block/blksnap/Makefile 64 | @@ -0,0 +1,15 @@ 65 | +# SPDX-License-Identifier: GPL-2.0 66 | + 67 | +blksnap-y := \ 68 | + cbt_map.o \ 69 | + chunk.o \ 70 | + diff_area.o \ 71 | + diff_buffer.o \ 72 | + diff_storage.o \ 73 | + event_queue.o \ 74 | + main.o \ 75 | + snapimage.o \ 76 | + snapshot.o \ 77 | + tracker.o 78 | + 79 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 80 | -- 81 | 2.20.1 82 | 83 | -------------------------------------------------------------------------------- /patches/lk6.4-rc4/v4-0011-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From 8fe5fc07736ca3f63116b23daa97c9b7d12dd7bb Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Mon, 5 Jun 2023 16:54:17 +0200 4 | Subject: [PATCH v4 11/11] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Co-developed-by: Christoph Hellwig 9 | Signed-off-by: Christoph Hellwig 10 | Signed-off-by: Sergei Shtepa 11 | --- 12 | drivers/block/Kconfig | 2 ++ 13 | drivers/block/Makefile | 2 ++ 14 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 15 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 16 | 4 files changed, 31 insertions(+) 17 | create mode 100644 drivers/block/blksnap/Kconfig 18 | create mode 100644 drivers/block/blksnap/Makefile 19 | 20 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 21 | index 5b9d4aaebb81..74d2d55526a3 100644 22 | --- a/drivers/block/Kconfig 23 | +++ b/drivers/block/Kconfig 24 | @@ -404,4 +404,6 @@ config BLKDEV_UBLK_LEGACY_OPCODES 25 | 26 | source "drivers/block/rnbd/Kconfig" 27 | 28 | +source "drivers/block/blksnap/Kconfig" 29 | + 30 | endif # BLK_DEV 31 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 32 | index 101612cba303..9a2a9a56a247 100644 33 | --- a/drivers/block/Makefile 34 | +++ b/drivers/block/Makefile 35 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 36 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 37 | 38 | swim_mod-y := swim.o swim_asm.o 39 | + 40 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 41 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 42 | new file mode 100644 43 | index 000000000000..14081359847b 44 | --- /dev/null 45 | +++ b/drivers/block/blksnap/Kconfig 46 | @@ -0,0 +1,12 @@ 47 | +# SPDX-License-Identifier: GPL-2.0 48 | +# 49 | +# Block device snapshot module configuration 50 | +# 51 | + 52 | +config BLKSNAP 53 | + tristate "Block Devices Snapshots Module (blksnap)" 54 | + help 55 | + Allow to create snapshots and track block changes for block devices. 56 | + Designed for creating backups for simple block devices. Snapshots are 57 | + temporary and are released then backup is completed. Change block 58 | + tracking allows to create incremental or differential backups. 59 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 60 | new file mode 100644 61 | index 000000000000..8d528b95579a 62 | --- /dev/null 63 | +++ b/drivers/block/blksnap/Makefile 64 | @@ -0,0 +1,15 @@ 65 | +# SPDX-License-Identifier: GPL-2.0 66 | + 67 | +blksnap-y := \ 68 | + cbt_map.o \ 69 | + chunk.o \ 70 | + diff_area.o \ 71 | + diff_buffer.o \ 72 | + diff_storage.o \ 73 | + event_queue.o \ 74 | + main.o \ 75 | + snapimage.o \ 76 | + snapshot.o \ 77 | + tracker.o 78 | + 79 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 80 | -- 81 | 2.20.1 82 | 83 | -------------------------------------------------------------------------------- /patches/lk6.5-block/v5-0011-blksnap-Kconfig-and-Makefile.patch: -------------------------------------------------------------------------------- 1 | From e5e8263c83f3bec3a70f898d01aae280dc6e9d98 Mon Sep 17 00:00:00 2001 2 | From: Sergei Shtepa 3 | Date: Mon, 12 Jun 2023 12:56:35 +0200 4 | Subject: [PATCH v5 11/11] blksnap: Kconfig and Makefile 5 | 6 | Allows to build a module and add the blksnap to the kernel tree. 7 | 8 | Co-developed-by: Christoph Hellwig 9 | Signed-off-by: Christoph Hellwig 10 | Signed-off-by: Sergei Shtepa 11 | --- 12 | drivers/block/Kconfig | 2 ++ 13 | drivers/block/Makefile | 2 ++ 14 | drivers/block/blksnap/Kconfig | 12 ++++++++++++ 15 | drivers/block/blksnap/Makefile | 15 +++++++++++++++ 16 | 4 files changed, 31 insertions(+) 17 | create mode 100644 drivers/block/blksnap/Kconfig 18 | create mode 100644 drivers/block/blksnap/Makefile 19 | 20 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig 21 | index 5b9d4aaebb81..74d2d55526a3 100644 22 | --- a/drivers/block/Kconfig 23 | +++ b/drivers/block/Kconfig 24 | @@ -404,4 +404,6 @@ config BLKDEV_UBLK_LEGACY_OPCODES 25 | 26 | source "drivers/block/rnbd/Kconfig" 27 | 28 | +source "drivers/block/blksnap/Kconfig" 29 | + 30 | endif # BLK_DEV 31 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile 32 | index 101612cba303..9a2a9a56a247 100644 33 | --- a/drivers/block/Makefile 34 | +++ b/drivers/block/Makefile 35 | @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ 36 | obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o 37 | 38 | swim_mod-y := swim.o swim_asm.o 39 | + 40 | +obj-$(CONFIG_BLKSNAP) += blksnap/ 41 | diff --git a/drivers/block/blksnap/Kconfig b/drivers/block/blksnap/Kconfig 42 | new file mode 100644 43 | index 000000000000..14081359847b 44 | --- /dev/null 45 | +++ b/drivers/block/blksnap/Kconfig 46 | @@ -0,0 +1,12 @@ 47 | +# SPDX-License-Identifier: GPL-2.0 48 | +# 49 | +# Block device snapshot module configuration 50 | +# 51 | + 52 | +config BLKSNAP 53 | + tristate "Block Devices Snapshots Module (blksnap)" 54 | + help 55 | + Allow to create snapshots and track block changes for block devices. 56 | + Designed for creating backups for simple block devices. Snapshots are 57 | + temporary and are released then backup is completed. Change block 58 | + tracking allows to create incremental or differential backups. 59 | diff --git a/drivers/block/blksnap/Makefile b/drivers/block/blksnap/Makefile 60 | new file mode 100644 61 | index 000000000000..8d528b95579a 62 | --- /dev/null 63 | +++ b/drivers/block/blksnap/Makefile 64 | @@ -0,0 +1,15 @@ 65 | +# SPDX-License-Identifier: GPL-2.0 66 | + 67 | +blksnap-y := \ 68 | + cbt_map.o \ 69 | + chunk.o \ 70 | + diff_area.o \ 71 | + diff_buffer.o \ 72 | + diff_storage.o \ 73 | + event_queue.o \ 74 | + main.o \ 75 | + snapimage.o \ 76 | + snapshot.o \ 77 | + tracker.o 78 | + 79 | +obj-$(CONFIG_BLKSNAP) += blksnap.o 80 | -- 81 | 2.20.1 82 | 83 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/blksnap-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/blksnap 2 | usr/lib 3 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/blksnap-tests.install: -------------------------------------------------------------------------------- 1 | opt/blksnap/tests 2 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/blksnap-tools.install: -------------------------------------------------------------------------------- 1 | usr/sbin/blksnap 2 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/blksnap-tools.manpages: -------------------------------------------------------------------------------- 1 | doc/blksnap.8 2 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/control: -------------------------------------------------------------------------------- 1 | Source: blksnap 2 | Section: admin 3 | Priority: optional 4 | Maintainer: Veeam Software Group GmbH 5 | Build-Depends: 6 | bash, 7 | cmake, 8 | debhelper (>= 10.0.0), 9 | g++, 10 | libboost-filesystem-dev, 11 | libboost-program-options-dev, 12 | libssl-dev, 13 | uuid-dev, 14 | Homepage: https://github.org/veeam/blksnap 15 | 16 | Package: blksnap-dev 17 | Architecture: linux-any 18 | Section: libdevel 19 | Depends: ${misc:Depends} 20 | Description: blksnap - development package 21 | Blksnap provides the ability to create non-persistent snapshots on 22 | any block device and keep track of changed blocks. 23 | It make possible do consistent backup without having to configure (or remake) 24 | a system with restrictions in the filesystem choice or using LVM 25 | . 26 | This package contains the static library and header files for blksnap 27 | 28 | Package: blksnap-tests 29 | Architecture: linux-any 30 | Section: utils 31 | Depends: bash, blksnap-tools, ${misc:Depends}, ${shlibs:Depends} 32 | Description: blksnap - package with testing scripts 33 | Blksnap provides the ability to create non-persistent snapshots on 34 | any block device and keep track of changed blocks. 35 | It make possible do consistent backup without having to configure (or remake) 36 | a system with restrictions in the filesystem choice or using LVM 37 | . 38 | The test scripts are written in bash and use the blksnap tool to control 39 | the blksnap module. The test scripts allow to check the main functions of 40 | the module. To implement complex test algorithms, С++ tests are implemented. 41 | . 42 | This package contains scripts for blksnap testing 43 | 44 | Package: blksnap-tools 45 | Architecture: linux-any 46 | Depends: ${misc:Depends}, ${shlibs:Depends} 47 | Description: blksnap - utility package 48 | Blksnap provides the ability to create non-persistent snapshots on 49 | any block device and keep track of changed blocks. 50 | It make possible do consistent backup without having to configure (or remake) 51 | a system with restrictions in the filesystem choice or using LVM 52 | . 53 | The blksnap tool allows to manage the module from the command line. 54 | The program allows for execution of individual ioctls of the blksnap module. 55 | The interface of the program may seem inconvenient to the user, 56 | since it is assumed that it will be called by other applications. 57 | . 58 | This package contains the command line tool for use blksnap 59 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: blksnap 3 | Source: https://github.org/veeam/blksnap 4 | Files-Excluded: patches/ pkg/ 5 | 6 | Files: * 7 | Copyright: 2022 Veeam Software Group GmbH 8 | License: GPL-2+ 9 | 10 | Files: lib/* 11 | include/* 12 | Copyright: 2022, Veeam Software Group GmbH 13 | License: LGPL-3+ 14 | 15 | 16 | License: GPL-2+ 17 | This package is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU General Public License as published by 19 | the Free Software Foundation; either version 2 of the License, or 20 | (at your option) any later version. 21 | . 22 | This package is distributed in the hope that it will be useful, 23 | but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | GNU General Public License for more details. 26 | . 27 | You should have received a copy of the GNU General Public License 28 | along with this program. If not, see . 29 | . 30 | On Debian systems, the complete text of the GNU General Public License 31 | version 2 can be found in `/usr/share/common-licenses/GPL-2'. 32 | 33 | License: LGPL-3+ 34 | This program is free software; you can redistribute it and/or modify it under 35 | the terms of the GNU Library General Public License as published by the Free 36 | Software Foundation; either version 3 of the License, or (at your option) any 37 | later version. 38 | . 39 | This program is distributed in the hope that it will be useful, but WITHOUT 40 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 41 | FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for 42 | more details. 43 | . 44 | You should have received a copy of the GNU General Public License 45 | along with this program. If not, see . 46 | . 47 | On Debian systems, the complete text of the GNU Library General Public License 48 | version 3 can be found in `/usr/share/common-licenses/LGPL-3'. 49 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | include /usr/share/dpkg/default.mk 4 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 5 | DPKG_EXPORT_BUILDFLAGS = 1 6 | CFLAGS+=$(CPPFLAGS) 7 | CXXFLAGS+=$(CPPFLAGS) 8 | 9 | 10 | DEB_CMAKE_EXTRA_FLAGS = \ 11 | -DCMAKE_INSTALL_PREFIX=/usr \ 12 | -DCMAKE_BUILD_TYPE=RelWithDebInfo 13 | 14 | %: 15 | dh $@ 16 | 17 | override_dh_auto_configure: 18 | dh_auto_configure -- $(DEB_CMAKE_EXTRA_FLAGS) 19 | 20 | -------------------------------------------------------------------------------- /pkg/deb/blksnap/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /pkg/deb/build-blksnap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ -n "$1" ] 4 | then 5 | VERSION="$1" 6 | else 7 | VERSION="2.0.0.0" 8 | fi 9 | 10 | CURR_DIR=$(pwd) 11 | cd "../../" 12 | 13 | # prepare debian directory 14 | rm -rf ./debian 15 | cp -r ${CURR_DIR}/blksnap ./debian 16 | 17 | cat > ./debian/changelog << EOF 18 | blksnap (${VERSION}) stable; urgency=low 19 | 20 | * Release. 21 | -- Veeam Software Group GmbH $(date -R) 22 | EOF 23 | 24 | # build backage 25 | dpkg-buildpackage -us -uc -b 26 | 27 | cd ${CURR_DIR} 28 | -------------------------------------------------------------------------------- /tests/1000-simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | 6 | if [ -z $1 ] 7 | then 8 | DIFF_STORAGE_DIR=${HOME} 9 | else 10 | DIFF_STORAGE_DIR=$1 11 | fi 12 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 13 | 14 | . ./functions.sh 15 | . ./blksnap.sh 16 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 17 | 18 | echo "---" 19 | echo "Simple test start" 20 | 21 | blksnap_load 22 | 23 | # check module is ready 24 | blksnap_version 25 | 26 | TESTDIR=${HOME}/blksnap-test 27 | rm -rf ${TESTDIR} 28 | mkdir -p ${TESTDIR} 29 | 30 | MPDIR=/mnt/blksnap-test 31 | rm -rf ${MPDIR} 32 | mkdir -p ${MPDIR} 33 | 34 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 35 | fallocate --length 4KiB ${DIFF_STORAGE} 36 | 37 | # create first device 38 | IMAGEFILE_1=${TESTDIR}/simple_1.img 39 | imagefile_make ${IMAGEFILE_1} 64 40 | 41 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 42 | mkfs.ext4 ${DEVICE_1} 43 | echo "new device ${DEVICE_1}" 44 | 45 | MOUNTPOINT_1=${MPDIR}/simple_1 46 | mkdir -p ${MOUNTPOINT_1} 47 | mount ${DEVICE_1} ${MOUNTPOINT_1} 48 | 49 | # create second device 50 | IMAGEFILE_2=${TESTDIR}/simple_2.img 51 | imagefile_make ${IMAGEFILE_2} 128 52 | 53 | DEVICE_2=$(loop_device_attach ${IMAGEFILE_2} ${BLOCK_SIZE}) 54 | mkfs.ext4 ${DEVICE_2} 55 | echo "new device ${DEVICE_2}" 56 | 57 | MOUNTPOINT_2=${MPDIR}/simple_2 58 | mkdir -p ${MOUNTPOINT_2} 59 | mount ${DEVICE_2} ${MOUNTPOINT_2} 60 | 61 | generate_files_direct ${MOUNTPOINT_1} "before" 9 62 | drop_cache 63 | 64 | #echo "Block device prepared, press ..." 65 | #read -n 1 66 | 67 | blksnap_snapshot_create "${DEVICE_1} ${DEVICE_2}" "${DIFF_STORAGE}" "2G" 68 | blksnap_snapshot_take 69 | 70 | #echo "Snapshot was token, press ..." 71 | #read -n 1 72 | 73 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 74 | echo "Write to original" 75 | generate_files_direct ${MOUNTPOINT_1} "after" 3 76 | drop_cache 77 | 78 | check_files ${MOUNTPOINT_1} 79 | 80 | echo "Check snapshots" 81 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 82 | IMAGE_1=${TESTDIR}/image0 83 | mkdir -p ${IMAGE_1} 84 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 85 | #echo "pause, press ..." 86 | #read -n 1 87 | check_files ${IMAGE_1} 88 | 89 | echo "Write to snapshot" 90 | generate_files_direct ${IMAGE_1} "snapshot" 3 91 | 92 | drop_cache 93 | umount ${DEVICE_IMAGE_1} 94 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 95 | 96 | #echo "pause, press ..." 97 | #read -n 1 98 | check_files ${IMAGE_1} 99 | 100 | umount ${IMAGE_1} 101 | 102 | blksnap_snapshot_destroy 103 | 104 | #echo "Destroy snapshot, press ..." 105 | #read -n 1 106 | 107 | drop_cache 108 | umount ${DEVICE_1} 109 | mount ${DEVICE_1} ${MOUNTPOINT_1} 110 | 111 | check_files ${MOUNTPOINT_1} 112 | 113 | echo "Destroy second device" 114 | blksnap_detach ${DEVICE_2} 115 | umount ${MOUNTPOINT_2} 116 | loop_device_detach ${DEVICE_2} 117 | imagefile_cleanup ${IMAGEFILE_2} 118 | 119 | echo "Destroy first device" 120 | blksnap_detach ${DEVICE_1} 121 | umount ${MOUNTPOINT_1} 122 | loop_device_detach ${DEVICE_1} 123 | imagefile_cleanup ${IMAGEFILE_1} 124 | 125 | blksnap_unload 126 | 127 | echo "Simple test finish" 128 | echo "---" 129 | -------------------------------------------------------------------------------- /tests/1100-loop_diff_storage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ./functions.sh 6 | . ./blksnap.sh 7 | 8 | BLk_SZ=128 9 | 10 | echo "---" 11 | echo "Simple test start" 12 | 13 | # diff_storage_minimum=65536 - set 64 K sectors, it's 32MiB diff_storage portion size 14 | blksnap_load "diff_storage_minimum=65536" 15 | 16 | # check module is ready 17 | blksnap_version 18 | 19 | TESTDIR=${HOME}/blksnap-test 20 | rm -rf ${TESTDIR} 21 | mkdir -p ${TESTDIR} 22 | 23 | MPDIR=/mnt/blksnap-test 24 | rm -rf ${MPDIR} 25 | mkdir -p ${MPDIR} 26 | 27 | # create difference storage device 28 | DIFF_STOGAGE_FILE=${TESTDIR}/diff_storage.img 29 | imagefile_make ${DIFF_STOGAGE_FILE} ${BLk_SZ} 30 | 31 | DIFF_STOGAGE_DEVICE=$(loop_device_attach ${DIFF_STOGAGE_FILE}) 32 | echo "new device ${DIFF_STOGAGE_DEVICE}" 33 | 34 | # create first device 35 | IMAGEFILE_1=${TESTDIR}/simple_1.img 36 | imagefile_make ${IMAGEFILE_1} ${BLk_SZ} 37 | 38 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1}) 39 | mkfs.ext4 ${DEVICE_1} 40 | echo "new device ${DEVICE_1}" 41 | 42 | MOUNTPOINT_1=${MPDIR}/simple_1 43 | mkdir -p ${MOUNTPOINT_1} 44 | mount ${DEVICE_1} ${MOUNTPOINT_1} 45 | 46 | generate_files_direct ${MOUNTPOINT_1} "before" 9 47 | drop_cache 48 | 49 | #echo "Block device prepared, press ..." 50 | #read -n 1 51 | 52 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STOGAGE_DEVICE}" "${BLk_SZ}M" 53 | blksnap_snapshot_take 54 | 55 | #echo "Snapshot was token, press ..." 56 | #read -n 1 57 | 58 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 59 | echo "Write to original" 60 | generate_files_direct ${MOUNTPOINT_1} "after" 3 61 | drop_cache 62 | 63 | check_files ${MOUNTPOINT_1} 64 | 65 | echo "Check snapshots" 66 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 67 | IMAGE_1=${TESTDIR}/image0 68 | mkdir -p ${IMAGE_1} 69 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 70 | #echo "pause, press ..." 71 | #read -n 1 72 | check_files ${IMAGE_1} 73 | 74 | echo "Write to snapshot" 75 | generate_files_direct ${IMAGE_1} "snapshot" 3 76 | 77 | drop_cache 78 | umount ${DEVICE_IMAGE_1} 79 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 80 | 81 | #echo "pause, press ..." 82 | #read -n 1 83 | check_files ${IMAGE_1} 84 | 85 | umount ${IMAGE_1} 86 | 87 | blksnap_snapshot_destroy 88 | 89 | #echo "Destroy snapshot, press ..." 90 | #read -n 1 91 | 92 | drop_cache 93 | umount ${DEVICE_1} 94 | mount ${DEVICE_1} ${MOUNTPOINT_1} 95 | 96 | check_files ${MOUNTPOINT_1} 97 | 98 | echo "Destroy first device" 99 | blksnap_detach ${DEVICE_1} 100 | umount ${MOUNTPOINT_1} 101 | loop_device_detach ${DEVICE_1} 102 | imagefile_cleanup ${IMAGEFILE_1} 103 | 104 | echo "Destroy diff storage device" 105 | loop_device_detach ${DIFF_STOGAGE_DEVICE} 106 | imagefile_cleanup ${DIFF_STOGAGE_FILE} 107 | 108 | blksnap_unload 109 | 110 | echo "Simple test finish" 111 | echo "---" 112 | -------------------------------------------------------------------------------- /tests/1200-tmpfs_diff_storage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | BLK_SZ=128 6 | 7 | if [ -z $1 ] 8 | then 9 | DIFF_STORAGE_DIR=${HOME}/tmp 10 | else 11 | DIFF_STORAGE_DIR=$1/tmp 12 | fi 13 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 14 | 15 | . ./functions.sh 16 | . ./blksnap.sh 17 | 18 | echo "---" 19 | echo "Simple test start" 20 | 21 | # diff_storage_minimum=65536 - set 64 K sectors, it's 32MiB diff_storage portion size 22 | blksnap_load "diff_storage_minimum=65536" 23 | 24 | # check module is ready 25 | blksnap_version 26 | 27 | TESTDIR=${HOME}/blksnap-test 28 | rm -rf ${TESTDIR} 29 | mkdir -p ${TESTDIR} 30 | 31 | MPDIR=/mnt/blksnap-test 32 | rm -rf ${MPDIR} 33 | mkdir -p ${MPDIR} 34 | 35 | mkdir -p ${DIFF_STORAGE_DIR} 36 | mount -t tmpfs -o size=${BLK_SZ}M diff_st ${DIFF_STORAGE_DIR} 37 | 38 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 39 | fallocate --length 32MiB ${DIFF_STORAGE} 40 | 41 | # create device 42 | IMAGEFILE_1=${TESTDIR}/simple_1.img 43 | imagefile_make ${IMAGEFILE_1} ${BLK_SZ} 44 | 45 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1}) 46 | mkfs.ext4 ${DEVICE_1} 47 | echo "new device ${DEVICE_1}" 48 | 49 | MOUNTPOINT_1=${MPDIR}/simple_1 50 | mkdir -p ${MOUNTPOINT_1} 51 | mount ${DEVICE_1} ${MOUNTPOINT_1} 52 | 53 | generate_files_direct ${MOUNTPOINT_1} "before" 9 54 | drop_cache 55 | 56 | #echo "Block device prepared, press ..." 57 | #read -n 1 58 | 59 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE}" "2G" 60 | blksnap_snapshot_take 61 | 62 | #echo "Snapshot was token, press ..." 63 | #read -n 1 64 | 65 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 66 | echo "Write to original" 67 | generate_files_direct ${MOUNTPOINT_1} "after" 3 68 | drop_cache 69 | 70 | check_files ${MOUNTPOINT_1} 71 | 72 | echo "Check snapshots" 73 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 74 | IMAGE_1=${TESTDIR}/image0 75 | mkdir -p ${IMAGE_1} 76 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 77 | #echo "pause, press ..." 78 | #read -n 1 79 | check_files ${IMAGE_1} 80 | 81 | echo "Write to snapshot" 82 | generate_files_direct ${IMAGE_1} "snapshot" 3 83 | 84 | drop_cache 85 | umount ${DEVICE_IMAGE_1} 86 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 87 | 88 | #echo "pause, press ..." 89 | #read -n 1 90 | check_files ${IMAGE_1} 91 | 92 | umount ${IMAGE_1} 93 | 94 | blksnap_snapshot_destroy 95 | 96 | #echo "Destroy snapshot, press ..." 97 | #read -n 1 98 | 99 | drop_cache 100 | umount ${DEVICE_1} 101 | mount ${DEVICE_1} ${MOUNTPOINT_1} 102 | 103 | check_files ${MOUNTPOINT_1} 104 | 105 | echo "Destroy device" 106 | blksnap_detach ${DEVICE_1} 107 | umount ${MOUNTPOINT_1} 108 | loop_device_detach ${DEVICE_1} 109 | imagefile_cleanup ${IMAGEFILE_1} 110 | 111 | umount ${DIFF_STORAGE_DIR} 112 | 113 | blksnap_unload 114 | 115 | echo "Simple test finish" 116 | echo "---" 117 | -------------------------------------------------------------------------------- /tests/1300-tmpfile_diff_storage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | 6 | if [ -z $1 ] 7 | then 8 | DIFF_STORAGE_DIR=${HOME} 9 | else 10 | DIFF_STORAGE_DIR=$1 11 | fi 12 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 13 | 14 | . ./functions.sh 15 | . ./blksnap.sh 16 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 17 | 18 | echo "---" 19 | echo "Simple test start" 20 | echo "devices block size ${BLOCK_SIZE}" 21 | 22 | blksnap_load 23 | 24 | # check module is ready 25 | blksnap_version 26 | 27 | TESTDIR=${HOME}/blksnap-test 28 | rm -rf ${TESTDIR} 29 | mkdir -p ${TESTDIR} 30 | 31 | MPDIR=/mnt/blksnap-test 32 | rm -rf ${MPDIR} 33 | mkdir -p ${MPDIR} 34 | 35 | # create first device 36 | IMAGEFILE_1=${TESTDIR}/simple_1.img 37 | imagefile_make ${IMAGEFILE_1} 64 38 | 39 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 40 | mkfs.ext4 ${DEVICE_1} 41 | echo "new device ${DEVICE_1}" 42 | 43 | MOUNTPOINT_1=${MPDIR}/simple_1 44 | mkdir -p ${MOUNTPOINT_1} 45 | mount ${DEVICE_1} ${MOUNTPOINT_1} 46 | 47 | generate_files_direct ${MOUNTPOINT_1} "before" 9 48 | drop_cache 49 | 50 | #echo "Block device prepared, press ..." 51 | #read -n 1 52 | 53 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE_DIR}" "2G" 54 | blksnap_snapshot_take 55 | 56 | #echo "Snapshot was token, press ..." 57 | #read -n 1 58 | 59 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 60 | echo "Write to original" 61 | generate_files_direct ${MOUNTPOINT_1} "after" 3 62 | drop_cache 63 | 64 | check_files ${MOUNTPOINT_1} 65 | 66 | echo "Check snapshots" 67 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 68 | IMAGE_1=${TESTDIR}/image0 69 | mkdir -p ${IMAGE_1} 70 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 71 | #echo "pause, press ..." 72 | #read -n 1 73 | check_files ${IMAGE_1} 74 | 75 | echo "Write to snapshot" 76 | generate_files_direct ${IMAGE_1} "snapshot" 3 77 | 78 | drop_cache 79 | umount ${DEVICE_IMAGE_1} 80 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 81 | 82 | #echo "pause, press ..." 83 | #read -n 1 84 | check_files ${IMAGE_1} 85 | 86 | umount ${IMAGE_1} 87 | 88 | blksnap_snapshot_destroy 89 | 90 | #echo "Destroy snapshot, press ..." 91 | #read -n 1 92 | 93 | drop_cache 94 | umount ${DEVICE_1} 95 | mount ${DEVICE_1} ${MOUNTPOINT_1} 96 | 97 | check_files ${MOUNTPOINT_1} 98 | 99 | echo "Destroy first device" 100 | blksnap_detach ${DEVICE_1} 101 | umount ${MOUNTPOINT_1} 102 | loop_device_detach ${DEVICE_1} 103 | imagefile_cleanup ${IMAGEFILE_1} 104 | 105 | blksnap_unload 106 | 107 | echo "Simple test finish" 108 | echo "---" 109 | -------------------------------------------------------------------------------- /tests/1400-simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | 6 | if [ -z $1 ] 7 | then 8 | echo "Should be specified empty test block device." 9 | exit 255 10 | else 11 | DEVICE=$1 12 | fi 13 | 14 | if [ -z $2 ] 15 | then 16 | DIFF_STORAGE_DIR=${HOME} 17 | else 18 | DIFF_STORAGE_DIR=$1 19 | fi 20 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 21 | 22 | . ./functions.sh 23 | . ./blksnap.sh 24 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 25 | 26 | echo "---" 27 | echo "Simple test start" 28 | 29 | blksnap_load 30 | 31 | # check module is ready 32 | blksnap_version 33 | 34 | MPDIR=/mnt/blksnap-test 35 | rm -rf ${MPDIR} 36 | mkdir -p ${MPDIR} 37 | 38 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 39 | fallocate --length 4KiB ${DIFF_STORAGE} 40 | 41 | echo "Create new filesystem on ${DEVICE}" 42 | #echo "press ..." 43 | #read -n 1 44 | mkfs.ext4 ${DEVICE} 45 | 46 | MOUNTPOINT=${MPDIR}/simple 47 | mkdir -p ${MOUNTPOINT} 48 | mount ${DEVICE} ${MOUNTPOINT} 49 | 50 | generate_files_direct ${MOUNTPOINT} "before" 9 51 | drop_cache 52 | 53 | #echo "Block device prepared, press ..." 54 | #read -n 1 55 | 56 | blksnap_snapshot_create "${DEVICE}" "${DIFF_STORAGE}" "2G" 57 | blksnap_snapshot_take 58 | 59 | #echo "Snapshot was token, press ..." 60 | #read -n 1 61 | 62 | #echo "Write something" > ${MOUNTPOINT}/something.txt 63 | echo "Write to original" 64 | generate_files_direct ${MOUNTPOINT} "after" 3 65 | drop_cache 66 | 67 | check_files ${MOUNTPOINT} 68 | 69 | echo "Check snapshots" 70 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 71 | IMAGE=${TESTDIR}/image0 72 | mkdir -p ${IMAGE} 73 | mount ${DEVICE_IMAGE} ${IMAGE} 74 | #echo "pause, press ..." 75 | #read -n 1 76 | check_files ${IMAGE} 77 | 78 | echo "Write to snapshot" 79 | generate_files_direct ${IMAGE} "snapshot" 3 80 | 81 | drop_cache 82 | umount ${DEVICE_IMAGE} 83 | mount ${DEVICE_IMAGE} ${IMAGE} 84 | 85 | #echo "pause, press ..." 86 | #read -n 1 87 | check_files ${IMAGE} 88 | 89 | umount ${IMAGE} 90 | 91 | blksnap_snapshot_destroy 92 | 93 | #echo "Destroy snapshot, press ..." 94 | #read -n 1 95 | 96 | drop_cache 97 | umount ${DEVICE} 98 | mount ${DEVICE} ${MOUNTPOINT} 99 | 100 | check_files ${MOUNTPOINT} 101 | 102 | echo "Destroy first device" 103 | blksnap_detach ${DEVICE} 104 | umount ${MOUNTPOINT} 105 | 106 | blksnap_unload 107 | 108 | echo "Simple test finish" 109 | echo "---" 110 | -------------------------------------------------------------------------------- /tests/2000-stretch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | 12 | . ./functions.sh 13 | . ./blksnap.sh 14 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 15 | 16 | echo "---" 17 | echo "Stretch snapshot test" 18 | 19 | # diff_storage_minimum=262144 - set 256 K sectors, it's 128MiB diff_storage portion size 20 | blksnap_load "diff_storage_minimum=262144" 21 | 22 | # check module is ready 23 | blksnap_version 24 | 25 | TESTDIR=${HOME}/blksnap-test 26 | MPDIR=/mnt/blksnap-test 27 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 28 | 29 | rm -rf ${TESTDIR} 30 | rm -rf ${MPDIR} 31 | mkdir -p ${TESTDIR} 32 | mkdir -p ${MPDIR} 33 | 34 | # create first device 35 | IMAGEFILE_1=${TESTDIR}/simple_1.img 36 | imagefile_make ${IMAGEFILE_1} 4096 37 | 38 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 39 | mkfs.ext4 ${DEVICE_1} 40 | echo "new device ${DEVICE_1}" 41 | 42 | MOUNTPOINT_1=${MPDIR}/simple_1 43 | mkdir -p ${MOUNTPOINT_1} 44 | mount ${DEVICE_1} ${MOUNTPOINT_1} 45 | 46 | generate_files_direct ${MOUNTPOINT_1} "before" 5 47 | drop_cache 48 | 49 | rm -f ${DIFF_STORAGE} 50 | fallocate --length 128MiB ${DIFF_STORAGE} 51 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE}" "512M" 52 | 53 | generate_files_direct ${MOUNTPOINT_1} "tracked" 5 54 | drop_cache 55 | 56 | blksnap_snapshot_watcher 57 | #echo "Press for taking snapshot..." 58 | #read -n 1 59 | 60 | blksnap_snapshot_take 61 | 62 | generate_block_MB ${MOUNTPOINT_1} "after" 100 63 | check_files ${MOUNTPOINT_1} 64 | 65 | echo "Check snapshot before overflow." 66 | #echo "press..." 67 | #read -n 1 68 | 69 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 70 | IMAGE_1=${MPDIR}/image0 71 | mkdir -p ${IMAGE_1} 72 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 73 | check_files ${IMAGE_1} 74 | 75 | echo "Try to make snapshot overflow." 76 | #echo "press..." 77 | generate_block_MB ${MOUNTPOINT_1} "overflow" 768 78 | 79 | echo "Umount images" 80 | #echo "press..." 81 | umount ${IMAGE_1} 82 | 83 | echo "Destroy snapshot" 84 | #echo "press..." 85 | blksnap_snapshot_destroy 86 | blksnap_watcher_wait 87 | 88 | #echo "Check generated data" 89 | #check_files ${MOUNTPOINT_1} 90 | 91 | echo "Destroy device" 92 | #echo "press..." 93 | blksnap_detach ${DEVICE_1} 94 | umount ${MOUNTPOINT_1} 95 | loop_device_detach ${DEVICE_1} 96 | imagefile_cleanup ${IMAGEFILE_1} 97 | 98 | blksnap_unload 99 | 100 | echo "Stretch snapshot test finish" 101 | echo "---" 102 | -------------------------------------------------------------------------------- /tests/2100-overflow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR="/dev/shm" 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 12 | 13 | . ./functions.sh 14 | . ./blksnap.sh 15 | 16 | echo "---" 17 | echo "Overflow snapshot test" 18 | 19 | # diff_storage_minimum=262144 - set 256 K sectors, it's 128MiB diff_storage portion size 20 | blksnap_load "diff_storage_minimum=262144" 21 | 22 | # check module is ready 23 | blksnap_version 24 | 25 | TESTDIR=/root/blksnap-test 26 | MPDIR=/mnt/blksnap-test 27 | 28 | mkdir -p ${TESTDIR} 29 | rm -rf ${TESTDIR}/* 30 | mkdir -p ${MPDIR} 31 | rm -rf ${MPDIR}*/ 32 | 33 | MPTESTDIR=$(stat -c %m ${TESTDIR}) 34 | DEVICE="/dev/block/"$(mountpoint -d ${MPTESTDIR}) 35 | 36 | generate_files_direct ${TESTDIR} "before" 5 37 | drop_cache 38 | 39 | rm -f ${DIFF_STORAGE} 40 | fallocate --length 128MiB ${DIFF_STORAGE} 41 | blksnap_snapshot_create "${DEVICE}" "${DIFF_STORAGE}" "512M" 42 | 43 | generate_files_direct ${TESTDIR} "tracked" 5 44 | drop_cache 45 | 46 | blksnap_snapshot_watcher 47 | #echo "Press for taking snapshot..." 48 | #read -n 1 49 | 50 | blksnap_snapshot_take 51 | 52 | generate_block_MB ${TESTDIR} "after" 100 53 | check_files ${TESTDIR} 54 | 55 | echo "Check snapshot before overflow." 56 | #echo "press..." 57 | #read -n 1 58 | 59 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 60 | IMAGE=${MPDIR}/image0 61 | mkdir -p ${IMAGE} 62 | mount ${DEVICE_IMAGE} ${IMAGE} 63 | check_files ${IMAGE}/${TESTDIR} 64 | 65 | echo "Try to make snapshot overflow." 66 | #echo "press..." 67 | #read -n 1 68 | generate_block_MB ${TESTDIR} "overflow" 768 69 | 70 | echo "Umount images" 71 | umount ${IMAGE} 72 | 73 | echo "Destroy snapshot" 74 | #echo "press..." 75 | #read -n 1 76 | 77 | blksnap_snapshot_destroy 78 | blksnap_watcher_wait 79 | blksnap_detach ${DEVICE} 80 | blksnap_unload 81 | 82 | echo "Cleanup test directory" ${TESTDIR} 83 | rm -rf ${TESTDIR}/* 84 | 85 | echo "Overflow snapshot test finish" 86 | echo "---" 87 | -------------------------------------------------------------------------------- /tests/3000-cbt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | 12 | . ./functions.sh 13 | . ./blksnap.sh 14 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 15 | 16 | echo "---" 17 | echo "Change tracking test" 18 | 19 | # diff_storage_minimum=262144 - set 256 K sectors, it's 125MiB dikk_storage portion size 20 | blksnap_load "diff_storage_minimum=262144" 21 | 22 | # check module is ready 23 | blksnap_version 24 | 25 | TESTDIR=${HOME}/blksnap-test 26 | MPDIR=/mnt/blksnap-test 27 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 28 | 29 | rm -rf ${TESTDIR} 30 | rm -rf ${MPDIR} 31 | mkdir -p ${TESTDIR} 32 | mkdir -p ${MPDIR} 33 | 34 | # create first device 35 | IMAGEFILE_1=${TESTDIR}/simple_1.img 36 | imagefile_make ${IMAGEFILE_1} 4096 37 | 38 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 39 | mkfs.ext4 ${DEVICE_1} 40 | echo "new device ${DEVICE_1}" 41 | 42 | MOUNTPOINT_1=${MPDIR}/simple_1 43 | mkdir -p ${MOUNTPOINT_1} 44 | mount ${DEVICE_1} ${MOUNTPOINT_1} 45 | 46 | generate_files_direct ${MOUNTPOINT_1} "before" 5 47 | drop_cache 48 | 49 | rm -f ${DIFF_STORAGE} 50 | fallocate --length 1GiB ${DIFF_STORAGE} 51 | 52 | # full 53 | echo "First snapshot for just attached devices" 54 | blksnap_snapshot_create ${DEVICE_1} "${DIFF_STORAGE}" "1G" 55 | blksnap_snapshot_take 56 | 57 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt0.map 58 | echo "CBT map size: " 59 | stat -c%s "${TESTDIR}/cbt0.map" 60 | generate_block_MB ${MOUNTPOINT_1} "full" 10 61 | check_files ${MOUNTPOINT_1} 62 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt0_.map 63 | 64 | blksnap_snapshot_destroy 65 | cmp -l ${TESTDIR}/cbt0.map ${TESTDIR}/cbt0_.map 66 | 67 | # increment 1 68 | echo "First increment" 69 | blksnap_snapshot_create ${DEVICE_1} "${DIFF_STORAGE}" "1G" 70 | blksnap_snapshot_take 71 | 72 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt1.map 73 | generate_block_MB ${MOUNTPOINT_1} "inc-first" 10 74 | check_files ${MOUNTPOINT_1} 75 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt1_.map 76 | 77 | blksnap_snapshot_destroy 78 | cmp -l ${TESTDIR}/cbt1.map ${TESTDIR}/cbt1_.map 79 | 80 | # increment 2 81 | echo "Second increment" 82 | blksnap_snapshot_create ${DEVICE_1} "${DIFF_STORAGE}" "1G" 83 | blksnap_snapshot_take 84 | 85 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt2.map 86 | generate_block_MB ${MOUNTPOINT_1} "inc-second" 10 87 | check_files ${MOUNTPOINT_1} 88 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt2_.map 89 | 90 | blksnap_snapshot_destroy 91 | cmp -l ${TESTDIR}/cbt2.map ${TESTDIR}/cbt2_.map 92 | 93 | # increment 3 94 | echo "Second increment" 95 | blksnap_snapshot_create ${DEVICE_1} "${DIFF_STORAGE}" "1G" 96 | blksnap_snapshot_take 97 | 98 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt3.map 99 | fallocate --length 2MiB "${MOUNTPOINT_1}/dirty_file" 100 | blksnap_markdirty ${DEVICE_1} "${MOUNTPOINT_1}/dirty_file" 101 | blksnap_readcbt ${DEVICE_1} ${TESTDIR}/cbt3_.map 102 | 103 | blksnap_snapshot_destroy 104 | 105 | set +e 106 | echo "dirty blocks:" 107 | cmp -l ${TESTDIR}/cbt3.map ${TESTDIR}/cbt3_.map 2>&1 108 | set -e 109 | 110 | echo "Destroy first device" 111 | blksnap_detach ${DEVICE_1} 112 | umount ${MOUNTPOINT_1} 113 | loop_device_detach ${DEVICE_1} 114 | imagefile_cleanup ${IMAGEFILE_1} 115 | 116 | blksnap_unload 117 | 118 | echo "Change tracking test finish" 119 | echo "---" 120 | -------------------------------------------------------------------------------- /tests/4000-diff_storage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ./functions.sh 6 | . ./blksnap.sh 7 | 8 | echo "---" 9 | echo "Diff storage test" 10 | 11 | # diff_storage_minimum=262144 - set 256 K sectors, it's 128MiB diff_storage portion size 12 | blksnap_load "diff_storage_minimum=262144" 13 | 14 | # check module is ready 15 | blksnap_version 16 | 17 | if [ -z $1 ] 18 | then 19 | TEST_DIR=${HOME}/blksnap-test 20 | else 21 | TEST_DIR=$(realpath $1"/blksnap-test") 22 | fi 23 | mkdir -p ${TEST_DIR} 24 | rm -rf ${TEST_DIR}/* 25 | 26 | MP_TEST_DIR=$(stat -c %m ${TEST_DIR}) 27 | DEVICE="/dev/block/"$(mountpoint -d ${MP_TEST_DIR}) 28 | echo "Test directory [${TEST_DIR}] on device [${DEVICE}] selected" 29 | 30 | RELATIVE_TEST_DIR=${TEST_DIR#${MP_TEST_DIR}} 31 | 32 | MP_DIR=/mnt/blksnap-test 33 | 34 | rm -rf ${MP_DIR} 35 | mkdir -p ${MP_DIR} 36 | 37 | generate_block_MB ${TEST_DIR} "before" 10 38 | check_files ${TEST_DIR} 39 | 40 | DIFF_STORAGE=/dev/shm 41 | 42 | blksnap_snapshot_create "${DEVICE}" "${DIFF_STORAGE}" "1G" 43 | blksnap_snapshot_watcher 44 | blksnap_snapshot_take 45 | 46 | generate_block_MB ${TEST_DIR} "after" 100 47 | check_files ${TEST_DIR} 48 | 49 | IMAGE=${MP_DIR}/image0 50 | mkdir -p ${IMAGE} 51 | 52 | echo "Mount image" 53 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 54 | mount ${DEVICE_IMAGE} ${IMAGE} 55 | # for XFS filesystem nouuid option needed 56 | #mount -o nouuid /dev/blksnap-image0 ${IMAGE} 57 | 58 | check_files ${IMAGE}/${RELATIVE_TEST_DIR} 59 | 60 | echo "Umount image" 61 | umount ${IMAGE} 62 | 63 | echo "Destroy snapshot" 64 | blksnap_snapshot_destroy 65 | blksnap_watcher_wait 66 | blksnap_detach ${DEVICE} 67 | blksnap_unload 68 | 69 | echo "Diff storage test finish" 70 | echo "---" 71 | -------------------------------------------------------------------------------- /tests/5000-pullout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 12 | 13 | . ./functions.sh 14 | . ./blksnap.sh 15 | 16 | echo "---" 17 | echo "pullout test start" 18 | 19 | blksnap_load 20 | 21 | # check module is ready 22 | blksnap_version 23 | 24 | TESTDIR=/tmp/blksnap-test 25 | rm -rf ${TESTDIR} 26 | mkdir -p ${TESTDIR} 27 | 28 | MPDIR=/mnt/blksnap-test 29 | rm -rf ${MPDIR} 30 | mkdir -p ${MPDIR} 31 | 32 | ALG="lzo" 33 | modprobe zram num_devices=2 && sleep 1 34 | 35 | # create first device 36 | DEVICE_1="/dev/zram0" 37 | zramctl --size 128M --algorithm ${ALG} ${DEVICE_1} 38 | mkfs.ext4 ${DEVICE_1} 39 | echo "new device ${DEVICE_1}" 40 | 41 | MOUNTPOINT_1=${MPDIR}/simple_1 42 | mkdir -p ${MOUNTPOINT_1} 43 | mount ${DEVICE_1} ${MOUNTPOINT_1} 44 | 45 | # create second device 46 | DEVICE_2="/dev/zram1" 47 | zramctl --size 128M --algorithm ${ALG} ${DEVICE_2} 48 | mkfs.ext4 ${DEVICE_2} 49 | echo "new device ${DEVICE_2}" 50 | 51 | MOUNTPOINT_2=${MPDIR}/simple_2 52 | mkdir -p ${MOUNTPOINT_2} 53 | mount ${DEVICE_2} ${MOUNTPOINT_2} 54 | 55 | generate_files_sync ${MOUNTPOINT_1} "before" 9 56 | drop_cache 57 | 58 | echo "Block device prepared" 59 | #echo "press ..." 60 | #read -n 1 61 | 62 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 63 | rm -f ${DIFF_STORAGE} 64 | fallocate --length 256MiB ${DIFF_STORAGE} 65 | blksnap_snapshot_create "${DEVICE_1} ${DEVICE_2}" "${DIFF_STORAGE}" "1G" 66 | blksnap_snapshot_take 67 | 68 | echo "Snapshot was token" 69 | #echo "press ..." 70 | #read -n 1 71 | 72 | blksnap_snapshot_collect 73 | 74 | echo "Write to original" 75 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 76 | generate_files_sync ${MOUNTPOINT_1} "after" 3 77 | drop_cache 78 | 79 | check_files ${MOUNTPOINT_1} 80 | 81 | echo "Check snapshots" 82 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 83 | IMAGE_1=${TESTDIR}/image0 84 | mkdir -p ${IMAGE_1} 85 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 86 | check_files ${IMAGE_1} 87 | 88 | echo "Write to snapshot" 89 | generate_files_sync ${IMAGE_1} "snapshot" 3 90 | 91 | drop_cache 92 | umount ${DEVICE_IMAGE_1} 93 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 94 | 95 | check_files ${IMAGE_1} 96 | 97 | umount ${IMAGE_1} 98 | 99 | blksnap_snapshot_destroy 100 | 101 | echo "Destroy snapshot" 102 | #echo "press ..." 103 | #read -n 1 104 | 105 | drop_cache 106 | umount ${DEVICE_1} 107 | mount ${DEVICE_1} ${MOUNTPOINT_1} 108 | 109 | check_files ${MOUNTPOINT_1} 110 | 111 | echo "Destroy devices" 112 | umount ${MOUNTPOINT_2} 113 | umount ${MOUNTPOINT_1} 114 | modprobe -r zram 115 | 116 | blksnap_unload 117 | 118 | echo "pullout test finish" 119 | echo "---" 120 | -------------------------------------------------------------------------------- /tests/6000-snapimage_write.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ./functions.sh 6 | . ./blksnap.sh 7 | 8 | echo "---" 9 | echo "Snapshot write test" 10 | 11 | # diff_storage_minimum=262144 - set 256 K sectors, it's 125MiB. 12 | modprobe blksnap diff_storage_minimum=262144 chunk_maximum_in_queue=16 13 | sleep 2s 14 | 15 | # check module is ready 16 | blksnap_version 17 | 18 | if [ -z $1 ] 19 | then 20 | echo "Should use loop device" 21 | 22 | #echo "Create original loop device" 23 | LOOPFILE=${HOME}/blksnap-original.img 24 | dd if=/dev/zero of=${LOOPFILE} count=1024 bs=1M 25 | 26 | DEVICE=$(loop_device_attach ${LOOPFILE}) 27 | mkfs.xfs -f ${DEVICE} 28 | # mkfs.ext4 ${DEVICE} 29 | 30 | ORIGINAL=/mnt/blksnap-original 31 | mkdir -p ${ORIGINAL} 32 | mount ${DEVICE} ${ORIGINAL} 33 | else 34 | echo "Should use device [$1]" 35 | 36 | DEVICE=$1 37 | 38 | MNTDIR=$(findmnt -n -o TARGET ${DEVICE}) 39 | echo ${MNTDIR} 40 | ORIGINAL=${MNTDIR}"/blksnap-original" 41 | rm -rf ${ORIGINAL}/* 42 | mkdir -p ${ORIGINAL} 43 | fi 44 | 45 | FSTYPE=$(findmnt -n -o FSTYPE ${DEVICE}) 46 | 47 | if [ "${FSTYPE}" = "xfs" ] 48 | then 49 | MOUNTOPT="-o nouuid" 50 | else 51 | MOUNTOPT="" 52 | fi 53 | 54 | if [ -z $2 ] 55 | then 56 | ITERATION_CNT="3" 57 | else 58 | ITERATION_CNT="$2" 59 | fi 60 | 61 | IMAGE=/mnt/blksnap-image0 62 | mkdir -p ${IMAGE} 63 | 64 | DIFF_STORAGE="/dev/shm" 65 | 66 | generate_files_direct ${ORIGINAL} "original-it#0" 5 67 | drop_cache 68 | 69 | for ITERATOR in $(seq 1 $ITERATION_CNT) 70 | do 71 | echo "Itearation: ${ITERATOR}" 72 | 73 | blksnap_snapshot_create ${DEVICE} "${DIFF_STORAGE}" "256M" 74 | blksnap_snapshot_take 75 | 76 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 77 | mount ${MOUNTOPT} ${DEVICE_IMAGE} ${IMAGE} 78 | 79 | generate_block_MB ${IMAGE} "image-it#${ITERATOR}" 10 & 80 | IMAGE_PID=$! 81 | generate_block_MB ${ORIGINAL} "original-it#${ITERATOR}" 10 82 | wait ${IMAGE_PID} 83 | 84 | drop_cache 85 | 86 | check_files ${IMAGE} & 87 | IMAGE_PID=$! 88 | check_files ${ORIGINAL} 89 | wait ${IMAGE_PID} 90 | 91 | drop_cache 92 | 93 | #echo "pause, press ..." 94 | #read -n 1 95 | 96 | echo "Remount image device "${DEVICE_IMAGE} 97 | umount ${DEVICE_IMAGE} 98 | mount ${MOUNTOPT} ${DEVICE_IMAGE} ${IMAGE} 99 | 100 | check_files ${IMAGE} & 101 | IMAGE_PID=$! 102 | check_files ${ORIGINAL} 103 | wait ${IMAGE_PID} 104 | 105 | #echo "pause, press ..." 106 | #read -n 1 107 | 108 | umount ${IMAGE} 109 | 110 | blksnap_snapshot_destroy 111 | done 112 | 113 | if [ -z $1 ] 114 | then 115 | echo "Destroy original loop device" 116 | umount ${ORIGINAL} 117 | 118 | blksnap_detach ${DEVICE} 119 | 120 | loop_device_detach ${DEVICE} 121 | imagefile_cleanup ${LOOPFILE} 122 | else 123 | echo "Cleanup directory [${ORIGINAL}]" 124 | rm -rf ${ORIGINAL}/* 125 | fi 126 | 127 | echo "Unload module" 128 | modprobe -r blksnap 129 | 130 | echo "Snapshot write test finish" 131 | echo "---" 132 | -------------------------------------------------------------------------------- /tests/6100-snapimage_write.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 12 | 13 | . ./functions.sh 14 | . ./blksnap.sh 15 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 16 | 17 | echo "---" 18 | echo "Snapshot direct write test" 19 | 20 | # diff_storage_minimum=262144 - set 256 K sectors, it's 125MiB. 21 | modprobe blksnap diff_storage_minimum=262144 22 | 23 | modprobe blksnap 24 | sleep 2s 25 | 26 | # check module is ready 27 | blksnap_version 28 | 29 | 30 | echo "Should use loop device" 31 | 32 | TESTDIR="${HOME}/blksnap-test" 33 | rm -rf ${TESTDIR} 34 | mkdir -p ${TESTDIR} 35 | 36 | #echo "Create original loop device" 37 | LOOPFILE="${TESTDIR}/blksnap-original.img" 38 | dd if=/dev/zero of=${LOOPFILE} count=256 bs=1M 39 | 40 | DEVICE=$(loop_device_attach ${LOOPFILE} ${BLOCK_SIZE}) 41 | 42 | if [ -z $1 ] 43 | then 44 | ITERATION_CNT="1" 45 | else 46 | ITERATION_CNT="$1" 47 | fi 48 | 49 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 50 | fallocate --length 1GiB ${DIFF_STORAGE} 51 | 52 | for ITERATOR in $(seq 1 $ITERATION_CNT) 53 | do 54 | echo "Itearation: ${ITERATOR}" 55 | 56 | blksnap_snapshot_create ${DEVICE} "${DIFF_STORAGE}" "256M" 57 | blksnap_snapshot_take 58 | 59 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 60 | 61 | FILE="${TESTDIR}/image-it#${ITERATOR}" 62 | generate_file_magic ${FILE} 2048 63 | 64 | dd if=${FILE} of=${DEVICE} bs=1KiB count=1024 seek=0 oflag=direct status=none 65 | 66 | dd if=${FILE} of=${DEVICE_IMAGE} bs=1KiB count=1024 seek=126 oflag=direct status=none 67 | 68 | dd if=${FILE} of=${DEVICE_IMAGE} bs=1KiB count=1024 seek=$((2048 + 126)) oflag=direct status=none 69 | 70 | dd if=${FILE} of=${DEVICE_IMAGE} bs=1KiB count=1024 seek=$((4096 + 126)) oflag=direct status=none 71 | 72 | 73 | sync ${DEVICE_IMAGE} 74 | # echo "pause, press ..." 75 | # read -n 1 76 | 77 | dd if=${DEVICE_IMAGE} of="${FILE}_copy" bs=1KiB count=1024 skip=126 iflag=direct status=none 78 | cmp ${FILE} "${FILE}_copy" && echo "Files are equal." 79 | 80 | dd if=${DEVICE_IMAGE} of="${FILE}_copy1" bs=1KiB count=1024 skip=$((2048 + 126)) iflag=direct status=none 81 | cmp ${FILE} "${FILE}_copy1" && echo "Files are equal." 82 | 83 | dd if=${DEVICE_IMAGE} of="${FILE}_copy2" bs=1KiB count=1024 skip=$((4096 + 126)) oflag=direct status=none 84 | cmp ${FILE} "${FILE}_copy2" && echo "Files are equal." 85 | 86 | 87 | # echo "pause, press ..." 88 | # read -n 1 89 | 90 | blksnap_snapshot_destroy 91 | done 92 | 93 | echo "Destroy original loop device" 94 | 95 | blksnap_detach ${DEVICE} 96 | 97 | loop_device_detach ${DEVICE} 98 | imagefile_cleanup ${LOOPFILE} 99 | 100 | echo "Cleanup test directory [${TESTDIR}]" 101 | rm -rf "${TESTDIR}" 102 | 103 | echo "Unload module" 104 | modprobe -r blksnap 105 | 106 | echo "Snapshot direct write test finish" 107 | echo "---" 108 | -------------------------------------------------------------------------------- /tests/7000-destroy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | 6 | if [ -z $1 ] 7 | then 8 | DIFF_STORAGE_DIR=${HOME} 9 | else 10 | DIFF_STORAGE_DIR=$1 11 | fi 12 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 13 | 14 | . ./functions.sh 15 | . ./blksnap.sh 16 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 17 | 18 | echo "---" 19 | echo "Destroy test start" 20 | 21 | blksnap_load 22 | 23 | # check module is ready 24 | blksnap_version 25 | 26 | TESTDIR=/tmp/blksnap-test 27 | rm -rf ${TESTDIR} 28 | mkdir -p ${TESTDIR} 29 | 30 | MPDIR=/mnt/blksnap-test 31 | rm -rf ${MPDIR} 32 | mkdir -p ${MPDIR} 33 | 34 | 35 | # create first device 36 | IMAGEFILE_1=${TESTDIR}/simple_1.img 37 | imagefile_make ${IMAGEFILE_1} 128 38 | 39 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 40 | mkfs.ext4 ${DEVICE_1} 41 | echo "new device ${DEVICE_1}" 42 | 43 | MOUNTPOINT_1=${MPDIR}/simple_1 44 | mkdir -p ${MOUNTPOINT_1} 45 | mount ${DEVICE_1} ${MOUNTPOINT_1} 46 | 47 | echo "Write to original before taking snapshot" 48 | generate_files_sync ${MOUNTPOINT_1} "before" 9 49 | drop_cache 50 | 51 | DIFF_STORAGE=${DIFF_STORAGE_DIR}/diff_storage 52 | fallocate --length 1GiB ${DIFF_STORAGE} 53 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE}" "128M" 54 | blksnap_snapshot_take 55 | 56 | echo "mount snapshot" 57 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 58 | IMAGE_1=${TESTDIR}/image0 59 | mkdir -p ${IMAGE_1} 60 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 61 | 62 | set +e 63 | 64 | echo "Write to original after taking snapshot" 65 | generate_files_sync ${MOUNTPOINT_1} "after" 4 & 66 | PID_GEN1=$! 67 | dd if=${DEVICE_IMAGE_1} of=/dev/zero & 68 | PID_DD1=$! 69 | 70 | echo "Write to snapshot" 71 | generate_files_sync ${IMAGE_1} "snapshot" 4 & 72 | PID_GEN2=$! 73 | dd if=${DEVICE_IMAGE_1} of=/dev/zero & 74 | PID_DD2=$! 75 | 76 | echo "Destroy snapshot ..." 77 | blksnap_snapshot_destroy 78 | 79 | umount --lazy --force ${IMAGE_1} 80 | 81 | echo "Waiting for all process terminate" 82 | wait ${PID_GEN1} 83 | wait ${PID_DD1} 84 | wait ${PID_GEN2} 85 | wait ${PID_DD2} 86 | 87 | set -e 88 | 89 | echo "Destroy device" 90 | blksnap_detach ${DEVICE_1} 91 | umount ${MOUNTPOINT_1} 92 | loop_device_detach ${DEVICE_1} 93 | imagefile_cleanup ${IMAGEFILE_1} 94 | 95 | blksnap_unload 96 | 97 | echo "Destroy test finish" 98 | echo "---" 99 | -------------------------------------------------------------------------------- /tests/8000-inline-encryption.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 12 | 13 | . ./functions.sh 14 | . ./blksnap.sh 15 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 16 | 17 | echo "---" 18 | echo "Inline encryption test start" 19 | echo "devices block size ${BLOCK_SIZE}" 20 | 21 | blksnap_load 22 | blksnap_version 23 | 24 | TESTDIR=${HOME}/blksnap-test 25 | rm -rf ${TESTDIR} 26 | mkdir -p ${TESTDIR} 27 | 28 | MPDIR=/mnt/blksnap-test 29 | rm -rf ${MPDIR} 30 | mkdir -p ${MPDIR} 31 | 32 | # Create device 33 | IMAGEFILE_1=${TESTDIR}/simple_1.img 34 | imagefile_make ${IMAGEFILE_1} 64 35 | 36 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 37 | mkfs.ext4 -O encrypt ${DEVICE_1} 38 | echo "new device ${DEVICE_1}" 39 | 40 | MOUNTPOINT_1=${MPDIR}/simple_1 41 | mkdir -p ${MOUNTPOINT_1} 42 | mount -o inlinecrypt,test_dummy_encryption ${DEVICE_1} ${MOUNTPOINT_1} 43 | #tune2fs -O encrypt ${DEVICE_1} 44 | 45 | generate_files_direct ${MOUNTPOINT_1} "before" 3 46 | drop_cache 47 | 48 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE_DIR}" "64M" 49 | blksnap_snapshot_take 50 | 51 | echo "Write to original" 52 | generate_files_direct ${MOUNTPOINT_1} "after" 3 53 | umount ${MOUNTPOINT_1} 54 | 55 | echo "Try to read snapshot image" 56 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 57 | set +e 58 | dd if=${DEVICE_IMAGE_1} of=${TESTDIR}/image1 bs=1KiB oflag=direct status=none 59 | drop_cache 60 | set -e 61 | 62 | blksnap_snapshot_destroy 63 | 64 | echo "Destroy device" 65 | blksnap_detach ${DEVICE_1} 66 | loop_device_detach ${DEVICE_1} 67 | imagefile_cleanup ${IMAGEFILE_1} 68 | 69 | blksnap_unload 70 | 71 | echo "Inline encryption test finish" 72 | echo "---" 73 | -------------------------------------------------------------------------------- /tests/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | echo "Execute all tests" 6 | echo "***" 7 | 8 | for SCRIPT in $(ls ????-*.sh) 9 | do 10 | . ${SCRIPT} 11 | done 12 | 13 | echo "***" 14 | echo "Complete" 15 | -------------------------------------------------------------------------------- /tests/blksnap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -f "/usr/bin/blksnap" ] || [ -f "/usr/sbin/blksnap" ] 6 | then 7 | BLKSNAP=blksnap 8 | else 9 | BLKSNAP="$(cd ../; pwd)/tools/blksnap/bin/blksnap" 10 | fi 11 | 12 | ID="" 13 | BLKSNAP_FILENAME=$(modinfo --field filename blksnap) 14 | STRETCH_PROCESS_PID="" 15 | 16 | blksnap_load() 17 | { 18 | if [ ${BLKSNAP_FILENAME} = "(builtin)" ] 19 | then 20 | return 21 | fi 22 | 23 | modprobe blksnap $1 24 | sleep 2s 25 | } 26 | 27 | blksnap_unload() 28 | { 29 | if [ ${BLKSNAP_FILENAME} = "(builtin)" ] 30 | then 31 | return 32 | fi 33 | 34 | echo "Unload module" 35 | modprobe -r blksnap 2>&1 || sleep 1 && modprobe -r blksnap && echo "Unload success" 36 | } 37 | 38 | blksnap_version() 39 | { 40 | ${BLKSNAP} version 41 | } 42 | 43 | blksnap_snapshot_create() 44 | { 45 | PARAM="" 46 | 47 | for DEVICE in $1 48 | do 49 | PARAM="${PARAM} --device ${DEVICE}" 50 | done 51 | PARAM="${PARAM} --file $2" 52 | PARAM="${PARAM} --limit $3" 53 | 54 | ID=$(${BLKSNAP} snapshot_create ${PARAM}) 55 | echo "New snapshot ${ID} was created" 56 | } 57 | 58 | blksnap_snapshot_destroy() 59 | { 60 | echo "Destroy snapshot ${ID}" 61 | ${BLKSNAP} snapshot_destroy --id=${ID} 62 | } 63 | 64 | blksnap_snapshot_take() 65 | { 66 | echo "Take snapshot ${ID}" 67 | 68 | ${BLKSNAP} snapshot_take --id=${ID} 69 | } 70 | 71 | blksnap_snapshot_collect() 72 | { 73 | echo "Collect snapshots" 74 | 75 | ${BLKSNAP} snapshot_collect 76 | } 77 | 78 | blksnap_attach() 79 | { 80 | local DEVICE=$1 81 | 82 | ${BLKSNAP} attach --device=${DEVICE} 83 | } 84 | 85 | blksnap_detach() 86 | { 87 | local DEVICE=$1 88 | 89 | ${BLKSNAP} detach --device=${DEVICE} 90 | } 91 | 92 | blksnap_cbtinfo() 93 | { 94 | local DEVICE=$1 95 | 96 | ${BLKSNAP} cbtinfo --device=${DEVICE} --file=${CBTMAP} 97 | } 98 | 99 | blksnap_readcbt() 100 | { 101 | local DEVICE=$1 102 | local CBTMAP=$2 103 | 104 | ${BLKSNAP} readcbtmap --device=${DEVICE} --file=${CBTMAP} 105 | } 106 | 107 | blksnap_markdirty() 108 | { 109 | local DIRTYFILE=$2 110 | 111 | ${BLKSNAP} markdirtyblock --file=${DIRTYFILE} 112 | } 113 | 114 | blksnap_snapshot_watcher() 115 | { 116 | ${BLKSNAP} snapshot_watcher --id=${ID} & 117 | STRETCH_PROCESS_PID=$! 118 | } 119 | blksnap_watcher_wait() 120 | { 121 | echo "Waiting for streach process terminate" 122 | wait ${STRETCH_PROCESS_PID} 123 | } 124 | 125 | blksnap_get_image() 126 | { 127 | ${BLKSNAP} snapshot_info --field image --device $1 128 | } 129 | 130 | blksnap_cleanup() 131 | { 132 | for ID in $(${BLKSNAP} snapshot_collect) 133 | do 134 | ${BLKSNAP} snapshot_destroy --id=${ID} 135 | done 136 | } 137 | -------------------------------------------------------------------------------- /tests/cpp/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # https://clang.llvm.org/docs/ClangFormatStyleOptions.html 3 | BasedOnStyle: WebKit 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlines: Left 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: false 9 | AllowShortBlocksOnASingleLine: false 10 | AllowShortCaseLabelsOnASingleLine: false 11 | AllowShortFunctionsOnASingleLine: None 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: None 15 | AlwaysBreakAfterReturnType: None 16 | AlwaysBreakBeforeMultilineStrings: false 17 | AlwaysBreakTemplateDeclarations: Yes 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BreakBeforeBinaryOperators: All 21 | BreakBeforeBraces: Custom 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: true 25 | AfterEnum: true 26 | AfterFunction: true 27 | AfterNamespace: true 28 | AfterObjCDeclaration: true 29 | AfterStruct: true 30 | AfterUnion: true 31 | AfterExternBlock: true 32 | BeforeCatch: true 33 | BeforeElse: true 34 | IndentBraces: false 35 | SplitEmptyFunction: true 36 | SplitEmptyRecord: false 37 | SplitEmptyNamespace: false 38 | BreakBeforeTernaryOperators: true 39 | BreakConstructorInitializers: BeforeComma 40 | BreakInheritanceList: BeforeComma 41 | BreakStringLiterals: false 42 | ColumnLimit: 120 43 | CommentPragmas: '^ IWYU pragma:' 44 | CompactNamespaces: false 45 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 46 | ConstructorInitializerIndentWidth: 4 47 | ContinuationIndentWidth: 2 48 | Cpp11BracedListStyle: true 49 | DerivePointerAlignment: false 50 | DisableFormat: false 51 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 52 | IncludeCategories: 53 | - Regex: '^".*_config.h"$' 54 | Priority: -2 55 | - Regex: '^"(stdafx|PrecompiledHeader)' 56 | Priority: -1 57 | - Regex: '^<([a-zA-Z0-9_]+.*)>$' 58 | Priority: 1 59 | - Regex: '^<([.]+.*)>$' 60 | Priority: 2 61 | - Regex: '.*' 62 | Priority: 3 63 | IncludeBlocks: Regroup 64 | IndentCaseLabels: false 65 | IndentPPDirectives: AfterHash 66 | IndentWidth: 4 67 | IndentWrappedFunctionNames: true 68 | KeepEmptyLinesAtTheStartOfBlocks: false 69 | Language: Cpp 70 | MaxEmptyLinesToKeep: 1 71 | NamespaceIndentation: All 72 | PointerAlignment: Left 73 | SortIncludes: true 74 | SpaceAfterCStyleCast: false 75 | SpaceAfterTemplateKeyword: false 76 | SpaceBeforeAssignmentOperators: true 77 | SpaceBeforeCpp11BracedList: false 78 | SpaceBeforeCtorInitializerColon: true 79 | SpaceBeforeInheritanceColon: true 80 | SpaceBeforeParens: ControlStatements 81 | SpaceBeforeRangeBasedForLoopColon: true 82 | SpaceInEmptyParentheses: false 83 | SpacesBeforeTrailingComments: 1 84 | SpacesInAngles: false 85 | SpacesInCStyleCastParentheses: false 86 | SpacesInContainerLiterals: false 87 | SpacesInParentheses: false 88 | SpacesInSquareBrackets: false 89 | TabWidth: 4 90 | UseTab: Never 91 | ... 92 | -------------------------------------------------------------------------------- /tests/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0+ 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | project(blksnap-tests) 5 | 6 | set(CMAKE_CXX_STANDARD 14) 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -pthread") 8 | 9 | set(Boost_USE_STATIC_LIBS ON) 10 | FIND_PACKAGE( Boost COMPONENTS program_options filesystem REQUIRED) 11 | 12 | FIND_LIBRARY(LIBUUID_LIBRARY libuuid.so REQUIRED) 13 | if (NOT LIBUUID_LIBRARY) 14 | message(FATAL_ERROR "libuuid not found. please install uuid-dev or libuuid-devel package.") 15 | endif () 16 | 17 | set(OPENSSL_USE_STATIC_LIBS TRUE) 18 | find_package(OpenSSL REQUIRED) 19 | if (NOT OPENSSL_LIBRARIES) 20 | message(FATAL_ERROR "openssl not found. please install libssl-dev package.") 21 | endif () 22 | 23 | add_subdirectory(helpers) 24 | 25 | set(TESTS_LIBS blksnap-dev Helpers::Lib Boost::program_options Boost::filesystem ${LIBUUID_LIBRARY}) 26 | 27 | set(TEST_CORRUPT test_corrupt) 28 | add_executable(${TEST_CORRUPT} TestSector.cpp corrupt.cpp) 29 | target_link_libraries(${TEST_CORRUPT} PRIVATE ${TESTS_LIBS}) 30 | target_include_directories(${TEST_CORRUPT} PRIVATE ./) 31 | 32 | set(TEST_CBT test_cbt) 33 | add_executable(${TEST_CBT} cbt.cpp) 34 | target_link_libraries(${TEST_CBT} PRIVATE ${TESTS_LIBS}) 35 | target_include_directories(${TEST_CBT} PRIVATE ./) 36 | 37 | set(TEST_BOUNDARY test_boundary) 38 | add_executable(${TEST_BOUNDARY} TestSector.cpp boundary.cpp) 39 | target_link_libraries(${TEST_BOUNDARY} PRIVATE ${TESTS_LIBS}) 40 | target_include_directories(${TEST_BOUNDARY} PRIVATE ./) 41 | 42 | set(TEST_PERFORMANCE test_performance) 43 | add_executable(${TEST_PERFORMANCE} performance.cpp) 44 | target_link_libraries(${TEST_PERFORMANCE} PRIVATE ${TESTS_LIBS}) 45 | target_include_directories(${TEST_PERFORMANCE} PRIVATE ./) 46 | 47 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../ 48 | DESTINATION /opt/blksnap/tests 49 | USE_SOURCE_PERMISSIONS 50 | PATTERN "*.sh" 51 | PATTERN "cpp" EXCLUDE 52 | ) 53 | 54 | install(TARGETS ${TEST_CORRUPT} ${TEST_CBT} ${TEST_DIFF_STORAGE} ${TEST_BOUNDARY} ${TEST_PERFORMANCE} 55 | DESTINATION /opt/blksnap/tests 56 | ) 57 | -------------------------------------------------------------------------------- /tests/cpp/TestSector.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct STestHeader 8 | { 9 | char head[8]; 10 | int crc; 11 | int seqNumber; 12 | blksnap::sector_t sector; 13 | clock_t seqTime; 14 | 15 | void Init(int inSeqNumber, blksnap::sector_t inSector, const clock_t inSeqTime); 16 | }; 17 | 18 | struct STestSector 19 | { 20 | STestHeader header; 21 | char body[SECTOR_SIZE - sizeof(STestHeader)]; 22 | }; 23 | 24 | enum EFailType 25 | { 26 | eFailCorruptedSector, 27 | eFailIncorrectSector, 28 | }; 29 | 30 | class CTestSectorGenetor 31 | { 32 | public: 33 | CTestSectorGenetor(const bool useCrc32) 34 | : m_useCrc32(useCrc32) 35 | , m_seqNumber(0) 36 | , m_failCount(0) 37 | , m_logLineCount(0) {}; 38 | ~CTestSectorGenetor() {}; 39 | 40 | inline void IncSequence() 41 | { 42 | m_seqNumber++; 43 | }; 44 | 45 | inline int GetSequenceNumber() 46 | { 47 | return m_seqNumber; 48 | }; 49 | 50 | void Generate(unsigned char* buffer, size_t size, blksnap::sector_t sector); 51 | void Generate(unsigned char* buffer, size_t size, blksnap::sector_t sector, clock_t seqTime); 52 | void Check(unsigned char* buffer, size_t size, blksnap::sector_t sector, const int seqNumber, const clock_t seqTime, const bool isStrictly = false); 53 | 54 | 55 | inline int Fails() 56 | { 57 | return m_failCount; 58 | }; 59 | /** 60 | * The function ShowFails() does not contain locks, since it should be 61 | * called when only one thread has access to used data. 62 | */ 63 | inline const std::vector& GetFails() 64 | { 65 | return m_failedRanges; 66 | }; 67 | 68 | private: 69 | bool m_useCrc32; 70 | std::atomic m_seqNumber; 71 | int m_failCount; 72 | int m_logLineCount; 73 | std::vector m_failedRanges; 74 | bool m_isCrc32Checking; 75 | 76 | private: 77 | void LogSector(blksnap::sector_t sector, const std::string& failMessage); 78 | void SetFailedSector(blksnap::sector_t sector, const std::string& failMessage); 79 | 80 | }; 81 | -------------------------------------------------------------------------------- /tests/cpp/cbt.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace po = boost::program_options; 8 | using blksnap::sector_t; 9 | 10 | void Main(int argc, char* argv[]) 11 | { 12 | std::runtime_error("It's not implemented yet."); 13 | } 14 | 15 | int main(int argc, char* argv[]) 16 | { 17 | try 18 | { 19 | Main(argc, argv); 20 | } 21 | catch (std::exception& ex) 22 | { 23 | std::cerr << ex.what() << std::endl; 24 | return 1; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/cpp/helpers/AlignedBuffer.hpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | 4 | template 5 | class AlignedBuffer 6 | { 7 | public: 8 | AlignedBuffer(size_t size) 9 | : m_alignment(size * sizeof(T)) 10 | , m_size(size) 11 | { 12 | Allocate(); 13 | }; 14 | AlignedBuffer(size_t alignment, size_t size) 15 | : m_alignment(size) 16 | , m_size(size) 17 | { 18 | Allocate(); 19 | }; 20 | ~AlignedBuffer() 21 | { 22 | Free(); 23 | }; 24 | 25 | void Resize(size_t size) 26 | { 27 | Free(); 28 | m_size = size; 29 | Allocate(); 30 | }; 31 | 32 | size_t Size() 33 | { 34 | return m_size; 35 | } 36 | 37 | T* Data() 38 | { 39 | return static_cast(m_buf); 40 | }; 41 | 42 | private: 43 | size_t m_alignment; 44 | size_t m_size; 45 | void* m_buf; 46 | 47 | private: 48 | void Free() 49 | { 50 | if (m_buf) 51 | { 52 | ::free(m_buf); 53 | m_buf = nullptr; 54 | } 55 | }; 56 | void Allocate() 57 | { 58 | m_buf = ::aligned_alloc(m_alignment, m_size * sizeof(T)); 59 | }; 60 | }; 61 | -------------------------------------------------------------------------------- /tests/cpp/helpers/BlockDevice.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include "BlockDevice.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | CBlockDevice::CBlockDevice(const std::string& name, const bool isSync, const off_t size) 11 | : m_name(name) 12 | , m_size(size) 13 | , m_fd(0) 14 | { 15 | unsigned int flags = isSync ? O_SYNC | O_DSYNC : 0; 16 | 17 | m_fd = ::open(m_name.c_str(), O_EXCL | O_RDWR | O_DIRECT | flags); 18 | if (m_fd < 0) 19 | throw std::system_error(errno, std::generic_category(), "Failed to open file '" + m_name + "'."); 20 | }; 21 | 22 | CBlockDevice::~CBlockDevice() 23 | { 24 | if (m_fd) 25 | { 26 | ::close(m_fd); 27 | m_fd = 0; 28 | } 29 | }; 30 | 31 | void CBlockDevice::Read(void* buf, size_t count, off_t offset) 32 | { 33 | ssize_t ret = ::pread(m_fd, buf, count, offset); 34 | if (ret < 0) 35 | throw std::system_error(errno, std::generic_category(), "Failed to read block device. offset=" + std::to_string(offset) + " size=" + std::to_string(count)); 36 | if (ret < count) 37 | throw std::runtime_error("Reading outside the boundaries of a block device"); 38 | }; 39 | 40 | void CBlockDevice::Write(const void* buf, size_t count, off_t offset) 41 | { 42 | ssize_t ret = ::pwrite(m_fd, buf, count, offset); 43 | if (ret < 0) 44 | throw std::system_error(errno, std::generic_category(), "Failed to write block device. offset=" + std::to_string(offset) + " size=" + std::to_string(count)); 45 | if (ret < count) 46 | throw std::runtime_error("Writing outside the boundaries of a block device"); 47 | }; 48 | 49 | off_t CBlockDevice::Size() 50 | { 51 | if (m_size == 0) 52 | if (::ioctl(m_fd, BLKGETSIZE64, &m_size) == -1) 53 | throw std::system_error(errno, std::generic_category(), "Failed to get block device size"); 54 | 55 | return m_size; 56 | }; 57 | 58 | size_t CBlockDevice::BlockSize() 59 | { 60 | size_t size = 0; 61 | /* 62 | * On the arm64 platform the BLKBSZGET call can returns a value only in 63 | * lower 32-bit digits. 64 | * Therefore, the size must be set to zero before calling on le arch. 65 | * In the big endian systems, this code may have problems. 66 | * It looks like something is wrong for the case when CONFIG_COMPAT is 67 | * enabled. 68 | */ 69 | if (::ioctl(m_fd, BLKBSZGET, &size) == -1) 70 | throw std::system_error(errno, std::generic_category(), "Failed to get block size for device"); 71 | 72 | return size; 73 | } 74 | 75 | const std::string& CBlockDevice::Name() 76 | { 77 | return m_name; 78 | }; 79 | -------------------------------------------------------------------------------- /tests/cpp/helpers/BlockDevice.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | 5 | class CBlockDevice 6 | { 7 | public: 8 | CBlockDevice(const std::string& name, const bool isSync = false, const off_t size = 0); 9 | ~CBlockDevice(); 10 | 11 | void Read(void* buf, size_t count, off_t offset); 12 | void Write(const void* buf, size_t count, off_t offset); 13 | 14 | off_t Size(); 15 | size_t BlockSize(); 16 | const std::string& Name(); 17 | 18 | private: 19 | std::string m_name; 20 | off_t m_size; 21 | int m_fd; 22 | }; 23 | -------------------------------------------------------------------------------- /tests/cpp/helpers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0+ 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | project(helpers) 5 | 6 | set(SOURCE_FILES 7 | Log.cpp 8 | BlockDevice.cpp 9 | RandomHelper.cpp 10 | ) 11 | add_library(${PROJECT_NAME} ${SOURCE_FILES}) 12 | add_library(Helpers::Lib ALIAS ${PROJECT_NAME}) 13 | -------------------------------------------------------------------------------- /tests/cpp/helpers/CheckSumHelper.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | 4 | #include "SHA256Calc.h" 5 | 6 | SHA256Calc::SHA256Calc() 7 | { 8 | if (SHA256_Init(&m_sha_ctx) != 1) 9 | throw std::runtime_error("Failed to init SHA256_CTX"); 10 | } 11 | 12 | SHA256Calc::~SHA256Calc() 13 | {} 14 | 15 | void SHA256Calc::Final(unsigned char* sha_hash) 16 | { 17 | if (SHA256_Final(sha_hash, &m_sha_ctx) != 1) 18 | throw std::runtime_error("Failed to final SHA256_CTX"); 19 | } 20 | 21 | void SHA256Calc::Update(const void* data, size_t len) 22 | { 23 | if (SHA256_Update(&m_sha_ctx, data, len) != 1) 24 | throw std::runtime_error("Failed to update SHA256_CTX"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/cpp/helpers/CheckSumHelper.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #pragma once 3 | 4 | #include 5 | 6 | class SHA256Calc 7 | { 8 | public: 9 | SHA256Calc(); 10 | ~SHA256Calc(); 11 | 12 | void Final(unsigned char sha_hash[SHA256_DIGEST_LENGTH]); 13 | void Update(const void* data, size_t len); 14 | 15 | private: 16 | SHA256_CTX m_sha_ctx; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/cpp/helpers/Device.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | #include 5 | 6 | struct SDeviceId 7 | { 8 | unsigned int mj; 9 | unsigned int mn; 10 | 11 | SDeviceId() 12 | : mj(0) 13 | , mn(0){}; 14 | 15 | SDeviceId(int mjr, int mnr) 16 | : mj(mjr) 17 | , mn(mnr){}; 18 | 19 | std::string ToString() const 20 | { 21 | return std::to_string(mj) + ":" + std::to_string(mn); 22 | }; 23 | 24 | bool operator==(const SDeviceId& devId) const 25 | { 26 | return (mj == devId.mj) && (mn == devId.mn); 27 | }; 28 | 29 | bool operator!=(const SDeviceId& devId) const 30 | { 31 | return !operator==(devId); 32 | }; 33 | 34 | bool operator<(const SDeviceId& devId) const 35 | { 36 | if (mj < devId.mj) 37 | return true; 38 | 39 | if (mj == devId.mj) 40 | if (mn < devId.mn) 41 | return true; 42 | 43 | return false; 44 | }; 45 | 46 | static SDeviceId DeviceByName(const std::string& name) 47 | { 48 | struct stat st; 49 | 50 | if (::stat(name.c_str(), &st)) 51 | throw std::system_error(errno, std::generic_category(), name); 52 | 53 | return SDeviceId(major(st.st_rdev), minor(st.st_rdev)); 54 | }; 55 | }; 56 | -------------------------------------------------------------------------------- /tests/cpp/helpers/FsHelper.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include "FsHelper.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | CAllocatedFile::CAllocatedFile(const std::string& name, const off_t size) 11 | : m_name(name) 12 | , m_size(size) 13 | { 14 | int fd = ::open(filename.c_str(), O_CREAT | O_RDWR | O_EXCL | O_LARGEFILE); 15 | if (fd < 0) 16 | throw std::system_error(errno, std::generic_category(), 17 | "Failed to create file for diff storage."); 18 | 19 | if (::fallocate64(fd, 0, 0, m_size)) 20 | { 21 | int err = errno; 22 | 23 | ::close(fd); 24 | throw std::system_error(err, std::generic_category(), "Failed to allocate file for diff storage."); 25 | } 26 | 27 | ::close(fd); 28 | }; 29 | 30 | CAllocatedFile::~CAllocatedFile() 31 | {}; 32 | 33 | const CAllocatedFile::std::string& Name() 34 | { 35 | return m_name; 36 | } 37 | 38 | off_t CAllocatedFile::Size() 39 | { 40 | return m_size; 41 | } 42 | 43 | void CAllocatedFile::Location(dev_t& dev_id, std::vector& ranges) 44 | { 45 | int ret = 0; 46 | const char* errMessage; 47 | int fd = -1; 48 | struct fiemap* map = NULL; 49 | int extentMax = 500; 50 | long long fileSize; 51 | struct stat64 st; 52 | 53 | if (::stat64(m_name.c_str(), &st)) 54 | throw std::system_error(errno, std::generic_category(), "Failed to get file size."); 55 | 56 | dev_id = st.st_dev; 57 | fileSize = st.st_size; 58 | 59 | ranges.clear(); 60 | 61 | fd = ::open(filename.c_str(), O_RDONLY | O_EXCL | O_LARGEFILE); 62 | if (fd < 0) 63 | { 64 | ret = errno; 65 | errMessage = "Failed to open file."; 66 | goto out; 67 | } 68 | 69 | map = (struct fiemap*)::malloc(sizeof(struct fiemap) + sizeof(struct fiemap_extent) * extentMax); 70 | if (!map) 71 | { 72 | ret = ENOMEM; 73 | errMessage = "Failed to allocate memory for fiemap structure."; 74 | goto out; 75 | } 76 | 77 | for (long long fileOffset = 0; fileOffset < fileSize;) 78 | { 79 | map->fm_start = fileOffset; 80 | map->fm_length = fileSize - fileOffset; 81 | map->fm_extent_count = extentMax; 82 | map->fm_flags = 0; 83 | 84 | if (::ioctl(fd, FS_IOC_FIEMAP, map)) 85 | { 86 | ret = errno; 87 | errMessage = "Failed to call FS_IOC_FIEMAP."; 88 | goto out; 89 | } 90 | 91 | for (int i = 0; i < map->fm_mapped_extents; ++i) 92 | { 93 | struct fiemap_extent* extent = map->fm_extents + i; 94 | 95 | if (extent->fe_physical & (SECTOR_SIZE - 1)) 96 | { 97 | ret = EINVAL; 98 | errMessage = "File location is not ordered by sector size."; 99 | goto out; 100 | } 101 | 102 | ranges.emplace_back(extent->fe_physical, extent->fe_length); 103 | 104 | fileOffset = extent->fe_logical + extent->fe_length; 105 | 106 | //std::cout << "allocate range: ofs=" << rg.sector_offset << " cnt=" << rg.sector_count << std::endl; 107 | } 108 | } 109 | 110 | out: 111 | if (map) 112 | ::free(map); 113 | if (fd >= 0) 114 | ::close(fd); 115 | if (ret) 116 | throw std::system_error(ret, std::generic_category(), errMessage); 117 | } 118 | -------------------------------------------------------------------------------- /tests/cpp/helpers/FsHelper.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | 5 | struct BlockRange { 6 | off_t offset; 7 | off_t count; 8 | 9 | BlockRange(const off_t inOffset, const off_t inCount) 10 | : offset(inOffset) 11 | , count(inCount) 12 | {}; 13 | }; 14 | 15 | class CAllocatedFile 16 | { 17 | public: 18 | CAllocatedFile(const std::string& name, const off_t size); 19 | ~CAllocatedFile(); 20 | 21 | const std::string& Name(); 22 | off_t Size(); 23 | void Location(dev_t& dev_id, std::vector& ranges); 24 | 25 | private: 26 | std::string m_name; 27 | off_t size; 28 | } 29 | -------------------------------------------------------------------------------- /tests/cpp/helpers/Log.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class CLog 9 | { 10 | public: 11 | CLog() 12 | : m_isOpen(false){}; 13 | ~CLog(){}; 14 | 15 | void Open(const std::string& filename); 16 | 17 | void Info(const char* message); 18 | void Info(const std::string& message); 19 | void Info(const std::stringstream& ss); 20 | void Info(const void* buf, const size_t size); 21 | 22 | void Err(const char* message); 23 | void Err(const std::string& message); 24 | void Err(const std::stringstream& ss); 25 | void Err(const void* buf, const size_t size); 26 | 27 | void Detail(const char* message); 28 | void Detail(const std::string& message); 29 | void Detail(const std::stringstream& ss); 30 | void Detail(const void* buf, const size_t size); 31 | 32 | private: 33 | std::mutex m_lock; 34 | bool m_isOpen; 35 | std::ofstream m_out; 36 | }; 37 | 38 | extern CLog logger; 39 | -------------------------------------------------------------------------------- /tests/cpp/helpers/LoopDevice.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | class LoopDevice 8 | { 9 | public: 10 | using Ptr = std::shared_ptr; 11 | 12 | ~LoopDevice(); 13 | static LoopDevice::Ptr Create(boost::filesystem::path directory, size_t size); 14 | 15 | boost::filesystem::path GetDevice() const; 16 | void Mkfs(const std::string fsType = "ext4"); 17 | 18 | private: 19 | LoopDevice(boost::filesystem::path image, boost::filesystem::path loop); 20 | 21 | static boost::filesystem::path LoopSetup(boost::filesystem::path path); 22 | static void LoopDetach(boost::filesystem::path path); 23 | 24 | private: 25 | boost::filesystem::path m_image; 26 | boost::filesystem::path m_loopDevice; 27 | }; 28 | -------------------------------------------------------------------------------- /tests/cpp/helpers/MountPoint.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include "MountPoint.h" 3 | 4 | #include 5 | #include 6 | 7 | MountPoint::MountPoint(boost::filesystem::path device, boost::filesystem::path mountPoint) 8 | : m_device(device) 9 | , m_mountPoint(mountPoint) 10 | { 11 | Mount(); 12 | } 13 | 14 | MountPoint::~MountPoint() 15 | { 16 | try 17 | { 18 | UnMount(); 19 | } 20 | catch (std::exception& ex) 21 | { 22 | std::cerr << "Failed to unmount " << m_device << ". Mount point " << m_mountPoint << std::endl; 23 | std::cerr << ex.what() << std::endl; 24 | } 25 | } 26 | 27 | boost::filesystem::path MountPoint::GetDevice() const 28 | { 29 | return m_device; 30 | } 31 | 32 | boost::filesystem::path MountPoint::GetMountPoint() const 33 | { 34 | return m_mountPoint; 35 | } 36 | 37 | void MountPoint::Mount() 38 | { 39 | if (!boost::filesystem::exists(m_mountPoint)) 40 | boost::filesystem::create_directories(m_mountPoint); 41 | 42 | boost::process::ipstream out, err; 43 | std::string command = std::string("mount ") + m_device.string() + " " + m_mountPoint.string(); 44 | 45 | int res = boost::process::system(command, boost::process::std_out > out, boost::process::std_err > err, 46 | boost::process::std_in < boost::process::null); 47 | 48 | std::string loopPath((std::istreambuf_iterator(out)), std::istreambuf_iterator()); 49 | std::string error((std::istreambuf_iterator(err)), std::istreambuf_iterator()); 50 | 51 | if (res != 0) 52 | throw std::runtime_error(std::string("Failed to mount device: ") + error); 53 | } 54 | 55 | void MountPoint::UnMount() 56 | { 57 | boost::process::ipstream out, err; 58 | std::string command = std::string("umount ") + m_device.string(); 59 | 60 | int res = boost::process::system(command, boost::process::std_out > out, boost::process::std_err > err, 61 | boost::process::std_in < boost::process::null); 62 | 63 | std::string loopPath((std::istreambuf_iterator(out)), std::istreambuf_iterator()); 64 | std::string error((std::istreambuf_iterator(err)), std::istreambuf_iterator()); 65 | 66 | if (res != 0) 67 | throw std::runtime_error(std::string("Failed to umount device: ") + error); 68 | } 69 | -------------------------------------------------------------------------------- /tests/cpp/helpers/MountPoint.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #pragma once 3 | 4 | #include 5 | 6 | class MountPoint 7 | { 8 | public: 9 | MountPoint(boost::filesystem::path device, boost::filesystem::path mountPoint); 10 | ~MountPoint(); 11 | 12 | boost::filesystem::path GetDevice() const; 13 | boost::filesystem::path GetMountPoint() const; 14 | 15 | private: 16 | void Mount(); 17 | void UnMount(); 18 | 19 | private: 20 | boost::filesystem::path m_device; 21 | boost::filesystem::path m_mountPoint; 22 | }; 23 | -------------------------------------------------------------------------------- /tests/cpp/helpers/RandomHelper.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include "RandomHelper.h" 3 | 4 | #include 5 | #include 6 | 7 | void CRandomHelper::GenerateBuffer(void* buffer, size_t size) 8 | { 9 | size_t icount = size / sizeof(int); 10 | int* ibuf = static_cast(buffer); 11 | char* chbuf = static_cast(buffer); 12 | int rnd = ::random(); 13 | 14 | for (size_t offset = 0; offset < icount; offset++) 15 | ibuf[offset] = static_cast(offset * rnd); 16 | 17 | for (size_t offset = (icount * sizeof(int)); offset < size; offset++) 18 | chbuf[offset] = static_cast((offset * rnd) & 0xFF); 19 | } 20 | 21 | int CRandomHelper::GenerateInt() 22 | { 23 | return ::random(); 24 | } 25 | -------------------------------------------------------------------------------- /tests/cpp/helpers/RandomHelper.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | 4 | class CRandomHelper 5 | { 6 | public: 7 | static void GenerateBuffer(void* buffer, size_t size); 8 | static int GenerateInt(); 9 | }; 10 | -------------------------------------------------------------------------------- /tests/cpp/helpers/Uuid.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include "Uuid.h" 3 | 4 | #include 5 | #include 6 | 7 | Uuid::Uuid() noexcept 8 | { 9 | uuid_clear(m_uuid); 10 | } 11 | 12 | Uuid::Uuid(uuid_t uuid) noexcept 13 | { 14 | uuid_copy(m_uuid, uuid); 15 | } 16 | 17 | Uuid::Uuid(const Uuid& other) noexcept 18 | { 19 | uuid_copy(m_uuid, other.m_uuid); 20 | } 21 | 22 | Uuid& Uuid::operator=(const Uuid& other) noexcept 23 | { 24 | uuid_copy(m_uuid, other.m_uuid); 25 | return *this; 26 | } 27 | 28 | std::string Uuid::ToStr() const 29 | { 30 | char str[UUID_STR_LEN]; 31 | uuid_unparse(m_uuid, str); 32 | return std::string(str); 33 | } 34 | 35 | void Uuid::Set(uuid_t other) 36 | { 37 | uuid_copy(m_uuid, other); 38 | } 39 | 40 | bool Uuid::operator==(const Uuid& other) const noexcept 41 | { 42 | return uuid_compare(m_uuid, other.m_uuid) == 0; 43 | } 44 | 45 | bool Uuid::operator!=(const Uuid& other) const noexcept 46 | { 47 | return uuid_compare(m_uuid, other.m_uuid) != 0; 48 | } 49 | 50 | Uuid::operator bool() const noexcept 51 | { 52 | return !uuid_is_null(m_uuid); 53 | } 54 | 55 | Uuid Uuid::GenerateRandom() 56 | { 57 | uuid_t uuid; 58 | uuid_generate(uuid); 59 | return Uuid(uuid); 60 | } 61 | 62 | Uuid Uuid::Parse(const std::string& str) 63 | { 64 | uuid_t uuid; 65 | if (uuid_parse(str.c_str(), uuid) != 0) 66 | { 67 | std::stringstream ss; 68 | ss << "Failed to convert {" << str << "} to uuid."; 69 | throw std::runtime_error(ss.str()); 70 | } 71 | 72 | return Uuid(uuid); 73 | } 74 | 75 | Uuid Uuid::FromBuffer(const unsigned char* buf) 76 | { 77 | Uuid uuid; 78 | uuid_copy(uuid.m_uuid, buf); 79 | return uuid; 80 | } 81 | 82 | void Uuid::Clear() 83 | { 84 | uuid_clear(m_uuid); 85 | } 86 | 87 | bool Uuid::IsSet() const noexcept 88 | { 89 | return (bool)*this; 90 | } 91 | 92 | const unsigned char* Uuid::GetRaw() const 93 | { 94 | return m_uuid; 95 | } 96 | -------------------------------------------------------------------------------- /tests/cpp/helpers/Uuid.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | class Uuid 8 | { 9 | public: 10 | Uuid() noexcept; 11 | explicit Uuid(uuid_t uuid) noexcept; 12 | Uuid(const Uuid& other) noexcept; 13 | 14 | Uuid& operator=(const Uuid& other) noexcept; 15 | 16 | void Set(uuid_t other); 17 | void Clear(); 18 | 19 | [[nodiscard]] std::string ToStr() const; 20 | 21 | bool operator==(const Uuid& other) const noexcept; 22 | bool operator!=(const Uuid& other) const noexcept; 23 | explicit operator bool() const noexcept; 24 | bool IsSet() const noexcept; 25 | 26 | const unsigned char* GetRaw() const; 27 | 28 | static Uuid GenerateRandom(); 29 | static Uuid Parse(const std::string& str); 30 | static Uuid FromBuffer(const unsigned char* buf); 31 | 32 | private: 33 | uuid_t m_uuid; 34 | }; 35 | 36 | static inline std::ostream& operator<<(std::ostream& os, const Uuid& uuid) 37 | { 38 | return os << uuid.ToStr(); 39 | } 40 | -------------------------------------------------------------------------------- /tests/cpp/performance.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "helpers/AlignedBuffer.hpp" 13 | #include "helpers/BlockDevice.h" 14 | #include "helpers/Log.h" 15 | #include "helpers/RandomHelper.h" 16 | #include "TestSector.h" 17 | 18 | namespace po = boost::program_options; 19 | using blksnap::sector_t; 20 | using blksnap::SRange; 21 | 22 | void CheckPerformance(const std::string& device, const std::string& diffStorage) 23 | { 24 | bool isErrorFound = false; 25 | 26 | logger.Info("--- Test: check performance ---"); 27 | 28 | throw std::runtime_error("Is not implemented yet."); 29 | 30 | if (isErrorFound) 31 | throw std::runtime_error("--- Failed: check performance ---"); 32 | 33 | logger.Info("--- Success: check performance ---"); 34 | } 35 | 36 | void Main(int argc, char* argv[]) 37 | { 38 | po::options_description desc; 39 | std::string usage = std::string("Checking the performance of the COW algorithm of the blksnap module."); 40 | 41 | desc.add_options() 42 | ("help,h", "Show usage information.") 43 | ("log,l", po::value(),"Detailed log of all transactions.") 44 | ("device,d", po::value(), "Device name. ") 45 | ("diff_storage,s", po::value(), 46 | "Directory name for allocating diff storage files."); 47 | po::variables_map vm; 48 | po::parsed_options parsed = po::command_line_parser(argc, argv).options(desc).run(); 49 | po::store(parsed, vm); 50 | po::notify(vm); 51 | 52 | if (vm.count("help")) 53 | { 54 | std::cout << usage << std::endl; 55 | std::cout << desc << std::endl; 56 | return; 57 | } 58 | 59 | if (vm.count("log")) 60 | { 61 | std::string filename = vm["log"].as(); 62 | logger.Open(filename); 63 | } 64 | 65 | if (!vm.count("device")) 66 | throw std::invalid_argument("Argument 'device' is missed."); 67 | std::string origDevName = vm["device"].as(); 68 | 69 | if (!vm.count("diff_storage")) 70 | throw std::invalid_argument("Argument 'diff_storage' is missed."); 71 | std::string diffStorage = vm["diff_storage"].as(); 72 | 73 | std::srand(std::time(0)); 74 | CheckPerformance(origDevName, diffStorage); 75 | } 76 | 77 | int main(int argc, char* argv[]) 78 | { 79 | try 80 | { 81 | Main(argc, argv); 82 | } 83 | catch (std::exception& ex) 84 | { 85 | std::cerr << ex.what() << std::endl; 86 | return 1; 87 | } 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /tests/fio/1000-sequental_read.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ../functions.sh 6 | . ../blksnap.sh 7 | 8 | echo "---" 9 | echo "FIO sequental read test" 10 | 11 | fio --version 12 | blksnap_load 13 | blksnap_version 14 | 15 | if [ -z $1 ] 16 | then 17 | TEST_DIR=${HOME}/blksnap-test 18 | else 19 | TEST_DIR=$(realpath $1"/blksnap-test") 20 | fi 21 | mkdir -p ${TEST_DIR} 22 | rm -rf ${TEST_DIR}/* 23 | 24 | MP_TEST_DIR=$(stat -c %m ${TEST_DIR}) 25 | DEVICE="/dev/block/"$(mountpoint -d ${MP_TEST_DIR}) 26 | echo "Test directory [${TEST_DIR}] on device [${DEVICE}] selected" 27 | 28 | MP_DIR=/mnt/blksnap-test 29 | rm -rf ${MP_DIR} 30 | mkdir -p ${MP_DIR} 31 | 32 | fio --directory "${MP_TEST_DIR}" --section sequental_read ./blksnap.fio 33 | 34 | blksnap_snapshot_create "${DEVICE}" "/dev/shm" "1G" 35 | blksnap_snapshot_watcher 36 | blksnap_snapshot_take 37 | 38 | 39 | IMAGE=${MP_DIR}/image0 40 | mkdir -p ${IMAGE} 41 | 42 | echo "Mount image" 43 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 44 | mount ${DEVICE_IMAGE} ${IMAGE} 45 | 46 | fio --directory "${IMAGE}/${MP_TEST_DIR}" --section sequental_read ./blksnap.fio 47 | 48 | echo "Umount image" 49 | umount ${IMAGE} 50 | 51 | echo "Destroy snapshot" 52 | blksnap_snapshot_destroy 53 | blksnap_watcher_wait 54 | blksnap_detach ${DEVICE} 55 | 56 | blksnap_unload 57 | 58 | echo "FIO sequental read test finish" 59 | echo "---" 60 | -------------------------------------------------------------------------------- /tests/fio/1010-sequental_read_4k.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ../functions.sh 6 | . ../blksnap.sh 7 | 8 | echo "---" 9 | echo "FIO sequental read test" 10 | 11 | fio --version 12 | blksnap_load 13 | blksnap_version 14 | 15 | if [ -z $1 ] 16 | then 17 | TEST_DIR=${HOME}/blksnap-test 18 | else 19 | TEST_DIR=$(realpath $1"/blksnap-test") 20 | fi 21 | mkdir -p ${TEST_DIR} 22 | rm -rf ${TEST_DIR}/* 23 | 24 | MP_TEST_DIR=$(stat -c %m ${TEST_DIR}) 25 | DEVICE="/dev/block/"$(mountpoint -d ${MP_TEST_DIR}) 26 | echo "Test directory [${TEST_DIR}] on device [${DEVICE}] selected" 27 | 28 | MP_DIR=/mnt/blksnap-test 29 | rm -rf ${MP_DIR} 30 | mkdir -p ${MP_DIR} 31 | 32 | fio --directory "${MP_TEST_DIR}" --section sequental_read_4k ./blksnap.fio 33 | 34 | blksnap_snapshot_create "${DEVICE}" "/dev/shm" "1G" 35 | blksnap_snapshot_watcher 36 | blksnap_snapshot_take 37 | 38 | 39 | IMAGE=${MP_DIR}/image0 40 | mkdir -p ${IMAGE} 41 | 42 | echo "Mount image" 43 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 44 | mount ${DEVICE_IMAGE} ${IMAGE} 45 | 46 | fio --directory "${IMAGE}/${MP_TEST_DIR}" --section sequental_read_4k ./blksnap.fio 47 | 48 | echo "Umount image" 49 | umount ${IMAGE} 50 | 51 | echo "Destroy snapshot" 52 | blksnap_snapshot_destroy 53 | blksnap_watcher_wait 54 | blksnap_detach ${DEVICE} 55 | 56 | blksnap_unload 57 | 58 | echo "FIO sequental read test finish" 59 | echo "---" 60 | -------------------------------------------------------------------------------- /tests/fio/1100-random_read.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ../functions.sh 6 | . ../blksnap.sh 7 | 8 | echo "---" 9 | echo "FIO random read test" 10 | 11 | fio --version 12 | blksnap_load 13 | blksnap_version 14 | 15 | if [ -z $1 ] 16 | then 17 | TEST_DIR=${HOME}/blksnap-test 18 | else 19 | TEST_DIR=$(realpath $1"/blksnap-test") 20 | fi 21 | mkdir -p ${TEST_DIR} 22 | rm -rf ${TEST_DIR}/* 23 | 24 | MP_TEST_DIR=$(stat -c %m ${TEST_DIR}) 25 | DEVICE="/dev/block/"$(mountpoint -d ${MP_TEST_DIR}) 26 | echo "Test directory [${TEST_DIR}] on device [${DEVICE}] selected" 27 | 28 | MP_DIR=/mnt/blksnap-test 29 | rm -rf ${MP_DIR} 30 | mkdir -p ${MP_DIR} 31 | 32 | fio --directory "${MP_TEST_DIR}" --section random_read ./blksnap.fio 33 | 34 | blksnap_snapshot_create "${DEVICE}" "/dev/shm" "1G" 35 | blksnap_snapshot_watcher 36 | blksnap_snapshot_take 37 | 38 | 39 | IMAGE=${MP_DIR}/image0 40 | mkdir -p ${IMAGE} 41 | 42 | echo "Mount image" 43 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 44 | mount ${DEVICE_IMAGE} ${IMAGE} 45 | 46 | fio --directory "${IMAGE}/${MP_TEST_DIR}" --section random_read ./blksnap.fio 47 | 48 | echo "Umount image" 49 | umount ${IMAGE} 50 | 51 | echo "Destroy snapshot" 52 | blksnap_snapshot_destroy 53 | blksnap_watcher_wait 54 | blksnap_detach ${DEVICE} 55 | 56 | blksnap_unload 57 | 58 | echo "FIO sequental read test finish" 59 | echo "---" 60 | -------------------------------------------------------------------------------- /tests/fio/1110-random_read_4k.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ../functions.sh 6 | . ../blksnap.sh 7 | 8 | echo "---" 9 | echo "FIO random read test" 10 | 11 | fio --version 12 | blksnap_load 13 | blksnap_version 14 | 15 | if [ -z $1 ] 16 | then 17 | TEST_DIR=${HOME}/blksnap-test 18 | else 19 | TEST_DIR=$(realpath $1"/blksnap-test") 20 | fi 21 | mkdir -p ${TEST_DIR} 22 | rm -rf ${TEST_DIR}/* 23 | 24 | MP_TEST_DIR=$(stat -c %m ${TEST_DIR}) 25 | DEVICE="/dev/block/"$(mountpoint -d ${MP_TEST_DIR}) 26 | echo "Test directory [${TEST_DIR}] on device [${DEVICE}] selected" 27 | 28 | MP_DIR=/mnt/blksnap-test 29 | rm -rf ${MP_DIR} 30 | mkdir -p ${MP_DIR} 31 | 32 | fio --directory "${MP_TEST_DIR}" --section random_read_4k ./blksnap.fio 33 | 34 | blksnap_snapshot_create "${DEVICE}" "/dev/shm" "1G" 35 | blksnap_snapshot_watcher 36 | blksnap_snapshot_take 37 | 38 | 39 | IMAGE=${MP_DIR}/image0 40 | mkdir -p ${IMAGE} 41 | 42 | echo "Mount image" 43 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 44 | mount ${DEVICE_IMAGE} ${IMAGE} 45 | 46 | fio --directory "${IMAGE}/${MP_TEST_DIR}" --section random_read_4k ./blksnap.fio 47 | 48 | echo "Umount image" 49 | umount ${IMAGE} 50 | 51 | echo "Destroy snapshot" 52 | blksnap_snapshot_destroy 53 | blksnap_watcher_wait 54 | blksnap_detach ${DEVICE} 55 | 56 | blksnap_unload 57 | 58 | echo "FIO sequental read test finish" 59 | echo "---" 60 | -------------------------------------------------------------------------------- /tests/fio/2000-cow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ../functions.sh 6 | . ../blksnap.sh 7 | 8 | echo "---" 9 | echo "FIO COW algorithm performance test" 10 | 11 | fio --version 12 | blksnap_load 13 | blksnap_version 14 | 15 | if [ -z $1 ] 16 | then 17 | echo "You must specify the path to the block device for testing." 18 | exit -1 19 | else 20 | DEVICE="$1" 21 | fi 22 | 23 | fio --filename "${DEVICE}" --section sequental_read ./blksnap.fio 24 | fio --filename "${DEVICE}" --section random_read_4k ./blksnap.fio 25 | 26 | blksnap_snapshot_create "${DEVICE}" "/dev/shm" "1G" 27 | blksnap_snapshot_watcher 28 | blksnap_snapshot_take 29 | 30 | DEVICE_IMAGE=$(blksnap_get_image ${DEVICE}) 31 | 32 | fio --filename "${DEVICE}" --section random_write_4k ./blksnap.fio 33 | fio --filename "${DEVICE}" --section sequental_read ./blksnap.fio 34 | 35 | echo "Destroy snapshot" 36 | blksnap_snapshot_destroy 37 | blksnap_watcher_wait 38 | blksnap_detach "${DEVICE}" 39 | 40 | blksnap_unload 41 | 42 | echo "FIO COW algorithm performance test finish" 43 | echo "---" 44 | -------------------------------------------------------------------------------- /tests/fio/blksnap.fio: -------------------------------------------------------------------------------- 1 | [global] 2 | ioengine=libaio 3 | kb_base=1024 4 | ; directory=${DIR} 5 | ; filename_format=jobname.jobnumber.filenumber 6 | direct=1 7 | iodepth=8 8 | 9 | [sequental_read] 10 | rw=read 11 | bs=1m 12 | size=512m 13 | 14 | [sequental_read_4k] 15 | rw=read 16 | bs=4k 17 | size=128m 18 | 19 | [sequental_write] 20 | rw=write 21 | bs=1m 22 | size=512m 23 | 24 | [sequental_write_4k] 25 | rw=write 26 | bs=4k 27 | size=128m 28 | 29 | [random_read] 30 | rw=randread 31 | bs=1m 32 | size=512m 33 | 34 | [random_read_4k] 35 | rw=randread 36 | bs=4k 37 | size=128m 38 | 39 | [random_write] 40 | rw=randwrite 41 | bs=1m 42 | size=512m 43 | 44 | [random_write_4k] 45 | rw=randwrite 46 | bs=4k 47 | size=128m 48 | -------------------------------------------------------------------------------- /tests/make_loop_dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | set -e 6 | DEVICE_PATH="/tmp/loopbackfile.img" 7 | #echo "Prepare device $DEVICE_PATH" 8 | 9 | #echo "fill zero" 10 | dd if=/dev/zero of=$DEVICE_PATH bs=1G count=1 11 | 12 | #echo "mkfs" 13 | mkfs.ext4 $DEVICE_PATH 14 | 15 | LOOP_PATH=$(losetup -f --show $DEVICE_PATH) 16 | echo $LOOP_PATH 17 | -------------------------------------------------------------------------------- /tests/manual.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | . ./functions.sh 6 | . ./blksnap.sh 7 | 8 | echo "---" 9 | echo "Manual test start" 10 | 11 | DEVICE=$1 12 | if [ -z ${DEVICE} ] 13 | then 14 | echo "Should be set device ${DEVICE} as first parameter" 15 | exit 1 16 | fi 17 | echo "Text with experiment device ${DEVICE}" 18 | 19 | DIFF_STORAGE=$2 20 | if [ -z ${DIFF_STORAGE} ] 21 | then 22 | echo "Should be set difference storage ${DIFF_STORAGE} as second parameter" 23 | exit 1 24 | fi 25 | echo "Difference will be storage on ${DIFF_STORAGE}" 26 | 27 | # check module is ready 28 | blksnap_version 29 | 30 | echo "Block device prepared, press ..." 31 | read -n 1 32 | 33 | DIFF_STORAGE=${DIFF_STORAGE}/diff_storage 34 | fallocate --length 1GiB ${DIFF_STORAGE} 35 | blksnap_snapshot_create "${DEVICE}" "${DIFF_STORAGE}" "1G" 36 | blksnap_snapshot_take 37 | echo "Snapshot was token" 38 | 39 | blksnap_snapshot_collect 40 | echo "Make your manual tests, then press ..." 41 | read -n 1 42 | 43 | echo "Destroy snapshot" 44 | blksnap_snapshot_destroy 45 | 46 | rm ${DIFF_STORAGE} 47 | 48 | echo "Manual test finish" 49 | echo "---" 50 | -------------------------------------------------------------------------------- /tests/mod_2000-stretch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | if [ -z $1 ] 6 | then 7 | DIFF_STORAGE_DIR=${HOME} 8 | else 9 | DIFF_STORAGE_DIR=$1 10 | fi 11 | 12 | . ./functions.sh 13 | . ./mod_blksnap.sh 14 | BLOCK_SIZE=$(block_size_mnt ${DIFF_STORAGE_DIR}) 15 | 16 | echo "---" 17 | echo "Stretch snapshot test" 18 | 19 | # diff_storage_minimum=262144 - set 256 K sectors, it's 128MiB diff_storage portion size 20 | blksnap_load "diff_storage_minimum=262144" 21 | 22 | # check module is ready 23 | blksnap_version 24 | 25 | TESTDIR=${HOME}/blksnap-test 26 | MPDIR=/mnt/blksnap-test 27 | 28 | rm -rf ${TESTDIR} 29 | rm -rf ${MPDIR} 30 | mkdir -p ${TESTDIR} 31 | mkdir -p ${MPDIR} 32 | echo "remove files: "$(ls ${DIFF_STORAGE_DIR}/diff_storage*) 33 | rm -rf ${DIFF_STORAGE_DIR}/diff_storage* 34 | 35 | # create first device 36 | IMAGEFILE_1=${TESTDIR}/simple_1.img 37 | imagefile_make ${IMAGEFILE_1} 4096 38 | 39 | DEVICE_1=$(loop_device_attach ${IMAGEFILE_1} ${BLOCK_SIZE}) 40 | mkfs.ext4 ${DEVICE_1} 41 | echo "new device ${DEVICE_1}" 42 | 43 | MOUNTPOINT_1=${MPDIR}/simple_1 44 | mkdir -p ${MOUNTPOINT_1} 45 | mount ${DEVICE_1} ${MOUNTPOINT_1} 46 | 47 | generate_files_direct ${MOUNTPOINT_1} "before" 5 48 | drop_cache 49 | 50 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE_DIR}" "512M" 51 | 52 | generate_files_direct ${MOUNTPOINT_1} "tracked" 5 53 | drop_cache 54 | 55 | blksnap_snapshot_watcher 56 | #echo "Press for taking snapshot..." 57 | #read -n 1 58 | 59 | blksnap_snapshot_take 60 | 61 | generate_block_MB ${MOUNTPOINT_1} "after" 100 62 | check_files ${MOUNTPOINT_1} 63 | 64 | echo "Check snapshot before overflow." 65 | #echo "press..." 66 | #read -n 1 67 | 68 | DEVICE_IMAGE_1=$(blksnap_get_image ${DEVICE_1}) 69 | IMAGE_1=${MPDIR}/image0 70 | mkdir -p ${IMAGE_1} 71 | mount ${DEVICE_IMAGE_1} ${IMAGE_1} 72 | check_files ${IMAGE_1} 73 | 74 | echo "Try to make snapshot overflow." 75 | #echo "press..." 76 | generate_block_MB ${MOUNTPOINT_1} "overflow" 768 77 | 78 | echo "Umount images" 79 | #echo "press..." 80 | umount ${IMAGE_1} 81 | 82 | echo "Destroy snapshot" 83 | #echo "press..." 84 | blksnap_snapshot_destroy 85 | blksnap_watcher_wait 86 | #echo "Check generated data" 87 | #check_files ${MOUNTPOINT_1} 88 | 89 | echo "Destroy first device" 90 | #echo "press..." 91 | blksnap_detach ${DEVICE_1} 92 | umount ${MOUNTPOINT_1} 93 | loop_device_detach ${DEVICE_1} 94 | imagefile_cleanup ${IMAGEFILE_1} 95 | 96 | blksnap_unload 97 | 98 | echo "Stretch snapshot test finish" 99 | echo "---" 100 | -------------------------------------------------------------------------------- /tests/perf-cow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | # 6 | # Requirement: 7 | # The 'TESTDIR' directory and the 'DIFF_STORAGE_DIR' directory 8 | # must be on different block devices. 9 | # 10 | 11 | if [ -z $1 ] 12 | then 13 | TESTDIR="/home/user" 14 | else 15 | TESTDIR=$2 16 | fi 17 | DEVICE_1=$(findmnt -n -o SOURCE -T ${TESTDIR}) 18 | echo "Test directory ${TESTDIR} on device ${DEVICE_1}" 19 | 20 | if [ -z $2 ] 21 | then 22 | DIFF_STORAGE_DIR="/tmp" 23 | else 24 | DIFF_STORAGE_DIR=$1 25 | fi 26 | 27 | SOURCE_FILE=${DIFF_STORAGE_DIR}/test_file.dat 28 | if [ ! -f ${SOURCE_FILE} ] 29 | then 30 | dd if=/dev/urandom of=${SOURCE_FILE} count=$((7 * 1024)) bs=1M oflag=direct status=none 31 | fi 32 | TARGET_FILE=${TESTDIR}/test_file.dat 33 | 34 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 35 | 36 | . ./functions.sh 37 | . ./blksnap.sh 38 | 39 | echo "---" 40 | echo "Perf COW test start" 41 | 42 | blksnap_load 43 | 44 | # check module is ready 45 | blksnap_version 46 | 47 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 48 | fallocate --length 1024MiB ${DIFF_STORAGE} 49 | 50 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE}" "8G" 51 | blksnap_snapshot_take 52 | 53 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 54 | echo "Write to original" 55 | # echo "press a key..." 56 | # read -n 1 57 | perf record -ag dd if=${SOURCE_FILE} of=${TARGET_FILE} bs=1M iflag=direct oflag=direct 58 | 59 | #echo "Destroy snapshot, press ..." 60 | #read -n 1 61 | blksnap_snapshot_destroy 62 | 63 | echo "Destroy device" 64 | blksnap_detach ${DEVICE_1} 65 | 66 | rm ${TARGET_FILE} 67 | rm ${DIFF_STORAGE} 68 | 69 | blksnap_unload 70 | 71 | echo "Perf COW test finish" 72 | echo "---" 73 | 74 | perf report 75 | -------------------------------------------------------------------------------- /tests/perf-snapshot_read.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | # 6 | # Requirement: 7 | # The 'TESTDIR' directory and the 'DIFF_STORAGE_DIR' directory 8 | # must be on different block devices. 9 | # 10 | 11 | if [ -z $1 ] 12 | then 13 | TESTDIR="/home/user" 14 | else 15 | TESTDIR=$2 16 | fi 17 | DEVICE_1=$(findmnt -n -o SOURCE -T ${TESTDIR}) 18 | echo "Test directory ${TESTDIR} on device ${DEVICE_1}" 19 | 20 | if [ -z $2 ] 21 | then 22 | DIFF_STORAGE_DIR="/tmp" 23 | else 24 | DIFF_STORAGE_DIR=$1 25 | fi 26 | 27 | SOURCE_FILE=${DIFF_STORAGE_DIR}/test_file.dat 28 | if [ ! -f ${SOURCE_FILE} ] 29 | then 30 | dd if=/dev/urandom of=${SOURCE_FILE} count=$((7 * 1024)) bs=1M 31 | fi 32 | TARGET_FILE=${TESTDIR}/test_file.dat 33 | 34 | echo "Diff storage directory ${DIFF_STORAGE_DIR}" 35 | 36 | . ./functions.sh 37 | . ./blksnap.sh 38 | 39 | echo "---" 40 | echo "Perf snapshot read test start" 41 | 42 | blksnap_load 43 | 44 | # check module is ready 45 | blksnap_version 46 | 47 | DIFF_STORAGE="${DIFF_STORAGE_DIR}/diff_storage" 48 | fallocate --length 1024MiB ${DIFF_STORAGE} 49 | 50 | blksnap_snapshot_create "${DEVICE_1}" "${DIFF_STORAGE}" "8G" 51 | blksnap_snapshot_take 52 | 53 | #echo "Write something" > ${MOUNTPOINT_1}/something.txt 54 | echo "Write to original" 55 | dd if=${SOURCE_FILE} of=${TARGET_FILE} bs=1M oflag=direct 56 | 57 | echo "Read from snapshot " 58 | perf record -ag dd if=${TARGET_FILE} of=/dev/null bs=1M iflag=direct 59 | 60 | #echo "Destroy snapshot, press ..." 61 | #read -n 1 62 | blksnap_snapshot_destroy 63 | 64 | echo "Destroy device" 65 | blksnap_detach ${DEVICE_1} 66 | 67 | rm ${TARGET_FILE} 68 | rm ${DIFF_STORAGE} 69 | 70 | blksnap_unload 71 | 72 | echo "Perf snapshot read test finish" 73 | echo "---" 74 | 75 | perf report 76 | -------------------------------------------------------------------------------- /tests/unload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # SPDX-License-Identifier: GPL-2.0+ 4 | 5 | modprobe -r blksnap 6 | 7 | echo 0 > /sys/kernel/livepatch/bdevfilter/enabled 8 | sleep 3s 9 | modprobe -r bdevfilter 10 | -------------------------------------------------------------------------------- /tools/blksnap/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # https://clang.llvm.org/docs/ClangFormatStyleOptions.html 3 | BasedOnStyle: WebKit 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlines: Left 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: false 9 | AllowShortBlocksOnASingleLine: false 10 | AllowShortCaseLabelsOnASingleLine: false 11 | AllowShortFunctionsOnASingleLine: None 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: None 15 | AlwaysBreakAfterReturnType: None 16 | AlwaysBreakBeforeMultilineStrings: false 17 | AlwaysBreakTemplateDeclarations: Yes 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BreakBeforeBinaryOperators: All 21 | BreakBeforeBraces: Custom 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: true 25 | AfterEnum: true 26 | AfterFunction: true 27 | AfterNamespace: true 28 | AfterObjCDeclaration: true 29 | AfterStruct: true 30 | AfterUnion: true 31 | AfterExternBlock: true 32 | BeforeCatch: true 33 | BeforeElse: true 34 | IndentBraces: false 35 | SplitEmptyFunction: true 36 | SplitEmptyRecord: false 37 | SplitEmptyNamespace: false 38 | BreakBeforeTernaryOperators: true 39 | BreakConstructorInitializers: BeforeComma 40 | BreakInheritanceList: BeforeComma 41 | BreakStringLiterals: false 42 | ColumnLimit: 120 43 | CommentPragmas: '^ IWYU pragma:' 44 | CompactNamespaces: false 45 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 46 | ConstructorInitializerIndentWidth: 4 47 | ContinuationIndentWidth: 2 48 | Cpp11BracedListStyle: true 49 | DerivePointerAlignment: false 50 | DisableFormat: false 51 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 52 | IncludeCategories: 53 | - Regex: '^".*_config.h"$' 54 | Priority: -2 55 | - Regex: '^"(stdafx|PrecompiledHeader)' 56 | Priority: -1 57 | - Regex: '^<([a-zA-Z0-9_]+.*)>$' 58 | Priority: 1 59 | - Regex: '^<([.]+.*)>$' 60 | Priority: 2 61 | - Regex: '.*' 62 | Priority: 3 63 | IncludeBlocks: Regroup 64 | IndentCaseLabels: false 65 | IndentPPDirectives: AfterHash 66 | IndentWidth: 4 67 | IndentWrappedFunctionNames: true 68 | KeepEmptyLinesAtTheStartOfBlocks: false 69 | Language: Cpp 70 | MaxEmptyLinesToKeep: 1 71 | NamespaceIndentation: All 72 | PointerAlignment: Left 73 | SortIncludes: true 74 | SpaceAfterCStyleCast: false 75 | SpaceAfterTemplateKeyword: false 76 | SpaceBeforeAssignmentOperators: true 77 | SpaceBeforeCpp11BracedList: false 78 | SpaceBeforeCtorInitializerColon: true 79 | SpaceBeforeInheritanceColon: true 80 | SpaceBeforeParens: ControlStatements 81 | SpaceBeforeRangeBasedForLoopColon: true 82 | SpaceInEmptyParentheses: false 83 | SpacesBeforeTrailingComments: 1 84 | SpacesInAngles: false 85 | SpacesInCStyleCastParentheses: false 86 | SpacesInContainerLiterals: false 87 | SpacesInParentheses: false 88 | SpacesInSquareBrackets: false 89 | TabWidth: 4 90 | UseTab: Never 91 | ... 92 | -------------------------------------------------------------------------------- /tools/blksnap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0+ 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | project(blksnap-tools) 5 | 6 | set(CMAKE_CXX_STANDARD 14) 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc") 8 | 9 | set(Boost_USE_STATIC_LIBS ON) 10 | FIND_PACKAGE( Boost COMPONENTS program_options filesystem REQUIRED) 11 | 12 | FIND_LIBRARY(LIBUUID_LIBRARY libuuid.so REQUIRED) 13 | if (NOT LIBUUID_LIBRARY) 14 | message(FATAL_ERROR "libuuid not found. please install uuid-dev or libuuid-devel package.") 15 | endif () 16 | 17 | add_executable(${PROJECT_NAME} main.cpp) 18 | set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "blksnap") 19 | 20 | set(TOOLS_LIBS ${LIBUUID_LIBRARY} blksnap-dev Boost::filesystem Boost::program_options) 21 | target_link_libraries(${PROJECT_NAME} PRIVATE ${TOOLS_LIBS}) 22 | target_include_directories(${PROJECT_NAME} PRIVATE ./) 23 | 24 | install(TARGETS ${PROJECT_NAME} DESTINATION /usr/sbin) 25 | --------------------------------------------------------------------------------