~xnox/ubuntu/quantal/mdadm/merge

« back to all changes in this revision

Viewing changes to contrib/mdadd.sh

  • Committer: Dmitrijs Ledkovs
  • Author(s): Surbhi Palande
  • Date: 2010-09-30 17:46:19 UTC
  • mfrom: (1.1.25 sid)
  • Revision ID: dmitrijs.ledkovs@canonical.com-20100930174619-cqsokylnluraiyr8
Tags: 3.1.4-1+8efb9d1ubuntu1
* Merge from debian unstable. (LP: #603582) 
* Remaining changes
  - Assemble.c, config.c: upgraded to the mdadm-3.1.4 version of these files
    from Debian.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/rules: kept debian's switch to using dh_lintian
  - debian/mdadm.links, debian/mdadm.manpages: dropped owing to the fact
    that these are not used in Ubuntu. Also dropped the build-dep on docbook
    to man)
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntus version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/bash
 
2
 
 
3
MY_VERSION="1.46"
 
4
# ----------------------------------------------------------------------------------------------------------------------
 
5
# Linux MD (Soft)RAID Add Script - Add a (new) harddisk to another multi MD-array harddisk
 
6
# Last update: June 9, 2009
 
7
# (C) Copyright 2005-2009 by Arno van Amersfoort
 
8
# Homepage              : http://rocky.eld.leidenuniv.nl/
 
9
# Email                 : a r n o v a AT r o c k y DOT e l d DOT l e i d e n u n i v DOT n l
 
10
#                         (note: you must remove all spaces and substitute the @ and the . at the proper locations!)
 
11
# ----------------------------------------------------------------------------------------------------------------------
 
12
# This program is free software; you can redistribute it and/or
 
13
# modify it under the terms of the GNU General Public License
 
14
# version 2 as published by the Free Software Foundation.
 
15
#
 
16
# This program is distributed in the hope that it will be useful,
 
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
# GNU General Public License for more details.
 
20
#
 
21
# You should have received a copy of the GNU General Public License
 
22
# along with this program; if not, write to the Free Software
 
23
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
24
# ----------------------------------------------------------------------------------------------------------------------
 
25
 
 
26
TAB=$(printf "\t")
 
27
EOL='
 
28
'
 
29
 
 
30
show_help()
 
31
{
 
32
  echo "Bad or missing parameter(s)"
 
33
  echo "Usage: $(basename $0) [ source_disk ] [ target_disk ] [ options ]"
 
34
  echo "Options:"
 
35
  echo "--force       = Even proceed if target device does not appear empty"
 
36
  echo "--noptupdate  = Do NOT update the partition table on the target device (EXPERT!)"
 
37
  echo "--nombrupdate = Do NOT update the MBR boot-loader on the target device (EXPERT!)"
 
38
}
 
39
 
 
40
 
 
41
get_partitions()
 
42
{
 
43
  cat /proc/partitions |awk '{ print $NF }' |sed -e '1,2d' -e 's,^/dev/,,'
 
44
}
 
45
 
 
46
 
 
47
check_binary()
 
48
{
 
49
  if ! which "$1" >/dev/null 2>&1; then
 
50
    printf "\033[40m\033[1;31mERROR: Binary \"$1\" does not exist or is not executable!\033[0m\n" >&2
 
51
    printf "\033[40m\033[1;31m       Please, make sure that it is (properly) installed!\033[0m\n" >&2
 
52
    exit 2
 
53
  fi
 
54
}
 
55
 
 
56
 
 
57
sanity_check()
 
58
{
 
59
  if [ "$UID" != "0" ]; then
 
60
    printf "\033[40m\033[1;31mERROR: Root check FAILED (you MUST be root to use this script)! Quitting...\n\033[0m"
 
61
    exit 1
 
62
  fi
 
63
 
 
64
  check_binary mdadm
 
65
  check_binary sfdisk
 
66
  check_binary fdisk
 
67
  check_binary dd
 
68
  check_binary awk
 
69
  check_binary grep
 
70
  check_binary sed
 
71
  check_binary cat
 
72
 
 
73
  if [ -z "$SOURCE" ] || [ -z "$TARGET" ]; then
 
74
    echo "ERROR: Bad or missing argument(s)"
 
75
    show_help;
 
76
    exit 4
 
77
  fi
 
78
 
 
79
  if ! echo "$SOURCE" |grep -q '^/dev/'; then
 
80
    printf "\033[40m\033[1;31mERROR: Source device $SOURCE does not start with /dev/! Quitting...\n\033[0m"
 
81
    exit 5
 
82
  fi
 
83
 
 
84
  if ! echo "$TARGET" |grep -q '^/dev/'; then
 
85
    printf "\033[40m\033[1;31mERROR: Target device $TARGET does not start with /dev/! Quitting...\n\033[0m"
 
86
    exit 5
 
87
  fi
 
88
 
 
89
  if echo "$SOURCE" |grep -q 'md[0-9]'; then
 
90
    printf "\033[40m\033[1;31mERROR: The source device specified is an md-device! Quitting...\n\033[0m"
 
91
    echo "A physical drive (part of the md-array('s)) is required as source device (ie. /dev/hda)!"
 
92
    exit 5
 
93
  fi
 
94
 
 
95
  # We also want variables without /dev/ :
 
96
  SOURCE_NODEV="$(echo "$SOURCE" |sed 's,^/dev/,,')"
 
97
  TARGET_NODEV="$(echo "$TARGET" |sed 's,^/dev/,,')"
 
98
 
 
99
  if ! get_partitions |grep -E -q -x "$SOURCE_NODEV""p?[0-9]+"; then
 
100
    printf "\033[40m\033[1;31mERROR: Source device $SOURCE does not contain any partitions!? Quitting...\n\033[0m"
 
101
    exit 7
 
102
  fi
 
103
 
 
104
  if get_partitions |grep -E -q -x "$TARGET_NODEV""p?[0-9]+" && [ "$FORCE" != "1" ]; then
 
105
    printf "\033[40m\033[1;31mERROR: Target device $TARGET is NOT empty! Use --force to override. Quitting...\n\033[0m"
 
106
    exit 8
 
107
  fi
 
108
 
 
109
  echo "--> Saving mdadm detail scan to /tmp/mdadm-detail-scan.txt..." 
 
110
  mdadm --detail --scan --verbose >/tmp/mdadm-detail-scan.txt
 
111
  retval=$?
 
112
  if [ "$retval" != "0" ]; then
 
113
    printf "\033[40m\033[1;31mERROR: mdadm returned an error($retval) while determining detail information!\n\033[0m"
 
114
    exit 10
 
115
  fi 
 
116
 
 
117
  echo "--> Saving partition table of target device $TARGET to /tmp/partitions.$TARGET_NODEV..."
 
118
  sfdisk -d "$TARGET" >"/tmp/partitions.$TARGET_NODEV"
 
119
  retval=$?
 
120
  if [ "$retval" != "0" ]; then
 
121
    printf "\033[40m\033[1;31mERROR: sfdisk returned an error($retval) while reading the partition table!\n\033[0m"
 
122
    exit 9
 
123
  fi
 
124
 
 
125
  echo "--> Saving partition table of source device $SOURCE to /tmp/partitions.$SOURCE_NODEV..."
 
126
  sfdisk -d "$SOURCE" >"/tmp/partitions.$SOURCE_NODEV"
 
127
  retval=$?
 
128
  if [ "$retval" != "0" ]; then
 
129
    printf "\033[40m\033[1;31mERROR: sfdisk returned an error($retval) while reading the partition table!\n\033[0m"
 
130
    exit 9
 
131
  fi
 
132
 
 
133
  MD_DEV=""
 
134
  IFS=$EOL
 
135
  for MDSTAT_LINE in `cat /proc/mdstat`; do
 
136
    if echo "$MDSTAT_LINE" |grep -q '^md'; then
 
137
      MD_DEV_LINE="$MDSTAT_LINE"
 
138
      MD_DEV="$(echo "$MDSTAT_LINE" |awk '{ print $1 }')"
 
139
 
 
140
      unset IFS
 
141
      for part_nodev in `cat "/tmp/partitions.$TARGET_NODEV" |grep '^/dev/' |grep -v 'Id= 0' |awk '{ print $1 }' |sed 's,^/dev/,,'`; do
 
142
        if echo "$MD_DEV_LINE" |grep -E -q "[[:blank:]]$part_nodev\["; then
 
143
          printf "\033[40m\033[1;31mWARNING: Partition /dev/$part_nodev on target device is already in use by array /dev/$MD_DEV!\nPress enter to continue or CTRL-C to abort...\n\033[0m"
 
144
          read
 
145
        fi
 
146
      done
 
147
    fi
 
148
 
 
149
    if echo "$MDSTAT_LINE" |grep -E -q '[[:blank:]]blocks[[:blank:]]' && ! echo "$MDSTAT_LINE" |grep -q '_'; then
 
150
      # This array is NOT degraded so now check whether we want to add devices to it:
 
151
      unset IFS
 
152
      #FIXME!
 
153
      for part_nodev in `cat "/tmp/partitions.$SOURCE_NODEV" |grep '^/dev/' |grep -v 'Id= 0' |awk '{ print $1 }' |sed 's,^/dev/,,'`; do
 
154
        if echo "$MD_DEV_LINE" |grep -E -q "[[:blank:]]$part_nodev\["; then
 
155
          printf "\033[40m\033[1;31mWARNING: Array $MD_DEV is NOT degraded, target device $TARGET$(echo "$part_nodev" |sed "s,$SOURCE_NODEV,,") will become a hotspare!\nPress enter to continue or CTRL-C to abort...\n\033[0m"     echo "WARNING: Array is not degraded: $LINE"
 
156
          read
 
157
        fi
 
158
      done
 
159
    fi
 
160
  done
 
161
}
 
162
 
 
163
 
 
164
# Program entry point
 
165
echo "MDadd for SoftRAID-MDADM v$MY_VERSION"
 
166
echo "Written by Arno van Amersfoort"
 
167
echo "--------------------------------"
 
168
 
 
169
# Set environment variables to default
 
170
FORCE=0
 
171
NOPTUPDATE=0
 
172
NOMBRUPDATE=0
 
173
SOURCE=""
 
174
TARGET=""
 
175
 
 
176
# Check arguments
 
177
for arg in $*; do
 
178
  ARGNAME="$(echo "$arg" |cut -d= -f1)"
 
179
  ARGVAL="$(echo "$arg" |cut -d= -f2)"
 
180
 
 
181
  if ! echo "$ARGNAME" |grep -q '^-'; then
 
182
    if [ -z "$SOURCE" ]; then
 
183
      SOURCE="$ARGVAL"
 
184
    else
 
185
      if [ -z "$TARGET" ]; then
 
186
        TARGET="$ARGVAL"
 
187
      else
 
188
        show_help;
 
189
        exit 3
 
190
      fi
 
191
    fi
 
192
  else
 
193
    case "$ARGNAME" in
 
194
      --force|-force|-f) FORCE=1;;
 
195
      --noptupdate|-noptupdate|--noptu|-noptu) NOPTUPDATE=1;;
 
196
      --nombrupdate|-nombrupdate|--nombru|nombru) NOMBRUPDATE=1;;
 
197
      --help) show_help;
 
198
              exit 0;;
 
199
      *) echo "ERROR: Bad argument: $ARGNAME";
 
200
         show_help;
 
201
         exit 3;;
 
202
    esac
 
203
  fi
 
204
done
 
205
 
 
206
# Make sure everything is sane:
 
207
sanity_check;
 
208
 
 
209
# Disable all swaps on target disk
 
210
echo "--> Disabling any swap partitions on target device $TARGET"
 
211
IFS=$EOL
 
212
for SWAP in `grep -E "^$TARGET""p?[0-9]+" /proc/swaps |awk '{ print $1 }'`; do
 
213
  swapoff $SWAP >/dev/null 2>&1
 
214
done
 
215
 
 
216
# Update track0 on target disk
 
217
if [ "$NOMBRUPDATE" != "1" ]; then
 
218
  echo "--> Copying track0(containing MBR) from $SOURCE to $TARGET..."
 
219
  dd if="$SOURCE" of="$TARGET" bs=65536 count=1
 
220
  retval=$?
 
221
  if [ "$retval" != "0" ]; then
 
222
    printf "\033[40m\033[1;31mERROR: dd returned an error($retval) while copying track0!\n\033[0m"
 
223
    exit 9
 
224
  fi
 
225
fi
 
226
 
 
227
if [ "$NOPTUPDATE" != "1" ]; then
 
228
  echo "--> Restoring partition table from /tmp/partitions.$SOURCE_NODEV to $TARGET..."
 
229
  cat "/tmp/partitions.$SOURCE_NODEV" |sfdisk --force "$TARGET"
 
230
  retval=$?
 
231
  if [ "$retval" != "0" ]; then
 
232
    printf "\033[40m\033[1;31mERROR: sfdisk returned an error($retval) while writing the partition table!\n\033[0m"
 
233
    exit 9
 
234
  fi
 
235
else
 
236
  echo "--> Restoring partition table from /tmp/partitions.$TARGET_NODEV to $TARGET..."
 
237
  cat "/tmp/partitions.$TARGET_NODEV" |sfdisk --force "$TARGET"
 
238
  retval=$?
 
239
  if [ "$retval" != "0" ]; then
 
240
    printf "\033[40m\033[1;31mERROR: sfdisk returned an error($retval) while writing the partition table!\n\033[0m"
 
241
    exit 9
 
242
  fi
 
243
fi
 
244
 
 
245
 
 
246
# Copy/build all md devices that exist on the source drive:
 
247
BOOT=0
 
248
NO_ADD=1
 
249
IFS=$EOL
 
250
for LINE in `cat /tmp/mdadm-detail-scan.txt`; do
 
251
  if echo "$LINE" |grep -E -q '^ARRAY[[:blank:]]'; then
 
252
    MD_DEV=$(echo "$LINE" |awk '{ print $2 }')
 
253
  fi
 
254
 
 
255
  if echo "$LINE" |grep -q "devices=.*$SOURCE"; then
 
256
    NO_ADD=0
 
257
    PARTITION_NR="$(echo "$LINE" |sed -e "s:.*devices=.*$SOURCE::" -e "s:,.*::")"
 
258
 
 
259
    if [ -z "$PARTITION_NR" ]; then
 
260
      printf "\033[40m\033[1;31mERROR: Unable to retrieve detail information for $SOURCE from $MD_DEV!\n\033[0m"
 
261
      exit 11
 
262
    fi
 
263
 
 
264
    # Check whether we're a root or boot partition
 
265
    if grep -E -q -e "^$MD_DEV[[:blank:]]*/boot[[:blank:]]" -e "$MD_DEV[[:blank:]]*/[[:blank:]]" /etc/fstab; then
 
266
      BOOT=1
 
267
    fi
 
268
 
 
269
    echo ""
 
270
    echo "--> Adding $TARGET$PARTITION_NR to RAID array $MD_DEV:"
 
271
    printf "\033[40m\033[1;31m"
 
272
    mdadm --add "$MD_DEV" "$TARGET""$PARTITION_NR"
 
273
    retval=$?
 
274
    if [ "$retval" != "0" ]; then
 
275
      printf "\033[40m\033[1;31mERROR: mdadm returned an error($retval) while adding device!\n\033[0m"
 
276
      exit 12
 
277
    fi
 
278
    printf "\033[0m"
 
279
  fi
 
280
done
 
281
 
 
282
echo ""
 
283
 
 
284
# Create swapspace on partitions with ID=82
 
285
echo "--> Creating swapspace on target device (if any swap partitions exist):"
 
286
IFS=$EOL
 
287
for SWAP_DEVICE in `sfdisk -d "$TARGET" |grep -i 'Id=82' |awk '{ print $1 }'`; do
 
288
  mkswap "$SWAP_DEVICE"
 
289
  swapon "$SWAP_DEVICE"
 
290
 
 
291
  if ! grep -E -q "^$SWAP_DEVICE[[:blank:]]*none[[:blank:]]*swap[[:blank:]]" /etc/fstab; then
 
292
    printf "\033[40m\033[1;31mWARNING: /etc/fstab does NOT contain a (valid) swap entry for $SWAP_DEVICE\n\033[0m"
 
293
  fi
 
294
done
 
295
 
 
296
#echo "--> Showing current mdadm detail-scan (you may need to update your mdadm.conf (manually):"
 
297
#mdadm --detail --scan
 
298
 
 
299
echo "--> Showing current /proc/mdstat (you may need to update your mdadm.conf (manually):"
 
300
cat /proc/mdstat
 
301
echo ""
 
302
 
 
303
if [ "$NO_ADD" = "1" ]; then
 
304
  printf "\033[40m\033[1;31mWARNING: No mdadm --add actions were performed, please investigate!\n\033[0m"
 
305
fi
 
306
 
 
307
if [ "$BOOT" = "1" ]; then
 
308
  printf "\033[40m\033[1;31mNOTE: Boot and/or root partition detected.\n      You *MAY* need to reinstall your boot loader (ie. GRUB) on this device!\n\033[0m"
 
309
fi
 
310
 
 
311
# TODO?:
 
312
# sanity check nopt (check if target device has a partition table)?
 
313
# detect if device has superblock (mdadm --examine /dev/sda1; echo $?)?
 
314
# continue ask (show what will be done):?