#!/bin/sh # Self-contained POSIX tests for exact RDS data-volume selection and formatting # authorization. Fake sysfs and command stubs avoid root and block devices. set -eu SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) SCRIPT="${SCRIPT_DIR}/rds-datadir" WORK=$(mktemp -d) trap 'rm -rf "${WORK}"' EXIT STUBBIN="${WORK}/bin" mkdir -p "${STUBBIN}" cat > "${STUBBIN}/blkid" <<'EOF' #!/bin/sh [ "$1" = "-p" ] && [ "$2" = "-o" ] && [ "$3" = "export" ] || exit 4 dev="$4" kind=$(awk -v d="${dev}" '$1 == d { print $2; exit }' "${PROBE_TABLE}" 2>/dev/null) value=$(awk -v d="${dev}" '$1 == d { print $3; exit }' "${PROBE_TABLE}" 2>/dev/null) case "${kind}" in fs) printf 'DEVNAME=%s\nTYPE=%s\n' "${dev}" "${value}" ;; pttable) printf 'DEVNAME=%s\nPTTYPE=%s\n' "${dev}" "${value:-gpt}" ;; fspt) printf 'DEVNAME=%s\nTYPE=%s\nPTTYPE=gpt\n' "${dev}" "${value}" ;; ambiguous) exit 8 ;; unreadable) echo "read error" >&2; exit 2 ;; error) exit 4 ;; *) exit 2 ;; esac EOF cat > "${STUBBIN}/mkfs.ext4" <<'EOF' #!/bin/sh echo "mkfs.ext4 $*" >> "${MKFS_CALLS}" [ "${MKFS_FAIL:-0}" = "1" ] && exit 1 dev="" for arg in "$@"; do dev="${arg}"; done printf '%s fs ext4\n' "${dev}" >> "${PROBE_TABLE}" EOF cat > "${STUBBIN}/mount" <<'EOF' #!/bin/sh echo "mount $*" >> "${MOUNT_CALLS}" exit "${MOUNT_RC:-0}" EOF cat > "${STUBBIN}/chown" <<'EOF' #!/bin/sh echo "chown $*" >> "${CHOWN_CALLS}" EOF chmod +x "${STUBBIN}"/* PATH="${STUBBIN}:${PATH}" export PATH FAILS=0 fail() { echo "FAIL: $*"; FAILS=$((FAILS + 1)); } pass() { echo "ok: $*"; } DATA_MOUNT="${WORK}/data" ENGINE_USER="dbengine" SYS_BLOCK="${WORK}/sys/block" DEV_DIR="${WORK}/dev" MOUNTS="${WORK}/mounts" HANDOFF="${WORK}/handoff/bootstrap.env" PROBE_TABLE="${WORK}/probe.table" MKFS_CALLS="${WORK}/mkfs.calls" MOUNT_CALLS="${WORK}/mount.calls" CHOWN_CALLS="${WORK}/chown.calls" export PROBE_TABLE MKFS_CALLS MOUNT_CALLS CHOWN_CALLS add_disk() { mkdir -p "${SYS_BLOCK}/$1" "${DEV_DIR}" : > "${DEV_DIR}/$1" [ -n "${2:-}" ] && printf '%s\n' "$2" > "${SYS_BLOCK}/$1/serial" return 0 } add_partition() { mkdir -p "${SYS_BLOCK}/$1/$1$2"; } write_handoff() { mkdir -p "$(dirname "${HANDOFF}")" cat > "${HANDOFF}" < "${MOUNTS}" : > "${PROBE_TABLE}" : > "${MKFS_CALLS}" : > "${MOUNT_CALLS}" : > "${CHOWN_CALLS}" unset MKFS_FAIL MOUNT_RC || true write_handoff vol-expected volexpected 1 false } run() { env RDS_DATA_MOUNT="${DATA_MOUNT}" \ RDS_ENGINE_USER="${ENGINE_USER}" \ RDS_SYS_BLOCK="${SYS_BLOCK}" \ RDS_DEV_DIR="${DEV_DIR}" \ RDS_MOUNTS_FILE="${MOUNTS}" \ RDS_HANDOFF_ENV="${HANDOFF}" \ RDS_DATA_VOLUME_WAIT=1 \ MKFS_FAIL="${MKFS_FAIL:-0}" \ MOUNT_RC="${MOUNT_RC:-0}" \ sh "${SCRIPT}" "${WORK}/out" 2>&1; then pass "$1" return 0 fi fail "$1: non-zero exit: $(cat "${WORK}/out")" return 1 } # A refusal must be diagnosable on the serial console, so the expected reason is # asserted too: a non-zero exit alone also matches a script that died silently. # Always returns 0; a non-zero status here would abort the suite under set -e. run_fails() { if run > "${WORK}/out" 2>&1; then fail "$1: expected a non-zero exit" elif ! grep -q "\[rds-datadir\] ERROR: .*$2" "${WORK}/out"; then fail "$1: refused without reporting '$2': $(cat "${WORK}/out")" else pass "$1: refused with a reported reason" fi return 0 } nothing_formatted() { if grep -q . "${MKFS_CALLS}"; then fail "$1: unexpectedly ran mkfs"; else pass "$1: no mkfs"; fi } # A matching create grant formats only the exact disk and consumes only the # authorization line. An unrelated generic volume is ignored. reset_state add_disk vda add_disk vdb volunrelated add_disk vdc volexpected write_handoff vol-expected volexpected 1 true if run_ok "authorized blank exact volume"; then grep -q "mkfs.ext4 .*${DEV_DIR}/vdc" "${MKFS_CALLS}" && pass "authorized: exact disk formatted" || fail "authorized: exact disk not formatted" grep -q -- '-m 0' "${MKFS_CALLS}" && pass "authorized: no reserved blocks" || fail "authorized: reserved blocks left on" grep -q "mount -t ext4 ${DEV_DIR}/vdc ${DATA_MOUNT}" "${MOUNT_CALLS}" && pass "authorized: mounted" || fail "authorized: not mounted" # The engine reads its own datadir, so the mount is handed to the preset's # user rather than to whichever engine this script was first written for. grep -q "chown ${ENGINE_USER}:${ENGINE_USER} ${DATA_MOUNT}" "${CHOWN_CALLS}" && pass "authorized: handed to the engine user" || fail "authorized: not handed to ${ENGINE_USER}" grep -q '^RDS_MASTER_PASSWORD=' "${HANDOFF}" && pass "authorized: bootstrap material preserved" || fail "authorized: bootstrap material removed" if grep -q '^RDS_FORMAT_AUTHORIZED=' "${HANDOFF}"; then fail "authorized: grant retained"; else pass "authorized: grant consumed"; fi fi # A lone vol* disk with the wrong serial never becomes a fallback candidate, and # the absent expected volume is reported as an attach timeout. reset_state add_disk vda add_disk vdb volwrong write_handoff vol-expected volexpected 1 true run_fails "serial mismatch" "volume vol-expected with serial volexpected was not attached" nothing_formatted "serial mismatch" # Selection must not depend on sysfs enumeration order: the expected disk is # found even when an unrelated vol* disk sorts after it. reset_state add_disk vda add_disk vdb volexpected add_disk vdc volunrelated write_handoff vol-expected volexpected 1 true if run_ok "unrelated disk sorts last"; then grep -q "mkfs.ext4 .*${DEV_DIR}/vdb" "${MKFS_CALLS}" && pass "sort order: expected disk formatted" || fail "sort order: expected disk not formatted" grep -q "mount -t ext4 ${DEV_DIR}/vdb ${DATA_MOUNT}" "${MOUNT_CALLS}" && pass "sort order: mounted" || fail "sort order: not mounted" fi # Duplicate exact serials are ambiguous even if both name generic data disks. reset_state add_disk vdb volexpected add_disk vdc volexpected write_handoff vol-expected volexpected 1 true run_fails "duplicate expected serial" "refusing to choose one" nothing_formatted "duplicate expected serial" # Existing supported filesystems mount without any grant. for fs in ext4 xfs; do reset_state add_disk vdb volexpected printf '%s fs %s\n' "${DEV_DIR}/vdb" "${fs}" > "${PROBE_TABLE}" if run_ok "existing ${fs}"; then nothing_formatted "existing ${fs}" grep -q "mount -t ${fs} ${DEV_DIR}/vdb ${DATA_MOUNT}" "${MOUNT_CALLS}" && pass "existing ${fs}: mounted by type" || fail "existing ${fs}: not mounted" fi done # Blank restore/start/replacement volumes have no grant and fail closed. reset_state add_disk vdb volexpected run_fails "blank without grant" "no recognizable filesystem and this boot has no matching format authorization" nothing_formatted "blank without grant" # Partition tables, visible partitions, unsupported filesystems, ambiguity, and # operational probe errors all fail without formatting. for kind in pttable fspt unsupported ambiguous unreadable error; do reset_state add_disk vdb volexpected case "${kind}" in pttable) printf '%s pttable gpt\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="carries a partition table or partitions" ;; fspt) printf '%s fspt ext4\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="carries a partition table or partitions" ;; unsupported) printf '%s fs btrfs\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="holds unsupported filesystem btrfs" ;; ambiguous) printf '%s ambiguous x\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="ambiguous or conflicting signatures" ;; unreadable) printf '%s unreadable x\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="refusing to classify it as blank" ;; error) printf '%s error x\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" reason="could not probe" ;; esac write_handoff vol-expected volexpected 1 true run_fails "probe ${kind}" "${reason}" nothing_formatted "probe ${kind}" done # An uncreatable probe capture leaves blkid unrun, and some shells report that # as the blank-device exit 2. Root ignores the directory mode, so it cannot run # the case at all. if [ "$(id -u)" -ne 0 ]; then reset_state add_disk vdb volexpected write_handoff vol-expected volexpected 1 true chmod 0500 "$(dirname "${HANDOFF}")" run_fails "unwritable probe capture" "could not create the probe error capture" nothing_formatted "unwritable probe capture" chmod 0700 "$(dirname "${HANDOFF}")" fi reset_state add_disk vdb volexpected add_partition vdb 1 printf '%s fs ext4\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" write_handoff vol-expected volexpected 1 true run_fails "sysfs partition plus filesystem" "carries a partition table or partitions" nothing_formatted "sysfs partition plus filesystem" # Missing identity and invalid generation cannot authorize even when true. for field in id serial generation; do reset_state add_disk vdb volexpected write_handoff vol-expected volexpected 1 true case "${field}" in id) sed -i "s/RDS_DATA_VOLUME_ID='vol-expected'/RDS_DATA_VOLUME_ID=''/" "${HANDOFF}" reason="has no RDS_DATA_VOLUME_ID" ;; serial) sed -i "s/RDS_DATA_VOLUME_SERIAL='volexpected'/RDS_DATA_VOLUME_SERIAL=''/" "${HANDOFF}" reason="has no RDS_DATA_VOLUME_SERIAL" ;; generation) sed -i "s/RDS_VM_GENERATION='1'/RDS_VM_GENERATION='0'/" "${HANDOFF}" reason="invalid RDS_VM_GENERATION" ;; esac run_fails "invalid ${field}" "${reason}" nothing_formatted "invalid ${field}" done # A failed format retains the one boot's grant for a legitimate retry. reset_state add_disk vdb volexpected write_handoff vol-expected volexpected 1 true MKFS_FAIL=1 run_fails "mkfs failure" "mkfs.ext4 failed on" grep -q '^RDS_FORMAT_AUTHORIZED=' "${HANDOFF}" && pass "mkfs failure: grant retained" || fail "mkfs failure: grant lost" [ ! -s "${MOUNT_CALLS}" ] && pass "mkfs failure: not mounted" || fail "mkfs failure: mounted raw disk" # If mkfs succeeded but the guest died before consuming the line, observing the # supported filesystem consumes it without formatting again. reset_state add_disk vdb volexpected printf '%s fs ext4\n' "${DEV_DIR}/vdb" > "${PROBE_TABLE}" write_handoff vol-expected volexpected 1 true if run_ok "lingering grant on filesystem"; then nothing_formatted "lingering grant" if grep -q '^RDS_FORMAT_AUTHORIZED=' "${HANDOFF}"; then fail "lingering grant: retained"; else pass "lingering grant: consumed"; fi fi # A service restart verifies the mounted source is the expected exact device and # removes any lingering authorization. reset_state add_disk vdb volexpected printf '%s %s ext4 rw 0 0\n' "${DEV_DIR}/vdb" "${DATA_MOUNT}" >> "${MOUNTS}" write_handoff vol-expected volexpected 1 true if run_ok "already mounted exact device"; then [ ! -s "${MOUNT_CALLS}" ] && pass "already mounted: no duplicate mount" || fail "already mounted: mounted twice" if grep -q '^RDS_FORMAT_AUTHORIZED=' "${HANDOFF}"; then fail "already mounted: grant retained"; else pass "already mounted: grant consumed"; fi fi reset_state add_disk vdb volexpected printf '%s %s ext4 rw 0 0\n' "${DEV_DIR}/wrong" "${DATA_MOUNT}" >> "${MOUNTS}" run_fails "already mounted wrong device" "not expected device" nothing_formatted "already mounted wrong device" # An image whose service states no layout must not fall back to another engine's # paths: a volume mounted where the engine is not looking reads as an empty # datadir, and the bootstrap that follows serves an empty database beside the # customer's data. Both refusals come before the handoff is even read. reset_state add_disk vdb volexpected write_handoff vol-expected volexpected 1 true DATA_MOUNT="" run_fails "no mount point" "RDS_DATA_MOUNT is not set" nothing_formatted "no mount point" reset_state add_disk vdb volexpected write_handoff vol-expected volexpected 1 true ENGINE_USER="" run_fails "no engine user" "RDS_ENGINE_USER is not set" nothing_formatted "no engine user" if [ "${FAILS}" -eq 0 ]; then echo "PASS: all rds-datadir cases" exit 0 fi echo "FAILED: ${FAILS} case(s)" exit 1