diff options
Diffstat (limited to 'src/usr/local/sbin/ufslabels.sh')
-rwxr-xr-x | src/usr/local/sbin/ufslabels.sh | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/usr/local/sbin/ufslabels.sh b/src/usr/local/sbin/ufslabels.sh new file mode 100755 index 0000000..bded665 --- /dev/null +++ b/src/usr/local/sbin/ufslabels.sh @@ -0,0 +1,149 @@ +#!/bin/sh +############################################ +# +# Change fstab to use ufsid and geom labels to avoid relying on device numbers directly. +# +############################################ + +# : cat /etc/fstab +# # Device Mountpoint FStype Options Dump Pass# +# /dev/ad0s1a / ufs rw 1 1 +# /dev/ad0s1b none swap sw 0 0 + +string_length() { + unset LEN + LEN=$(echo -n "${1}" | /usr/bin/wc -m) +} + +get_ufsid() { + # $1 = device + # : /sbin/dumpfs /dev/ad0s1a | /usr/bin/head -n 2 | /usr/bin/tail -n 1 | /usr/bin/cut -f2 -d'[' | /usr/bin/cut -f1 -d ']' | /usr/bin/sed -e 's/[[:blank:]]//g' + # 51928c99a471c440 + + unset UFSID + local _dev="${1}" + + if [ -z "${_dev}" ]; then + return + fi + + ID_PARTS=$(/sbin/dumpfs /dev/${_dev} | \ + /usr/bin/head -n 2 | \ + /usr/bin/tail -n 1 | \ + /usr/bin/cut -f2 -d'[' | \ + /usr/bin/cut -f1 -d ']') + # " 51110eb0 f288b35d " (note it has more spaces than we need/want) + ID_PART1=$(echo ${ID_PARTS} | awk '{print $1}') + # "51110eb0" + ID_PART2=$(echo ${ID_PARTS} | awk '{print $2}') + # "f288b35d" + + if [ -z "${ID_PART1}" -o -z "${ID_PART2}" ]; then + echo "Invalid ufsid on ${1} (${ID_PARTS}), cannot continue" + exit -1 + fi + + # Safety check to avoid http://www.freebsd.org/cgi/query-pr.cgi?pr=156908 + string_length "${ID_PART1}" + if [ ${LEN} -ne 8 ]; then + ID_PART1=$(printf "%08s" "${ID_PART1}") + fi + string_length "${ID_PART2}" + if [ ${LEN} -ne 8 ]; then + ID_PART2=$(printf "%08s" "${ID_PART2}") + fi + UFSID="${ID_PART1}${ID_PART2}" +} + +find_fs_device() { + unset DEV + DEV=$(/usr/bin/grep -e "[[:blank:]]*${1}[[:blank:]]" ${FSTAB} | awk '{print $1}') + DEV=${DEV##/dev/} +} + +FSTAB=${DESTDIR}/etc/fstab +unset NEED_CHANGES +cp ${FSTAB} ${FSTAB}.tmp + +ALL_FILESYSTEMS=$(/usr/bin/awk '/ufs/ && !(/dev\/mirror\// || /dev\/ufsid\// || /dev\/label\// || /dev\/geom\//) {print $2}' ${DESTDIR}/etc/fstab) + +for FS in ${ALL_FILESYSTEMS} +do + find_fs_device "${FS}" + if [ "${DEV}" != "" ]; then + get_ufsid ${DEV} + string_length "${UFSID}" + if [ ${LEN} -ne 16 ]; then + echo "Invalid UFS ID for FS ${FS} ($UFSID), skipping" + else + /usr/bin/sed -i '' -e "s/${DEV}/ufsid\/${UFSID}/g" ${FSTAB}.tmp + NEED_CHANGES=1 + fi + else + echo "Unable to find device for ${FS}" + exit -1 + fi + echo "FS: ${FS} on device ${DEV} with ufsid ${UFSID}" +done + +ALL_SWAPFS=$(/usr/bin/awk '/swap/ && !(/dev\/mirror\// || /dev\/ufsid\// || /dev\/label\// || /dev\/geom\//) {print $1}' ${DESTDIR}/etc/fstab) +SWAPNUM=0 +for SFS in ${ALL_SWAPFS} +do + DEV=${SFS##/dev/} + if [ "${DEV}" != "" ]; then + SWAPDEV=${DEV} + echo "FS: Swap slice ${SWAPNUM} on device ${SWAPDEV}" + if [ "${SWAPDEV}" != "" ]; then + /usr/bin/sed -i '' -e "s/${SWAPDEV}/label\/swap${SWAPNUM}/g" ${FSTAB}.tmp + NEED_CHANGES=1 + fi + SWAPNUM=$((SWAPNUM+1)) + fi +done + +if [ -z "${NEED_CHANGES}" ]; then + echo Nothing to do, all filesystems and swap already use some form of device-independent labels + exit 0 +fi + +echo "====================" +echo "Current fstab:" +cat ${FSTAB} +echo "====================" +echo "New fstab:" +cat ${FSTAB}.tmp + +if [ "${1}" = "commit" ]; then + COMMIT=y +else + echo "Commit changes? (y/n):" + read COMMIT +fi + +# Commit changes +if [ "${COMMIT}" = "y" -o "${COMMIT}" = "Y" ]; then + + echo "Applying label to swap partition" + SWAPNUM=0 + for SFS in ${ALL_SWAPFS} + do + find_fs_device "${SFS}" + if [ "${DEV}" != "" ]; then + SWAPDEV=${DEV} + if [ -n "${SWAPDEV}" ]; then + echo "Disabling swap ${SWAPDEV} to apply label" + /sbin/swapoff /dev/${SWAPDEV} + /sbin/glabel label swap${SWAPNUM} /dev/${SWAPDEV} + fi + SWAPNUM=$((SWAPNUM+1)) + fi + done + + echo "Activating new fstab" + /bin/mv -f ${FSTAB} ${FSTAB}.old + /bin/mv -f ${FSTAB}.tmp ${FSTAB} + + echo "Re-enabling swap" + /sbin/swapon -a 2>/dev/null >/dev/null +fi |