Skip to content

Commit

Permalink
fix(dracut-functions): implement a cache for get_maj_min
Browse files Browse the repository at this point in the history
On systems with a large number of devices, usually multipath devices,
dracut can spend a lot of time stat'ing the devices to collect the
major/minor numbers, leading to huge slowness rebuilding the initramfs
when stat'ing devices is slow (seen with oracleasm file systems in
particular).
This commit implements a basic cache stored in a file under
DRACUT_TMPDIR storing the major:minor corresponding to the specified
device.

Reproducer: create N loopback devices used as a LVM extension to volume
group hosting the root file system

  # LVMVG="rhel"
  # NDEVICES=200
  # mkdir devices; for i in $(seq 1 $NDEVICES); do
    truncate -s 10m devices/$i; losetup loop$i devices/$i
  done
  # vgextend $LVMVG $(/bin/ls -1 /dev/loop[0-9]*)

With standard code (tested with RHEL8.3 dracut):

  # dracut -f --debug /tmp/initramfs.img $(uname -r) >/tmp/debug 2>&1
  # grep -c "stat -L -c" /tmp/debug
  2440

With this code:

  # dracut -f --debug /tmp/initramfs.img $(uname -r) >/tmp/debug_optim 2>&1
  # grep -c "stat -L -c" /tmp/debug_optim
  205

Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
  • Loading branch information
rmetrich authored and haraldh committed May 6, 2021
1 parent 543b801 commit c3bb9d1
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
9 changes: 7 additions & 2 deletions dracut-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,13 @@ get_fs_env() {
# 8:2
get_maj_min() {
local _majmin
_majmin="$(stat -L -c '%t:%T' "$1" 2> /dev/null)"
printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
out="$(grep -m1 -oP "^$1 \K\S+$" "${get_maj_min_cache_file:?}")"
if [ -z "$out" ]; then
_majmin="$(stat -L -c '%t:%T' "$1" 2> /dev/null)"
out="$(printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))")"
echo "$1 $out" >> "${get_maj_min_cache_file:?}"
fi
echo -n "$out"
}
# get_devpath_block <device>
Expand Down
4 changes: 4 additions & 0 deletions dracut.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,10 @@ readonly DRACUT_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t dracut.XXXXXX)"
exit 1
}
# Cache file used to optimize get_maj_min()
declare -x -r get_maj_min_cache_file="${DRACUT_TMPDIR}/majmin_cache"
: > "$get_maj_min_cache_file"
# clean up after ourselves no matter how we die.
trap '
ret=$?;
Expand Down

0 comments on commit c3bb9d1

Please sign in to comment.