gates / gates (push) Successful in 7m2s
Closed R-1115, R-1111, R-1112, R-1113, R-1109, R-1110, R-1114, R-1096; opened R-1116 (decoy suites in the other runners), R-1117 (Immich/Nextcloud Redis volume, deferred). Controller 0.325.0 is the floor since 08:21 UTC. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
49 lines
3.7 KiB
Bash
Executable File
49 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# damage.sh — R-1096 step 3, inside scratch guest 9202. Throwaway containers named r1096-*, removed at the end.
|
|
# Input: /root/r1096/aof-copy = docmost-redis's /data copied while it ran the OLD form (AOF), taken before the switch.
|
|
set -u
|
|
IMG=redis:7-alpine
|
|
W=/root/r1096/work; rm -rf $W; mkdir -p $W
|
|
say() { echo "== $*"; }
|
|
run_on() { # run_on <dir> <args...>: start redis on a COPY of <dir>, report whether it serves and its last log lines
|
|
local d=$1; shift
|
|
docker rm -f r1096-probe >/dev/null 2>&1
|
|
docker run -d --name r1096-probe -v $d:/data $IMG redis-server "$@" >/dev/null
|
|
sleep 4
|
|
echo " state: $(docker inspect -f '{{.State.Status}} exit={{.State.ExitCode}}' r1096-probe)"
|
|
echo " dbsize: $(docker exec r1096-probe redis-cli DBSIZE 2>&1 | head -1) probe key 7: $(docker exec r1096-probe redis-cli GET felhom:probe:7 2>&1 | cut -c1-6)…"
|
|
docker logs r1096-probe 2>&1 | grep -iE 'Bad file|Unrecoverable|Short read|corrupt|loaded|fix|Ready|aborting|error|Done loading' | tail -4 | sed 's/^/ log: /'
|
|
docker rm -f r1096-probe >/dev/null 2>&1
|
|
}
|
|
|
|
say "A1 CONTROL: the old-form copy, undamaged, --appendonly yes"
|
|
cp -a /root/r1096/aof-copy $W/a1; chown -R 999:1000 $W/a1
|
|
run_on $W/a1 --appendonly yes
|
|
|
|
say "A2 the old form, damaged the 2026-09-24 way: 64 zero bytes written INTO the AOF, 400 bytes before its end"
|
|
cp -a /root/r1096/aof-copy $W/a2; chown -R 999:1000 $W/a2
|
|
F=$W/a2/appendonlydir/appendonly.aof.1.incr.aof; S=$(stat -c %s $F)
|
|
dd if=/dev/zero of=$F bs=1 seek=$((S-400)) count=64 conv=notrunc status=none
|
|
echo " file $S bytes, zeros at $((S-400))..$((S-337)); size after $(stat -c %s $F)"
|
|
run_on $W/a2 --appendonly yes
|
|
|
|
say "R1 the NEW form on a FULL disk (tmpfs 1 MiB): a save that cannot be written"
|
|
docker rm -f r1096-full >/dev/null 2>&1
|
|
docker run -d --name r1096-full --tmpfs /data:rw,size=1m,uid=999,gid=1000 $IMG sleep infinity >/dev/null
|
|
docker exec r1096-full sh -c 'mkdir -p /data/r && chown redis /data/r && su redis -s /bin/sh -c "redis-server --port 6390 --dir /data/r --appendonly no --daemonize yes --logfile /data/r.log" ' ; sleep 1
|
|
docker exec r1096-full sh -c 'for i in $(seq 1 50); do redis-cli -p 6390 SET felhom:probe:$i v$i >/dev/null; done; redis-cli -p 6390 SAVE; sha256sum /data/r/dump.rdb; ls -la /data/r'
|
|
echo " now 1.2 MB of new data, which cannot fit:"
|
|
docker exec r1096-full sh -c 'head -c 900000 /dev/urandom | base64 -w0 | redis-cli -p 6390 -x SET big >/dev/null; redis-cli -p 6390 BGSAVE; sleep 2; redis-cli -p 6390 INFO persistence | grep -E "rdb_last_bgsave_status|rdb_changes_since"; redis-cli -p 6390 SET after-fail 1; sha256sum /data/r/dump.rdb; ls -la /data/r; df -k /data | tail -1; tail -3 /data/r.log'
|
|
echo " stop WITHOUT saving (what a kill does), start again on the same folder:"
|
|
docker exec r1096-full sh -c 'redis-cli -p 6390 SHUTDOWN NOSAVE; sleep 1; su redis -s /bin/sh -c "redis-server --port 6390 --dir /data/r --appendonly no --daemonize yes --logfile /data/r2.log"; sleep 1; echo " dbsize after start: $(redis-cli -p 6390 DBSIZE) probe 7: $(redis-cli -p 6390 GET felhom:probe:7)"; grep -E "Done loading|Short read|Unrecoverable" /data/r2.log | tail -2'
|
|
docker rm -f r1096-full >/dev/null
|
|
|
|
say "R2 what a TRUNCATED dump.rdb does (half the file) — the shape the temp-file-and-rename write never leaves behind"
|
|
mkdir -p $W/r2; cp /var/lib/docker/volumes/docmost_docmost_redis_data/_data/dump.rdb $W/r2/full.rdb
|
|
S=$(stat -c %s $W/r2/full.rdb); head -c $((S/2)) $W/r2/full.rdb > $W/r2/dump.rdb; rm $W/r2/full.rdb; chown -R 999:1000 $W/r2
|
|
echo " dump.rdb cut from $S to $(stat -c %s $W/r2/dump.rdb) bytes"
|
|
run_on $W/r2 --appendonly no
|
|
|
|
rm -rf $W
|
|
say "cleanup: $(docker ps -a --filter name=r1096- --format '{{.Names}}' | wc -l) r1096-* containers left"
|