Read only filesystem size issues.
Dean Brown
[email protected]
Tue, 12 Dec 2000 22:00:17 -0800
This is a multi-part message in MIME format.
--------------606A77B606D468CCCDA4194C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Adi,
I've attached the portion of the pwl_target_load script that I've
studied in detail with comments starting in the first column. I believe
I noted all the issues that I found. Feel free to question any
assumptions I have made.
Adi Linden wrote:
>
> Hi Dean,
>
> I am just looking at bugfixes for PeeWeeLinux.
>
> > > > 1) When calculating the size of the / filesystem, the /home and /root
> > > > directories are included. These directories are then separated out and
> > > > placed in the second partition. The size of the /home and /root
> > > > directories are not subtracted from the / filesystem. This overestimates
> > > > the size of the / filesystem by the size of the /home and /root
> > > > directories.
>
> I looked at the pwl_target_load script. The filesystem size calculated is
> compared to the total device space available. Since both /root and /home
> are placed on the target device both need to be considered when
> calculating if the extracted system will fit onto the target device.
I agree, though I believe they are being considered twice.
> I did however miss to deduct the sizes of /etc, /var and /dev from the
> root partition. Those three directories are placed in a ramdisk and the
> size of the compressed ramdisk is already taken into consideration when
> calculating the root filesystem sizes.
--
Dean Brown
--------------606A77B606D468CCCDA4194C
Content-Type: text/plain; charset=us-ascii;
name="pwl_target_load_backup"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pwl_target_load_backup"
######################################################################
#
# func_rd_build_ro_root_rd
#
# This function will create a target device with a large root
# partition. The /etc, /dev and /home aprtitions are stored
# in compressed ramdisks.
#
# The /root directory is linked to /home/root. The /tmp and /var
# directories are linked to /dev/var and /dev/var/tmp respectively.
#
# Chain of events:
# ================
#
# 1. Sanity Checks
# a. Check for binaries and files
# b. Make sure we have a flash device
# c. Make sure no flash partition is mounted
# 2. Create initrd
# 3. Calculate
# a. /dev filesystem size
# b. /etc filesystem size
# 4. Create /dev ramdisk
# a. Create loopback device
# b. Mount loop device
# c. Copy files
# d. Unmount loop device
# e. Compress loop device into a ramdisk
# f. Decomission loop device
# 5. Create /etc ramdisk
# Just like the /dev ramdisk
# Except relocate ld.so.cache
# 7. Calculate
# a. Available space
# b. Root partition including kernel, boot.b and ramdisks
# c. Home partition
# d. See if things fit
# 8. Partition target device
# a. /
# b. /home
# c. /mnt/flash
# 9. Create filesystems on target partitions
# 10. Mount partitions
# a. Mount /
# b. Create /dev, /etc, /home and /mnt/flash
# c. Create /tmp and /var symlinks
# d. Mount /home
# e. Mount /mnt/flash
# 11. Copy files except for /dev, /etc, /tmp, /var
# 12. Copy files necessary for booting in /dev, /etc, /var
# 13. Run ldconfig
# 14. Bootloader
# a. copy boot.b
# b. create lilo.conf
# c. run lilo
# 15. Unmount all partitions
# 16. Remove temporary files
func_rd_build_ro_root_rd () {
# sanity check
func_rd_sanity || return 1
# create the linuxrc script that initrd needs
func_rd_action m "Creating linuxrc..."
func_rd_linuxrc_ro_root_rd > $rd_tmp/linuxrc
func_rd_action test
# build the initrd and store temporarily
func_rd_boot_initrd || return 1
# calculate the /dev filesystem size
rd_size_fs_var=`du -s -k --exclude=$rd_kernel $rd_projectroot/var | cut -f 1`
rd_size_fs_dev=`du -s -k --exclude=$rd_kernel $rd_projectroot/dev | cut -f 1`
rd_size_fs_dev=$((rd_size_fs_dev + rd_size_fs_var))
rd_size_fs_dev=$((rd_size_fs_dev + rd_dev_free))
# calculate the /etc filesystem size
rd_size_fs_etc=`du -s -k --exclude=$rd_kernel $rd_projectroot/etc | cut -f 1`
rd_size_fs_etc=$((rd_size_fs_etc + rd_etc_free))
# create the dev ramdisk
# create loopback device
func_rd_make_loopback $rd_size_fs_dev 1024
# mount loop device
func_rd_action m "Mounting loopback device for /dev filesystem..."
mount -t ext2 $rd_loop_dev $rd_mount
func_rd_action test
# remove lost+found
rm -rf $rd_mount/lost+found
# copy files nothing to exclude might as well use cp -a
func_rd_action m "Copying files..."
cp -a $rd_projectroot/dev/* $rd_mount
# remember we need to copy /var here too!
mkdir -p $rd_mount/var
cp -a $rd_projectroot/var/* $rd_mount/var
func_rd_action test
# unmount loop device
func_rd_action m "Unmounting loopback device..."
umount $rd_loop_dev
func_rd_action test
# compress the loop device into a ramdisk
func_rd_action m "Compressing loopback device into ramdisk.dev..."
{ dd if=$rd_loop_dev bs=1k count=$rd_size_fs_dev | gzip -v9 > $rd_tmp/ramdisk.dev } >>$rd_log 2>&1
func_rd_action test
# decomission ramdisk
func_rd_break_loopback
# create the etc ramdisk
# create loopback device
func_rd_make_loopback $rd_size_fs_etc 1024
# mount loop device
func_rd_action m "Mounting loopback device for /etc filesystem..."
mount -t ext2 $rd_loop_dev $rd_mount
func_rd_action test
# remove lost+found
rm -rf $rd_mount/lost+found
# copy files nothing to exclude might as well use cp -a
func_rd_action m "Copying files..."
cp -a $rd_projectroot/etc/* $rd_mount
# relocate the ld.so.cahe to /lib/ld.so.cache
rm -f $rd_mount/etc/ld.so.cache
ln -sf /lib/ld.so.cache $rd_mount/ld.so.cache
func_rd_action test
# add fstab
# make some noise
func_rd_action m "Creating fstab..."
# see if we're allowed to
if [ "$rd_initscripts" = "y" ]; then
# lets do it!
func_rd_fstab_ro_root_rd > $rd_mount/fstab
# send the ok
func_rd_action s
else
# duh we're not configured print a warning
func_rd_action w
fi
# fix inittab
func_rd_fix_inittab
# unmount loop device
func_rd_action m "Unmounting loopback device..."
umount $rd_loop_dev
func_rd_action test
# compress the loop device into a ramdisk
func_rd_action m "Compressing loopback device into ramdisk.etc..."
{ dd if=$rd_loop_dev bs=1k count=$rd_size_fs_etc | gzip -v9 > $rd_tmp/ramdisk.etc } >>$rd_log 2>&1
func_rd_action test
# decomission ramdisk
func_rd_break_loopback
# get flash size
func_rd_action m "Determining space on target device..."
rd_size_avail=`sfdisk -s $rd_target`
# here you calculate the size of the entire filesystem including /home, /root, /dev, and /etc
# calculate the required root fs space
rd_size_fs=`du -s -k $rd_projectroot | cut -f 1`
# these are the compressed images of the /dev and /etc directories
# add the ramdisk sizes
rd_size_fs=$((rd_size_fs + `du -s -k $rd_tmp/ramdisk.dev | cut -f 1`))
rd_size_fs=$((rd_size_fs + `du -s -k $rd_tmp/ramdisk.etc | cut -f 1`))
# add the bootloader
rd_size_fs=$((rd_size_fs + `du -s -k $rd_bootb | cut -f 1`))
# add a few kB for a margin
rd_size_fs=$((rd_size_fs + rd_size_boot_margin))
# this block calculates the size of the /hom and /root directories that are also a part of
# the above calculations.
# calculate the home partition size
rd_size_home=`du -s -k $rd_projectroot/home | cut -f 1`
# add /root
rd_size_home=$((rd_size_home + `du -s -k $rd_projectroot/root | cut -f 1`))
# add the desired free space
rd_size_home=$((rd_size_home + rd_home_free))
##########
#
# Note: sfdisk is screwy when it comes to creating partitions
# based on blocks. Specifying in MB seems to work alright.
#
# The solution... calculate sizes in MB. Since bash truncates
# floating point numbers at we add 1 to round up at all times.
# Except for the available space... we don't want to oversize!
#
# The rd_size_boot_margin is taken off sinze we're rounding
# up anyways. Hopefully there'll be a fix for this soon!
#
rd_size_fs=$((rd_size_fs - rd_size_boot_margin))
# from above
# this is the entire ./projects/<proj_name>/mnt directory
rd_size_fs=$((rd_size_fs / 1024 + 1))
# this is the /home and /root included in the rd_size_fs number above
rd_size_home=$((rd_size_home / 1024 + 1))
# this is the available size of the Compact Flash as reported by sfdisk.
# NOTE that this does not match the actual device size as there appears
# to be space reserved for bad block mapping (I assume)
# The effective result of this is that the value that rd_size_avail contains
# is essentially rounded down to the next lowest MByte.
rd_size_avail=$((rd_size_avail / 1024))
#
##########
# check if things will fit
# also take our /home partition into consideration
# Here is where your calculation double includes the /home and /root directories.
if [ $((rd_size_fs + rd_size_home)) -gt $rd_size_avail ]
then
func_rd_action f
echo " +Available Space: $rd_size_avail"
echo " +Required Space: $((rd_size_fs + rd_size_home))"
return 1
else
func_rd_action s
fi
# partition our target device
func_rd_action m "Partitioning target davice $rd_target..."
# /dev/hda1 will be a ext2 partition
# /dev/hda2 will be a ext2 partition
# /dev/hda3 will be a ext2 partition
# both partitions sized per previous calculations
# /dev/hda3 will be what's left
sfdisk -uM $rd_target >>$rd_log 2>&1 <<-EOF
,${rd_size_fs},83,*
,${rd_size_home},83
,,83
;
EOF
func_rd_action test
# create filesystems
func_rd_action m "Creating ext2 filesystem on ${rd_target}1..."
mke2fs -b 1024 -m0 ${rd_target}1 >>$rd_log 2>&1
func_rd_action test
func_rd_action m "Creating ext2 filesystem on ${rd_target}2..."
mke2fs -b 1024 -m0 ${rd_target}2 >>$rd_log 2>&1
func_rd_action test
func_rd_action m "Creating ext2 filesystem on ${rd_target}3..."
mke2fs -b 1024 -m0 ${rd_target}3 >>$rd_log 2>&1
func_rd_action test
# mount /
func_rd_action m "Mounting root partition ${rd_target}1..."
mount -t ext2 ${rd_target}1 $rd_mount
func_rd_action test
# create mount points for partitions
mkdir -p $rd_mount/home
mkdir -p $rd_mount/mnt/flash
# create mount points for ramdisks
mkdir -p $rd_mount/dev
mkdir -p $rd_mount/etc
# mount remaining partitions
func_rd_action m "Mounting /home partition ${rd_target}2..."
mount -t ext2 ${rd_target}2 $rd_mount/home
func_rd_action test
func_rd_action m "Mounting /mnt/flash partition ${rd_target}3..."
mount -t ext2 ${rd_target}3 $rd_mount/mnt/flash
func_rd_action test
func_rd_action m "Copying files..."
# copy files
for i in $rd_projectroot/*; do
# clear the flag
rd_status=
# you are not copying /root here, but you are copying /home, but by mounting /home
# the space taken by this copy is wasted.
# mark any directories we don't want to copy
for j in dev etc root tmp var; do
if [ `basename $i` = $j ]; then
rd_status=no
fi
done
# copy if we're clear
if [ ! $rd_status ]; then
cp -a $i $rd_mount
fi
done
# copy whatever is in /root to /home/root
cp -a $rd_projectroot/root $rd_mount/home
# create symlinks for our new file locations
ln -sf /dev/var $rd_mount/var
ln -sf /dev/var/tmp $rd_mount/tmp
ln -sf /home/root $rd_mount/root
# copy ramdisk, initrd, boot.b
cp -f $rd_tmp/ramdisk.dev $rd_mount/boot/ramdisk.dev
cp -f $rd_tmp/ramdisk.etc $rd_mount/boot/ramdisk.etc
cp -f $rd_tmp/$rd_initrd $rd_mount/boot/$rd_initrd
cp -f $rd_bootb $rd_mount/boot/boot.b
# create devices required before anything is mounted
cp -a $rd_projectroot/dev/console $rd_mount/dev/console
cp -a $rd_projectroot/dev/systty $rd_mount/dev/systty
cp -a $rd_projectroot/dev/null $rd_mount/dev/null
cp -a $rd_projectroot/dev/ram $rd_mount/dev/ram
cp -a $rd_projectroot/dev/ram0 $rd_mount/dev/ram0
# can this be modified to only copy the devices actually in rd_projectroot/dev?
for i in 1 2 3 4 5 6 7 8 9; do
cp -a $rd_projectroot${rd_boot}${i} ${rd_mount}${rd_boot}${i}
cp -a $rd_projectroot/dev/ram$i ${rd_mount}/dev/ram$i
done
for i in 0 1 2 3 4; do
cp -a $rd_projectroot/dev/tty$i $rd_mount/dev/tty$i
done
# copy our modified inittab to the root directory
cp -f $rd_tmp/inittab $rd_mount/etc/inittab
func_rd_action test
# add rc.init
# make some noise
func_rd_action m "Creating fstab and rc.init..."
# There is no way that I can see to modify this flag in pwl
# see if we're allowed to
if [ "$rd_initscripts" = "y" ]; then
# lets do it!
func_rd_fstab_ro_root_rd > $rd_mount/etc/fstab
func_rd_init_ro_root_rd > $rd_mount/rc.init
# make sure rc.init is executable
chmod 755 $rd_mount/rc.init
# send the ok
func_rd_action s
else
# duh we're not configured print a warning
func_rd_action w
fi
# in the XFree86 package there is a ld.so.conf file that accomplishes the
# the linking of /usr/X11R6/lib. Is there a reason you have it hard coded here as well?
# run library loader and include XFree86 lib directory
# remember it's been relocated to /lib/ld.so.cache
func_rd_action m "Creating ld.so.cache..."
ldconfig -v -C /lib/ld.so.cache -r $rd_mount /usr/X11R6/lib >>$rd_log 2>&1
func_rd_action test
# create lilo.conf
func_rd_action m "Creating lilo.conf..."
# lets amend the ramdisk size and make sure the kernel
# will boot the ramdisk without complaining
rd_bp_map=$rd_mount/boot/map
rd_bp_bootb=$rd_mount/boot/boot.b
rd_bp_kernel=$rd_mount/boot/$rd_kernel
rd_bp_initrd=$rd_mount/boot/$rd_initrd
rd_bp_root=${rd_boot}1
rd_bp_rd=20000
func_rd_boot_lilo > $rd_tmp/lilo.conf
func_rd_action test
# run lilo
func_rd_action m "Installing lilo bootloader..."
lilo -v -C $rd_tmp/lilo.conf >>$rd_log 2>&1
func_rd_action test
# umount partitions
func_rd_action m "Unmounting the /mnt/flash partition ${rd_target}3..."
umount ${rd_target}3
func_rd_action test
func_rd_action m "Unmounting the /home partition ${rd_target}2..."
umount ${rd_target}2
func_rd_action test
func_rd_action m "Unmounting the / partition ${rd_target}1..."
umount ${rd_target}1
func_rd_action test
}
--------------606A77B606D468CCCDA4194C--
---------------------------------------------------
See the list archives at http://adis.on.ca/archives/
See the PWL homepage at http://peeweelinux.com
---------------------------------------------------