home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / rescue / sbin / mdrun < prev    next >
Text File  |  2006-11-29  |  5KB  |  148 lines

  1. #!/bin/sh
  2.  
  3. # mdrun, (c) Eduard Bloch <blade@debian.org> 2003
  4.  
  5. # Usage: 
  6. # Without arguments: autodetect all RAID partitions and activate MDs
  7. # Arguments: [ DEVDIR ] NUMBER UUID [ <NUMBER UUID> ... ]
  8. # a number of number/uuid pairs, where NUMBER is the one from /dev/md/*
  9. # Argument: LIST
  10. # lists all raids in the syntax needed for the pairs (see above)
  11.  
  12. # IMPORTANT: create /dev/fs directory if you have devfs support in the kernel
  13. # but do not want to mount it over /dev. Usage of /dev/fs directory will keep
  14. # mdrun away from /dev.
  15.  
  16. # If the first argument is a directory, it will be used as a writeable
  17. # temporary directory for device nodes. mdrun needs mknod to create them
  18. # on-the-fly
  19.  
  20. # Environment: 
  21. # MORERAIDVOLUMES (list of strings) : additional raid disks to scan, 
  22. #                                     eg. loop devices
  23.  
  24. if ! test -e /proc/partitions ; then
  25.    echo "/proc not mounted!"
  26.    exit 1
  27. fi
  28.  
  29. DEVDIR=/dev
  30.  
  31. if [ -d "$1" ] ; then
  32.    AUTOCREATE=true
  33.    DEVDIR="$1"
  34.    shift
  35. fi
  36.  
  37. # For people that compile the kernel with devfs (means: different
  38. # proc/partitions content), but without auto-mounting it
  39. if ! uname -r | grep "^2.6" 1>/dev/null && [ -z "$AUTOCREATE" ] && grep "    devfs" /proc/filesystems >/dev/null 2>&1 && ! grep "^devfs" /proc/mounts >/dev/null 2>&1 ; then
  40.  
  41.    mkdir /dev/fs 2>/dev/null
  42.    # if we can do it - good, we will use it. Otherwise, use /dev even if it is ugly
  43.  
  44.    # mount devfs for now to make the device names match, umount later
  45.    if [ -d /dev/fs ] ; then
  46.       DEVDIR=/dev/fs
  47.    fi
  48.    mount none $DEVDIR -tdevfs
  49.    UMNTDEVFS="umount $DEVDIR"
  50. fi
  51.  
  52. # arr(array, index): return contents in array[index]; as with Bourne shell
  53. # in general, there is no easy way to distinguish between index not
  54. # existing and empty string assigned.
  55. arr() { sa_i=`arr_index $2`; eval "echo \"\$$1_${sa_i}\""; unset sa_i; }
  56.  
  57. # seterr(array, index, value): assign the given value to array[index].
  58. setarr() { sa_i=`arr_index $2`; eval "$1_${sa_i}=\"$3\""; unset sa_i; }
  59.  
  60. # arr_index(index): make sure the given index is valid for use.
  61. arr_index() { echo $1 | sed -e 's/:/_/g' | sed 's;/;_;g'; }
  62.  
  63.  
  64. BASE=$DEVDIR/md
  65. export BASE
  66. #devfs
  67. test -d $BASE && BASE=$BASE/
  68.  
  69. next_free_md() {
  70.    for raidnr in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
  71.       if ! mdadm -D $BASE$raidnr >/dev/null 2>&1 ; then
  72.          echo $BASE$raidnr
  73.          return 0
  74.       fi
  75.    done
  76.    return 1
  77. }
  78.  
  79. listpairs() {
  80.    for NUMBER in `cat /proc/mdstat | grep "^md. : active" | sed -e 's/^md\(.\) :.*/\1/'`; do
  81.       echo $NUMBER
  82.       mdadm -D ${BASE}$NUMBER 2>/dev/null |grep UUID | sed 's/.*: \(.*\)/\1/' 
  83.    done
  84. }
  85.  
  86. if [ "$1" = LIST ] ; then
  87.    echo `listpairs`
  88.    $UMNTDEVFS
  89.    exit 0
  90. fi
  91.  
  92. DEVDIRESC=$(echo $DEVDIR | sed -e 's!/!\\/!g')
  93. if [ "$AUTOCREATE" ] ; then
  94.    CREATECMD=$(sed -e "s/.*major.*//; s/.*\ \([:0-9:]\+\)\ \+\ \([:0-9:]\+\)\ \+\ [:0-9:]\+\ \+\([:a-z0-9\/:]\+\).*/mknod \3 b \1 \2 ; / ; s/\//_/g" < /proc/partitions)
  95.    export CREATECMD
  96.    export DEVDIR
  97.    # and we need array nodes, of course
  98.    (
  99.       cd $DEVDIR ;
  100.       eval $CREATECMD ; 
  101.       for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do
  102.          mknod ${BASE}$x b 9 $x
  103.       done
  104.    )
  105.    PARTLIST=$(sed -e "s/.*major.*//; s/.*\ \([:0-9:]\+\)\ \+\ \([:0-9:]\+\)\ \+\ [:0-9:]\+\ \+\([:a-z0-9\/:]\+\).*/DEVDIR\3 /; s/\//_/g ; s/DEVDIR/$DEVDIRESC\//;" < /proc/partitions)
  106. else
  107.    PARTLIST=$(sed -e "s/.*major.*//; s/^[:0-9 :]* \([:a-z:].[:a-z0-9\/:]*\).*/\1/; s/^\([:a-z:].*\)/$DEVDIRESC\/\1/g" < /proc/partitions)
  108. fi
  109.  
  110. for SRC in $PARTLIST $MORERAIDVOLUMES ; do
  111.    SUM=$(mdadm -E $SRC 2>/dev/null | grep UUID | sed 's/.*: \(.*\)/\1/')
  112.    for x in $SUM; do
  113.       UUIDS="$UUIDS $SUM"
  114.       setarr MDS $SUM "`arr MDS $SUM` $SRC"
  115.    done
  116. done
  117.  
  118. if [ "$#" -gt 1 ] ; then
  119.    NUMBER=${BASE}$1
  120.    MD=$2
  121.    shift ; shift
  122.    if [ "`arr MDS $MD`" != "started" ] ; then
  123.       mdadm -A $NUMBER -f `arr MDS $MD` && setarr MDS $MD "started" 
  124.       # just to be sure
  125.       ln /dev/md/$NUMBER /dev/md$NUMBER 2>/dev/null
  126.    fi
  127. fi
  128.  
  129. # and process the rest, if it exists
  130. # do not touch active arrays
  131. #dropactive() {
  132.    for NUMBER in `cat /proc/mdstat | grep "^md. : active" | sed -e 's/^md\(.\) :.*/\1/'`; do
  133.       setarr MDS `mdadm -D ${BASE}$NUMBER 2>/dev/null |grep UUID | sed 's/.*: \(.*\)/\1/'` "started"
  134.    done
  135. #}
  136.  
  137.  
  138. for MD in $UUIDS; do
  139.    if [ "`arr MDS $MD`" != "started" ] ; then
  140.       NUMBER=`next_free_md`
  141.       mdadm -A $NUMBER -f `arr MDS $MD` && setarr MDS $MD "started" 
  142.       # just to be sure
  143.       ln /dev/md/$NUMBER /dev/md$NUMBER 2>/dev/null
  144.    fi
  145. done
  146.  
  147. $UMNTDEVFS
  148.