#!/bin/bash # # There is a race condition with gnupg --verify when multiple processes # act at the same time. # strace helps cause the race condition (probably by slowing thing down) # gpgv does not seem to have the issue. # # args given to this are passed through to gpg. so '--lock-once' # would seem like it should fix the problem, but does not. # # without creating the GNUPGHOME, first, we see frequent errors like: ## gpg: Signature made Fri 10 Jan 2014 05:41:43 PM UTC using DSA key ID 437D05B5 ## gpg: fatal: /home/ubuntu/.gnupg/trustdb.gpg: invalid trustdb ## secmem usage: 1408/1408 bytes in 2/2 blocks of pool 1408/32768 # # with it, we see errors in the --verify stage ## gpg: Signature made Fri 10 Jan 2014 05:41:43 PM UTC using DSA key ID 437D05B5 ## gpg: 12: read expected rec type 10, got 0 ## gpg: lookup_hashtable failed: trust database error ## gpg: trustdb: searching trust record failed: trust database error ## gpg: Error: The trustdb is corrupted. ## gpg: You may try to re-create the trustdb using the commands: ## gpg: cd ~/.gnupg ## gpg: gpg2 --export-ownertrust > otrust.tmp ## gpg: rm trustdb.gpg ## gpg: gpg2 --import-ownertrust < otrust.tmp ## gpg: If that does not work, please consult the manual export GNUPGHOME="$PWD/out.gnupghome" cmd=( gpg --verify ) if [ "${USE_GPGV:-0}" != "0" ]; then #gpgv does not seem to have the issue cmd=( gpgv ) else rm -Rf "$GNUPGHOME" mkdir "$GNUPGHOME" && chmod 700 "$GNUPGHOME" fi url="http://archive.ubuntu.com/ubuntu/dists/precise-updates/main/installer-amd64/20101020ubuntu136.15/images" kr=/usr/share/keyrings/ubuntu-archive-keyring.gpg for f in SHA256SUMS SHA256SUMS.gpg; do [ -f "$f" ] && continue wget "$url/$f" -O $f.tmp && mv "$f.tmp" "$f" || { echo "failed get $url/$f"; exit 1; } done pids=( ) max=100 case "$1" in [0-9]|[0-9][0-9]|[0-9][0-9][0-9]) max="$1"; shift;; esac echo "max=$max cmd=${cmd[*]} args: $*" for((i=0;i<$max;i++)); do strace -o out.$i.strace \ "${cmd[@]}" "--keyring=$kr" SHA256SUMS.gpg SHA256SUMS >out.$i 2>&1 & pids[${#pids[@]}]=$! done for((i=0;i<$max;i++)); do wait ${pids[$i]} ret=$? [ $ret -eq 0 ] || { echo "$i failed: out.$i [$ret]" 1>&2; errors=$(($errors+1)); } done exit $errors