[ 
https://issues.apache.org/jira/browse/HDDS-17051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Andrey Yarovoy reassigned HDDS-17051:
-------------------------------------

    Assignee: Andrey Yarovoy

> EC reconstruction read loses the S3 authentication and read-consistency hint 
> when a reader thread refreshes block locations from OM
> -----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17051
>                 URL: https://issues.apache.org/jira/browse/HDDS-17051
>             Project: Apache Ozone
>          Issue Type: Bug
>          Components: EC Client
>            Reporter: Andrey Yarovoy
>            Assignee: Andrey Yarovoy
>            Priority: Major
>
> *Problem*
> When a datanode holding an EC data replica fails, `ECBlockInputStreamProxy` 
> switches to
> `ECBlockReconstructedStripeInputStream`. That stream reads the remaining 
> indexes on the client's
> `ecReconstructExecutor` pool (`loadDataBuffersFromStream` submits 
> `readIntoBuffer` for each selected index). Each
> index's `BlockInputStream` is opened and read on the pool thread.
> If that read gets a `StorageContainerException` or a connectivity error, 
> `BlockInputStream` refreshes the block
> locations through its `refreshFunction`. In `RpcClient` that function is 
> `getKeyInfo(...)`, an OM call, so it runs on
> the pool thread.
> The OM client keeps the request context in thread-locals of 
> `OzoneManagerProtocolClientSideTranslatorPB`. The S3
> Gateway sets them on the request thread:
>  - `threadLocalS3Auth`: the S3 credentials the request is authorized as
>  - `threadLocalReadConsistencyHint`: from the `x-ozone-read-consistency` 
> header
> `ecReconstructExecutor` is a plain `ThreadPoolExecutor`, so neither value is 
> set on its threads. As a result:
>  - *{*}Secure S3 Gateway:{*}* `OzoneClientCache` always sets 
> `ozone.s3.auth.check=true`, so with `ozone.security.enabled`
> `submitRequest` throws `IllegalArgumentException("S3 Auth expected to be set 
> but is null ...")`.
>  - The retry lambda in `RpcClient.getInputStreamWithRetryFunction` catches 
> only `IOException`, so the exception
> escapes the refresh. The task fails, and the index is marked failed.
>  - The refresh that would have found the new location is lost. A degraded 
> read that should succeed can then fail
> with too few good locations, and that happens exactly when the cluster is 
> already degraded.
>  - *{*}Without the S3 auth check{*}* (non-secure): the refresh is sent 
> without S3 authentication. OM then sees the
> gateway's own identity instead of the S3 user's.
>  - *{*}In all cases:{*}* the refresh does not carry the request's 
> read-consistency hint. It uses the client's default
> consistency instead.
> *Proposed change*
> Build `ecReconstructExecutor` in `RpcClient` with the 
> request-context-propagating executor from HDDS-16867
> (`createRequestContextPropagatingExecutor(...)` with `requestContext()`), 
> instead of `createThreadPoolExecutor(...)`.
> For each task the wrapper:
>  - copies the submitter's S3 auth and read-consistency hint onto the worker
>  - runs the task
>  - restores the worker's previous values, or removes them if it had none, 
> including when the task throws
> so pool threads never keep a request's credentials after the task ends.
> The pool is created lazily, after `ozoneManagerClient`, which is already the 
> case for the HDDS-16867 pool. No
> configuration, protocol or compatibility change.
> Depends on HDDS-16867.
> *Testing*
>  - *{*}Unit test, in `TestOzoneECClient`{*}* (both read modes, using its 
> existing mock OM transport and datanode
> storage):
>  - set S3 auth and a read-consistency hint on the reading thread;
>  - fail one data datanode so the read fails over to reconstruction;
>  - make one GetBlock on a remaining index return `CONTAINER_NOT_FOUND`
> (`MockDatanodeStorage.failNextGetBlocks` from HDDS-16867), so the refresh 
> happens on an
> `ec-reconstruct-reader-` thread;
>  - assert that the data is correct, that the failed GetBlock ran on a 
> reconstruct-pool thread, and that every OM
> request carries both the S3 authentication and the hint.
> It should fail without the change.
>  - Existing EC reconstruction tests 
> (`TestECBlockReconstructedStripeInputStream`, `TestOzoneECClient`) and
> `TestRpcClient`.



--
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