2

I have 3 commands I have to run manually to expand my USB filesystem. I am looking for help on automating this in a script that does not need user input at all. I understand you can expand the filesystem using command "raspi-config --expand-rootfs" but I need to combine all these commands into a script.

sudo bash
sed -E 's/mmcblk0p?/sda/' /usr/bin/raspi-config | bash

-- THEN manually expand filesystem --

presish
  • 35
  • 5
  • It is highly inadvisable to perform a global edit on raspi-config and it is far from clear what this would do. See https://raspberrypi.stackexchange.com/a/56623/8697 You can find this file on a fresh image (it is deleted after run) – Milliways Feb 28 '20 at 01:21
  • I boot into a USB Image not SD image. So the command is meant to redirect the filesystem expansion to the USB mounting point. – presish Feb 28 '20 at 01:24
  • @Milliways do you know how to find the full size of the filesystem I can expand to based on Dmitry response below? – presish Mar 04 '20 at 19:43

2 Answers2

3

Rather than adapting raspi-config to your needs, wouldn't it be easier to write your own script to expand the root FS?

parted /dev/sda resizepart 2 XXXX # resize /dev/sda2 to XXXX in MB
parted /dev/sda resizepart 2 100% # or just use all available space
resize2fs /dev/sda2 # resize filesystem

(obviously, you don't need both parted lines in an actual script, choose the one that fits your use case)

Take a look inside raspi-config or here if you need to find out the partition size dynamically.

Dmitry Grigoryev
  • 26,688
  • 4
  • 44
  • 133
  • that's what I ultimately want to do. So the 102400 is the space I need to figure out ? I used the "tune2fs -l /dev/mmcblk0p2" but which parameter is the value I need to fully expand to? – presish Mar 02 '20 at 22:58
  • The suggestion is not working... I have a 32GB USB and noticed when I manually expand the fs /dev/sda2 is the partition that expands. So I ran "parted /dev/sda resizepart 2 32768" and I get an Error that the location is outside the device /dev/sda – presish Mar 04 '20 at 22:30
  • @presish there is one vital step missing! You need to reboot after modifying the partition table. – Milliways Mar 05 '20 at 04:29
  • @Milliways so between 'parted' and 'resize2fs' i need a reboot? How do I determine the correct partition size for my needs? For 32GB I thought it would be 32768 but that doesn't work. – presish Mar 05 '20 at 17:56
  • @Milliways when I run "parted /dev/sda resizepart 2 32768" I get "Error: The location 32768 is outside of the device /dev/sda" – presish Mar 05 '20 at 19:49
  • 1
    First of all, I can't believe I wasted a full day because I was doing `resize2fs /dev/sdX` instead of `/dev/sdX2`.......... Second, it may be worth adding that you can use `parted /dev/sdX resizepart 2 100%` to expand to the full size without needing other commands to determine the size. – php_nub_qq Jul 08 '22 at 19:12
  • @php_nub_qq Thanks for the hint! – Dmitry Grigoryev Jul 18 '22 at 11:18
2

There is no need to "find the full size of the filesystem" - by default fdisk will use all space (and will indeed suggest the size). The only precaution is the need to ensure the correct partition START is selected.

If you REALLY want to use parted you can use a command like

cat /sys/block/mmcblk0/size 

to get the size (you would need to use the appropriate disk identifier).

See https://raspberrypi.stackexchange.com/a/49921/8697 - this is a generic Linux procedure that should work on any MBR disk

This CAN be scripted, but as the link points out "scripting fdisk is far from straightforward and you will probably never need to repeat".

The script I used to resize images - could be adapted, but be warned it takes so long to get it right you would be better to do it manually.

Alternatively you could adapt the script Raspbian uses:-

#!/bin/sh

reboot_pi () {
  umount /boot
  mount / -o remount,ro
  sync
  if [ "$NOOBS" = "1" ]; then
    if [ "$NEW_KERNEL" = "1" ]; then
      reboot -f "$BOOT_PART_NUM"
    else
      echo "$BOOT_PART_NUM" > "/sys/module/${BCM_MODULE}/parameters/reboot_part"
    fi
  fi
  echo b > /proc/sysrq-trigger
  sleep 5
  exit 0
}

check_commands () {
  if ! command -v whiptail > /dev/null; then
      echo "whiptail not found"
      sleep 5
      return 1
  fi
  for COMMAND in grep cut sed parted fdisk findmnt partprobe; do
    if ! command -v $COMMAND > /dev/null; then
      FAIL_REASON="$COMMAND not found"
      return 1
    fi
  done
  return 0
}

check_noobs () {
  if [ "$BOOT_PART_NUM" = "1" ]; then
    NOOBS=0
  else
    NOOBS=1
  fi
}

get_variables () {
  ROOT_PART_DEV=$(findmnt / -o source -n)
  ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
  ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
  ROOT_DEV="/dev/${ROOT_DEV_NAME}"
  ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition")

  BOOT_PART_DEV=$(findmnt /boot -o source -n)
  BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3)
  BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
  BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")

  OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')

  check_noobs

  ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
  TARGET_END=$((ROOT_DEV_SIZE - 1))

  PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')

  LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1)

  ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:")
  ROOT_PART_START=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 2)
  ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3)

  if [ "$NOOBS" = "1" ]; then
    EXT_PART_LINE=$(echo "$PARTITION_TABLE" | grep ":::;" | head -n 1)
    EXT_PART_NUM=$(echo "$EXT_PART_LINE" | cut -d ":" -f 1)
    EXT_PART_START=$(echo "$EXT_PART_LINE" | cut -d ":" -f 2)
    EXT_PART_END=$(echo "$EXT_PART_LINE" | cut -d ":" -f 3)
  fi
}

fix_partuuid() {
  DISKID="$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')"

  sed -i "s/${OLD_DISKID}/${DISKID}/g" /etc/fstab
  sed -i "s/${OLD_DISKID}/${DISKID}/" /boot/cmdline.txt
}

check_variables () {
  if [ "$NOOBS" = "1" ]; then
    if [ "$EXT_PART_NUM" -gt 4 ] || \
       [ "$EXT_PART_START" -gt "$ROOT_PART_START" ] || \
       [ "$EXT_PART_END" -lt "$ROOT_PART_END" ]; then
      FAIL_REASON="Unsupported extended partition"
      return 1
    fi
  fi

  if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then
      FAIL_REASON="Boot and root partitions are on different devices"
      return 1
  fi

  if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then
    FAIL_REASON="Root partition should be last partition"
    return 1
  fi

  if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then
    FAIL_REASON="Root partition runs past the end of device"
    return 1
  fi

  if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then
    FAIL_REASON="Could not determine partitions"
    return 1
  fi
}

check_kernel () {
  local MAJOR=$(uname -r | cut -f1 -d.)
  local MINOR=$(uname -r | cut -f2 -d.)
  if [ "$MAJOR" -eq "4" ] && [ "$MINOR" -lt "9" ]; then
    return 0
  fi
  if [ "$MAJOR" -lt "4" ]; then
    return 0
  fi
  NEW_KERNEL=1
}

main () {
  get_variables

  if ! check_variables; then
    return 1
  fi

  check_kernel

  if [ "$NOOBS" = "1" ] && [ "$NEW_KERNEL" != "1" ]; then
    BCM_MODULE=$(grep -e "^Hardware" /proc/cpuinfo | cut -d ":" -f 2 | tr -d " " | tr '[:upper:]' '[:lower:]')
    if ! modprobe "$BCM_MODULE"; then
      FAIL_REASON="Couldn't load BCM module $BCM_MODULE"
      return 1
    fi
  fi

  if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
    reboot_pi
  fi

  if [ "$NOOBS" = "1" ]; then
    if ! parted -m "$ROOT_DEV" u s resizepart "$EXT_PART_NUM" yes "$TARGET_END"; then
      FAIL_REASON="Extended partition resize failed"
      return 1
    fi
  fi

  if ! parted -m "$ROOT_DEV" u s resizepart "$ROOT_PART_NUM" "$TARGET_END"; then
    FAIL_REASON="Root partition resize failed"
    return 1
  fi

  partprobe "$ROOT_DEV"
  fix_partuuid

  return 0
}

mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmp /run
mkdir -p /run/systemd

mount /boot
mount / -o remount,rw

sed -i 's| init=/usr/lib/raspi-config/init_resize\.sh||' /boot/cmdline.txt
sed -i 's| sdhci\.debug_quirks2=4||' /boot/cmdline.txt

if ! grep -q splash /boot/cmdline.txt; then
  sed -i "s/ quiet//g" /boot/cmdline.txt
fi
sync

echo 1 > /proc/sys/kernel/sysrq

if ! check_commands; then
  reboot_pi
fi

if main; then
  whiptail --infobox "Resized root filesystem. Rebooting in 5 seconds..." 20 60
  sleep 5
else
  sleep 5
  whiptail --msgbox "Could not expand filesystem, please try raspi-config or rc_gui.\n${FAIL_REASON}" 20 60
fi

reboot_pi
Milliways
  • 54,718
  • 26
  • 92
  • 182