Skip to content

Conversation

@vojtechtrefny
Copy link
Member

@vojtechtrefny vojtechtrefny commented Dec 1, 2025

This currently allows setting the device as read only and enabling discard for all types of devices supported by cryptsetup.

Fixes: #1138

Summary by CodeRabbit

  • New Features
    • Added flag-based open options for encrypted volumes, enabling read-only mounts and optional discard support across LUKS, TrueCrypt/VeraCrypt, BitLocker and FileVault2 while preserving backward-compatible wrappers.
  • Python API
    • Exposed a new Python wrapper to call the flag-enabled open operations from bindings.
  • Tests
    • Added tests validating flag-based opens, including discard activation and read-only verification.

✏️ Tip: You can customize this high-level summary in your review settings.

@gemini-code-assist
Copy link

Summary of Changes

Hello @vojtechtrefny, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the libblockdev library by introducing a unified mechanism to specify activation flags when opening encrypted devices. This change allows users to explicitly control options such as read-only access and discard support for LUKS, TrueCrypt/VeraCrypt, BitLocker, and FVAULT2 volumes, improving flexibility and functionality for device management.

Highlights

  • New BDCryptoOpenFlags Enum: A new enum, BDCryptoOpenFlags, has been introduced to standardize activation flags for encrypted devices, including ALLOW_DISCARDS and READONLY options.
  • Extended Device Opening Functions: New _flags variants (e.g., bd_crypto_luks_open_flags) have been added for LUKS, TrueCrypt/VeraCrypt, BitLocker, and FVAULT2 device opening functions, allowing explicit control over activation flags.
  • Backward Compatibility: Existing _open functions (e.g., bd_crypto_luks_open) are now wrappers that call their respective _flags counterparts, ensuring no breaking changes for existing API users.
  • Python Bindings Update: The Python API has been updated to expose the new _flags functions, specifically for TrueCrypt, enabling Python users to leverage the new activation flags.
  • Comprehensive Testing: New test cases have been added to validate the correct application of ALLOW_DISCARDS and READONLY flags across various encrypted device types, ensuring robust functionality.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This change adds a new bitfield type BDCryptoOpenFlags and flag-aware open functions for LUKS, TrueCrypt, BitLocker and FileVault2. New _open_flags variants accept allow-discards and readonly flags; existing boolean read_only APIs are retained as wrappers that delegate to the new flag variants. Tests and Python bindings were updated to exercise the new APIs.

Changes

Cohort / File(s) Summary
API Declarations
src/lib/plugin_apis/crypto.api, src/plugins/crypto.h
Added typedef enum { BD_CRYPTO_OPEN_ALLOW_DISCARDS = 1 << 0, BD_CRYPTO_OPEN_READONLY = 1 << 1 } BDCryptoOpenFlags; and declared four new public functions: bd_crypto_luks_open_flags, bd_crypto_tc_open_flags, bd_crypto_bitlk_open_flags, bd_crypto_fvault2_open_flags.
Core Implementation
src/plugins/crypto.c
Implemented _flags variants for the four open functions that accept BDCryptoOpenFlags, map flags to CRYPT_ACTIVATE_* activate flags (ALLOW_DISCARDS, READONLY) and call existing crypt_activate_* APIs. Added backward-compatible wrappers (*_open) that convert the old read_only boolean into flags and delegate to the new variants.
Python Bindings
src/python/gi/overrides/BlockDev.py
Added crypto_tc_open_flags wrapper (with passphrase normalization) and exposed it via __all__; created internal alias _crypto_tc_open_flags mapped to BlockDev.crypto_tc_open_flags.
Documentation
docs/libblockdev-sections.txt
Updated documentation to list the new _open_flags public variants alongside existing open functions and described the new BDCryptoOpenFlags.
Tests
tests/crypto_test.py
Added _is_ro(dm_name) helper, new CryptoTestLuksOpenFlags test class with _luks_open_flags, test_luks_open_flags, test_luks2_open_flags, and extended existing crypto open/close tests (VeraCrypt, BitLocker, FileVault2, TrueCrypt) to exercise open-with-flags behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify flag-to-activate mapping in src/plugins/crypto.c (BD_CRYPTO_OPEN_ALLOW_DISCARDS -> CRYPT_ACTIVATE_ALLOW_DISCARDS; BD_CRYPTO_OPEN_READONLY -> CRYPT_ACTIVATE_READONLY).
  • Ensure wrappers correctly convert the read_only boolean into BDCryptoOpenFlags.
  • Confirm Python binding crypto_tc_open_flags signature, passphrase encoding, and override registration are consistent with other overrides.
  • Review tests (tests/crypto_test.py) for reliable dmsetup use and read-only detection logic.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.28% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding support for activate flags when opening a device, which is the core objective of the PR.
Linked Issues check ✅ Passed The PR fully implements the requirements from #1138: new _open_flags functions are added for all crypto device types, CRYPT_ACTIVATE_ALLOW_DISCARDS flag support is implemented, and READONLY flag support is included.
Out of Scope Changes check ✅ Passed All changes are directly related to adding activate flags functionality. No out-of-scope modifications detected; changes include flag enums, new API functions, implementation, headers, Python overrides, and comprehensive tests.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable enhancement by adding *_open_flags functions, allowing activation flags like READONLY and ALLOW_DISCARDS when opening encrypted devices. The implementation thoughtfully maintains backward compatibility. While the changes are mostly well-tested, I've identified a few issues, including a critical syntax error, a bug in the Python overrides, some documentation mistakes, and opportunities to improve test coverage for the new READONLY flag.

BD_CRYPTO_LUKS_ACTIVATE_HIGH_PRIORITY = 1 << 6,
} BDCryptoLUKSPersistentFlags;

typedef enum {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cryptsetup has just one set of "flags", some of these can be set persistently for LUKS, some can be used for crypt_activate and some for some other functionality. Looking at the BDCryptoLUKSPersistentFlags flags, it might be better to make the flag names more specific for the "persistent flag" use case, but it's too late now and so the BDCryptoOpenFlags flag names might look a bit weird. But if you have a better idea for naming these, I am definitely open to suggestions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me as it is

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/python/gi/overrides/BlockDev.py (1)

347-361: Consider adding *_open_flags wrappers for BitLocker and FileVault2.

The existing crypto_bitlk_open and crypto_fvault2_open wrappers handle passphrase-to-bytes encoding. For consistency, similar wrappers for crypto_bitlk_open_flags and crypto_fvault2_open_flags should be added if they will be called from Python with string passphrases.

Example for BitLocker:

_crypto_bitlk_open_flags = BlockDev.crypto_bitlk_open_flags
@override(BlockDev.crypto_bitlk_open_flags)
def crypto_bitlk_open_flags(device, name, passphrase, flags=0):
    if isinstance(passphrase, str):
        passphrase = passphrase.encode("utf-8")
    return _crypto_bitlk_open_flags(device, name, passphrase, flags)
__all__.append("crypto_bitlk_open_flags")
tests/crypto_test.py (1)

1519-1530: Consider adding READONLY test for VeraCrypt.

The VeraCrypt test only verifies ALLOW_DISCARDS. For consistency with BitLocker and FileVault2 tests, consider testing the READONLY flag as well.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f327bf7 and aa0ca48.

📒 Files selected for processing (6)
  • docs/libblockdev-sections.txt (2 hunks)
  • src/lib/plugin_apis/crypto.api (5 hunks)
  • src/plugins/crypto.c (20 hunks)
  • src/plugins/crypto.h (3 hunks)
  • src/python/gi/overrides/BlockDev.py (1 hunks)
  • tests/crypto_test.py (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/crypto_test.py (2)
src/python/gi/overrides/BlockDev.py (2)
  • CryptoKeyslotContext (284-300)
  • crypto_tc_open_flags (341-344)
tests/utils.py (1)
  • run_command (561-566)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (46)
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_udisks
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_udisks
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_blivet
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_blivet
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_udisks
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_blivet
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: compilation (clang-15)
  • GitHub Check: compilation (gcc-13)
  • GitHub Check: compilation (clang-16)
  • GitHub Check: compilation (clang-18)
  • GitHub Check: compilation (gcc-10)
  • GitHub Check: compilation (gcc-11)
  • GitHub Check: compilation (clang-14)
  • GitHub Check: compilation (clang-17)
  • GitHub Check: compilation (gcc-14)
  • GitHub Check: compilation (gcc-12)
  • GitHub Check: udisks-build
  • GitHub Check: Analyze (cpp)
  • GitHub Check: symbols
  • GitHub Check: Analyze (python)
  • GitHub Check: blivet-tests
  • GitHub Check: csmock
🔇 Additional comments (15)
src/plugins/crypto.h (2)

175-178: LGTM: Flag enum is well-defined.

The BDCryptoOpenFlags enum uses proper bit-shift values for flags, allowing them to be combined with bitwise OR. This aligns with the existing BDCryptoIntegrityOpenFlags pattern in the codebase.


298-298: LGTM: New flag-based open function declarations are consistent.

The new *_open_flags function declarations correctly replace the gboolean read_only parameter with BDCryptoOpenFlags flags, maintaining backward compatibility by keeping the original functions unchanged.

Also applies to: 328-328, 332-332, 336-336

src/python/gi/overrides/BlockDev.py (1)

341-344: Consider: Wrapper uses raw passphrase instead of context object.

The crypto_tc_open_flags wrapper accepts a raw passphrase parameter and encodes it internally. However, looking at the C API (bd_crypto_tc_open_flags), it expects a BDCryptoKeyslotContext. This wrapper may need to construct a context object from the passphrase, similar to CryptoKeyslotContext(passphrase=passphrase).

Verify that passing a raw encoded passphrase works correctly with the underlying GI binding, or consider creating a context object internally.

tests/crypto_test.py (4)

120-127: LGTM: Helper method for read-only state verification.

The _is_ro helper correctly resolves the dm-mapper device path and reads the ro attribute from sysfs to verify read-only state.


714-738: LGTM: Test coverage for LUKS open with flags.

The tests verify that ALLOW_DISCARDS flag correctly enables discard support on the mapped device via dmsetup table inspection.


1631-1644: LGTM: BitLocker open with flags test.

The test correctly verifies both ALLOW_DISCARDS (via dmsetup) and READONLY (via _is_ro) flags work together.


1745-1758: LGTM: FileVault2 open with flags test.

The test correctly verifies both ALLOW_DISCARDS and READONLY flags, consistent with the BitLocker test.

src/lib/plugin_apis/crypto.api (2)

364-367: LGTM: Flag enum definition in API.

The BDCryptoOpenFlags enum is correctly defined with the same values as in the header file.


970-970: LGTM: New flag-based open function declarations.

The API function declarations for bd_crypto_luks_open_flags, bd_crypto_tc_open_flags, bd_crypto_bitlk_open_flags, and bd_crypto_fvault2_open_flags are correctly defined with the BDCryptoOpenFlags parameter.

Also applies to: 1352-1352, 1410-1410, 1453-1453

src/plugins/crypto.c (6)

1264-1374: LGTM! Flag-based activation logic is correct.

The new bd_crypto_luks_open_flags function correctly maps BDCryptoOpenFlags to cryptsetup's activation flags and passes them to all activation code paths (passphrase, keyfile, keyring).


3194-3303: LGTM! TrueCrypt/VeraCrypt flag support is correctly implemented.

The flag conversion logic is consistent with the LUKS implementation and correctly passes activation flags to cryptsetup.


3305-3327: LGTM! Wrapper maintains backward compatibility.

The wrapper correctly delegates to bd_crypto_tc_open_flags with proper flag conversion.


3589-3687: LGTM! BitLocker flag support is correctly implemented.

The implementation is consistent with other device types and correctly handles both passphrase and keyfile activation paths.


3689-3706: LGTM! Wrapper correctly delegates to the flags variant.


3721-3826: LGTM! FileVault2 flag support is correctly implemented.

The implementation properly handles conditional compilation and follows the same pattern as other device types.

@vojtechtrefny vojtechtrefny force-pushed the master_luks-open-flags branch from aa0ca48 to c3415f1 Compare December 2, 2025 11:07
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugins/crypto.c (1)

3721-3851: Missing closing brace in bd_crypto_fvault2_open when LIBCRYPTSETUP_26 is not defined.

In the #ifndef LIBCRYPTSETUP_26 branch of bd_crypto_fvault2_open, the function body is never closed; the only } is inside the #else branch. When compiling without LIBCRYPTSETUP_26, this will produce a syntax error.

You can fix this by adding a closing brace before the #else, so each branch defines a complete function:

 #ifndef LIBCRYPTSETUP_26
 gboolean bd_crypto_fvault2_open (const gchar *device G_GNUC_UNUSED, const gchar *name G_GNUC_UNUSED, BDCryptoKeyslotContext *context G_GNUC_UNUSED,
-                                 gboolean read_only G_GNUC_UNUSED, GError **error) {
-    /* this will return FALSE and set error, because FVAULT2 technology is not available */
-    return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_FVAULT2, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
-#else
+                                 gboolean read_only G_GNUC_UNUSED, GError **error) {
+    /* this will return FALSE and set error, because FVAULT2 technology is not available */
+    return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_FVAULT2, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
+}
+#else
 gboolean bd_crypto_fvault2_open (const gchar *device, const gchar *name, BDCryptoKeyslotContext *context, gboolean read_only, GError **error) {
     return bd_crypto_fvault2_open_flags (device, name, context, read_only ? BD_CRYPTO_OPEN_READONLY : 0, error);
 }
 #endif
♻️ Duplicate comments (1)
src/lib/plugin_apis/crypto.api (1)

947-970: Fix bd_crypto_luks_open_flags documentation example

The example block still says “using %bd_crypto_luks_open” even though it demonstrates bd_crypto_luks_open_flags, and it passes 0 as flags, which doesn’t showcase the new API.

Consider updating the example title and using a real flag, e.g.:

- * Example of using %bd_crypto_luks_open with %BDCryptoKeyslotContext:
+ * Example of using %bd_crypto_luks_open_flags with %BDCryptoKeyslotContext:
@@
- * context = bd_crypto_keyslot_context_new_passphrase ("passphrase", 10, NULL);
- * bd_crypto_luks_open_flags ("/dev/vda1", "luks-device", context, 0, NULL);
+ * context = bd_crypto_keyslot_context_new_passphrase ("passphrase", 10, NULL);
+ * bd_crypto_luks_open_flags ("/dev/vda1", "luks-device", context, BD_CRYPTO_OPEN_READONLY, NULL);

This keeps the example aligned with the function name and better illustrates how to use the flag bitfield.

🧹 Nitpick comments (1)
src/plugins/crypto.c (1)

1265-1401: LUKS _open_flags implementation looks correct; doc example header still names the old function.

The new bd_crypto_luks_open_flags() helper cleanly translates BDCryptoOpenFlags into crypt_flags and reuses the existing activation paths; the wrapper bd_crypto_luks_open() preserves the previous read_only API while delegating to the flags-based variant.

The only nit is in the doc block for bd_crypto_luks_open_flags: the example header still says “Example of using %bd_crypto_luks_open…” even though the example actually calls bd_crypto_luks_open_flags(). Updating that symbol name in the comment would avoid confusion.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa0ca48 and c3415f1.

📒 Files selected for processing (6)
  • docs/libblockdev-sections.txt (2 hunks)
  • src/lib/plugin_apis/crypto.api (5 hunks)
  • src/plugins/crypto.c (20 hunks)
  • src/plugins/crypto.h (3 hunks)
  • src/python/gi/overrides/BlockDev.py (1 hunks)
  • tests/crypto_test.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/libblockdev-sections.txt
  • src/python/gi/overrides/BlockDev.py
🧰 Additional context used
🧬 Code graph analysis (1)
tests/crypto_test.py (2)
src/python/gi/overrides/BlockDev.py (2)
  • CryptoKeyslotContext (284-300)
  • crypto_tc_open_flags (341-344)
tests/utils.py (1)
  • run_command (561-566)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (42)
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_udisks
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_blivet
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: compilation (clang-17)
  • GitHub Check: compilation (clang-18)
  • GitHub Check: compilation (gcc-14)
  • GitHub Check: compilation (clang-15)
  • GitHub Check: compilation (clang-16)
  • GitHub Check: compilation (clang-14)
  • GitHub Check: compilation (gcc-10)
  • GitHub Check: compilation (gcc-13)
  • GitHub Check: compilation (gcc-11)
  • GitHub Check: compilation (gcc-12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (cpp)
  • GitHub Check: blivet-tests
  • GitHub Check: udisks-build
  • GitHub Check: symbols
  • GitHub Check: csmock
🔇 Additional comments (16)
src/lib/plugin_apis/crypto.api (4)

364-367: BDCryptoOpenFlags definition matches usage and header

Enum values for BD_CRYPTO_OPEN_ALLOW_DISCARDS and BD_CRYPTO_OPEN_READONLY are well‑chosen and consistent with other flag enums in this API; no issues from an ABI/API standpoint.


1333-1352: TrueCrypt/VeraCrypt _open_flags API and docs look consistent

The bd_crypto_tc_open_flags prototype, parameter order, and documentation (including @flags and supported context types) are consistent with the rest of the crypto API and with bd_crypto_tc_open.


1396-1411: BitLocker _open_flags API mirrors existing open behavior

bd_crypto_bitlk_open_flags cleanly extends bd_crypto_bitlk_open by replacing the boolean read_only with BDCryptoOpenFlags flags, while keeping context handling and tech category docs consistent.


1439-1453: FileVault2 _open_flags API is consistent with other flag-based opens

bd_crypto_fvault2_open_flags follows the same pattern as the LUKS/TrueCrypt/BitLocker variants; the docs correctly describe @flags and supported context types.

tests/crypto_test.py (5)

120-127: _is_ro helper correctly inspects dm read-only state

Using /sys/block/<dm-name>/ro via the real /dev/mapper/<name> path is a straightforward and reliable way to assert RO status for dm devices; this is appropriate for these tests.


714-742: LUKS _open_flags tests now cover both discards and read-only

CryptoTestLuksOpenFlags exercises both ALLOW_DISCARDS and READONLY, checks dmsetup table for allow_discards, and uses _is_ro to validate read-only state for both LUKS1 and LUKS2. This gives solid coverage of the new flag behavior.


1522-1535: VeraCrypt _open_flags test validates flags end-to-end

The added crypto_tc_open_flags test opens the VeraCrypt volume with ALLOW_DISCARDS | READONLY, then checks dmsetup output and _is_ro("libblockdevTestTC"). This is a good end‑to‑end verification of the new flags for TrueCrypt/VeraCrypt mappings.


1637-1650: BitLocker _open_flags test aligns with feature goals

For BitLocker, the test reuses the existing open/close flow and then re-opens with CryptoOpenFlags.ALLOW_DISCARDS | READONLY, validating both allow_discards in the dm table and the RO state via _is_ro. This correctly exercises the new flags on BITLK devices (gated by HAVE_BITLK).


1751-1764: FileVault2 _open_flags test completes coverage across device types

The FileVault2 test mirrors the BitLocker pattern: open with flags, assert allow_discards and RO state, and cleanly close. Together with the LUKS, TrueCrypt, and BITLK tests, this gives uniform coverage of BDCryptoOpenFlags across all supported techs.

src/plugins/crypto.h (5)

175-178: BDCryptoOpenFlags enum is consistent with public API

BDCryptoOpenFlags here matches the definition in src/lib/plugin_apis/crypto.api (same bits and members), so consumers see a coherent flag type across both plugin and public headers.


296-299: LUKS _open_flags declaration is a clean extension

bd_crypto_luks_open_flags replaces the boolean read_only with BDCryptoOpenFlags flags while keeping the rest of the signature stable, which is a backward‑compatible and predictable evolution of the API.


326-329: TrueCrypt _open_flags prototype matches the documented API

bd_crypto_tc_open_flags mirrors bd_crypto_tc_open’s parameters and simply swaps the read_only boolean for BDCryptoOpenFlags flags at the end, matching the ordering and semantics described in crypto.api.


331-333: BitLocker _open_flags declaration is consistent with existing open

bd_crypto_bitlk_open_flags follows the same pattern as the LUKS and TC variants, preserving the existing calling convention and adding BDCryptoOpenFlags as a drop‑in replacement for read_only.


335-337: FileVault2 _open_flags declaration completes the set

bd_crypto_fvault2_open_flags extends the FileVault2 open API in the same way as the other technologies, keeping consistency across the crypto plugin surface.

src/plugins/crypto.c (2)

3194-3326: TrueCrypt/VeraCrypt _open_flags helper and wrapper are consistent with existing semantics.

bd_crypto_tc_open_flags() properly validates the optional passphrase context, counts keyfiles, maps BDCryptoOpenFlags to an internal crypt_flags bitmask, and then activates via the existing path. bd_crypto_tc_open() now just delegates to the new helper with a read_onlyBD_CRYPTO_OPEN_READONLY mapping, so existing callers retain behavior while gaining the option to use the richer flags API.


3589-3705: BITLK _open_flags plumbing mirrors the LUKS path and keeps the old API intact.

bd_crypto_bitlk_open_flags() follows the same pattern as the LUKS open helper: validate the DM name, load the device, derive crypt_flags from BDCryptoOpenFlags, and reuse the existing passphrase/keyfile activation logic. The bd_crypto_bitlk_open() wrapper’s read_onlyBD_CRYPTO_OPEN_READONLY mapping preserves previous semantics while allowing callers to opt into the new flags-based entry point.

This currently allows setting the device as read only and enabling
discard for all types of devices supported by cryptsetup.

Fixes: storaged-project#1138
@vojtechtrefny vojtechtrefny force-pushed the master_luks-open-flags branch from c3415f1 to 8338945 Compare December 2, 2025 11:19
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
tests/crypto_test.py (1)

714-741: Consider testing flags individually for better coverage.

The test correctly verifies both ALLOW_DISCARDS and READONLY flags together. For more comprehensive coverage, consider adding separate test cases that verify each flag individually:

  • Test with only ALLOW_DISCARDS
  • Test with only READONLY
  • Test with both combined (current implementation)

This would ensure each flag works correctly in isolation and in combination.

src/lib/plugin_apis/crypto.api (1)

947-970: Improve documentation example to demonstrate flag usage.

The documentation example currently passes 0 for the flags parameter, which is valid but doesn't demonstrate the purpose of the new function. Consider showing an actual flag being used to make the example more illustrative:

context = bd_crypto_keyslot_context_new_passphrase ("passphrase", 10, NULL);
bd_crypto_luks_open_flags ("/dev/vda1", "luks-device", context, 
                           BD_CRYPTO_OPEN_READONLY | BD_CRYPTO_OPEN_ALLOW_DISCARDS, NULL);

This would better demonstrate how to use the flags parameter in practice.

src/plugins/crypto.c (3)

1265-1401: LUKS _open_flags implementation looks correct; consider a tiny doc/example tweak and flag helper.

The flag handling and activation calls for bd_crypto_luks_open_flags mirror existing patterns and look correct. Two small, optionally-addressable nits:

  • The example still uses flags = 0; consider demonstrating BD_CRYPTO_OPEN_ALLOW_DISCARDS or BD_CRYPTO_OPEN_READONLY to highlight the new capability.
  • The BDCryptoOpenFlagscrypt_flags mapping is duplicated in other _open_flags functions; a small static helper (e.g. _bd_crypto_open_flags_to_crypt_flags()) would reduce duplication and keep behavior in one place.

3194-3326: TrueCrypt/VeraCrypt _open_flags variant is consistent; only minor reuse opportunity.

bd_crypto_tc_open_flags correctly:

  • Validates the dm name and key material.
  • Preserves existing behavior via crypt_params_tcrypt and crypt_load(CRYPT_TCRYPT, &params).
  • Applies BDCryptoOpenFlags only to the activation step via crypt_activate_by_volume_key.

Same as for LUKS, the local crypt_flags construction is identical in several _open_flags functions; factoring it into a shared helper would simplify future maintenance without changing semantics.


3589-3705: BITLK _open_flags and wrapper maintain existing semantics; flags mapping is fine but duplicated.

bd_crypto_bitlk_open_flags and bd_crypto_bitlk_open:

  • Keep the previous “read-only vs read-write” behavior through the wrapper.
  • Correctly propagate BD_CRYPTO_OPEN_ALLOW_DISCARDS and BD_CRYPTO_OPEN_READONLY to crypt_activate_by_passphrase.

Again, the only repetition is the BDCryptoOpenFlagscrypt_flags conversion, which matches other call sites; extracting a small helper for that mapping would DRY things up.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3415f1 and 8338945.

📒 Files selected for processing (6)
  • docs/libblockdev-sections.txt (2 hunks)
  • src/lib/plugin_apis/crypto.api (5 hunks)
  • src/plugins/crypto.c (20 hunks)
  • src/plugins/crypto.h (3 hunks)
  • src/python/gi/overrides/BlockDev.py (1 hunks)
  • tests/crypto_test.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/libblockdev-sections.txt
  • src/python/gi/overrides/BlockDev.py
🧰 Additional context used
🧬 Code graph analysis (2)
src/plugins/crypto.h (1)
src/plugins/crypto.c (5)
  • bd_crypto_luks_open_flags (1287-1374)
  • bd_crypto_tc_open_flags (3212-3303)
  • bd_crypto_fvault2_open (3843-3847)
  • bd_crypto_fvault2_open (3849-3851)
  • bd_crypto_fvault2_open_flags (3740-3826)
tests/crypto_test.py (2)
src/python/gi/overrides/BlockDev.py (2)
  • CryptoKeyslotContext (284-300)
  • crypto_tc_open_flags (341-344)
tests/utils.py (1)
  • run_command (561-566)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (42)
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_udisks
  • GitHub Check: testing-farm:fedora-43-x86_64:revdeps_blivet
  • GitHub Check: testing-farm:fedora-43-x86_64
  • GitHub Check: testing-farm:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-x86_64
  • GitHub Check: rpm-build:fedora-43-x86_64
  • GitHub Check: rpm-build:fedora-rawhide-aarch64
  • GitHub Check: rpm-build:fedora-43-aarch64
  • GitHub Check: rpm-build:fedora-rawhide-ppc64le
  • GitHub Check: rpm-build:fedora-43-ppc64le
  • GitHub Check: compilation (clang-16)
  • GitHub Check: compilation (clang-18)
  • GitHub Check: compilation (clang-14)
  • GitHub Check: compilation (gcc-12)
  • GitHub Check: compilation (clang-17)
  • GitHub Check: compilation (gcc-11)
  • GitHub Check: compilation (gcc-10)
  • GitHub Check: compilation (clang-15)
  • GitHub Check: compilation (gcc-14)
  • GitHub Check: compilation (gcc-13)
  • GitHub Check: symbols
  • GitHub Check: blivet-tests
  • GitHub Check: csmock
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (cpp)
  • GitHub Check: udisks-build
🔇 Additional comments (6)
tests/crypto_test.py (2)

120-127: LGTM! Helper correctly checks device read-only state.

The _is_ro helper properly reads from sysfs to determine if a mapped device is read-only. The implementation correctly resolves the device path and constructs the appropriate sysfs path.


1522-1535: LGTM! Consistent test coverage across crypto formats.

The open-with-flags tests for VeraCrypt, BitLocker, and FileVault2 follow the same pattern as the LUKS tests, properly verifying both the ALLOW_DISCARDS flag (via dmsetup) and the READONLY flag (via the _is_ro helper). The consistent structure makes the tests easy to understand and maintain.

Also applies to: 1637-1650, 1751-1764

src/lib/plugin_apis/crypto.api (2)

364-367: LGTM! Enum properly defines activation flags.

The BDCryptoOpenFlags enum is correctly defined with proper bitfield values, allowing flags to be combined using bitwise OR operations. The naming is clear and consistent with other enums in the codebase.


1333-1352: LGTM! Consistent API design across crypto formats.

The *_open_flags function declarations for TrueCrypt, BitLocker, and FileVault2 are well-structured and consistent with each other. Each properly accepts the BDCryptoOpenFlags parameter and includes complete documentation.

Also applies to: 1396-1410, 1439-1453

src/plugins/crypto.h (1)

175-178: LGTM! Header properly declares new flags API.

The BDCryptoOpenFlags enum and the four new *_open_flags function declarations are correctly defined and consistent with the API definitions in crypto.api. The existing *_open functions remain unchanged, preserving backward compatibility while providing the new flag-based alternatives.

Also applies to: 298-298, 328-328, 332-332, 336-336

src/plugins/crypto.c (1)

3721-3852: FVAULT2 _open_flags logic matches other backends; please double‑check header declaration.

The FVAULT2 changes look good overall:

  • The #ifndef LIBCRYPTSETUP_26 stubs for both bd_crypto_fvault2_open_flags and bd_crypto_fvault2_open correctly route to bd_crypto_is_tech_avail.
  • The real implementations follow the same keyfile/passphrase and error‑handling patterns as BITLK.
  • BDCryptoOpenFlags are translated to CRYPT_ACTIVATE_* as expected.

One thing to verify outside this file: ensure the declaration in crypto.h (and any public API description files) uses exactly the same name and signature as this implementation, i.e. gboolean bd_crypto_fvault2_open_flags(..., BDCryptoOpenFlags flags, GError **error). A mismatch (for example a stray _FLAGS spelling or different parameter order) would break compilation or introspection.

@vojtechtrefny
Copy link
Member Author

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature by allowing activation flags to be used when opening various types of encrypted devices. The implementation is consistent across LUKS, TrueCrypt/VeraCrypt, BitLocker, and FileVault2, and includes corresponding API documentation, Python bindings, and tests. My review identifies a few opportunities to improve code maintainability and API consistency. Specifically, I've suggested refactoring duplicated code in the C implementation and tests into helper functions, and adding missing Python overrides for the new functions to ensure a consistent developer experience.

Comment on lines +1323 to +1326
if (flags & BD_CRYPTO_OPEN_ALLOW_DISCARDS)
crypt_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (flags & BD_CRYPTO_OPEN_READONLY)
crypt_flags |= CRYPT_ACTIVATE_READONLY;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This flag conversion logic is duplicated in bd_crypto_tc_open_flags, bd_crypto_bitlk_open_flags, and bd_crypto_fvault2_open_flags. To improve maintainability and reduce code duplication, consider extracting this logic into a static helper function.

For example, you could define a function like this near other static helpers (e.g., after _is_dm_name_valid):

static guint32
_bd_crypto_get_activate_flags (BDCryptoOpenFlags flags)
{
    guint32 crypt_flags = 0;

    if (flags & BD_CRYPTO_OPEN_ALLOW_DISCARDS)
        crypt_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
    if (flags & BD_CRYPTO_OPEN_READONLY)
        crypt_flags |= CRYPT_ACTIVATE_READONLY;

    return crypt_flags;
}

Then, you can replace the declaration guint32 crypt_flags = 0; (line 1295) with guint32 crypt_flags = _bd_crypto_get_activate_flags(flags); and remove this block of if statements. This refactoring should be applied to all new ..._open_flags functions to centralize the flag handling.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, you should've suggested static inline func instead, or a macro! Too much context switching here.

Comment on lines +339 to +345
_crypto_tc_open_flags = BlockDev.crypto_tc_open_flags
@override(BlockDev.crypto_tc_open_flags)
def crypto_tc_open_flags(device, name, passphrase, flags=0, keyfiles=None, hidden=False, system=False, veracrypt=False, veracrypt_pim=0):
if isinstance(passphrase, str):
passphrase = passphrase.encode("utf-8")
return _crypto_tc_open_flags(device, name, passphrase, keyfiles, hidden, system, veracrypt, veracrypt_pim, flags)
__all__.append("crypto_tc_open_flags")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This pull request introduces new _flags versions for opening encrypted devices (luks, tc, bitlk, fvault2), but an override is only provided for crypto_tc_open_flags. For consistency and ease of use, you should also provide overrides for crypto_luks_open_flags, crypto_bitlk_open_flags, and crypto_fvault2_open_flags.

Without these overrides, users will have to manually create a CryptoKeyslotContext object for these functions, which is inconsistent with the existing _open functions that accept a passphrase string directly.

For example, for LUKS, you could add:

_crypto_luks_open_flags = BlockDev.crypto_luks_open_flags
@override(BlockDev.crypto_luks_open_flags)
def crypto_luks_open_flags(device, name, passphrase, flags=0):
    if isinstance(passphrase, str):
        passphrase = passphrase.encode("utf-8")
    return _crypto_luks_open_flags(device, name, passphrase, flags)
__all__.append("crypto_luks_open_flags")

Similar overrides should be added for bitlk and fvault2.

Comment on lines +725 to +730
# check that discard is enabled for the mapped device
_ret, out, _err = run_command("dmsetup table %s" % self._dm_name)
self.assertIn("allow_discards", out)

# check that the device is read-only
self.assertTrue(self._is_ro("libblockdevTestLUKS"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code for checking allow_discards and read-only status is duplicated in test_veracrypt_open_close, test_bitlk_open_close, and test_fvault2_open_close. To improve test code maintainability, consider extracting this logic into a helper method within the CryptoTestCase class.

For example:

def _check_open_flags(self, dm_name):
    # check that discard is enabled for the mapped device
    _ret, out, _err = run_command("dmsetup table %s" % dm_name)
    self.assertIn("allow_discards", out)

    # check that the device is read-only
    self.assertTrue(self._is_ro(dm_name))

Then you can call self._check_open_flags("libblockdevTestLUKS") here and in the other test methods.

@vojtechtrefny vojtechtrefny requested a review from tbzatek December 2, 2025 11:37
Comment on lines +1323 to +1326
if (flags & BD_CRYPTO_OPEN_ALLOW_DISCARDS)
crypt_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (flags & BD_CRYPTO_OPEN_READONLY)
crypt_flags |= CRYPT_ACTIVATE_READONLY;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, you should've suggested static inline func instead, or a macro! Too much context switching here.

BD_CRYPTO_LUKS_ACTIVATE_HIGH_PRIORITY = 1 << 6,
} BDCryptoLUKSPersistentFlags;

typedef enum {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me as it is

@vojtechtrefny vojtechtrefny merged commit a8ac292 into storaged-project:master Dec 3, 2025
44 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for activating crypt devices with discard enabled

2 participants