From ee8d396fa639cd89e08fdd6646c32308f3b25f4f Mon Sep 17 00:00:00 2001 From: zador-blood-stained Date: Mon, 16 Jan 2017 21:53:36 +0300 Subject: [PATCH] Split firstrun and resize2fs scripts --- distributions.sh | 3 +- scripts/firstrun | 191 ++++------------------- scripts/firstrun.service | 8 +- scripts/resize2fs | 139 +++++++++++++++-- scripts/resize2fs.service | 14 ++ scripts/update-motd.d/98-autoreboot-warn | 2 +- 6 files changed, 182 insertions(+), 175 deletions(-) create mode 100644 scripts/resize2fs.service diff --git a/distributions.sh b/distributions.sh index 21334158b2..94cc26c09e 100644 --- a/distributions.sh +++ b/distributions.sh @@ -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 diff --git a/scripts/firstrun b/scripts/firstrun index c6c20cacb0..0fd569550a 100644 --- a/scripts/firstrun +++ b/scripts/firstrun @@ -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 /dev/null 2>&1 - read entropy_after >${Log} - MEMTOTAL=$(( $(awk -F" " '/^MemTotal/ {print $2}' /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 /dev/null 2>&1 + service sshd restart + read 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 diff --git a/scripts/firstrun.service b/scripts/firstrun.service index 39a44b861a..2446c8042f 100644 --- a/scripts/firstrun.service +++ b/scripts/firstrun.service @@ -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 diff --git a/scripts/resize2fs b/scripts/resize2fs index e677d16cbe..fb53d3a4bf 100644 --- a/scripts/resize2fs +++ b/scripts/resize2fs @@ -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 >${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 diff --git a/scripts/resize2fs.service b/scripts/resize2fs.service new file mode 100644 index 0000000000..4b0ed50508 --- /dev/null +++ b/scripts/resize2fs.service @@ -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 diff --git a/scripts/update-motd.d/98-autoreboot-warn b/scripts/update-motd.d/98-autoreboot-warn index 15ffa5ab7d..826c1ecfbb 100644 --- a/scripts/update-motd.d/98-autoreboot-warn +++ b/scripts/update-motd.d/98-autoreboot-warn @@ -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") &