From 048532662999a5f0909646f26f5368ddbf0558fa Mon Sep 17 00:00:00 2001 From: "pyther@pyther.net" Date: Sun, 27 Feb 2011 17:41:20 -0500 Subject: Rewrite finddisks and findblockdevices (now find_usable_blockdevices) find_usable_blockdevices returns a list of block devices such as those exposed by SCSI/Sata, CCISS, IDA, LVM and Linux SOFT RAID; as well as any partitions on top of those. Devices in use by LVM and SOFT RAID are excluded. Signed-off-by: Dieter Plaetinck --- src/core/libs/lib-blockdevices-filesystems.sh | 165 ++++++++++++++------------ src/core/libs/lib-ui-interactive.sh | 4 +- 2 files changed, 88 insertions(+), 81 deletions(-) (limited to 'src/core') diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh index ac749a3..a52dcca 100644 --- a/src/core/libs/lib-blockdevices-filesystems.sh +++ b/src/core/libs/lib-blockdevices-filesystems.sh @@ -206,99 +206,106 @@ getlabel() { # find partitionable blockdevices # $1 extra things to echo for each device (optional) (backslash escapes will get interpreted) finddisks() { - workdir="$PWD" - if cd /sys/block 2>/dev/null - then - # ide devices - for dev in $(ls | egrep '^hd') - do - if [ "$(cat $dev/device/media)" = "disk" ] - then - echo -ne "/dev/$dev $1" - fi - done - #scsi/sata devices, and virtio blockdevices (/dev/vd*) - for dev in $(ls | egrep '^[sv]d') - do - # TODO: what is the significance of 5? ASKDEV - if [ "$(cat $dev/device/type)" != "5" ] - then - echo -ne "/dev/$dev $1" + shopt -s nullglob + + # Block Devices + for dev in /sys/block/*; do + if [[ -f $dev/device/type ]]; then + local type + read type < /sys/block/${dev##*/}/device/type + # Block Devices with size =< 0 may be an empty card reader + read size < /sys/block/${dev##*/}/size + # Type 5 is a ROM Device - Optical Drives + if [[ $type != 5 ]] && (( $size > 0 )); then + source "$dev/uevent" + echo -ne "/dev/$DEVNAME $1" + unset DEVNAME fi - done - fi + fi + done + # cciss controllers - if cd /dev/cciss 2>/dev/null - then - for dev in $(ls | egrep -v 'p') - do - echo -ne "/dev/cciss/$dev $1" - done - fi - # Smart 2 controllers - if cd /dev/ida 2>/dev/null - then - for dev in $(ls | egrep -v 'p') - do - echo -ne "/dev/ida/$dev $1" - done - fi - cd "$workdir" + for dev in /dev/cciss/*; do + if [[ $dev != *[[:digit:]]p[[:digit:]]* ]]; then + echo "$dev $1" + fi + done + + # Smart 2 Controller + for dev in /dev/ida/*; do + if [[ $dev != *[[:digit:]]p[[:digit:]]* ]]; then + echo "$dev $1" + fi + done + + shopt -u nullglob } -# find block devices, both partionable or not (i.e. partitions themselves) + +# find usable blockdevices, both partionable or not (i.e. partitions themselves) # $1 extra things to echo for each partition (optional) (backslash escapes will get interpreted) -findblockdevices() { - workdir="$PWD" - for devpath in $(finddisks) - do - disk=$(basename $devpath) - echo -ne "/dev/$disk $1" - cd /sys/block/$disk - shopt -s nullglob - for part in $disk* - do - # check if not already assembled to a raid device. TODO: what is the significance of the 5? ASKDEV - if [ -n "$part" ] && ! grep -q $part /proc/mdstat 2>/dev/null && ! fstype 2>/dev/null /dev/null | grep -q '5' - then - if [ -d $part ] - then - echo -ne "/dev/$part $1" - fi +find_usable_blockdevices() { + shopt -s nullglob + + local parts + + # Cycle through all root block devices (sda, sdb, etc...) + # Look for partitions and include them only if they are not part of a + # RAID or LVM configuration. Also, exclude extended partitions + for devpath in $(finddisks); do + hidebldev= + unset parts + + # Glob allows for following matches: + # /dev/sda -> /dev/sda1 + # /dev/cciss/c0d1 -> /dev/cciss/c0d1p1 + for dev in ${devpath}*[[:digit:]]*; do + local disk="${dev%%[[:digit:]]*}" + local partnum="${dev##*[[:alpha:]]}" + + # Don't display extended partition (not logical parts) + [ "$(sfdisk -c "$disk" "$partnum" 2>/dev/null)" = 5 ] && continue; + + # Don't list parts that are part of RAID or LVM volumes + # Although we strongly encourage users to setup LVM in AIF, we want to make + # life a bit easier for those who have setup LVM/softraid before running AIF + if grep -qsw "${dev##*/}" /proc/mdstat || { pvscan -s 2>/dev/null | grep -q "$dev"; }; then + hidebldev="True" + else + parts+=("$dev") fi done - shopt -u nullglob + + # If hidebldev is not set and we have no partitions then + # Echo root block device if root block device is not part of a LVM or RAID configuration + # Otherwise echo the partitions + if [[ -z $hidebldev ]] && (( ! ${#parts[@]} )); then + if ! grep -qsw "${devpath##*/}" /proc/mdstat && ! pvscan -s 2>/dev/null | grep -q "$devpath"; then + echo -ne "$devpath $1" + fi + elif (( ${#parts[@]} )); then + for part in ${parts[@]}; do + echo -ne "$part $1" + done + fi done + # mapped devices - for devpath in $(ls /dev/mapper 2>/dev/null | grep -v control) - do - echo -ne "/dev/mapper/$devpath $1" + for devpath in /dev/mapper/*; do + # Exclude /control directory and other non-block files (such as??) + if [[ -b $devpath ]]; then + echo -ne "$devpath $1" + fi done + # raid md devices - for devpath in $(ls -d /dev/md* | grep '[0-9]' 2>/dev/null) - do - if grep -qw $(echo $devpath /proc/mdstat | sed -e 's|/dev/||g') - then + for devpath in /dev/md[0-9]*; do + if grep -qw "${devpath//\/dev\//}" /proc/mdstat; then echo -ne "$devpath $1" fi done - # cciss controllers - if cd /dev/cciss 2>/dev/null - then - for dev in $(ls | egrep 'p') - do - echo -ne "/dev/cciss/$dev $1" - done - fi - # Smart 2 controllers - if cd /dev/ida 2>/dev/null - then - for dev in $(ls | egrep 'p') - do - echo -ne "/dev/ida/$dev $1" - done - fi - cd "$workdir" + + shopt -u nullglob } diff --git a/src/core/libs/lib-ui-interactive.sh b/src/core/libs/lib-ui-interactive.sh index b244a6e..64be570 100644 --- a/src/core/libs/lib-ui-interactive.sh +++ b/src/core/libs/lib-ui-interactive.sh @@ -557,7 +557,7 @@ interactive_filesystems() { if [ ! -f $TMP_BLOCKDEVICES ] || ! ask_yesno "Previous blockdevice definitions found:\n`cat $TMP_BLOCKDEVICES`\n\ Use these as a starting point? Make sure your disk(s) are partitioned correctly so your definitions can be applied. Pick 'no' when in doubt to start from scratch" no then - findblockdevices 'raw no_label no_fs\n' > $TMP_BLOCKDEVICES + find_usable_blockdevices 'raw no_label no_fs\n' > $TMP_BLOCKDEVICES fi [ -z "$PART_ACCESS" ] && PART_ACCESS=dev @@ -885,7 +885,7 @@ interactive_grub() { # Create and edit the grub menu.lst interactive_grub_menulst - DEVS="$(findblockdevices '_ ')" + DEVS="$(find_usable_blockdevices '_ ')" if [ "$DEVS" = " " ]; then notify "No hard drives were found" return 1 -- cgit v1.2.3-54-g00ecf