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

Siyao Meng updated HDDS-17389:
------------------------------
    Attachment: CR-1-export-startup-cleanup-only-owned-entries.patch

> Recon export cleanup deletes every directory and .tar file in 
> ozone.recon.export.directory, not only files created by exports
> -----------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17389
>                 URL: https://issues.apache.org/jira/browse/HDDS-17389
>             Project: Apache Ozone
>          Issue Type: Bug
>    Affects Versions: 2.2.0, 2.2.1
>            Reporter: Siyao Meng
>            Priority: Major
>         Attachments: CR-1-export-startup-cleanup-only-owned-entries.patch, 
> TestBugCR1ExportDirSweep.java
>
>
> h3. Mechanism
> The {{ExportJobManager}} constructor removes leftovers of earlier exports 
> from {{ozone.recon.export.directory}}. It lists the directory and calls 
> {{FileUtils.deleteQuietly}} (recursive) on every subdirectory and on every 
> file ending in {{.tar}}, without looking at the name. The manager itself only 
> creates {{<jobId>}} working directories (a random UUID) and 
> {{export_<state>_<millis>.tar}} files, so everything else it deletes was put 
> there by someone else.
> The configured value is used as is. Nothing checks that the directory is 
> dedicated to exports or differs from {{ozone.recon.db.dir}}, and neither 
> {{ozone-default.xml}} nor {{ReconServerConfigKeys}} says that its contents 
> are removed. SCM's container ID export ({{ExportFileManager}}) clears its 
> export directory on startup more narrowly: it removes only {{export_<UUID>}} 
> directories and {{*.tar.gz.tmp}} files.
> h3. Trigger
> # Set {{ozone.recon.export.directory}} to a directory that holds other data, 
> for example the Recon DB directory itself or a shared scratch directory.
> # Start Recon. The cleanup runs when the {{ExportJobManager}} singleton is 
> created, which happens once per Recon process on first use of the containers 
> API (argued from the Guice binding, not run in a Recon server).
> The default ({{ozone.recon.export.directory}} empty, resolved to 
> {{<ozone.recon.db.dir>/exports}}) is not affected.
> h3. Impact
> * With the export directory equal to {{ozone.recon.db.dir}}: Recon's 
> container key DB, OM snapshot DB, Recon SCM DB and Derby SQL DB directories 
> are deleted, and so is {{recon/}} with Recon's storage {{current/VERSION}} 
> file (run against stand-in directories with those names, see reproduction). 
> Because the sweep runs on the first containers API request, Recon has these 
> databases open at that point, so they are deleted under a running process 
> (argued from code, not run).
> * With a shared directory: other applications' directories and any {{.tar}} 
> file (for example backups) are deleted permanently (run). Other files are 
> kept.
> * It repeats on every Recon start.
> h3. Reproduction
> [^TestBugCR1ExportDirSweep.java] ({{hadoop-ozone/recon}}, package 
> {{org.apache.hadoop.ozone.recon.api}}) builds {{ExportJobManager}} through 
> its public constructor with real configuration keys, as Guice does; only 
> {{ContainerHealthSchemaManager}}, which the cleanup does not use, is mocked. 
> The first test points the export directory at the Recon DB directory holding 
> {{recon-container-key.db_...}}, {{om.snapshot.db_...}}, {{recon-scm.db}}, 
> {{ozone_recon_derby.db}} and {{recon/current/VERSION}}; after construction 
> the directory is empty. The second uses a shared directory with 
> {{other-app-cache/}}, {{operator-backup-2026-10-01.tar}} and {{notes.txt}}; 
> only {{notes.txt}} is left. Both tests pass on unmodified source, 
> deterministic; a passing test means the defect is present.
> h3. Patch
> [^CR-1-export-startup-cleanup-only-owned-entries.patch], against 
> fb2d0310a9c6ea37c72cefb5cc1d5b4db35a7ab1. It also applies to master at 
> 9c3e5477ffb.
> The cleanup now removes a directory only if its name is a valid UUID 
> ({{UUIDUtil.isValidUuidString}}, as in SCM's {{ExportFileManager}}) and a 
> file only if its name has the form {{export_<state>_<millis>.tar}}, the names 
> {{submitJob}} and {{executeExport}} create. The state part accepts any 
> letters, because {{submitJob}} lower cases it with the JVM default locale 
> (under a Turkish locale {{MISSING}} gets a dotless i). Leftovers of an 
> interrupted export are still removed and other files are kept. A directory 
> whose name is a UUID is still removed, because the job manager names its own 
> working directories that way. In the default directory, which only holds 
> export files, the behaviour is unchanged.
> Covered in the existing {{TestExportJobManager}}: the new 
> {{startupCleanupKeepsEntriesNotCreatedByExports}} checks that {{backup.tar}}, 
> {{export_backup.tar}} and a DB directory survive, and 
> {{startupCleanupRemovesLeftoverTarsAndDirs}} now uses the names the manager 
> really creates (it used {{stale_export.tar}} and {{stale_job_id/}} before), 
> including a tar named with the Turkish lower case of {{MISSING}}, and still 
> expects them removed. The test builds that name with an explicit locale and 
> does not change the JVM default. Without the change the new test fails 
> because {{backup.tar}} is deleted. With it {{TestExportJobManager}}, 
> {{TestExportJob}} and {{TestContainerEndpoint}} (54 tests) pass and 
> checkstyle is clean. With the patch both tests of the reproduction fail, 
> because all entries are kept.
> Found by code review of the Recon unhealthy container export job manager, as 
> part of the TLA+ verification effort under HDDS-15926, on commit 
> fb2d0310a9c6ea37c72cefb5cc1d5b4db35a7ab1. 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
(v10.3.26#10030026)

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

Reply via email to