salvage: drop stale sidecars when payload is missing
This commit is contained in:
7
AI.md
7
AI.md
@@ -71,9 +71,16 @@ use, the current project status that the user pasted into the chat.
|
||||
`0x12`.
|
||||
- Keep `0x57` subfunction dispatch in `handle_func_0x57()` / namespace code,
|
||||
not as a second subfunction switch in `nwconn.c`.
|
||||
- Versioned backend payload names follow Samba `vfs_recycle` literally:
|
||||
`Copy #1 of NAME`, `Copy #2 of NAME`, ... . Do not localize this string and
|
||||
do not run it through gettext; the NCP scan reply still reports the original
|
||||
deleted filename for every version.
|
||||
- Versioned salvage entries may have different `.recycle`/`.salvage` names but
|
||||
`87/16` returns the original deleted filename for every version. Do not match
|
||||
recover/purge by display name alone.
|
||||
- Scan must treat `.salvage` JSON as a sidecar for the matching `.recycle`
|
||||
payload. If an external tool such as Samba or an administrator removes the
|
||||
payload, `87/16` must not return the stale sidecar and should remove the JSON.
|
||||
- Scan, recover, and purge should share the same scan/sequence/basehandle view
|
||||
so that a sequence returned by scan identifies the exact sidecar used later.
|
||||
- Append salvage endpoint tests to `tests/salvage/salvage_smoke_suite.sh` rather
|
||||
|
||||
21
TODO.md
21
TODO.md
@@ -247,20 +247,21 @@ Current status:
|
||||
- The runtime configuration uses low `nw.ini` sections `51-59`. Section `53`
|
||||
maps Samba-style behaviour flags (`k`, `v`, `t`, `m`), and sections
|
||||
`55-58` cover size filters, exclude, exclude_dir, and noversions lists.
|
||||
- NCP delete, Samba-compatible history naming, and the initial `87/16` salvage
|
||||
scan are covered by the combined smoke suite in `tests/salvage/`.
|
||||
- NCP delete, Samba-compatible history naming, `87/16` scan, `87/17` recover,
|
||||
and `87/18` purge are covered by the combined smoke suite in `tests/salvage/`.
|
||||
- The legacy old salvage calls `22/27`, `22/28`, and `22/29` are adapters over
|
||||
the same shared backend, not a second deleted-entry implementation.
|
||||
- Samba-compatible history naming is the literal English `Copy #n of NAME`
|
||||
format used by `vfs_recycle`; it is not localized.
|
||||
- `NCP 0x2222 / 87 / 16` has a backend-backed scanner that reads `.salvage`
|
||||
JSON entries and returns one salvageable entry per call.
|
||||
JSON entries and returns one salvageable entry per call. Stale JSON sidecars
|
||||
whose `.recycle` payload has disappeared are not returned and are removed by
|
||||
the scan path.
|
||||
|
||||
Follow-up:
|
||||
|
||||
- Continue the normal NetWare salvage family on top of the shared backend:
|
||||
- `NCP 0x2222 / 87 / 17` - Recover Salvageable File
|
||||
- `NCP 0x2222 / 87 / 18` - Purge Salvageable File
|
||||
- optional legacy `NCP 0x2222 / 22 / 27` - Scan Salvageable File (old)
|
||||
- Append endpoint-level recover/purge checks to `tests/salvage/salvage_smoke_suite.sh`.
|
||||
- Add cleanup coverage for stale `.salvage` JSON when the matching `.recycle`
|
||||
payload has been manually removed.
|
||||
- Add explicit endpoint coverage for stale `.salvage` cleanup after manually or
|
||||
externally removing the matching `.recycle` payload.
|
||||
|
||||
### AFP / Mac namespace backend
|
||||
|
||||
|
||||
@@ -1853,6 +1853,7 @@ static int nwsalvage_scan_metadata_dir(const char *metadata_dir,
|
||||
char metadata_path[NWSALVAGE_PATH_MAX];
|
||||
char recycle_path[NWSALVAGE_PATH_MAX];
|
||||
struct nwsalvage_metadata_entry entry;
|
||||
struct stat st;
|
||||
size_t len;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
@@ -1879,6 +1880,20 @@ static int nwsalvage_scan_metadata_dir(const char *metadata_dir,
|
||||
entry.recycle_relative_path) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The .salvage JSON is only a sidecar for the real payload below
|
||||
* .recycle. Samba, an administrator, or filesystem cleanup may remove
|
||||
* the payload behind our back. Do not return such stale metadata from
|
||||
* NCP 87/16 scans; remove the orphaned sidecar and keep scanning.
|
||||
*/
|
||||
if (stat(recycle_path, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
(void)unlink(metadata_path);
|
||||
continue;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
|
||||
memset(result, 0, sizeof(*result));
|
||||
result->scan_sequence = *match_index;
|
||||
result->scan_volume = (unsigned long)atoi(volume_name); /* overwritten below */
|
||||
|
||||
@@ -19,15 +19,19 @@ The current salvage tests cover:
|
||||
|
||||
- local layout contract for `.recycle` payloads and `.salvage` JSON metadata,
|
||||
- NCP create/delete capture through the normal server delete path,
|
||||
- Samba-compatible history naming with `Copy #1 of NAME`,
|
||||
- NCP `87/16` Scan Salvageable Files through the official `ncpfs` helper API,
|
||||
- Samba-compatible, non-localized history naming with `Copy #1 of NAME`,
|
||||
- NCP `87/16` scan, `87/17` recover, and `87/18` purge through the official
|
||||
`ncpfs` helper API,
|
||||
- stale `.salvage` sidecars are ignored and cleaned when their `.recycle`
|
||||
payload is externally removed,
|
||||
- report-file generation with `--out FILE`.
|
||||
|
||||
`tests/salvage/salvage_smoke_suite.sh` is the single NCP integration entry
|
||||
point. It creates and deletes the same file twice, then appends the `87/16` scan check,
|
||||
so one report covers delete capture, history/versioning, and scan visibility.
|
||||
The scan check expects duplicate sequence entries for the original deleted name;
|
||||
the `Copy #1 of ...` history path is validated through the JSON sidecars.
|
||||
point. It creates multiple versions of the same file through NCP, deletes them
|
||||
through NCP, scans salvageable entries, recovers the oldest sequence, and checks
|
||||
the restored payload through NCP read. The scan check expects duplicate
|
||||
sequence entries for the original deleted name; backend history paths stay
|
||||
hidden behind the salvage endpoints.
|
||||
|
||||
The NCP smoke suite is intended to run as the same Unix user that normally runs
|
||||
the test client, not necessarily as root. Pre-clean of old `.recycle` or
|
||||
|
||||
@@ -87,7 +87,8 @@ SYS/.salvage/SUPERVISOR/PUBLIC/Copy #1 of SLVGCHK.TXT.json
|
||||
|
||||
If `v` is not enabled, or a file matches the `noversions` list, the old recycle
|
||||
payload/metadata is replaced instead of creating a `Copy #x of ...` history
|
||||
entry.
|
||||
entry. The `Copy #n of ...` prefix is intentionally not localized; it follows
|
||||
Samba `vfs_recycle` literally and should be stable across server locales.
|
||||
|
||||
## Layout smoke
|
||||
|
||||
@@ -99,7 +100,9 @@ require a running mars_nwe server and does not use NCP.
|
||||
```
|
||||
|
||||
It verifies the basic `.recycle`/`.salvage` directory contract and stale JSON
|
||||
detection.
|
||||
detection. Runtime scans also treat `.salvage` JSON as a sidecar for the
|
||||
matching `.recycle` payload: if the payload is removed externally, the entry
|
||||
must disappear from `87/16` scan results and the stale JSON should be cleaned.
|
||||
|
||||
## NCP path visibility
|
||||
|
||||
|
||||
Reference in New Issue
Block a user