/lib/bilibop/lockfs_mount_helper is in bilibop-lockfs 0.4.23.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | #!/bin/sh
set -e
# /lib/bilibop/lockfs_mount_helper {{{
# Mount helper script for 'lockfs' filesystem type entries in /etc/fstab.
# This script cannot be run manually. The expected way to run it is the
# following:
# 1. Enable bilibop-lockfs:
# * set BILIBOP_LOCKFS to "true" in /etc/bilibop/bilibop.conf or
# * append 'lockfs' parameter in the boot commandline
# 2. One time '/' is an aufs mountpoint, the temporary /etc/fstab is
# modified to replace filesystem types (third field) of some entries
# by 'lockfs' (options are modified too to remember the original
# fstype).
# 3. /sbin/mount.lockfs is created if it don't already exist. This can be a
# symlink to /lib/bilibop/lockfs_mount_helper if this helper is executable,
# or a copy of the helper (followed by chmod +x) if the helper is not
# executable. If the helper is missing, /sbin/mount.lockfs will be a
# poor fallback to call mount normally.
# 4. /etc/fstab is parsed by 'mount -a', and then mount calls mount.lockfs
# with the proper arguments when a 'lockfs' fstype is encountered.
# }}}
PATH="/sbin:/bin"
usage() {
cat <<EOF
${0##*/}: mount helper script for bilibop-lockfs.
This script can not be run manually, but only by a mount process,
and only if bilibop-lockfs is enabled.
EOF
}
# mount_fallback() =========================================================={{{
# What we want is: mount a device on its original mountpoint and rewrite the
# fstab entry to keep it consistent. This function should be called in case of
# error or if the device is whitelisted. This function parses the arguments of
# the script itself (i.e. mount_fallback "$@").
mount_fallback() {
${DEBUG} && echo "> mount_fallback $@" >&2
local opt options= fstype=
for opt in $(IFS=','; echo ${4}); do
case "${opt}" in
fstype=*)
eval "${opt}"
;;
*)
options="${options:+${options},}${opt}"
;;
esac
done
sed -i "s;^\s*\([^#][^ ]\+\s\+${2}\s\+\)lockfs\s.*;\1${fstype:-auto} ${options:-defaults} 0 0;" /etc/fstab
mount ${flags} ${1} ${2} ${fstype:+-t ${fstype}} ${options:+-o ${options}}
}
# ===========================================================================}}}
# Works only if the parent process is /bin/mount:
if [ "$(readlink -f /proc/${PPID}/exe)" != "/bin/mount" ]; then
usage >&2
exit 3
fi
. /lib/bilibop/common.sh
get_bilibop_variables
get_udev_root
# Works only if the root filesystem is already managed by bilibop-lockfs:
if is_aufs_mountpoint -q / && [ -f "${BILIBOP_RUNDIR}/lock" ]; then
LOCKFS="true"
robr="$(aufs_readonly_branch /)"
rwbr="$(aufs_writable_branch /)"
else
echo "${0##*/}: bilibop-lockfs is disabled." >&2
exit 1
fi
# Some configurations can have been overridden from the boot commandline:
for param in $(cat /proc/cmdline); do
case "${param}" in
lockfs=*)
for policy in $(IFS=','; echo ${param#lockfs=}); do
case "${policy}" in
default)
BILIBOP_LOCKFS_POLICY=""
BILIBOP_LOCKFS_WHITELIST=""
BILIBOP_LOCKFS_SIZE=""
;;
hard|soft)
BILIBOP_LOCKFS_POLICY="${policy}"
;;
all)
BILIBOP_LOCKFS_WHITELIST=""
;;
-/*)
BILIBOP_LOCKFS_WHITELIST="${BILIBOP_LOCKFS_WHITELIST:+${BILIBOP_LOCKFS_WHITELIST} }${policy#-}"
;;
esac
done
;;
esac
done
# But if there is a physical lock, it takes precedence:
if [ -f "${BILIBOP_RUNDIR}/plocked" ]; then
. ${BILIBOP_RUNDIR}/plocked
fi
# the mount(8) command, after parsing commandline arguments and/or /etc/fstab,
# always provides arguments to the helper scripts in this order:
# FILESYSTEM MOUNTPOINT [FLAGS] -o MOUNTOPTIONS
# where FLAGS are generic, not filesystem specific: -n, -s, -v for example; -r
# (or --read-only) and -w (or --rw or --read-write) are translated to -o ro and
# -o rw respectively by the mount command itself.
while [ "${1}" ]; do
case "${1}" in
-o)
MNTARGS="${MNTARGS:+${MNTARGS} }${1} ${2}"
shift 2
;;
-*)
# Do not skip other options (-n, -s, -v), but take them
# apart: we will reuse them for each mount invocation.
flags="${flags:+${flags} }${1}"
shift
;;
*)
MNTARGS="${MNTARGS:+${MNTARGS} }${1}"
shift
;;
esac
done
# Reinitialize script arguments
eval set -- "${MNTARGS}"
if [ -b "${1}" ]; then
device="${1}"
# Check if this device is whitelisted:
if [ -n "${BILIBOP_LOCKFS_WHITELIST}" ]; then
# Query ID_FS_* udev environment variables of the device:
eval $(query_udev_envvar $(readlink -f ${device}))
if [ -z "${ID_FS_USAGE}" ]; then
eval $(blkid -o udev -p ${device})
fi
[ "${ID_FS_USAGE}" = "filesystem" -o "${ID_FS_USAGE}" = "crypto" ] &&
for skip in ${BILIBOP_LOCKFS_WHITELIST}; do
case "${skip}" in
UUID=${ID_FS_UUID}|LABEL=${ID_FS_LABEL}|TYPE=${ID_FS_TYPE})
LOCKFS="false"
break
;;
esac
done
fi
elif [ -f "${1}" ]; then
lofile="${1}"
LOFILE="${robr}${lofile}"
else
# There is no block device to mount (here 'block device' includes
# files associated to a loop device). Bind mounts and remote fs
# should have been discarded by the bilibop-lockfs script in the
# initramfs...
LOCKFS="false"
fi
# If bilibop-lockfs is not enabled (the device is whitelisted, or we don't
# know how to manage it), rewrite the fstab entry and do a normal mount:
if [ "${LOCKFS}" != "true" ]; then
mount_fallback "${@}"
exit $?
fi
mntpnt="${2}"
options="${4}"
# Parse mount options. Two cases:
# 1. the block device will be mounted with the same options than in the
# original fstab entry, plus 'ro'.
# 2. the tmpfs will be mounted with only some options of the previous:
# ro, nodev, noexec, nosuid, if they exist.
for opt in $(IFS=','; echo ${options}); do
# 1. Options for the readonly branch:
case "${opt}" in
fstype=*)
eval "${opt}"
;;
rw)
;;
*)
robr_opts="${robr_opts:+${robr_opts},}${opt}"
;;
esac
# 2. Options for the writable branch:
case "${opt}" in
ro|nodev|noexec|nosuid)
rwbr_opts="${rwbr_opts:+${rwbr_opts},}${opt}"
;;
*)
;;
esac
done
# Each readonly branch is mounted under the subtree of the main readonly
# branch (/aufs/ro) and each writable branch is mounted under the subtree
# of the main writable branch (/aufs/rw):
robr="${robr}${mntpnt}"
rwbr="${rwbr}${mntpnt}"
# If the policy is not explicitly set to 'soft', set the block device as
# readonly, and use 'rr' aufs option to improve performances:
if [ "${BILIBOP_LOCKFS_POLICY}" = "soft" ]; then
RO="ro"
else
RO="rr"
[ -b "${device}" ] && blockdev --setro ${device}
fi
# Try to mount the readonly branch. In case of failure, undo what has been
# done before, do a normal mount, rewrite the fstab entry to be consistent
# with that, and exit:
if ! mount ${flags} ${fstype:+-t ${fstype}} -o ${robr_opts:+${robr_opts},}ro ${device:-${LOFILE}} ${robr}; then
[ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
mount_fallback "${@}"
exit 3
fi
# The amount of RAM to allow to this mountpoint:
SIZE=
for size in ${BILIBOP_LOCKFS_SIZE}; do
case "${size}" in
${mntpnt}=[1-9]*)
SIZE="$(printf "${size#${mntpnt}=}" | grep '^[1-9][0-9]*[KkMmGg%]\?$')"
break
;;
esac
done
# Create the mountpoint (it should not exist before this step):
if [ ! -d "${rwbr}" ]; then
mkdir -p ${rwbr}
grep -q "^${mntpnt}$" ${BILIBOP_RUNDIR}/lock ||
echo "${mntpnt}" >>${BILIBOP_RUNDIR}/lock
fi
# Try to mount the writable branch, and in case of failure, undo what
# has been done before, etc.
if ! mount ${flags} -t tmpfs -o ${rwbr_opts:+${rwbr_opts},}${SIZE:+size=${SIZE},}mode=0755 tmpfs ${rwbr}; then
umount ${robr}
[ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
mount_fallback "${@}"
exit 3
fi
# Fix permissions and ownership of the writable branch (and catch the values;
# they will be reused later):
mod="$(LC_ALL=C chmod -v --reference="${robr}" "${rwbr}" | sed 's;.* \([0-7]\{4\}\) (.\+)$;\1;')"
own="$(LC_ALL=C chown -v --reference="${robr}" "${rwbr}" | sed 's;.* \([^:]\+:[^:]\+\)$;\1;')"
owner="${own%:*}"
if [ "${owner}" != "root" ]; then
uid="$(grep "^${owner}:" /etc/passwd | sed 's;^\([^:]*:\)\{2\}\([^:]\+\):.*;\2;')"
fi
group="${own#*:}"
if [ "${group}" != "root" ]; then
gid="$(grep "^${group}:" /etc/group | sed 's;^\([^:]*:\)\{2\}\([^:]\+\):.*;\2;')"
fi
# Try to mount the aufs now. In case of failure, undo what has been done
# before, etc.
if ! mount ${flags} -t aufs -o br:${rwbr}=rw:${robr}=${RO} none ${mntpnt}; then
umount ${robr}
umount ${rwbr}
[ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
mount_fallback "${@}"
exit 3
fi
# All is OK. So we can rewrite fstab entry to reflect the real mounts. This
# can be important for clean unmounts at shutdown (for the case a filesystem
# is remounted rw during a session).
robr_line="${device:-${LOFILE}} ${robr} ${fstype:-auto} ${robr_opts:+${robr_opts},}ro 0 0"
rwbr_line="tmpfs ${rwbr} tmpfs ${rwbr_opts:+${rwbr_opts},}${SIZE:+size=${SIZE},}${uid:+uid=${uid},}${gid:+gid=${gid},}mode=${mod} 0 0"
aufs_line="none ${mntpnt} aufs br:${rwbr}=rw:${robr}=${RO} 0 0"
sed -i "s;^\s*[^#][^ ]\+\s\+${mntpnt}\s\+lockfs\s.*;${robr_line}\n${rwbr_line}\n${aufs_line};" /etc/fstab
# vim: et sts=4 sw=4 ts=4
|