1
|
#!/bin/sh
|
2
|
#
|
3
|
# rc.ramdisk_functions.sh
|
4
|
#
|
5
|
# part of pfSense (https://www.pfsense.org)
|
6
|
# Copyright (c) 2020-2022 Rubicon Communications, LLC (Netgate)
|
7
|
# All rights reserved.
|
8
|
#
|
9
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
10
|
# you may not use this file except in compliance with the License.
|
11
|
# You may obtain a copy of the License at
|
12
|
#
|
13
|
# http://www.apache.org/licenses/LICENSE-2.0
|
14
|
#
|
15
|
# Unless required by applicable law or agreed to in writing, software
|
16
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
17
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
18
|
# See the License for the specific language governing permissions and
|
19
|
# limitations under the License.
|
20
|
|
21
|
# Source like so:
|
22
|
# . /etc/rc.ramdisk_functions.sh
|
23
|
# Then use these variables and functions wherever RAM disk operations are needed
|
24
|
|
25
|
RAMDISK_FLAG_FILE=/conf/ram_disks_failed
|
26
|
RAMDISK_DEFAULT_SIZE_tmp=40
|
27
|
RAMDISK_DEFAULT_SIZE_var=60
|
28
|
|
29
|
# Replacement for /etc/rc.d/zfsbe onestart
|
30
|
_be_remount_ds() {
|
31
|
local _dataset="${1}"
|
32
|
|
33
|
/sbin/zfs list -rH -o mountpoint,name,canmount,mounted -s mountpoint -t filesystem "${_dataset}" | \
|
34
|
while read _mp _name _canmount _mounted ; do
|
35
|
# skip filesystems that must *not* be mounted
|
36
|
[ "${_canmount}" = "off" -o "${_mp}" = "/" ] && continue
|
37
|
# unmount the dataset if mounted...
|
38
|
[ "$_mounted" = "yes" ] && /sbin/umount -f "${_name}"
|
39
|
# mount the dataset
|
40
|
/sbin/zfs mount "${_name}"
|
41
|
done
|
42
|
}
|
43
|
|
44
|
# Replacement for /etc/rc.d/zfsbe onestart
|
45
|
_be_mount_zfs() {
|
46
|
echo -n "Mounting ZFS boot environment..."
|
47
|
/sbin/mount -p | while read _dev _mp _type _rest; do
|
48
|
[ "${_mp}" = "/" ] || continue
|
49
|
if [ "${_type}" = "zfs" ] ; then
|
50
|
_be_remount_ds "${_dev}"
|
51
|
fi
|
52
|
break
|
53
|
done
|
54
|
echo " done."
|
55
|
}
|
56
|
|
57
|
# Check if RAM disks are enabled in config.xml
|
58
|
ramdisk_check_enabled () {
|
59
|
[ "$(/usr/local/sbin/read_xml_tag.sh boolean system/use_mfs_tmpvar)" = "true" ]
|
60
|
return $?
|
61
|
}
|
62
|
|
63
|
# Checks that RAM disks are both enabled and that they have not failed
|
64
|
ramdisk_is_active () {
|
65
|
ramdisk_check_enabled && [ ! -e ${RAMDISK_FLAG_FILE} ]
|
66
|
return $?
|
67
|
}
|
68
|
|
69
|
# Checks if RAM disk setup failed
|
70
|
ramdisk_failed () {
|
71
|
[ -e ${RAMDISK_FLAG_FILE} ]
|
72
|
return $?
|
73
|
}
|
74
|
|
75
|
# Resets the RAM disk failure status
|
76
|
ramdisk_reset_status () {
|
77
|
if [ -f ${RAMDISK_FLAG_FILE} ]; then
|
78
|
rm -f ${RAMDISK_FLAG_FILE}
|
79
|
fi
|
80
|
}
|
81
|
|
82
|
# Checks if RAM disks were active on a previous boot (or active now)
|
83
|
ramdisk_was_active() {
|
84
|
# If /var is on a memory disk, then RAM disks are active now or were active and recently disabled
|
85
|
DISK_NAME=`/bin/df /var/db/rrd | /usr/bin/tail -1 | /usr/bin/awk '{print $1;}'`
|
86
|
DISK_TYPE=`/usr/bin/basename ${DISK_NAME} | /usr/bin/cut -c1-2`
|
87
|
[ "${DISK_TYPE}" = "md" ]
|
88
|
return $?
|
89
|
}
|
90
|
|
91
|
# Echos the effective size of the given RAM disk (var or tmp)
|
92
|
# If set, use that value. If unset, use the default value
|
93
|
# Usage example:
|
94
|
# tmpsize = $( ramdisk_get_size tmp )
|
95
|
# varsize = $( ramdisk_get_size var )
|
96
|
ramdisk_get_size () {
|
97
|
NAME=${1}
|
98
|
DEFAULT_SIZE=$(eval echo \${RAMDISK_DEFAULT_SIZE_${NAME}})
|
99
|
|
100
|
SIZE=$(/usr/local/sbin/read_xml_tag.sh string system/use_mfs_${NAME}_size)
|
101
|
if [ -n "${SIZE}" ] && [ ${SIZE} -gt 0 ]; then
|
102
|
echo ${SIZE}
|
103
|
else
|
104
|
echo ${DEFAULT_SIZE}
|
105
|
fi
|
106
|
return 0
|
107
|
}
|
108
|
|
109
|
# Tests if the current total RAM disk size can fit in free kernel memory
|
110
|
ramdisk_check_size () {
|
111
|
tmpsize=$( ramdisk_get_size tmp )
|
112
|
varsize=$( ramdisk_get_size var )
|
113
|
# Check available RAM
|
114
|
PAGES_FREE=$( /sbin/sysctl -n vm.stats.vm.v_free_count )
|
115
|
PAGE_SIZE=$( /sbin/sysctl -n vm.stats.vm.v_page_size )
|
116
|
MEM_FREE=$( /bin/expr ${PAGES_FREE} \* ${PAGE_SIZE} )
|
117
|
# Convert to MB
|
118
|
MEM_FREE=$( /bin/expr ${MEM_FREE} / 1024 / 1024 )
|
119
|
# Total size of desired RAM disks
|
120
|
MEM_NEED=$( /bin/expr ${tmpsize} + ${varsize} )
|
121
|
[ ${MEM_FREE} -gt ${MEM_NEED} ]
|
122
|
return $?
|
123
|
}
|
124
|
|
125
|
# Attempt to mount the given RAM disk (var or tmp)
|
126
|
# Usage:
|
127
|
# ramdisk_try_mount tmp
|
128
|
# ramdisk_try_mount var
|
129
|
ramdisk_try_mount () {
|
130
|
NAME=$1
|
131
|
if [ ramdisk_check_size ]; then
|
132
|
SIZE=$(eval echo \${${NAME}size})m
|
133
|
/sbin/mount -o rw,size=${SIZE},mode=1777 -t tmpfs tmpfs /${NAME}
|
134
|
return $?
|
135
|
else
|
136
|
return 1;
|
137
|
fi
|
138
|
}
|
139
|
|
140
|
# If the install has RAM disks, or if the full install _was_ using RAM disks, make a backup.
|
141
|
ramdisk_make_backup () {
|
142
|
if ramdisk_is_active || ramdisk_was_active; then
|
143
|
echo "Backing up RAM disk contents"
|
144
|
/etc/rc.backup_aliastables.sh
|
145
|
/etc/rc.backup_rrd.sh
|
146
|
/etc/rc.backup_dhcpleases.sh
|
147
|
/etc/rc.backup_logs.sh
|
148
|
/etc/rc.backup_captiveportal.sh
|
149
|
# /etc/rc.backup_voucher.sh
|
150
|
fi
|
151
|
}
|
152
|
|
153
|
# Relocate the pkg database to a specific given location, either disk (/var) or
|
154
|
# to its safe location for use with RAM disks (/root/var)
|
155
|
# Usage:
|
156
|
# ramdisk_relocate_pkgdb disk
|
157
|
# ramdisk_relocate_pkgdb ram
|
158
|
ramdisk_relocate_pkgdb () {
|
159
|
if [ ${1} = "disk" ]; then
|
160
|
local SRC=/root
|
161
|
local DST=
|
162
|
else
|
163
|
local SRC=
|
164
|
local DST=/root
|
165
|
fi
|
166
|
|
167
|
echo "Moving pkg database for ${1} storage"
|
168
|
if [ -d ${SRC}/var/db/pkg ]; then
|
169
|
echo "Clearing ${DST}/var/db/pkg"
|
170
|
rm -rf ${DST}/var/db/pkg 2>/dev/null
|
171
|
/bin/mkdir -p ${DST}/var/db
|
172
|
echo "Moving ${SRC}/var/db/pkg to ${DST}/var/db/"
|
173
|
mv -f ${SRC}/var/db/pkg ${DST}/var/db
|
174
|
fi
|
175
|
if [ -d ${SRC}/var/cache/pkg ]; then
|
176
|
echo "Clearing ${DST}/var/cache/pkg"
|
177
|
rm -rf ${DST}/var/cache/pkg 2>/dev/null
|
178
|
/bin/mkdir -p ${DST}/var/cache
|
179
|
echo "Moving ${SRC}/var/cache/pkg to ${DST}/var/cache/"
|
180
|
mv -f ${SRC}/var/cache/pkg ${DST}/var/cache
|
181
|
fi
|
182
|
}
|
183
|
|
184
|
# Relocate the pkg database as needed based on RAM disk options and status
|
185
|
ramdisk_relocate_pkgdb_all () {
|
186
|
unset MOVE_PKG_DATA
|
187
|
unset USE_RAMDISK
|
188
|
if ramdisk_check_enabled; then
|
189
|
USE_RAMDISK=true
|
190
|
fi
|
191
|
if [ -z "${USE_RAMDISK}" -a -f /root/var/db/pkg/local.sqlite ]; then
|
192
|
if ramdisk_failed; then
|
193
|
echo "Not relocating pkg db due to previous RAM disk failure."
|
194
|
return 1
|
195
|
fi
|
196
|
# If RAM disks are disabled, move files back into place
|
197
|
MOVE_PKG_DATA=1
|
198
|
ramdisk_relocate_pkgdb disk
|
199
|
elif [ -n "${USE_RAMDISK}" -a -f /var/db/pkg/local.sqlite ]; then
|
200
|
# If RAM disks are enabled, move files to a safe place
|
201
|
MOVE_PKG_DATA=1
|
202
|
ramdisk_relocate_pkgdb ram
|
203
|
fi
|
204
|
}
|
205
|
|
206
|
# Setup symbolic links for the pkg database
|
207
|
ramdisk_link_pkgdb () {
|
208
|
/bin/mkdir -p /var/db /var/cache
|
209
|
if [ ! -e /var/db/pkg ]; then
|
210
|
echo "Creating pkg db symlink"
|
211
|
ln -sf ../../root/var/db/pkg /var/db/pkg
|
212
|
fi
|
213
|
if [ ! -e /var/cache/pkg ]; then
|
214
|
echo "Creating pkg cache symlink"
|
215
|
ln -sf ../../root/var/cache/pkg /var/cache/pkg
|
216
|
fi
|
217
|
}
|
218
|
|
219
|
# Unmounts parent and subordinate datasets
|
220
|
ramdisk_zfs_deep_unmount() {
|
221
|
local _path="${1}"
|
222
|
|
223
|
/sbin/zfs list -rH -o name,mountpoint -S mountpoint -t filesystem "${_path}" | \
|
224
|
while read _name _mp; do
|
225
|
echo -n "Unmounting ZFS volume ${_name} at ${_mp} for RAM disk..."
|
226
|
/sbin/zfs unmount -f "${_name}" 1>/dev/null 2>&1
|
227
|
echo " done."
|
228
|
done
|
229
|
}
|
230
|
|
231
|
# Mounts ZFS datasets and BE datasets
|
232
|
ramdisk_fixup_zfs_mount() {
|
233
|
echo -n "Mounting ZFS volumes..."
|
234
|
/sbin/zfs mount -a 1>/dev/null 2>&1
|
235
|
_be_mount_zfs
|
236
|
echo " done."
|
237
|
}
|
238
|
|
239
|
# Unmounts ZFS datasets and remounts BE datasets
|
240
|
ramdisk_fixup_zfs_unmount() {
|
241
|
ramdisk_zfs_deep_unmount "/tmp"
|
242
|
ramdisk_zfs_deep_unmount "/var"
|
243
|
_be_mount_zfs
|
244
|
}
|