123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- #!/bin/sh
- #
- # This script umounts mounted iSCSI devices on shutdown, if possible.
- # It is supposed to catch most use cases but is not designed to work
- # for every corner-case. It handles LVM and multipath, but only if
- # one of the following stackings is used:
- # LVM -> multipath -> iSCSI
- # multipath -> iSCSI
- # LVM -> iSCSI
- # LVM -> LUKS -> multipath -> iSCSI
- # LVM -> LUKS -> iSCSI
- # LUKS -> LVM -> multipath -> iSCSI
- # LUKS -> multipath -> iSCSI
- # LUKS -> LVM -> iSCSI
- # LUKS -> iSCSI
- # It does not try to umount anything belonging to any device that is
- # also used as a backing store for the root filesystem. Any iSCSI
- # device part of the backing store of the root filesystem will be noted
- # in /run/open-iscsi/shutdown-keep-sessions, so that the session not be
- # closed on shutdown.
- #
- # KNOWN ISSUES:
- # - It doesn't handle submounts properly in all corner cases.
- # Specifically, it doesn't handle a non-iSCSI mount below an
- # iSCSI mount if it isn't also marked _netdev in /etc/fstab.
- # - It does not handle other things device mapper can do, such as
- # RAID, crypto, manual mappings of parts of disks, etc.
- # - It doesn't try to kill programs still accessing those mounts,
- # umount will just fail then.
- # - It doesn't handle more complicated stackings such as overlayfs,
- # FUSE filesystems, loop devices, etc.
- # - It doesn't handle swap.
- #
- # LONG TERM GOAL:
- # - In the long term, there should be a solution where for each part
- # of the stacking (device mapper, LVM, overlayfs, etc.) explicit
- # depdendencies are declared with the init system such that it can
- # be automatically dismantled. That would make this script
- # superfluous and also not be a layering violation, as it
- # currently is.
- #
- # CODING CHOICES:
- # - On systems running sysvinit, this script might be called without
- # /usr being mounted, so a lot of very useful commands are not
- # available: head, tail, stat, awk, etc. This makes the script
- # quite ugly at places, but that can't be avoided.
- #
- # Author: Christian Seiler <christian@iwakd.de>
- #
- # Make sure we don't include /usr in our path, else future modifications
- # to this script might accidentally use something from there and cause
- # failure on separate-/usr sysvinit systems that isn't immediately
- # noticed.
- PATH=/sbin:/bin
- EXCLUDE_MOUNTS_AT_SHUTDOWN=""
- if [ -f /etc/default/open-iscsi ]; then
- . /etc/default/open-iscsi
- fi
- MULTIPATH=/sbin/multipath
- PVS=/sbin/pvs
- LVS=/sbin/lvs
- VGS=/sbin/vgs
- VGCHANGE=/sbin/vgchange
- CRYPTSETUP=/sbin/cryptsetup
- DMSETUP=/sbin/dmsetup
- if [ -x $PVS ] && [ -x $LVS ] && [ -x $VGCHANGE ] ; then
- HAVE_LVM=1
- else
- HAVE_LVM=0
- fi
- if [ -x $CRYPTSETUP ] && [ -x $DMSETUP ] ; then
- HAVE_LUKS=1
- else
- HAVE_LUKS=0
- fi
- DRY_RUN=0
- # We need to make sure that we don't try to umount the root device
- # and for systemd systems, also /usr (which is pre-mounted in initrd
- # there).
- EXCLUDE_MOUNTS="/"
- if [ -d /run/systemd/system ] ; then
- EXCLUDE_MOUNTS="$EXCLUDE_MOUNTS /usr"
- fi
- EXCLUDE_MOUNTS="${EXCLUDE_MOUNTS}${EXCLUDE_MOUNTS_AT_SHUTDOWN+ $EXCLUDE_MOUNTS_AT_SHUTDOWN}"
- unset _EXCLUDE_MOUNTS
- error_usage() {
- echo "Usage: $0 [--dry-run | --timeout secs]" >&2
- exit 1
- }
- timeout=0
- if [ $# -gt 2 ] ; then
- error_usage
- fi
- if [ $# -eq 2 ] ; then
- if [ x"$1"x != x"--timeout"x ] ; then
- error_usage
- fi
- case "$2" in
- (-1) timeout="$2" ;;
- (*[!0-9]*|"") error_usage ;;
- (*) timeout="$2" ;;
- esac
- elif [ $# -eq 1 ] ; then
- if [ x"$1"x != x"--dry-run"x ] ; then
- error_usage
- fi
- DRY_RUN=1
- fi
- # poor man's hash implementation using shell variables
- hash_keys() {
- _hash_keys_hash_key_prefix="${1}_"
- (
- IFS='='
- set | while read var value ; do
- if [ x"${var#$_hash_keys_hash_key_prefix}"x != x"${var}"x ] ; then
- printf '%s\n' "${var#$_hash_keys_hash_key_prefix}"
- fi
- done
- )
- }
- hash_clear() {
- for k in $(hash_keys "$1") ; do
- unset "${1}_${k}"
- done
- }
- hash_get() {
- _hash_get_var="$2_$(printf '%s' "$3" | sed 's%[^A-Za-z0-9_]%_%g')"
- eval _hash_get_value=\$${_hash_get_var}
- eval $1=\${_hash_get_value}
- }
- hash_set() {
- _hash_set_var="$1_$(printf '%s' "$2" | sed 's%[^A-Za-z0-9_]%_%g')"
- eval ${_hash_set_var}=\${3}
- }
- hash_unset() {
- _hash_set_var="$1_$(printf '%s' "$2" | sed 's%[^A-Za-z0-9_]%_%g')"
- unset ${_hash_set_var}
- }
- in_set() {
- eval _set=\$$1
- case "${_set}" in
- ("$2"|*" $2"|"$2 "*|*" $2 "*) return 0 ;;
- (*) return 1 ;;
- esac
- }
- _add_to_set() {
- eval _set=\$$1
- case "${_set}" in
- ("$2"|*" $2"|"$2 "*|*" $2 "*) ;;
- ("") _set="$2" ;;
- (*) _set="${_set} $2" ;;
- esac
- eval $1=\${_set}
- }
- add_to_set() {
- _add_to_set_set="$1"
- shift
- for _add_to_set_val in "$@" ; do
- _add_to_set "${_add_to_set_set}" "${_add_to_set_val}"
- done
- }
- hash_add_to_set() {
- _hash_add_to_set_var="$1_$(printf '%s' "$2" | sed 's%[^A-Za-z0-9_]%_%g')"
- shift
- shift
- add_to_set "${_hash_add_to_set_var}" "$@"
- }
- device_majmin() {
- eval $1=\"\"
- _majmin_dec=$(LC_ALL=C ls -lnd /dev/"$2" | while read _perms _links _uid _gid _majcomma _min _rest ; do
- if [ x"${_majcomma%,}"x != x"${_majcomma}"x ] ; then
- printf '%s' ${_majcomma%,}:${_min}
- fi
- break
- done)
- [ -n "${_majmin_dec}" ] || return
- eval $1=\${_majmin_dec}
- }
- get_lvm_vgs() {
- # handle the case where we didn't get passed any PVs
- # at all
- [ $# -gt 0 ] || return 0
- # subshell for pwd change
- (
- cd /dev
- $PVS --noheadings -o vg_name "$@" 2>/dev/null
- )
- }
- enumerate_luks() {
- hash_clear LUKS_DEVICES_REVERSE_MAP
- _all_crypt_devices=$($DMSETUP info --noheadings -o name -c -S subsystem=CRYPT 2>/dev/null || :)
- for _crypt_device in ${_all_crypt_devices} ; do
- [ -b "/dev/mapper/${_crypt_device}" ] || continue
- _crypt_device="$(readlink -fe "/dev/mapper/${_crypt_device}" 2>/dev/null || :)"
- _crypt_device="${_crypt_device#/dev/}"
- [ -b "/dev/${_crypt_device}" ] || continue
- # dmsetup deps is weird, it outputs the following:
- # 1 dependencies : (XYZ)
- _dep=$($DMSETUP deps -o blkdevname "/dev/${_crypt_device}" | sed -n '1s%.*: (\(.*\)).*%\1%p')
- if [ -n "$_dep" ] && [ -b "/dev/${_dep}" ] ; then
- _dep="$(readlink -fe "/dev/$_dep" 2>/dev/null || :)"
- _dep="${_dep#/dev/}"
- fi
- if [ -n "$_dep" ] && [ -b "/dev/${_dep}" ] ; then
- hash_set LUKS_DEVICES_REVERSE_MAP "${_dep}" "${_crypt_device}"
- fi
- done
- }
- enumerate_iscsi_devices() {
- # Empty arrays
- iscsi_disks=""
- iscsi_partitions=""
- iscsi_multipath_disks=""
- iscsi_multipath_disk_aliases=""
- iscsi_multipath_partitions=""
- iscsi_lvm_vgs=""
- iscsi_lvm_lvs=""
- iscsi_potential_mount_sources=""
- iscsi_luks_pass1=""
- iscsi_luks_pass2=""
- hash_clear ISCSI_DEVICE_SESSIONS
- hash_clear ISCSI_MPALIAS_SESSIONS
- hash_clear ISCSI_LVMVG_SESSIONS
- hash_clear ISCSI_NUMDEVICE_SESSIONS
- ISCSI_EXCLUDED_SESSIONS=""
- # We first need to generate a global reverse mapping of all
- # cryptsetup (e.g. LUKS) devices, because there's no easy way
- # to query "is this the encrypted backing of an active crypto
- # mapping?
- enumerate_luks
- # Look for all iscsi disks
- for _host_dir in /sys/devices/platform/host* /sys/devices/pci*/*/*/host* ; do
- if ! [ -d "$_host_dir"/iscsi_host* ] || ! [ -d "$_host_dir"/iscsi_host/host* ] ; then
- continue
- fi
- for _session_dir in "$_host_dir"/session* ; do
- [ -d "$_session_dir"/target* ] || continue
- for _block_dev_dir in "$_session_dir"/target*/*\:*/block/* ; do
- _block_dev=${_block_dev_dir##*/}
- [ x"${_block_dev}"x != x"*"x ] || continue
- add_to_set iscsi_disks "${_block_dev}"
- hash_add_to_set ISCSI_DEVICE_SESSIONS "${_block_dev}" ${_session_dir}
- done
- done
- done
- # Look for all partitions on those disks
- for _disk in $iscsi_disks ; do
- hash_get _disk_sessions ISCSI_DEVICE_SESSIONS "${_disk}"
- for _part_dir in /sys/class/block/"${_disk}"/"${_disk}"?* ; do
- _part="${_part_dir##*/}"
- [ x"${_part}"x != x"${_disk}?*"x ] || continue
- add_to_set iscsi_partitions "${_part}"
- hash_set ISCSI_DEVICE_SESSIONS "${_part}" "${_disk_sessions}"
- done
- done
- if [ -x $MULTIPATH ] ; then
- # Look for all multipath disks
- for _disk in $iscsi_disks ; do
- hash_get _disk_sessions ISCSI_DEVICE_SESSIONS "${_disk}"
- for _alias in $($MULTIPATH -v1 -l /dev/"$_disk") ; do
- _mp_dev="$(readlink -fe "/dev/mapper/${_alias}" || :)"
- [ -n "${_mp_dev}" ] || continue
- add_to_set iscsi_multipath_disks "${_mp_dev#/dev/}"
- add_to_set iscsi_multipath_disk_aliases "${_alias}"
- hash_add_to_set ISCSI_DEVICE_SESSIONS "${_mp_dev#/dev/}" ${_disk_sessions}
- hash_add_to_set ISCSI_MPALIAS_SESSIONS "${_alias}" ${_disk_sessions}
- done
- done
- # Look for partitions on these multipath disks
- for _alias in $iscsi_multipath_disk_aliases ; do
- hash_get _mp_sessions ISCSI_MPALIAS_SESSIONS "${_alias}"
- for _part_name in /dev/mapper/"${_alias}"-part* ; do
- _part="$(readlink -fe "$_part_name" 2>/dev/null || :)"
- [ -n "${_part}" ] || continue
- add_to_set iscsi_multipath_partitions "${_part#/dev/}"
- hash_set ISCSI_DEVICE_SESSIONS "${_part#/dev/}" "${_mp_sessions}"
- done
- done
- fi
- if [ $HAVE_LUKS -eq 1 ] ; then
- # Look for all LUKS devices.
- for _dev in $iscsi_disks $iscsi_partitions $iscsi_multipath_disks $iscsi_multipath_partitions ; do
- hash_get _luksDev LUKS_DEVICES_REVERSE_MAP "${_dev}"
- [ -n "${_luksDev}" ] || continue
- add_to_set iscsi_luks_pass1 "${_luksDev}"
- hash_get _currentSession ISCSI_DEVICE_SESSIONS "${_dev}"
- if [ -n "${_currentSession}" ] ; then
- hash_set ISCSI_DEVICE_SESSIONS "${_luksDev}" "${_currentSession}"
- fi
- done
- fi
- if [ $HAVE_LVM -eq 1 ] ; then
- # Look for all LVM volume groups that have a backing store
- # on any iSCSI device we found. Also, add $LVMGROUPS set in
- # /etc/default/open-iscsi (for more complicated stacking
- # configurations we don't automatically detect).
- for _vg in $(get_lvm_vgs $iscsi_disks $iscsi_partitions $iscsi_multipath_disks $iscsi_multipath_partitions $iscsi_luks_pass1) $LVMGROUPS ; do
- add_to_set iscsi_lvm_vgs "$_vg"
- done
- # $iscsi_lvm_vgs is now unique list
- for _vg in $iscsi_lvm_vgs ; do
- # get PVs to track iSCSI sessions
- for _pv in $($VGS --noheadings -o pv_name "$_vg" 2>/dev/null) ; do
- _pv_dev="$(readlink -fe "$_pv" 2>/dev/null || :)"
- [ -n "${_pv_dev}" ] || continue
- hash_get _pv_sessions ISCSI_DEVICE_SESSIONS "${_pv_dev#/dev/}"
- hash_add_to_set ISCSI_LVMVG_SESSIONS "${_vg}" ${_pv_sessions}
- done
- # now we collected all sessions belonging to this VG
- hash_get _vg_sessions ISCSI_LVMVG_SESSIONS "${_vg}"
- # find all LVs
- for _lv in $($VGS --noheadings -o lv_name "$_vg" 2>/dev/null) ; do
- _dev="$(readlink -fe "/dev/${_vg}/${_lv}" 2>/dev/null || :)"
- [ -n "${_dev}" ] || continue
- iscsi_lvm_lvs="$iscsi_lvm_lvs ${_dev#/dev/}"
- hash_set ISCSI_DEVICE_SESSIONS "${_dev#/dev/}" "${_vg_sessions}"
- done
- done
- fi
- if [ $HAVE_LUKS -eq 1 ] ; then
- # Look for all LUKS devices.
- for _dev in $iscsi_lvm_lvs ; do
- hash_get _luksDev LUKS_DEVICES_REVERSE_MAP "${_dev}"
- [ -n "${_luksDev}" ] || continue
- add_to_set iscsi_luks_pass2 "${_luksDev}"
- hash_get _currentSession ISCSI_DEVICE_SESSIONS "${_dev}"
- if [ -n "${_currentSession}" ] ; then
- hash_set ISCSI_DEVICE_SESSIONS "${_luksDev}" "${_currentSession}"
- fi
- done
- fi
- # Gather together all mount sources
- iscsi_potential_mount_sources="$iscsi_potential_mount_sources $iscsi_disks $iscsi_partitions"
- iscsi_potential_mount_sources="$iscsi_potential_mount_sources $iscsi_multipath_disks $iscsi_multipath_partitions"
- iscsi_potential_mount_sources="$iscsi_potential_mount_sources $iscsi_lvm_lvs"
- iscsi_potential_mount_sources="$iscsi_potential_mount_sources $iscsi_luks_pass1 $iscsi_luks_pass2"
- # Convert them to numerical representation
- iscsi_potential_mount_sources_majmin=""
- for _src in $iscsi_potential_mount_sources ; do
- device_majmin _src_majmin "$_src"
- [ -n "$_src_majmin" ] || continue
- iscsi_potential_mount_sources_majmin="${iscsi_potential_mount_sources_majmin} ${_src_majmin}"
- hash_get _dev_sessions ISCSI_DEVICE_SESSIONS "${_src}"
- hash_set ISCSI_NUMDEVICE_SESSIONS "${_src_majmin}" "${_dev_sessions}"
- done
- # Enumerate mount points
- iscsi_mount_points=""
- iscsi_mount_point_ids=""
- while read _mpid _mppid _mpdev _mpdevpath _mppath _mpopts _other ; do
- if in_set iscsi_potential_mount_sources_majmin "$_mpdev" ; then
- if in_set EXCLUDE_MOUNTS "${_mppath}" ; then
- hash_get _dev_sessions ISCSI_NUMDEVICE_SESSIONS "${_mpdev}"
- add_to_set ISCSI_EXCLUDED_SESSIONS $_dev_sessions
- continue
- fi
- # list mountpoints in reverse order (in case
- # some are stacked) mount --move may cause the
- # order of /proc/self/mountinfo to not always
- # reflect the stacking order, so this is not
- # fool-proof, but it's better than nothing
- iscsi_mount_points="$_mppath $iscsi_mount_points"
- iscsi_mount_point_ids="$_mpid $iscsi_mount_points"
- fi
- done < /proc/self/mountinfo
- }
- try_umount() {
- # in order to handle stacking try twice; together with the fact
- # that the list of mount points is in reverse order of the
- # contents /proc/self/mountinfo this should catch most cases
- for retry in 1 2 ; do
- for path in $iscsi_mount_points ; do
- # first try to see if it really is a mountpoint
- # still (might be the second round this is done
- # and the mount is already gone, or something
- # else umounted it first)
- if ! fstab-decode mountpoint -q "$path" ; then
- continue
- fi
- # try to umount it
- if ! fstab-decode umount "$path" ; then
- # unfortunately, umount's exit code
- # may be a false negative, i.e. it
- # might give a failure exit code, even
- # though it succeeded, so check again
- if fstab-decode mountpoint -q "$path" ; then
- echo "Could not unmount $path" >&2
- any_umount_failed=1
- fi
- fi
- done
- done
- }
- try_deactivate_lvm() {
- [ $HAVE_LVM -eq 1 ] || return
- for vg in $iscsi_lvm_vgs ; do
- vg_excluded=0
- hash_get vg_sessions ISCSI_LVMVG_SESSIONS "$vg"
- for vg_session in $vg_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$vg_session" ; then
- vg_excluded=1
- fi
- done
- if [ $vg_excluded -eq 1 ] ; then
- # volume group on same iSCSI session as excluded
- # mount, don't disable it
- # (FIXME: we should only exclude VGs that contain
- # those mounts, not also those that happen to be
- # in the same iSCSI session)
- continue
- fi
- if ! $VGCHANGE --available=n $vg ; then
- # Make sure the volume group (still) exists. If
- # it doesn't we count that as deactivated, so
- # don't fail then.
- _vg_test=$(vgs -o vg_name --noheadings $vg 2>/dev/null || :)
- if [ -n "${_vg_test}" ] ; then
- echo "Cannot deactivate Volume Group $vg" >&2
- any_umount_failed=1
- fi
- fi
- done
- }
- try_dismantle_multipath() {
- [ -x $MULTIPATH ] || return
- for mpalias in $iscsi_multipath_disk_aliases ; do
- mp_excluded=0
- hash_get mp_sessions ISCSI_MPALIAS_SESSIONS "$mpalias"
- for mp_session in $mp_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$mp_session" ; then
- mp_excluded=1
- fi
- done
- if [ $mp_excluded -eq 1 ] ; then
- # multipath device on same iSCSI session as
- # excluded mount, don't disable it
- # (FIXME: we should only exclude multipath mounts
- # that contain those mounts, not also those that
- # happen to be in the same iSCSI session)
- continue
- fi
- if ! $MULTIPATH -f $mpalias ; then
- echo "Cannot dismantle Multipath Device $mpalias" >&2
- any_umount_failed=1
- fi
- done
- }
- try_dismantle_luks() {
- [ $HAVE_LUKS -eq 1 ] || return
- case "$1" in
- 1) iscsi_luks_current_pass="$iscsi_luks_pass1" ;;
- 2|*) iscsi_luks_current_pass="$iscsi_luks_pass2" ;;
- esac
- for luksDev in $iscsi_luks_current_pass ; do
- luks_excluded=0
- hash_get device_sessions ISCSI_DEVICE_SESSIONS "$luksDev"
- for device_session in $device_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$device_session" ; then
- luks_excluded=1
- fi
- done
- if [ $luks_excluded -eq 1 ] ; then
- continue
- fi
- _luksName="$($DMSETUP info -c --noheadings -o name /dev/"$luksDev" 2>/dev/null || :)"
- [ -n "${_luksName}" ] || continue
- if ! $CRYPTSETUP close "${_luksName}" ; then
- echo "Cannot dismantle cryptsetup device ${_luksName}" >&2
- any_umount_failed=1
- fi
- done
- }
- # Don't do this if we are using systemd as init system, since systemd
- # takes care of network filesystems (including those marked _netdev) by
- # itself.
- if ! [ -d /run/systemd/system ] && [ $HANDLE_NETDEV -eq 1 ] && [ $DRY_RUN -eq 0 ]; then
- echo "Unmounting all devices marked _netdev";
- umount -a -O _netdev >/dev/null 2>&1
- fi
- enumerate_iscsi_devices
- # Dry run? Just print what we want to do (useful for administrator to check).
- if [ $DRY_RUN -eq 1 ] ; then
- echo "$0: would umount the following mount points:"
- had_mount=0
- if [ -n "$iscsi_mount_points" ] ; then
- for v in $iscsi_mount_points ; do
- echo " $v"
- had_mount=1
- done
- fi
- [ $had_mount -eq 1 ] || echo " (none)"
- echo "$0: would disable the following LUKS devices (second pass):"
- had_luks=0
- if [ -n "$iscsi_luks_pass2" ] ; then
- for v in ${iscsi_luks_pass2} ; do
- luks_excluded=0
- hash_get device_sessions ISCSI_DEVICE_SESSIONS "$v"
- for device_session in $device_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$device_session" ; then
- luks_excluded=1
- fi
- done
- if [ $luks_excluded -eq 1 ] ; then
- continue
- fi
- _luksName="$($DMSETUP info -c --noheadings -o name /dev/"$v" 2>/dev/null || :)"
- [ -n "${_luksName}" ] || continue
- echo " ${_luksName}"
- had_luks=1
- done
- fi
- [ $had_luks -eq 1 ] || echo " (none)"
- echo "$0: would deactivate the following LVM Volume Groups:"
- had_vg=0
- if [ -n "$iscsi_lvm_vgs" ] ; then
- for v in $iscsi_lvm_vgs ; do
- # sync this exclusion logic with try_deactivate_lvm
- vg_excluded=0
- hash_get vg_sessions ISCSI_LVMVG_SESSIONS "$v"
- for vg_session in $vg_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$vg_session" ; then
- vg_excluded=1
- fi
- done
- if [ $vg_excluded -eq 1 ] ; then
- continue
- fi
- echo " $v"
- had_vg=1
- done
- fi
- [ $had_vg -eq 1 ] || echo " (none)"
- echo "$0: would disable the following LUKS devices (first pass):"
- had_luks=0
- if [ -n "$iscsi_luks_pass1" ] ; then
- for v in ${iscsi_luks_pass1} ; do
- luks_excluded=0
- hash_get device_sessions ISCSI_DEVICE_SESSIONS "$v"
- for device_session in $device_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$device_session" ; then
- luks_excluded=1
- fi
- done
- if [ $luks_excluded -eq 1 ] ; then
- continue
- fi
- _luksName="$($DMSETUP info -c --noheadings -o name /dev/"$v" 2>/dev/null || :)"
- [ -n "${_luksName}" ] || continue
- echo " ${_luksName}"
- had_luks=1
- done
- fi
- [ $had_luks -eq 1 ] || echo " (none)"
- echo "$0: would deactivate the following multipath volumes:"
- had_mp=0
- if [ -n "$iscsi_multipath_disk_aliases" ] ; then
- for v in $iscsi_multipath_disk_aliases ; do
- # sync this exclusion logic with try_dismantle_multipath
- mp_excluded=0
- hash_get mp_sessions ISCSI_MPALIAS_SESSIONS "$v"
- for mp_session in $mp_sessions ; do
- if in_set ISCSI_EXCLUDED_SESSIONS "$mp_session" ; then
- mp_excluded=1
- fi
- done
- if [ $mp_excluded -eq 1 ] ; then
- continue
- fi
- echo " $v"
- had_mp=1
- done
- fi
- [ $had_mp -eq 1 ] || echo " (none)"
- if [ -n "$ISCSI_EXCLUDED_SESSIONS" ] ; then
- echo "$0: the following sessions are excluded from disconnection (because / or another excluded mount is on them):"
- for v in $ISCSI_EXCLUDED_SESSIONS ; do
- echo " $v"
- done
- fi
- exit 0
- fi
- # after our first enumeration, write out a list of sessions that
- # shouldn't be terminated because excluded mounts are on those
- # sessions
- if [ -n "$ISCSI_EXCLUDED_SESSIONS" ] ; then
- mkdir -p -m 0700 /run/open-iscsi
- for session in $ISCSI_EXCLUDED_SESSIONS ; do
- printf '%s\n' $session
- done > /run/open-iscsi/shutdown-keep-sessions
- else
- # make sure there's no leftover from a previous call
- rm -f /run/open-iscsi/shutdown-keep-sessions
- fi
- any_umount_failed=0
- try_umount
- try_dismantle_luks 2
- try_deactivate_lvm
- try_dismantle_luks 1
- try_dismantle_multipath
- while [ $any_umount_failed -ne 0 ] && ( [ $timeout -gt 0 ] || [ $timeout -eq -1 ] ) ; do
- # wait a bit, perhaps there was still a program that
- # was terminating
- sleep 1
- # try again and decrease timeout
- enumerate_iscsi_devices
- any_umount_failed=0
- try_umount
- try_dismantle_luks 2
- try_deactivate_lvm
- try_dismantle_luks 1
- try_dismantle_multipath
- if [ $timeout -gt 0 ] ; then
- timeout=$((timeout - 1))
- fi
- done
- # Create signaling file (might be useful)
- if [ $any_umount_failed -eq 1 ] ; then
- touch /run/open-iscsi/some_umount_failed
- else
- rm -f /run/open-iscsi/some_umount_failed
- fi
- exit $any_umount_failed
|