The existing logic is nice in theory, but in practice freebsd-update will not preserve the timestamps on these files. When doing a major upgrade, e.g. from 12.1-RELEASE -> 12.2-RELEASE, pwd.mkdb et al. appear in the INDEX and we clobber the timestamp several times in the process of packaging up the existing system into /var/db/freebsd-update/files and extracting for comparisons. This leads to these files not getting regenerated when they're most likely to be needed.
[aside]
I had a diff in progress to preserve timestamps, but ultimately decided that the cost to do so was much greater than just regenerating them every time:
root@viper:/usr/src/usr.sbin/freebsd-update# cat freebsd-update.diff --- freebsd-update.orig 2020-12-16 08:31:41.992097000 -0600 +++ freebsd-update 2020-12-16 10:43:11.812398000 -0600 @@ -1869,7 +1869,7 @@ fi # Make sure the file hasn't changed. - cp "${BASEDIR}/${F}" tmpfile + cp -p "${BASEDIR}/${F}" tmpfile if [ `sha256 -q tmpfile` != ${HASH} ]; then echo echo "File changed while FreeBSD Update running: ${F}" @@ -1877,8 +1877,8 @@ fi # Place the file into storage. - gzip -c < tmpfile > files/${HASH}.gz - rm tmpfile + mv tmpfile files/${HASH} + gzip files/${HASH} done < $2.hashes # Produce a list of patches to download @@ -2389,7 +2389,8 @@ while read F; do # Currently installed file V=`look "${F}|" $2 | cut -f 7 -d '|'` - gunzip < files/${V}.gz > merge/old/${F} + cp -p files/${V}.gz merge/old/${F}.gz + gunzip merge/old/${F}.gz # Old release if look "${F}|" $1 | fgrep -q "|f|"; then @@ -2432,7 +2433,7 @@ /etc/spwd.db | /etc/pwd.db | /etc/login.conf.db) # Don't merge these -- we're rebuild them # after updates are installed. - cp merge/old/${F} merge/new/${F} + cp -p merge/old/${F} merge/new/${F} ;; *) if ! diff3 -E -m -L "current version" \ @@ -2514,7 +2515,8 @@ if [ -f merge/new/${F} ]; then V=`${SHA256} -q merge/new/${F}` - gzip -c < merge/new/${F} > files/${V}.gz + cp -p merge/new/${F} files/${V} + gzip files/${V} echo "${F}|${V}" fi done < $1-paths > newhashes @@ -2818,10 +2820,10 @@ f) if [ -z "${LINK}" ]; then # Create a file, without setting flags. - gunzip < files/${HASH}.gz > ${HASH} - install -S -o ${OWNER} -g ${GROUP} \ - -m ${PERM} ${HASH} ${BASEDIR}/${FPATH} - rm ${HASH} + gunzip -k files/${HASH}.gz + install -Sp -o ${OWNER} -g ${GROUP} \ + -m ${PERM} files/${HASH} ${BASEDIR}/${FPATH} + rm files/${HASH} else # Create a hard link. ln -f ${BASEDIR}/${LINK} ${BASEDIR}/${FPATH}