#!/bin/sh
# A mechanism to mitigate block devices naming in random order.
# i.e., make only 1 CPU online when udev is started.

CMDLINE_FILE="${CMDLINE_FILE:-/proc/cmdline}"
SYS_DIR="${SYS_DIR:-/sys}"

if [ ! -f "$CMDLINE_FILE" ] || [ -z "$(grep -Ew "(ocs_1_cpu_udev|maxcpus=1)" "$CMDLINE_FILE" 2>/dev/null)" ]; then
  # Skip if neither ocs_1_cpu_udev nor maxcpus=1 exists.
  exit 0
fi

# Check if already running on single CPU (e.g. booted with maxcpus=1 or single-core system)
if [ -f "$SYS_DIR/devices/system/cpu/online" ]; then
  online_cpus="$(cat "$SYS_DIR/devices/system/cpu/online" 2>/dev/null)"
  if [ "$online_cpus" = "0" ]; then
    echo "System is already running on single CPU (CPU 0)."
    exit 0
  fi
fi

cpu_no="$(LC_ALL=C grep -iE "^processor" /proc/cpuinfo 2>/dev/null | wc -l)"
if [ "$cpu_no" -le 1 ]; then
  echo "System has only 1 CPU processor."
  exit 0
fi

echo "Disabling SMP-like behavior before udev is started..."
for cpu in "$SYS_DIR"/devices/system/cpu/cpu[1-9]*; do
  if [ -e "$cpu/online" ]; then
    echo -n "$(basename "$cpu"), "
    (echo 0 > "$cpu/online" 2>/dev/null || echo "Failed to disable $(basename "$cpu")") &
  fi
done
echo

# Wait for single CPU status with a fast 1-second timeout (20 * 0.05s) to avoid boot delays
echo -n "Waiting for single CPU status... "
timeout=20 # 1 second max
exit_cond="false"
while [ "$exit_cond" = "false" ] && [ $timeout -gt 0 ]; do
  if [ -f "$SYS_DIR/devices/system/cpu/online" ]; then
    [ "$(cat "$SYS_DIR/devices/system/cpu/online" 2>/dev/null)" = "0" ] && exit_cond="true"
  else
    cpu_no="$(LC_ALL=C grep -iE "^processor" /proc/cpuinfo 2>/dev/null | wc -l)"
    [ "$cpu_no" -le 1 ] && exit_cond="true"
  fi
  [ "$exit_cond" = "true" ] && break
  sleep 0.05
  timeout=$((timeout - 1))
done

if [ "$exit_cond" = "true" ]; then
  echo "done!"
else
  echo "done (proceeding)!"
fi
