OSDN Git Service

Update partition shrink function
authornatemaia <natemaia10@gmail.com>
Sun, 21 Apr 2019 04:11:56 +0000 (21:11 -0700)
committernatemaia <natemaia10@gmail.com>
Sun, 21 Apr 2019 06:30:24 +0000 (23:30 -0700)
archlabs-installer

index e9038cf..277341b 100755 (executable)
@@ -5,7 +5,7 @@
 # Some ideas and code reworked from other resources
 # AIF, Cnichi, Calamares, Arch Wiki.. Credit where credit is due
 
-VER="2.0.36"     # installer version
+VER="2.0.40"     # installer version
 DIST="ArchLabs"  # linux distributor
 MNT="/mnt"       # install mountpoint
 ANS="/tmp/ans"   # dialog answer file
@@ -717,7 +717,7 @@ part_menu()
                if [[ $DISPLAY && $TERM != 'linux' ]] && hash gparted >/dev/null 2>&1; then
                        dlg choice menu "Edit Partitions" "$_part" \
                                "auto"    "Whole device automatic partitioning" \
-                               "resize"  "Resize an existing ext2/3/4 or ntfs partition" \
+                               "shrink"  "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
                                "gparted" "GUI front end to parted" \
                                "cfdisk"  "Curses based variant of fdisk" \
                                "parted"  "GNU partition editor" \
@@ -726,7 +726,7 @@ part_menu()
                else
                        dlg choice menu "Edit Partitions" "$_part" \
                                "auto"   "Whole device automatic partitioning" \
-                               "resize" "Resize an existing ext2/3/4 or ntfs partition" \
+                               "shrink" "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
                                "cfdisk" "Curses based variant of fdisk" \
                                "parted" "GNU partition editor" \
                                "fdisk"  "Dialog-driven creation and manipulation of partitions" \
@@ -735,8 +735,8 @@ part_menu()
 
                if [[ $choice == 'done' ]]; then
                        return 0
-               elif [[ $choice == 'resize' ]]; then
-                       part_resize "$device"
+               elif [[ $choice == 'shrink' ]]; then
+                       part_shrink "$device"
                elif [[ $choice == 'auto' ]]; then
                        local root_size txt table boot_fs
                        root_size=$(lsblk -lno SIZE "$device" | awk 'NR == 1 {
@@ -906,7 +906,7 @@ part_format()
        sleep "${delay:-0}"
 }
 
-part_resize()
+part_shrink()
 {
        part=""
        typeset -i size num
@@ -921,20 +921,26 @@ part_resize()
                        ext*|ntfs)
                                msg "Resize" "\nGathering device size info.\n" 0
 
-                               # shit hacks to get device size info
+                               # get device size info
                                num="${part: -1}"
-                               end=$(parted -s "$device" print | awk '/^\s*'"$num"'/ {print $3}')
-                               devsize=$(parted -s "$device" print | awk '/Disk '"${device//\//\\/}"':/ {print $3}')
-                               mount "$part" $MNT >/dev/null 2>&1; sleep 0.5
-                               min=$(df "$part" | awk '/'"${part//\//\\/}"'/ {print int($3 / 1024)}') # used
-                               max=$(df "$part" | awk '/'"${part//\//\\/}"'/ {print int($4 / 1024)}') # available
-                               umount $MNT >/dev/null 2>&1
+                               end=$(parted -s "$device" unit KiB print | awk '/^\s*'"$num"'/ {print int($3)}')                    # part size in KiB
+                               devsize=$(parted -s "$device" unit KiB print | awk '/Disk '"${device//\//\\/}"':/ {print int($3)}') # whole device size in KiB
+
+                               # minimum in KiB (2^10)
+                               case "$fs" in
+                                       ext[2-4]) min=$(dumpe2fs -h "$part" |& awk '/Block count/{count=$NF} /Block size/{size=$NF} END{print int((count * size) / 1024)}') ;;
+                                       ntfs) min=$(ntfsresize -f -m "$part" | awk 'NR == 2 {print int(($NF * 1000 * 1000) / 1024)}') ;;
+                               esac
+
+                               # KiB -> MiB
+                               mbmin=$((min / 1024))
+                               mbend=$((end / 1024))
 
                                # get new size from user
                                tput cnorm
-                               if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$min" "$max" $((max / 2)) 2>$ANS; then
-                                       (( (size = $(< "$ANS")) + 1025 <= max )) || return 1
-                                       size=$((( (size * 1024) / 4 ) * 4)) # 4K block alignment
+                               if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$mbmin" "$mbend" $((mbend / 2)) 2>$ANS; then
+                                       (( (size = $(< "$ANS")) < mbend )) || return 1
+                                       size=$((size * 1024))
                                else
                                        return 1
                                fi
@@ -943,28 +949,31 @@ part_resize()
                                case "$fs" in
                                        ext[2-4])
                                                e2fsck -f "$part"; sleep 0.5
-                                               resize2fs -f "$part" ${size}K 2>$ERR
-                                               errshow "resize2fs -f $part ${size}K" { echo 'press enter to continue'; read; return 1; }
+                                               resize2fs -f "$part" ${size}K 2>$ERR # K=2^10 bytes
+                                               errshow "resize2fs -f $part ${size}K" || return 1
+                                               ;;
+                                       ntfs)
+                                               ntfsresize -fc "$part" || { msg "Resize" "\nThe ntfs partition $part cannot be resized because it is scheduled for a consistency check.\n\nTo do a consistency check in windows open command prompt as admin and run:\n\n\tchkdsk /f /r /x\n"; return 1; }
+                                               ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2>$ERR # k=10^3 bytes
+                                               errshow "ntfsresize -f -s $(( (size * 1024) / 1000 ))k $part" || return 1
                                                ;;
-                                       ntfs) ntfsresize -f -s ${size}k "$part" || { echo 'press enter to continue'; read; return 1; } ;;
                                esac
 
+                               echo "filesystem shrunk successfully, now the partition"
                                sleep 0.5
-                               (( size += 1024 ))
-                               parted "$device" resizepart "$num" ${size}Kib || return 1
+                               parted "$device" resizepart "$num" ${size}KiB || return 1
+                               (( size++ ))
                                sleep 0.5
 
-                               if (( ++size < (max * 1024) )); then
-                                       if [[ $devsize == "$end" ]]; then
-                                               parted -s "$device" mkpart primary ext4 ${size}Kib 100% 2>$ERR
-                                       else
-                                               parted -s "$device" mkpart primary ext4 ${size}Kib "$end" 2>$ERR
-                                       fi
-                                       errshow "parted -s $device mkpart primary ext4 ${size}Kib 100%" || return 1
+                               if [[ $devsize == "$end" ]]; then
+                                       parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2>$ERR
+                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB 100%" || return 1
+                               else
+                                       parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2>$ERR
+                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB ${end}KiB" || return 1
                                fi
 
-                               sleep 1
-                               msg "Resize Complete" "\n$part has been successfully resized to $(( (size - 1025) / 1024 ))M.\n"
+                               msg "Resize Complete" "\n$part has been successfully resized to $((size / 1024))M.\n"
                                ;;
                        *) msg "Invalid Filesystem: $fs" "\nResizing only supports ext and ntfs.\n\nFor unformatted partitions, cfdisk can be used.\n" ;;
                esac