Program name: DripCopy
One‑line description: A resilient, rate‑limited, one‑file‑per‑second copier for CD/DVD data on low‑power or unstable USB hosts (e.g., Raspberry Pi), designed to prevent optical drives from ramping to high RPM and brown‑out resetting.
Conventional file copying from optical media (e.g., cp -a, rsync, or dumping the whole block device with dd) can cause external USB CD/DVD drives to spin up to high RPM. On hosts with limited 5 V current—typical of single‑board computers and many bus‑powered ports—these sustained spin‑ups lead to voltage sag, USB resets, and kernel‑level I/O errors (often surfacing as “Input/output error” or the misleading “Cannot allocate memory” during directory enumeration). Once the device resets, the filesystem view may partially collapse, causing repeated paths, inflated file counts, and stalled transfers.
DripCopy addresses this by copying gently:
- It throttles each file read (via
pv -L) to a user‑specified rate (e.g., 150 KiB/s), making the drive firmware less likely to jump to full RPM. - It paces the drive with a 1‑second sleep between files, allowing the spindle and the 5 V rail to recover.
- It deduplicates paths on the fly, so transient directory read glitches do not cause repeated work or runaway counts.
- It skips already‑copied outputs (size match) to support resumable operation.
- It performs atomic writes to avoid partial/corrupt outputs on interruption.
- It retries failures and attempts to remount if the device disappears.
- It records success and error logs for post‑run analysis.
The result is a practical, fault‑tolerant way to extract files from discs when you cannot (yet) use a powered USB hub or dual‑plug Y‑cable, and when imaging the entire disc with ddrescue is overkill or impossible due to repeated bus resets.
Note: If you require a bit‑perfect image of the disc, use
ddrescuewith a mapfile on/dev/srXand power the drive adequately.DripCopyfocuses on file extraction with high tolerance for flaky power and transient device resets.
- Rate‑limited per‑file I/O using
pv -L(default 150 KiB/s; configurable). - One‑file‑per‑second pacing (
sleep 1by default; configurable). - On‑the‑fly de‑duplication of paths from
findto neutralize repeated directory entries under I/O stress. - Resumable runs that skip already‑copied files by size.
- Atomic writes via a
*.parttemporary withmvon success. - Best‑effort kernel hints to reduce readahead bursts (
read_ahead_kb=0,blockdev --setra 0). - Retry logic per file with back‑off delay.
- Mount recovery attempts if the automounted path collapses after a USB reset.
- Structured logs under
DEST/.slow_copy_logs/for successes and failures.
- OS: Linux (tested on Debian/Raspberry Pi OS “bookworm”).
- Shell/tools:
bash,find,stat,mv,touch,tee. - Required package:
pvfor rate limiting. - Optional:
sudofor adjusting readahead on/dev/srXand for mounting; administrator privileges may be needed depending on your setup.
Install pv on Debian/Ubuntu/Raspberry Pi OS:
sudo apt-get update && sudo apt-get install -y pv- Place
dripcopy.shsomewhere on your$PATH(e.g.,~/binor/usr/local/bin). - Make it executable:
chmod +x dripcopy.sh
- Ensure your disc is inserted and recognized (often automounted under
/media/$USER/...).
Basic invocation (defaults shown below are sensible for Raspberry Pi‑class hardware):
./dripcopy.shYou can override behavior without editing the script by setting variables on the command line:
-
DEVICE: Optical device node. Default:
/dev/sr1
Example:DEVICE=/dev/sr0 ./dripcopy.sh -
SRC_ROOT: Mountpoint of the disc. Default:
/media/den/Genki1_text1
The script will auto‑detect the current automount forDEVICEifSRC_ROOTis not a mount point. -
FOLDERS: Top‑level folders (array) to copy. Default:
("Genki1_KaiwaBunpo-hen" "Genki1_Yomikaki-hen")
Example:FOLDERS='("AUDIO_TS" "VIDEO_TS")' ./dripcopy.sh -
DEST: Destination directory for copied files. Default:
~/cd_copy -
RATE: Per‑file read limit passed to
pv -L. Default:150k
Lower this (e.g.,120kor100k) if the drive still spins up or resets; raise slightly if stable. -
SLEEP_BETWEEN: Seconds to sleep between files. Default:
1 -
RETRIES: Copy retries per file. Default:
3 -
RETRY_SLEEP: Seconds to sleep before each retry. Default:
3 -
READAHEAD_KB: Kernel readahead hint for
/dev/srX. Default:0(disable).
Examples
Copy with tighter throttling and longer rests:
RATE=120k SLEEP_BETWEEN=2 ./dripcopy.shUse a different device and destination:
DEVICE=/dev/sr0 DEST="$HOME/genki_copy" ./dripcopy.shSpecify your own top‑level folders:
FOLDERS='("DiscContent" "Exercises")' ./dripcopy.sh- Setup and tuning. Optionally reduces kernel readahead for the optical device to prevent bursty reads that cause sudden spin‑ups. Ensures
DESTis writable by the invoking user. - Mount resolution. Verifies that
SRC_ROOTis a mount point; if not, attempts to discover the current automount forDEVICE(via/proc/mounts) and uses it. - Streamed traversal. For each specified top‑level folder, the script streams a
find -print0of files and processes entries one at a time. - De‑duplication. Maintains an in‑memory hash of seen paths to ignore duplicates caused by transient kernel read glitches.
- Skip already‑copied. Compares source and destination sizes; identical sizes are skipped to allow resumable runs.
- Throttled copy. Uses
pv -L RATEto throttle each file read, writing to a*.partfile, then atomically renames to the target path on success; preserves modification times (touch -r). - Retries and recovery. On failure, waits
RETRY_SLEEPseconds and retries up toRETRIEStimes; if the source disappeared, it attempts to re‑establish the mount and continues. - Pacing. Sleeps
SLEEP_BETWEENseconds between files to let the drive and USB 5 V rail recover. - Logging. Records successes in
copied_*.logand errors inerrors_*.logunderDEST/.slow_copy_logs/.
- Use DripCopy when you primarily need the files and your host’s USB power is marginal. DripCopy minimizes sustained current draw and tolerates transient resets.
- Use ddrescue when you need a bit‑exact image (ISO) or forensic‑grade recovery. For ddrescue to work well, supply adequate power (powered USB hub or Y‑cable) so the device does not reset mid‑read.
-
“Cannot allocate memory” while listing or copying from the mountpoint:
This is typically an optical I/O error/USB reset surfacing via the VFS path. Unmount, power‑cycle the drive, lowerRATE, and try again. Consider a powered hub. -
“No medium found” / device disappears:
The drive likely brown‑ed out and reset. Power‑cycle; tryRATE=100kand ensureSLEEP_BETWEEN≥1. A powered hub solves this decisively. -
Repeated path entries / inflated file counts:
Caused by transient errors during directory enumeration. DripCopy de‑duplicates entries, so it safely ignores duplicates and continues. -
Permission denied writing to
DEST:
If you previously wrote asroot, fix ownership:sudo chown -R "$USER":"$USER" "$DEST" chmod -R u+rwX "$DEST"
-
Automounter conflicts:
If the desktop automounter fights with manual mounts, prefer the existing automount path. DripCopy will discover and use it automatically when possible.
- DripCopy does not validate file integrity beyond size and successful read completion; it is not a bit‑exact imaging tool.
- If firmware insists on full‑RPM retries for damaged sectors, even low
RATEmay not prevent spin‑up; hardware power fixes (powered USB hub/Y‑cable) are then required. - De‑duplication is path‑based; if the kernel returns different bogus paths for the same on‑disc object, both may be attempted (harmless but noisy).
- Spot‑check with
file,ffprobe, or media players for audio content. - Use checksums if you have a known‑good reference:
(cd "$DEST" && find . -type f -print0 | xargs -0 md5sum) > DEST.md5
MIT License. See header in dripcopy.sh for details.
- The
pvutility by Andrew Wood. - The Linux kernel & userspace tools (
find,stat,blockdev) that make controlled I/O patterns possible on constrained hardware.
- v0.1.0 — First public release: streamed traversal, per‑file throttling, de‑duplication, retries, remount attempt, atomic writes, resumable operation.