home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Linux / Ubuntu_64-bit / ubuntu-11.04-desktop-amd64.iso / casper / filesystem.squashfs / sbin / dmraid-activate < prev    next >
Text File  |  2011-03-25  |  7KB  |  266 lines

  1. #!/bin/sh
  2. #
  3. # dmraid-activate: Script to reformat the output of dmraid to be useful with
  4. # udev.
  5. #
  6. # (c) 2008 Canonical Ltd.
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21.  
  22. # Arguments: $1 = Name of array you want activated.
  23. activate_array ()
  24. {
  25.     Raid_Setinfo=$(dmraid -i -si "$1")
  26.     if [ -z "$Raid_Setinfo" ]; then
  27.         log_error "Cannot retrieve RAID set information for $1"
  28.         return 1
  29.     fi
  30.  
  31.     Raid_Type=$(dmraid -i -si -ct "$1")
  32.     Raid_Nodevs=$(dmraid -i -si -cd "$1")
  33.  
  34.     case "$Raid_Type" in
  35.         stripe)
  36.             if [ "$Raid_Nodevs" -lt 2 ]; then
  37.                 if [ -n "$Degraded" ]; then
  38.                     log_error "Cannot bring up a RAID0 array in degraded mode, not all devices present."
  39.                 fi
  40.                 return 2
  41.             fi
  42.             ;;
  43.         mirror)
  44.             if [ "$Raid_Nodevs" -lt 2 ]; then
  45.                 if [ -z "$Degraded" ]; then
  46.                     log_error "Raid set $Raid_Name is degraded. Not activating"
  47.                     return 2
  48.                 else
  49.                     log_warning "Activating $Raid_Name in degraded mode"
  50.                     Return_Val=3
  51.                 fi
  52.             fi
  53.             ;;
  54.         raid5_*)
  55.             modprobe -q dm_raid45
  56.             if [ "$Raid_Nodevs" -lt 3 ]; then
  57.                 if [ -z "$Degraded" ]; then
  58.                     log_error "Raid set $Raid_Name is degraded. Not activating"
  59.                     return 2
  60.                 else
  61.                     log_warning "Activating $Raid_Name in degraded mode"
  62.                     Return_Val=3
  63.                 fi
  64.             fi
  65.             ;;
  66.     esac
  67.  
  68.     # At this point we have the required number of devs, or the user wants the
  69.     # array brought up in degraded mode, except in the case of striped arrays.
  70.  
  71.     dmraid -i -ay -Z "$1"
  72.     return $Return_Val
  73. }
  74.  
  75. log_warning()
  76. {
  77.     if type logger > /dev/null ; then
  78.         logger -t dmraid-activate "WARNING: $1"
  79.     else
  80.         echo "dmraid-activate: WARNING: $1"
  81.     fi
  82. }
  83.  
  84. log_error()
  85. {
  86.     if type logger > /dev/null ; then
  87.         logger -t dmraid-activate "ERROR: $1"
  88.     else
  89.         echo "dmraid-activate: ERROR: $1"
  90.     fi
  91. }
  92.  
  93. ddf1_virtual_drive_names()
  94. {
  95.     ddf1_awk_script="$(cat <<'EOF'
  96. BEGIN {
  97.     section = ""
  98.     disk_ref = ""
  99.     guid_i = 0
  100.  
  101.     # Heximal to decimal conversion array
  102.     for (i = 0; i <= 9; i++) hex2dec[i] = i
  103.     hex2dec["a"] = 10; hex2dec["b"] = 11; hex2dec["c"] = 12
  104.     hex2dec["e"] = 13; hex2dec["d"] = 14; hex2dec["f"] = 15;
  105. }
  106.  
  107. function section_begins(name)
  108. {
  109.     section = name
  110.     vd_guid = ""
  111.     drive_map = 0
  112. }
  113.  
  114. function extract_vd_guid(line,      g)
  115. {
  116.     g = substr(line, match(line,/\[[0-9a-f ]+\]$/)+1, RLENGTH-2)
  117.     gsub(/ /, "", g)
  118.     # IF LSI, do timestamp substitution to get persistent name, see
  119.     # 19_ddf1_lsi_persistent_name.patch
  120.     if (g ~ /^4c5349/)
  121.         g = substr(g, 1, 32) "47114711" substr(g, 41)
  122.     return g
  123. }
  124.  
  125. function extract_vd_name(line,     hex, n, max, i, d1, d2, sed)
  126. {
  127.     n = tolower(substr(line, match(line,/\[[0-9a-f ]+\]$/)+1, RLENGTH-2))
  128.     max = split(n, hex, / /)
  129.  
  130.     if (max <= 0 || hex[0] == "00") return ""
  131.  
  132.     # Convert name from hex to string (16 bytes)
  133.     n = ""
  134.     for (i = 1; i <= max; i++) {
  135.         d1 = hex2dec[substr(hex[i], 1, 1)]
  136.         d2 = hex2dec[substr(hex[i], 2, 1)]
  137.         if ((d1 + d2) == 0) break
  138.         n = n sprintf("%c", d1 * 16 + d2)
  139.     }
  140.     # Shell-escape single quotes in the name
  141.     gsub(/'/,"'\\''", n)
  142.     # Finally strip non-graph chars from the end of the string
  143.     # mawk does not support character classes. Use sed.
  144.     sed = "echo '" n "' | sed 's/[^[:graph:]]\+$//'"
  145.     sed | getline n
  146.     close(sed)
  147.     return n
  148. }
  149.  
  150. {
  151.     if (!/^0x/ && / at /) {
  152.         # Section begins
  153.         section_begins(substr($0, 1, match($0, / at /)-1))
  154.     } else if (section == "Disk Data" && /^0x020 reference:[ \t]*[0-9A-Fx]+/) {
  155.         disk_ref = $3
  156.         sub(/^0x/, "", disk_ref)
  157.     } else if (disk_ref) {
  158.         # We need to parse 'Virtual Drive' sections in order to extract VD
  159.         # names
  160.         if (section == "Virtual Drive") {
  161.             if (/^0x000 guid:/) {
  162.                 vd_guid = extract_vd_guid($0)
  163.             } else if (/^0x030 name:/) {
  164.                 vd_name = extract_vd_name($0)
  165.                 if (vd_name)
  166.                     vd_names[vd_guid] = vd_name
  167.             }
  168.         } else if (section == "Virtual Drive Config Record") {
  169.             if (/^0x008 guid:/) {
  170.                 vd_guid = extract_vd_guid($0)
  171.             } else if (drive_map) {
  172.                 # 0: 4BCBB980 @ 0
  173.                 if ($2 == disk_ref) {
  174.                     guids[guid_i] = vd_guid
  175.                     guid_i++
  176.                 }
  177.             } else if (vd_guid) {
  178.                 drive_map = /^Drive map:/
  179.             }
  180.         }
  181.     }
  182. }
  183. END {
  184.     # Print discovered virtual drive names (or GUIDs) which belong to this
  185.     # physical drive
  186.     for (guid_i in guids) {
  187.         guid = guids[guid_i]
  188.         if (guid in vd_names) {
  189.             print vd_names[guid]
  190.         } else {
  191.             print guid
  192.         }
  193.     }
  194. }
  195. EOF
  196. )"
  197.     dmraid -i -n "$1" | awk "$ddf1_awk_script"
  198. }
  199.  
  200. if grep -qs "\<nodmraid\>" /proc/cmdline; then
  201.     log_warning "dmraid disabled by boot option"
  202.     exit 0
  203. fi
  204.  
  205. modprobe -q dm_mod
  206.  
  207. if [ -z "$1" ] || [ "$1" = "--degraded" ] && [ "$#" -lt 2 ]; then
  208.     echo "Node name not specified." >&2
  209.     exit 1
  210. fi
  211.  
  212. if [ "$1" = "--degraded" ]; then
  213.     Degraded=1
  214.     Node_Name=$2
  215. else
  216.     Node_Name=$1
  217. fi
  218.  
  219. Raid_Name=$(dmraid -i -r -cr /dev/$Node_Name | grep -vi "No RAID disks" | grep -vi "formats discovered")
  220.  
  221. if [ -z "$Raid_Name" ]; then
  222.     exit 0
  223. fi
  224.  
  225. newline="
  226. "
  227.  
  228. case "$Raid_Name" in
  229.     isw_*)
  230.         # We need a special case for isw arrays, since it is possible to have several
  231.         # subsets of a RAID group, of varying RAID types.
  232.         Isw_Group_Name=$Raid_Name
  233.         Isw_Subsets=$(dmraid -i -n "/dev/$Node_Name" | grep volume | sed 's/.*volume: " *\(.*\)"$/\1/')
  234.  
  235.         for isw_subset in $Isw_Subsets
  236.         do
  237.             activate_array "${Isw_Group_Name}_${isw_subset}"
  238.         done
  239.         break
  240.         ;;
  241.     .ddf1_disks)
  242.         # Dummy name for the main DDF1 group. Needs special handling to
  243.         # find RAID subsets (name or GUID) for this physical drive
  244.         Ddf1_names=`ddf1_virtual_drive_names "/dev/$Node_Name"`
  245.  
  246.         # Returned names might contain space characters. Therefore
  247.         # split fields at new line. Use $IFS to avoid forking a new shell
  248.         save_IFS="$IFS"
  249.         IFS="$newline"
  250.         for ddf1_name in $Ddf1_names
  251.         do
  252.             IFS="$save_IFS"
  253.             activate_array "ddf1_${ddf1_name}"
  254.             IFS="$newline"
  255.         done
  256.         IFS="$save_IFS"
  257.         break
  258.         ;;
  259.     *)
  260.         activate_array "$Raid_Name"
  261.         break
  262.         ;;
  263. esac
  264.  
  265. exit $Return_Val
  266.