Varlenthegray

Resize EXT4

Jul 19th, 2025
359
0
19 hours
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.31 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. set -euo pipefail
  4.  
  5. # Configuration - MODIFY THESE VALUES FOR YOUR SETUP
  6. DISK="/dev/nvme1n1"
  7. EXT4_PART="${DISK}p1"
  8. ZFS_PART="${DISK}p2"
  9. MOUNTPOINT="/mnt/pve/vm-data"
  10. ZFS_POOL="zfs-vm"
  11. EXT4_RESIZE="864G"
  12. PARTITION_END="872GiB"
  13.  
  14. # Colors for better output readability (because we're fancy like that)
  15. RED='\033[0;31m'
  16. GREEN='\033[0;32m'
  17. YELLOW='\033[1;33m'
  18. BLUE='\033[0;34m'
  19. NC='\033[0m' # No Color
  20.  
  21. abort() {
  22.     echo -e "${RED}❌ ERROR: $1${NC}"
  23.     exit 1
  24. }
  25.  
  26. info() {
  27.     echo -e "${BLUE}ℹ️  INFO: $1${NC}"
  28. }
  29.  
  30. warn() {
  31.     echo -e "${YELLOW}⚠️  WARNING: $1${NC}"
  32. }
  33.  
  34. success() {
  35.     echo -e "${GREEN}✅ SUCCESS: $1${NC}"
  36. }
  37.  
  38. check_cmd() {
  39.     "$@" || abort "Command failed: $*"
  40. }
  41.  
  42. check_mount_absent() {
  43.     mountpoint -q "$1" && abort "$1 is still mounted, aborting."
  44. }
  45.  
  46. check_partition_exists() {
  47.     lsblk -no NAME "$1" | grep -q "$(basename "$2")" || abort "Expected partition $2 not found on $1."
  48. }
  49.  
  50. check_partition_absent() {
  51.     lsblk -no NAME "$1" | grep -q "$(basename "$2")" && abort "Partition $2 already exists on $1."
  52. }
  53.  
  54. # Pre-flight checks (because nobody likes surprises)
  55. info "Starting pre-flight checks..."
  56.  
  57. # Check if running as root
  58. [[ $EUID -eq 0 ]] || abort "This script must be run as root (sudo)"
  59.  
  60. # Check if disk exists
  61. [[ -b "$DISK" ]] || abort "Disk $DISK does not exist or is not a block device"
  62.  
  63. # Check if partition 1 exists
  64. check_partition_exists "$DISK" "$EXT4_PART"
  65.  
  66. # Check if partition 2 doesn't exist yet
  67. check_partition_absent "$DISK" "$ZFS_PART"
  68.  
  69. # Verify current filesystem is ext4
  70. FSTYPE=$(lsblk -no FSTYPE "$EXT4_PART")
  71. [[ "$FSTYPE" == "ext4" ]] || abort "Partition $EXT4_PART is not ext4 (found: $FSTYPE)"
  72.  
  73. # Get disk size and verify it makes sense
  74. DISK_SIZE=$(lsblk -bno SIZE "$DISK")
  75. DISK_SIZE_GB=$((DISK_SIZE / 1024 / 1024 / 1024))
  76. info "Disk size: ${DISK_SIZE_GB}GB"
  77.  
  78. # Verify sizes make sense (rough check)
  79. if [[ $DISK_SIZE_GB -lt 900 ]]; then
  80.     abort "Disk appears too small (${DISK_SIZE_GB}GB) for the configured partition sizes"
  81. fi
  82.  
  83. # Get current filesystem usage
  84. FS_USAGE=$(df -BG "$MOUNTPOINT" | awk 'NR==2 {print $3}' | sed 's/G//')
  85. info "Current filesystem usage: ${FS_USAGE}GB"
  86.  
  87. # Verify we have enough space for the shrink
  88. if [[ $FS_USAGE -gt 850 ]]; then
  89.     abort "Filesystem usage (${FS_USAGE}GB) is too high to shrink to 864GB safely"
  90. fi
  91.  
  92. # Get current partition table
  93. info "Current partition layout:"
  94. lsblk "$DISK"
  95.  
  96. # Final confirmation (because YOLO isn't a backup strategy)
  97. echo
  98. warn "This will:"
  99. warn "  1. Shutdown all VMs"
  100. warn "  2. Unmount $MOUNTPOINT"
  101. warn "  3. Shrink ext4 filesystem to 864GB"
  102. warn "  4. Shrink partition 1 to 872GiB"
  103. warn "  5. Create new ZFS partition from 872GiB to end of disk"
  104. warn "  6. Create ZFS pool '$ZFS_POOL'"
  105. echo
  106. read -p "Are you absolutely sure you want to continue? (type 'YES' to proceed): " confirm
  107.  
  108. if [[ "$confirm" != "YES" ]]; then
  109.     abort "Operation cancelled by user. Smart move! 🧠"
  110. fi
  111.  
  112. # The actual work begins here
  113. success "Pre-flight checks completed. Starting partition resize..."
  114.  
  115. echo
  116. info "Checking if $EXT4_PART is mounted..."
  117. check_mount_absent "$MOUNTPOINT"
  118.  
  119. info "Stopping all running VMs..."
  120. VM_COUNT=$(qm list | awk 'NR>1 {print $1}' | wc -l)
  121. if [[ $VM_COUNT -gt 0 ]]; then
  122.     info "Found $VM_COUNT VMs to shutdown"
  123.     qm list | awk 'NR>1 {print $1}' | xargs -r -n1 qm shutdown
  124.     info "Waiting 30 seconds for VMs to shutdown gracefully..."
  125.     sleep 30
  126.    
  127.     # Force stop any remaining running VMs
  128.     RUNNING_VMS=$(qm list | awk 'NR>1 && $3=="running" {print $1}')
  129.     if [[ -n "$RUNNING_VMS" ]]; then
  130.         warn "Some VMs are still running, forcing stop..."
  131.         echo "$RUNNING_VMS" | xargs -r -n1 qm stop
  132.         sleep 5
  133.     fi
  134. else
  135.     info "No running VMs found"
  136. fi
  137.  
  138. info "Unmounting $EXT4_PART from $MOUNTPOINT..."
  139. check_cmd umount "$MOUNTPOINT"
  140.  
  141. info "Verifying ext4 filesystem on $EXT4_PART..."
  142. check_cmd e2fsck -f "$EXT4_PART"
  143.  
  144. info "Shrinking ext4 filesystem to $EXT4_RESIZE..."
  145. info "This may take several minutes depending on data amount..."
  146. check_cmd resize2fs "$EXT4_PART" "$EXT4_RESIZE"
  147.  
  148. info "Resizing partition 1 to $PARTITION_END..."
  149. check_cmd parted -s "$DISK" unit GiB resizepart 1 "$PARTITION_END"
  150.  
  151. info "Verifying filesystem after partition resize..."
  152. check_cmd e2fsck -f "$EXT4_PART"
  153.  
  154. info "Remounting $EXT4_PART..."
  155. check_cmd mount "$EXT4_PART" "$MOUNTPOINT"
  156.  
  157. info "Creating new ZFS partition after $PARTITION_END..."
  158. check_cmd parted -s "$DISK" -- mkpart primary "$PARTITION_END" 100%
  159.  
  160. info "Waiting for kernel to detect new partition..."
  161. sleep 5
  162. partprobe "$DISK"
  163. udevadm settle
  164. sleep 2
  165.  
  166. check_partition_exists "$DISK" "$ZFS_PART"
  167.  
  168. info "Creating ZFS pool: $ZFS_POOL..."
  169. check_cmd zpool create "$ZFS_POOL" "$ZFS_PART"
  170.  
  171. info "Checking ZFS pool status..."
  172. zpool status "$ZFS_POOL" || abort "ZFS pool creation failed."
  173.  
  174. info "Adding ZFS pool to Proxmox storage config..."
  175. check_cmd pvesm add zfspool "$ZFS_POOL" -pool "$ZFS_POOL"
  176.  
  177. # Final status check
  178. echo
  179. success "All steps completed successfully! 🎉"
  180. echo
  181. info "Final partition layout:"
  182. lsblk "$DISK"
  183. echo
  184. info "ZFS pool status:"
  185. zpool status "$ZFS_POOL"
  186. echo
  187. info "Storage configuration:"
  188. pvesm status
  189.  
  190. success "Your disk surgery was successful! No patients were harmed in the making of this partition. 🏥"
Advertisement
Add Comment
Please, Sign In to add comment