From bda856e1023868b1e9605e845bedbd8b7ed2944e Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Thu, 2 May 2013 13:38:55 +0200 Subject: hotplug/Linux: add iscsi block hotplug script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This hotplug script has been tested with IET and NetBSD iSCSI targets, without authentication. This hotplug script will only work with PV guests not using pygrub. Signed-off-by: Roger Pau Monné Acked-by: Ian Jackson --- tools/hotplug/Linux/Makefile | 1 + tools/hotplug/Linux/block-iscsi | 154 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 tools/hotplug/Linux/block-iscsi (limited to 'tools/hotplug') diff --git a/tools/hotplug/Linux/Makefile b/tools/hotplug/Linux/Makefile index 99bf87f418..8b0d7f4dda 100644 --- a/tools/hotplug/Linux/Makefile +++ b/tools/hotplug/Linux/Makefile @@ -22,6 +22,7 @@ XEN_SCRIPTS += blktap XEN_SCRIPTS += xen-hotplug-cleanup XEN_SCRIPTS += external-device-migrate XEN_SCRIPTS += vscsi +XEN_SCRIPTS += block-iscsi XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh XEN_SCRIPT_DATA += block-common.sh diff --git a/tools/hotplug/Linux/block-iscsi b/tools/hotplug/Linux/block-iscsi new file mode 100644 index 0000000000..8e36852832 --- /dev/null +++ b/tools/hotplug/Linux/block-iscsi @@ -0,0 +1,154 @@ +#!/bin/bash -e +# +# Open-iSCSI Xen block device hotplug script +# +# Author Roger Pau Monné +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; version 2.1 only. with the special +# exception on linking described in file LICENSE. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Usage: +# +# Target should be specified using the following syntax: +# +# script=block-iscsi,vdev=xvda,target=iqn=,portal= +# +# Portal address must be in IP format. +# + +dir=$(dirname "$0") +. "$dir/block-common.sh" + +remove_label() +{ + echo $1 | sed "s/^\("$2"\)//" +} + +check_tools() +{ + if ! command -v iscsiadm > /dev/null 2>&1; then + fatal "Unable to find iscsiadm tool" + fi + if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then + fatal "Unable to find multipath" + fi +} + +# Sets the following global variables based on the params field passed in as +# a parameter: iqn, portal, auth_method, user, multipath, password +parse_target() +{ + # set multipath default value + multipath="n" + for param in $(echo "$1" | tr "," "\n") + do + case $param in + iqn=*) + iqn=$(remove_label $param "iqn=") + ;; + portal=*) + portal=$(remove_label $param "portal=") + ;; + multipath=*) + multipath=$(remove_label $param "multipath=") + ;; + esac + done + if [ -z "$iqn" ] || [ -z "$portal" ]; then + fatal "iqn= and portal= are required parameters" + fi + if [ "$multipath" != "y" ] && [ "$multipath" != "n" ]; then + fatal "multipath valid values are y and n, $multipath not a valid value" + fi +} + +# Sets $dev to point to the device associated with the value in iqn +find_device() +{ + count=0 + while [ ! -e /dev/disk/by-path/*"$iqn"-lun-0 ]; do + sleep 0.1 + count=`expr $count + 1` + if [ count = 100 ]; then + # 10s timeout while waiting for iSCSI disk to settle + fatal "timeout waiting for iSCSI disk to settle" + fi + done + sddev=$(readlink -f /dev/disk/by-path/*"$iqn"-lun-0 || true) + if [ ! -b "$sddev" ]; then + fatal "Unable to find attached device path" + fi + if [ "$multipath" = "y" ]; then + mdev=$(multipath -ll "$sddev" | head -1 | awk '{ print $1}') + if [ ! -b /dev/mapper/"$mdev" ]; then + fatal "Unable to find attached device multipath" + fi + dev="/dev/mapper/$mdev" + else + dev="$sddev" + fi +} + +# Attaches the target $iqn in $portal and sets $dev to point to the +# multipath device +attach() +{ + do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null + find_device +} + +# Discovers targets in $portal and checks that $iqn is one of those targets +# Also sets the auth parameters to attach the device +prepare() +{ + # Check if target is already opened + iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened" + # Discover portal targets + iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \ + fatal "No matching target iqn found" +} + +# Attaches the device and writes xenstore backend entries to connect +# the device +add() +{ + attach + write_dev $dev +} + +# Disconnects the device +remove() +{ + find_device + do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null +} + +command=$1 +target=$(xenstore-read $XENBUS_PATH/params || true) +if [ -z "$target" ]; then + fatal "No information about the target" +fi + +parse_target "$target" + +check_tools || exit 1 + +case $command in +add) + prepare + add + ;; +remove) + remove + ;; +*) + exit 1 + ;; +esac -- cgit v1.2.3