#! /bin/bash
# Copyright (c) 2005 Mark Harvey
# All rights reserved.
#
# Author: Mark Harvey, 2005 - 2009
#	  mark794@gmail.com
#	  mark_harvey@symantec.com
#
# /etc/init.d/mhvtl
#
# Script to start mhvtl kernel module & vtltape userspace daemon
#
# Virtual tape & library system
#
# $Id: mhvtl,v 1.12.2.3 2006-08-30 06:35:01 markh Exp $
#
### BEGIN INIT INFO
# Provides:       mhvtl
# Required-Start: syslog
# Required-Stop:
# Default-Start:  2 3 5
# Default-Stop: 0 1 6
# Description:    Script to start/stop mhvtl kernel modules & vtltape userspace daemons
### END INIT INFO
#
# This is needed for RedHat ??
# chkconfig: - 30 30
#

USER=vtl
MHVTL_CONFIG_PATH=/etc/mhvtl

OPTIONS=

export PATH=$PATH:/usr/bin

if [ -f /etc/rc.status ]; then
	. /etc/rc.status
	rc_reset
fi

# add_library(DEV_ID, Channel, target, lun, Vend, Prod, ProdRev, S/No)
add_library()
{
ID=$1
CH=$2
TARGET=$3
LUN=$4
VENDORID=$5
PRODUCTID=$6
PRODUCTREV=$7
UNITSERNO=$8

printf "Library: %02d CHANNEL: %02d TARGET: %02d LUN: %02d\n" \
		$ID $CH $TARGET $LUN >> $MHVTL_CONFIG_PATH/device.conf
echo " Vendor identification: $VENDORID" >> $MHVTL_CONFIG_PATH/device.conf
echo " Product identification: $PRODUCTID" >> $MHVTL_CONFIG_PATH/device.conf
echo " Product revision level: $PRODUCTREV" >> $MHVTL_CONFIG_PATH/device.conf
echo " Unit serial number: $UNITSERNO" >> $MHVTL_CONFIG_PATH/device.conf
printf " NAA: %02d:22:33:44:ab:%02d:%02d:%02d\n" \
		$ID $CH $TARGET $LUN >> $MHVTL_CONFIG_PATH/device.conf
echo "" >> $MHVTL_CONFIG_PATH/device.conf
}

# add_drive(DEV_ID, Channel, target, lun, Vend, Prod, ProdRev, S/No libID)
add_drive()
{
ID=$1
CH=$2
TARGET=$3
LUN=$4
VENDORID=$5
PRODUCTID=$6
PRODUCTREV=$7
UNITSERNO=$8
LIB=$9
# Get 10th arg
shift 9
SLOT=$1

printf "Drive: %02d CHANNEL: %02d TARGET: %02d LUN: %02d\n" \
		$ID $CH $TARGET $LUN >> $MHVTL_CONFIG_PATH/device.conf
printf " Library ID: %02d Slot: %02d\n" \
		$LIB $SLOT >> $MHVTL_CONFIG_PATH/device.conf
echo " Vendor identification: $VENDORID" >> $MHVTL_CONFIG_PATH/device.conf
echo " Product identification: $PRODUCTID" >> $MHVTL_CONFIG_PATH/device.conf
echo " Product revision level: $PRODUCTREV" >> $MHVTL_CONFIG_PATH/device.conf
echo " Unit serial number: $UNITSERNO" >> $MHVTL_CONFIG_PATH/device.conf
printf " NAA: %02d:22:33:44:ab:%02d:%02d:%02d\n" \
		$LIB $CH $TARGET $LUN >> $MHVTL_CONFIG_PATH/device.conf
echo " Compression: factor 1 enabled 1" >> $MHVTL_CONFIG_PATH/device.conf
echo "" >> $MHVTL_CONFIG_PATH/device.conf
}

# Create a 'device.conf' if it does not exist...
if [ ! -f $MHVTL_CONFIG_PATH/device.conf ]; then

mkdir -p $MHVTL_CONFIG_PATH
cat > $MHVTL_CONFIG_PATH/device.conf << VTL_CONF

VERSION: 4

# VPD page format:
# <page #> <Length> <x> <x+1>... <x+n>
# NAA format is an 8 hex byte value seperated by ':'
# Note: NAA is part of inquiry VPD 0x83
#
# Each 'record' is separated by one (or more) blank lines.
# Each 'record' starts at column 1
# Serial num max len is 10.
# Compression: factor X enabled 0|1
#     Where X is zlib compression factor	1 = Fastest compression
#						9 = Best compression
#     enabled 0 == off, 1 == on

VTL_CONF


#         index channel target LUN Vendor ProdID ProdRev S/No
add_library 10 0 0 0 "SPECTRA" "PYTHON"  "550V"  "XYZZY_A"
#         index channel target LUN Vendor ProdID ProdRev S/No Lib#
add_drive   11 0 1 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_A1" 10 1
add_drive   12 0 2 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_A2" 10 2
add_drive   13 0 3 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_A3" 10 3
add_drive   14 0 4 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_A4" 10 4

add_library 30 1 0 0 "SPECTRA" "PYTHON"  "550V"  "XYZZY_B"
add_drive   31 1 1 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_B1" 30 1
add_drive   32 1 2 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_B2" 30 2
add_drive   33 1 3 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_B3" 30 3
add_drive   34 1 4 0 "IBM" "ULT3580-TD4" "550V" "XYZZY_B4" 30 4

fi

# Create a 'mhvtl.conf' if it does not exist...
if [ ! -f $MHVTL_CONFIG_PATH/mhvtl.conf ]; then

mkdir -p $MHVTL_CONFIG_PATH
cat > $MHVTL_CONFIG_PATH/mhvtl.conf << VTL_CONF

# Home directory for config file(s)
MHVTL_CONFIG_PATH=$MHVTL_CONFIG_PATH

# Default media capacity (500 M)
CAPACITY=500

# Set default verbosity [0|1|2|3]
VERBOSE=1

# Set kernel module debuging [0|1]
VTL_DEBUG=0
VTL_CONF
fi

# Upgrade mhvtl.conf with 'MHVTL_CONFIG_PATH' default
EXIST=`grep MHVTL_CONFIG_PATH $MHVTL_CONFIG_PATH/mhvtl.conf | wc -l`
if [ $EXIST -eq 0 ]; then
	echo "" >> $MHVTL_CONFIG_PATH/mhvtl.conf
	echo "# Default config directory" >> $MHVTL_CONFIG_PATH/mhvtl.conf
	echo "MHVTL_CONFIG_PATH=$MHVTL_CONFIG_PATH" >> $MHVTL_CONFIG_PATH/mhvtl.conf
fi

. $MHVTL_CONFIG_PATH/mhvtl.conf

# Earlier versions of mhvtl.conf may not contain the 'CAPACITY' string.
# Update if nessessary..
EXIST=`grep CAPACITY $MHVTL_CONFIG_PATH/mhvtl.conf|wc -l`
if [ $EXIST -eq 0 ]; then
	echo "" >> $MHVTL_CONFIG_PATH/mhvtl.conf
	echo "# Default media capacity" >> $MHVTL_CONFIG_PATH/mhvtl.conf
	echo CAPACITY=500 >> $MHVTL_CONFIG_PATH/mhvtl.conf
fi

V=`grep VERSION $MHVTL_CONFIG_PATH/device.conf|awk '{print $2}'`
if [ $V -ne 4 ]; then
	echo "Upgrading existing device.conf to version 4"
	/usr/bin/update_device.conf
fi

# Now check for for 'library_contents'
LIBLIST=`awk '$1 == "Library:" {print $2}' $MHVTL_CONFIG_PATH/device.conf`
for LIBID in $LIBLIST
do
	if [ ! -f $MHVTL_CONFIG_PATH/library_contents.$LIBID ]; then
		echo
		echo "Could not locate library config file: $MHVTL_CONFIG_PATH/library_contents.$LIBID"
		echo "Creating a default one"
		echo "Please stop mhvtl & edit $MHVTL_CONFIG_PATH/library_contents.$LIBID to suit your requirements"

		echo "VERSION: 2" > $MHVTL_CONFIG_PATH/library_contents.$LIBID
		echo "" > $MHVTL_CONFIG_PATH/library_contents.$LIBID
		# Count number of drives in this library
		DRV_COUNT=`grep "Library ID: $LIBID" $MHVTL_CONFIG_PATH/device.conf|wc -l`
		# Add a 'Drive X:' for each drive
		for a in `seq 1 $DRV_COUNT`
		do
			printf "Drive %d:\n" $a >> $MHVTL_CONFIG_PATH/library_contents.$LIBID
		done
		cat >> $MHVTL_CONFIG_PATH/library_contents.$LIBID << CONF_SAMPLE

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1
# Trailing "TA" - T10000+
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+
#
CONF_SAMPLE

		for a in `seq 1 10`; do
			printf "Slot $a: DD%02d%02dS3\n" $LIBID $a \
				>> $MHVTL_CONFIG_PATH/library_contents.$LIBID
		done
		for a in `seq 11 20`; do
			printf "Slot $a: UD%02d%02dL4\n" $LIBID $a \
				>> $MHVTL_CONFIG_PATH/library_contents.$LIBID
		done
		printf "Slot 21: CLN%02d0S3\n" $LIBID >> $MHVTL_CONFIG_PATH/library_contents.$LIBID
		printf "Slot 22: CLN%02d1L4\n" $LIBID >> $MHVTL_CONFIG_PATH/library_contents.$LIBID
	fi
done

case "$1" in
    start)
	if [ ! -e /sys/module/mhvtl  ]; then
		modprobe mhvtl opts=$VTL_DEBUG
	fi

	if [ ! -e /sys/module/mhvtl/version  ]; then
		echo "No kernel module loaded to feed these daemons."
		echo ""
		echo "Need mhvtl kernel module version at least 0.16.0"
		echo ""
		echo "Please see http://sites.google.com/site/linuxvtl2/"
		exit 1
	fi
	vtlMidVersion=`cat /sys/module/mhvtl/version|awk -F. '{print $2}'`
	if [ $vtlMidVersion -lt 16 ]; then
		echo "Incorrect kernel module for these daemons."
		echo -e "Should be at 0.16.x\n"
		echo -e "Please see http://sites.google.com/site/linuxvtl2\n"
		exit 1
	fi

	# Load sg driver if not already loaded..
	if [ ! -e /sys/module/sg ]; then
		/sbin/modprobe sg
		sleep 1
	fi

	if [ ! -z "`ps --user $USER|grep -v TIME`" ]; then
		echo "mhvtl already running..."
		exit 1
	fi

	chown -R $USER:$USER $MHVTL_CONFIG_PATH
	chmod 770 /opt/vtl

	# creating devices
	make_vtl_devices $USER > /dev/null

	# Now correct file permissions..
	chown -R $USER:$USER /opt/vtl /dev/mhvtl[0-9]*

	# Build Library media
	make_vtl_media $USER
	if [ $? != 0 ]; then
		echo "make_vtl_media failed.."
		exit 1
	fi

	# Build Library config - No. of drives & serial Nos etc..
	# This also loads each tape daemon.
	build_library_config $USER
	if [ $? != 0 ]; then
		echo "build_library_config failed.. Could not start daemons"
		exit 1
	fi

	if [ -f /etc/rc.status ]; then
		rc_status -v
	fi
	;;

    stop)
        echo "shutdown of mhvtl"

	if [ -z "`ps --user $USER|grep -v TIME`" ]; then
		echo "mhvtl not running..."
		exit 0
	fi

	for a in `ps -eo cmd |awk '/^vtltape -q/ {print $3}'`
	do
		echo "   Sending exit to $a"
		vtlcmd $a exit
		usleep 100 > /dev/null 2>&1 /dev/null
	done

	for a in `ps -eo cmd |awk '/^vtllibrary -q/ {print $3}'`
	do
		echo "   Sending exit to $a"
		vtlcmd $a exit
		usleep 100 > /dev/null 2>&1 /dev/null
	done

	if [ -f /etc/rc.status ]; then
		rc_status -v
	fi
	;;
    shutdown)
	# Remove kernel module (mhvtl) along with messageQ key.
        echo "Removing mhvtl kernel module"
	for a in `ps -eo cmd |awk '/^vtltape -q/ {print $3}'`
	do
		echo "   Sending exit to $a"
		vtlcmd $a exit
		usleep 100 > /dev/null 2>&1 /dev/null
	done

	for a in `ps -eo cmd |awk '/^vtllibrary -q/ {print $3}'`
	do
		echo "   Sending exit to $a"
		vtlcmd $a exit
		usleep 100 > /dev/null 2>&1 /dev/null
	done

	# Sleep long enough for the daemons to see the exit commands.
	sleep 1

	rmmod mhvtl
	Q_EXISTS=`ipcs -q|grep 4d61726b|awk '{print $2}'`
	if [ "X$Q_EXISTS" != "X" ]; then
		ipcrm -q $Q_EXISTS
	fi
	if [ -f /etc/rc.status ]; then
		rc_status -v
	fi
	;;
    *)
	echo "Usage: $0 {start|stop|shutdown}"
	exit 1
esac
if [ -f /etc/rc.status ]; then
	rc_exit
fi
