#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          udev
# Required-Start:    mountkernfs vdev-modprobe.sh
# Required-Stop:     
# Default-Start:     S
# Default-Stop:      
# Short-Description: Start vdevd, populate /dev and load drivers.
# Description:	     Manages the /dev directory tree
### END INIT INFO

PATH="/sbin:/bin:/usr/bin"

# Avoid any attempt to kill vdev by the shebang operator /lib/runit/invoke-run
# specified at the beginning of the runit run script
if [ -d /proc/1/. ] && [ "$(cat /proc/1/comm)" = 'runit' ] && [ "$(echo $@ | cut -d' ' -f1,2)" = "stop --force-sysv" ]; then
    exit 0
fi

VDEV_CONFIG_DIR=/etc/vdev
VDEV_HELPERS_DIR=/lib/vdev

SCRIPTNAME=$0

# fill defaults 
if [ -z "$VDEV_BIN" ]; then 
    VDEV_BIN=/sbin/vdevd
fi

[ -x $VDEV_BIN ] || exit 0

if [ -z "$VDEV_MOUNTPOINT" ]; then
    VDEV_MOUNTPOINT=/dev
fi
    
if [ -d "$VDEV_MOUNTPOINT"/block ]; then
    VDEV_CONFIG="$VDEV_CONFIG_DIR"/vdevd.conf
else 
    VDEV_CONFIG="$VDEV_CONFIG_DIR"/vdevd.1.conf
fi

##CHASSIS="$(/usr/sbin/dmidecode -t chassis | /bin/grep Type | /usr/bin/cut -d' ' -f2)"

# defaults
tmpfs_size="10M"

. /lib/lsb/init-functions

# load an ini file as a set of namespaced environment variables, echoing them to stdout
# $1 is the path to the file 
# $2 is the namespace to be prepended to each variable name 
source_ini_file() {

    local FILE_PATH NAMESPACE line KEY VALUE
   
    FILE_PATH=$1
    NAMESPACE=$2
   
    /bin/cat $FILE_PATH | /bin/sed "s/.*\[.*\].*//g" | \
    while read line; do 
   
        KEY=$(echo $line | /bin/sed "s/\(^.*\)=.*/\1/g");
        VALUE=$(echo $line | /bin/sed "s/^.*=\(.*\)$/\1/g");
      
        if [ -n "$KEY" ]; then 
      
            echo "${NAMESPACE}${KEY}=${VALUE}"
        fi
    done
}

# system-wide vdevd needs /sys to be mounted
if [ ! -d /sys/class/ ]; then
    log_failure_msg "vdev requires a mounted sysfs, not started"
    log_end_msg 1
fi

# system-wide vdevd needs "modern" sysfs
if [ -d /sys/class/mem/null -a ! -L /sys/class/mem/null ] || \
   [ -e /sys/block -a ! -e /sys/class/block ]; then
    log_warning_msg "CONFIG_SYSFS_DEPRECATED must not be selected"
    log_warning_msg "Booting will continue in 30 seconds but many things will be broken"
    sleep 30
fi

# load vdev config variables as vdev_config_*
eval $(source_ini_file $VDEV_CONFIG "vdev_config_")

# config sanity check 
if [ -z "$vdev_config_pidfile" ]; then 
    log_warning_msg "No PID file defined in $VDEV_CONFIG.  Please set the pidfile= directive."
    log_warning_msg "You will be unable stop or restart vdevd with this script."
fi

vdevd_start() {
    # clear uevent helper--vdevd subsumes its role
    if [ -w /sys/kernel/uevent_helper ]; then
        echo > /sys/kernel/uevent_helper
    fi
   
    # set the SELinux context for devices created in the initramfs
    [ -x /sbin/restorecon ] && /sbin/restorecon -R "$VDEV_MOUNTPOINT"
   
    log_daemon_msg "Starting the system device event dispatcher" "vdevd\n"
   
    # make sure log directory exists...
    if [ -n "$vdev_config_logfile" ]; then 
      
        vdev_log_dir="$(echo "$vdev_config_logfile" | sed 's/[^/]\+$//g')"

        if [ -n "$vdev_log_dir" ]; then 
            mkdir -p "$vdev_log_dir"
        fi
    fi

    # make sure the pid directory exists 
    if [ -n "$vdev_config_pidfile" ]; then

        vdev_pid_dir="$(echo "$vdev_config_pidfile" | sed 's/[^/]\+$//g')"

        if [ -n "$vdev_pid_dir" ]; then 
            mkdir -p "$vdev_pid_dir"
        fi
    fi
   
    # start vdev
    if "$VDEV_BIN" -c "$VDEV_CONFIG" $@ "$VDEV_MOUNTPOINT"; then
        log_end_msg $?
   
    else
        log_warning_msg $?
        log_warning_msg "Waiting 15 seconds and trying to continue anyway"
        sleep 15
    fi
    if [ "$(basename -- $VDEV_CONFIG)" = "vdevd.1.conf" ]; then
        while [ -n "$(/usr/bin/lslocks -o command | /bin/grep "^vdevd$")" ]; do
            sleep 0.2
        done
        #if [ "$CHASSIS" != "Tower" ] && [ "$CHASSIS" != "Desktop" ]; then
            "$VDEV_HELPERS_DIR"/vdev_print_input_devices
            [ $? -eq 0 ] && "$VDEV_HELPERS_DIR"/vdev_wait
        #fi
        if [ -d /proc/1/. ] && [ "$(cat /proc/1/comm)" != 'runit' ] ; then
            "$VDEV_BIN" -H -c "$VDEV_CONFIG_DIR"/vdevd.conf "$VDEV_MOUNTPOINT"
        fi
    fi
}


vdevd_stop() {
    log_daemon_msg "Sending SIGTERM to the system device event dispatcher" "vdevd"
    "$VDEV_HELPERS_DIR"/vdev_killall
    log_end_msg $?
}

case "$1" in
   start)
      vdevd_start
      ;;
   stop)
      vdevd_stop 
      ;;
   restart)
      vdevd_stop
      sleep 1
      vdevd_start
      ;;
   status)
      if [ -f "$VDEV_PIDFILE" ] && [ -n "$(/bin/cat $VDEV_PIDFILE)" ]; then
          /bin/echo "vdev running with PID $(/bin/cat $VDEV_PIDFILE)"
      fi
      ;;
   *)
      echo "Usage: $SCRIPTNAME {start|stop|once|restart}" >&2
      exit 1
      ;;
esac
