├── .fmf └── version ├── .github ├── dependabot.yml └── workflows │ ├── blivet-tests.yml │ ├── codeql-analysis.yml │ ├── compilation.yml │ ├── csmock.yml │ ├── spelling.yml │ └── udisks-build.yml ├── .gitignore ├── .packit.yaml ├── LICENSE ├── Makefile.am ├── NEWS.rst ├── README.DEVEL.md ├── README.md ├── acinclude.m4 ├── autogen.sh ├── configure.ac ├── data ├── Makefile.am └── conf.d │ ├── 00-default.cfg │ ├── 10-lvm-dbus.cfg │ └── Makefile.am ├── dist ├── Makefile.am └── libblockdev.spec.in ├── docs ├── 3.0-api-changes.xml ├── Makefile.am ├── libblockdev-docs.xml.in └── libblockdev-sections.txt ├── include ├── Makefile.am └── blockdev │ └── Makefile.am ├── misc ├── PythonDocs.Dockerfile ├── Vagrantfile ├── ci.Dockerfile ├── install-test-dependencies.yml └── libblockdev-tasks.yml ├── plans ├── blivet.fmf ├── tests.fmf └── udisks.fmf ├── scripts ├── Makefile.am └── boilerplate_generator.py ├── src ├── Makefile.am ├── lib │ ├── Makefile.am │ ├── blockdev.c.in │ ├── blockdev.h │ ├── blockdev.pc.in │ ├── plugin_apis │ │ ├── Makefile.am │ │ ├── btrfs.api │ │ ├── crypto.api │ │ ├── dm.api │ │ ├── fs.api │ │ ├── loop.api │ │ ├── lvm.api │ │ ├── mdraid.api │ │ ├── mpath.api │ │ ├── nvdimm.api │ │ ├── nvme.api │ │ ├── part.api │ │ ├── s390.api │ │ ├── smart.api │ │ └── swap.api │ ├── plugins.c │ └── plugins.h ├── plugins │ ├── Makefile.am │ ├── btrfs.c │ ├── btrfs.h │ ├── check_deps.c │ ├── check_deps.h │ ├── crypto.c │ ├── crypto.h │ ├── dm.c │ ├── dm.h │ ├── dm_logging.c │ ├── dm_logging.h │ ├── fs.c │ ├── fs.h │ ├── fs │ │ ├── Makefile.am │ │ ├── btrfs.c │ │ ├── btrfs.h │ │ ├── common.c │ │ ├── common.h │ │ ├── exfat.c │ │ ├── exfat.h │ │ ├── ext.c │ │ ├── ext.h │ │ ├── f2fs.c │ │ ├── f2fs.h │ │ ├── generic.c │ │ ├── generic.h │ │ ├── mount.c │ │ ├── mount.h │ │ ├── nilfs.c │ │ ├── nilfs.h │ │ ├── ntfs.c │ │ ├── ntfs.h │ │ ├── udf.c │ │ ├── udf.h │ │ ├── vfat.c │ │ ├── vfat.h │ │ ├── xfs.c │ │ └── xfs.h │ ├── loop.c │ ├── loop.h │ ├── lvm │ │ ├── Makefile.am │ │ ├── lvm-common.c │ │ ├── lvm-dbus.c │ │ ├── lvm-private.h │ │ ├── lvm.c │ │ ├── lvm.h │ │ ├── vdo_stats.c │ │ └── vdo_stats.h │ ├── mdraid.c │ ├── mdraid.h │ ├── mpath.c │ ├── mpath.h │ ├── nvdimm.c │ ├── nvdimm.h │ ├── nvme │ │ ├── Makefile.am │ │ ├── nvme-error.c │ │ ├── nvme-fabrics.c │ │ ├── nvme-info.c │ │ ├── nvme-op.c │ │ ├── nvme-private.h │ │ ├── nvme.c │ │ └── nvme.h │ ├── part.c │ ├── part.h │ ├── s390.c │ ├── s390.h │ ├── smart │ │ ├── Makefile.am │ │ ├── drivedb-parser.c │ │ ├── libatasmart.c │ │ ├── smart-common.c │ │ ├── smart-private.h │ │ ├── smart.h │ │ └── smartmontools.c │ ├── swap.c │ └── swap.h ├── python │ ├── Makefile.am │ └── gi │ │ ├── Makefile.am │ │ └── overrides │ │ ├── BlockDev.py │ │ └── Makefile.am └── utils │ ├── Makefile.am │ ├── blockdev-utils.pc.in │ ├── dbus.c │ ├── dbus.h │ ├── dev_utils.c │ ├── dev_utils.h │ ├── exec.c │ ├── exec.h │ ├── extra_arg.c │ ├── extra_arg.h │ ├── logging.c │ ├── logging.h │ ├── module.c │ ├── module.h │ ├── sizes.h │ └── utils.h ├── tests ├── Makefile.am ├── README.rst ├── __init__.py ├── bitlk-images.tar.gz ├── btrfs_test.py ├── crypto_test.py ├── dm_test.py ├── fake_utils │ ├── btrfs_low_version │ │ └── btrfs │ ├── btrfs_new_version_format │ │ └── btrfs │ ├── btrfs_subvols_docker │ │ └── btrfs │ ├── dm_low_version │ │ └── dmsetup │ ├── fsck_f2fs_low_version │ │ └── fsck.f2fs │ ├── lib_missing_utils │ │ └── nothing_needed_here │ ├── loop_low_version │ │ └── losetup │ ├── lvm_low_version │ │ └── lvm │ ├── mdadm_extra_name_stuff │ │ └── mdadm │ ├── mdadm_fw_RAID_examine │ │ └── mdadm │ ├── mdadm_fw_RAID_examine_migrate │ │ └── mdadm │ ├── mdadm_no_metadata_examine │ │ └── mdadm │ ├── mdraid_low_version │ │ └── mdadm │ ├── mpath_low_version │ │ └── multipath │ ├── mpath_no_mpathconf │ │ └── multipath │ ├── smartctl │ │ └── smartctl │ ├── swap_low_version │ │ └── mkswap │ ├── swap_no_swapoff │ │ ├── mkswap │ │ └── swapon │ ├── swap_no_swapon │ │ ├── mkswap │ │ └── swapoff │ └── utils_fake_util │ │ ├── libblockdev-fake-util │ │ ├── libblockdev-fake-util-fail │ │ └── libblockdev-fake-util-stderr ├── fs_tests │ ├── __init__.py │ ├── btrfs_test.py │ ├── exfat_test.py │ ├── ext_test.py │ ├── f2fs_test.py │ ├── fs_test.py │ ├── generic_test.py │ ├── mount_test.py │ ├── nilfs_test.py │ ├── ntfs_test.py │ ├── udf_test.py │ ├── vfat_test.py │ └── xfs_test.py ├── fvault2-images.tar.gz ├── library_test.py ├── loop_test.py ├── lvm_dbus_tests.py ├── lvm_test.py ├── mdraid_test.py ├── mpath_test.py ├── nvdimm_test.py ├── nvme_test.py ├── overrides_hack.py ├── overrides_test.py ├── part_test.py ├── run_tests.py ├── s390_test.py ├── skip.yml ├── smart_dumps │ ├── 01_old_ver.json │ ├── 02_exit_err.json │ ├── 03_exit_err_32.json │ ├── 04_malformed.json │ ├── 05_empty.json │ ├── Biwintech_SSD_SX500.bin │ ├── GIGABYTE_GP-GSTFS31100TNTD.bin │ ├── HGST_HMS5C4040BLE640.json │ ├── HGST_HUS726060ALA640.json │ ├── HGST_HUSMR3280ASS200.json │ ├── Hitachi_HDS5C3020ALA632.json │ ├── Hitachi_HDS721010CLA632.bin │ ├── IBM_IC25N020ATCS04-0.bin │ ├── INTEL_SSDSC2BB120G4L.json │ ├── KINGSTON_SA400S37240G_SBFK71B1.bin │ ├── KINGSTON_SA400S37480G_SBFKQ13.bin │ ├── Maxtor_6Y120P0.bin │ ├── Patriot_Burst_240GB.bin │ ├── SAMSUNG_HS122JC.bin │ ├── SAMSUNG_MMCRE28G5MXP-0VBH1.bin │ ├── SEAGATE_ST600MP0036.json │ ├── SiliconPower_SSD_SBFM61.3.bin │ ├── TOSHIBA_AL15SEB120NY.json │ ├── TOSHIBA_AL15SEB18EQY.json │ ├── TOSHIBA_KPM5XMUG400G.json │ ├── TOSHIBA_THNSNH128GBST.bin │ ├── TOSHIBA_THNSNH128GBST.json │ ├── WD4001FYYG-01SL3.json │ ├── WDC_WD10EFRX-68PJCN0.json │ └── WDC_WD20EARS-00MVWB0.bin ├── smart_test.py ├── smartmontools_test.py ├── swap_test.py ├── test_configs │ ├── default_config │ │ └── 00-default.cfg │ ├── lvm_dbus_config │ │ ├── 00-default.cfg │ │ └── 10-lvm-dbus.cfg │ ├── plugin_multi_conf.d │ │ ├── 00-default.cfg │ │ └── 10-lvm2.cfg │ └── plugin_prio_conf.d │ │ └── 00-default.cfg ├── truecrypt-images.tar.gz ├── utils.py └── utils_test.py └── tools ├── Makefile.am ├── lvm-cache-stats.c └── vfat-resize.c /.fmf/version: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | # Set update schedule for GitHub actions. 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | commit-message: 10 | prefix: "infra" 11 | -------------------------------------------------------------------------------- /.github/workflows/blivet-tests.yml: -------------------------------------------------------------------------------- 1 | name: Blivet tests 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: blivet-tests 11 | runs-on: ubuntu-24.04 12 | env: 13 | CI_CONTAINER: libblockdev-ci-blivet-tests 14 | steps: 15 | - name: Checkout libblockdev repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Install podman 19 | run: | 20 | sudo apt -qq update 21 | sudo apt -y -qq install podman 22 | 23 | - name: Build the container 24 | run: | 25 | podman build --no-cache -t ${{ env.CI_CONTAINER }} -f misc/ci.Dockerfile . 26 | 27 | - name: Start the container 28 | run: | 29 | podman run -d -t --name ${{ env.CI_CONTAINER }} --privileged --volume "$(pwd):/app" --workdir "/app" ${{ env.CI_CONTAINER }} 30 | 31 | - name: Install Blivet test dependencies in the container 32 | run: | 33 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "ansible-playbook -i "localhost," -c local /blivet/misc/install-test-dependencies.yml" 34 | 35 | - name: Install libblockdev build dependencies in the container 36 | run: | 37 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "ansible-playbook -i "localhost," -c local misc/install-test-dependencies.yml -e 'test_dependencies=false'" 38 | 39 | - name: Build and install libblockdev in the container 40 | run: | 41 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "./autogen.sh && ./configure --prefix=/usr && make -j && make install" 42 | 43 | - name: Run Blivet tests in the container 44 | run: | 45 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "cd /blivet && make check" 46 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | schedule: 9 | - cron: '29 9 * * 4' 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-24.04 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [ 'cpp', 'python' ] 24 | 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v4 28 | 29 | # Initializes the CodeQL tools for scanning. 30 | - name: Initialize CodeQL 31 | uses: github/codeql-action/init@v3 32 | with: 33 | languages: ${{ matrix.language }} 34 | 35 | - name: Install build dependencies 36 | run: | 37 | sudo apt -y install ansible 38 | ansible-playbook -b -i "localhost," -c local misc/install-test-dependencies.yml -e "test_dependencies=false" 39 | 40 | - name: Build 41 | run: | 42 | ./autogen.sh && ./configure && make -j 43 | 44 | - name: Perform CodeQL Analysis 45 | uses: github/codeql-action/analyze@v3 46 | with: 47 | category: "/language:${{matrix.language}}" 48 | -------------------------------------------------------------------------------- /.github/workflows/compilation.yml: -------------------------------------------------------------------------------- 1 | name: Compilation with different compilers 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: compilation 11 | runs-on: ubuntu-24.04 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | compiler: ['gcc-10', 'gcc-11', 'gcc-12', 'gcc-13', 'gcc-14', 17 | 'clang-14', 'clang-15', 'clang-16', 'clang-17', 'clang-18'] 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - name: Install build dependencies 23 | run: | 24 | sudo apt -y install ansible 25 | ansible-playbook -b -i "localhost," -c local misc/install-test-dependencies.yml -e "test_dependencies=false" 26 | 27 | - name: Install compiler 28 | run: | 29 | sudo apt -y install ${{ matrix.compiler }} 30 | 31 | - name: Configure 32 | run: | 33 | ./autogen.sh && CC=${{ matrix.compiler }} ./configure 34 | 35 | - name: Make 36 | run: | 37 | make 38 | -------------------------------------------------------------------------------- /.github/workflows/csmock.yml: -------------------------------------------------------------------------------- 1 | name: Run static analysis using csmock 2 | 3 | env: 4 | CSMOCK_CHROOTS: "default" 5 | CSMOCK_TOOLS: "clang cppcheck gcc" 6 | 7 | on: 8 | pull_request: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | build: 14 | name: csmock 15 | runs-on: ubuntu-22.04 16 | env: 17 | CI_CONTAINER: libblockdev-ci-csmock 18 | steps: 19 | - name: Checkout libblockdev repository 20 | uses: actions/checkout@v4 21 | 22 | - name: Install podman 23 | run: | 24 | sudo apt -qq update 25 | sudo apt -y -qq install podman 26 | 27 | - name: Build the container 28 | run: | 29 | podman build --no-cache -t ${{ env.CI_CONTAINER }} -f misc/ci.Dockerfile . 30 | 31 | - name: Start the container 32 | run: | 33 | podman run -d -t --name ${{ env.CI_CONTAINER }} --privileged --volume "$(pwd):/app" --workdir "/app" ${{ env.CI_CONTAINER }} 34 | 35 | - name: Install test dependencies in the container 36 | run: | 37 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "ansible-playbook -i "localhost," -c local misc/install-test-dependencies.yml -e 'test_dependencies=false'" 38 | 39 | - name: Run csmock build in the container 40 | run: | 41 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "/ci/run_csmock_tests -c /ci/copr-builder.conf -p libblockdev-udisks -t ${{ env.CSMOCK_TOOLS }} -r ${{ env.CSMOCK_CHROOTS }}" 42 | 43 | - name: Upload the csmock logs 44 | if: always() 45 | uses: actions/upload-artifact@v4 46 | with: 47 | name: csmock_logs 48 | path: csmock_*/* 49 | -------------------------------------------------------------------------------- /.github/workflows/spelling.yml: -------------------------------------------------------------------------------- 1 | name: Check spelling using codespell and spellintian 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: spelling 11 | runs-on: ubuntu-24.04 12 | env: 13 | CI_CONTAINER: libblockdev-ci-spelling 14 | steps: 15 | - name: Checkout libblockdev repository 16 | uses: actions/checkout@v4 17 | with: 18 | path: libblockdev 19 | 20 | - name: Install codespell and lintian 21 | run: | 22 | sudo apt -qq update 23 | sudo apt -y -qq install codespell lintian 24 | 25 | - name: Get the storaged-project/ci repository 26 | uses: actions/checkout@v4 27 | with: 28 | repository: storaged-project/ci 29 | path: ci 30 | 31 | - name: Run the checks 32 | run: | 33 | python3 ../ci/run_spell_checks -p libblockdev -i gir 34 | working-directory: ./libblockdev 35 | -------------------------------------------------------------------------------- /.github/workflows/udisks-build.yml: -------------------------------------------------------------------------------- 1 | name: UDisks build 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: udisks-build 11 | runs-on: ubuntu-24.04 12 | env: 13 | CI_CONTAINER: libblockdev-ci-udisks-build 14 | steps: 15 | - name: Checkout libblockdev repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Install podman 19 | run: | 20 | sudo apt -qq update 21 | sudo apt -y -qq install podman 22 | 23 | - name: Build the container 24 | run: | 25 | podman build --no-cache -t ${{ env.CI_CONTAINER }} -f misc/ci.Dockerfile . 26 | 27 | - name: Start the container 28 | run: | 29 | podman run -d -t --name ${{ env.CI_CONTAINER }} --privileged --volume "$(pwd):/app" --workdir "/app" ${{ env.CI_CONTAINER }} 30 | 31 | - name: Install UDisks build dependencies in the container 32 | run: | 33 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "dnf -y builddep --skip-unavailable /udisks/packaging/udisks2.spec" 34 | 35 | - name: Install libblockdev build dependencies in the container 36 | run: | 37 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "ansible-playbook -i "localhost," -c local misc/install-test-dependencies.yml -e 'test_dependencies=false'" 38 | 39 | - name: Build and install libblockdev in the container 40 | run: | 41 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "./autogen.sh && ./configure --prefix=/usr && make -j && make install" 42 | 43 | - name: Build UDisks in the container 44 | run: | 45 | podman exec -it ${{ env.CI_CONTAINER }} bash -c "cd /udisks && ./autogen.sh --enable-modules && make -j" 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .*.swp 3 | .coverage 4 | coverage-report.log 5 | tests/error_occurred 6 | **/*.pyc 7 | *libblockdev*.tar.gz 8 | src/lib/plugin_apis/*.[ch] 9 | src/plugins/.dirstamp 10 | BlockDev-*.gir 11 | BlockDev-*.typelib 12 | Makefile 13 | Makefile.in 14 | aclocal.m4 15 | ar-lib 16 | compile 17 | py-compile 18 | config.guess 19 | config.log 20 | config.status 21 | config.sub 22 | configure 23 | depcomp 24 | install-sh 25 | libtool 26 | ltmain.sh 27 | m4/ 28 | autom4te.cache/ 29 | missing 30 | src/lib/.deps/ 31 | src/lib/blockdev.c 32 | src/lib/blockdev.pc 33 | src/utils/blockdev-utils.pc 34 | **/*.deps 35 | **/*.libs 36 | **/*.la 37 | **/*.lo 38 | **/*.o 39 | **/Makefile 40 | **/Makefile.in 41 | **/*.stamp 42 | **/*.bak 43 | include/blockdev/*.h 44 | include/blockdev/fs 45 | docs/libblockdev-decl-list.txt 46 | docs/libblockdev-decl.txt 47 | docs/libblockdev-overrides.txt 48 | docs/libblockdev-undeclared.txt 49 | docs/libblockdev-undocumented.txt 50 | docs/libblockdev-unused.txt 51 | docs/libblockdev.types 52 | docs/xml/ 53 | docs/html/ 54 | docs/libblockdev-docs.xml 55 | dist/libblockdev.spec 56 | tools/lvm-cache-stats 57 | tools/vfat-resize 58 | misc/.vagrant 59 | tests/config_h.py 60 | -------------------------------------------------------------------------------- /.packit.yaml: -------------------------------------------------------------------------------- 1 | actions: 2 | post-upstream-clone: 3 | - 'cp dist/libblockdev.spec.in dist/libblockdev.spec' 4 | - 'sed -i -e "s/@WITH_..*@/1/g" -e "s/@MAJOR_VER@/3/g" dist/libblockdev.spec' 5 | create-archive: 6 | - './autogen.sh' 7 | - './configure' 8 | - 'make' 9 | - 'make local' 10 | - 'bash -c "ls *.tar*"' 11 | get-current-version: 12 | - 'bash -c "grep Version: dist/libblockdev.spec.in | cut -f2 -d\":\" | tr -d \" \""' 13 | 14 | jobs: 15 | - job: copr_build 16 | metadata: 17 | targets: 18 | - fedora-rawhide-aarch64 19 | - fedora-rawhide-ppc64le 20 | - fedora-rawhide-x86_64 21 | - fedora-latest-aarch64 22 | - fedora-latest-ppc64le 23 | - fedora-latest-x86_64 24 | - fedora-latest-stable-aarch64 25 | - fedora-latest-stable-ppc64le 26 | - fedora-latest-stable-x86_64 27 | trigger: pull_request 28 | 29 | - job: copr_build 30 | trigger: commit 31 | owner: "@storage" 32 | project: blivet-daily 33 | branch: master 34 | preserve_project: true 35 | actions: 36 | post-upstream-clone: 37 | # bump release to 99 to always be ahead of Fedora builds 38 | - 'bash -c "sed -i -r \"s/Release:(\s*)\S+/Release: 99%{?dist}/\" dist/libblockdev.spec.in"' 39 | - 'cp dist/libblockdev.spec.in dist/libblockdev.spec' 40 | - 'sed -i -e "s/@WITH_..*@/1/g" -e "s/@MAJOR_VER@/3/g" dist/libblockdev.spec' 41 | create-archive: 42 | - './autogen.sh' 43 | - './configure' 44 | - 'make' 45 | - 'make local' 46 | - 'bash -c "ls *.tar*"' 47 | get-current-version: 48 | - 'bash -c "grep Version: dist/libblockdev.spec.in | cut -f2 -d\":\" | tr -d \" \""' 49 | 50 | - job: copr_build 51 | trigger: commit 52 | owner: "@storage" 53 | project: udisks-daily 54 | branch: master 55 | preserve_project: true 56 | actions: 57 | post-upstream-clone: 58 | # bump release to 99 to always be ahead of Fedora builds 59 | - 'bash -c "sed -i -r \"s/Release:(\s*)\S+/Release: 99%{?dist}/\" dist/libblockdev.spec.in"' 60 | - 'cp dist/libblockdev.spec.in dist/libblockdev.spec' 61 | - 'sed -i -e "s/@WITH_..*@/1/g" -e "s/@MAJOR_VER@/3/g" dist/libblockdev.spec' 62 | create-archive: 63 | - './autogen.sh' 64 | - './configure' 65 | - 'make' 66 | - 'make local' 67 | - 'bash -c "ls *.tar*"' 68 | get-current-version: 69 | - 'bash -c "grep Version: dist/libblockdev.spec.in | cut -f2 -d\":\" | tr -d \" \""' 70 | 71 | - job: propose_downstream 72 | trigger: release 73 | dist_git_branches: 74 | - fedora-development 75 | - fedora-latest 76 | 77 | - job: koji_build 78 | trigger: commit 79 | dist_git_branches: 80 | - fedora-development 81 | - fedora-latest 82 | 83 | - job: bodhi_update 84 | trigger: commit 85 | dist_git_branches: 86 | - fedora-branched 87 | 88 | - job: tests 89 | trigger: pull_request 90 | targets: 91 | - fedora-latest-stable 92 | 93 | # run tests for libblockdev consumers, see plans/ with `revdeps_blivet == yes` 94 | - job: tests 95 | identifier: revdeps_blivet 96 | trigger: pull_request 97 | notifications: 98 | failure_comment: 99 | message: "Blivet tests failed for commit {commit_sha}. @vojtechtrefny please check." 100 | targets: 101 | - fedora-latest-stable 102 | tf_extra_params: 103 | environments: 104 | - artifacts: 105 | - type: repository-file 106 | id: https://copr.fedorainfracloud.org/coprs/g/storage/blivet-daily/repo/fedora-$releasever/group_storage-blivet-daily-fedora-$releasever.repo 107 | tmt: 108 | context: 109 | revdeps_blivet: "yes" 110 | 111 | - job: tests 112 | identifier: revdeps_udisks 113 | trigger: pull_request 114 | notifications: 115 | failure_comment: 116 | message: "udisks tests failed for commit {commit_sha}. @vojtechtrefny @tbzatek please check." 117 | targets: 118 | - fedora-latest-stable 119 | tf_extra_params: 120 | environments: 121 | - artifacts: 122 | - type: repository-file 123 | id: https://copr.fedorainfracloud.org/coprs/g/storage/udisks-daily/repo/fedora-$releasever/group_storage-udisks-daily-fedora-$releasever.repo 124 | tmt: 125 | context: 126 | revdeps_udisks: "yes" 127 | 128 | srpm_build_deps: 129 | - make 130 | - gcc 131 | - libtool 132 | - autoconf 133 | - autoconf-archive 134 | - automake 135 | - cryptsetup-devel 136 | - device-mapper-devel 137 | - e2fsprogs-devel 138 | - glib2-devel 139 | - glib2-doc 140 | - gobject-introspection-devel 141 | - gtk-doc 142 | - json-glib-devel 143 | - keyutils-libs-devel 144 | - kmod-devel 145 | - libatasmart-devel 146 | - libblkid-devel 147 | - libbytesize-devel 148 | - libfdisk-devel 149 | - libmount-devel 150 | - libnvme-devel 151 | - libuuid-devel 152 | - libyaml-devel 153 | - ndctl-devel 154 | - nss-devel 155 | - parted-devel 156 | - python3-devel 157 | - systemd-devel 158 | - volume_key-devel 159 | 160 | downstream_package_name: libblockdev 161 | specfile_path: dist/libblockdev.spec 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### CI status 2 | 3 | CI status 4 | 5 | ### Introduction 6 | 7 | libblockdev is a C library supporting GObject introspection for manipulation of 8 | block devices. It has a plugin-based architecture where each technology (like 9 | LVM, Btrfs, MD RAID, Swap,...) is implemented in a separate plugin, possibly 10 | with multiple implementations (e.g. using LVM CLI or the new LVM DBus API). 11 | 12 | #### Features 13 | 14 | Following storage technologies are supported by libblockdev 15 | 16 | - partitions 17 | - MSDOS, GPT 18 | - filesystem operations 19 | - ext2, ext3, ext4, xfs, vfat, ntfs, exfat, btrfs, f2fs, nilfs2, udf 20 | - mounting 21 | - LVM 22 | - thin provisioning, LVM RAID, cache, LVM VDO 23 | - BTRFS 24 | - multi-device volumes, subvolumes, snapshots 25 | - swap 26 | - encryption 27 | - LUKS, TrueCrypt/VeraCrypt, BitLocker, FileVault2 28 | - integrity 29 | - SED OPAL 30 | - DM (device mapper) 31 | - loop devices 32 | - MD RAID 33 | - multipath 34 | - s390 35 | - DASD, zFCP 36 | - NVDIMM namespaces (deprecated) 37 | - NVMe 38 | - SMART 39 | 40 | #### Architecture 41 | 42 | The library itself is only a thin wrapper around a set of plugins, each for a 43 | particular technology listed above. The library provides an API consisting of 44 | sets of functions provided by its plugins. For example, there is a 45 | symbol/function called ``bd_lvm_lvcreate`` provided by the library which is 46 | dynamically loaded from the LVM plugin when the library's ``bd_init`` function 47 | will be called. Initially all those functions are no-ops just printing a warning 48 | on stderr and doing nothing. This way applications using the library won't 49 | crash, the operations just won't be run. Of course, the library 50 | has ``bd_is_plugin_available``, which allows applications to check if something 51 | is provided/implemented or not. 52 | 53 | #### Technologies behind the library 54 | 55 | The library is written in C using the GLib library. The GLib library provides a 56 | lot of handy utilities that may be used by the library (no need for a new 57 | implementation of hash tables, lists, etc.) and moreover, it should be really 58 | easy to create bindings for the library via GObject introspection that works 59 | even with "not OOP" code. However, instead of returning links to structs 60 | (e.g. as a return value of the ``bd_lvm_vginfo`` function) it will return 61 | references to GObjects with attributes/properties and access methods. The reason 62 | is again an easy way to create bindings which we get for free. 63 | 64 | ### License 65 | 66 | The libblockdev code is licensed under LGPL 2.1 or later, see [LICENSE](LICENSE) 67 | for full text of the license. 68 | 69 | ### Development 70 | 71 | For developer documentation see [README.DEVEL.md](README.DEVEL.md). 72 | 73 | API documentation is available at [https://storaged.org/libblockdev](https://storaged.org/libblockdev). 74 | 75 | #### Branches and supported versions 76 | 77 | The currently actively developed and supported version is 3.x on the *main* branch. 78 | New features should target this release. 79 | 80 | The older 2.x version available on the *2.x-branch* is still supported but new features 81 | are not planned for this release. 82 | -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | dnl autoconf macros for libblockdev 2 | dnl 3 | dnl Copyright (C) 2014 Red Hat, Inc. 4 | dnl 5 | dnl This program is free software; you can redistribute it and/or modify 6 | dnl it under the terms of the GNU Lesser General Public License as published 7 | dnl by the Free Software Foundation; either version 2.1 of the License, or 8 | dnl (at your option) any later version. 9 | dnl 10 | dnl This program is distributed in the hope that it will be useful, 11 | dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | dnl GNU Lesser General Public License for more details. 14 | dnl 15 | dnl You should have received a copy of the GNU Lesser General Public License 16 | dnl along with this program. If not, see . 17 | dnl 18 | dnl THIS IS A MODIFIED VERSION OF THE ANACONDA'S acinclude.m4 FILE. 19 | dnl 20 | dnl Author: David Shea 21 | dnl Vratislav Podzimek 22 | 23 | dnl LIBBLOCKDEV_SOFT_FAILURE(MESSAGE) 24 | dnl 25 | dnl Store a message that in some contexts could be considered indicative 26 | dnl of a failure, but in other contexts could be indicative of who cares. 27 | dnl 28 | dnl Any message sent to this macro will be stored, and they can all be 29 | dnl displayed at the end of configure using the LIBBLOCKDEV_FAILURES macro. 30 | AC_DEFUN([LIBBLOCKDEV_SOFT_FAILURE], [dnl 31 | AS_IF([test x"$libblockdev_failure_messages" = x], 32 | [libblockdev_failure_messages="[$1]"], 33 | [libblockdev_failure_messages="$libblockdev_failure_messages 34 | [$1]" 35 | ])])dnl 36 | 37 | dnl LIBBLOCKDEV_PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES) 38 | dnl 39 | dnl Check whether a module is available, using pkg-config. Instead of failing 40 | dnl if a module is not found, store the failure in a message that can be 41 | dnl printed using the LIBBLOCKDEV_FAILURES macro. 42 | dnl 43 | dnl The syntax and behavior of VARIABLE-PREFIX and MODULES is the same as for 44 | dnl PKG_CHECK_MODULES. 45 | AC_DEFUN([LIBBLOCKDEV_PKG_CHECK_MODULES], [dnl 46 | PKG_CHECK_MODULES([$1], [$2], [], [LIBBLOCKDEV_SOFT_FAILURE($[$1]_PKG_ERRORS)]) 47 | ])dnl 48 | 49 | dnl LIBBLOCKDEV_PKG_CHECK_EXISTS(MODULES) 50 | dnl 51 | dnl Check whether a module exists, using pkg-config. Instead of failing 52 | dnl if a module is not found, store the failure in a message that can be 53 | dnl printed using the LIBBLOCKDEV_FAILURES macro. 54 | dnl 55 | dnl The syntax and behavior of MODULES is the same as for 56 | dnl PKG_CHECK_EXISTS. 57 | AC_DEFUN([LIBBLOCKDEV_PKG_CHECK_EXISTS], [dnl 58 | PKG_CHECK_EXISTS([$1], [], [LIBBLOCKDEV_SOFT_FAILURE([Check for $1 failed])]) 59 | ])dnl 60 | 61 | dnl LIBBLOCKDEV_CHECK_HEADER(HEADER, CFLAGS, ERR_MSG) 62 | dnl 63 | dnl Check if the given HEADER exists and is usable -- gcc can compile a source 64 | dnl file that just includes the HEADER using the given CFLAGS. In case of 65 | dnl failure, the ERR_MSG will be printed using the LIBBLOCKDEV_FAILURES macro. 66 | AC_DEFUN([LIBBLOCKDEV_CHECK_HEADER], [dnl 67 | echo -n "Checking header [$1] existence and usability..." 68 | temp_file=$(mktemp --tmpdir XXXXX.c) 69 | echo "#include <$1>" > $temp_file 70 | ${CC} -c [$2] $temp_file 71 | status=$? 72 | rm -f $temp_file 73 | rm -f $(basename ${temp_file%%.c}.o) 74 | if test $status = 0; then 75 | echo yes 76 | else 77 | echo no 78 | libblockdev_failure_messages="$libblockdev_failure_messages 79 | [$3]" 80 | fi 81 | ])dnl 82 | 83 | 84 | dnl LIBBLOCKDEV_PLUGIN(NAME, name) 85 | dnl 86 | dnl Define things needed in Makefile.am`s as well as sources for making 87 | dnl compilation and build modular. 88 | AC_DEFUN([LIBBLOCKDEV_PLUGIN], [dnl 89 | AC_ARG_WITH([$2], 90 | AS_HELP_STRING([--with-$2], [support $2 @<:@default=yes@:>@]), 91 | [], 92 | [with_$2=yes]) 93 | 94 | AC_SUBST([WITH_$1], [0]) 95 | AM_CONDITIONAL(WITH_$1, test "x$with_$2" != "xno") 96 | AS_IF([test "x$with_$2" != "xno"], 97 | [AC_DEFINE([WITH_BD_$1], [], [Define if $2 is supported]) AC_SUBST([WITH_$1], [1])], 98 | []) 99 | ])dnl 100 | 101 | 102 | dnl LIBBLOCKDEV_FAILURES 103 | dnl 104 | dnl Print the failure messages collected by LIBBLOCKDEV_SOFT_FAILURE, 105 | dnl LIBBLOCKDEV_PKG_CHECK_MODULES and LIBBLOCKDEV_CHECK_HEADER 106 | AC_DEFUN([LIBBLOCKDEV_FAILURES], [dnl 107 | AS_IF([test x"$libblockdev_failure_messages" = x], [], [dnl 108 | echo "" 109 | echo "*** Libblockdev encountered the following issues during configuration:" 110 | echo "$libblockdev_failure_messages" 111 | echo "" 112 | echo "*** Libblockdev will not successfully build without these missing dependencies" 113 | AS_EXIT(1) 114 | ])])dnl 115 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | test -n "$srcdir" || srcdir=`dirname "$0"` 3 | test -n "$srcdir" || srcdir=. 4 | 5 | pushd $srcdir 6 | 7 | (test -f configure.ac) || { 8 | echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***" 9 | exit 1 10 | } 11 | 12 | PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac` 13 | 14 | aclocal --install || exit 1 15 | autoreconf --verbose --force --install -Wno-portability || exit 1 16 | popd 17 | -------------------------------------------------------------------------------- /data/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = conf.d 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /data/conf.d/00-default.cfg: -------------------------------------------------------------------------------- 1 | # This is the default configuration for the libblockdev library. For 2 | # each supported technology/plugin there is a separate section/group 3 | # with the 'sonames' key. The value of the key has to be a list of 4 | # sonames of shared objects that should be attempted to be loaded for 5 | # the plugin falling back to the next one in the list. 6 | # 7 | # So this example: 8 | # [lvm] 9 | # sonames=libbd_lvm-dbus.so.0;libbd_lvm.so.0 10 | # 11 | # would result in the libbd_lvm-dbus.so.0 shared object attempted to 12 | # be loaded and if that failed, the libbd_lvm.so.0 would be attempted 13 | # to be loaded. 14 | 15 | [btrfs] 16 | sonames=libbd_btrfs.so.3 17 | 18 | [crypto] 19 | sonames=libbd_crypto.so.3 20 | 21 | [dm] 22 | sonames=libbd_dm.so.3 23 | 24 | [fs] 25 | sonames=libbd_fs.so.3 26 | 27 | [loop] 28 | sonames=libbd_loop.so.3 29 | 30 | [lvm] 31 | sonames=libbd_lvm.so.3 32 | 33 | [mdraid] 34 | sonames=libbd_mdraid.so.3 35 | 36 | [mpath] 37 | sonames=libbd_mpath.so.3 38 | 39 | [nvdimm] 40 | sonames=libbd_nvdimm.so.3 41 | 42 | [nvme] 43 | sonames=libbd_nvme.so.3 44 | 45 | [part] 46 | sonames=libbd_part.so.3 47 | 48 | [smart] 49 | sonames=libbd_smart.so.3;libbd_smartmontools.so.3 50 | 51 | [swap] 52 | sonames=libbd_swap.so.3 53 | 54 | [s390] 55 | sonames=libbd_s390.so.3 56 | -------------------------------------------------------------------------------- /data/conf.d/10-lvm-dbus.cfg: -------------------------------------------------------------------------------- 1 | [lvm] 2 | sonames=libbd_lvm-dbus.so.3 3 | -------------------------------------------------------------------------------- /data/conf.d/Makefile.am: -------------------------------------------------------------------------------- 1 | libbdconfdir = $(sysconfdir)/libblockdev/@MAJOR_VER@/conf.d 2 | dist_libbdconf_DATA = ${srcdir}/00-default.cfg 3 | 4 | if WITH_LVM_DBUS 5 | dist_libbdconf_DATA += ${srcdir}/10-lvm-dbus.cfg 6 | endif 7 | 8 | MAINTAINERCLEANFILES = Makefile.in 9 | -------------------------------------------------------------------------------- /dist/Makefile.am: -------------------------------------------------------------------------------- 1 | dist_noinst_DATA = libblockdev.spec 2 | 3 | MAINTAINERCLEANFILES = Makefile.in libblockdev.spec 4 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | all-local: html-doc.stamp 2 | 3 | html-doc.stamp: ${srcdir}/libblockdev-docs.xml ${srcdir}/libblockdev-sections.txt ${srcdir}/3.0-api-changes.xml $(wildcard ${srcdir}/../src/plugins/*.[ch]) $(wildcard ${srcdir}/../src/lib/*.[ch]) $(wildcard ${srcdir}/../src/utils/*.[ch]) 4 | touch ${builddir}/html-doc.stamp 5 | test "${builddir}" = "${srcdir}" || cp ${srcdir}/libblockdev-sections.txt ${srcdir}/libblockdev-docs.xml ${builddir} 6 | gtkdoc-scan --rebuild-types --module=libblockdev --source-dir=${srcdir}/../src/plugins/ --source-dir=${srcdir}/../src/lib/ --source-dir=${srcdir}/../src/utils/ --ignore-headers="${srcdir}/../src/plugins/check_deps.h ${srcdir}/../src/plugins/dm_logging.h ${srcdir}/../src/plugins/vdo_stats.h ${srcdir}/../src/plugins/fs/common.h" 7 | gtkdoc-mkdb --module=libblockdev --output-format=xml --source-dir=${srcdir}/../src/plugins/ --source-dir=${srcdir}/../src/lib/ --source-dir=${srcdir}/../src/utils/ --source-suffixes=c,h 8 | test -d ${builddir}/html || mkdir ${builddir}/html 9 | (cd ${builddir}/html; gtkdoc-mkhtml libblockdev ${builddir}/../libblockdev-docs.xml) 10 | gtkdoc-fixxref --module=libblockdev --module-dir=html --html-dir=/usr/share/gtk-doc/html 11 | 12 | clean-local: 13 | -rm -rf ${builddir}/html 14 | -rm -rf ${builddir}/xml 15 | test ! -f ${builddir}/html-doc.stamp || rm ${builddir}/html-doc.stamp 16 | test "${builddir}" = "${srcdir}" || rm -f ${builddir}/libblockdev-sections.txt ${builddir}/libblockdev-docs.xml ${builddir}/3.0-api-changes.xml 17 | 18 | install-data-local: 19 | test -d ${DESTDIR}${datadir}/gtk-doc/html/libblockdev || mkdir -p ${DESTDIR}${datadir}/gtk-doc/html/libblockdev 20 | install -m0644 ${builddir}/html/* ${DESTDIR}${datadir}/gtk-doc/html/libblockdev/ 21 | 22 | uninstall-local: 23 | -rm -rf ${DESTDIR}${datadir}/gtk-doc/html/libblockdev/ 24 | 25 | dist_noinst_DATA = ${srcdir}/libblockdev-sections.txt ${srcdir}/libblockdev-docs.xml ${srcdir}/3.0-api-changes.xml 26 | 27 | CLEANFILES = html.stamp sgml.stamp \ 28 | libblockdev-decl-list.txt \ 29 | libblockdev-decl.txt \ 30 | libblockdev-overrides.txt \ 31 | libblockdev-undeclared.txt \ 32 | libblockdev-undocumented.txt \ 33 | libblockdev-unused.txt \ 34 | libblockdev.types 35 | 36 | MAINTAINERCLEANFILES = Makefile.in libblockdev-docs.xml 37 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = blockdev 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /include/blockdev/Makefile.am: -------------------------------------------------------------------------------- 1 | all-local: 2 | for header in ${srcdir}/../../src/plugins/*.h; do ln -sf $${header} ./; done 3 | for header in ${srcdir}/../../src/plugins/lvm/lvm.h; do ln -sf $${header} ./; done 4 | for header in ${srcdir}/../../src/plugins/nvme/nvme.h; do ln -sf $${header} ./; done 5 | for header in ${srcdir}/../../src/plugins/smart/smart.h; do ln -sf $${header} ./; done 6 | for header in ${srcdir}/../../src/utils/*.h; do ln -sf $${header} ./; done 7 | for header in ${srcdir}/../../src/lib/*.h; do ln -sf $${header} ./; done 8 | mkdir -p fs; 9 | cd fs; for header in ${srcdir}/../../../src/plugins/fs/*.h; do ln -sf $${header} ./; done 10 | 11 | clean-local: 12 | rm -f *.h 13 | rm -rf fs 14 | 15 | MAINTAINERCLEANFILES = Makefile.in 16 | -------------------------------------------------------------------------------- /misc/PythonDocs.Dockerfile: -------------------------------------------------------------------------------- 1 | # image for building documentation for Python bindings, see README.DEVEL.md for more details 2 | 3 | FROM debian:testing 4 | LABEL maintainer Vojtech Trefny 5 | 6 | # add deb-src repo 7 | RUN echo "deb-src http://deb.debian.org/debian testing main" >> /etc/apt/sources.list 8 | 9 | RUN apt-get update 10 | 11 | # pgi-docgen dependencies 12 | RUN apt-get -y install python3 python3-pip python3-jinja2 python3-sphinx python3-bs4 python3-graphviz libgirepository-1.0-1 gir1.2-glib-2.0 13 | 14 | RUN apt-get -y install git 15 | 16 | # latest pgi from git 17 | RUN pip3 install "git+https://github.com/pygobject/pgi.git" --break-system-packages 18 | 19 | WORKDIR /root 20 | 21 | # install latest libblockdev 22 | RUN git clone https://github.com/storaged-project/libblockdev 23 | 24 | WORKDIR /root/libblockdev 25 | 26 | # install libblockdev build dependencies 27 | RUN apt-get -y install ansible 28 | RUN apt-get -y install libnvme-dev 29 | RUN ansible-playbook -K -i "localhost," -c local misc/install-test-dependencies.yml 30 | 31 | RUN ./autogen.sh && ./configure --prefix=/usr && make -j6 && DEB_PYTHON_INSTALL_LAYOUT="deb" make install 32 | 33 | WORKDIR /root 34 | 35 | # get latest pgi-docgen and generate documentation for libblockdev 36 | RUN git clone https://github.com/pygobject/pgi-docgen 37 | 38 | WORKDIR /root/pgi-docgen 39 | 40 | RUN ./tools/build.sh BlockDev-3.0 41 | -------------------------------------------------------------------------------- /misc/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # 5 | # A Vagrantfile template that can be used for creating machines for libblockdev 6 | # development/testing. 7 | # 8 | # Use 'vagrant up && vagrant ssh' to spawn the default machine (most recent 9 | # Fedora) and ssh into it or e.g. 'vagrant up bd-f29 && vagrant ssh bd-f29' to 10 | # use a Fedora 29 based machine, etc. 11 | # 12 | 13 | def os_cpu_cores 14 | case RbConfig::CONFIG['host_os'] 15 | when /darwin/ 16 | Integer(`sysctl -n hw.ncpu`) 17 | when /linux/ 18 | Integer(`getconf _NPROCESSORS_ONLN`) 19 | else 20 | raise StandardError, "Unsupported platform" 21 | end 22 | end 23 | 24 | Vagrant.configure("2") do |config| 25 | # common configuration 26 | 27 | config.vm.synced_folder "../", "/home/vagrant/libblockdev/", 28 | type: "rsync", rsync__args: ["-a", "-l", "--exclude=misc"] # override the default args 29 | 30 | # CHECK THAT THE BELOW OPTIONS ARE OKAY FOR YOUR HW 31 | config.vm.provider :libvirt do |v| 32 | v.memory = "2048" 33 | v.cpus = os_cpu_cores 34 | v.disk_driver :cache => "unsafe" 35 | end 36 | 37 | # just some handy stuff to have in shell OOTB 38 | config.vm.provision :shell, inline: <<-SHELL 39 | echo 'alias make="make -j -l4"' >> /home/vagrant/.bashrc 40 | echo 'cd libblockdev' >> /home/vagrant/.bash_history 41 | echo './autogen.sh && ./configure' >> /home/vagrant/.bash_history 42 | SHELL 43 | 44 | # install all test dependencies using ansible 45 | config.vm.provision "ansible" do |ansible| 46 | ansible.playbook = "install-test-dependencies.yml" 47 | ansible.extra_vars = { ansible_python_interpreter:"/usr/bin/python3" } 48 | end 49 | 50 | config.vm.define "bd-f40", primary: true, autostart: true do |f40| 51 | f40.vm.box = "fedora/40-cloud-base" 52 | end 53 | 54 | config.vm.define "bd-f39", primary: false, autostart: false do |f39| 55 | f39.vm.box = "fedora/39-cloud-base" 56 | end 57 | 58 | config.vm.define "bd-u2404", primary: false, autostart: false do |u2404| 59 | u2404.vm.box = "generic/ubuntu2404" 60 | end 61 | 62 | config.vm.define "bd-debiant", primary: false, autostart: false do |debiant| 63 | debiant.vm.box = "debian/testing64" 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /misc/ci.Dockerfile: -------------------------------------------------------------------------------- 1 | # latest fedora image for running some of our tests in GH actions 2 | 3 | FROM registry.fedoraproject.org/fedora:latest 4 | 5 | RUN set -e; \ 6 | dnf install -y ansible python3-pip rpm-build mock csmock git dnf-plugins-core; \ 7 | pip3 install copr-builder; \ 8 | git clone --depth 1 https://github.com/storaged-project/ci.git; \ 9 | git clone --depth 1 https://github.com/storaged-project/udisks.git; \ 10 | git clone --depth 1 https://github.com/storaged-project/blivet.git; 11 | 12 | WORKDIR / 13 | -------------------------------------------------------------------------------- /misc/install-test-dependencies.yml: -------------------------------------------------------------------------------- 1 | # This is a simple ansible playbook for installing packages needed by the 2 | # libblockdev test suite. 3 | # You can do this by using 'make install-requires' or manually using 4 | # 'ansible-playbook -K -i "localhost," -c local install-test-dependencies.yml' 5 | # Currently only Fedora, CentOS and Debian/Ubuntu are supported by this playbook. 6 | 7 | --- 8 | - hosts: all 9 | become: true 10 | vars: 11 | test_dependencies: true # whether to install test dependencies or not 12 | 13 | tasks: 14 | - name: Include tasks from libblockdev-tasks.yml 15 | ansible.builtin.include_tasks: libblockdev-tasks.yml 16 | -------------------------------------------------------------------------------- /plans/blivet.fmf: -------------------------------------------------------------------------------- 1 | # reverse dependency test for blivet 2 | enabled: false 3 | 4 | adjust+: 5 | when: revdeps_blivet == yes 6 | enabled: true 7 | 8 | prepare: 9 | - name: copr 10 | how: shell 11 | script: 12 | - sudo dnf install -y python3-libdnf5 'dnf-command(copr)' 13 | - sudo dnf copr enable -y @storage/udisks-daily 14 | # TF prioritizes Fedora tag repo over all others, in particular our daily COPR 15 | - for f in $(grep -l -r 'testing-farm-tag-repository' /etc/yum.repos.d); do sed -i '/priority/d' "$f" ;done 16 | - sudo dnf -y update 17 | 18 | - name: ansible 19 | how: shell 20 | script: 21 | - sudo dnf install -y curl ansible 22 | - curl -Ok https://raw.githubusercontent.com/storaged-project/blivet/main/misc/install-test-dependencies.yml 23 | - curl -Ok https://raw.githubusercontent.com/storaged-project/blivet/main/misc/blivet-tasks.yml 24 | - ansible-playbook -K -i "localhost," -c local install-test-dependencies.yml 25 | 26 | discover: 27 | how: shell 28 | url: https://github.com/storaged-project/blivet 29 | ref: main 30 | tests: 31 | - name: all 32 | test: make test 33 | 34 | execute: 35 | how: tmt 36 | -------------------------------------------------------------------------------- /plans/tests.fmf: -------------------------------------------------------------------------------- 1 | summary: Run tests 2 | 3 | adjust+: 4 | when: revdeps_blivet == yes or revdeps_udisks == yes 5 | enabled: false 6 | 7 | prepare: 8 | - name: copr 9 | how: shell 10 | script: 11 | - sudo dnf install -y python3-libdnf5 'dnf-command(copr)' 12 | - sudo dnf copr enable -y @storage/udisks-daily 13 | # TF prioritizes Fedora tag repo over all others, in particular our daily COPR 14 | - for f in $(grep -l -r 'testing-farm-tag-repository' /etc/yum.repos.d); do sed -i '/priority/d' "$f" ;done 15 | - sudo dnf -y update 16 | 17 | - name: ansible 18 | how: ansible 19 | playbook: misc/install-test-dependencies.yml 20 | 21 | execute: 22 | how: tmt 23 | script: ./autogen.sh && ./configure && make -j && sudo make ci 24 | -------------------------------------------------------------------------------- /plans/udisks.fmf: -------------------------------------------------------------------------------- 1 | # reverse dependency test for udisks 2 | enabled: false 3 | 4 | adjust+: 5 | when: revdeps_udisks == yes 6 | enabled: true 7 | 8 | prepare: 9 | - name: copr 10 | how: shell 11 | script: 12 | - sudo dnf install -y python3-libdnf5 'dnf-command(copr)' 13 | - sudo dnf copr enable -y @storage/udisks-daily 14 | # TF prioritizes Fedora tag repo over all others, in particular our daily COPR 15 | - for f in $(grep -l -r 'testing-farm-tag-repository' /etc/yum.repos.d); do sed -i '/priority/d' "$f" ;done 16 | - sudo dnf -y update 17 | # amazon-ec2-utils creates sda -> nvme symlinks breaking our tests 18 | # amazon-ec2-utils also ships /etc/udev/rules.d/60-cdrom_id.rules that breaks scsi_debug cdrom capabilities 19 | - if rpm -q amazon-ec2-utils; then rpm -e --verbose amazon-ec2-utils && udevadm trigger; fi 20 | 21 | - name: ansible 22 | how: shell 23 | script: 24 | - sudo dnf install -y curl ansible 25 | - curl -Ok https://raw.githubusercontent.com/storaged-project/udisks/master/misc/install-test-dependencies.yml 26 | - curl -Ok https://raw.githubusercontent.com/storaged-project/udisks/master/misc/udisks-tasks.yml 27 | - ansible-playbook -K -i "localhost," -c local install-test-dependencies.yml 28 | 29 | discover: 30 | how: shell 31 | url: https://github.com/storaged-project/udisks 32 | ref: master 33 | tests: 34 | - name: all 35 | test: ./autogen.sh --enable-modules && make -j && sudo make dbus-tests 36 | 37 | execute: 38 | how: tmt 39 | -------------------------------------------------------------------------------- /scripts/Makefile.am: -------------------------------------------------------------------------------- 1 | dist_noinst_SCRIPTS = boilerplate_generator.py 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = utils plugins lib python 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /src/lib/Makefile.am: -------------------------------------------------------------------------------- 1 | -include $(INTROSPECTION_MAKEFILE) 2 | 3 | SUBDIRS = plugin_apis 4 | 5 | lib_LTLIBRARIES = libblockdev.la 6 | libblockdev_la_CFLAGS = $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) 7 | libblockdev_la_LIBADD = ${builddir}/../utils/libbd_utils.la $(GLIB_LIBS) $(GOBJECT_LIBS) -ldl 8 | 9 | if WITH_BTRFS 10 | libblockdev_la_CFLAGS += $(GOBJECT_CFLAGS) 11 | libblockdev_la_LIBADD += $(GOBJECT_LIBS) 12 | endif 13 | if WITH_LVM 14 | libblockdev_la_CFLAGS += $(GOBJECT_CFLAGS) 15 | libblockdev_la_LIBADD += $(GOBJECT_LIBS) 16 | endif 17 | 18 | libblockdev_la_LDFLAGS = -L${srcdir}/../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 19 | libblockdev_la_CPPFLAGS = -I${builddir}/../../include/ 20 | libblockdev_la_SOURCES = blockdev.c blockdev.h plugins.c plugins.h 21 | 22 | if HAVE_INTROSPECTION 23 | GIHEADERS = ${builddir}/plugin_apis/mdraid.h \ 24 | ${builddir}/plugin_apis/swap.h \ 25 | ${builddir}/plugin_apis/btrfs.h \ 26 | ${builddir}/plugin_apis/lvm.h \ 27 | ${builddir}/plugin_apis/crypto.h \ 28 | ${builddir}/plugin_apis/dm.h \ 29 | ${builddir}/plugin_apis/loop.h \ 30 | ${builddir}/plugin_apis/mpath.h \ 31 | ${builddir}/plugin_apis/part.h \ 32 | ${builddir}/plugin_apis/fs.h \ 33 | ${builddir}/plugin_apis/nvdimm.h \ 34 | ${builddir}/plugin_apis/nvme.h \ 35 | ${builddir}/plugin_apis/smart.h 36 | 37 | GIHEADERS += $(wildcard ${srcdir}/../utils/*.[ch]) 38 | GIHEADERS += blockdev.c blockdev.h plugins.c plugins.h 39 | 40 | if WITH_S390 41 | GIHEADERS += ${builddir}/plugin_apis/s390.h 42 | endif 43 | 44 | BlockDev-3.0.gir: libblockdev.la 45 | 46 | BlockDev_3_0_gir_FILES = $(GIHEADERS) 47 | BlockDev_3_0_gir_LIBS = libblockdev.la 48 | BlockDev_3_0_gir_INCLUDES = GObject-2.0 Gio-2.0 49 | BlockDev_3_0_gir_CFLAGS = -I${builddir}/../../include/ 50 | BlockDev_3_0_gir_LDFLAGS = -L${builddir}/../utils/ -lbd_utils 51 | BlockDev_3_0_gir_SCANNERFLAGS = --warn-error --warn-all --identifier-prefix=BD --symbol-prefix=bd 52 | BlockDev_3_0_gir_EXPORT_PACKAGES = blockdev 53 | 54 | INTROSPECTION_GIRS = BlockDev-3.0.gir 55 | 56 | typelibdir = $(libdir)/girepository-1.0 57 | typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) 58 | 59 | girdir = $(datadir)/gir-1.0 60 | gir_DATA = $(INTROSPECTION_GIRS) 61 | 62 | CLEANFILES = BlockDev-3.0.gir $(typelib_DATA) 63 | endif 64 | 65 | pkgconfigdir = $(libdir)/pkgconfig 66 | pkgconfig_DATA = ${builddir}/blockdev.pc 67 | 68 | libincludedir = $(includedir)/blockdev 69 | libinclude_HEADERS = blockdev.h plugins.h 70 | 71 | MAINTAINERCLEANFILES = Makefile.in blockdev.pc blockdev.c 72 | -------------------------------------------------------------------------------- /src/lib/blockdev.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_LIB 5 | #define BD_LIB 6 | 7 | #include "plugins.h" 8 | 9 | /** 10 | * bd_init_error_quark: (skip) 11 | */ 12 | GQuark bd_init_error_quark (void); 13 | #define BD_INIT_ERROR bd_init_error_quark () 14 | typedef enum { 15 | BD_INIT_ERROR_FAILED, 16 | BD_INIT_ERROR_PLUGINS_FAILED, 17 | BD_INIT_ERROR_NOT_IMPLEMENTED, 18 | } BDInitError; 19 | 20 | gboolean bd_init (BDPluginSpec **require_plugins, BDUtilsLogFunc log_func, GError **error); 21 | gboolean bd_ensure_init (BDPluginSpec **require_plugins, BDUtilsLogFunc log_func, GError **error); 22 | gboolean bd_reinit (BDPluginSpec **require_plugins, gboolean reload, BDUtilsLogFunc log_func, GError **error); 23 | gboolean bd_try_init(BDPluginSpec **request_plugins, BDUtilsLogFunc log_func, 24 | gchar ***loaded_plugin_names, GError **error); 25 | gboolean bd_try_reinit (BDPluginSpec **require_plugins, gboolean reload, BDUtilsLogFunc log_func, 26 | gchar ***loaded_plugin_names, GError **error); 27 | gboolean bd_is_initialized (void); 28 | 29 | #endif /* BD_LIB */ 30 | -------------------------------------------------------------------------------- /src/lib/blockdev.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | includedir=@includedir@ 4 | libdir=@libdir@ 5 | 6 | Name: BlockDev 7 | Description: Library for doing low-level operations with block devices 8 | URL: https://github.com/storaged-project/libblockdev 9 | Version: @VERSION@ 10 | Requires: glib-2.0 11 | Libs: -L${libdir} -lblockdev 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /src/lib/plugin_apis/Makefile.am: -------------------------------------------------------------------------------- 1 | API_FILES := $(wildcard ${srcdir}/*.api) 2 | SOURCE_FILES := $(patsubst %.api,%.c,${API_FILES}) 3 | HEADER_FILES := $(patsubst %.api,%.h,${API_FILES}) 4 | 5 | all-local: generate_boilerplate 6 | 7 | %.c %.h: %.api ${srcdir}/../../../scripts/boilerplate_generator.py 8 | ${PYTHON} ${srcdir}/../../../scripts/boilerplate_generator.py $*.api ./ 9 | 10 | generate_boilerplate: ${SOURCE_FILES} ${HEADER_FILES} 11 | 12 | dist_noinst_HEADERS = ${API_FILES} ${SOURCE_FILES} ${HEADER_FILES} 13 | 14 | CLEANFILES = ${SOURCE_FILES} ${HEADER_FILES} 15 | 16 | MAINTAINERCLEANFILES = Makefile.in 17 | 18 | .PHONY: generate_boilerplate 19 | -------------------------------------------------------------------------------- /src/lib/plugin_apis/dm.api: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_DM_API 5 | #define BD_DM_API 6 | 7 | GQuark bd_dm_error_quark (void) { 8 | return g_quark_from_static_string ("g-bd-dm-error-quark"); 9 | } 10 | 11 | #define BD_DM_ERROR bd_dm_error_quark () 12 | typedef enum { 13 | BD_DM_ERROR_TECH_UNAVAIL, 14 | BD_DM_ERROR_SYS, 15 | BD_DM_ERROR_NOT_ROOT, 16 | BD_DM_ERROR_TASK, 17 | BD_DM_ERROR_RAID_FAIL, 18 | BD_DM_ERROR_RAID_NO_DEVS, 19 | BD_DM_ERROR_RAID_NO_EXIST, 20 | } BDDMError; 21 | 22 | typedef enum { 23 | BD_DM_TECH_MAP = 0, 24 | } BDDMTech; 25 | 26 | typedef enum { 27 | BD_DM_TECH_MODE_CREATE_ACTIVATE = 1 << 0, 28 | BD_DM_TECH_MODE_REMOVE_DEACTIVATE = 1 << 1, 29 | BD_DM_TECH_MODE_QUERY = 1 << 2, 30 | } BDDMTechMode; 31 | 32 | /** 33 | * bd_dm_is_tech_avail: 34 | * @tech: the queried tech 35 | * @mode: a bit mask of queried modes of operation (#BDDMTechMode) for @tech 36 | * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available) 37 | * 38 | * Returns: whether the @tech-@mode combination is available -- supported by the 39 | * plugin implementation and having all the runtime dependencies available 40 | */ 41 | gboolean bd_dm_is_tech_avail (BDDMTech tech, guint64 mode, GError **error); 42 | 43 | /** 44 | * bd_dm_create_linear: 45 | * @map_name: name of the map 46 | * @device: device to create map for 47 | * @length: length of the mapping in sectors 48 | * @uuid: (nullable): UUID for the new dev mapper device or %NULL if not specified 49 | * @error: (out) (optional): place to store error (if any) 50 | * 51 | * Returns: whether the new linear mapping @map_name was successfully created 52 | * for the @device or not 53 | * 54 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_CREATE_ACTIVATE 55 | */ 56 | gboolean bd_dm_create_linear (const gchar *map_name, const gchar *device, guint64 length, const gchar *uuid, GError **error); 57 | 58 | /** 59 | * bd_dm_remove: 60 | * @map_name: name of the map to remove 61 | * @error: (out) (optional): place to store error (if any) 62 | * 63 | * Returns: whether the @map_name map was successfully removed or not 64 | * 65 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_REMOVE_DEACTIVATE 66 | */ 67 | gboolean bd_dm_remove (const gchar *map_name, GError **error); 68 | 69 | /** 70 | * bd_dm_name_from_node: 71 | * @dm_node: name of the DM node (e.g. "dm-0") 72 | * @error: (out) (optional): place to store error (if any) 73 | * 74 | * Returns: map name of the map providing the @dm_node device or %NULL 75 | * (@error) contains the error in such cases 76 | * 77 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY 78 | */ 79 | gchar* bd_dm_name_from_node (const gchar *dm_node, GError **error); 80 | 81 | /** 82 | * bd_dm_node_from_name: 83 | * @map_name: name of the queried DM map 84 | * @error: (out) (optional): place to store error (if any) 85 | * 86 | * Returns: DM node name for the @map_name map or %NULL (@error) contains 87 | * the error in such cases 88 | * 89 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY 90 | */ 91 | gchar* bd_dm_node_from_name (const gchar *map_name, GError **error); 92 | 93 | /** 94 | * bd_dm_get_subsystem_from_name: 95 | * @device_name: name of the device 96 | * @error: (out) (optional): place to store error (if any) 97 | * 98 | * Returns: subsystem of the given device 99 | * 100 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY 101 | */ 102 | gchar* bd_dm_get_subsystem_from_name (const gchar *device_name, GError **error); 103 | 104 | /** 105 | * bd_dm_map_exists: 106 | * @map_name: name of the queried map 107 | * @live_only: whether to go through the live maps only or not 108 | * @active_only: whether to ignore suspended maps or not 109 | * @error: (out) (optional): place to store error (if any) 110 | * 111 | * Returns: whether the given @map_name exists (and is live if @live_only is 112 | * %TRUE (and is active if @active_only is %TRUE)). 113 | * 114 | * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY 115 | */ 116 | gboolean bd_dm_map_exists (const gchar *map_name, gboolean live_only, gboolean active_only, GError **error); 117 | 118 | #endif /* BD_DM_API */ 119 | -------------------------------------------------------------------------------- /src/lib/plugin_apis/mpath.api: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_MPATH_API 5 | #define BD_MPATH_API 6 | 7 | GQuark bd_mpath_error_quark (void) { 8 | return g_quark_from_static_string ("g-bd-mpath-error-quark"); 9 | } 10 | 11 | #define BD_MPATH_ERROR bd_mpath_error_quark () 12 | typedef enum { 13 | BD_MPATH_ERROR_TECH_UNAVAIL, 14 | BD_MPATH_ERROR_INVAL, 15 | BD_MPATH_ERROR_FLUSH, 16 | BD_MPATH_ERROR_NOT_ROOT, 17 | BD_MPATH_ERROR_DM_ERROR, 18 | } BDMpathError; 19 | 20 | typedef enum { 21 | BD_MPATH_TECH_BASE = 0, 22 | BD_MPATH_TECH_FRIENDLY_NAMES, 23 | } BDMpathTech; 24 | 25 | typedef enum { 26 | BD_MPATH_TECH_MODE_QUERY = 1 << 0, 27 | BD_MPATH_TECH_MODE_MODIFY = 1 << 1, 28 | } BDMpathTechMode; 29 | 30 | /** 31 | * bd_mpath_is_tech_avail: 32 | * @tech: the queried tech 33 | * @mode: a bit mask of queried modes of operation for @tech 34 | * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available) 35 | * 36 | * Returns: whether the @tech-@mode combination is available -- supported by the 37 | * plugin implementation and having all the runtime dependencies available 38 | */ 39 | gboolean bd_mpath_is_tech_avail (BDMpathTech tech, guint64 mode, GError **error); 40 | 41 | /** 42 | * bd_mpath_flush_mpaths: 43 | * @error: (out) (optional): place to store error (if any) 44 | * 45 | * Returns: whether multipath device maps were successfully flushed or not 46 | * 47 | * Flushes all unused multipath device maps. 48 | * 49 | * Tech category: %BD_MPATH_TECH_BASE-%BD_MPATH_TECH_MODE_MODIFY 50 | */ 51 | gboolean bd_mpath_flush_mpaths (GError **error); 52 | 53 | /** 54 | * bd_mpath_is_mpath_member: 55 | * @device: device to test 56 | * @error: (out) (optional): place to store error (if any) 57 | * 58 | * Returns: %TRUE if the device is a multipath member, %FALSE if not or an error 59 | * appeared when queried (@error is set in those cases) 60 | * 61 | * Tech category: %BD_MPATH_TECH_BASE-%BD_MPATH_TECH_MODE_QUERY 62 | */ 63 | gboolean bd_mpath_is_mpath_member (const gchar *device, GError **error); 64 | 65 | /** 66 | * bd_mpath_get_mpath_members: 67 | * @error: (out) (optional): place to store error (if any) 68 | * 69 | * Returns: (transfer full) (array zero-terminated=1): list of names of all devices that are 70 | * members of the mpath mappings (or %NULL 71 | * in case of error) 72 | * 73 | * Tech category: %BD_MPATH_TECH_BASE-%BD_MPATH_TECH_MODE_QUERY 74 | */ 75 | gchar** bd_mpath_get_mpath_members (GError **error); 76 | 77 | /** 78 | * bd_mpath_set_friendly_names: 79 | * @enabled: whether friendly names should be enabled or not 80 | * @error: (out) (optional): place to store error (if any) 81 | * 82 | * Returns: if successfully set or not 83 | * 84 | * Tech category: %BD_MPATH_TECH_FRIENDLY_NAMES-%BD_MPATH_TECH_MODE_MODIFY 85 | */ 86 | gboolean bd_mpath_set_friendly_names (gboolean enabled, GError **error); 87 | 88 | #endif /* BD_MPATH_API */ 89 | -------------------------------------------------------------------------------- /src/lib/plugins.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "plugins.h" 4 | 5 | /** 6 | * SECTION: plugins 7 | * @short_description: functions related to querying plugins 8 | * @title: Plugins 9 | * @include: blockdev.h 10 | */ 11 | 12 | /** 13 | * bd_plugin_spec_copy: (skip) 14 | * @spec: (nullable): %BDPluginSpec to copy 15 | * 16 | * Creates a new copy of @spec. 17 | */ 18 | BDPluginSpec* bd_plugin_spec_copy (BDPluginSpec *spec) { 19 | if (!spec) 20 | return NULL; 21 | 22 | BDPluginSpec *new_spec = g_new0 (BDPluginSpec, 1); 23 | 24 | new_spec->name = spec->name; 25 | new_spec->so_name = g_strdup (spec->so_name); 26 | 27 | return new_spec; 28 | } 29 | 30 | /** 31 | * bd_plugin_spec_free: (skip) 32 | * @spec: (nullable): %BDPluginSpec to free 33 | * 34 | * Frees @spec. 35 | */ 36 | void bd_plugin_spec_free (BDPluginSpec *spec) { 37 | if (!spec) 38 | return; 39 | g_free ((gchar *) spec->so_name); 40 | g_free (spec); 41 | } 42 | 43 | /** 44 | * bd_plugin_spec_new: (constructor) 45 | * @name: %BDPlugin name, e.g. %BD_PLUGIN_LVM 46 | * @so_name: (nullable): SO name of the plugin to load or %NULL for default 47 | * 48 | * Returns: (transfer full): a new plugin spec 49 | */ 50 | BDPluginSpec* bd_plugin_spec_new (BDPlugin name, const gchar *so_name) { 51 | BDPluginSpec* ret = g_new0 (BDPluginSpec, 1); 52 | ret->name = name; 53 | /* FIXME: this should be const, but we are already allocating a new string in _copy 54 | * and freeing it in _free 55 | */ 56 | ret->so_name = so_name ? g_strdup (so_name) : NULL; 57 | 58 | return ret; 59 | } 60 | 61 | GType bd_plugin_spec_get_type (void) { 62 | static GType type = 0; 63 | 64 | if (G_UNLIKELY(type == 0)) { 65 | type = g_boxed_type_register_static("BDPluginSpec", 66 | (GBoxedCopyFunc) bd_plugin_spec_copy, 67 | (GBoxedFreeFunc) bd_plugin_spec_free); 68 | } 69 | 70 | return type; 71 | } 72 | -------------------------------------------------------------------------------- /src/lib/plugins.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_PLUGINS 5 | #define BD_PLUGINS 6 | 7 | typedef enum { 8 | BD_PLUGIN_LVM = 0, 9 | BD_PLUGIN_BTRFS, 10 | BD_PLUGIN_SWAP, 11 | BD_PLUGIN_LOOP, 12 | BD_PLUGIN_CRYPTO, 13 | BD_PLUGIN_MPATH, 14 | BD_PLUGIN_DM, 15 | BD_PLUGIN_MDRAID, 16 | BD_PLUGIN_S390, 17 | BD_PLUGIN_PART, 18 | BD_PLUGIN_FS, 19 | BD_PLUGIN_NVDIMM, 20 | BD_PLUGIN_NVME, 21 | BD_PLUGIN_SMART, 22 | BD_PLUGIN_UNDEF 23 | } BDPlugin; 24 | 25 | #define BD_TYPE_PLUGIN_SPEC (bd_plugin_spec_get_type ()) 26 | GType bd_plugin_spec_get_type(void); 27 | 28 | /** 29 | * BDPluginSpec: 30 | * @name: %BDPlugin name, e.g. %BD_PLUGIN_LVM 31 | * @so_name: (nullable): SO name of the plugin to load or %NULL for default 32 | * 33 | */ 34 | typedef struct BDPluginSpec { 35 | BDPlugin name; 36 | const gchar *so_name; 37 | } BDPluginSpec; 38 | 39 | BDPluginSpec* bd_plugin_spec_copy (BDPluginSpec *spec); 40 | void bd_plugin_spec_free (BDPluginSpec *spec); 41 | BDPluginSpec* bd_plugin_spec_new (BDPlugin name, const gchar *so_name); 42 | 43 | gboolean bd_is_plugin_available (BDPlugin plugin); 44 | gchar** bd_get_available_plugin_names (void); 45 | gchar* bd_get_plugin_soname (BDPlugin plugin); 46 | gchar* bd_get_plugin_name (BDPlugin plugin); 47 | 48 | #endif /* BD_PLUGINS */ 49 | -------------------------------------------------------------------------------- /src/plugins/btrfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef BD_BTRFS 6 | #define BD_BTRFS 7 | 8 | #define BD_BTRFS_MAIN_VOLUME_ID 5 9 | #define BD_BTRFS_MIN_MEMBER_SIZE (128 MiB) 10 | 11 | GQuark bd_btrfs_error_quark (void); 12 | #define BD_BTRFS_ERROR bd_btrfs_error_quark () 13 | typedef enum { 14 | BD_BTRFS_ERROR_TECH_UNAVAIL, 15 | BD_BTRFS_ERROR_DEVICE, 16 | BD_BTRFS_ERROR_PARSE, 17 | } BDBtrfsError; 18 | 19 | typedef struct BDBtrfsDeviceInfo { 20 | guint64 id; 21 | gchar *path; 22 | guint64 size; 23 | guint64 used; 24 | } BDBtrfsDeviceInfo; 25 | 26 | void bd_btrfs_device_info_free (BDBtrfsDeviceInfo *info); 27 | BDBtrfsDeviceInfo* bd_btrfs_device_info_copy (BDBtrfsDeviceInfo *info); 28 | 29 | typedef struct BDBtrfsSubvolumeInfo { 30 | guint64 id; 31 | guint64 parent_id; 32 | gchar *path; 33 | } BDBtrfsSubvolumeInfo; 34 | 35 | void bd_btrfs_subvolume_info_free (BDBtrfsSubvolumeInfo *info); 36 | BDBtrfsSubvolumeInfo* bd_btrfs_subvolume_info_copy (BDBtrfsSubvolumeInfo *info); 37 | 38 | typedef struct BDBtrfsFilesystemInfo { 39 | gchar *label; 40 | gchar *uuid; 41 | guint64 num_devices; 42 | guint64 used; 43 | } BDBtrfsFilesystemInfo; 44 | 45 | void bd_btrfs_filesystem_info_free (BDBtrfsFilesystemInfo *info); 46 | BDBtrfsFilesystemInfo* bd_btrfs_filesystem_info_copy (BDBtrfsFilesystemInfo *info); 47 | 48 | 49 | typedef enum { 50 | BD_BTRFS_TECH_FS = 0, 51 | BD_BTRFS_TECH_MULTI_DEV, 52 | BD_BTRFS_TECH_SUBVOL, 53 | BD_BTRFS_TECH_SNAPSHOT, 54 | } BDBtrfsTech; 55 | 56 | typedef enum { 57 | BD_BTRFS_TECH_MODE_CREATE = 1 << 0, 58 | BD_BTRFS_TECH_MODE_DELETE = 1 << 1, 59 | BD_BTRFS_TECH_MODE_MODIFY = 1 << 2, 60 | BD_BTRFS_TECH_MODE_QUERY = 1 << 3, 61 | } BDBtrfsTechMode; 62 | 63 | /* 64 | * If using the plugin as a standalone library, the following functions should 65 | * be called to: 66 | * 67 | * init() - initialize the plugin, returning TRUE on success 68 | * close() - clean after the plugin at the end or if no longer used 69 | * 70 | */ 71 | gboolean bd_btrfs_init (void); 72 | void bd_btrfs_close (void); 73 | 74 | gboolean bd_btrfs_is_tech_avail (BDBtrfsTech tech, guint64 mode, GError **error); 75 | 76 | gboolean bd_btrfs_create_volume (const gchar **devices, const gchar *label, const gchar *data_level, const gchar *md_level, const BDExtraArg **extra, GError **error); 77 | gboolean bd_btrfs_add_device (const gchar *mountpoint, const gchar *device, const BDExtraArg **extra, GError **error); 78 | gboolean bd_btrfs_remove_device (const gchar *mountpoint, const gchar *device, const BDExtraArg **extra, GError **error); 79 | gboolean bd_btrfs_create_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error); 80 | gboolean bd_btrfs_delete_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error); 81 | guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **error); 82 | gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, const BDExtraArg **extra, GError **error); 83 | gboolean bd_btrfs_create_snapshot (const gchar *source, const gchar *dest, gboolean ro, const BDExtraArg **extra, GError **error); 84 | BDBtrfsDeviceInfo** bd_btrfs_list_devices (const gchar *device, GError **error); 85 | BDBtrfsSubvolumeInfo** bd_btrfs_list_subvolumes (const gchar *mountpoint, gboolean snapshots_only, GError **error); 86 | BDBtrfsFilesystemInfo* bd_btrfs_filesystem_info (const gchar *device, GError **error); 87 | 88 | gboolean bd_btrfs_mkfs (const gchar **devices, const gchar *label, const gchar *data_level, const gchar *md_level, const BDExtraArg **extra, GError **error); 89 | gboolean bd_btrfs_resize (const gchar *mountpoint, guint64 size, const BDExtraArg **extra, GError **error); 90 | gboolean bd_btrfs_check (const gchar *device, const BDExtraArg **extra, GError **error); 91 | gboolean bd_btrfs_repair (const gchar *device, const BDExtraArg **extra, GError **error); 92 | gboolean bd_btrfs_change_label (const gchar *mountpoint, const gchar *label, GError **error); 93 | 94 | #endif /* BD_BTRFS */ 95 | -------------------------------------------------------------------------------- /src/plugins/check_deps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vratislav Podzimek 18 | */ 19 | 20 | #include 21 | 22 | #ifndef BD_CHECK_DEPS 23 | #define BD_CHECK_DEPS 24 | 25 | typedef struct UtilDep { 26 | const gchar *name; 27 | const gchar *version; 28 | const gchar *ver_arg; 29 | const gchar *ver_regexp; 30 | } UtilDep; 31 | 32 | typedef struct DBusDep { 33 | const gchar *bus_name; 34 | const gchar *obj_prefix; 35 | GBusType bus_type; 36 | const gchar *version; 37 | const gchar *ver_prop; 38 | const gchar *ver_intf; 39 | const gchar *ver_path; 40 | } DBusDep; 41 | 42 | typedef struct UtilFeatureDep { 43 | const gchar *util_name; 44 | const gchar *feature; 45 | const gchar *feature_arg; 46 | const gchar *feature_regexp; 47 | } UtilFeatureDep; 48 | 49 | gboolean check_deps (volatile guint *avail_deps, guint req_deps, const UtilDep *deps_specs, guint l_deps, GMutex *deps_check_lock, GError **error); 50 | gboolean check_module_deps (volatile guint *avail_deps, guint req_deps, const gchar *const*modules, guint l_modules, GMutex *deps_check_lock, GError **error); 51 | gboolean check_dbus_deps (volatile guint *avail_deps, guint req_deps, const DBusDep *buses, guint l_buses, GMutex *deps_check_lock, GError **error); 52 | gboolean check_features (volatile guint *avail_deps, guint req_deps, const UtilFeatureDep *deps_specs, guint l_deps, GMutex *deps_check_lock, GError **error); 53 | 54 | #endif /* BD_CHECK_DEPS */ 55 | -------------------------------------------------------------------------------- /src/plugins/dm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_DM 4 | #define BD_DM 5 | 6 | GQuark bd_dm_error_quark (void); 7 | #define BD_DM_ERROR bd_dm_error_quark () 8 | typedef enum { 9 | BD_DM_ERROR_TECH_UNAVAIL, 10 | BD_DM_ERROR_SYS, 11 | BD_DM_ERROR_NOT_ROOT, 12 | BD_DM_ERROR_TASK, 13 | BD_DM_ERROR_RAID_FAIL, 14 | BD_DM_ERROR_RAID_NO_DEVS, 15 | BD_DM_ERROR_RAID_NO_EXIST, 16 | } BDDMError; 17 | 18 | typedef enum { 19 | BD_DM_TECH_MAP = 0, 20 | } BDDMTech; 21 | 22 | typedef enum { 23 | BD_DM_TECH_MODE_CREATE_ACTIVATE = 1 << 0, 24 | BD_DM_TECH_MODE_REMOVE_DEACTIVATE = 1 << 1, 25 | BD_DM_TECH_MODE_QUERY = 1 << 2, 26 | } BDDMTechMode; 27 | 28 | /* 29 | * If using the plugin as a standalone library, the following functions should 30 | * be called to: 31 | * 32 | * init() - initialize the plugin, returning TRUE on success 33 | * close() - clean after the plugin at the end or if no longer used 34 | * 35 | */ 36 | gboolean bd_dm_init (void); 37 | void bd_dm_close (void); 38 | 39 | gboolean bd_dm_is_tech_avail (BDDMTech tech, guint64 mode, GError **error); 40 | 41 | gboolean bd_dm_create_linear (const gchar *map_name, const gchar *device, guint64 length, const gchar *uuid, GError **error); 42 | gboolean bd_dm_remove (const gchar *map_name, GError **error); 43 | gboolean bd_dm_map_exists (const gchar *map_name, gboolean live_only, gboolean active_only, GError **error); 44 | gchar* bd_dm_name_from_node (const gchar *dm_node, GError **error); 45 | gchar* bd_dm_node_from_name (const gchar *map_name, GError **error); 46 | gchar* bd_dm_get_subsystem_from_name (const gchar *device_name, GError **error); 47 | 48 | #endif /* BD_DM */ 49 | -------------------------------------------------------------------------------- /src/plugins/dm_logging.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "dm_logging.h" 27 | 28 | G_GNUC_INTERNAL void 29 | redirect_dm_log (int level, const char *file G_GNUC_UNUSED, int line G_GNUC_UNUSED, 30 | int dm_errno_or_class G_GNUC_UNUSED, const char *f, ...) { 31 | gchar *dm_msg = NULL; 32 | gchar *message = NULL; 33 | gint ret = 0; 34 | va_list args; 35 | 36 | va_start (args, f); 37 | ret = g_vasprintf (&dm_msg, f, args); 38 | va_end (args); 39 | 40 | if (ret < 0) { 41 | g_free (dm_msg); 42 | return; 43 | } 44 | 45 | 46 | #ifdef DEBUG 47 | message = g_strdup_printf ("[libdevmapper] %s:%d %s", file, line, dm_msg); 48 | #else 49 | message = g_strdup_printf ("[libdevmapper] %s", dm_msg); 50 | #endif 51 | 52 | /* libdevmapper has some custom special log levels, these should be 53 | internal, but just to be sure mark everything weird as debug */ 54 | if (level > LOG_DEBUG) 55 | level = LOG_DEBUG; 56 | 57 | bd_utils_log (level, message); 58 | 59 | g_free (dm_msg); 60 | g_free (message); 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/plugins/dm_logging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | */ 19 | 20 | #include 21 | 22 | #ifndef BD_DM_LOGGING 23 | #define BD_DM_LOGGING 24 | 25 | void redirect_dm_log (int level, const char *file, int line, int dm_errno_or_class, const char *f, ...) G_GNUC_PRINTF (5, 6); 26 | 27 | #endif /* BD_DM_LOGGING */ 28 | -------------------------------------------------------------------------------- /src/plugins/fs.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_FS 4 | #define BD_FS 5 | 6 | GQuark bd_fs_error_quark (void); 7 | #define BD_FS_ERROR bd_fs_error_quark () 8 | typedef enum { 9 | BD_FS_ERROR_TECH_UNAVAIL, 10 | BD_FS_ERROR_INVAL, 11 | BD_FS_ERROR_PARSE, 12 | BD_FS_ERROR_FAIL, 13 | BD_FS_ERROR_NOFS, 14 | BD_FS_ERROR_PIPE, 15 | BD_FS_ERROR_UNMOUNT_FAIL, 16 | BD_FS_ERROR_NOT_SUPPORTED, 17 | BD_FS_ERROR_NOT_MOUNTED, 18 | BD_FS_ERROR_AUTH, 19 | BD_FS_ERROR_LABEL_INVALID, 20 | BD_FS_ERROR_UUID_INVALID, 21 | BD_FS_ERROR_UNKNOWN_FS, 22 | } BDFSError; 23 | 24 | /* XXX: where the file systems start at the enum of technologies */ 25 | #define BD_FS_OFFSET 2 26 | #define BD_FS_LAST_FS 13 27 | typedef enum { 28 | BD_FS_TECH_GENERIC = 0, 29 | BD_FS_TECH_MOUNT = 1, 30 | BD_FS_TECH_EXT2 = 2, 31 | BD_FS_TECH_EXT3 = 3, 32 | BD_FS_TECH_EXT4 = 4, 33 | BD_FS_TECH_XFS = 5, 34 | BD_FS_TECH_VFAT = 6, 35 | BD_FS_TECH_NTFS = 7, 36 | BD_FS_TECH_F2FS = 8, 37 | BD_FS_TECH_NILFS2 = 9, 38 | BD_FS_TECH_EXFAT = 10, 39 | BD_FS_TECH_BTRFS = 11, 40 | BD_FS_TECH_UDF = 12, 41 | } BDFSTech; 42 | 43 | /* XXX: number of the highest bit of all modes */ 44 | #define BD_FS_MODE_LAST 7 45 | typedef enum { 46 | BD_FS_TECH_MODE_MKFS = 1 << 0, 47 | BD_FS_TECH_MODE_WIPE = 1 << 1, 48 | BD_FS_TECH_MODE_CHECK = 1 << 2, 49 | BD_FS_TECH_MODE_REPAIR = 1 << 3, 50 | BD_FS_TECH_MODE_SET_LABEL = 1 << 4, 51 | BD_FS_TECH_MODE_QUERY = 1 << 5, 52 | BD_FS_TECH_MODE_RESIZE = 1 << 6, 53 | BD_FS_TECH_MODE_SET_UUID = 1 << 7, 54 | } BDFSTechMode; 55 | 56 | 57 | /* 58 | * If using the plugin as a standalone library, the following functions should 59 | * be called to: 60 | * 61 | * init() - initialize the plugin, returning TRUE on success 62 | * close() - clean after the plugin at the end or if no longer used 63 | * 64 | */ 65 | gboolean bd_fs_init (void); 66 | void bd_fs_close (void); 67 | 68 | gboolean bd_fs_is_tech_avail (BDFSTech tech, guint64 mode, GError **error); 69 | 70 | #endif /* BD_FS */ 71 | 72 | #include "fs/ext.h" 73 | #include "fs/f2fs.h" 74 | #include "fs/generic.h" 75 | #include "fs/mount.h" 76 | #include "fs/ntfs.h" 77 | #include "fs/vfat.h" 78 | #include "fs/xfs.h" 79 | #include "fs/nilfs.h" 80 | #include "fs/exfat.h" 81 | #include "fs/btrfs.h" 82 | #include "fs/udf.h" 83 | -------------------------------------------------------------------------------- /src/plugins/fs/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = subdir-objects 2 | 3 | lib_LTLIBRARIES = libbd_fs.la 4 | 5 | libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-error=unused-parameter -Wno-error=shift-count-overflow 6 | libbd_fs_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(BLKID_LIBS) $(MOUNT_LIBS) $(UUID_LIBS) $(EXT2FS_LIBS) 7 | libbd_fs_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 8 | libbd_fs_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ 9 | libbd_fs_la_SOURCES = ../check_deps.c ../check_deps.h \ 10 | ../fs.c ../fs.h \ 11 | common.c common.h \ 12 | ext.c ext.h \ 13 | generic.c generic.h \ 14 | mount.c mount.h \ 15 | ntfs.c ntfs.h \ 16 | vfat.c vfat.h \ 17 | xfs.c xfs.h \ 18 | f2fs.c f2fs.h \ 19 | nilfs.c nilfs.h \ 20 | exfat.c exfat.h \ 21 | btrfs.c btrfs.h \ 22 | udf.c udf.h 23 | 24 | libincludefsdir = $(includedir)/blockdev/fs/ 25 | libincludefs_HEADERS = ext.h \ 26 | generic.h \ 27 | mount.h \ 28 | ntfs.h \ 29 | vfat.h \ 30 | xfs.h \ 31 | f2fs.h \ 32 | nilfs.h \ 33 | exfat.h \ 34 | btrfs.h \ 35 | udf.h 36 | -------------------------------------------------------------------------------- /src/plugins/fs/btrfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_BTRFS 5 | #define BD_FS_BTRFS 6 | 7 | typedef struct BDFSBtrfsInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 size; 11 | guint64 free_space; 12 | } BDFSBtrfsInfo; 13 | 14 | BDFSBtrfsInfo* bd_fs_btrfs_info_copy (BDFSBtrfsInfo *data); 15 | void bd_fs_btrfs_info_free (BDFSBtrfsInfo *data); 16 | 17 | gboolean bd_fs_btrfs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 18 | gboolean bd_fs_btrfs_check (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_btrfs_repair (const gchar *device, const BDExtraArg **extra, GError **error); 20 | gboolean bd_fs_btrfs_set_label (const gchar *mpoint, const gchar *label, GError **error); 21 | gboolean bd_fs_btrfs_check_label (const gchar *label, GError **error); 22 | gboolean bd_fs_btrfs_set_uuid (const gchar *device, const gchar *uuid, GError **error); 23 | gboolean bd_fs_btrfs_check_uuid ( const gchar *uuid, GError **error); 24 | BDFSBtrfsInfo* bd_fs_btrfs_get_info (const gchar *mpoint, GError **error); 25 | gboolean bd_fs_btrfs_resize (const gchar *mpoint, guint64 new_size, const BDExtraArg **extra, GError **error); 26 | 27 | #endif /* BD_FS_BTRFS */ 28 | -------------------------------------------------------------------------------- /src/plugins/fs/common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vratislav Podzimek 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include "fs.h" 33 | #include "common.h" 34 | 35 | G_GNUC_INTERNAL gint 36 | synced_close (gint fd) { 37 | gint ret = 0; 38 | ret = fsync (fd); 39 | if (close (fd) != 0) 40 | ret = 1; 41 | return ret; 42 | } 43 | 44 | 45 | G_GNUC_INTERNAL gboolean 46 | get_uuid_label (const gchar *device, gchar **uuid, gchar **label, GError **error) { 47 | blkid_probe probe = NULL; 48 | gint fd = 0; 49 | gint status = 0; 50 | const gchar *value = NULL; 51 | 52 | probe = blkid_new_probe (); 53 | if (!probe) { 54 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 55 | "Failed to create a probe for the device '%s'", device); 56 | return FALSE; 57 | } 58 | 59 | fd = open (device, O_RDONLY|O_CLOEXEC); 60 | if (fd == -1) { 61 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 62 | "Failed to create a probe for the device '%s': %s", 63 | device, strerror_l (errno, _C_LOCALE)); 64 | blkid_free_probe (probe); 65 | return FALSE; 66 | } 67 | 68 | status = blkid_probe_set_device (probe, fd, 0, 0); 69 | if (status != 0) { 70 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 71 | "Failed to create a probe for the device '%s'", device); 72 | blkid_free_probe (probe); 73 | synced_close (fd); 74 | return FALSE; 75 | } 76 | 77 | blkid_probe_enable_partitions (probe, 1); 78 | 79 | status = blkid_do_probe (probe); 80 | if (status != 0) { 81 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 82 | "Failed to probe the device '%s'", device); 83 | blkid_free_probe (probe); 84 | synced_close (fd); 85 | return FALSE; 86 | } 87 | 88 | status = blkid_probe_has_value (probe, "LABEL"); 89 | 90 | if (status == 0) 91 | *label = g_strdup (""); 92 | else { 93 | status = blkid_probe_lookup_value (probe, "LABEL", &value, NULL); 94 | if (status != 0) { 95 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 96 | "Failed to get label for the device '%s'", device); 97 | blkid_free_probe (probe); 98 | synced_close (fd); 99 | return FALSE; 100 | } 101 | 102 | if (value) 103 | *label = g_strdup (value); 104 | else 105 | *label = g_strdup (""); 106 | } 107 | 108 | status = blkid_probe_has_value (probe, "UUID"); 109 | if (status == 0) 110 | *uuid = g_strdup (""); 111 | else { 112 | status = blkid_probe_lookup_value (probe, "UUID", &value, NULL); 113 | if (status != 0) { 114 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, 115 | "Failed to get UUID for the device '%s'", device); 116 | blkid_free_probe (probe); 117 | synced_close (fd); 118 | g_free (label); 119 | return FALSE; 120 | } 121 | 122 | if (value) 123 | *uuid = g_strdup (value); 124 | else 125 | *uuid = g_strdup (""); 126 | } 127 | 128 | blkid_free_probe (probe); 129 | synced_close (fd); 130 | 131 | return TRUE; 132 | } 133 | 134 | G_GNUC_INTERNAL gboolean 135 | check_uuid (const gchar *uuid, GError **error) { 136 | g_autofree gchar *lowercase = NULL; 137 | gint ret = 0; 138 | uuid_t uu; 139 | 140 | if (!g_str_is_ascii (uuid)) { 141 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_UUID_INVALID, 142 | "Provided UUID is not a valid RFC-4122 UUID."); 143 | return FALSE; 144 | } 145 | 146 | lowercase = g_ascii_strdown (uuid, -1); 147 | ret = uuid_parse (lowercase, uu); 148 | if (ret < 0){ 149 | g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_UUID_INVALID, 150 | "Provided UUID is not a valid RFC-4122 UUID."); 151 | return FALSE; 152 | } 153 | 154 | return TRUE; 155 | } 156 | -------------------------------------------------------------------------------- /src/plugins/fs/common.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_COMMON 5 | #define BD_FS_COMMON 6 | 7 | /* "C" locale to get the locale-agnostic error messages */ 8 | #define _C_LOCALE (locale_t) 0 9 | 10 | gint synced_close (gint fd); 11 | gboolean get_uuid_label (const gchar *device, gchar **uuid, gchar **label, GError **error); 12 | gboolean check_uuid (const gchar *uuid, GError **error); 13 | 14 | #endif /* BD_FS_COMMON */ 15 | -------------------------------------------------------------------------------- /src/plugins/fs/exfat.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_EXFAT 5 | #define BD_FS_EXFAT 6 | 7 | typedef struct BDFSExfatInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 sector_size; 11 | guint64 sector_count; 12 | guint64 cluster_count; 13 | } BDFSExfatInfo; 14 | 15 | BDFSExfatInfo* bd_fs_exfat_info_copy (BDFSExfatInfo *data); 16 | void bd_fs_exfat_info_free (BDFSExfatInfo *data); 17 | 18 | gboolean bd_fs_exfat_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_exfat_check (const gchar *device, const BDExtraArg **extra, GError **error); 20 | gboolean bd_fs_exfat_repair (const gchar *device, const BDExtraArg **extra, GError **error); 21 | gboolean bd_fs_exfat_set_label (const gchar *device, const gchar *label, GError **error); 22 | gboolean bd_fs_exfat_check_label (const gchar *label, GError **error); 23 | gboolean bd_fs_exfat_set_uuid (const gchar *device, const gchar *uuid, GError **error); 24 | gboolean bd_fs_exfat_check_uuid (const gchar *uuid, GError **error); 25 | BDFSExfatInfo* bd_fs_exfat_get_info (const gchar *device, GError **error); 26 | 27 | #endif /* BD_FS_EXFAT */ 28 | -------------------------------------------------------------------------------- /src/plugins/fs/ext.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_EXT 5 | #define BD_FS_EXT 6 | 7 | typedef struct BDFSExtInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | gchar *state; 11 | guint64 block_size; 12 | guint64 block_count; 13 | guint64 free_blocks; 14 | } BDFSExtInfo; 15 | 16 | typedef struct BDFSExtInfo BDFSExt4Info; 17 | typedef struct BDFSExtInfo BDFSExt3Info; 18 | typedef struct BDFSExtInfo BDFSExt2Info; 19 | 20 | BDFSExt2Info* bd_fs_ext2_info_copy (BDFSExt2Info *data); 21 | void bd_fs_ext2_info_free (BDFSExt2Info *data); 22 | 23 | BDFSExt3Info* bd_fs_ext3_info_copy (BDFSExt3Info *data); 24 | void bd_fs_ext3_info_free (BDFSExt3Info *data); 25 | 26 | BDFSExt4Info* bd_fs_ext4_info_copy (BDFSExt4Info *data); 27 | void bd_fs_ext4_info_free (BDFSExt4Info *data); 28 | 29 | gboolean bd_fs_ext2_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 30 | gboolean bd_fs_ext2_check (const gchar *device, const BDExtraArg **extra, GError **error); 31 | gboolean bd_fs_ext2_repair (const gchar *device, gboolean unsafe, const BDExtraArg **extra, GError **error); 32 | gboolean bd_fs_ext2_set_label (const gchar *device, const gchar *label, GError **error); 33 | gboolean bd_fs_ext2_check_label (const gchar *label, GError **error); 34 | gboolean bd_fs_ext2_set_uuid (const gchar *device, const gchar *uuid, GError **error); 35 | gboolean bd_fs_ext2_check_uuid (const gchar *uuid, GError **error); 36 | BDFSExt2Info* bd_fs_ext2_get_info (const gchar *device, GError **error); 37 | gboolean bd_fs_ext2_resize (const gchar *device, guint64 new_size, const BDExtraArg **extra, GError **error); 38 | guint64 bd_fs_ext2_get_min_size (const gchar *device, GError **error); 39 | 40 | gboolean bd_fs_ext3_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 41 | gboolean bd_fs_ext3_check (const gchar *device, const BDExtraArg **extra, GError **error); 42 | gboolean bd_fs_ext3_repair (const gchar *device, gboolean unsafe, const BDExtraArg **extra, GError **error); 43 | gboolean bd_fs_ext3_set_uuid (const gchar *device, const gchar *uuid, GError **error); 44 | gboolean bd_fs_ext3_check_uuid (const gchar *uuid, GError **error); 45 | gboolean bd_fs_ext3_set_label (const gchar *device, const gchar *label, GError **error); 46 | gboolean bd_fs_ext3_check_label (const gchar *label, GError **error); 47 | BDFSExt3Info* bd_fs_ext3_get_info (const gchar *device, GError **error); 48 | gboolean bd_fs_ext3_resize (const gchar *device, guint64 new_size, const BDExtraArg **extra, GError **error); 49 | guint64 bd_fs_ext3_get_min_size (const gchar *device, GError **error); 50 | 51 | gboolean bd_fs_ext4_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 52 | gboolean bd_fs_ext4_check (const gchar *device, const BDExtraArg **extra, GError **error); 53 | gboolean bd_fs_ext4_repair (const gchar *device, gboolean unsafe, const BDExtraArg **extra, GError **error); 54 | gboolean bd_fs_ext4_set_label (const gchar *device, const gchar *label, GError **error); 55 | gboolean bd_fs_ext4_check_label (const gchar *label, GError **error); 56 | gboolean bd_fs_ext4_set_uuid (const gchar *device, const gchar *uuid, GError **error); 57 | gboolean bd_fs_ext4_check_uuid (const gchar *uuid, GError **error); 58 | BDFSExt4Info* bd_fs_ext4_get_info (const gchar *device, GError **error); 59 | gboolean bd_fs_ext4_resize (const gchar *device, guint64 new_size, const BDExtraArg **extra, GError **error); 60 | guint64 bd_fs_ext4_get_min_size (const gchar *device, GError **error); 61 | 62 | #endif /* BD_FS_EXT */ 63 | -------------------------------------------------------------------------------- /src/plugins/fs/f2fs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_F2FS 5 | #define BD_FS_F2FS 6 | 7 | /* this is taken from f2fs_fs.h */ 8 | typedef enum { 9 | BD_FS_F2FS_FEATURE_ENCRYPT = 1 << 0, 10 | BD_FS_F2FS_FEATURE_BLKZONED = 1 << 1, 11 | BD_FS_F2FS_FEATURE_ATOMIC_WRITE = 1 << 2, 12 | BD_FS_F2FS_FEATURE_EXTRA_ATTR = 1 << 3, 13 | BD_FS_F2FS_FEATURE_PRJQUOTA = 1 << 4, 14 | BD_FS_F2FS_FEATURE_INODE_CHKSUM = 1 << 5, 15 | BD_FS_F2FS_FEATURE_FLEXIBLE_INLINE_XATTR = 1 << 6, 16 | BD_FS_F2FS_FEATURE_QUOTA_INO = 1 << 7, 17 | BD_FS_F2FS_FEATURE_INODE_CRTIME = 1 << 8, 18 | BD_FS_F2FS_FEATURE_LOST_FOUND = 1 << 9, 19 | BD_FS_F2FS_FEATURE_VERITY = 1 << 10, 20 | BD_FS_F2FS_FEATURE_SB_CHKSUM = 1 << 11, 21 | } BDFSF2FSFeature; 22 | 23 | typedef struct BDFSF2FSInfo { 24 | gchar *label; 25 | gchar *uuid; 26 | guint64 sector_size; 27 | guint64 sector_count; 28 | guint64 features; 29 | } BDFSF2FSInfo; 30 | 31 | BDFSF2FSInfo* bd_fs_f2fs_info_copy (BDFSF2FSInfo *data); 32 | void bd_fs_f2fs_info_free (BDFSF2FSInfo *data); 33 | 34 | gboolean bd_fs_f2fs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 35 | gboolean bd_fs_f2fs_check (const gchar *device, const BDExtraArg **extra, GError **error); 36 | gboolean bd_fs_f2fs_repair (const gchar *device, const BDExtraArg **extra, GError **error); 37 | BDFSF2FSInfo* bd_fs_f2fs_get_info (const gchar *device, GError **error); 38 | gboolean bd_fs_f2fs_resize (const gchar *device, guint64 new_size, gboolean safe, const BDExtraArg **extra, GError **error); 39 | gboolean bd_fs_f2fs_check_label (const gchar *label, GError **error); 40 | 41 | #endif /* BD_FS_F2FS */ 42 | -------------------------------------------------------------------------------- /src/plugins/fs/generic.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_FS_GENERIC 4 | #define BD_FS_GENERIC 5 | 6 | gboolean bd_fs_wipe (const gchar *device, gboolean all, gboolean force, GError **error) ; 7 | gboolean bd_fs_clean (const gchar *device, gboolean force, GError **error); 8 | gchar* bd_fs_get_fstype (const gchar *device, GError **error); 9 | 10 | gboolean bd_fs_freeze (const gchar *mountpoint, GError **error); 11 | gboolean bd_fs_unfreeze (const gchar *mountpoint, GError **error); 12 | 13 | typedef enum { 14 | BD_FS_MKFS_LABEL = 1 << 0, 15 | BD_FS_MKFS_UUID = 1 << 1, 16 | BD_FS_MKFS_DRY_RUN = 1 << 2, 17 | BD_FS_MKFS_NODISCARD = 1 << 3, 18 | BD_FS_MKFS_FORCE = 1 << 4, 19 | BD_FS_MKFS_NOPT = 1 << 5, 20 | } BDFSMkfsOptionsFlags; 21 | 22 | typedef struct BDFSMkfsOptions { 23 | const gchar *label; 24 | const gchar *uuid; 25 | gboolean dry_run; 26 | gboolean no_discard; 27 | gboolean force; 28 | gboolean no_pt; 29 | guint8 reserve[32]; 30 | } BDFSMkfsOptions; 31 | 32 | BDFSMkfsOptions* bd_fs_mkfs_options_copy (BDFSMkfsOptions *data); 33 | void bd_fs_mkfs_options_free (BDFSMkfsOptions *data); 34 | 35 | const gchar** bd_fs_supported_filesystems (GError **error); 36 | 37 | gboolean bd_fs_mkfs (const gchar *device, const gchar *fstype, BDFSMkfsOptions *options, const BDExtraArg **extra, GError **error); 38 | 39 | gboolean bd_fs_resize (const gchar *device, guint64 new_size, const gchar *fstype, GError **error); 40 | gboolean bd_fs_repair (const gchar *device, const gchar *fstype, GError **error); 41 | gboolean bd_fs_check (const gchar *device, const gchar *fstype, GError **error); 42 | gboolean bd_fs_set_label (const gchar *device, const gchar *label, const gchar *fstype, GError **error); 43 | gboolean bd_fs_check_label (const gchar *fstype, const gchar *label, GError **error); 44 | gboolean bd_fs_set_uuid (const gchar *device, const gchar *uuid, const gchar *fstype, GError **error); 45 | gboolean bd_fs_check_uuid (const gchar *fstype, const gchar *uuid, GError **error); 46 | guint64 bd_fs_get_size (const gchar *device, const gchar *fstype, GError **error); 47 | guint64 bd_fs_get_free_space (const gchar *device, const gchar *fstype, GError **error); 48 | guint64 bd_fs_get_min_size (const gchar *device, const gchar *fstype, GError **error); 49 | 50 | typedef enum { 51 | BD_FS_OFFLINE_SHRINK = 1 << 1, 52 | BD_FS_OFFLINE_GROW = 1 << 2, 53 | BD_FS_ONLINE_SHRINK = 1 << 3, 54 | BD_FS_ONLINE_GROW = 1 << 4 55 | } BDFSResizeFlags; 56 | 57 | typedef enum { 58 | BD_FS_SUPPORT_SET_LABEL = 1 << 1, 59 | BD_FS_SUPPORT_SET_UUID = 1 << 2 60 | } BDFSConfigureFlags; 61 | 62 | typedef enum { 63 | BD_FS_FSCK_CHECK = 1 << 1, 64 | BD_FS_FSCK_REPAIR = 1 << 2 65 | } BDFSFsckFlags; 66 | 67 | typedef enum { 68 | BD_FS_FEATURE_OWNERS = 1 << 1, 69 | BD_FS_FEATURE_PARTITION_TABLE = 1 << 2, 70 | } BDFSFeatureFlags; 71 | 72 | typedef struct BDFSFeatures { 73 | BDFSResizeFlags resize; 74 | BDFSMkfsOptionsFlags mkfs; 75 | BDFSFsckFlags fsck; 76 | BDFSConfigureFlags configure; 77 | BDFSFeatureFlags features; 78 | const gchar *partition_id; 79 | const gchar *partition_type; 80 | guint64 min_size; 81 | guint64 max_size; 82 | } BDFSFeatures; 83 | 84 | BDFSFeatures* bd_fs_features_copy (BDFSFeatures *data); 85 | void bd_fs_features_free (BDFSFeatures *data); 86 | 87 | const BDFSFeatures* bd_fs_features (const gchar *fstype, GError **error); 88 | 89 | gboolean bd_fs_can_mkfs (const gchar *type, BDFSMkfsOptionsFlags *options, gchar **required_utility, GError **error); 90 | gboolean bd_fs_can_resize (const gchar *type, BDFSResizeFlags *mode, gchar **required_utility, GError **error); 91 | gboolean bd_fs_can_check (const gchar *type, gchar **required_utility, GError **error); 92 | gboolean bd_fs_can_repair (const gchar *type, gchar **required_utility, GError **error); 93 | gboolean bd_fs_can_set_label (const gchar *type, gchar **required_utility, GError **error); 94 | gboolean bd_fs_can_set_uuid (const gchar *type, gchar **required_utility, GError **error); 95 | gboolean bd_fs_can_get_size (const gchar *type, gchar **required_utility, GError **error); 96 | gboolean bd_fs_can_get_free_space (const gchar *type, gchar **required_utility, GError **error); 97 | gboolean bd_fs_can_get_info (const gchar *type, gchar **required_utility, GError **error); 98 | gboolean bd_fs_can_get_min_size (const gchar *type, gchar **required_utility, GError **error); 99 | 100 | #endif /* BD_FS_GENERIC */ 101 | -------------------------------------------------------------------------------- /src/plugins/fs/mount.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_MOUNT 5 | #define BD_FS_MOUNT 6 | 7 | gboolean bd_fs_unmount (const gchar *spec, gboolean lazy, gboolean force, const BDExtraArg **extra, GError **error); 8 | gboolean bd_fs_mount (const gchar *device, const gchar *mountpoint, const gchar *fstype, const gchar *options, const BDExtraArg **extra, GError **error); 9 | gchar* bd_fs_get_mountpoint (const gchar *device, GError **error); 10 | gboolean bd_fs_is_mountpoint (const gchar *path, GError **error); 11 | 12 | #endif /* BD_FS_MOUNT */ 13 | -------------------------------------------------------------------------------- /src/plugins/fs/nilfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_NILFS 5 | #define BD_FS_NILFS 6 | 7 | typedef struct BDFSNILFS2Info { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 size; 11 | guint64 block_size; 12 | guint64 free_blocks; 13 | } BDFSNILFS2Info; 14 | 15 | BDFSNILFS2Info* bd_fs_nilfs2_info_copy (BDFSNILFS2Info *data); 16 | void bd_fs_nilfs2_info_free (BDFSNILFS2Info *data); 17 | 18 | gboolean bd_fs_nilfs2_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_nilfs2_set_label (const gchar *device, const gchar *label, GError **error); 20 | gboolean bd_fs_nilfs2_check_label (const gchar *label, GError **error); 21 | gboolean bd_fs_nilfs2_set_uuid (const gchar *device, const gchar *uuid, GError **error); 22 | gboolean bd_fs_nilfs2_check_uuid (const gchar *uuid, GError **error); 23 | BDFSNILFS2Info* bd_fs_nilfs2_get_info (const gchar *device, GError **error); 24 | gboolean bd_fs_nilfs2_resize (const gchar *device, guint64 new_size, GError **error); 25 | 26 | #endif /* BD_FS_NILFS */ 27 | -------------------------------------------------------------------------------- /src/plugins/fs/ntfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_NTFS 5 | #define BD_FS_NTFS 6 | 7 | typedef struct BDFSNtfsInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 size; 11 | guint64 free_space; 12 | } BDFSNtfsInfo; 13 | 14 | BDFSNtfsInfo* bd_fs_ntfs_info_copy (BDFSNtfsInfo *data); 15 | void bd_fs_ntfs_info_free (BDFSNtfsInfo *data); 16 | 17 | gboolean bd_fs_ntfs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 18 | gboolean bd_fs_ntfs_check (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_ntfs_repair (const gchar *device, const BDExtraArg **extra, GError **error); 20 | gboolean bd_fs_ntfs_set_label (const gchar *device, const gchar *label, GError **error); 21 | gboolean bd_fs_ntfs_check_label (const gchar *label, GError **error); 22 | gboolean bd_fs_ntfs_set_uuid (const gchar *device, const gchar *uuid, GError **error); 23 | gboolean bd_fs_ntfs_check_uuid ( const gchar *uuid, GError **error); 24 | BDFSNtfsInfo* bd_fs_ntfs_get_info (const gchar *device, GError **error); 25 | gboolean bd_fs_ntfs_resize (const gchar *device, guint64 new_size, GError **error); 26 | guint64 bd_fs_ntfs_get_min_size (const gchar *device, GError **error); 27 | 28 | #endif /* BD_FS_NTFS */ 29 | -------------------------------------------------------------------------------- /src/plugins/fs/udf.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_UDF 5 | #define BD_FS_UDF 6 | 7 | typedef struct BDFSUdfInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | gchar *revision; 11 | gchar *lvid; 12 | gchar *vid; 13 | guint64 block_size; 14 | guint64 block_count; 15 | guint64 free_blocks; 16 | } BDFSUdfInfo; 17 | 18 | BDFSUdfInfo* bd_fs_udf_info_copy (BDFSUdfInfo *data); 19 | void bd_fs_udf_info_free (BDFSUdfInfo *data); 20 | 21 | gboolean bd_fs_udf_mkfs (const gchar *device, const gchar *media_type, gchar *revision, guint64 block_size, const BDExtraArg **extra, GError **error); 22 | gboolean bd_fs_udf_set_label (const gchar *device, const gchar *label, GError **error); 23 | gboolean bd_fs_udf_check_label (const gchar *label, GError **error); 24 | gboolean bd_fs_udf_set_uuid (const gchar *device, const gchar *uuid, GError **error); 25 | gboolean bd_fs_udf_check_uuid ( const gchar *uuid, GError **error); 26 | BDFSUdfInfo* bd_fs_udf_get_info (const gchar *device, GError **error); 27 | 28 | #endif /* BD_FS_UDF */ 29 | -------------------------------------------------------------------------------- /src/plugins/fs/vfat.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_VFAT 5 | #define BD_FS_VFAT 6 | 7 | typedef struct BDFSVfatInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 cluster_size; 11 | guint64 cluster_count; 12 | guint64 free_cluster_count; 13 | } BDFSVfatInfo; 14 | 15 | BDFSVfatInfo* bd_fs_vfat_info_copy (BDFSVfatInfo *data); 16 | void bd_fs_vfat_info_free (BDFSVfatInfo *data); 17 | 18 | gboolean bd_fs_vfat_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_vfat_check (const gchar *device, const BDExtraArg **extra, GError **error); 20 | gboolean bd_fs_vfat_repair (const gchar *device, const BDExtraArg **extra, GError **error); 21 | gboolean bd_fs_vfat_set_label (const gchar *device, const gchar *label, GError **error); 22 | gboolean bd_fs_vfat_check_label (const gchar *label, GError **error); 23 | gboolean bd_fs_vfat_set_uuid (const gchar *device, const gchar *uuid, GError **error); 24 | gboolean bd_fs_vfat_check_uuid (const gchar *uuid, GError **error); 25 | BDFSVfatInfo* bd_fs_vfat_get_info (const gchar *device, GError **error); 26 | gboolean bd_fs_vfat_resize (const gchar *device, guint64 new_size, GError **error); 27 | 28 | #endif /* BD_FS_VFAT */ 29 | -------------------------------------------------------------------------------- /src/plugins/fs/xfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_FS_XFS 5 | #define BD_FS_XFS 6 | 7 | typedef struct BDFSXfsInfo { 8 | gchar *label; 9 | gchar *uuid; 10 | guint64 block_size; 11 | guint64 block_count; 12 | } BDFSXfsInfo; 13 | 14 | BDFSXfsInfo* bd_fs_xfs_info_copy (BDFSXfsInfo *data); 15 | void bd_fs_xfs_info_free (BDFSXfsInfo *data); 16 | 17 | gboolean bd_fs_xfs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error); 18 | gboolean bd_fs_xfs_check (const gchar *device, const BDExtraArg **extra, GError **error); 19 | gboolean bd_fs_xfs_repair (const gchar *device, const BDExtraArg **extra, GError **error); 20 | gboolean bd_fs_xfs_set_label (const gchar *device, const gchar *label, GError **error); 21 | gboolean bd_fs_xfs_check_label (const gchar *label, GError **error); 22 | gboolean bd_fs_xfs_set_uuid (const gchar *device, const gchar *uuid, GError **error); 23 | gboolean bd_fs_xfs_check_uuid (const gchar *uuid, GError **error); 24 | BDFSXfsInfo* bd_fs_xfs_get_info (const gchar *device, GError **error); 25 | gboolean bd_fs_xfs_resize (const gchar *mpoint, guint64 new_size, const BDExtraArg **extra, GError **error); 26 | 27 | #endif /* BD_FS_XFS */ 28 | -------------------------------------------------------------------------------- /src/plugins/loop.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_LOOP 4 | #define BD_LOOP 5 | 6 | GQuark bd_loop_error_quark (void); 7 | #define BD_LOOP_ERROR bd_loop_error_quark () 8 | typedef enum { 9 | BD_LOOP_ERROR_TECH_UNAVAIL, 10 | BD_LOOP_ERROR_FAIL, 11 | BD_LOOP_ERROR_DEVICE, 12 | } BDLoopError; 13 | 14 | typedef enum { 15 | BD_LOOP_TECH_LOOP = 0, 16 | } BDLoopTech; 17 | 18 | typedef enum { 19 | BD_LOOP_TECH_MODE_CREATE = 1 << 0, 20 | BD_LOOP_TECH_MODE_DESTROY = 1 << 1, 21 | BD_LOOP_TECH_MODE_MODIFY = 1 << 2, 22 | BD_LOOP_TECH_MODE_QUERY = 1 << 3, 23 | } BDLoopTechMode; 24 | 25 | /** 26 | * BDLoopInfo: 27 | * @backing_file: backing file for the give loop device; 28 | * @offset: offset of the start of the device (in @backing_file); 29 | * @autoclear: whether the autoclear flag is set or not; 30 | * @direct_io: whether direct IO is enabled or not; 31 | * @part_scan: whether the partition scan is enforced or not; 32 | * @read_only: whether the device is read-only or not; 33 | */ 34 | typedef struct BDLoopInfo { 35 | gchar *backing_file; 36 | guint64 offset; 37 | gboolean autoclear; 38 | gboolean direct_io; 39 | gboolean part_scan; 40 | gboolean read_only; 41 | } BDLoopInfo; 42 | 43 | 44 | void bd_loop_info_free (BDLoopInfo *info); 45 | BDLoopInfo* bd_loop_info_copy (BDLoopInfo *info); 46 | 47 | 48 | /* 49 | * If using the plugin as a standalone library, the following functions should 50 | * be called to: 51 | * 52 | * init() - initialize the plugin, returning TRUE on success 53 | * close() - clean after the plugin at the end or if no longer used 54 | * 55 | */ 56 | gboolean bd_loop_init (void); 57 | void bd_loop_close (void); 58 | 59 | gboolean bd_loop_is_tech_avail (BDLoopTech tech, guint64 mode, GError **error); 60 | 61 | BDLoopInfo* bd_loop_info (const gchar *loop, GError **error); 62 | 63 | gchar* bd_loop_get_loop_name (const gchar *file, GError **error); 64 | gboolean bd_loop_setup (const gchar *file, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, guint64 sector_size, const gchar **loop_name, GError **error); 65 | gboolean bd_loop_setup_from_fd (gint fd, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, guint64 sector_size, const gchar **loop_name, GError **error); 66 | gboolean bd_loop_teardown (const gchar *loop, GError **error); 67 | 68 | gboolean bd_loop_set_autoclear (const gchar *loop, gboolean autoclear, GError **error); 69 | 70 | #endif /* BD_LOOP */ 71 | -------------------------------------------------------------------------------- /src/plugins/lvm/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = subdir-objects 2 | 3 | lib_LTLIBRARIES = 4 | libincludedir = $(includedir)/blockdev 5 | 6 | if WITH_LVM 7 | libinclude_HEADERS = lvm.h 8 | else 9 | if WITH_LVM_DBUS 10 | libinclude_HEADERS = lvm.h 11 | endif 12 | endif 13 | 14 | 15 | if WITH_LVM 16 | 17 | lib_LTLIBRARIES += libbd_lvm.la 18 | 19 | libbd_lvm_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) $(YAML_CFLAGS) -Wall -Wextra -Werror 20 | libbd_lvm_la_LIBADD = ${builddir}/../../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) $(YAML_LIBS) 21 | libbd_lvm_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 22 | libbd_lvm_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ -I. -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 23 | 24 | libbd_lvm_la_SOURCES = \ 25 | lvm.c \ 26 | lvm.h \ 27 | lvm-private.h \ 28 | lvm-common.c \ 29 | vdo_stats.c \ 30 | vdo_stats.h \ 31 | ../check_deps.c \ 32 | ../check_deps.h \ 33 | ../dm_logging.c \ 34 | ../dm_logging.h 35 | 36 | endif 37 | 38 | if WITH_LVM_DBUS 39 | 40 | lib_LTLIBRARIES += libbd_lvm-dbus.la 41 | 42 | libbd_lvm_dbus_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) $(YAML_CFLAGS) -Wall -Wextra -Werror 43 | libbd_lvm_dbus_la_LIBADD = ${builddir}/../../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) $(YAML_LIBS) 44 | libbd_lvm_dbus_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 45 | libbd_lvm_dbus_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ -I. -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 46 | 47 | libbd_lvm_dbus_la_SOURCES = \ 48 | lvm-dbus.c \ 49 | lvm.h \ 50 | lvm-private.h \ 51 | lvm-common.c \ 52 | vdo_stats.c \ 53 | vdo_stats.h \ 54 | ../check_deps.c \ 55 | ../check_deps.h \ 56 | ../dm_logging.c \ 57 | ../dm_logging.h 58 | 59 | endif 60 | -------------------------------------------------------------------------------- /src/plugins/lvm/lvm-private.h: -------------------------------------------------------------------------------- 1 | #ifndef BD_LVM_PRIVATE 2 | #define BD_LVM_PRIVATE 3 | 4 | #define SECTOR_SIZE 512 5 | #define DEFAULT_PE_SIZE (4 MiB) 6 | #define USE_DEFAULT_PE_SIZE 0 7 | #define RESOLVE_PE_SIZE(size) ((size) == USE_DEFAULT_PE_SIZE ? DEFAULT_PE_SIZE : (size)) 8 | 9 | #define LVM_MIN_VERSION "2.02.116" 10 | #define LVM_VERSION_FSRESIZE "2.03.19" 11 | 12 | extern GMutex global_config_lock; 13 | extern gchar *global_config_str; 14 | 15 | extern gchar *global_devices_str; 16 | 17 | #endif /* BD_LVM_PRIVATE */ 18 | -------------------------------------------------------------------------------- /src/plugins/lvm/vdo_stats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | */ 19 | 20 | #include 21 | 22 | #ifndef BD_VDO_STATS 23 | #define BD_VDO_STATS 24 | 25 | gboolean get_stat_val_double (GHashTable *stats, const gchar *key, gdouble *val); 26 | gboolean get_stat_val64 (GHashTable *stats, const gchar *key, gint64 *val); 27 | gboolean get_stat_val64_default (GHashTable *stats, const gchar *key, gint64 *val, gint64 def); 28 | 29 | GHashTable* vdo_get_stats_full (const gchar *name, GError **error); 30 | 31 | #endif /* BD_VDO_STATS */ 32 | -------------------------------------------------------------------------------- /src/plugins/mdraid.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_MD 5 | #define BD_MD 6 | 7 | /* these defaults were determined empirically (taken from blivet) */ 8 | #define BD_MD_SUPERBLOCK_SIZE (2 MiB) 9 | #define BD_MD_CHUNK_SIZE (512 KiB) 10 | 11 | GQuark bd_md_error_quark (void); 12 | #define BD_MD_ERROR bd_md_error_quark () 13 | typedef enum { 14 | BD_MD_ERROR_TECH_UNAVAIL, 15 | BD_MD_ERROR_FAIL, 16 | BD_MD_ERROR_PARSE, 17 | BD_MD_ERROR_BAD_FORMAT, 18 | BD_MD_ERROR_NO_MATCH, 19 | BD_MD_ERROR_INVAL, 20 | } BDMDError; 21 | 22 | typedef struct BDMDExamineData { 23 | gchar *device; 24 | gchar *level; 25 | guint64 num_devices; 26 | gchar *name; 27 | guint64 size; 28 | gchar *uuid; 29 | guint64 update_time; 30 | gchar *dev_uuid; 31 | guint64 events; 32 | gchar *metadata; 33 | guint64 chunk_size; 34 | } BDMDExamineData; 35 | 36 | BDMDExamineData* bd_md_examine_data_copy (BDMDExamineData *data); 37 | void bd_md_examine_data_free (BDMDExamineData *data); 38 | 39 | typedef struct BDMDDetailData { 40 | gchar *device; 41 | gchar *metadata; 42 | gchar *creation_time; 43 | gchar *level; 44 | gchar *name; 45 | guint64 array_size; 46 | guint64 use_dev_size; 47 | guint64 raid_devices; 48 | guint64 total_devices; 49 | guint64 active_devices; 50 | guint64 working_devices; 51 | guint64 failed_devices; 52 | guint64 spare_devices; 53 | gboolean clean; 54 | gchar *uuid; 55 | gchar *container; 56 | } BDMDDetailData; 57 | 58 | void bd_md_detail_data_free (BDMDDetailData *data); 59 | BDMDDetailData* bd_md_detail_data_copy (BDMDDetailData *data); 60 | 61 | typedef enum { 62 | BD_MD_TECH_MDRAID = 0, 63 | } BDMDTech; 64 | 65 | typedef enum { 66 | BD_MD_TECH_MODE_CREATE = 1 << 0, 67 | BD_MD_TECH_MODE_DELETE = 1 << 1, 68 | BD_MD_TECH_MODE_MODIFY = 1 << 2, 69 | BD_MD_TECH_MODE_QUERY = 1 << 3, 70 | } BDMDTechMode; 71 | 72 | 73 | /* 74 | * If using the plugin as a standalone library, the following functions should 75 | * be called to: 76 | * 77 | * init() - initialize the plugin, returning TRUE on success 78 | * close() - clean after the plugin at the end or if no longer used 79 | * 80 | */ 81 | gboolean bd_md_init (void); 82 | void bd_md_close (void); 83 | 84 | gboolean bd_md_is_tech_avail (BDMDTech tech, guint64 mode, GError **error); 85 | 86 | guint64 bd_md_get_superblock_size (guint64 member_size, const gchar *version, GError **error); 87 | gboolean bd_md_create (const gchar *device_name, const gchar *level, const gchar **disks, guint64 spares, const gchar *version, const gchar *bitmap, guint64 chunk_size, const BDExtraArg **extra, GError **error); 88 | gboolean bd_md_destroy (const gchar *device, GError **error); 89 | gboolean bd_md_deactivate (const gchar *raid_spec, GError **error); 90 | gboolean bd_md_activate (const gchar *raid_spec, const gchar **members, const gchar *uuid, gboolean start_degraded, const BDExtraArg **extra, GError **error); 91 | gboolean bd_md_run (const gchar *raid_spec, GError **error); 92 | gboolean bd_md_nominate (const gchar *device, GError **error); 93 | gboolean bd_md_denominate (const gchar *device, GError **error); 94 | gboolean bd_md_add (const gchar *raid_spec, const gchar *device, guint64 raid_devs, const BDExtraArg **extra, GError **error); 95 | gboolean bd_md_remove (const gchar *raid_spec, const gchar *device, gboolean fail, const BDExtraArg **extra, GError **error); 96 | BDMDExamineData* bd_md_examine (const gchar *device, GError **error); 97 | BDMDDetailData* bd_md_detail (const gchar *raid_spec, GError **error); 98 | gchar* bd_md_canonicalize_uuid (const gchar *uuid, GError **error); 99 | gchar* bd_md_get_md_uuid (const gchar *uuid, GError **error); 100 | gchar* bd_md_node_from_name (const gchar *name, GError **error); 101 | gchar* bd_md_name_from_node (const gchar *node, GError **error); 102 | gchar* bd_md_get_status (const gchar *raid_spec, GError **error); 103 | gboolean bd_md_set_bitmap_location (const gchar *raid_spec, const gchar *location, GError **error); 104 | gchar* bd_md_get_bitmap_location (const gchar *raid_spec, GError **error); 105 | gboolean bd_md_request_sync_action (const gchar *raid_spec, const gchar *action, GError **error); 106 | 107 | #endif /* BD_MD */ 108 | -------------------------------------------------------------------------------- /src/plugins/mpath.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_MPATH 4 | #define BD_MPATH 5 | 6 | GQuark bd_mpath_error_quark (void); 7 | #define BD_MPATH_ERROR bd_mpath_error_quark () 8 | typedef enum { 9 | BD_MPATH_ERROR_TECH_UNAVAIL, 10 | BD_MPATH_ERROR_INVAL, 11 | BD_MPATH_ERROR_FLUSH, 12 | BD_MPATH_ERROR_NOT_ROOT, 13 | BD_MPATH_ERROR_DM_ERROR, 14 | } BDMpathError; 15 | 16 | typedef enum { 17 | BD_MPATH_TECH_BASE = 0, 18 | BD_MPATH_TECH_FRIENDLY_NAMES, 19 | } BDMpathTech; 20 | 21 | typedef enum { 22 | BD_MPATH_TECH_MODE_QUERY = 1 << 0, 23 | BD_MPATH_TECH_MODE_MODIFY = 1 << 1, 24 | } BDMpathTechMode; 25 | 26 | 27 | /* 28 | * If using the plugin as a standalone library, the following functions should 29 | * be called to: 30 | * 31 | * init() - initialize the plugin, returning TRUE on success 32 | * close() - clean after the plugin at the end or if no longer used 33 | * 34 | */ 35 | gboolean bd_mpath_init (void); 36 | void bd_mpath_close (void); 37 | 38 | gboolean bd_mpath_is_tech_avail (BDMpathTech tech, guint64 mode, GError **error); 39 | 40 | gboolean bd_mpath_flush_mpaths (GError **error); 41 | gboolean bd_mpath_is_mpath_member (const gchar *device, GError **error); 42 | gchar** bd_mpath_get_mpath_members (GError **error); 43 | gboolean bd_mpath_set_friendly_names (gboolean enabled, GError **error); 44 | 45 | #endif /* BD_MPATH */ 46 | -------------------------------------------------------------------------------- /src/plugins/nvdimm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_NVDIMM 5 | #define BD_NVDIMM 6 | 7 | GQuark bd_nvdimm_error_quark (void); 8 | #define BD_NVDIMM_ERROR bd_nvdimm_error_quark () 9 | typedef enum { 10 | BD_NVDIMM_ERROR_TECH_UNAVAIL, 11 | BD_NVDIMM_ERROR_NAMESPACE_FAIL, 12 | BD_NVDIMM_ERROR_NAMESPACE_PARSE, 13 | BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, 14 | BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL, 15 | } BDNVDIMMError; 16 | 17 | typedef enum { 18 | BD_NVDIMM_NAMESPACE_MODE_RAW, 19 | BD_NVDIMM_NAMESPACE_MODE_SECTOR, 20 | BD_NVDIMM_NAMESPACE_MODE_MEMORY, 21 | BD_NVDIMM_NAMESPACE_MODE_DAX, 22 | BD_NVDIMM_NAMESPACE_MODE_FSDAX, 23 | BD_NVDIMM_NAMESPACE_MODE_DEVDAX, 24 | BD_NVDIMM_NAMESPACE_MODE_UNKNOWN, 25 | } BDNVDIMMNamespaceMode; 26 | 27 | typedef struct BDNVDIMMNamespaceInfo { 28 | gchar *dev; 29 | guint64 mode; 30 | guint64 size; 31 | gchar *uuid; 32 | guint64 sector_size; 33 | gchar *blockdev; 34 | gboolean enabled; 35 | } BDNVDIMMNamespaceInfo; 36 | 37 | void bd_nvdimm_namespace_info_free (BDNVDIMMNamespaceInfo *info); 38 | BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *info); 39 | 40 | typedef enum { 41 | BD_NVDIMM_TECH_NAMESPACE = 0, 42 | } BDNVDIMMTech; 43 | 44 | typedef enum { 45 | BD_NVDIMM_TECH_MODE_CREATE = 1 << 0, 46 | BD_NVDIMM_TECH_MODE_REMOVE = 1 << 1, 47 | BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE = 1 << 2, 48 | BD_NVDIMM_TECH_MODE_QUERY = 1 << 3, 49 | BD_NVDIMM_TECH_MODE_RECONFIGURE = 1 << 4, 50 | } BDNVDIMMTechMode; 51 | 52 | /* 53 | * If using the plugin as a standalone library, the following functions should 54 | * be called to: 55 | * 56 | * init() - initialize the plugin, returning TRUE on success 57 | * close() - clean after the plugin at the end or if no longer used 58 | * 59 | */ 60 | gboolean bd_nvdimm_init (void); 61 | void bd_nvdimm_close (void); 62 | 63 | gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **error); 64 | 65 | BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error); 66 | const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error); 67 | 68 | gchar* bd_nvdimm_namespace_get_devname (const gchar *device, GError **error); 69 | 70 | gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra, GError **error); 71 | gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra, GError **error); 72 | 73 | BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info (const gchar *namespace, const BDExtraArg **extra, GError **error); 74 | BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus, const gchar *region, gboolean idle, const BDExtraArg **extra, GError **error); 75 | 76 | gboolean bd_nvdimm_namespace_reconfigure (const gchar* namespace, BDNVDIMMNamespaceMode mode, gboolean force, const BDExtraArg **extra, GError** error); 77 | 78 | const guint64 *bd_nvdimm_namespace_get_supported_sector_sizes (BDNVDIMMNamespaceMode mode, GError **error); 79 | 80 | #endif /* BD_NVDIMM */ 81 | -------------------------------------------------------------------------------- /src/plugins/nvme/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = subdir-objects 2 | 3 | lib_LTLIBRARIES = libbd_nvme.la 4 | 5 | libbd_nvme_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(NVME_CFLAGS) -Wall -Wextra -Werror 6 | libbd_nvme_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(NVME_LIBS) 7 | libbd_nvme_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 8 | libbd_nvme_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ -I. -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 9 | 10 | libbd_nvme_la_SOURCES = \ 11 | nvme.h \ 12 | nvme.c \ 13 | nvme-private.h \ 14 | nvme-info.c \ 15 | nvme-error.c \ 16 | nvme-op.c \ 17 | nvme-fabrics.c \ 18 | ../check_deps.c \ 19 | ../check_deps.h 20 | 21 | libbd_nvmeincludedir = $(includedir)/blockdev 22 | libbd_nvmeinclude_HEADERS = nvme.h 23 | -------------------------------------------------------------------------------- /src/plugins/nvme/nvme-private.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef BD_NVME_PRIVATE 6 | #define BD_NVME_PRIVATE 7 | 8 | /* TODO: move to a common libblockdev header */ 9 | #ifdef __clang__ 10 | #define ZERO_INIT {} 11 | #else 12 | #define ZERO_INIT {0} 13 | #endif 14 | 15 | /* "C" locale to get the locale-agnostic error messages */ 16 | #define _C_LOCALE (locale_t) 0 17 | 18 | /* nvme-error.c */ 19 | G_GNUC_INTERNAL 20 | void _nvme_status_to_error (gint status, gboolean fabrics, GError **error); 21 | G_GNUC_INTERNAL 22 | void _nvme_fabrics_errno_to_gerror (int result, int _errno, GError **error); 23 | 24 | /* nvme-info.c */ 25 | G_GNUC_INTERNAL 26 | gint _open_dev (const gchar *device, GError **error); 27 | G_GNUC_INTERNAL 28 | void *_nvme_alloc (size_t len); 29 | 30 | #endif /* BD_NVME_PRIVATE */ 31 | -------------------------------------------------------------------------------- /src/plugins/nvme/nvme.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2021 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Tomas Bzatek 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | #include "nvme.h" 35 | #include "nvme-private.h" 36 | 37 | /** 38 | * SECTION: nvme 39 | * @short_description: plugin for NVMe device reporting and management 40 | * @title: NVMe 41 | * @include: nvme.h 42 | * 43 | * A plugin for NVMe device reporting and management, based around libnvme. 44 | */ 45 | 46 | 47 | /** 48 | * bd_nvme_init: 49 | * 50 | * Initializes the plugin. **This function is called automatically by the 51 | * library's initialization functions.** 52 | * 53 | */ 54 | gboolean bd_nvme_init (void) { 55 | /* nothing to do here */ 56 | return TRUE; 57 | }; 58 | 59 | /** 60 | * bd_nvme_close: 61 | * 62 | * Cleans up after the plugin. **This function is called automatically by the 63 | * library's functions that unload it.** 64 | * 65 | */ 66 | void bd_nvme_close (void) { 67 | /* nothing to do here */ 68 | } 69 | 70 | /** 71 | * bd_nvme_is_tech_avail: 72 | * @tech: the queried tech 73 | * @mode: a bit mask of queried modes of operation (#BDNVMETechMode) for @tech 74 | * @error: (out) (nullable): place to store error (details about why the @tech-@mode combination is not available) 75 | * 76 | * Returns: whether the @tech-@mode combination is available -- supported by the 77 | * plugin implementation and having all the runtime dependencies available 78 | */ 79 | gboolean bd_nvme_is_tech_avail (BDNVMETech tech, G_GNUC_UNUSED guint64 mode, GError **error) { 80 | switch (tech) { 81 | case BD_NVME_TECH_NVME: 82 | return TRUE; 83 | case BD_NVME_TECH_FABRICS: 84 | return TRUE; 85 | default: 86 | g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_TECH_UNAVAIL, "Unknown technology"); 87 | return FALSE; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/plugins/part.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_PART 4 | #define BD_PART 5 | 6 | GQuark bd_part_error_quark (void); 7 | #define BD_PART_ERROR bd_part_error_quark () 8 | typedef enum { 9 | BD_PART_ERROR_TECH_UNAVAIL, 10 | BD_PART_ERROR_FAIL, 11 | BD_PART_ERROR_INVAL, 12 | BD_PART_ERROR_EXISTS, 13 | } BDPartError; 14 | 15 | typedef enum { 16 | BD_PART_TABLE_MSDOS, 17 | BD_PART_TABLE_GPT, 18 | BD_PART_TABLE_UNDEF, 19 | } BDPartTableType; 20 | 21 | typedef enum { 22 | BD_PART_TYPE_NORMAL = 0x00, 23 | BD_PART_TYPE_LOGICAL = 0x01, 24 | BD_PART_TYPE_EXTENDED = 0x02, 25 | BD_PART_TYPE_FREESPACE = 0x04, 26 | BD_PART_TYPE_METADATA = 0x08, 27 | BD_PART_TYPE_PROTECTED = 0x10 28 | } BDPartType; 29 | 30 | typedef enum { 31 | BD_PART_TYPE_REQ_NORMAL = 0x00, 32 | BD_PART_TYPE_REQ_LOGICAL = 0x01, 33 | BD_PART_TYPE_REQ_EXTENDED = 0x02, 34 | BD_PART_TYPE_REQ_NEXT = 0x04 35 | } BDPartTypeReq; 36 | 37 | typedef enum { 38 | BD_PART_ALIGN_NONE, 39 | BD_PART_ALIGN_MINIMAL, 40 | BD_PART_ALIGN_OPTIMAL, 41 | } BDPartAlign; 42 | 43 | typedef struct BDPartSpec { 44 | gchar *path; 45 | gchar *name; 46 | gchar *uuid; 47 | gchar *id; 48 | gchar *type_guid; 49 | guint64 type; 50 | guint64 start; 51 | guint64 size; 52 | gboolean bootable; 53 | guint64 attrs; 54 | gchar *type_name; 55 | } BDPartSpec; 56 | 57 | BDPartSpec* bd_part_spec_copy (BDPartSpec *data); 58 | void bd_part_spec_free (BDPartSpec *data); 59 | 60 | typedef struct BDPartDiskSpec { 61 | gchar *path; 62 | BDPartTableType table_type; 63 | guint64 size; 64 | guint64 sector_size; 65 | } BDPartDiskSpec; 66 | 67 | BDPartDiskSpec* bd_part_disk_spec_copy (BDPartDiskSpec *data); 68 | void bd_part_disk_spec_free (BDPartDiskSpec *data); 69 | 70 | typedef enum { 71 | BD_PART_TECH_MBR = 0, 72 | BD_PART_TECH_GPT, 73 | } BDPartTech; 74 | 75 | typedef enum { 76 | BD_PART_TECH_MODE_CREATE_TABLE = 1 << 0, 77 | BD_PART_TECH_MODE_MODIFY_TABLE = 1 << 1, 78 | BD_PART_TECH_MODE_QUERY_TABLE = 1 << 2, 79 | BD_PART_TECH_MODE_MODIFY_PART = 1 << 3, 80 | BD_PART_TECH_MODE_QUERY_PART = 1 << 4, 81 | } BDPartTechMode; 82 | 83 | /* 84 | * If using the plugin as a standalone library, the following functions should 85 | * be called to: 86 | * 87 | * init() - initialize the plugin, returning TRUE on success 88 | * close() - clean after the plugin at the end or if no longer used 89 | * 90 | */ 91 | gboolean bd_part_init (void); 92 | void bd_part_close (void); 93 | 94 | gboolean bd_part_is_tech_avail (BDPartTech tech, guint64 mode, GError **error); 95 | 96 | gboolean bd_part_create_table (const gchar *disk, BDPartTableType type, gboolean ignore_existing, GError **error); 97 | 98 | BDPartSpec* bd_part_get_part_spec (const gchar *disk, const gchar *part, GError **error); 99 | BDPartSpec* bd_part_get_part_by_pos (const gchar *disk, guint64 position, GError **error); 100 | BDPartDiskSpec* bd_part_get_disk_spec (const gchar *disk, GError **error); 101 | BDPartSpec** bd_part_get_disk_parts (const gchar *disk, GError **error); 102 | BDPartSpec** bd_part_get_disk_free_regions (const gchar *disk, GError **error); 103 | BDPartSpec* bd_part_get_best_free_region (const gchar *disk, BDPartType type, guint64 size, GError **error); 104 | 105 | BDPartSpec* bd_part_create_part (const gchar *disk, BDPartTypeReq type, guint64 start, guint64 size, BDPartAlign align, GError **error); 106 | gboolean bd_part_delete_part (const gchar *disk, const gchar *part, GError **error); 107 | gboolean bd_part_resize_part (const gchar *disk, const gchar *part, guint64 size, BDPartAlign align, GError **error); 108 | 109 | gboolean bd_part_set_part_name (const gchar *disk, const gchar *part, const gchar *name, GError **error); 110 | gboolean bd_part_set_part_type (const gchar *disk, const gchar *part, const gchar *type_guid, GError **error); 111 | gboolean bd_part_set_part_id (const gchar *disk, const gchar *part, const gchar *part_id, GError **error); 112 | gboolean bd_part_set_part_bootable (const gchar *disk, const gchar *part, gboolean bootable, GError **error); 113 | gboolean bd_part_set_part_attributes (const gchar *disk, const gchar *part, guint64 attrs, GError **error); 114 | gboolean bd_part_set_part_uuid (const gchar *disk, const gchar *part, const gchar *uuid, GError **error); 115 | 116 | const gchar* bd_part_get_part_table_type_str (BDPartTableType type, GError **error); 117 | const gchar* bd_part_get_type_str (BDPartType type, GError **error); 118 | 119 | #endif /* BD_PART */ 120 | -------------------------------------------------------------------------------- /src/plugins/s390.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_S390 5 | #define BD_S390 6 | 7 | GQuark bd_s390_error_quark (void); 8 | #define BD_S390_ERROR bd_s390_error_quark () 9 | typedef enum { 10 | BD_S390_ERROR_TECH_UNAVAIL, 11 | BD_S390_ERROR_DEVICE, 12 | BD_S390_ERROR_FORMAT_FAILED, 13 | BD_S390_ERROR_DASDFMT, 14 | BD_S390_ERROR_IO, 15 | } BDS390Error; 16 | 17 | typedef enum { 18 | BD_S390_TECH_DASD = 0, 19 | BD_S390_TECH_ZFCP, 20 | } BDS390Tech; 21 | 22 | typedef enum { 23 | BD_S390_TECH_MODE_MODIFY = 1 << 0, 24 | BD_S390_TECH_MODE_QUERY = 1 << 1, 25 | } BDS390TechMode; 26 | 27 | /* 28 | * If using the plugin as a standalone library, the following functions should 29 | * be called to: 30 | * 31 | * init() - initialize the plugin, returning TRUE on success 32 | * close() - clean after the plugin at the end or if no longer used 33 | * 34 | */ 35 | gboolean bd_s390_init (void); 36 | void bd_s390_close (void); 37 | 38 | gboolean bd_s390_is_tech_avail (BDS390Tech tech, guint64 mode, GError **error); 39 | 40 | gboolean bd_s390_dasd_format (const gchar *dasd, const BDExtraArg **extra, GError **error); 41 | gboolean bd_s390_dasd_needs_format (const gchar *dasd, GError **error); 42 | gboolean bd_s390_dasd_online (const gchar *dasd, GError **error); 43 | gboolean bd_s390_dasd_is_ldl (const gchar *dasd, GError **error); 44 | gboolean bd_s390_dasd_is_fba (const gchar *dasd, GError **error); 45 | 46 | gchar* bd_s390_sanitize_dev_input (const gchar *dev, GError **error); 47 | 48 | gchar* bd_s390_zfcp_sanitize_wwpn_input (const gchar *wwpn, GError **error); 49 | gchar* bd_s390_zfcp_sanitize_lun_input (const gchar *lun, GError **error); 50 | gboolean bd_s390_zfcp_online (const gchar *devno, const gchar *wwpn, const gchar *lun, GError **error); 51 | gboolean bd_s390_zfcp_scsi_offline(const gchar *devno, const gchar *wwpn, const gchar *lun, GError **error); 52 | gboolean bd_s390_zfcp_offline(const gchar *devno, const gchar *wwpn, const gchar *lun, GError **error); 53 | 54 | #endif /* BD_S390 */ 55 | -------------------------------------------------------------------------------- /src/plugins/smart/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = subdir-objects 2 | 3 | lib_LTLIBRARIES = 4 | libincludedir = $(includedir)/blockdev 5 | 6 | if WITH_SMART 7 | libinclude_HEADERS = smart.h 8 | else 9 | if WITH_SMARTMONTOOLS 10 | libinclude_HEADERS = smart.h 11 | endif 12 | endif 13 | 14 | 15 | if WITH_SMART 16 | 17 | lib_LTLIBRARIES += libbd_smart.la 18 | 19 | libbd_smart_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(SMART_CFLAGS) $(DRIVEDB_H_CFLAGS) -Wall -Wextra -Werror 20 | libbd_smart_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(SMART_LIBS) 21 | libbd_smart_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 22 | libbd_smart_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ -I. -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 23 | 24 | libbd_smart_la_SOURCES = \ 25 | smart.h \ 26 | smart-private.h \ 27 | smart-common.c \ 28 | drivedb-parser.c \ 29 | libatasmart.c \ 30 | ../check_deps.c \ 31 | ../check_deps.h 32 | 33 | endif 34 | 35 | 36 | if WITH_SMARTMONTOOLS 37 | 38 | lib_LTLIBRARIES += libbd_smartmontools.la 39 | 40 | libbd_smartmontools_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(JSON_GLIB_CFLAGS) $(DRIVEDB_H_CFLAGS) -Wall -Wextra -Werror 41 | libbd_smartmontools_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(JSON_GLIB_LIBS) 42 | libbd_smartmontools_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' 43 | libbd_smartmontools_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ -I. -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 44 | 45 | libbd_smartmontools_la_SOURCES = \ 46 | smart.h \ 47 | smart-private.h \ 48 | smart-common.c \ 49 | drivedb-parser.c \ 50 | smartmontools.c \ 51 | ../check_deps.c \ 52 | ../check_deps.h 53 | 54 | endif 55 | -------------------------------------------------------------------------------- /src/plugins/swap.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_SWAP 5 | #define BD_SWAP 6 | 7 | GQuark bd_swap_error_quark (void); 8 | #define BD_SWAP_ERROR bd_swap_error_quark () 9 | typedef enum { 10 | BD_SWAP_ERROR_TECH_UNAVAIL, 11 | BD_SWAP_ERROR_UNKNOWN_STATE, 12 | BD_SWAP_ERROR_ACTIVATE, 13 | BD_SWAP_ERROR_ACTIVATE_OLD, 14 | BD_SWAP_ERROR_ACTIVATE_SUSPEND, 15 | BD_SWAP_ERROR_ACTIVATE_UNKNOWN, 16 | BD_SWAP_ERROR_ACTIVATE_PAGESIZE, 17 | BD_SWAP_ERROR_LABEL_INVALID, 18 | BD_SWAP_ERROR_UUID_INVALID, 19 | } BDSwapError; 20 | 21 | typedef enum { 22 | BD_SWAP_TECH_SWAP = 0, 23 | } BDSwapTech; 24 | 25 | typedef enum { 26 | BD_SWAP_TECH_MODE_CREATE = 1 << 0, 27 | BD_SWAP_TECH_MODE_ACTIVATE_DEACTIVATE = 1 << 1, 28 | BD_SWAP_TECH_MODE_QUERY = 1 << 2, 29 | BD_SWAP_TECH_MODE_SET_LABEL = 1 << 3, 30 | BD_SWAP_TECH_MODE_SET_UUID = 1 << 3, 31 | } BDSwapTechMode; 32 | 33 | /* 34 | * If using the plugin as a standalone library, the following functions should 35 | * be called to: 36 | * 37 | * init() - initialize the plugin, returning TRUE on success 38 | * close() - clean after the plugin at the end or if no longer used 39 | * 40 | */ 41 | gboolean bd_swap_init (void); 42 | void bd_swap_close (void); 43 | 44 | gboolean bd_swap_is_tech_avail (BDSwapTech tech, guint64 mode, GError **error); 45 | 46 | gboolean bd_swap_mkswap (const gchar *device, const gchar *label, const gchar *uuid, const BDExtraArg **extra, GError **error); 47 | gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error); 48 | gboolean bd_swap_swapoff (const gchar *device, GError **error); 49 | gboolean bd_swap_swapstatus (const gchar *device, GError **error); 50 | gboolean bd_swap_set_label (const gchar *device, const gchar *label, GError **error); 51 | gboolean bd_swap_check_label (const gchar *label, GError **error); 52 | gboolean bd_swap_set_uuid (const gchar *device, const gchar *uuid, GError **error); 53 | gboolean bd_swap_check_uuid (const gchar *uuid, GError **error); 54 | 55 | #endif /* BD_SWAP */ 56 | -------------------------------------------------------------------------------- /src/python/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = gi 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /src/python/gi/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = overrides 2 | 3 | MAINTAINERCLEANFILES = Makefile.in 4 | -------------------------------------------------------------------------------- /src/python/gi/overrides/Makefile.am: -------------------------------------------------------------------------------- 1 | if WITH_PYTHON3 2 | py3libdir = $(shell python3 -c "import sysconfig; print(sysconfig.get_path('platlib', vars={'platbase': '${exec_prefix}'}))") 3 | py3overridesdir = $(py3libdir)/gi/overrides 4 | dist_py3overrides_DATA = BlockDev.py 5 | endif 6 | 7 | dist_noinst_SOURCES = __init__.py 8 | 9 | MAINTAINERCLEANFILES = Makefile.in 10 | -------------------------------------------------------------------------------- /src/utils/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libbd_utils.la 2 | libbd_utils_la_CFLAGS = $(GLIB_CFLAGS) $(UDEV_CFLAGS) $(KMOD_CFLAGS) -Wall -Wextra -Werror 3 | libbd_utils_la_LDFLAGS = -version-info 3:0:0 -Wl,--no-undefined 4 | libbd_utils_la_LIBADD = $(GLIB_LIBS) -lm $(GIO_LIBS) $(UDEV_LIBS) $(KMOD_LIBS) 5 | libbd_utils_la_SOURCES = utils.h exec.c exec.h sizes.h extra_arg.c extra_arg.h dev_utils.c dev_utils.h module.c module.h dbus.c dbus.h logging.c logging.h 6 | 7 | libincludedir = $(includedir)/blockdev 8 | libinclude_HEADERS = utils.h exec.h sizes.h extra_arg.h dev_utils.h module.h dbus.h logging.h 9 | 10 | pkgconfigdir = $(libdir)/pkgconfig 11 | pkgconfig_DATA = ${builddir}/blockdev-utils.pc 12 | 13 | MAINTAINERCLEANFILES = Makefile.in 14 | -------------------------------------------------------------------------------- /src/utils/blockdev-utils.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | includedir=@includedir@ 4 | libdir=@libdir@ 5 | 6 | Name: BlockDev-utils 7 | Description: A library with utility functions used by the libblockdev library 8 | URL: https://github.com/storaged-project/libblockdev 9 | Version: @VERSION@ 10 | Requires: glib-2.0 11 | Libs: -L${libdir} -lbd_utils 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /src/utils/dbus.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "dbus.h" 24 | 25 | #define DBUS_TOP_IFACE "org.freedesktop.DBus" 26 | #define DBUS_TOP_OBJ "/org/freedesktop/DBus" 27 | #define DBUS_PROPS_IFACE "org.freedesktop.DBus.Properties" 28 | #define DBUS_INTRO_IFACE "org.freedesktop.DBus.Introspectable" 29 | 30 | 31 | /** 32 | * bd_utils_dbus_error_quark: (skip) 33 | */ 34 | GQuark bd_utils_dbus_error_quark (void) 35 | { 36 | return g_quark_from_static_string ("g-bd-utils-dbus-error-quark"); 37 | } 38 | 39 | /** 40 | * bd_utils_dbus_service_available: 41 | * @connection: (nullable): existing GDBusConnection or %NULL 42 | * @bus_type: bus type (system or session), ignored if @connection is specified 43 | * @bus_name: name of the service to check (e.g. "com.redhat.lvmdbus1") 44 | * @obj_prefix: object path prefix for the service (e.g. "/com/redhat/lvmdbus1") 45 | * @error: (out) (optional): place to store error (if any) 46 | * 47 | * Returns: whether the service was found in the system 48 | */ 49 | gboolean bd_utils_dbus_service_available (GDBusConnection *connection, GBusType bus_type, const gchar *bus_name, const gchar *obj_prefix, GError **error) { 50 | GVariant *ret = NULL; 51 | GVariant *real_ret = NULL; 52 | GVariantIter iter; 53 | GVariant *service = NULL; 54 | gboolean found = FALSE; 55 | GDBusConnection *bus = NULL; 56 | 57 | if (connection) 58 | bus = g_object_ref (connection); 59 | else { 60 | bus = g_bus_get_sync (bus_type, NULL, error); 61 | if (!bus) { 62 | g_prefix_error (error, "Failed to get system bus: "); 63 | return FALSE; 64 | } 65 | 66 | ret = g_dbus_connection_call_sync (bus, DBUS_TOP_IFACE, DBUS_TOP_OBJ, DBUS_TOP_IFACE, 67 | "ListNames", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 68 | -1, NULL, error); 69 | if (!ret) { 70 | g_object_unref (bus); 71 | return FALSE; 72 | } 73 | } 74 | 75 | real_ret = g_variant_get_child_value (ret, 0); 76 | g_variant_unref (ret); 77 | 78 | g_variant_iter_init (&iter, real_ret); 79 | while (!found && (service = g_variant_iter_next_value (&iter))) { 80 | found = (g_strcmp0 (g_variant_get_string (service, NULL), bus_name) == 0); 81 | g_variant_unref (service); 82 | } 83 | g_variant_unref (real_ret); 84 | 85 | ret = g_dbus_connection_call_sync (bus, DBUS_TOP_IFACE, DBUS_TOP_OBJ, DBUS_TOP_IFACE, 86 | "ListActivatableNames", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 87 | -1, NULL, error); 88 | if (!ret) { 89 | g_object_unref (bus); 90 | return FALSE; 91 | } 92 | 93 | real_ret = g_variant_get_child_value (ret, 0); 94 | g_variant_unref (ret); 95 | 96 | g_variant_iter_init (&iter, real_ret); 97 | while (!found && (service = g_variant_iter_next_value (&iter))) { 98 | found = (g_strcmp0 (g_variant_get_string (service, NULL), bus_name) == 0); 99 | g_variant_unref (service); 100 | } 101 | g_variant_unref (real_ret); 102 | 103 | if (!found) { 104 | g_object_unref (bus); 105 | return FALSE; 106 | } 107 | 108 | /* try to introspect the root node - i.e. check we can access it and possibly 109 | autostart the service */ 110 | ret = g_dbus_connection_call_sync (bus, bus_name, obj_prefix, DBUS_INTRO_IFACE, 111 | "Introspect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 112 | -1, NULL, error); 113 | if (!ret) { 114 | g_object_unref (bus); 115 | return FALSE; 116 | } 117 | 118 | g_variant_unref (ret); 119 | g_object_unref (bus); 120 | return TRUE; 121 | } 122 | -------------------------------------------------------------------------------- /src/utils/dbus.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_UTILS_DBUS 5 | #define BD_UTILS_DBUS 6 | 7 | GQuark bd_utils_dbus_error_quark (void); 8 | #define BD_UTILS_DBUS_ERROR bd_utils_dbus_error_quark () 9 | typedef enum { 10 | BD_UTILS_DBUS_ERROR_FAIL, 11 | BD_UTILS_DBUS_ERROR_NOEXIST, 12 | } BDUtilsDBusError; 13 | 14 | gboolean bd_utils_dbus_service_available (GDBusConnection *connection, GBusType bus_type, const gchar *bus_name, const gchar *obj_prefix, GError **error); 15 | 16 | #endif /* BD_UTILS_DBUS */ 17 | -------------------------------------------------------------------------------- /src/utils/dev_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vratislav Podzimek 18 | */ 19 | 20 | #include 21 | 22 | #ifndef BD_UTILS_DEV_UTILS 23 | #define BD_UTILS_DEV_UTILS 24 | 25 | GQuark bd_utils_dev_utils_error_quark (void); 26 | #define BD_UTILS_DEV_UTILS_ERROR bd_utils_dev_utils_error_quark () 27 | 28 | typedef enum { 29 | BD_UTILS_DEV_UTILS_ERROR_FAILED, 30 | } BDUtilsDevUtilsError; 31 | 32 | gchar* bd_utils_resolve_device (const gchar *dev_spec, GError **error); 33 | gchar** bd_utils_get_device_symlinks (const gchar *dev_spec, GError **error); 34 | 35 | #endif /* BD_UTILS_DEV_UTILS */ 36 | -------------------------------------------------------------------------------- /src/utils/exec.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "extra_arg.h" 3 | 4 | #ifndef BD_UTILS_EXEC 5 | #define BD_UTILS_EXEC 6 | 7 | typedef enum { 8 | BD_UTILS_PROG_STARTED, 9 | BD_UTILS_PROG_PROGRESS, 10 | BD_UTILS_PROG_FINISHED, 11 | } BDUtilsProgStatus; 12 | 13 | /** 14 | * BDUtilsProgFunc: 15 | * @task_id: ID of the task/action the progress is reported for 16 | * @status: progress status 17 | * @completion: percentage of completion 18 | * @msg: (nullable): arbitrary progress message (for the user) 19 | */ 20 | typedef void (*BDUtilsProgFunc) (guint64 task_id, BDUtilsProgStatus status, guint8 completion, gchar *msg); 21 | 22 | /** 23 | * BDUtilsProgExtract: 24 | * @line: line to extract progress from 25 | * @completion: (out): percentage of completion 26 | * 27 | * Callback function used to process a line captured from spawned command's standard 28 | * output and standard error output. Typically used to extract completion percentage 29 | * of a long-running job. 30 | * 31 | * Note that both outputs are read simultaneously with no guarantees of message order 32 | * this function is called with. 33 | * 34 | * The value the @completion points to may contain value previously returned from 35 | * this callback or zero when called for the first time. This is useful for extractors 36 | * where only some kind of a tick mark is printed out as a progress and previous value 37 | * is needed to compute an incremented value. It's important to keep in mind that this 38 | * function is only called over lines, i.e. progress reporting printing out tick marks 39 | * (e.g. dots) without a newline character might not work properly. 40 | * 41 | * The @line string usually contains trailing newline character, which may be absent 42 | * however in case the spawned command exits without printing one. It's guaranteed 43 | * this function is called over remaining buffer no matter what the trailing 44 | * character is. 45 | * 46 | * Returns: whether the line was a progress reporting line and should be excluded 47 | * from the collected standard output string or not. 48 | */ 49 | typedef gboolean (*BDUtilsProgExtract) (const gchar *line, guint8 *completion); 50 | 51 | GQuark bd_utils_exec_error_quark (void); 52 | #define BD_UTILS_EXEC_ERROR bd_utils_exec_error_quark () 53 | typedef enum { 54 | BD_UTILS_EXEC_ERROR_FAILED, 55 | BD_UTILS_EXEC_ERROR_NOOUT, 56 | BD_UTILS_EXEC_ERROR_INVAL_VER, 57 | BD_UTILS_EXEC_ERROR_UTIL_UNAVAILABLE, 58 | BD_UTILS_EXEC_ERROR_UTIL_UNKNOWN_VER, 59 | BD_UTILS_EXEC_ERROR_UTIL_LOW_VER, 60 | BD_UTILS_EXEC_ERROR_UTIL_CHECK_ERROR, 61 | BD_UTILS_EXEC_ERROR_UTIL_FEATURE_CHECK_ERROR, 62 | BD_UTILS_EXEC_ERROR_UTIL_FEATURE_UNAVAILABLE, 63 | } BDUtilsExecError; 64 | 65 | gboolean bd_utils_exec_and_report_error (const gchar **argv, const BDExtraArg **extra, GError **error); 66 | gboolean bd_utils_exec_and_report_error_no_progress (const gchar **argv, const BDExtraArg **extra, GError **error); 67 | gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtraArg **extra, gint *status, GError **error); 68 | gboolean bd_utils_exec_and_capture_output (const gchar **argv, const BDExtraArg **extra, gchar **output, GError **error); 69 | gboolean bd_utils_exec_and_capture_output_no_progress (const gchar **argv, const BDExtraArg **extra, gchar **output, gchar **stderr, gint *status, GError **error); 70 | gboolean bd_utils_exec_and_report_progress (const gchar **argv, const BDExtraArg **extra, BDUtilsProgExtract prog_extract, gint *proc_status, GError **error); 71 | gboolean bd_utils_exec_with_input (const gchar **argv, const gchar *input, const BDExtraArg **extra, GError **error); 72 | gint bd_utils_version_cmp (const gchar *ver_string1, const gchar *ver_string2, GError **error); 73 | gboolean bd_utils_check_util_version (const gchar *util, const gchar *version, const gchar *version_arg, const gchar *version_regexp, GError **error); 74 | 75 | gboolean bd_utils_init_prog_reporting (BDUtilsProgFunc new_prog_func, GError **error); 76 | gboolean bd_utils_init_prog_reporting_thread (BDUtilsProgFunc new_prog_func, GError **error); 77 | gboolean bd_utils_mute_prog_reporting_thread (GError **error); 78 | gboolean bd_utils_prog_reporting_initialized (void); 79 | guint64 bd_utils_report_started (const gchar *msg); 80 | void bd_utils_report_progress (guint64 task_id, guint64 completion, const gchar *msg); 81 | void bd_utils_report_finished (guint64 task_id, const gchar *msg); 82 | 83 | guint64 bd_utils_get_next_task_id (void); 84 | void bd_utils_log_task_status (guint64 task_id, const gchar *msg); 85 | 86 | gboolean bd_utils_echo_str_to_file (const gchar *str, const gchar *file_path, GError **error); 87 | 88 | #endif /* BD_UTILS_EXEC */ 89 | -------------------------------------------------------------------------------- /src/utils/extra_arg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "extra_arg.h" 5 | 6 | /** 7 | * bd_extra_arg_copy: 8 | * @arg: (nullable): %BDExtraArg to copy 9 | * 10 | * Creates a new copy of @arg. 11 | */ 12 | BDExtraArg* bd_extra_arg_copy (BDExtraArg *arg) { 13 | if (arg == NULL) 14 | return NULL; 15 | 16 | BDExtraArg *ret = g_new0 (BDExtraArg, 1); 17 | ret->opt = g_strdup (arg->opt); 18 | ret->val = g_strdup (arg->val); 19 | 20 | return ret; 21 | } 22 | 23 | /** 24 | * bd_extra_arg_free: 25 | * @arg: (nullable): %BDExtraArg to free 26 | * 27 | * Frees @arg. 28 | */ 29 | void bd_extra_arg_free (BDExtraArg *arg) { 30 | if (arg == NULL) 31 | return; 32 | 33 | g_free (arg->opt); 34 | g_free (arg->val); 35 | g_free (arg); 36 | } 37 | 38 | /** 39 | * bd_extra_arg_list_free: 40 | * @args: (nullable) (array zero-terminated=1): A list of %BDExtraArg to free 41 | * 42 | * Frees @args and all its elements. 43 | */ 44 | void bd_extra_arg_list_free (BDExtraArg **args) { 45 | BDExtraArg **a; 46 | 47 | if (args == NULL) 48 | return; 49 | 50 | for (a = args; *a; a++) 51 | bd_extra_arg_free (*a); 52 | g_free (args); 53 | } 54 | 55 | GType bd_extra_arg_get_type (void) { 56 | static GType type = 0; 57 | 58 | if (G_UNLIKELY (!type)) 59 | type = g_boxed_type_register_static ("BDExtraArg", 60 | (GBoxedCopyFunc) bd_extra_arg_copy, 61 | (GBoxedFreeFunc) bd_extra_arg_free); 62 | 63 | return type; 64 | } 65 | 66 | /** 67 | * bd_extra_arg_new: (constructor) 68 | * @opt: extra option 69 | * @val: value for the extra option @opt 70 | * 71 | * Example of calling bd_fs_xfs_mkfs() with an extra argument. 72 | * This will result in calling `mkfs.xfs` with `-L label`. 73 | * 74 | * |[ 75 | * BDExtraArg label_arg = {"-L", "label"}; 76 | * const BDExtraArg *extra_args[2] = {&label_arg, NULL}; 77 | * 78 | * ret = bd_fs_xfs_mkfs ("/dev/sda", extra_args, error); 79 | * 80 | * ]| 81 | * 82 | * Returns: (transfer full): a new extra argument 83 | */ 84 | BDExtraArg* bd_extra_arg_new (const gchar *opt, const gchar *val) { 85 | BDExtraArg *ret = g_new0 (BDExtraArg, 1); 86 | ret->opt = g_strdup (opt ? opt : ""); 87 | ret->val = g_strdup (val ? val : ""); 88 | 89 | return ret; 90 | } 91 | -------------------------------------------------------------------------------- /src/utils/extra_arg.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_UTILS_EXTRA_ARG 5 | #define BD_UTILS_EXTRA_ARG 6 | 7 | #define BD_UTIL_TYPE_EXTRA_ARG (bd_extra_arg_get_type ()) 8 | GType bd_extra_arg_get_type (void); 9 | 10 | /** 11 | * BDExtraArg: 12 | * @opt: extra option (command line option for most functions that allow extra options 13 | * to be passed, e.g. "-L" to call `mkfs.xfs -L`) 14 | * @val: value for @opt, can be an empty string or %NULL for options without parameter 15 | * 16 | * See bd_extra_arg_new() for an example on how to construct the extra args. 17 | */ 18 | typedef struct BDExtraArg { 19 | gchar *opt; 20 | gchar *val; 21 | } BDExtraArg; 22 | 23 | BDExtraArg* bd_extra_arg_copy (BDExtraArg *arg); 24 | void bd_extra_arg_free (BDExtraArg *arg); 25 | void bd_extra_arg_list_free (BDExtraArg **args); 26 | BDExtraArg* bd_extra_arg_new (const gchar *opt, const gchar *val); 27 | 28 | #endif /* BD_UTILS_EXTRA_ARG */ 29 | -------------------------------------------------------------------------------- /src/utils/logging.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Red Hat, Inc. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "logging.h" 25 | 26 | static BDUtilsLogFunc log_func = &bd_utils_log_stdout; 27 | 28 | #ifdef DEBUG 29 | static int log_level = BD_UTILS_LOG_DEBUG; 30 | #else 31 | static int log_level = BD_UTILS_LOG_WARNING; 32 | #endif 33 | 34 | /** 35 | * bd_utils_init_logging: 36 | * @new_log_func: (nullable) (scope notified): logging function to use or 37 | * %NULL to disable logging; use 38 | * #bd_utils_log_stdout to reset to 39 | * the default behaviour 40 | * @error: (out) (optional): place to store error (if any) 41 | * 42 | * Returns: whether logging was successfully initialized or not 43 | */ 44 | gboolean bd_utils_init_logging (BDUtilsLogFunc new_log_func, GError **error G_GNUC_UNUSED) { 45 | /* XXX: the error attribute will likely be used in the future when this 46 | function gets more complicated */ 47 | 48 | log_func = new_log_func; 49 | 50 | return TRUE; 51 | } 52 | 53 | /** 54 | * bd_utils_set_log_level: 55 | * @level: log level 56 | * 57 | * Level of messages to log. Only messages with level <= @level will be logged. 58 | * For example using with #BD_UTILS_LOG_WARNING (default value) only messages 59 | * with log levels #BD_UTILS_LOG_WARNING, #BD_UTILS_LOG_ERR, ..., #BD_UTILS_LOG_EMERG 60 | * will be logged. 61 | * 62 | * Note: #BD_UTILS_LOG_DEBUG level messages are always skipped unless compiled 63 | * with `--enable-debug` configure option. 64 | */ 65 | void bd_utils_set_log_level (gint level) { 66 | log_level = level; 67 | } 68 | 69 | /** 70 | * bd_utils_log: 71 | * @level: log level 72 | * @msg: log message 73 | */ 74 | void bd_utils_log (gint level, const gchar *msg) { 75 | if (log_func && level <= log_level) 76 | log_func (level, msg); 77 | } 78 | 79 | /** 80 | * bd_utils_log_format: 81 | * @level: log level 82 | * @format: printf-style format for the log message 83 | * @...: arguments for @format 84 | */ 85 | void bd_utils_log_format (gint level, const gchar *format, ...) { 86 | gchar *msg = NULL; 87 | va_list args; 88 | gint ret = 0; 89 | 90 | if (log_func && level <= log_level) { 91 | va_start (args, format); 92 | ret = g_vasprintf (&msg, format, args); 93 | va_end (args); 94 | 95 | if (ret < 0) { 96 | g_free (msg); 97 | return; 98 | } 99 | 100 | log_func (level, msg); 101 | } 102 | 103 | g_free (msg); 104 | } 105 | 106 | /** 107 | * bd_utils_log_stdout: 108 | * @level: log level 109 | * @msg: log message 110 | * 111 | * Convenient function for logging to stdout. Can be used as #BDUtilsLogFunc. 112 | * 113 | */ 114 | void bd_utils_log_stdout (gint level, const gchar *msg) { 115 | if (level > log_level) 116 | return; 117 | 118 | switch (level) { 119 | case BD_UTILS_LOG_DEBUG: 120 | #ifdef DEBUG 121 | g_debug ("%s", msg); 122 | #endif 123 | break; 124 | case BD_UTILS_LOG_INFO: 125 | case BD_UTILS_LOG_NOTICE: 126 | g_info ("%s", msg); 127 | break; 128 | case BD_UTILS_LOG_WARNING: 129 | case BD_UTILS_LOG_ERR: 130 | g_warning ("%s", msg); 131 | break; 132 | case BD_UTILS_LOG_EMERG: 133 | case BD_UTILS_LOG_ALERT: 134 | case BD_UTILS_LOG_CRIT: 135 | g_critical ("%s", msg); 136 | break; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/utils/logging.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef BD_UTILS_LOGGING 5 | #define BD_UTILS_LOGGING 6 | 7 | /* These are same as syslog levels, unfortunately GObject Introspection 8 | * doesn't work with "redefined" constants so we can't use syslog 9 | * constants here. 10 | */ 11 | #define BD_UTILS_LOG_EMERG 0 12 | #define BD_UTILS_LOG_ALERT 1 13 | #define BD_UTILS_LOG_CRIT 2 14 | #define BD_UTILS_LOG_ERR 3 15 | #define BD_UTILS_LOG_WARNING 4 16 | #define BD_UTILS_LOG_NOTICE 5 17 | #define BD_UTILS_LOG_INFO 6 18 | #define BD_UTILS_LOG_DEBUG 7 19 | 20 | /** 21 | * BDUtilsLogFunc: 22 | * @level: log level (as understood by syslog(3)) 23 | * @msg: log message 24 | * 25 | * Function type for logging function used by the libblockdev's exec utils to 26 | * log the information about program executing. 27 | */ 28 | typedef void (*BDUtilsLogFunc) (gint level, const gchar *msg); 29 | 30 | gboolean bd_utils_init_logging (BDUtilsLogFunc new_log_func, GError **error); 31 | 32 | void bd_utils_set_log_level (gint level); 33 | 34 | void bd_utils_log (gint level, const gchar *msg); 35 | void bd_utils_log_format (gint level, const gchar *format, ...) G_GNUC_PRINTF (2, 3); 36 | void bd_utils_log_stdout (gint level, const gchar *msg); 37 | 38 | #endif /* BD_UTILS_LOGGING */ 39 | -------------------------------------------------------------------------------- /src/utils/module.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_UTILS_MODULE 4 | #define BD_UTILS_MODULE 5 | 6 | GQuark bd_utils_module_error_quark (void); 7 | #define BD_UTILS_MODULE_ERROR bd_utils_module_error_quark () 8 | typedef enum { 9 | BD_UTILS_MODULE_ERROR_KMOD_INIT_FAIL, 10 | BD_UTILS_MODULE_ERROR_FAIL, 11 | BD_UTILS_MODULE_ERROR_NOEXIST, 12 | BD_UTILS_MODULE_ERROR_MODULE_CHECK_ERROR, 13 | BD_UTILS_MODULE_ERROR_INVALID_PLATFORM, 14 | } BDUtilsModuleError; 15 | 16 | typedef struct { 17 | guint major; 18 | guint minor; 19 | guint micro; 20 | } BDUtilsLinuxVersion; 21 | 22 | gboolean bd_utils_have_kernel_module (const gchar *module_name, GError **error); 23 | gboolean bd_utils_load_kernel_module (const gchar *module_name, const gchar *options, GError **error); 24 | gboolean bd_utils_unload_kernel_module (const gchar *module_name, GError **error); 25 | 26 | BDUtilsLinuxVersion * bd_utils_get_linux_version (GError **error); 27 | gint bd_utils_check_linux_version (guint major, guint minor, guint micro); 28 | 29 | #endif /* BD_UTILS_MODULE */ 30 | -------------------------------------------------------------------------------- /src/utils/sizes.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef BD_UTILS_SIZES 4 | #define BD_UTILS_SIZES 5 | 6 | #define KIBIBYTE *1024ULL 7 | #define MEBIBYTE *1024ULL KIBIBYTE 8 | #define GIBIBYTE *1024ULL MEBIBYTE 9 | #define TEBIBYTE *1024ULL GIBIBYTE 10 | #define PEBIBYTE *1024ULL TEBIBYTE 11 | #define EXBIBYTE *1024ULL PEBIBYTE 12 | 13 | #define KiB KIBIBYTE 14 | #define MiB MEBIBYTE 15 | #define GiB GIBIBYTE 16 | #define TiB TEBIBYTE 17 | #define PiB PEBIBYTE 18 | #define EiB EXBIBYTE 19 | 20 | #define KILOBYTE *1000ULL 21 | #define MEGABYTE *1000ULL KILOBYTE 22 | #define GIGABYTE *1000ULL MEGABYTE 23 | #define TERABYTE *1000ULL GIGABYTE 24 | #define PETABYTE *1000ULL TERABYTE 25 | #define EXABYTE *1000ULL PETABYTE 26 | 27 | #define KB KILOBYTE 28 | #define MB MEGABYTE 29 | #define GB GIGABYTE 30 | #define TB TERABYTE 31 | #define PB PETABYTE 32 | #define EB EXABYTE 33 | 34 | #endif /* BD_UTILS_SIZES */ 35 | -------------------------------------------------------------------------------- /src/utils/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef BD_UTILS 2 | #define BD_UTILS 3 | 4 | #include "sizes.h" 5 | #include "exec.h" 6 | #include "extra_arg.h" 7 | #include "dev_utils.h" 8 | #include "module.h" 9 | #include "dbus.h" 10 | #include "logging.h" 11 | 12 | /** 13 | * SECTION: utils 14 | * @short_description: library providing utility functions used by the blockdev library and its plugins 15 | * @title: Utils 16 | * @include: utils.h 17 | */ 18 | 19 | #endif /* BD_UTILS */ 20 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | # Generate config.h.py with translated defines for easy use within Python 2 | 3 | CONFIG_H_PY = config_h.py 4 | PLUGINS = 5 | 6 | if WITH_BTRFS 7 | PLUGINS += btrfs 8 | endif 9 | 10 | if WITH_CRYPTO 11 | PLUGINS += crypto 12 | endif 13 | 14 | if WITH_DM 15 | PLUGINS += dm 16 | endif 17 | 18 | if WITH_LOOP 19 | PLUGINS += loop 20 | endif 21 | 22 | if WITH_LVM 23 | PLUGINS += lvm 24 | endif 25 | 26 | if WITH_LVM_DBUS 27 | PLUGINS += lvm-dbus 28 | endif 29 | 30 | if WITH_MDRAID 31 | PLUGINS += mdraid 32 | endif 33 | 34 | if WITH_MPATH 35 | PLUGINS += mpath 36 | endif 37 | 38 | if WITH_SWAP 39 | PLUGINS += swap 40 | endif 41 | 42 | if WITH_PART 43 | PLUGINS += part 44 | endif 45 | 46 | if WITH_FS 47 | PLUGINS += fs 48 | endif 49 | 50 | if WITH_NVDIMM 51 | PLUGINS += nvdimm 52 | endif 53 | 54 | if WITH_NVME 55 | PLUGINS += nvme 56 | endif 57 | 58 | if WITH_SMART 59 | PLUGINS += smart 60 | endif 61 | 62 | if WITH_SMARTMONTOOLS 63 | PLUGINS += smartmontools 64 | endif 65 | 66 | if WITH_TOOLS 67 | PLUGINS += tools 68 | endif 69 | 70 | $(CONFIG_H_PY): 71 | echo -n 'ENABLED_PLUGINS = [ ' > $(CONFIG_H_PY) 72 | for i in $(PLUGINS); do \ 73 | echo -n "'$$i', " >> $(CONFIG_H_PY); \ 74 | done 75 | echo ']' >> $(CONFIG_H_PY) 76 | 77 | all: $(CONFIG_H_PY) 78 | 79 | EXTRA_DIST = 80 | 81 | clean-local: 82 | rm -f *~ $(CONFIG_H_PY) 83 | -------------------------------------------------------------------------------- /tests/README.rst: -------------------------------------------------------------------------------- 1 | See the chapter `Testing libblockdev' in the docs/ directory or on-line at 2 | http://storaged.org/libblockdev/ 3 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import gi.overrides 2 | gi.overrides.__path__.insert(0, "src/python") 3 | -------------------------------------------------------------------------------- /tests/bitlk-images.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/bitlk-images.tar.gz -------------------------------------------------------------------------------- /tests/fake_utils/btrfs_low_version/btrfs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat </dev/null 4 | is_detail=$? 5 | 6 | echo "$@"|grep -- "--brief" &>/dev/null 7 | is_brief=$? 8 | 9 | echo "$@"|grep -- "--export" &>/dev/null 10 | is_export=$? 11 | 12 | if [ $is_detail -eq 0 ]; then 13 | cat </dev/null 4 | is_brief=$? 5 | 6 | echo "$@"|grep -- "--export" &>/dev/null 7 | is_export=$? 8 | 9 | if [ $is_brief -eq 0 ]; then 10 | cat </dev/null 4 | is_brief=$? 5 | 6 | echo "$@"|grep -- "--export" &>/dev/null 7 | is_export=$? 8 | 9 | if [ $is_brief -eq 0 ]; then 10 | cat </dev/null 4 | is_brief=$? 5 | 6 | if [ $is_brief -eq 0 ]; then 7 | cat </dev/null 4 | is_dash_version=$? 5 | 6 | echo "$@"|grep "version" &>/dev/null 7 | is_version=$? 8 | 9 | if [ $is_dash_version -eq "0" ]; then 10 | echo "1.0" 11 | elif [ $is_version -eq "0" ]; then 12 | echo "Version: 1.1" 13 | else 14 | echo "Version: 1.2" 15 | fi 16 | -------------------------------------------------------------------------------- /tests/fake_utils/utils_fake_util/libblockdev-fake-util-fail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Version: 1.1" 4 | exit 1 5 | -------------------------------------------------------------------------------- /tests/fake_utils/utils_fake_util/libblockdev-fake-util-stderr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Version: 1.1" 1>&2 4 | -------------------------------------------------------------------------------- /tests/fs_tests/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append("..") 3 | 4 | import overrides_hack 5 | 6 | from .exfat_test import * 7 | from .ext_test import * 8 | from .f2fs_test import * 9 | from .generic_test import * 10 | from .mount_test import * 11 | from .nilfs_test import * 12 | from .ntfs_test import * 13 | from .vfat_test import * 14 | from .xfs_test import * 15 | from .btrfs_test import * 16 | from .udf_test import * 17 | -------------------------------------------------------------------------------- /tests/fvault2-images.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/fvault2-images.tar.gz -------------------------------------------------------------------------------- /tests/mpath_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os 3 | import overrides_hack 4 | import shutil 5 | 6 | from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, get_version, TestTags, tag_test, required_plugins 7 | 8 | import gi 9 | gi.require_version('GLib', '2.0') 10 | gi.require_version('BlockDev', '3.0') 11 | from gi.repository import GLib, BlockDev 12 | 13 | 14 | @required_plugins(("mpath",)) 15 | class MpathTest(unittest.TestCase): 16 | 17 | requested_plugins = BlockDev.plugin_specs_from_names(("mpath",)) 18 | 19 | @classmethod 20 | def setUpClass(cls): 21 | if not BlockDev.is_initialized(): 22 | BlockDev.init(cls.requested_plugins, None) 23 | else: 24 | BlockDev.reinit(cls.requested_plugins, True, None) 25 | 26 | 27 | class MpathTestCase(MpathTest): 28 | def setUp(self): 29 | self.addCleanup(self._clean_up) 30 | self.dev_file = create_sparse_tempfile("mpath_test", 1024**3) 31 | try: 32 | self.loop_dev = create_lio_device(self.dev_file) 33 | except RuntimeError as e: 34 | raise RuntimeError("Failed to setup loop device for testing: %s" % e) 35 | 36 | def _clean_up(self): 37 | try: 38 | delete_lio_device(self.loop_dev) 39 | except RuntimeError: 40 | # just move on, we can do no better here 41 | pass 42 | os.unlink(self.dev_file) 43 | 44 | def test_is_mpath_member(self): 45 | """Verify that is_mpath_member works as expected""" 46 | 47 | # just test that some non-mpath is not reported as a multipath member 48 | # device and no error is reported 49 | self.assertFalse(BlockDev.mpath_is_mpath_member("/dev/loop0")) 50 | 51 | class MpathNoDevTestCase(MpathTest): 52 | @tag_test(TestTags.NOSTORAGE) 53 | def test_plugin_version(self): 54 | self.assertEqual(BlockDev.get_plugin_soname(BlockDev.Plugin.MPATH), "libbd_mpath.so.3") 55 | 56 | @tag_test(TestTags.NOSTORAGE) 57 | def test_get_mpath_members(self): 58 | """Verify that get_mpath_members works as expected""" 59 | ret = BlockDev.mpath_get_mpath_members() 60 | self.assertIsNotNone(ret) 61 | 62 | @tag_test(TestTags.NOSTORAGE) 63 | def test_set_friendly_names(self): 64 | """Verify that set_friendly_names works as expected""" 65 | if not shutil.which('mpathconf'): 66 | self.skipTest("skipping The 'mpathconf' utility is not available") 67 | else: 68 | succ = BlockDev.mpath_set_friendly_names(True) 69 | self.assertTrue(succ) 70 | 71 | 72 | class MpathDepsTest(MpathTest): 73 | @tag_test(TestTags.NOSTORAGE) 74 | def test_missing_dependencies(self): 75 | """Verify that checking for technology support works as expected""" 76 | 77 | with fake_utils("tests/fake_utils/mpath_low_version/"): 78 | with self.assertRaisesRegex(GLib.GError, "Too low version of multipath"): 79 | BlockDev.mpath_is_tech_avail(BlockDev.MpathTech.BASE, BlockDev.MpathTechMode.QUERY) 80 | 81 | with fake_path(all_but="multipath"): 82 | with self.assertRaisesRegex(GLib.GError, "The 'multipath' utility is not available"): 83 | BlockDev.mpath_is_tech_avail(BlockDev.MpathTech.BASE, BlockDev.MpathTechMode.QUERY) 84 | 85 | with fake_path(all_but="mpathconf"): 86 | # "base" should be available without mpathconf 87 | avail = BlockDev.mpath_is_tech_avail(BlockDev.MpathTech.BASE, BlockDev.MpathTechMode.QUERY) 88 | self.assertTrue(avail) 89 | 90 | with self.assertRaisesRegex(GLib.GError, "The 'mpathconf' utility is not available"): 91 | BlockDev.mpath_is_tech_avail(BlockDev.MpathTech.FRIENDLY_NAMES, BlockDev.MpathTechMode.MODIFY) 92 | -------------------------------------------------------------------------------- /tests/overrides_hack.py: -------------------------------------------------------------------------------- 1 | import os 2 | import gi.overrides 3 | 4 | if 'LIBBLOCKDEV_TESTS_SKIP_OVERRIDE' not in os.environ and \ 5 | not gi.overrides.__path__[0].endswith("src/python/gi/overrides"): 6 | local_overrides = None 7 | # our overrides don't take precedence, let's fix it 8 | for i, path in enumerate(gi.overrides.__path__): 9 | if path.endswith("src/python/gi/overrides"): 10 | local_overrides = path 11 | 12 | gi.overrides.__path__.remove(local_overrides) 13 | gi.overrides.__path__.insert(0, local_overrides) 14 | -------------------------------------------------------------------------------- /tests/s390_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os 3 | import overrides_hack 4 | 5 | from utils import fake_path, TestTags, tag_test, required_plugins 6 | 7 | import gi 8 | gi.require_version('GLib', '2.0') 9 | gi.require_version('BlockDev', '3.0') 10 | from gi.repository import GLib, BlockDev 11 | 12 | @unittest.skipUnless(os.uname()[4].startswith('s390'), "s390x architecture required") 13 | @required_plugins(("s390",)) 14 | class S390TestCase(unittest.TestCase): 15 | 16 | requested_plugins = BlockDev.plugin_specs_from_names(("s390",)) 17 | 18 | @classmethod 19 | def setUpClass(cls): 20 | 21 | if not BlockDev.is_initialized(): 22 | BlockDev.init(cls.requested_plugins, None) 23 | else: 24 | BlockDev.reinit(cls.requested_plugins, True, None) 25 | 26 | @tag_test(TestTags.NOSTORAGE) 27 | def test_plugin_version(self): 28 | self.assertEqual(BlockDev.get_plugin_soname(BlockDev.Plugin.S390), "libbd_s390.so.3") 29 | 30 | @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) 31 | def test_device_input(self): 32 | """Verify that s390_sanitize_dev_input works as expected""" 33 | dev = "1234" 34 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), '0.0.' + dev) 35 | 36 | dev = "123456" 37 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), '0.0.' + dev) 38 | 39 | # the device number is padded on the left with 0s up to 4 digits 40 | dev = "123.abc" 41 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), "0.0.0abc") 42 | dev = "abc" 43 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), "0.0.0abc") 44 | dev = ".abc" 45 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), "0.0.0abc") 46 | 47 | # a complete number is unchanged 48 | dev = "0.0.abcd" 49 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), dev) 50 | 51 | # a too long number doesn't mean a crash no matter if it makes sense 52 | dev = "0.0.abcdefgh" 53 | self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), dev) 54 | 55 | @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) 56 | def test_wwpn_input(self): 57 | """Verify that s390_zfcp_sanitize_wwpn_input works as expected""" 58 | # missing "0x" from beginning of wwpn; this should be added by fx 59 | wwpn = "01234567abcdefab" 60 | self.assertEqual(BlockDev.s390_zfcp_sanitize_wwpn_input(wwpn), "0x01234567abcdefab") 61 | # this should be fine as-is 62 | wwpn = "0x01234567abcdefab" 63 | self.assertEqual(BlockDev.s390_zfcp_sanitize_wwpn_input(wwpn), wwpn) 64 | 65 | # too short 66 | wwpn = "a" 67 | with self.assertRaises(GLib.GError): 68 | BlockDev.s390_zfcp_sanitize_wwpn_input(wwpn) 69 | 70 | @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) 71 | def test_lun_input(self): 72 | """Verify that s390_zfcp_sanitize_lun_input works as expected""" 73 | # user does not prepend lun with "0x"; this should get added 74 | lun = "01234567abcdefab" 75 | self.assertEqual(BlockDev.s390_zfcp_sanitize_lun_input(lun), "0x01234567abcdefab") 76 | # a user enters a lun that is between 0 and 16 chars long (non-inclusive); 0 padding should be added to expand to 16 77 | lun = "0x123" 78 | self.assertEqual(BlockDev.s390_zfcp_sanitize_lun_input(lun), "0x0123000000000000") 79 | lun = "0x12345" 80 | self.assertEqual(BlockDev.s390_zfcp_sanitize_lun_input(lun), "0x1234500000000000") 81 | lun = "0x123456" 82 | self.assertEqual(BlockDev.s390_zfcp_sanitize_lun_input(lun), "0x1234560000000000") 83 | # this should be fine as-is 84 | lun = "0x1234567800000000" 85 | self.assertEqual(BlockDev.s390_zfcp_sanitize_lun_input(lun), lun) 86 | 87 | # too long 88 | lun = "12345678901234567890" 89 | with self.assertRaises(GLib.GError): 90 | BlockDev.s390_zfcp_sanitize_lun_input(lun) 91 | 92 | 93 | @unittest.skipUnless(os.uname()[4].startswith('s390'), "s390x architecture required") 94 | class S390DepsTest(unittest.TestCase): 95 | 96 | requested_plugins = BlockDev.plugin_specs_from_names(("s390",)) 97 | 98 | @classmethod 99 | def setUpClass(cls): 100 | 101 | if not BlockDev.is_initialized(): 102 | BlockDev.init(cls.requested_plugins, None) 103 | else: 104 | BlockDev.reinit(cls.requested_plugins, True, None) 105 | 106 | @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) 107 | def test_missing_dependencies(self): 108 | """Verify that checking for technology support works as expected""" 109 | 110 | with fake_path(all_but="dasdfmt"): 111 | # dasdfmt is not available, so the s390 plugin should fail to load 112 | with self.assertRaisesRegex(GLib.GError, "The 'dasdfmt' utility is not available"): 113 | BlockDev.s390_is_tech_avail(BlockDev.S390Tech.DASD, BlockDev.S390TechMode.MODIFY) 114 | -------------------------------------------------------------------------------- /tests/skip.yml: -------------------------------------------------------------------------------- 1 | # List of tests to be skipped 2 | # 3 | # Example: 4 | # This will skip the 'test_mount_ntfs' test case on Debian 10 5 | # and on all 32bit machines 6 | # 7 | ################################### 8 | # - test: fs_test.MountTest.test_mount_ntfs 9 | # skip_on: 10 | # - distro: "debian" 11 | # version: "10" 12 | # reason: "NTFS mounting is broken on Debian testing" 13 | # 14 | # - arch: "i686" 15 | # reason: "testing skipping from config file" 16 | ################################### 17 | # 18 | # Notes: 19 | # - multiple combinations of reasons are supported. 20 | # - 'reason' and at least one of 'distro', 'version' and 'arch' is required 21 | # - 'test' (ID of the test case) can be specified as a regular expression 22 | # for example 'mpath_test.MpathUnloadTest.*' to skip all mpath unload tests 23 | # - all "skips" can specified as a list, for example 'version: [10, 11]' 24 | 25 | --- 26 | 27 | - test: mdraid_test.MDTestAddRemove.test_add_remove 28 | skip_on: 29 | - distro: "debian" 30 | reason: "Removing spare disks from an array is broken on Debian" 31 | 32 | - test: nvdimm_test.NVDIMMNoDevTest.test_supported_sector_sizes 33 | skip_on: 34 | - arch: "i686" 35 | reason: "Lists of 64bit integers are broken on i686 with GI" 36 | 37 | - test: fs_tests.mount_test.MountTestCase.test_mount_ntfs 38 | skip_on: 39 | - distro: "debian" 40 | reason: "mount.ntfs-3g randomly hangs on Debian testing" 41 | 42 | - test: lvm_dbus_tests.LvmTestLVsnapshots.test_snapshotcreate_lvorigin_snapshotmerge 43 | skip_on: 44 | - distro: "centos" 45 | version: "9" 46 | reason: "snapshot merge doesn't work on CentOS 9 Stream with LVM DBus API" 47 | 48 | - test: (lvm_test|lvm_dbus_tests).LvmPVVGLVWritecacheAttachDetachTestCase 49 | skip_on: 50 | - arch: "i686" 51 | reason: "Cache attach/detach fails with ENOMEM on 32bit systems" 52 | 53 | - test: (lvm_test|lvm_dbus_tests).LVMVDOTest 54 | skip_on: 55 | - distro: "debian" 56 | arch: "i686" 57 | reason: "vdo userspace tools are not available on 32bit Debian" 58 | 59 | - test: lvm_dbus_tests.LvmTestPartialLVs 60 | skip_on: 61 | - reason: "LVM DBus doesn't support LV repair yet" 62 | 63 | - test: (lvm_test|lvm_dbus_tests).LvmNoDevTestCase.test_lvm_config 64 | skip_on: 65 | - distro: "debian" 66 | version: "12" 67 | reason: "LVM >= 2.03.17 needed for LVM config parsing with --valuesonly" 68 | 69 | - test: nvdimm_test 70 | skip_on: 71 | - distro: ["fedora", "centos", "debian"] 72 | reason: "NVDIMM plugin is deprecated" 73 | -------------------------------------------------------------------------------- /tests/smart_dumps/05_empty.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/05_empty.json -------------------------------------------------------------------------------- /tests/smart_dumps/Biwintech_SSD_SX500.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/Biwintech_SSD_SX500.bin -------------------------------------------------------------------------------- /tests/smart_dumps/GIGABYTE_GP-GSTFS31100TNTD.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/GIGABYTE_GP-GSTFS31100TNTD.bin -------------------------------------------------------------------------------- /tests/smart_dumps/HGST_HUSMR3280ASS200.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.18.18-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "-a", 17 | "--json", 18 | "/dev/sdc" 19 | ], 20 | "exit_status": 0 21 | }, 22 | "local_time": { 23 | "time_t": 1661183098, 24 | "asctime": "Mon Aug 22 11:44:58 2022 EDT" 25 | }, 26 | "device": { 27 | "name": "/dev/sdc", 28 | "info_name": "/dev/sdc", 29 | "type": "scsi", 30 | "protocol": "SCSI" 31 | }, 32 | "scsi_vendor": "HGST", 33 | "scsi_product": "HUSMR3280ASS200", 34 | "scsi_model_name": "HGST HUSMR3280ASS200", 35 | "scsi_revision": "J172", 36 | "scsi_version": "SPC-4", 37 | "user_capacity": { 38 | "blocks": 1562824368, 39 | "bytes": 800166076416 40 | }, 41 | "logical_block_size": 512, 42 | "scsi_lb_provisioning": { 43 | "name": "resource provisioned", 44 | "value": 1, 45 | "management_enabled": { 46 | "name": "LBPME", 47 | "value": 1 48 | }, 49 | "read_zeros": { 50 | "name": "LBPRZ", 51 | "value": 1 52 | } 53 | }, 54 | "rotation_rate": 0, 55 | "form_factor": { 56 | "scsi_value": 3, 57 | "name": "2.5 inches" 58 | }, 59 | "logical_unit_id": "0x5000ccaccaccacca", 60 | "serial_number": "74747474X", 61 | "device_type": { 62 | "scsi_terminology": "Peripheral Device Type [PDT]", 63 | "scsi_value": 0, 64 | "name": "disk" 65 | }, 66 | "scsi_transport_protocol": { 67 | "name": "SAS (SPL-4)", 68 | "value": 6 69 | }, 70 | "smart_support": { 71 | "available": true, 72 | "enabled": true 73 | }, 74 | "temperature_warning": { 75 | "enabled": false 76 | }, 77 | "smart_status": { 78 | "passed": true 79 | }, 80 | "scsi_percentage_used_endurance_indicator": 0, 81 | "temperature": { 82 | "current": 27, 83 | "drive_trip": 60 84 | }, 85 | "power_on_time": { 86 | "hours": 4596, 87 | "minutes": 24 88 | }, 89 | "scsi_start_stop_cycle_counter": { 90 | "year_of_manufacture": "2019", 91 | "week_of_manufacture": "43", 92 | "specified_cycle_count_over_device_lifetime": 0, 93 | "accumulated_start_stop_cycles": 0, 94 | "specified_load_unload_count_over_device_lifetime": 0, 95 | "accumulated_load_unload_cycles": 0 96 | }, 97 | "scsi_error_counter_log": { 98 | "read": { 99 | "errors_corrected_by_eccfast": 0, 100 | "errors_corrected_by_eccdelayed": 0, 101 | "errors_corrected_by_rereads_rewrites": 0, 102 | "total_errors_corrected": 0, 103 | "correction_algorithm_invocations": 0, 104 | "gigabytes_processed": "48.639", 105 | "total_uncorrected_errors": 0 106 | }, 107 | "write": { 108 | "errors_corrected_by_eccfast": 0, 109 | "errors_corrected_by_eccdelayed": 0, 110 | "errors_corrected_by_rereads_rewrites": 0, 111 | "total_errors_corrected": 0, 112 | "correction_algorithm_invocations": 0, 113 | "gigabytes_processed": "2473.166", 114 | "total_uncorrected_errors": 0 115 | }, 116 | "verify": { 117 | "errors_corrected_by_eccfast": 0, 118 | "errors_corrected_by_eccdelayed": 0, 119 | "errors_corrected_by_rereads_rewrites": 0, 120 | "total_errors_corrected": 0, 121 | "correction_algorithm_invocations": 0, 122 | "gigabytes_processed": "7.988", 123 | "total_uncorrected_errors": 0 124 | } 125 | }, 126 | "scsi_self_test_0": { 127 | "code": { 128 | "value": 2, 129 | "string": "Background long" 130 | }, 131 | "result": { 132 | "value": 0, 133 | "string": "Completed" 134 | }, 135 | "power_on_time": { 136 | "hours": 1, 137 | "aka": "accumulated_power_on_hours" 138 | } 139 | }, 140 | "scsi_self_test_1": { 141 | "code": { 142 | "value": 1, 143 | "string": "Background short" 144 | }, 145 | "result": { 146 | "value": 0, 147 | "string": "Completed" 148 | }, 149 | "power_on_time": { 150 | "hours": 1, 151 | "aka": "accumulated_power_on_hours" 152 | } 153 | }, 154 | "scsi_extended_self_test_seconds": 1320 155 | } 156 | -------------------------------------------------------------------------------- /tests/smart_dumps/Hitachi_HDS721010CLA632.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/Hitachi_HDS721010CLA632.bin -------------------------------------------------------------------------------- /tests/smart_dumps/IBM_IC25N020ATCS04-0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/IBM_IC25N020ATCS04-0.bin -------------------------------------------------------------------------------- /tests/smart_dumps/KINGSTON_SA400S37240G_SBFK71B1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/KINGSTON_SA400S37240G_SBFK71B1.bin -------------------------------------------------------------------------------- /tests/smart_dumps/KINGSTON_SA400S37480G_SBFKQ13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/KINGSTON_SA400S37480G_SBFKQ13.bin -------------------------------------------------------------------------------- /tests/smart_dumps/Maxtor_6Y120P0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/Maxtor_6Y120P0.bin -------------------------------------------------------------------------------- /tests/smart_dumps/Patriot_Burst_240GB.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/Patriot_Burst_240GB.bin -------------------------------------------------------------------------------- /tests/smart_dumps/SAMSUNG_HS122JC.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/SAMSUNG_HS122JC.bin -------------------------------------------------------------------------------- /tests/smart_dumps/SAMSUNG_MMCRE28G5MXP-0VBH1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/SAMSUNG_MMCRE28G5MXP-0VBH1.bin -------------------------------------------------------------------------------- /tests/smart_dumps/SEAGATE_ST600MP0036.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.18.18-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "-a", 17 | "--json", 18 | "/dev/sdb" 19 | ], 20 | "exit_status": 0 21 | }, 22 | "local_time": { 23 | "time_t": 1661183078, 24 | "asctime": "Mon Aug 22 11:44:38 2022 EDT" 25 | }, 26 | "device": { 27 | "name": "/dev/sdb", 28 | "info_name": "/dev/sdb", 29 | "type": "scsi", 30 | "protocol": "SCSI" 31 | }, 32 | "scsi_vendor": "SEAGATE", 33 | "scsi_product": "ST600MP0036", 34 | "scsi_model_name": "SEAGATE ST600MP0036", 35 | "scsi_revision": "KT3A", 36 | "scsi_version": "SPC-4", 37 | "user_capacity": { 38 | "blocks": 1172123568, 39 | "bytes": 600127266816 40 | }, 41 | "logical_block_size": 512, 42 | "scsi_protection_type": 2, 43 | "scsi_protection_interval_bytes_per_lb": 8, 44 | "scsi_lb_provisioning": { 45 | "name": "fully provisioned", 46 | "value": 0, 47 | "management_enabled": { 48 | "name": "LBPME", 49 | "value": 0 50 | }, 51 | "read_zeros": { 52 | "name": "LBPRZ", 53 | "value": 0 54 | } 55 | }, 56 | "rotation_rate": 15000, 57 | "form_factor": { 58 | "scsi_value": 3, 59 | "name": "2.5 inches" 60 | }, 61 | "logical_unit_id": "0x5000c50accaccacc", 62 | "serial_number": "WAF1ABCD", 63 | "device_type": { 64 | "scsi_terminology": "Peripheral Device Type [PDT]", 65 | "scsi_value": 0, 66 | "name": "disk" 67 | }, 68 | "scsi_transport_protocol": { 69 | "name": "SAS (SPL-4)", 70 | "value": 6 71 | }, 72 | "smart_support": { 73 | "available": true, 74 | "enabled": true 75 | }, 76 | "temperature_warning": { 77 | "enabled": false 78 | }, 79 | "smart_status": { 80 | "passed": true 81 | }, 82 | "scsi_format_status": { 83 | "total_new_block_since_format": 0 84 | }, 85 | "temperature": { 86 | "current": 29, 87 | "drive_trip": 60 88 | }, 89 | "power_on_time": { 90 | "hours": 4665, 91 | "minutes": 46 92 | }, 93 | "scsi_start_stop_cycle_counter": { 94 | "year_of_manufacture": "2019", 95 | "week_of_manufacture": "50", 96 | "specified_cycle_count_over_device_lifetime": 10000, 97 | "accumulated_start_stop_cycles": 1090, 98 | "specified_load_unload_count_over_device_lifetime": 300000, 99 | "accumulated_load_unload_cycles": 1181 100 | }, 101 | "scsi_grown_defect_list": 0, 102 | "scsi_error_counter_log": { 103 | "read": { 104 | "errors_corrected_by_eccfast": 170693715, 105 | "errors_corrected_by_eccdelayed": 0, 106 | "errors_corrected_by_rereads_rewrites": 0, 107 | "total_errors_corrected": 170693715, 108 | "correction_algorithm_invocations": 0, 109 | "gigabytes_processed": "88.818", 110 | "total_uncorrected_errors": 0 111 | }, 112 | "write": { 113 | "errors_corrected_by_eccfast": 0, 114 | "errors_corrected_by_eccdelayed": 0, 115 | "errors_corrected_by_rereads_rewrites": 0, 116 | "total_errors_corrected": 0, 117 | "correction_algorithm_invocations": 0, 118 | "gigabytes_processed": "2256.473", 119 | "total_uncorrected_errors": 0 120 | }, 121 | "verify": { 122 | "errors_corrected_by_eccfast": 26102529, 123 | "errors_corrected_by_eccdelayed": 0, 124 | "errors_corrected_by_rereads_rewrites": 0, 125 | "total_errors_corrected": 26102529, 126 | "correction_algorithm_invocations": 0, 127 | "gigabytes_processed": "13.575", 128 | "total_uncorrected_errors": 0 129 | } 130 | }, 131 | "scsi_self_test_0": { 132 | "code": { 133 | "value": 7, 134 | "string": "Reserved(7)" 135 | }, 136 | "result": { 137 | "value": 0, 138 | "string": "Completed" 139 | }, 140 | "failed_segment": { 141 | "value": 64, 142 | "aka": "self_test_number" 143 | }, 144 | "power_on_time": { 145 | "hours": 3, 146 | "aka": "accumulated_power_on_hours" 147 | } 148 | }, 149 | "scsi_self_test_1": { 150 | "code": { 151 | "value": 1, 152 | "string": "Background short" 153 | }, 154 | "result": { 155 | "value": 0, 156 | "string": "Completed" 157 | }, 158 | "failed_segment": { 159 | "value": 96, 160 | "aka": "self_test_number" 161 | }, 162 | "power_on_time": { 163 | "hours": 1, 164 | "aka": "accumulated_power_on_hours" 165 | } 166 | }, 167 | "scsi_extended_self_test_seconds": 3360 168 | } 169 | -------------------------------------------------------------------------------- /tests/smart_dumps/SiliconPower_SSD_SBFM61.3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/SiliconPower_SSD_SBFM61.3.bin -------------------------------------------------------------------------------- /tests/smart_dumps/TOSHIBA_AL15SEB120NY.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.18.18-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "-a", 17 | "--json", 18 | "/dev/sdd" 19 | ], 20 | "exit_status": 0 21 | }, 22 | "local_time": { 23 | "time_t": 1661183115, 24 | "asctime": "Mon Aug 22 11:45:15 2022 EDT" 25 | }, 26 | "device": { 27 | "name": "/dev/sdd", 28 | "info_name": "/dev/sdd", 29 | "type": "scsi", 30 | "protocol": "SCSI" 31 | }, 32 | "scsi_vendor": "TOSHIBA", 33 | "scsi_product": "AL15SEB120NY", 34 | "scsi_model_name": "TOSHIBA AL15SEB120NY", 35 | "scsi_revision": "EF06", 36 | "scsi_version": "SPC-4", 37 | "user_capacity": { 38 | "blocks": 2344225968, 39 | "bytes": 1200243695616 40 | }, 41 | "logical_block_size": 512, 42 | "scsi_protection_type": 2, 43 | "scsi_protection_interval_bytes_per_lb": 8, 44 | "rotation_rate": 10000, 45 | "form_factor": { 46 | "scsi_value": 3, 47 | "name": "2.5 inches" 48 | }, 49 | "logical_unit_id": "0x5000039ccaccacca", 50 | "serial_number": "Z9W012345678", 51 | "device_type": { 52 | "scsi_terminology": "Peripheral Device Type [PDT]", 53 | "scsi_value": 0, 54 | "name": "disk" 55 | }, 56 | "scsi_transport_protocol": { 57 | "name": "SAS (SPL-4)", 58 | "value": 6 59 | }, 60 | "smart_support": { 61 | "available": true, 62 | "enabled": true 63 | }, 64 | "temperature_warning": { 65 | "enabled": false 66 | }, 67 | "smart_status": { 68 | "passed": true 69 | }, 70 | "temperature": { 71 | "current": 24, 72 | "drive_trip": 65 73 | }, 74 | "power_on_time": { 75 | "hours": 4617, 76 | "minutes": 5 77 | }, 78 | "scsi_start_stop_cycle_counter": { 79 | "year_of_manufacture": "2019", 80 | "week_of_manufacture": "51", 81 | "specified_cycle_count_over_device_lifetime": 50000, 82 | "accumulated_start_stop_cycles": 1073, 83 | "specified_load_unload_count_over_device_lifetime": 600000, 84 | "accumulated_load_unload_cycles": 5500 85 | }, 86 | "scsi_grown_defect_list": 0, 87 | "scsi_error_counter_log": { 88 | "read": { 89 | "errors_corrected_by_eccfast": 0, 90 | "errors_corrected_by_eccdelayed": 0, 91 | "errors_corrected_by_rereads_rewrites": 0, 92 | "total_errors_corrected": 0, 93 | "correction_algorithm_invocations": 0, 94 | "gigabytes_processed": "416922.085", 95 | "total_uncorrected_errors": 0 96 | }, 97 | "write": { 98 | "errors_corrected_by_eccfast": 0, 99 | "errors_corrected_by_eccdelayed": 0, 100 | "errors_corrected_by_rereads_rewrites": 0, 101 | "total_errors_corrected": 0, 102 | "correction_algorithm_invocations": 0, 103 | "gigabytes_processed": "2856.904", 104 | "total_uncorrected_errors": 0 105 | }, 106 | "verify": { 107 | "errors_corrected_by_eccfast": 0, 108 | "errors_corrected_by_eccdelayed": 0, 109 | "errors_corrected_by_rereads_rewrites": 0, 110 | "total_errors_corrected": 0, 111 | "correction_algorithm_invocations": 0, 112 | "gigabytes_processed": "20.321", 113 | "total_uncorrected_errors": 0 114 | } 115 | }, 116 | "scsi_self_test_0": { 117 | "code": { 118 | "value": 7, 119 | "string": "Reserved(7)" 120 | }, 121 | "result": { 122 | "value": 0, 123 | "string": "Completed" 124 | }, 125 | "failed_segment": { 126 | "value": 80, 127 | "aka": "self_test_number" 128 | }, 129 | "power_on_time": { 130 | "hours": 3, 131 | "aka": "accumulated_power_on_hours" 132 | } 133 | }, 134 | "scsi_self_test_1": { 135 | "code": { 136 | "value": 1, 137 | "string": "Background short" 138 | }, 139 | "result": { 140 | "value": 0, 141 | "string": "Completed" 142 | }, 143 | "power_on_time": { 144 | "hours": 1, 145 | "aka": "accumulated_power_on_hours" 146 | } 147 | }, 148 | "scsi_extended_self_test_seconds": 6429 149 | } 150 | -------------------------------------------------------------------------------- /tests/smart_dumps/TOSHIBA_AL15SEB18EQY.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.18.18-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "-a", 17 | "--json", 18 | "/dev/sde" 19 | ], 20 | "exit_status": 0 21 | }, 22 | "local_time": { 23 | "time_t": 1661183151, 24 | "asctime": "Mon Aug 22 11:45:51 2022 EDT" 25 | }, 26 | "device": { 27 | "name": "/dev/sde", 28 | "info_name": "/dev/sde", 29 | "type": "scsi", 30 | "protocol": "SCSI" 31 | }, 32 | "scsi_vendor": "TOSHIBA", 33 | "scsi_product": "AL15SEB18EQY", 34 | "scsi_model_name": "TOSHIBA AL15SEB18EQY", 35 | "scsi_revision": "EF06", 36 | "scsi_version": "SPC-4", 37 | "user_capacity": { 38 | "blocks": 3516328368, 39 | "bytes": 1800360124416 40 | }, 41 | "logical_block_size": 512, 42 | "physical_block_size": 4096, 43 | "scsi_protection_type": 2, 44 | "scsi_protection_interval_bytes_per_lb": 8, 45 | "rotation_rate": 10000, 46 | "form_factor": { 47 | "scsi_value": 3, 48 | "name": "2.5 inches" 49 | }, 50 | "logical_unit_id": "0x5000039ccaccacca", 51 | "serial_number": "Y9S012345678", 52 | "device_type": { 53 | "scsi_terminology": "Peripheral Device Type [PDT]", 54 | "scsi_value": 0, 55 | "name": "disk" 56 | }, 57 | "scsi_transport_protocol": { 58 | "name": "SAS (SPL-4)", 59 | "value": 6 60 | }, 61 | "smart_support": { 62 | "available": true, 63 | "enabled": true 64 | }, 65 | "temperature_warning": { 66 | "enabled": false 67 | }, 68 | "smart_status": { 69 | "passed": true 70 | }, 71 | "temperature": { 72 | "current": 25, 73 | "drive_trip": 65 74 | }, 75 | "power_on_time": { 76 | "hours": 4616, 77 | "minutes": 36 78 | }, 79 | "scsi_start_stop_cycle_counter": { 80 | "year_of_manufacture": "2019", 81 | "week_of_manufacture": "48", 82 | "specified_cycle_count_over_device_lifetime": 50000, 83 | "accumulated_start_stop_cycles": 1073, 84 | "specified_load_unload_count_over_device_lifetime": 600000, 85 | "accumulated_load_unload_cycles": 4996 86 | }, 87 | "scsi_grown_defect_list": 0, 88 | "scsi_error_counter_log": { 89 | "read": { 90 | "errors_corrected_by_eccfast": 0, 91 | "errors_corrected_by_eccdelayed": 0, 92 | "errors_corrected_by_rereads_rewrites": 0, 93 | "total_errors_corrected": 0, 94 | "correction_algorithm_invocations": 0, 95 | "gigabytes_processed": "548659.318", 96 | "total_uncorrected_errors": 0 97 | }, 98 | "write": { 99 | "errors_corrected_by_eccfast": 0, 100 | "errors_corrected_by_eccdelayed": 0, 101 | "errors_corrected_by_rereads_rewrites": 0, 102 | "total_errors_corrected": 0, 103 | "correction_algorithm_invocations": 0, 104 | "gigabytes_processed": "3346.357", 105 | "total_uncorrected_errors": 0 106 | }, 107 | "verify": { 108 | "errors_corrected_by_eccfast": 0, 109 | "errors_corrected_by_eccdelayed": 0, 110 | "errors_corrected_by_rereads_rewrites": 0, 111 | "total_errors_corrected": 0, 112 | "correction_algorithm_invocations": 0, 113 | "gigabytes_processed": "24.840", 114 | "total_uncorrected_errors": 0 115 | } 116 | }, 117 | "scsi_self_test_0": { 118 | "code": { 119 | "value": 7, 120 | "string": "Reserved(7)" 121 | }, 122 | "result": { 123 | "value": 0, 124 | "string": "Completed" 125 | }, 126 | "failed_segment": { 127 | "value": 80, 128 | "aka": "self_test_number" 129 | }, 130 | "power_on_time": { 131 | "hours": 3, 132 | "aka": "accumulated_power_on_hours" 133 | } 134 | }, 135 | "scsi_self_test_1": { 136 | "code": { 137 | "value": 1, 138 | "string": "Background short" 139 | }, 140 | "result": { 141 | "value": 0, 142 | "string": "Completed" 143 | }, 144 | "power_on_time": { 145 | "hours": 1, 146 | "aka": "accumulated_power_on_hours" 147 | } 148 | }, 149 | "scsi_extended_self_test_seconds": 8693 150 | } 151 | -------------------------------------------------------------------------------- /tests/smart_dumps/TOSHIBA_KPM5XMUG400G.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.18.18-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "-a", 17 | "--json", 18 | "/dev/sda" 19 | ], 20 | "exit_status": 0 21 | }, 22 | "local_time": { 23 | "time_t": 1661183054, 24 | "asctime": "Mon Aug 22 11:44:14 2022 EDT" 25 | }, 26 | "device": { 27 | "name": "/dev/sda", 28 | "info_name": "/dev/sda", 29 | "type": "scsi", 30 | "protocol": "SCSI" 31 | }, 32 | "scsi_vendor": "TOSHIBA", 33 | "scsi_product": "KPM5XMUG400G", 34 | "scsi_model_name": "TOSHIBA KPM5XMUG400G", 35 | "scsi_revision": "B026", 36 | "scsi_version": "SPC-4", 37 | "user_capacity": { 38 | "blocks": 781422768, 39 | "bytes": 400088457216 40 | }, 41 | "logical_block_size": 512, 42 | "physical_block_size": 4096, 43 | "scsi_lb_provisioning": { 44 | "name": "resource provisioned", 45 | "value": 1, 46 | "management_enabled": { 47 | "name": "LBPME", 48 | "value": 1 49 | }, 50 | "read_zeros": { 51 | "name": "LBPRZ", 52 | "value": 1 53 | } 54 | }, 55 | "rotation_rate": 0, 56 | "form_factor": { 57 | "scsi_value": 3, 58 | "name": "2.5 inches" 59 | }, 60 | "logical_unit_id": "0x58ce38eeeeeeeeee", 61 | "serial_number": "99A012345678", 62 | "device_type": { 63 | "scsi_terminology": "Peripheral Device Type [PDT]", 64 | "scsi_value": 0, 65 | "name": "disk" 66 | }, 67 | "scsi_transport_protocol": { 68 | "name": "SAS (SPL-4)", 69 | "value": 6 70 | }, 71 | "smart_support": { 72 | "available": true, 73 | "enabled": true 74 | }, 75 | "temperature_warning": { 76 | "enabled": false 77 | }, 78 | "smart_status": { 79 | "passed": true 80 | }, 81 | "scsi_percentage_used_endurance_indicator": 0, 82 | "temperature": { 83 | "current": 30, 84 | "drive_trip": 70 85 | }, 86 | "power_on_time": { 87 | "hours": 4665, 88 | "minutes": 12 89 | }, 90 | "scsi_start_stop_cycle_counter": { 91 | "year_of_manufacture": "2019", 92 | "week_of_manufacture": "37" 93 | }, 94 | "scsi_grown_defect_list": 0, 95 | "scsi_error_counter_log": { 96 | "read": { 97 | "errors_corrected_by_eccfast": 0, 98 | "errors_corrected_by_eccdelayed": 0, 99 | "errors_corrected_by_rereads_rewrites": 0, 100 | "total_errors_corrected": 0, 101 | "correction_algorithm_invocations": 0, 102 | "gigabytes_processed": "2295.821", 103 | "total_uncorrected_errors": 0 104 | }, 105 | "write": { 106 | "errors_corrected_by_eccfast": 0, 107 | "errors_corrected_by_eccdelayed": 0, 108 | "errors_corrected_by_rereads_rewrites": 0, 109 | "total_errors_corrected": 0, 110 | "correction_algorithm_invocations": 0, 111 | "gigabytes_processed": "12103.790", 112 | "total_uncorrected_errors": 0 113 | }, 114 | "verify": { 115 | "errors_corrected_by_eccfast": 0, 116 | "errors_corrected_by_eccdelayed": 0, 117 | "errors_corrected_by_rereads_rewrites": 0, 118 | "total_errors_corrected": 0, 119 | "correction_algorithm_invocations": 0, 120 | "gigabytes_processed": "3.995", 121 | "total_uncorrected_errors": 0 122 | } 123 | }, 124 | "scsi_self_test_0": { 125 | "code": { 126 | "value": 2, 127 | "string": "Background long" 128 | }, 129 | "result": { 130 | "value": 0, 131 | "string": "Completed" 132 | }, 133 | "power_on_time": { 134 | "hours": 1, 135 | "aka": "accumulated_power_on_hours" 136 | } 137 | }, 138 | "scsi_self_test_1": { 139 | "code": { 140 | "value": 1, 141 | "string": "Background short" 142 | }, 143 | "result": { 144 | "value": 0, 145 | "string": "Completed" 146 | }, 147 | "power_on_time": { 148 | "hours": 1, 149 | "aka": "accumulated_power_on_hours" 150 | } 151 | }, 152 | "scsi_extended_self_test_seconds": 300 153 | } 154 | -------------------------------------------------------------------------------- /tests/smart_dumps/TOSHIBA_THNSNH128GBST.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/TOSHIBA_THNSNH128GBST.bin -------------------------------------------------------------------------------- /tests/smart_dumps/WD4001FYYG-01SL3.json: -------------------------------------------------------------------------------- 1 | { 2 | "json_format_version": [ 3 | 1, 4 | 0 5 | ], 6 | "smartctl": { 7 | "version": [ 8 | 7, 9 | 3 10 | ], 11 | "svn_revision": "5338", 12 | "platform_info": "x86_64-linux-5.19.11-200.fc36.x86_64", 13 | "build_info": "(local build)", 14 | "argv": [ 15 | "smartctl", 16 | "--info", 17 | "--health", 18 | "--attributes", 19 | "--log=error", 20 | "--log=background", 21 | "--json", 22 | "--device=scsi", 23 | "/dev/sdq" 24 | ], 25 | "exit_status": 0 26 | }, 27 | "local_time": { 28 | "time_t": 1674653346, 29 | "asctime": "Wed Jan 25 08:29:06 2023 EST" 30 | }, 31 | "device": { 32 | "name": "/dev/sdq", 33 | "info_name": "/dev/sdq", 34 | "type": "scsi", 35 | "protocol": "SCSI" 36 | }, 37 | "scsi_vendor": "WD", 38 | "scsi_product": "WD4001FYYG-01SL3", 39 | "scsi_model_name": "WD WD4001FYYG-01SL3", 40 | "scsi_revision": "VR02", 41 | "scsi_version": "SPC-4", 42 | "user_capacity": { 43 | "blocks": 7814037168, 44 | "bytes": 4000787030016 45 | }, 46 | "logical_block_size": 512, 47 | "rotation_rate": 7200, 48 | "form_factor": { 49 | "scsi_value": 2, 50 | "name": "3.5 inches" 51 | }, 52 | "logical_unit_id": "0x50014eeeeeeeeeee", 53 | "serial_number": "WMC1F0123456", 54 | "device_type": { 55 | "scsi_terminology": "Peripheral Device Type [PDT]", 56 | "scsi_value": 0, 57 | "name": "disk" 58 | }, 59 | "scsi_transport_protocol": { 60 | "name": "SAS (SPL-4)", 61 | "value": 6 62 | }, 63 | "smart_support": { 64 | "available": true, 65 | "enabled": false 66 | }, 67 | "temperature_warning": { 68 | "enabled": true 69 | }, 70 | "smart_status": { 71 | "passed": true 72 | }, 73 | "temperature": { 74 | "current": 29, 75 | "drive_trip": 69 76 | }, 77 | "scsi_start_stop_cycle_counter": { 78 | "year_of_manufacture": "2012", 79 | "week_of_manufacture": "01", 80 | "specified_cycle_count_over_device_lifetime": 1048576, 81 | "accumulated_start_stop_cycles": 13, 82 | "specified_load_unload_count_over_device_lifetime": 1114112, 83 | "accumulated_load_unload_cycles": 1 84 | }, 85 | "scsi_grown_defect_list": 0, 86 | "scsi_error_counter_log": { 87 | "read": { 88 | "errors_corrected_by_eccfast": 2, 89 | "errors_corrected_by_eccdelayed": 6, 90 | "errors_corrected_by_rereads_rewrites": 117, 91 | "total_errors_corrected": 8, 92 | "correction_algorithm_invocations": 6, 93 | "gigabytes_processed": "491.518", 94 | "total_uncorrected_errors": 0 95 | }, 96 | "write": { 97 | "errors_corrected_by_eccfast": 0, 98 | "errors_corrected_by_eccdelayed": 0, 99 | "errors_corrected_by_rereads_rewrites": 0, 100 | "total_errors_corrected": 0, 101 | "correction_algorithm_invocations": 0, 102 | "gigabytes_processed": "43.026", 103 | "total_uncorrected_errors": 0 104 | } 105 | }, 106 | "scsi_background_scan": { 107 | "status": { 108 | "value": 0, 109 | "string": "no scans active", 110 | "number_scans_performed": 0, 111 | "scan_progress": "0.00%", 112 | "number_medium_scans_performed": 0 113 | } 114 | }, 115 | "power_on_time": { 116 | "hours": 63318, 117 | "minutes": 32 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /tests/smart_dumps/WDC_WD20EARS-00MVWB0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/smart_dumps/WDC_WD20EARS-00MVWB0.bin -------------------------------------------------------------------------------- /tests/test_configs/default_config/00-default.cfg: -------------------------------------------------------------------------------- 1 | ../../../data/conf.d/00-default.cfg -------------------------------------------------------------------------------- /tests/test_configs/lvm_dbus_config/00-default.cfg: -------------------------------------------------------------------------------- 1 | ../../../data/conf.d/00-default.cfg -------------------------------------------------------------------------------- /tests/test_configs/lvm_dbus_config/10-lvm-dbus.cfg: -------------------------------------------------------------------------------- 1 | ../../../data/conf.d/10-lvm-dbus.cfg -------------------------------------------------------------------------------- /tests/test_configs/plugin_multi_conf.d/00-default.cfg: -------------------------------------------------------------------------------- 1 | # This is the default configuration for the libblockdev library. For 2 | # each supported technology/plugin there is a separate section/group 3 | # with the 'sonames' key. The value of the key has to be a list of 4 | # sonames of shared objects that should be attempted to be loaded for 5 | # the plugin falling back to the next one in the list. 6 | # 7 | # So this example: 8 | # [lvm] 9 | # sonames=libbd_lvm-dbus.so.0;libbd_lvm.so.0 10 | # 11 | # would result in the libbd_lvm-dbus.so.0 shared object attempted to 12 | # be loaded and if that failed, the libbd_lvm.so.0 would be attempted 13 | # to be loaded. 14 | 15 | [btrfs] 16 | sonames=libbd_btrfs.so.3 17 | 18 | [crypto] 19 | sonames=libbd_crypto.so.3 20 | 21 | [dm] 22 | sonames=libbd_dm.so.3 23 | 24 | [loop] 25 | sonames=libbd_loop.so.3 26 | 27 | [lvm] 28 | sonames=libbd_lvm.so.3 29 | 30 | [mdraid] 31 | sonames=libbd_mdraid.so.3 32 | 33 | [mpath] 34 | sonames=libbd_mpath.so.3 35 | 36 | [part] 37 | sonames=libbd_part.so.3 38 | 39 | [swap] 40 | sonames=libbd_swap.so.3 41 | 42 | [s390] 43 | sonames=libbd_s390.so.3 44 | -------------------------------------------------------------------------------- /tests/test_configs/plugin_multi_conf.d/10-lvm2.cfg: -------------------------------------------------------------------------------- 1 | [lvm] 2 | sonames=libbd_lvm2.so.3 3 | -------------------------------------------------------------------------------- /tests/test_configs/plugin_prio_conf.d/00-default.cfg: -------------------------------------------------------------------------------- 1 | # This is the default configuration for the libblockdev library. For 2 | # each supported technology/plugin there is a separate section/group 3 | # with the 'sonames' key. The value of the key has to be a list of 4 | # sonames of shared objects that should be attempted to be loaded for 5 | # the plugin falling back to the next one in the list. 6 | # 7 | # So this example: 8 | # [lvm] 9 | # sonames=libbd_lvm-dbus.so.0;libbd_lvm.so.0 10 | # 11 | # would result in the libbd_lvm-dbus.so.0 shared object attempted to 12 | # be loaded and if that failed, the libbd_lvm.so.0 would be attempted 13 | # to be loaded. 14 | 15 | [btrfs] 16 | sonames=libbd_btrfs.so.3 17 | 18 | [crypto] 19 | sonames=libbd_crypto.so.3 20 | 21 | [dm] 22 | sonames=libbd_dm.so.3 23 | 24 | [loop] 25 | sonames=libbd_loop.so.3 26 | 27 | [lvm] 28 | sonames=libbd_lvm2.so.3;libbd_lvm.so.3 29 | 30 | [mdraid] 31 | sonames=libbd_mdraid.so.3 32 | 33 | [mpath] 34 | sonames=libbd_mpath.so.3 35 | 36 | [part] 37 | sonames=libbd_part.so.3 38 | 39 | [swap] 40 | sonames=libbd_swap.so.3 41 | 42 | [s390] 43 | sonames=libbd_s390.so.3 44 | -------------------------------------------------------------------------------- /tests/truecrypt-images.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storaged-project/libblockdev/d4eaa1bed61a82eec52b2e08132d22ade49a6c11/tests/truecrypt-images.tar.gz -------------------------------------------------------------------------------- /tools/Makefile.am: -------------------------------------------------------------------------------- 1 | if WITH_TOOLS 2 | bin_PROGRAMS = lvm-cache-stats vfat-resize 3 | 4 | lvm_cache_stats_CFLAGS = $(GLIB_CFLAGS) $(BYTESIZE_CFLAGS) -Wall -Wextra -Werror 5 | lvm_cache_stats_CPPFLAGS = -I${builddir}/../include/ 6 | lvm_cache_stats_LDFLAGS = -Wl,--no-undefined 7 | lvm_cache_stats_LDADD = ${builddir}/../src/lib/libblockdev.la $(GLIB_LIBS) $(BYTESIZE_LIBS) 8 | 9 | vfat_resize_CFLAGS = $(GLIB_CFLAGS) $(BYTESIZE_CFLAGS) $(PARTED_CFLAGS) $(PARTED_FS_CFLAGS) -Wall -Wextra -Werror 10 | vfat_resize_CPPFLAGS = -I${builddir}/../include/ 11 | vfat_resize_LDFLAGS = -Wl,--no-undefined 12 | vfat_resize_LDADD = ${builddir}/../src/lib/libblockdev.la $(GLIB_LIBS) $(BYTESIZE_LIBS) $(PARTED_LIBS) $(PARTED_FS_LIBS) $(UUID_LIBS) 13 | endif 14 | -------------------------------------------------------------------------------- /tools/vfat-resize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Red Hat, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | * Author: Vojtech Trefny 18 | * 19 | * This is just a small helper program for (V)FAT filesystem resizing using libparted. 20 | * We don't want this to be part of the library because libparted is licensed under GPLv3 21 | * and we want to keep libblockdev LGPL compatible. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | void print_usage (const char *cmd) { 35 | g_print ("Usage: %s device [size]\n" 36 | "-h --help Print this usage info\n" 37 | "If size is not specified the file system is adapted to the underlying block device\n", 38 | cmd); 39 | } 40 | 41 | PedExceptionOption bd_exc_handler (PedException *ex) { 42 | if (ex->type <= PED_EXCEPTION_WARNING && (ex->options & PED_EXCEPTION_IGNORE) != 0) { 43 | g_print ("[parted] %s\n", ex->message); 44 | return PED_EXCEPTION_IGNORE; 45 | } 46 | g_printerr ("[parted] %s\n",ex->message); 47 | return PED_EXCEPTION_UNHANDLED; 48 | } 49 | 50 | int main (int argc, char *argv[]) { 51 | PedDevice *ped_dev = NULL; 52 | PedGeometry geom = {0}; 53 | PedGeometry new_geom = {0}; 54 | PedFileSystem *fs = NULL; 55 | PedSector start = 0; 56 | PedSector length = 0; 57 | gint status = 0; 58 | guint64 new_size = 0; 59 | BSSize bs_size; 60 | BSError *bs_error = NULL; 61 | gchar *device = NULL; 62 | 63 | if (argc < 2 || g_strcmp0 (argv[1], "-h") == 0 || g_strcmp0 (argv[1], "--help") == 0) { 64 | print_usage (argv[0]); 65 | return 0; 66 | } 67 | 68 | if (argc == 3) { 69 | device = argv[1]; 70 | bs_size = bs_size_new_from_str (argv[2], &bs_error); 71 | if (bs_size) { 72 | new_size = bs_size_get_bytes (bs_size, NULL, &bs_error); 73 | bs_size_free (bs_size); 74 | } 75 | if (bs_error) { 76 | g_printerr ("Failed to parse size from '%s': '%s'\n", argv[2], bs_error->msg); 77 | bs_clear_error (&bs_error); 78 | return 1; 79 | } 80 | } else 81 | device = argv[1]; 82 | 83 | ped_exception_set_handler ((PedExceptionHandler*) bd_exc_handler); 84 | 85 | ped_dev = ped_device_get (device); 86 | if (!ped_dev) { 87 | g_printerr ("Failed to get ped device for the device '%s'\n", device); 88 | return 1; 89 | } 90 | 91 | status = ped_device_open (ped_dev); 92 | if (status == 0) { 93 | g_printerr ("Failed to get open the device '%s'\n", device); 94 | return 1; 95 | } 96 | 97 | status = ped_geometry_init (&geom, ped_dev, start, ped_dev->length); 98 | if (status == 0) { 99 | g_printerr ("Failed to initialize geometry for the device '%s'\n", device); 100 | ped_device_close (ped_dev); 101 | return 1; 102 | } 103 | 104 | fs = ped_file_system_open (&geom); 105 | if (!fs) { 106 | g_printerr ("Failed to read the filesystem on the device '%s'\n", device); 107 | ped_device_close (ped_dev); 108 | return 1; 109 | } 110 | 111 | if (new_size == 0) 112 | length = ped_dev->length; 113 | else 114 | length = (PedSector) ((PedSector) new_size / ped_dev->sector_size); 115 | 116 | status = ped_geometry_init (&new_geom, ped_dev, start, length); 117 | if (status == 0) { 118 | g_printerr ("Failed to initialize new geometry for the filesystem on '%s'\n", device); 119 | ped_file_system_close (fs); 120 | ped_device_close (ped_dev); 121 | return 1; 122 | } 123 | 124 | status = ped_file_system_resize (fs, &new_geom, NULL); 125 | if (status == 0) { 126 | g_printerr ("Failed to resize the filesystem on '%s'\n", device); 127 | ped_file_system_close (fs); 128 | ped_device_close (ped_dev); 129 | return 1; 130 | } 131 | 132 | ped_file_system_close (fs); 133 | ped_device_close (ped_dev); 134 | 135 | return 0; 136 | } 137 | --------------------------------------------------------------------------------