1
|
#!/bin/sh
|
2
|
#
|
3
|
# rc.ramdisk_functions.sh
|
4
|
#
|
5
|
# part of pfSense (https://www.pfsense.org)
|
6
|
# Copyright (c) 2020-2025 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" ] || [ "${_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=$(( PAGES_FREE * PAGE_SIZE ))
|
117
|
# Convert to MB
|
118
|
MEM_FREE=$(( MEM_FREE / 1024 / 1024 ))
|
119
|
# Total size of desired RAM disks
|
120
|
MEM_NEED=$(( 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
|
SIZE=$(eval echo \${${NAME}size})m
|
132
|
if [ "${NAME}" = "tmp" ]; then
|
133
|
MODE="1777"
|
134
|
else
|
135
|
MODE="1755"
|
136
|
fi
|
137
|
/sbin/mount -o rw,size="${SIZE}",mode="${MODE}" -t tmpfs tmpfs "/${NAME}"
|
138
|
return $?
|
139
|
}
|
140
|
|
141
|
# If the install has RAM disks, or if the full install _was_ using RAM disks, make a backup.
|
142
|
ramdisk_make_backup () {
|
143
|
if ramdisk_is_active || ramdisk_was_active; then
|
144
|
echo "Backing up RAM disk contents"
|
145
|
/etc/rc.backup_aliastables.sh
|
146
|
/etc/rc.backup_rrd.sh
|
147
|
/etc/rc.backup_dhcpleases.sh
|
148
|
/etc/rc.backup_logs.sh
|
149
|
/etc/rc.backup_captiveportal.sh
|
150
|
# /etc/rc.backup_voucher.sh
|
151
|
fi
|
152
|
}
|
153
|
|
154
|
# Relocate the pkg database to a specific given location, either disk (/var) or
|
155
|
# to its safe location for use with RAM disks (/root/var)
|
156
|
# Usage:
|
157
|
# ramdisk_relocate_pkgdb disk
|
158
|
# ramdisk_relocate_pkgdb ram
|
159
|
ramdisk_relocate_pkgdb () {
|
160
|
if [ "${1}" = "disk" ]; then
|
161
|
local SRC=/root
|
162
|
local DST=
|
163
|
else
|
164
|
local SRC=
|
165
|
local DST=/root
|
166
|
fi
|
167
|
|
168
|
echo "Moving pkg database for ${1} storage"
|
169
|
if [ -d ${SRC}/var/db/pkg ]; then
|
170
|
echo "Clearing ${DST}/var/db/pkg"
|
171
|
rm -rf ${DST}/var/db/pkg 2>/dev/null
|
172
|
/bin/mkdir -p ${DST}/var/db
|
173
|
echo "Moving ${SRC}/var/db/pkg to ${DST}/var/db/"
|
174
|
mv -f ${SRC}/var/db/pkg ${DST}/var/db
|
175
|
fi
|
176
|
if [ -d ${SRC}/var/cache/pkg ]; then
|
177
|
echo "Clearing ${DST}/var/cache/pkg"
|
178
|
rm -rf ${DST}/var/cache/pkg 2>/dev/null
|
179
|
/bin/mkdir -p ${DST}/var/cache
|
180
|
echo "Moving ${SRC}/var/cache/pkg to ${DST}/var/cache/"
|
181
|
mv -f ${SRC}/var/cache/pkg ${DST}/var/cache
|
182
|
fi
|
183
|
}
|
184
|
|
185
|
# Relocate the pkg database as needed based on RAM disk options and status
|
186
|
ramdisk_relocate_pkgdb_all () {
|
187
|
unset MOVE_PKG_DATA
|
188
|
unset USE_RAMDISK
|
189
|
if ramdisk_check_enabled; then
|
190
|
USE_RAMDISK=true
|
191
|
fi
|
192
|
if [ -z "${USE_RAMDISK}" ] && [ -f /root/var/db/pkg/local.sqlite ]; then
|
193
|
if ramdisk_failed; then
|
194
|
echo "Not relocating pkg db due to previous RAM disk failure."
|
195
|
return 1
|
196
|
fi
|
197
|
# If RAM disks are disabled, move files back into place
|
198
|
MOVE_PKG_DATA=1
|
199
|
ramdisk_relocate_pkgdb disk
|
200
|
elif [ -n "${USE_RAMDISK}" ] && [ -f /var/db/pkg/local.sqlite ]; then
|
201
|
# If RAM disks are enabled, move files to a safe place
|
202
|
MOVE_PKG_DATA=1
|
203
|
ramdisk_relocate_pkgdb ram
|
204
|
fi
|
205
|
}
|
206
|
|
207
|
# Setup symbolic links for the pkg database
|
208
|
ramdisk_link_pkgdb () {
|
209
|
/bin/mkdir -p /var/db /var/cache
|
210
|
if [ ! -e /var/db/pkg ]; then
|
211
|
echo "Creating pkg db symlink"
|
212
|
ln -sf ../../root/var/db/pkg /var/db/pkg
|
213
|
fi
|
214
|
if [ ! -e /var/cache/pkg ]; then
|
215
|
echo "Creating pkg cache symlink"
|
216
|
ln -sf ../../root/var/cache/pkg /var/cache/pkg
|
217
|
fi
|
218
|
}
|
219
|
|
220
|
# Unmounts parent and subordinate datasets
|
221
|
ramdisk_zfs_deep_unmount() {
|
222
|
local _path="${1}"
|
223
|
|
224
|
/sbin/zfs list -rH -o name,mountpoint -S mountpoint -t filesystem "${_path}" | \
|
225
|
while read _name _mp; do
|
226
|
echo -n "Unmounting ZFS volume ${_name} at ${_mp} for RAM disk..."
|
227
|
/sbin/zfs unmount -f "${_name}" 1>/dev/null 2>&1
|
228
|
echo " done."
|
229
|
done
|
230
|
}
|
231
|
|
232
|
# Mounts ZFS datasets and BE datasets
|
233
|
ramdisk_fixup_zfs_mount() {
|
234
|
echo -n "Mounting ZFS volumes..."
|
235
|
/sbin/zfs mount -a 1>/dev/null 2>&1
|
236
|
_be_mount_zfs
|
237
|
echo " done."
|
238
|
}
|
239
|
|
240
|
# Unmounts ZFS datasets and remounts BE datasets
|
241
|
ramdisk_fixup_zfs_unmount() {
|
242
|
ramdisk_zfs_deep_unmount "/tmp"
|
243
|
ramdisk_zfs_deep_unmount "/var"
|
244
|
_be_mount_zfs
|
245
|
}
|