Skip to content

K2GO-384 feat(backup): byte-accurate progress + ETA - #536

Merged
luisguzman-adfa merged 1 commit into
mainfrom
feat/K2GO-384-backup-progress
Sep 4, 2026
Merged

K2GO-384 feat(backup): byte-accurate progress + ETA#536
luisguzman-adfa merged 1 commit into
mainfrom
feat/K2GO-384-backup-progress

Conversation

@luisguzman-adfa

Copy link
Copy Markdown
Collaborator

Gives the backup the same determinate progress bar + honest ETA the restore
already has — it was an indeterminate spinner.

What changes

  • BackupEngine streams tar -cf - (uncompressed) and does the gzip in Java
    over the SAF stream, so the uncompressed bytes tar produces are observable and
    metered against the tree's total size (du -sb installed-rootfs). Byte
    progress tracks the gzip+write time; a member count front-loads on the many
    small files and stalls on the few large ones. Reuses the restore's pure ETA
    math (ExtractProgress / TransferRate) — no new strings, tests or fragment
    change.
  • DeepOpService.runBackup feeds progress through the existing DeepOpState
    channel (cancelKind stays NONE; backup's Cancel remains on the notification).
  • The Java loop is deliberately the seam a later backup-cancel will interrupt.

Fixes a latent backup bug

--ignore-failed-read is added because proot bind-mount stubs (iiab/sdcard, …)
are runtime mounts, not rootfs content, and are unreadable with the box stopped
("Cannot open: Permission denied"). tar skips them and exits 0.

The old tar | gzip pipe hit the same read error, but waitFor() returned
gzip's exit (0), silently masking tar's exit — so "successful" backups could
drop files unnoticed. This slice honors tar's real exit and, on success, logs
any entries tar skipped, so a genuinely dropped file is never silent.

Verification

Device (arm64): a backup shows a live bar + honest ETA (~3 min shown, 3:37
actual) and completes; the skipped mount stub is logged. A round-trip —
restoring that backup — extracts successfully, confirming the Java-gzip
.tar.gz is a standard, complete archive.

Gives the backup the same determinate bar + honest ETA the restore has;
it was an indeterminate spinner.

- BackupEngine streams `tar -cf -` (uncompressed) and gzips in Java over
  the SAF stream, metering the uncompressed bytes tar emits against
  `du -sb installed-rootfs`. Byte progress tracks the gzip+write time,
  unlike a member count (which front-loads on small files and stalls on
  the large ones). Reuses the restore's pure ETA math (ExtractProgress /
  TransferRate) -- no new strings, tests or fragment change. The Java loop
  is also the seam a later backup-cancel interrupts.
- `--ignore-failed-read`: proot bind-mount stubs (iiab/sdcard, ...) are
  runtime mounts, not rootfs content, and are unreadable with the box
  stopped. tar skips them and exits 0. The old `tar | gzip` pipe hit the
  same read error but reported gzip's exit (0), silently masking tar's
  exit -- so "successful" backups could drop files unnoticed. Now tar's
  real exit is honored and skipped entries are logged even on success.
@luisguzman-adfa
luisguzman-adfa merged commit 523426b into main Sep 4, 2026
3 checks passed
@luisguzman-adfa
luisguzman-adfa deleted the feat/K2GO-384-backup-progress branch September 4, 2026 08:16
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.

1 participant