summaryrefslogtreecommitdiffstats
path: root/src/usr/local/sbin/ufslabels.sh
blob: bded665153e0bc3a22e46e6ad5c9f52bdea8a664 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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
OpenPOWER on IntegriCloud