pax_global_header00006660000000000000000000000064116336523720014522gustar00rootroot0000000000000052 comment=b4513075d4f03f1c244c3b0f321fe600e7cf30da firsttime-extend-home-0.0.1/000075500000000000000000000000001163365237200157375ustar00rootroot00000000000000firsttime-extend-home-0.0.1/.gear-rules000064400000000000000000000000071163365237200200030ustar00rootroot00000000000000tar: . firsttime-extend-home-0.0.1/extend-home.sh000075500000000000000000000223061163365237200205160ustar00rootroot00000000000000#!/bin/sh -fu # This file is covered by the GNU General Public License, # which should be included with libshell as the file LICENSE. # All copyright information are listed in the COPYING. # Copyright (C) 2011 Andrew V. Stepanov # Runs only once, at first boot, after installation. # Purpose: extend home partition, using all available free space on USB-media. # Work condition: # home device is mounted. # home device is EXT{2,3,4} file system. # home & root is partions at same USB media. # Boot USB media has only two partions: root & home. # The string representation of the UUID should be based on lower case characters. # # Print messages in English. # export LC_ALL=C WITHOUT_RC_COMPAT=1 . /etc/init.d/functions # # Use libshell # SourceIfExists "/bin/shell-error" SourceIfExists "/bin/shell-quote" # # Use verbose mode in libshell. # verbose=1 # # Known variables. # COMMANDS="blkid udevadm mountpoint parted e2fsck resize2fs e2label df" PROC_CMDLINE="/proc/cmdline" CMDLINE= ROOT= BUS= ROOTFS_UUID= ROOTFS_DEV= HOMEFS_UUID= HOMEFS_DEV= ROOTFS_DEV_SLAVE= DEV_SLAVE= HOMEFS_DIR="/home" HOMEFS_LABEL="rosshome" HOMEFS_SIZE_OLD= HOMEFS_SIZE_NEW= ROOTFS_PARTITION_NUMBER= ROOTFS_PARTITION_NUMBER_REQUIRED=1 HOMEFS_PARTITION_NUMBER= HOMEFS_PARTITION_NUMBER_REQUIRED=2 msg_done() { action "$PROG: $@" true } msg_fatal() { action "$PROG: $@" false exit 1 } # # Entry point. # # # Turn off bootsplash (plymouth) # PLYMOUTH="/etc/init.d/plymouth" if [ -x "$PLYMOUTH" ]; then # start - actually means stop. "$PLYMOUTH" start || true fi msg_done "Start extend partition ($HOMEFS_DIR)" # # Check for all commands available. # for cmd in $COMMANDS; do if ! which "$cmd" >/dev/null 2>&1; then msg_fatal "Check $cmd is available" fi done msg_done "Check necessary commands are available" # # Check HOMEFS_DIR is mounted. # if ! mountpoint -q "$HOMEFS_DIR"; then msg_fatal "Check $HOMEFS_DIR is mountpoint" fi msg_done "Check $HOMEFS_DIR is mountpoint" # # Check for PROC_CMDLINE file is accessible. # if ! [ -f "$PROC_CMDLINE" -a -r "$PROC_CMDLINE" ]; then msg_fatal "Check $PROC_CMDLINE is accessible" fi msg_done "Check $PROC_CMDLINE is accessible" # # Read PROC_CMDLINE contents. # CMDLINE="$(head -n 1 "$PROC_CMDLINE")" if [ -z "$CMDLINE" ]; then msg_fatal "Read $PROC_CMDLINE ($CMDLINE)" fi msg_done "Read $PROC_CMDLINE ($CMDLINE)" # # Root filesystem location for kernel. # ROOT="$(echo "$CMDLINE" | sed -n -e '/root=./s/^.*root=\([^[:space:]]\+\).*$/\1/p')" msg_done "Lookup root= option in $PROC_CMDLINE ($ROOT)" if [ "$ROOT" != "${ROOT##UUID=}" ]; then # root= supplied with UUID= ROOTFS_UUID="${ROOT##UUID=}" ROOTFS_DEV="$(blkid -U "$ROOTFS_UUID")" elif [ "$ROOT" != "${ROOT##/dev/}" ]; then # root= supplied with /dev/ ROOTFS_DEV="${ROOT}" ROOTFS_UUID="$(blkid -s UUID -o value "$ROOTFS_DEV")" else msg_fatal "Rarse $ROOT from $PROC_CMDLINE" fi msg_done "Lookup root FS location ($ROOTFS_DEV)" msg_done "Lookup root FS UUID ($ROOTFS_UUID)" # # Check that ROOTFS_DEV is block device. # if ! [ -b "$ROOTFS_DEV" ]; then msg_fatal "Check $ROOTFS_DEV is block device" fi msg_done "Check $ROOTFS_DEV is block device" # # Check that ROOTFS_DEV is attached via USB. # BUS="$(udevadm info --query=property --name="$ROOTFS_DEV" | sed -n -e '/^ID_BUS=/s/.*=//p')" #XXX: if [ "$BUS" != "usb" ]; then msg_fatal "Check $ROOTFS_DEV located on USB device (BUS == $BUS)" fi msg_done "Check $ROOTFS_DEV located on USB device" # # Find device mounted at HOMEFS_DIR. # HOMEFS_DEV="$(sed -n -e "/[[:space:]]$(quote_sed_regexp "$HOMEFS_DIR")[[:space:]]/ s/[[:space:]].*$//p" "/proc/mounts" 2>/dev/null | head -n 1)" if [ -z "$HOMEFS_DEV" ]; then msg_fatal "Lookup at /proc/mounts device mounted at $HOMEFS_DIR" fi msg_done "Lookup at /proc/mounts device mounted at $HOMEFS_DIR ($HOMEFS_DEV)" HOMEFS_UUID="$(blkid -s UUID -o value "$HOMEFS_DEV")" msg_done "Lookup file system UUID at $HOMEFS_DEV ($HOMEFS_UUID)" # # Find parent device that holds ROOTFS_DEV. # ROOTFS_DEV_SLAVE="$(udevadm info --query=property --name="$ROOTFS_DEV" | sed -n -e "/UDISKS_PARTITION_SLAVE/ s/^.*\///p")" if [ -z "$ROOTFS_DEV_SLAVE" ]; then msg_fatal "Lookup $ROOTFS_DEV parent device" fi msg_done "Lookup $ROOTFS_DEV parent device ($ROOTFS_DEV_SLAVE)" # # Find parent device that holds HOMEFS_DEV. # DEV_SLAVE="$(udevadm info --query=property --name="$HOMEFS_DEV" | sed -n -e "/UDISKS_PARTITION_SLAVE/ s/^.*\///p")" if [ -z "$DEV_SLAVE" ]; then msg_fatal "Lookup $HOMEFS_DEV parent device" fi msg_done "Lookup $HOMEFS_DEV parent device ($DEV_SLAVE)" if [ "$ROOTFS_DEV_SLAVE" != "$DEV_SLAVE" ]; then msg_fatal "$ROOTFS_DEV and $HOMEFS_DEV located on various devices" fi DEV_SLAVE="/dev/$DEV_SLAVE" # # Check that DEV_SLAVE is block device. # if ! [ -b "$DEV_SLAVE" ]; then msg_fatal "Check $DEV_SLAVE is block device" fi msg_done "Check $DEV_SLAVE is block device" # # Get ROOTFS_DEV partition number. # ROOTFS_PARTITION_NUMBER="$(udevadm info --query=property --name="$ROOTFS_DEV" | sed -n -e "/UDISKS_PARTITION_NUMBER/s/^.\+=//p")" if [ -z "$ROOTFS_PARTITION_NUMBER" ]; then msg_fatal "Lookup partition number for $ROOTFS_DEV" fi msg_done "Lookup partition number for $ROOTFS_DEV ($ROOTFS_PARTITION_NUMBER)" if [ $ROOTFS_PARTITION_NUMBER -ne $ROOTFS_PARTITION_NUMBER_REQUIRED ]; then msg_fatal "Check $ROOTFS_DEV has partition number $ROOTFS_PARTITION_NUMBER_REQUIRED" fi msg_done "Check $ROOTFS_DEV has partition number $ROOTFS_PARTITION_NUMBER_REQUIRED" # # Get HOMEFS_DEV partition number. # HOMEFS_PARTITION_NUMBER="$(udevadm info --query=property --name="$HOMEFS_DEV" | sed -n -e "/UDISKS_PARTITION_NUMBER/s/^.\+=//p")" if [ -z "$HOMEFS_PARTITION_NUMBER" ]; then msg_fatal "Lookup partition number for $HOMEFS_DEV" fi msg_done "Lookup partition number for $HOMEFS_DEV ($HOMEFS_PARTITION_NUMBER)" if [ $HOMEFS_PARTITION_NUMBER -ne $HOMEFS_PARTITION_NUMBER_REQUIRED ]; then msg_fatal "Check $HOMEFS_DEV has partition number $HOMEFS_PARTITION_NUMBER_REQUIRED" fi msg_done "Check $HOMEFS_DEV has partition number $HOMEFS_PARTITION_NUMBER_REQUIRED" # # Gather information about current home partition. # HOMEFS_PARTITION_START="$(parted -s "$DEV_SLAVE" unit s print | sed -n -e "/^[[:space:]]*$HOMEFS_PARTITION_NUMBER[[:space:]]/p" | join -a1 -o 1.2 - /dev/null | sed -n -e 's/s//p')" if [ -z "$HOMEFS_PARTITION_START" ]; then msg_fatal "Lookup $HOMEFS_DEV partition start address" fi msg_done "Lookup $HOMEFS_DEV partition start address ($HOMEFS_PARTITION_START)" HOMEFS_PARTITION_END="$(parted -s "$DEV_SLAVE" unit s print | sed -n -e "/^[[:space:]]*$HOMEFS_PARTITION_NUMBER[[:space:]]/p" | join -a1 -o 1.3 - /dev/null | sed -n -e 's/s//p')" if [ -z "$HOMEFS_PARTITION_END" ]; then msg_fatal "Lookup $HOMEFS_DEV partition end address" fi msg_done "Lookup $HOMEFS_DEV partition end address ($HOMEFS_PARTITION_END)" # # Store current FS size. # HOMEFS_SIZE_OLD="$(df -h "$HOMEFS_DIR" | sed -n '2p' | join -a1 -o 1.4 - /dev/null)" # # Umount /home. # if ! umount "$HOMEFS_DIR"; then msg_fatal "Umount $HOMEFS_DIR" fi msg_done "Umount $HOMEFS_DIR" if grep -s -q "$HOMEFS_DEV" "/proc/mounts"; then msg_fatal "Check $HOMEFS_DEV nowhere mounted" fi msg_done "Check $HOMEFS_DEV nowhere mounted" if grep -s -q "$HOMEFS_UUID" "/proc/mounts"; then msg_fatal "Check $HOMEFS_UUID nowhere mounted" fi msg_done "Check $HOMEFS_UUID nowhere mounted" # # Remove current '/home' partition. # if ! parted -s "$DEV_SLAVE" rm "$HOMEFS_PARTITION_NUMBER"; then msg_fatal "Remove partition $HOMEFS_PARTITION_NUMBER" fi msg_done "Remove partition $HOMEFS_PARTITION_NUMBER" # # Locate free space at the end. # FREE_SPACE="$(parted -s "$DEV_SLAVE" unit s print free | sed -n -e '/Free/!d;p' | sed -n -e '$p')" FREE_SPACE_START="$(echo "$FREE_SPACE" | join -a1 -o 1.1 - /dev/null | sed -n -e 's/s//p')" FREE_SPACE_END="$(echo "$FREE_SPACE" | join -a1 -o 1.2 - /dev/null | sed -n -e 's/s//p')" if [ $HOMEFS_PARTITION_START -ne $FREE_SPACE_START ]; then msg_fatal "Check FREE_SPACE start from deleted $HOMEFS_DEV partition" fi if [ $HOMEFS_PARTITION_END -gt $FREE_SPACE_END ]; then msg_fatal "Check FREE_SPACE ended after old /home partition" fi msg_done "Lookup free space (start == $FREE_SPACE_START, end == $FREE_SPACE_END)" # # Make new partions above old /home partition. # if ! parted -s "$DEV_SLAVE" unit s mkpart primary "$FREE_SPACE_START" "$FREE_SPACE_END"; then msg_fatal "Can't create new partition at $DEV_SLAVE" fi msg_done "Create new partition at $DEV_SLAVE" # # Clear FS state. # if ! e2fsck -f -y "$HOMEFS_DEV"; then msg_fatal "Clear FS state at $HOMEFS_DEV" fi msg_done "Clear FS state at $HOMEFS_DEV" # # Grow up FS. # if ! resize2fs "$HOMEFS_DEV"; then msg_fatal "Grow-up FS on $HOMEFS_DEV" fi msg_done "Grow-up FS on $HOMEFS_DEV" if ! e2label "$HOMEFS_DEV" "$HOMEFS_LABEL"; then msg_fatal "Set label on $HOMEFS_DEV to $HOMEFS_LABEL" fi msg_done "Set label on $HOMEFS_DEV to $HOMEFS_LABEL" # # Mount /home partition according to /etc/fstab. # if ! mount "$HOMEFS_DEV"; then msg_fatal "Mount $HOMEFS_DEV" fi msg_done "Mount $HOMEFS_DEV" # # Store new FS size. # HOMEFS_SIZE_NEW="$(df -h "$HOMEFS_DIR" | sed -n '2p' | join -a1 -o 1.4 - /dev/null)" msg_done "Old size = $HOMEFS_SIZE_OLD, new size = $HOMEFS_SIZE_NEW" firsttime-extend-home-0.0.1/firsttime-extend-home.spec000064400000000000000000000011131163365237200230300ustar00rootroot00000000000000Name: firsttime-extend-home Version: 0.0.1 Release: alt1 Summary: Auto extend /home FS. License: GPL Group: System/Configuration/Other Url: http://www.altlinux.org BuildArch: noarch Source: %name-%version.tar %description Auto extend /home FS, using all unused space at the end of USB disk. Runs only once, at first bootup. %prep %setup %build %install mkdir -p %buildroot%_sysconfdir/firsttime.d install -pm755 *.sh %buildroot%_sysconfdir/firsttime.d/ %files %_sysconfdir/firsttime.d/* %changelog * Tue Aug 16 2011 Andriy Stepanov 0.0.1-alt1 - Initial build.