Skip to content

Fix: Skip DRBD adjust/res file regeneration when child layer device is inaccessible - #477

Closed
kvaps wants to merge 4 commits into
LINBIT:masterfrom
kvaps:fix/encrypted-resource-deletion
Closed

kvaps wants to merge 4 commits into
LINBIT:masterfrom
kvaps:fix/encrypted-resource-deletion

Conversation

@kvaps

@kvaps kvaps commented Jan 12, 2026 •

Copy link
Copy Markdown
Contributor

fixes #350 (comment)

Problem

This PR fixes three related issues with device availability checks in DRBD layer:

1. Resources stuck in StandAlone after node reboot

After node reboot, DRBD resources remain in StandAlone state instead of automatically reconnecting because child device availability checks block network reconnection operations that don't require disk access.

2. Resources end up in Unknown state after satellite restart

Race condition when drbdadm adjust temporarily brings devices down/up: the kernel hasn't created /dev/drbd* device nodes yet, but updateDiscGran() immediately tries to run lsblk, which fails and interrupts the DeviceManager cycle.

3. Encrypted resource deletion fails

When deleting LUKS-encrypted resources, the LUKS layer may close its device before the DRBD layer attempts to adjust or regenerate the res file, causing 'Failed to adjust DRBD resource' errors.

Solution

Commit 1: Skip DRBD operations when child devices are inaccessible during deletion

Add checks before regenerateResFile() and drbdUtils.adjust() to verify child layer devices are accessible. If devices don't exist (e.g., LUKS closed during deletion), skip operations and clear adjustRequired flag.

Commit 2: Skip lsblk when device path doesn't physically exist

Check Files.exists(devicePath) before calling lsblk in updateDiscGran(). If device node doesn't exist yet, skip the check - it will retry in the next DeviceManager cycle.

Commit 3: Only check child devices when disk access is needed

Distinguish between operations requiring disk access (volume creation, resize, metadata) and those that don't (network reconnect from StandAlone). Only check child device accessibility for disk operations, allowing automatic reconnection after reboot.

Testing

  • Encrypted (LUKS) resources deletion now completes successfully
  • DRBD resources automatically reconnect from StandAlone after node reboot
  • No more Unknown state resources after satellite restart with drbdadm adjust race conditions

kvaps and others added 3 commits December 16, 2025 02:08
…s inaccessible

When deleting encrypted (LUKS) resources, the LUKS layer may close its
device before DRBD layer attempts to adjust the resource or regenerate
the res file. This causes 'Failed to adjust DRBD resource' errors.

This fix adds checks before regenerateResFile() and drbdUtils.adjust()
to verify that child layer devices are accessible. If a child device
doesn't exist or is not accessible, these operations are skipped and
adjustRequired flag is cleared, allowing resource deletion to proceed
successfully.

Fixes issue where encrypted resources could not be deleted due to
DelayedApiRcException during DRBD resource adjustment.
Add physical device path existence check before calling lsblk in updateDiscGran().
This prevents race condition when drbdadm adjust temporarily brings devices down/up
and the kernel hasn't created the device node yet.

Issue: After satellite restart with patched code, some DRBD resources ended up in
Unknown state because:
1. drbdadm adjust successfully completes (brings devices up)
2. updateDiscGran() immediately tries to check discard granularity
3. /dev/drbd* device node doesn't exist yet (kernel hasn't created it)
4. lsblk fails with exit code 32 "not a block device"
5. StorageException interrupts DeviceManager cycle
6. DRBD device remains in incomplete state

Solution: Check Files.exists(devicePath) before calling lsblk. If device doesn't
exist yet, skip the check - it will be retried in the next DeviceManager cycle
when the device node is available.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
The previous implementation blocked `drbdadm adjust` whenever child
device paths were unavailable, even for operations that don't require
disk access (like network reconnect from StandAlone to Connected).

After node reboot, DRBD resources often remain in StandAlone state
because:
1. updateResourceToCurrentDrbdState() correctly detects StandAlone
   and sets adjustRequired=true
2. However, canAdjust check fails because child volumes may have
   devicePath=null (due to INACTIVE flag, cloning state, or
   initialization race)
3. adjust is skipped → adjustRequired=false → resources stay StandAlone

Root cause: The canAdjust check was added to protect LUKS deletion
scenarios but was applied to ALL cases, including network reconnect
which doesn't need disk access.

Fix: Check child device accessibility only when disk access is actually
required (volume creation, resize, metadata operations). Network
reconnect operations (StandAlone → Connected) now proceed without
checking child devices.

This ensures automatic DRBD reconnection after reboot while preserving
protection for LUKS deletion scenarios.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps
kvaps force-pushed the fix/encrypted-resource-deletion branch 2 times, most recently from 16c8a8e to f0eaa4c Compare January 12, 2026 13:40
kvaps added a commit to cozystack/cozystack that referenced this pull request Jan 12, 2026
## What this PR does

This PR updates piraeus-server patches to address several critical
production issues with DRBD resources and LUKS encryption:

1. **Add fix-duplicate-tcp-ports.diff** - Prevents duplicate TCP ports
after toggle-disk operations (upstream PR #476)

2. **Update skip-adjust-when-device-inaccessible.diff** - Comprehensive
fix for multiple issues:
   - Resources stuck in StandAlone state after node reboot
   - Unknown state race condition during satellite restart
   - Encrypted LUKS resource deletion failures
   - Network reconnect blocked by unavailable child device checks

These patches resolve scenarios where DRBD resources fail to
automatically reconnect after node reboots and improve LUKS resource
lifecycle management.

Upstream PRs:
- LINBIT/linstor-server#476
- LINBIT/linstor-server#477

### Release note

```release-note
[linstor] Fix DRBD resources stuck in StandAlone state after reboot and encrypted resource deletion issues
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * Prevents duplicate TCP port conflicts after disk toggle operations
  * Fixes resources stuck in StandAlone or Unknown state after reboot
  * Resolves issues with encrypted resource deletion
  * Improves handling of temporarily inaccessible storage devices

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

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
LuksLayer was the only layer in LINSTOR that never called
setExists(true) after successfully creating and opening a LUKS device.
All other layers (Storage, DRBD, Writecache, Cache, BCache) properly
set this flag.

This caused a critical issue when combined with the child device
accessibility check in DrbdLayer.adjustDrbd(): the check
"!childVlm.exists()" always evaluated to true for LUKS volumes,
preventing .res file regeneration for new DRBD+LUKS+STORAGE resources.
As a result, drbdadm create-md failed with "not defined in your config"
on all nodes, leaving resources in Unknown state.

The fix aligns LuksLayer with every other layer by calling
setExists(true) alongside the existing setOpened(true) call after
successful device creation/opening.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps

kvaps commented Feb 19, 2026

Copy link
Copy Markdown
Contributor Author

Added a new commit that fixes a critical regression introduced by the child device accessibility check.

Root cause: LuksLayer is the only layer in LINSTOR that never calls setExists(true) after successfully creating and opening a LUKS device. All other layers (Storage, DRBD, Writecache, Cache, BCache) properly set this flag. As a result, the !childVlm.exists() check in the canRegenerateResFile guard always evaluates to true for LUKS volumes, preventing .res file regeneration for all new DRBD+LUKS+STORAGE resources.

Symptoms: Every newly created resource with the DRBD+LUKS+STORAGE layer stack fails with:

drbdadm create-md <resource>/0
'<resource>/0' not defined in your config (for this host).

Typically 1 out of N nodes succeeds (via the prepare() phase), while all others fail because adjustDrbd() skips writing the .res file.

Fix: Added vlmData.setExists(true) in LuksLayer.processResource() after successful device creation/opening, aligning LUKS with every other layer. This also fixes secondary issues where SuspendManager and updateDiscGran() never treated LUKS volumes as existing.

The TODO comment in LuksVlmData.java:47 (// TODO maybe introduce States like "OPEN", "CLOSED", "UNINITIALIZED") confirms this was an unfinished area of the codebase.

kvaps added a commit to cozystack/cozystack that referenced this pull request Feb 19, 2026
## What this PR does

Adds the `skip-adjust-when-device-inaccessible.diff` patch (upstream
[LINBIT/linstor-server#477](LINBIT/linstor-server#477))
which:

- Skips DRBD adjust and .res file regeneration when child layer devices
are inaccessible (fixes encrypted resource deletion)
- Skips lsblk when device path doesn't physically exist yet (fixes race
condition after drbdadm adjust)
- Only checks child devices when disk access is actually needed (allows
network reconnect from StandAlone)
- Fixes missing `setExists(true)` in `LuksLayer` — the root cause of all
new DRBD+LUKS+STORAGE resources failing with "not defined in your
config"

### Release note

```release-note
[linstor] Fix DRBD+LUKS+STORAGE resource creation: all new encrypted volumes were failing because the DRBD .res file was never written due to a missing exists flag in the LUKS layer
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved handling of inaccessible storage devices by adding pre-checks
before performing operations
* Operations are now skipped when underlying storage devices are
unavailable, preventing unnecessary failures
* Enhanced error recovery during storage adjustments when devices are
temporarily inaccessible

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@kvaps

kvaps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Decided not to use these changes for now, closing. Will reopen if the issues arise again.

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.

LINSTOR tries to remove device from LVM without removing it from luks

1 participant