Siyao Meng created HDDS-17024:
---------------------------------

             Summary: Failed .container write during mark for close rolls the 
container back to OPEN without its space reservation
                 Key: HDDS-17024
                 URL: https://issues.apache.org/jira/browse/HDDS-17024
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng
         Attachments: MC-8-keep-reservation-on-failed-mark-for-close.patch, 
TestBugMC8MarkForCloseRollbackReservation.java

h3. Mechanism
{{KeyValueContainer.updateContainerData}} applies the state change first and 
writes the {{.container}} file second. For mark for close, 
{{ContainerData.setState(CLOSING)}} leaves OPEN and releases the container's 
reservation ({{maxSize - bytesUsed}}) and its reservation flag. When the file 
write then fails, the rollback {{setState(oldState)}} restores OPEN but does 
not reserve again. The container stays OPEN and writable with nothing reserved; 
its writes are not charged against the volume either. This is a regression from 
HDDS-12810 (2.1.0), which removed the reservation {{setState}} used to make on 
every transition back to OPEN.

h3. Trigger
SCM sends CloseContainer (or the pipeline is removed) and writing the 
container's {{.container}} file fails with an {{IOException}} (EIO, ENOSPC, 
EACCES) while the volume stays healthy. {{CloseContainerCommandHandler}} only 
logs the error, so the container remains OPEN until the close is retried 
successfully.

h3. Impact
While the container stays OPEN, the volume's committed bytes lack its headroom, 
so {{AvailableSpaceFilter}} admits new containers and imports the volume has no 
room for, and the storage report understates the committed space. A later 
successful close or a restart corrects the counter, but containers admitted in 
the meantime stay.

h3. Reproduction
[^TestBugMC8MarkForCloseRollbackReservation.java] 
({{hadoop-hdds/container-service}}) uses a real {{HddsVolume}} with a mocked 
1000 MB usage source, 600 MB containers, the real 
{{RoundRobinVolumeChoosingPolicy}} and {{KeyValueHandler}}. The fault is a real 
filesystem error: the container's metadata directory is read only (run as a non 
root user). A second create is refused with {{DISK_OUT_OF_SPACE}} before the 
fault. After the failed mark for close: {{state=OPEN committedSpace=false 
committed=0}}, and the same second create succeeds, leaving two OPEN containers 
with 1200 MB of headroom on a 1000 MB volume. A passing test means the defect 
is present. Not exercised: a real EIO or ENOSPC.

h3. Patch
[^MC-8-keep-reservation-on-failed-mark-for-close.patch], against 
cce1ca28944886218132f01c0e271c1fd0700078. It also applies to master at 
2536fe9cbc3. Released 2.1.0 and later are affected.

{{updateContainerData}} remembers whether space was reserved before the update; 
if the rollback leaves it unreserved, it calls {{ContainerData.commitSpace()}}, 
which reserves the current {{maxSize - bytesUsed}} again. The fix is in the 
rollback because that is the only place a container legitimately returns to 
OPEN, and the check of the earlier flag avoids reserving for an OPEN container 
that held nothing before (which the removed unconditional {{commitSpace}} in 
{{setState}} did not check). Covered by the new 
{{TestKeyValueContainer.testReservationKeptWhenMarkForCloseFails}}, which also 
checks that a retried mark for close then releases the space; it fails without 
the change (no reservation after the rollback). With it the container, handler, 
reader, persistence, close command, state machine and stale recovering scrubber 
suites pass (564 tests) and checkstyle is clean.

RECOVERING containers get the same rollback once HDDS-17022 makes them release 
on leaving RECOVERING and lets {{commitSpace}} reserve for them.

Found by TLA+ model checking and code review of the datanode volume and 
per-disk RocksDB lifecycle paths under HDDS-15926, on commit 
cce1ca28944886218132f01c0e271c1fd0700078. Checked against HDDS issues and 
apache/ozone pull requests for duplicates before filing. The attached patch is 
a proposal for review. Generated with Specula (Claude Opus 5.5).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to