#! /bin/sh ### BEGIN INIT INFO # Provides: target # Required-Start: $network $remote_fs $syslog # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: The Linux SCSI Target service ### END INIT INFO # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="The Linux SCSI Target" NAME=target DAEMON=/usr/bin/targetcli DAEMON_ARGS="" SCRIPTNAME=/etc/init.d/$NAME CFS_BASE="/sys/kernel/config/" CFS_TGT="${CFS_BASE}/target" CORE_MODS="target_core_mod target_core_pscsi target_core_iblock target_core_file" STARTUP_CONFIG="/etc/target/scsi_target.lio" # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions - requires lsb-base (>= 3.2-14) . /lib/lsb/init-functions load_specfiles() { FABRIC_MODS=$(python << EOF from rtslib import list_specfiles, parse_specfile print(" ".join(["%(kernel_module)s:%(configfs_group)s" % parse_specfile(spec) for spec in list_specfiles()])) EOF ) } save_running_config() { python << EOF import rtslib config = rtslib.Config() config.load_live() config.save("${STARTUP_CONFIG}") EOF } check_install() { # Check the system installation INSTALL=ok python -c "from rtslib import Config" > /dev/null 2>&1 if [ $? != 0 ]; then log_failure_msg "Cannot load rtslib" INSTALL=nok fi if [ "${INSTALL}" != ok ]; then exit 0 else log_action_msg "${DESC} looks properly installed" fi } load_configfs() { modprobe configfs > /dev/null 2>&1 if [ "$?" != 0 ]; then log_failure_msg "Failed to load configfs kernel module" return 1 fi mount -t configfs configfs ${CFS_BASE} > /dev/null 2>&1 case "$?" in 0) log_warning_msg "The configfs filesystem was not mounted, consider adding it to fstab";; 32) log_action_msg "The configfs filesystem is already mounted";; *) log_failure_msg "Failed to mount configfs"; return 1;; esac } load_modules() { for MODULE in ${CORE_MODS}; do if [ ! -z "$(cat /proc/modules | grep ^${MODULE}\ )" ]; then log_warning_msg "Core module ${MODULE} already loaded" else modprobe "${MODULE}" > /dev/null 2>&1 if [ "$?" != 0 ]; then log_failure_msg "Failed to load core module ${MODULE}" return 1 else log_action_msg "Loaded core module ${MODULE}" fi fi done for MOD_SPEC in ${FABRIC_MODS}; do MODULE="$(echo ${MOD_SPEC} | awk -F : '{print $1}')" if [ ! -z "$(cat /proc/modules | grep ^${MODULE}\ )" ]; then log_warning_msg "Fabric module ${MODULE} already loaded" else modprobe "${MODULE}" > /dev/null 2>&1 if [ "$?" != 0 ]; then log_warning_msg "Failed to load fabric module ${MODULE}" else log_action_msg "Loaded fabric module ${MODULE}" fi fi done } unload_modules() { RETCODE=0 for MOD_SPEC in ${FABRIC_MODS}; do MODULE="$(echo ${MOD_SPEC} | awk -F : '{print $1}')" CFS_GROUP="${CFS_TGT}/$(echo ${MOD_SPEC} | awk -F : '{print $2}')" if [ ! -z "$(lsmod | grep ^${MODULE}\ )" ]; then rmdir "${CFS_GROUP}" > /dev/null 2>&1 if [ -d "${CFS_GROUP}" ]; then log_failure_msg "Failed to remove ${CFS_GROUP}" RETCODE=1 else rmmod "${MODULE}" > /dev/null 2>&1 if [ "$?" != 0 ]; then log_failure_msg "Failed to unload fabric module ${MODULE}" RETCODE=1 else log_action_msg "Unloaded ${MODULE} fabric module" fi fi else log_warning_msg "Fabric module ${MODULE} is not loaded" fi done MODULES="$(echo ${CORE_MODS} | tac -s ' ')" for MODULE in ${MODULES}; do if [ ! -z "$(lsmod | grep ^${MODULE}\ )" ]; then rmmod "${MODULE}" > /dev/null 2>&1 if [ "$?" != 0 ]; then log_failure_msg "Failed to unload target core module ${MODULE}" RETCODE=1 else log_action_msg "Unloaded ${MODULE} target core module" fi else log_warning_msg "Target core module ${MODULE} is not loaded" fi done return "${RETCODE}" } load_config() { if [ -e "${STARTUP_CONFIG}" ]; then export __STARTUP_CONFIG="${STARTUP_CONFIG}" python 2> /dev/null << EOF import os, rtslib config = rtslib.Config() config.load(os.environ['__STARTUP_CONFIG'], allow_new_attrs=True) list(config.apply()) EOF if [ "$?" != 0 ]; then unset __STARTUP_CONFIG log_failure_msg "Failed to load ${STARTUP_CONFIG}" return 1 else unset __STARTUP_CONFIG log_action_msg "Loaded ${STARTUP_CONFIG}" fi else log_warning_msg "No ${STARTUP_CONFIG} to load" fi } clear_config() { python 2> /dev/null << EOF from rtslib import Config config = Config() list(config.apply()) EOF if [ "$?" != 0 ]; then log_failure_msg "Failed to clear configuration" return 1 else log_action_msg "Cleared configuration" fi } do_start() { # If the target is running and we do not have a config file on the # system, dump the running system config to the config file. This # helps migrating away from lio-utils or other legacy/devel systems. if [ ! -e "${STARTUP_CONFIG}" ] && [ -d "${CFS_TGT}" ]; then log_action_msg "Possible config migration detected, saving the " \ "running target to ${STARTUP_CONFIG}" save_running_config fi load_specfiles # Fill in FABRIC_MODS and CFS_GROUPS check_install && load_configfs && load_modules && load_config if [ "$?" != 0 ]; then log_failure_msg "Could not start ${DESC}" return 1 else log_success_msg "Started ${DESC}" fi } do_stop() { if [ ! -d ${CFS_TGT} ]; then log_success_msg "${DESC} is already stopped" else load_specfiles # Fill in FABRIC_MODS and CFS_GROUPS clear_config && unload_modules if [ "$?" != 0 ]; then log_failure_msg "Could not stop ${DESC}" return 1 else log_success_msg "Stopped ${DESC}" fi fi } do_status() { if [ -d ${CFS_TGT} ]; then log_action_msg "${DESC} is started" return 0 else log_action_msg "${DESC} is stopped" return 1 fi } case "$1" in start) do_start ;; stop) do_stop ;; status) do_status ;; restart|force-reload) do_stop && do_start ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac