Skip to content

Conversation

Bert-Proesmans
Copy link

@Bert-Proesmans Bert-Proesmans commented Sep 30, 2025

Fixes #1139

  • Adds unmount validation to example tests (module mode)
  • Updates zfs_fs and zfs_volume to use the full dataset path consistently

Currently running all tests locally, new/other issues might pop up due to change to test script.

Summary by CodeRabbit

  • New Features
    • None
  • Bug Fixes
    • Avoid errors during unmount by only unloading ZFS keys when they are actually loaded.
    • Use fully qualified dataset names for ZFS operations to improve mount/unmount reliability.
  • Tests
    • Expanded module-mode tests to verify unmount idempotency and stable remounts.

- Fix typo against full dataset path argument
- Make unmount with encryption keys idempotent
Copy link

coderabbitai bot commented Sep 30, 2025

Walkthrough

Adds idempotence checks to module-mode tests (double unmount then remount). Introduces internal _name for ZFS volumes and switches keystatus/load/unload operations to use the fully qualified dataset name. Unmount scripts now conditionally unload ZFS keys only when keystatus reports "available."

Changes

Cohort / File(s) Summary of changes
Module tests flow
lib/tests.nix
Test sequence updated: after initial mount, perform unmount twice, then remount before proceeding with destroy/recreate steps; direct-mode unchanged.
ZFS filesystem unmount key handling
lib/types/zfs_fs.nix
Unmount path now checks zfs get keystatus and only runs zfs unload-key when the key is available; uses dataset placeholder _name for checks/commands.
ZFS volume naming and key ops
lib/types/zfs_volume.nix
Adds internal option _name (default ${config._parent.name}/${config.name}). Updates creation checks/targets, post-create udev/partprobe steps, and mount/unmount keystatus/load/unload to use config._name.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant TestRunner as Module Tests
  participant Disko as Disko Scripts
  participant ZFS as ZFS CLI

  User->>TestRunner: run module-mode tests
  TestRunner->>Disko: mount
  Disko->>ZFS: (create/mount as configured)
  TestRunner->>Disko: unmount
  Disko->>ZFS: unmount + conditional unload-key(_name)
  TestRunner->>Disko: unmount (again)
  Disko->>ZFS: no-op unmount if already unmounted
  TestRunner->>Disko: mount (remount)
  Disko->>ZFS: keystatus(_name)? load-key if needed → mount
  TestRunner->>Disko: destroy/recreate...
  Note over Disko,ZFS: Direct-mode flow unchanged
Loading
sequenceDiagram
  autonumber
  participant Script as Un/mount Script
  participant ZFS as ZFS CLI

  rect rgb(230,240,255)
  note right of Script: Mount path
  Script->>ZFS: keystatus _name
  alt keystatus != "available"
    Script->>ZFS: load-key _name
  end
  Script->>ZFS: mount dataset(s)
  end

  rect rgb(255,240,230)
  note right of Script: Unmount path
  Script->>ZFS: unmount dataset(s)
  Script->>ZFS: keystatus _name
  alt keystatus == "available"
    Script->>ZFS: unload-key _name
  else
    Note over Script,ZFS: Skip unload-key
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The inclusion of post-create device readiness steps—namely zvol_wait, partprobe, and udevadm trigger/settle—in lib/types/zfs_volume.nix extends beyond the scope of fixing dataset name handling for load-key/unload-key and test validation as described in issue #1139 and the PR objectives. Please remove or relocate the zvol_wait, partprobe, and udevadm commands into a separate PR so that this changeset remains focused on correcting the encryption mount/unmount behavior and associated tests.
✅ 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 “Fix zfs with encryption mount/unmount” directly references the core change of correcting how encrypted ZFS filesystems are mounted and unmounted, which aligns with the updates to the zfs_fs and zfs_volume modules and the added test validation in this pull request. It is concise and specific enough that a reviewer immediately understands the pull request addresses encryption-related mount/unmount behavior.
Linked Issues Check ✅ Passed The pull request fulfills the objective of issue #1139 by introducing the internal option _name to represent the full dataset path and updating both the load-key and unload-key invocations in zfs_volume and zfs_fs to reference this full path. Additionally, the example tests in lib/tests.nix now include unmount validation to ensure idempotent unmount behavior in module mode, directly addressing the linked issue’s failure scenario.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • 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.

@Bert-Proesmans
Copy link
Author

Bert-Proesmans commented Sep 30, 2025

You can cherry-pick my changes to the ZFS types, otherwise decisions have to be made about how to handle the failing tests.

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 (1)
lib/types/zfs_volume.nix (1)

53-53: Suggest using config._name for consistency.

The device path construction manually concatenates ${config._parent.name}/${config.name}, which duplicates the logic in config._name. For consistency with the rest of the file and easier maintenance, consider using config._name.

Apply this diff:

-      device = "/dev/zvol/${config._parent.name}/${config.name}";
+      device = "/dev/zvol/${config._name}";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67ff980 and 928c5a2.

📒 Files selected for processing (3)
  • lib/tests.nix (1 hunks)
  • lib/types/zfs_fs.nix (1 hunks)
  • lib/types/zfs_volume.nix (4 hunks)
🔇 Additional comments (9)
lib/tests.nix (1)

348-350: LGTM! Test coverage for unmount idempotence is valuable.

The addition of double unmount followed by remount properly validates that the unmount script is idempotent and that the system can be remounted after unmounting. This will help catch regressions in the ZFS key management fixes.

lib/types/zfs_fs.nix (4)

18-23: LGTM! Fully qualified dataset name fixes the core issue.

The _name option correctly constructs the full dataset path by combining parent pool name and dataset name. This resolves issue #1139 where only the leaf name was used, causing "dataset does not exist" errors.


122-124: LGTM! Load-key now uses fully qualified dataset name.

The keystatus check and load-key operation correctly use config._name to reference the full dataset path, fixing mount failures with encrypted datasets.


146-150: LGTM! Conditional unload-key prevents spurious errors.

The unmount logic now:

  1. Checks if the key is "available" before attempting to unload
  2. Uses the fully qualified dataset name (config._name)

This prevents "dataset does not exist" errors and avoids attempting to unload keys that aren't loaded.


94-114: No action needed for _create parent initialization. config._parent defaults to the parent argument (passed into the type) and _name is declared before _create, so ${config._name} (and thus ${config._parent.name}) is always available at evaluation time.

lib/types/zfs_volume.nix (4)

16-21: LGTM! Fully qualified dataset name for ZFS volumes.

The _name option mirrors the implementation in zfs_fs.nix, providing consistent fully qualified dataset names across both ZFS filesystem and volume types.


70-78: LGTM! ZFS volume creation uses fully qualified name.

The create logic correctly uses config._name for:

  • Type existence checks
  • Volume creation target
  • Device path in partprobe

This ensures zvol operations reference the correct dataset path.


87-89: LGTM! Mount key loading uses fully qualified name.

The keystatus check and load-key operation correctly use config._name, matching the fix pattern in zfs_fs.nix.


103-107: LGTM! Conditional key unload prevents errors.

The unmount logic mirrors the fix in zfs_fs.nix:

  • Only unloads when keystatus is "available"
  • Uses fully qualified dataset name (config._name)

This prevents failures when keys aren't loaded or datasets don't exist.

@Enzime
Copy link
Member

Enzime commented Sep 30, 2025

I suspect all the tests are failing because all the other types don't have idempotent unmounts

- Fix consistent use of fully qualified dataset path
- Add idempotent unmounting with encryption keys
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 (1)
lib/types/zfs_volume.nix (1)

16-21: LGTM! Nitpick: Typo in description.

The _name option correctly constructs the fully qualified dataset path, which fixes the core issue in #1139.

Minor typo: "Fully quantified" should be "Fully qualified":

-      description = "Fully quantified name for dataset";
+      description = "Fully qualified name for dataset";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 928c5a2 and 0bd6597.

📒 Files selected for processing (1)
  • lib/types/zfs_volume.nix (4 hunks)
🔇 Additional comments (3)
lib/types/zfs_volume.nix (3)

70-71: LGTM!

The _create section correctly uses config._name for both existence checks and dataset creation, ensuring the full dataset path is used consistently.


87-88: LGTM!

The mount logic correctly uses config._name for both keystatus checks and load-key operations, ensuring encrypted datasets are properly handled with the full dataset path.


103-107: LGTM! Core fix for issue #1139.

The unmount logic now correctly uses config._name for both keystatus checks and unload-key operations. This fixes the "cannot open 'root': dataset does not exist" error by passing the fully qualified dataset path (e.g., zroot/root) instead of just the leaf name (root). The conditional keystatus check also makes unmounting idempotent.

@Bert-Proesmans
Copy link
Author

Bert-Proesmans commented Oct 1, 2025

i removed the change to the partprobe command in zfs_volume create step. The argument to partprobe is not related to the dataset path but to the device path EDIT; in the disko abstraction layer.

I suspect all the tests are failing because all the other types don't have idempotent unmounts

Yeah, I understand i'm pushing on invariants/guarantees with this PR. But the lack of tests for unmounting practically comes down to "unmounting is not guaranteed", let alone that it happens clean/idempotent (to match naive user expectations).

That's why I commented to cherry-pick or lay out decisions, because this is just a drive-by contribution and I'm not a maintainer. I can adjust the PR.

@Enzime
Copy link
Member

Enzime commented Oct 2, 2025

If you're interested in updating the rest of the types to support idempotent unmounts, that would be great 👍

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.

Unmount script on zfs-encrypted example fails at unload-key
2 participants