Install: read-only USB, resizable sys partitions

USB image:
- have a stateful partition
- use a read-only system partition

Installer:
- copy read-only system partition from USB to hard drive, skip fsck check
- make stateful partition empty

System:
- Change to tolerate empty stateful partition on bootup
- Don't keep so much of /var on stateful partition (var/lib should be in system
image)

Autoupdate:
- Fix a couple checks to allow partitions 3 and 4 to be system partitions
- Fix a misnomer in mk_memento_images.sh

Review URL: http://chromereview.prom.corp.google.com/1175102

git-svn-id: svn://chrome-svn/chromeos/trunk@87 06c00378-0e64-4dae-be16-12b19f9950a1
This commit is contained in:
adlr@google.com 2009-10-26 18:29:06 +00:00
parent 477d139886
commit 9cb9e73b2f
4 changed files with 87 additions and 82 deletions

View File

@ -146,7 +146,7 @@ if [ ! -e /etc/mtab ]; then
sudo touch /etc/mtab
fi
UUID=`uuidgen`
DISK_LABEL=C-$CHROMEOS_VERSION
DISK_LABEL=C-$CHROMEOS_VERSION_STRING
LOOP_DEV=`sudo losetup -f`
sudo losetup "$LOOP_DEV" "$ROOT_FS_IMG"
sudo mkfs.ext3 "$LOOP_DEV"
@ -258,9 +258,9 @@ dd if="$SYSLINUX_MBR" of="$MBR_IMG" bs=512 count=1 conv=sync
# Create a partition table in the MBR.
NUM_SECTORS=$((`stat --format="%s" "$ROOT_FS_IMG"` / 512))
sudo sfdisk -H64 -S32 -uS -f "$MBR_IMG" <<EOF
,$NUM_SECTORS,L,*,
,$NUM_SECTORS,L,-,
,$NUM_SECTORS,S,-,
,$NUM_SECTORS,L,*,
;
EOF

View File

@ -127,6 +127,55 @@ EOF
update-initramfs -u
fi
cat <<EOF > /etc/network/interfaces
auto lo
iface lo inet loopback
EOF
cat <<EOF > /etc/resolv.conf
# Use the connman dns proxy.
nameserver 127.0.0.1
EOF
chmod a-wx /etc/resolv.conf
# Set timezone symlink
rm -f /etc/localtime
ln -s /mnt/stateful_partition/etc/localtime /etc/localtime
# The postinst script is called after an AutoUpdate or USB install.
# the quotes around EOF mean don't evaluate anything inside this HEREDOC.
# TODO(adlr): set this file up in a package rather than here
cat <<"EOF" > /usr/sbin/chromeos-postinst
#!/bin/sh
set -e
# update /boot/extlinux.conf
INSTALL_ROOT=`dirname "$0"`
INSTALL_DEV="$1"
STATEFUL_PARTITION=$(echo "$INSTALL_DEV" | tr 1234 4411)
# set default label to chromeos-hd
sed -i 's/^DEFAULT .*/DEFAULT chromeos-hd/' "$INSTALL_ROOT"/boot/extlinux.conf
sed -i "{ s:HDROOT:$INSTALL_DEV: }" "$INSTALL_ROOT"/boot/extlinux.conf
# update /etc/fstab
sed -i "s|^[^ ]* /mnt/stateful_partition |\
$STATEFUL_PARTITION /mnt/stateful_partition |" "$INSTALL_ROOT"/etc/fstab
# NOTE: The stateful partition will not be mounted when this is
# called at USB-key install time.
EOF
chmod 0755 /usr/sbin/chromeos-postinst
ln -s /usr/sbin/chromeos-postinst /postinst
# make a mountpoint for stateful partition
sudo mkdir -p "$ROOTFS_DIR"/mnt/stateful_partition
sudo chmod 0755 "$ROOTFS_DIR"/mnt
sudo chmod 0755 "$ROOTFS_DIR"/mnt/stateful_partition
# If we don't create generic udev rules, then udev will try to save the
# history of various devices (i.e. always associate a given device and MAC
# address with the same wlan number). As we use a keyfob across different
@ -361,6 +410,11 @@ mknod --mode=0660 "$UDEV_DEVICES"/sda1 b 8 1
mknod --mode=0660 "$UDEV_DEVICES"/sda2 b 8 2
mknod --mode=0660 "$UDEV_DEVICES"/sda3 b 8 3
mknod --mode=0660 "$UDEV_DEVICES"/sda4 b 8 4
mknod --mode=0660 "$UDEV_DEVICES"/sdb b 8 16
mknod --mode=0660 "$UDEV_DEVICES"/sdb1 b 8 17
mknod --mode=0660 "$UDEV_DEVICES"/sdb2 b 8 18
mknod --mode=0660 "$UDEV_DEVICES"/sdb3 b 8 19
mknod --mode=0660 "$UDEV_DEVICES"/sdb4 b 8 20
mknod --mode=0660 "$UDEV_DEVICES"/fb0 c 29 0
mknod --mode=0660 "$UDEV_DEVICES"/dri/card0 c 226 0
mknod --mode=0640 "$UDEV_DEVICES"/input/mouse0 c 13 32
@ -420,8 +474,11 @@ done
# Add some tmpfs filesystems to fstab to enable session semantics
cat <<EOF >> /etc/fstab
/dev/root / rootfs ro 0 0
tmpfs /tmp tmpfs rw,nosuid,nodev 0 0
tmphomedir /home/chronos tmpfs rw,nosuid,nodev 0 0
LABEL=C-STATE /mnt/stateful_partition ext3 rw 0 1
/mnt/stateful_partition/home /home bind defaults,bind 0 0
/mnt/stateful_partition/var /var bind defaults,bind 0 0
EOF
# List all packages still installed post-pruning

View File

@ -64,16 +64,38 @@ then
exit 1
fi
fi
STATE_PART="$FLAGS_to"1
ROOT_PART="$FLAGS_to"3
sudo bash -c "cat \"${FLAGS_from}/mbr.image\" \
\"${FLAGS_from}/rootfs.image\" \
| dd of=\"$FLAGS_to\" bs=4M"
sudo dd if="${FLAGS_from}/mbr.image" of="$FLAGS_to"
sync
sudo partprobe "$FLAGS_to"
sync
sudo dd if="${FLAGS_from}/rootfs.image" of="$ROOT_PART" bs=4M
sudo mkfs.ext3 -F -L C-STATE "$STATE_PART"
sync
echo "Done."
else
# Output to a file, so just cat the source images together
PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image")
echo "Creating empty stateful partition"
dd if=/dev/zero of="${FLAGS_from}/stateful_partition.image" bs=1 count=1 \
seek=$(($PART_SIZE - 1))
mkfs.ext3 -F -L C-STATE "${FLAGS_from}/stateful_partition.image"
# Create a sparse output file
dd if=/dev/zero of="${FLAGS_to}" bs=1 count=1 \
seek=$(( ($PART_SIZE * 2) + 512 - 1))
echo "Copying USB image to file ${FLAGS_to}..."
cat "${FLAGS_from}/mbr.image" "${FLAGS_from}/rootfs.image" > "$FLAGS_to"
dd if="${FLAGS_from}/mbr.image" of="$FLAGS_to" conv=notrunc
dd if="${FLAGS_from}/stateful_partition.image" of="$FLAGS_to" seek=1 bs=512 \
conv=notrunc
cat "${FLAGS_from}/rootfs.image" >> "$FLAGS_to"
echo "Done. To copy to USB keyfob, outside the chroot, do something like:"
echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M"

View File

@ -22,88 +22,14 @@ then
exit 1
fi
FINAL_OUT_FILE=$(dirname "$1")/update.tgz
FINAL_OUT_FILE=$(dirname "$1")/update.gz
UNCOMPRESSED_OUT_FILE="$FINAL_OUT_FILE.uncompressed"
MOUNTPOINT="/tmp/mk_memento_images_mntpoint"
ORIGINAL_LABEL=$(sudo /sbin/e2label "$1")
# copy original over to the new file
cp "$1" "$UNCOMPRESSED_OUT_FILE"
# next steps require fs to be mounted. unmount if we die early
function cleanup_mount {
sudo umount "$MOUNTPOINT" || true
rmdir "$MOUNTPOINT"
}
mkdir -p "$MOUNTPOINT"
sudo mount -o loop "$UNCOMPRESSED_OUT_FILE" "$MOUNTPOINT"
trap cleanup_mount INT TERM EXIT
# make an empty postinst script. the quotes around EOF mean don't evaluate
# anything inside this HEREDOC.
cat <<"EOF" | sudo dd of="$MOUNTPOINT/postinst"
#!/bin/sh
set -e
# see if we're booted from hard drive or USB. We should not have booted from
# USB.
INITRD=$(cat /proc/cmdline | tr ' ' '\n' | grep ^initrd= | wc -l)
if [ "0" != "$INITRD" ]
then
# we're usb. abort.
exit 1
fi
# update /boot/extlinux.conf
INSTALL_ROOT=`dirname "$0"`
INSTALL_DEV="$1"
STATEFUL_PARTITION=$(echo "$INSTALL_DEV" | tr 12 44)
STATEFUL_PARTITION_DIR=/tmp/stateful_partition
# set default label to chromeos-hd
sed -i 's/^DEFAULT .*/DEFAULT chromeos-hd/' "$INSTALL_ROOT"/boot/extlinux.conf
sed -i "{ s:HDROOT:$INSTALL_DEV: }" "$INSTALL_ROOT"/boot/extlinux.conf
# fix fstab
# keep in sync with src/platform/installer/chromeos_install.sh
# TODO: Figure out if we can mount rootfs read-only
cat <<ENDFSTAB | sudo dd of="$INSTALL_ROOT"/etc/fstab
/dev/root / rootfs ro 0 0
tmpfs /tmp tmpfs rw,nosuid,nodev 0 0
$STATEFUL_PARTITION /mnt/stateful_partition ext3 rw 0 1
/mnt/stateful_partition/home /home bind defaults,bind 0 0
/mnt/stateful_partition/var /var bind defaults,bind 0 0
ENDFSTAB
mkdir -p "$INSTALL_ROOT"/mnt/stateful_partition
chmod 0755 "$INSTALL_ROOT"/mnt
chmod 0755 "$INSTALL_ROOT"/mnt/stateful_partition
# Creates an empty resolv.conf file with the right permissions to avoid
# it being clobbered by connman/dhclient.
# We assume the stateful partition at /mnt/stateful_partition will still be
# there when we boot into the new image
mkdir -p /mnt/stateful_partition/etc
# Default to Pacific timezone
# If user already has a timezone set, this won't replace it
ln -s /usr/share/zoneinfo/US/Pacific \
/mnt/stateful_partition/etc/localtime || true
ln -sf /mnt/stateful_partition/etc/localtime \
"$INSTALL_ROOT"/etc/localtime
EOF
sudo chmod 0755 "$MOUNTPOINT/postinst"
# done with mounting
trap - INT TERM EXIT
cleanup_mount
# Fix up the file system label. We prefix with 'A'
NEW_LABEL="A${ORIGINAL_LABEL}"
sudo /sbin/tune2fs -L "$NEW_LABEL" "$UNCOMPRESSED_OUT_FILE"