Split firstrun and resize2fs scripts

This commit is contained in:
zador-blood-stained 2017-01-16 21:53:36 +03:00
parent 695d821f49
commit ee8d396fa6
6 changed files with 182 additions and 175 deletions

View File

@ -140,10 +140,11 @@ install_common()
install -m 755 $SRC/lib/scripts/resize2fs $CACHEDIR/$SDCARD/etc/init.d/
install -m 755 $SRC/lib/scripts/firstrun $CACHEDIR/$SDCARD/etc/init.d/
install -m 644 $SRC/lib/scripts/resize2fs.service $CACHEDIR/$SDCARD/etc/systemd/system/
install -m 644 $SRC/lib/scripts/firstrun.service $CACHEDIR/$SDCARD/etc/systemd/system/
# enable firstrun script
chroot $CACHEDIR/$SDCARD /bin/bash -c "systemctl --no-reload enable firstrun.service >/dev/null 2>&1"
chroot $CACHEDIR/$SDCARD /bin/bash -c "systemctl --no-reload enable firstrun.service resize2fs.service >/dev/null 2>&1"
# enable verbose kernel messages on first boot
touch $CACHEDIR/$SDCARD/boot/.verbose

View File

@ -12,12 +12,6 @@
# starting at first time.
### END INIT INFO
# Immediately exit if not called by init system
if [[ $1 != start ]]; then
echo "Usage: $0 start" >&2
exit 0
fi
. /etc/armbian-release
. /etc/os-release
. /lib/init/vars.sh
@ -26,146 +20,6 @@ fi
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Log=/var/log/armhwinfo.log
# create helper script to set swap settings
cat <<-'EOF' > /tmp/create_swap.sh
#!/bin/bash
Log=/var/log/armhwinfo.log
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# update console info
setupcon --save
# SSH Keys creation
rm -f /etc/ssh/ssh_host*
read entropy_before </proc/sys/kernel/random/entropy_avail
dpkg-reconfigure openssh-server >/dev/null 2>&1
read entropy_after </proc/sys/kernel/random/entropy_avail
echo -e "### [firstrun] Recreated SSH keys (entropy: ${entropy_before} ${entropy_after})" >>${Log}
MEMTOTAL=$(( $(awk -F" " '/^MemTotal/ {print $2}' </proc/meminfo) / 1024 ))
FREESIZE=$(df -hm / | awk '/\// {print $(NF-2)}')
SWAPFILE=/var/swap
if [[ ! -f $SWAPFILE && $FREESIZE -gt 132 ]]; then
fallocate -l 128M $SWAPFILE || dd if=/dev/zero of=$SWAPFILE bs=1M count=128 status=noxfer
chown root:root $SWAPFILE
chmod 0600 $SWAPFILE
mkswap $SWAPFILE >/dev/null
swapon $SWAPFILE >/dev/null
grep -q swap /etc/fstab || echo "$SWAPFILE none swap sw 0 0" >> /etc/fstab
grep -q swap /etc/sysctl.conf || echo "vm.swappiness=0" >> /etc/sysctl.conf
echo -e "\n### [firstrun] Created 128MB emergency swap as $SWAPFILE" >>${Log}
fi
while [[ -f /tmp/firstrun_running ]]; do sleep 1; done
rm -f /tmp/create_swap.sh
sync &
EOF
chmod +x /tmp/create_swap.sh
do_expand_rootfs() {
local rootpart=$(findmnt -n -o SOURCE /) # i.e. /dev/mmcblk0p1
local rootdevice=$(lsblk -n -o PKNAME $rootpart) # i.e. mmcblk0
local rootdevicepath="/dev/$rootdevice" # i.e. /dev/mmcblk0
# get count of partitions and their boundaries
local partitions=$(( $(grep -c $rootdevice /proc/partitions) - 1 ))
local partstart=$(parted $rootdevicepath unit s print -sm | tail -1 | cut -d: -f2 | sed 's/s//') # start of first partition
local partend=$(parted $rootdevicepath unit s print -sm | head -3 | tail -1 | cut -d: -f3 | sed 's/s//') # end of first partition
local startfrom=$(( $partend + 1 ))
[[ $partitions == 1 ]] && startfrom=$partstart
echo "rootpart: $rootpart" >> $Log
echo "rootdevice: $rootdevice" >> $Log
echo "rootdevicepath: $rootdevicepath" >> $Log
echo "partitions: $partitions" >> $Log
# check whether a resizing rule is defined. We will take this value if it's not too low. In
# this case the value will be ignored and resizing to the whole card size happens.
if [[ -f /root/.rootfs_resize ]]; then
read RESIZE_VALUE <"/root/.rootfs_resize"
ResizeLog="Resize rule $RESIZE_VALUE defined for root partition"
case $RESIZE_VALUE in
*%)
# percentage value, we try to use 16MiB to align partitions since this is
# the erase block size of more recent SD cards (512 byte sectors, so we use 32
# as divider and substract 1)
local percentage=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * $percentage / 3200))}") - 1 ))
[[ $lastsector -lt $partend ]] && unset lastsector
;;
*s)
# sector value, we use it directly
local lastsector=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
[[ $lastsector -lt $partend ]] && unset lastsector
;;
esac
else
# Unattended mode. We run a q&d benchmark to be able to identify cards way too slow easily
echo -e "\n### quick iozone test:$(cd /root; iozone -e -I -a -s 1M -r 4k -i 0 -i 1 -i 2 | grep '^ 1024' | sed 's/ 1024 //')" >> $Log
# check device capacity. If 4GB or below do not use whole card but leave a 5% spare area
# to help older cards with wear leveling and garbage collection. In case this reduced card
# capacity is less than the actual image capacity this is a clear sign that someone wants
# to use Armbian on a card of inappropriate size so he gets what he deserves (at least he
# should know what he's doing)
local capacity=$(( $(lsblk -n -b -d -o SIZE $rootdevicepath) / 1024 / 1024 / 1024 )) # GiB
if [[ $capacity -lt 5 ]]; then # 4 GiB or less
local sparearea=200
local lastsector=$(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{print \$2 - ($sparearea * 1024 * ( 1024 / \$4 ))}")
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="4GB media so leaving 200MB spare area"
fi
elif [[ $CAPACITY -lt 9 ]]; then # 8 GiB or less
# Leave 2 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 98 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="8GB media so leaving 2 percent spare area"
fi
else
# Leave 1 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="Leaving 1 percent spare area"
fi
fi
fi
# Start resizing
echo -e "\n### [firstrun] ${ResizeLog}. Start resizing Partition now:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nExecuting fdisk, fsck and partprobe:" >>${Log}
UtilLinuxVersion=$(echo q | fdisk $rootdevicepath | awk -F"util-linux " '/ fdisk / {print $2}')
if [[ $partitions == 1 ]]; then
case ${UtilLinuxVersion} in
2.27.1*)
# if dealing with fdisk from util-linux 2.27.1 we need a workaround for just 1 partition
# https://github.com/igorpecovnik/lib/issues/353#issuecomment-224728506
((echo d; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1 || true
;;
*)
((echo d; echo $partitions; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1 || true
;;
esac
else
((echo d; echo $partitions; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1 || true
fi
s=0
fsck $root_partition >>${Log} 2>&1 || true
partprobe $rootdevicepath >>${Log} 2>&1 || s=$?
echo -e "\nNew partition table:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nNow executing resize2fs to enlarge rootfs to the maximum:\n" >>${Log}
resize2fs $rootpart >>${Log} 2>&1 || true
# check whether reboot is necessary for resize2fs to take effect
local freesize=$(df -hm / | awk '/\// {print $(NF-2)}')
if [[ $s != 0 || $freesize -lt 152 ]]; then
touch /var/run/reboot
update-rc.d resize2fs defaults >/dev/null 2>&1
echo -e "\n### [firstrun] Automated reboot needed to let /etc/init.d/resize2fs do the job" >>${Log}
fi
} # do_expand_rootfs
do_firstrun_automated_user_configuration()
{
#-----------------------------------------------------------------------------
@ -310,12 +164,11 @@ do_firstrun_automated_user_configuration()
fi
} #do_firstrun_automated_user_configuration
main() {
touch /tmp/firstrun_running
case "$1" in
start)
if [[ $(findmnt -n -o FSTYPE /) == ext4 && ! -f /root/.no_rootfs_resize ]]; then
do_expand_rootfs
fi
# Run a q&d benchmark to be able to identify cards way too slow easily
echo -e "\n### quick iozone test:$(cd /root; iozone -e -I -a -s 1M -r 4k -i 0 -i 1 -i 2 | grep '^ 1024' | sed 's/ 1024 //')" >> $Log
# tweaks
# enable BT on cubietruck
@ -325,9 +178,29 @@ main() {
# enable BT on Solidrun i.MX boards
[[ "$BOARD" == "Cubox i2eX/i4" ]] && update-rc.d brcm4330-patch defaults && /etc/init.d/brcm4330-patch start
do_firstrun_automated_user_configuration &
do_firstrun_automated_user_configuration
/tmp/create_swap.sh &
# update console info
setupcon --save
# SSH Keys creation
rm -f /etc/ssh/ssh_host*
read entropy_before </proc/sys/kernel/random/entropy_avail
dpkg-reconfigure openssh-server >/dev/null 2>&1
service sshd restart
read entropy_after </proc/sys/kernel/random/entropy_avail
echo -e "### [firstrun] Recreated SSH keys (entropy: ${entropy_before} ${entropy_after})" >>${Log}
FREESIZE=$(( $(findmnt --target / -n -o AVAIL -b) / 1048576 )) # MiB
SWAPFILE=/var/swap
if [[ ! -f $SWAPFILE && $FREESIZE -gt 132 ]]; then
fallocate -l 128M $SWAPFILE || dd if=/dev/zero of=$SWAPFILE bs=1M count=128 status=noxfer
chown root:root $SWAPFILE
chmod 0600 $SWAPFILE
mkswap $SWAPFILE
swapon $SWAPFILE
grep -q swap /etc/fstab || echo "$SWAPFILE none swap sw 0 0" >> /etc/fstab
grep -q swap /etc/sysctl.conf || echo "vm.swappiness=0" >> /etc/sysctl.conf
echo -e "\n### [firstrun] Created 128MB emergency swap as $SWAPFILE" >>${Log}
fi
# some hardware workarounds
case $LINUXFAMILY in
@ -366,8 +239,12 @@ main() {
;;
esac
update-rc.d -f firstrun remove >/dev/null 2>&1
rm /tmp/firstrun_running
} # main
systemctl disable firstrun
exit 0
;;
main
*)
echo "Usage: $0 start"
exit 0
;;
esac

View File

@ -1,13 +1,11 @@
[Unit]
Description=Armbian first run tasks
After=local-fs.target network.target
Before=getty.target system-getty.slice
DefaultDependencies=no
[Service]
Type=oneshot
Type=simple
RemainAfterExit=yes
ExecStart=/etc/init.d/firstrun start
ExecStart=/bin/bash /etc/init.d/firstrun start
[Install]
WantedBy=basic.target
WantedBy=multi-user.target

View File

@ -7,21 +7,138 @@
# Should-Start:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Resize the root filesystem to fill whole rootfs partition
# Description:
# Short-Description: Resize the root filesystem
# Description: Resize the root filesystem to fill the whole storage
### END INIT INFO
. /lib/init/vars.sh
. /lib/lsb/init-functions
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Log=/var/log/armhwinfo.log
do_expand_partition()
{
local rootpart=$(findmnt -n -o SOURCE /) # i.e. /dev/mmcblk0p1
local rootdevice=$(lsblk -n -o PKNAME $rootpart) # i.e. mmcblk0
local rootdevicepath="/dev/$rootdevice" # i.e. /dev/mmcblk0
# get count of partitions and their boundaries
local partitions=$(( $(grep -c $rootdevice /proc/partitions) - 1 ))
local partstart=$(parted $rootdevicepath unit s print -sm | tail -1 | cut -d: -f2 | sed 's/s//') # start of first partition
local partend=$(parted $rootdevicepath unit s print -sm | head -3 | tail -1 | cut -d: -f3 | sed 's/s//') # end of first partition
local startfrom=$(( $partend + 1 ))
[[ $partitions == 1 ]] && startfrom=$partstart
# check whether a resizing rule is defined. We will take this value if it's not too low. In
# this case the value will be ignored and resizing to the whole card size happens.
if [[ -f /root/.rootfs_resize ]]; then
read RESIZE_VALUE </root/.rootfs_resize
ResizeLog="Resize rule $RESIZE_VALUE defined for root partition"
case $RESIZE_VALUE in
*%)
# percentage value, we try to use 16MiB to align partitions since this is
# the erase block size of more recent SD cards (512 byte sectors, so we use 32
# as divider and substract 1)
local percentage=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * $percentage / 3200))}") - 1 ))
[[ $lastsector -lt $partend ]] && unset lastsector
;;
*s)
# sector value, we use it directly
local lastsector=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
[[ $lastsector -lt $partend ]] && unset lastsector
;;
esac
else
# check device capacity. If 4GB or below do not use whole card but leave a 5% spare area
# to help older cards with wear leveling and garbage collection. In case this reduced card
# capacity is less than the actual image capacity this is a clear sign that someone wants
# to use Armbian on a card of inappropriate size so he gets what he deserves (at least he
# should know what he's doing)
local capacity=$(( $(lsblk -n -b -d -o SIZE $rootdevicepath) / 1024 / 1024 / 1024 )) # GiB
if [[ $capacity -lt 5 ]]; then # 4 GiB or less
local lastsector=$(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{print \$2 - (200 * 1024 * ( 1024 / \$4 ))}")
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="4GB media so leaving 200MB spare area"
fi
elif [[ $CAPACITY -lt 9 ]]; then # 8 GiB or less
# Leave 2 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 98 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="8GB media so leaving 2 percent spare area"
fi
else
# Leave 1 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="Leaving 1 percent spare area"
fi
fi
fi
# Start resizing
echo -e "\n### [firstrun] ${ResizeLog}. Start resizing Partition now:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nExecuting fdisk, fsck and partprobe:" >>${Log}
local fdisk_version=$(fdisk --version | awk '{print $NF}' | grep -oE "^[[:digit:]].[[:digit:]]+")
if [[ $partitions == 1 ]] && awk "BEGIN{exit ! ($fdisk_version >= 2.27 )}"; then
# if dealing with fdisk from util-linux 2.27+ we need a workaround for just 1 partition
# though it does not break anything - just prevents an "unexpected command" to fdisk
# https://github.com/igorpecovnik/lib/issues/353#issuecomment-224728506
((echo d; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1
else
((echo d; echo $partitions; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1
fi
local s=0
partprobe $rootdevicepath >>${Log} 2>&1 || s=$?
echo -e "\nNew partition table:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nNow executing resize2fs to enlarge rootfs to the maximum:\n" >>${Log}
resize2fs $rootpart >>${Log} 2>&1
# check whether reboot is necessary for resize2fs to take effect
local freesize=$(( $(findmnt --target / -n -o AVAIL -b) / 1048576 )) # MiB
if [[ $s != 0 || $freesize -lt 512 ]]; then
touch /var/run/resize2fs-reboot
echo -e "\n### [firstrun] Automated reboot needed to finish the resize procedure" >>${Log}
fi
}
do_expand_filesystem()
{
local rootpart=$(findmnt -n -o SOURCE /) # i.e. /dev/mmcblk0p1
echo -e "\n### [resize2fs] Start resizing partition now\n" >> ${Log}
resize2fs $rootpart >> ${Log} 2>&1
}
case "$1" in
start)
local rootpart=$(findmnt -n -o SOURCE /) # i.e. /dev/mmcblk0p1
# skip resizing if rootfs is not ext4 or if explicitly disabled
if [[ $(findmnt -n -o FSTYPE /) != ext4 || -f /root/.no_rootfs_resize ]]; then
systemctl disable resize2fs
exit 0
fi
# if ext4 and rootfs should be resized then do it
if [[ $(findmnt -n -o FSTYPE /) == ext4 && ! -f /root/.no_rootfs_resize ]]; then
echo -e "\n### [resize2fs] Start resizing partition now\n" >>/var/log/armhwinfo.log
/sbin/resize2fs $rootpart >>/var/log/armhwinfo.log 2>&1
fi
# first stage - resize the partition
[[ ! -f /var/lib/armbian/resize_second_stage ]] && do_expand_partition
# disable further executions of this script
update-rc.d -f resize2fs remove >/dev/null 2>&1
;;
# second stage - resize the filesystem
[[ ! -f /var/run/resize2fs-reboot ]] && do_expand_filesystem
# disable itself
[[ ! -f /var/run/resize2fs-reboot ]] && systemctl disable resize2fs
exit 0
;;
*)
echo "Usage: $0 start"
exit 0
;;
esac

14
scripts/resize2fs.service Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=Armbian filesystem resize service
Before=basic.target
After=sysinit.target local-fs.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash /etc/init.d/resize2fs start
TimeoutStartSec=5min
[Install]
WantedBy=basic.target

View File

@ -1,6 +1,6 @@
#!/bin/bash
if [[ -f /var/run/reboot ]]; then
if [[ -f /var/run/resize2fs-reboot ]]; then
printf "\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
printf "\e[0;91mPlease reboot the system as soon as possible \x1B[0m \n\n"
(sleep 1 && rm "$0") &