bootdisk: ui-parted2 (HEAD) [malekith]

PLD CVS pld-cvs-commit w pld.org.pl
Pon, 29 Lip 2002, 13:18:37 CEST


Module name:	bootdisk
Changes by:	malekith	02/07/29 13:18:35

Modified files:
	ui-parted2

Log message:
- support configuration of RAID
- "Leave partitioner" instead of "Next >>"

Index: ui-parted2
===================================================================
RCS file: /cvsroot/bootdisk/batch-installer/ui/ui-parted2,v
diff -d -u -r1.19 -r1.20
--- ui-parted2	2002/07/26 10:18:48	1.19
+++ ui-parted2	2002/07/29 11:18:35	1.20
@@ -20,7 +20,12 @@
 
 load_part () {
   local suf
-  suf=`echo $1_$2 | sed -e 's|/|_|g'`
+  if test -n "$2" ; then
+    suf=`echo $1_$2 | sed -e 's|/|_|g'`
+  else
+    suf="$1"
+  fi
+  part_file=
   part_name=
   part_device=
   part_minor=
@@ -32,18 +37,30 @@
   part_fstab_options=defaults
   part_format_options=
   part_mnt_point=
-  if test -f /tmp/part.$suf ; then
+  part_md_list=
+  part_md_part_of=
+  part_md_level=
+  part_md_parity_algorithm=
+  part_md_chunk_size=
+  part_md_just_start=
+  part_md_persistent_superblock=
+  part_md_spare=
+  if test -f $suf ; then
+    . $suf
+  elif test -f /tmp/part.$suf ; then
     . /tmp/part.$suf
   else
+    part_file=/tmp/part.$suf
     id=1
     name=$(part $1 $2)
     while [ $id -lt 100 ] ; do
       eval_partition_info $id
-      if [ "$dest_part_mnt_point" = "" ] ; then
+      if [ "$dest_part_device" = "" ] ; then
         break
       fi
 
-      if [ "$dest_part_device" = $name ] ; then
+      case "$dest_part_device" in
+      "$name" | "$name:"* )
         part_name=$name
         part_device=$1
         part_minor=$2
@@ -60,31 +77,130 @@
         part_touch=yes
 	part_fstab_options="$dest_part_options"
 	part_format_options="$dest_part_format_options"
-      fi
+	break
+      esac
       
       id=$(($id+1))
     done
   fi
 }
 
+load_raid_partitions () {
+  id=1
+
+  while [ $id -lt 100 ] ; do
+    eval_partition_info $id
+    if [ "$dest_part_device" = "" ] ; then
+      break
+    fi
+
+    case "$dest_part_device" in
+    /dev/md* )
+      no=$(echo $dest_part_device | sed -e 's|^/dev/md\([0-9]*\).*|\1|')
+      load_part /dev/md $no
+      # fix it up
+      part_file=/tmp/part.md_$no
+      part_device=md
+      echo $dest_part_device | (IFS=: read device rest; echo $rest) | (
+        IFS=, 
+	read part_md_level rest
+	part_md_list=
+	part_md_persistent_superblock=yes
+	part_md_just_start=no
+	part_md_parity_algorithm=auto
+	part_md_chunk_size=auto
+	part_md_spare=
+	for md_device in $rest ; do
+	  unset IFS
+	  case $md_device in
+	    /dev/*:spare )
+	      part_md_spare="$part_md_spare $(
+	      	echo $md_device | (IFS=: read fst snd; echo $fst))"
+          esac
+	  case $md_device in
+	    parity_algorithm=* )
+	      part_md_parity_algorithm=$(echo $md_device | sed -e 's/.*=//')
+	      ;;
+	    chunk_size=* )
+	      part_md_chunk_size=$(echo $md_device | sed -e 's/.*=//')
+	      ;;
+	    persistent_superblock=0 )
+	      part_md_persistent_superblock=no
+	      ;;
+	    just_start=1 )
+	      part_md_just_start=yes
+	      ;;
+	    /dev/* )
+	      part_md_list="$part_md_list $(
+	  	for f in /tmp/part.* ; do
+	    	  ( 
+	      	    load_part $f
+		    case $md_device in
+		      "$part_name" | "$part_name":spare )
+	                echo -n "$part_file "
+	            esac
+	          )
+	        done)"
+              ;;
+	  esac
+	done
+	save_part
+	update_md_part_ofs
+      )
+    esac
+    
+    id=$(($id+1))
+  done
+}
+
 save_part () {
-  local suf
-  suf=`echo ${part_device}_${part_minor} | sed -e 's|/|_|g'`
-  cat > /tmp/part.$suf <<EOF
-part_name=$part_name
-part_device=$part_device
-part_minor=$part_minor
-part_start=$part_start
-part_size=$part_size
-part_filesystem=$part_filesystem
-part_format=$part_format
-part_touch=$part_touch
-part_fstab_options=$part_fstab_options
-part_format_options=$part_format_options
-part_mnt_point=$part_mnt_point
+  cat > $part_file <<EOF
+part_file="$part_file"
+part_name="$part_name"
+part_device="$part_device"
+part_minor="$part_minor"
+part_start="$part_start"
+part_size="$part_size"
+part_filesystem="$part_filesystem"
+part_format="$part_format"
+part_touch="$part_touch"
+part_fstab_options="$part_fstab_options"
+part_format_options="$part_format_options"
+part_mnt_point="$part_mnt_point"
+part_md_list="$part_md_list"
+part_md_part_of="$part_md_part_of"
+part_md_level="$part_md_level"
+part_md_parity_algorithm="$part_md_parity_algorithm"
+part_md_chunk_size="$part_md_chunk_size"
+part_md_just_start="$part_md_just_start"
+part_md_persistent_superblock="$part_md_persistent_superblock"
+part_md_spare="$part_md_spare"
 EOF
 }
 
+update_md_part_ofs () {
+  local we_are
+  if [ "$part_device" = md ] ; then
+    we_are=$part_file
+    for f in /tmp/part.* ; do
+      (
+        load_part $f
+        if [ "$part_md_part_of" = "$we_are" ] ; then
+	  part_md_part_of=
+	  save_part
+	fi
+      )
+    done
+    for f in $part_md_list ; do
+      (
+        load_part $f
+	part_md_part_of=$we_are
+	save_part
+      )
+    done
+  fi
+}
+
 disk_info () {
   for device in $dest_devices ; do
     parted -s $device print | grep '^Disk geometry' | \
@@ -106,6 +222,12 @@
     end_i=`echo $end | sed -e 's/\..*//'`
     name=$(part $1 $number)
     next_part=$(($number+1))
+    case " $fs $flags " in
+      *" raid "* )
+        fs=md
+	flags=
+	;;
+    esac
     if [ "$number" -ge 3 ] ; then
       new_part_type=logical
       if [ $next_part = 4 ] ; then
@@ -126,6 +248,8 @@
       if [ "$fs" = "linux-swap" ] ; then
         fs=swap
 	part_mnt_point=swap
+      elif [ "$fs" = "md" ] ; then
+        part_mnt_point=md
       elif [ "$type" = extended ] ; then
         fs=extended
       fi
@@ -136,9 +260,21 @@
     part_size=$(($end_i-$start_i))
     part_start=$start
     save_part 
-    echo "<item id='${1}@${number}'>$(printf "%-10s %10.3f %5dMb %-20s : %s" \
-    	$name $start $(($end_i-$start_i)) \
-	"$part_mnt_point ($part_filesystem)" "$flags")"
+    echo -n "<item id='${1}@${number}'>"
+    printf "%-10s %10.3f %5dMb %-20s : %s" $name $start $(($end_i-$start_i)) \
+	"$part_mnt_point ($part_filesystem)" "$flags"
+  done
+
+}
+
+raid_items () {
+  for f in /tmp/part.md* ; do
+    if test -f $f ; then
+      load_part $f
+      echo -n "<item id='md@${part_minor}'>"
+      printf "%-10s %10s %7s %-20s : %s" "/dev/md${part_minor}" "" "" \
+			"$part_mnt_point ($part_filesystem)" ""
+    fi
   done
 }
 
@@ -158,6 +294,7 @@
     <br><button>
 EOF
   fi
+  log info "res = $res"
 
   return $res
 }
@@ -165,7 +302,22 @@
 remove () {
   if yes_no no "$(nls "Ary you sure to remove %s?" "$part_name")" ; then
     show_result parted -s $part_device rm $part_minor
-    rm -f /tmp/part.`echo ${part_device}_${part_minor} | sed -e 's|/|_|g'`
+    part_md_list= update_md_part_ofs
+    if test -n "$part_md_part_of" ; then
+      file=$part_file
+      (
+        load_part $part_md_part_of
+	all=
+	for f in $part_md_list ; do
+	  if [ "$f" != "$file" ] ; then
+	    all="$all $f"
+	  fi
+	done
+	part_md_list="$all"
+	save_part
+      )
+    fi
+    rm -f $part_file
   fi
 }
 
@@ -182,6 +334,111 @@
   fi
 }
 
+check_box () {
+  local val id
+  id=$1
+  eval val=\$$1
+  shift
+  case "$val" in
+  yes )
+    echo -n "<check checked=1 id=$id $*>"
+    ;;
+  * )
+    echo -n "<check checked=0 id=$id $*>"
+    ;;
+  esac
+}
+
+input_box () {
+  local val id
+  id=$1
+  eval val=\$$1
+  shift
+  echo -n "<input id=$id caption='$val' $*>"
+}
+
+raid_help () {
+  dial <<EOF
+<text width=70 height=17>
+$(nls "Linear RAID simply concatenates devices. They are filled ")
+$(nls "sequentially. Read performance might increase compared to")
+$(nls "single drive.")
+<br><br>
+$(nls "RAID level 0 is like linear except writes are done in parallel,")
+$(nls "so all devices are filled to the same size. Devices doesn't have ")
+$(nls "to be of the same size, but should be. It is fastest software RAID,")
+$(nls "read/write speed is roughly number-of-devices times better then")
+$(nls "single drive.")
+<br><br>
+$(nls "RAID 1 is mirroring, devices need to be the same size.")
+<br><br>
+$(nls "RAID 4 is much like RAID 5 except is uses just one disk for parity")
+$(nls "information, making it bottleneck.")
+<br><br>
+$(nls "RAID 5 can be used on 3 or more devices of the same size. If one of")
+$(nls "them burns -- it repairs itself, if two burn -- your users will burn")
+$(nls "you :) Performance will increase compared to single drive.")
+<br><br>
+$(nls "Chunk size is expressed in kilobytes. 'auto' should work reasonably.")
+<br><br>
+$(nls "Spare devices is whitespace separated list of devices, that will be used")
+$(nls "as replacement when one of working disks burn. It is supported only")
+$(nls "by RAID levels 1, 4 and 5.")
+<br><br>
+$(nls "Persistent super-block is a special block, which is written in the ")
+$(nls "beginning of all disks participating in the array. It is used during")
+$(nls "machine boot, better leave it with 'yes'.")
+<br><br>
+$(nls "Check 'Just start, no mkraid' if you want to use existing RAID array.")
+<br><br>
+$(nls "Also don't bother changing parity-algorithm if you are not sure")
+$(nls "what it does.")
+</text>
+<button>
+EOF
+}
+
+raid_stuff () {
+  current_md=$part_file
+  
+  nls "Partitions contained in this RAID array:"
+  echo "<menu id=part_md_list checked='$part_md_list'>"
+  for f in /tmp/part.* ; do
+    (
+      load_part $f
+      case "$part_filesystem:$part_md_part_of" in
+        md: | md:$current_md )
+	  printf "<item checked=0 id=$f>%-20s %6dMB" "$part_name" "$part_size"
+      esac
+    )
+  done
+  echo "</menu><br>"
+
+  cat <<EOF
+<menu hidden=1 id=md_level>
+<item id=raidl>$(nls "Linear RAID")
+<item id=raid0>$(nls "RAID level 0")
+<item id=raid1>$(nls "RAID level 1 (mirroring)")
+<item id=raid4>$(nls "RAID level 4")
+<item id=raid5>$(nls "RAID level 5")
+</menu>
+<menu hidden=1 id=pa>
+<item id=auto>auto
+<item id=left-symmetric>left-symmetric
+<item id=right-symmetric>right-symmetric
+<item id=left-asymmetric>left-asymmetric
+<item id=right-asymmetric>right-asymmetric
+</menu>
+$(check_box part_md_persistent_superblock) $(nls "Persistent superblock.")
+ $(check_box part_md_just_start) $(nls "Just start, no mkraid.")<br>
+$(nls "Chunk size       :") $(input_box part_md_chunk_size)<br>
+$(nls "Spare devices    :") $(input_box part_md_spare)<br>
+$(nls "RAID level       :") $(input_box part_md_level menu=md_level)<br>
+$(nls "Parity algorithm :") $(input_box part_md_parity_algorithm menu=pa)<br>
+EOF
+
+}
+
 actions () {
   device=$(echo $part_id | sed -e 's/@.*//')
   part_no=$(echo $part_id | sed -e 's/.*@//')
@@ -197,12 +454,6 @@
  <button res=3 caption="$(nls "_Remove")"> 
 EOF
   else
-    if [ "$part_format" = yes ] ; then
-      part_format=1
-    fi
-    if [ "$part_touch" = yes ] ; then
-      part_touch=1
-    fi
     dial <<EOF
 <meta title="$part_name">
 $(filesystems_menu hidden)
@@ -210,26 +461,53 @@
 $(nls "Filesystem    :") <input id=part_filesystem menu=fs caption="$part_filesystem"><br>
 $(nls "fstab options :") <input id=part_fstab_options caption="$part_fstab_options"><br>
 $(nls "mkfs options  :") <input id=part_format_options caption="$part_format_options"><br>
-<check checked=$part_format id=part_format> $(nls "Create a filesystem on this partition.")<br>
-<check checked=$part_touch id=part_touch> $(nls "Mount during installation and add to fstab.")<br>
+$(check_box part_format) $(nls "Create a filesystem on this partition.")<br>
+$(check_box part_touch) $(nls "Mount during installation and add to fstab.")<br>
 <button res=1> 
  <button res=2 caption="$(nls "_Resize")"> 
  <button res=3 caption="$(nls "_Remove")"> 
+$(if [ "$part_device" = md ] ; then
+    echo "<button res=5 caption='$(nls "_RAID options")'>"
+  fi)
  <button res=4 caption="$(nls "_Cancel")">
 EOF
   fi
+
+  while [ "$res" = 5 ] ; do
+      dial <<EOF
+<meta title="$(nls "RAID Options")">
+$(raid_stuff)
+<button res=1> <button res=2 caption="$(nls "_Help")">
+ <button res=4 caption="$(nls "_Cancel")">
+EOF
+    if [ "$res" = 2 ] ; then
+      raid_help
+      res=5
+    fi
+  done
+
+  
   case $res in
     1)
-      if [ "$part_touch" = no -a -n "$part_mnt_point" ] ; then
-        # this sounds a bit stupid now... 
-        info "
+      if [ "$part_touch" = no ] ; then
+        case "$part_mnt_point" in
+	  md | swap | "" )
+	    : ok
+	    ;;
+	  * )
+            # this sounds a bit stupid now... 
+            info "
 $(nls "You have setup mountpoint, but you hasn't told the installer")<br>
 $(nls "to use this partition. Check 'Mount during installation ...'")<br>
 $(nls "to mount it during installation and include it in /etc/fstab.")"
+        esac
       fi
+      update_md_part_ofs
       save_part
       ;;
     2)
+      update_md_part_ofs
+      save_part
       resize
       ;;
     3)
@@ -380,6 +658,10 @@
   if [ "$fs" = md ] ; then
     show_result parted -s $device set $new_part_no raid on || return
   fi
+ 
+  # clear part_* stuff:
+  load_part /dev/null
+  part_file=/tmp/part.$(echo ${device}_$new_part_no | sed -e 's|/|_|g')
   part_filesystem=$fs
   if [ "$mnt" = skip ] ; then
     part_format=no
@@ -452,6 +734,36 @@
   done
 }
 
+encoded_raid_device () {
+  val="/dev/md$part_minor:$part_md_level"
+  for f in $part_md_list ; do
+    dev=$(load_part $f; echo $part_name)
+    spare=
+    if echo " $part_md_spare " | grep -q " $dev " ; then
+      spare=:spare
+    fi
+    val="${val},${dev}${spare}"
+  done
+
+  if [ "$part_md_persistent_superblock" = no ] ; then
+    val="$val,persistent_superblock=0"
+  fi
+
+  if [ "$part_md_just_start" = yes ] ; then
+    val="$val,just_start=1"
+  fi
+
+  if [ "$part_md_parity_algorithm" != auto ] ; then
+    val="$val,parity_algorithm=$part_md_parity_algorithm"
+  fi
+  
+  if [ "$part_md_chunk_size" != auto ] ; then
+    val="$val,chunk_size=$part_md_chunk_size"
+  fi
+
+  echo $val | sed -e 's/ //g'
+}
+
 save_it () {
   load_config
   
@@ -465,10 +777,9 @@
   id=1
   devs=
   actions=
-
   
   for f in /tmp/part.* ; do
-    . $f
+    load_part $f
     if [ "$part_touch" = no ] ; then
       continue
     fi
@@ -476,8 +787,12 @@
       part_filesystem=swap
       part_mnt_point=swap
     fi
-
-    eval "dest_part${id}_device=\"$part_name\""
+   
+    if [ "$part_device" = md ] ; then
+      eval "dest_part${id}_device=\"$(encoded_raid_device)\""
+    else
+      eval "dest_part${id}_device=\"$part_name\""
+    fi
     eval "dest_part${id}_mnt_point=\"$part_mnt_point\""
     eval "dest_part${id}_filesystem=\"$part_filesystem\""
     eval "dest_part${id}_format_partition=\"$part_format\""
@@ -486,12 +801,16 @@
     eval "dest_part${id}_size=\"$part_size\""	# just for reference
     
     log info "saved part #$id, $part_name on $part_mnt_point ($part_size MB, $part_filesystem)"
-    if echo " $devs " | grep -q " $part_device " ; then
-      :
-    else
-      devs="$devs $part_device"
-      actions="$actions use_existing"
+
+    if [ "$part_device" != md ] ; then
+      if echo " $devs " | grep -q " $part_device " ; then
+        :
+      else
+        devs="$devs $part_device"
+        actions="$actions use_existing"
+      fi
     fi
+    
     id=$(($id+1))
   done
 
@@ -501,6 +820,47 @@
   save_config
 }
 
+make_new_md () {
+  try=0
+
+  while [ $try -le 15 ] ; do
+    if test -f /tmp/part.md_$try ; then
+      :
+    else
+      break
+    fi
+    try=$(($try+1))
+  done
+  load_part /dev/null
+
+  part_minor=$try
+  part_file=/tmp/part.md_$part_minor
+  part_device=md
+  part_name=/dev/md$part_minor
+  part_filesystem=ext2
+  part_format=yes
+  part_touch=yes
+  part_fstab_options=defaults
+  part_mnt_point=/
+  part_md_level=raid5
+  part_md_parity_algorithm=auto
+  part_md_chunk_size=auto
+  part_md_just_start=no
+  part_md_persistent_superblock=yes
+  part_md_spare=""
+
+  save_part
+
+  dial <<EOF
+$(nls "New RAID entry for %s created." "$part_name")<br><br>
+$(nls "Press [Enter] on it to set it up. Note that in order")<br>
+$(nls "to add partitions to this array, you first need to")<br>
+$(nls "create some partitions with ,,filesystem'' set to 'md'.")<br>
+             <button>
+EOF
+  
+}
+
 #######
 # Main
 ######
@@ -517,8 +877,8 @@
   exit 1
 fi
 
-case `uname -m` in
-  ppc* )
+case $arch in
+  ppc )
     dial <<EOF
 <meta title="$(nls 'Warning!')">
 <br>
@@ -542,6 +902,7 @@
 part_no=1
 
 rm -f /tmp/part.*
+echo -n > /tmp/need-load-raid
 
 while : ; do
   dial <<EOF
@@ -555,12 +916,19 @@
   for f in $dest_devices ; do
     partition_items $f
   done
+  if test -f /tmp/need-load-raid ; then
+    # need to do that after partition_items has been called
+    load_raid_partitions
+    rm -f /tmp/need-load-raid
+  fi
+  raid_items
 )
 </menu>
 <br>
 <button res=1 caption="$(nls "_Actions")">
- <button res=2 caption="$(nls "_Make new partition")">
- <button res=4 caption="$(nls 'Next _>_>')">
+ <button res=2 caption="$(nls "_Make new partition")"><br>
+<button res=3 caption="$(nls "_Make RAID array")">
+ <button res=4 caption="$(nls '_Leave partitioner')">
 EOF
   case $res in
   1)
@@ -568,6 +936,9 @@
     ;;
   2)
     make_new
+    ;;
+  3)
+    make_new_md
     ;;
   4)
     save_it



Więcej informacji o liście dyskusyjnej pld-installer