LiveOS image

From FedoraProject

(Difference between revisions)
Jump to: navigation, search
m (Merge overlay into new image: expand description of working folder)
(File Systems: emphasize added files)
(31 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
Fedora has developed [[wikipedia:Live CD|Live CD]] [[wikipedia:Live USB|USB]] DVD images for their GNU/Linux operating system. Since the image file systems are stored in the /LiveOS folder of the image, this is the name we'll use to reference the product.
 
Fedora has developed [[wikipedia:Live CD|Live CD]] [[wikipedia:Live USB|USB]] DVD images for their GNU/Linux operating system. Since the image file systems are stored in the /LiveOS folder of the image, this is the name we'll use to reference the product.
  
This page shares some information about the LiveOS design that helps users take better advantage of their disc resources.
+
This page shares some critical information about the LiveOS design that helps users take better advantage of their more-limited-than-usual disc resources.
  
 
==References==
 
==References==
  
* [http://git.fedorahosted.org/git/?p=hosted/livecd;a=blob;f=tools/livecd-iso-to-disk.sh;hb=HEAD livecd-iso-to-disk] (Usage instructions are on the first pages.)
+
* [http://git.fedorahosted.org/cgit/livecd/tree/tools/livecd-iso-to-disk.sh livecd-iso-to-disk] (Usage instructions are on the first pages.)
 
* [[FedoraLiveCD]]
 
* [[FedoraLiveCD]]
 
* [[How to create and use a Live CD]]
 
* [[How to create and use a Live CD]]
Line 15: Line 15:
  
 
==Storage==
 
==Storage==
When a Live CD or Live DVD (a LiveOS image on read-only disc media) is booted, temporary storage is prepared for the system in RAM on each boot by [http://git.kernel.org/?p=boot/dracut/dracut.git;a=blob;f=modules.d/90dmsquash-live/dmsquash-live-root.sh;hb=HEAD /sbin/dmsquash-live-root] in initrd0, the initial ram disk filesystem. An in-memory, copy-on-write, system overlay is used (see [[#File Systems|File Systems]] below).   
+
 
 +
When a Live CD or Live DVD (a LiveOS image on read-only disc media) is booted, '''temporary storage''' is prepared for the system in RAM on each boot by [http://git.kernel.org/?p=boot/dracut/dracut.git;a=blob;f=modules.d/90dmsquash-live/dmsquash-live-root.sh;hb=HEAD /sbin/dmsquash-live-root] in initrd0, the initial ram disk filesystem. An in-memory, copy-on-write, system overlay is used (see [[#File Systems|File Systems]] below).  The boot script prepares up to 0.5 GiB of RAM space in a [[wikipedia:Sparse file|sparse file]] by default.
 +
 
 +
{{admon/important|Critical limitation|The overlay file of LiveOS holds new and changed file content and metadata in a pool of sectors allocated as needed in a fixed size file. Should the overlay storage space, whether temporary or persistent, be totally consumed, the filesystem will be flagged 'Invalid' and, if that filesystem is the booted rootfs, it will crash with Input/output or Bus errors. If such a crash does occur while using temporary storage space for the overlay, a simple reboot will rectify the situation.  With persistent storage the situation is more dire and will require appending "rd.live.overlay.reset" (formerly "reset_overlay") to the kernel command line on boot-up.  This will reset the state to its initial boot (though it won't reset a persistent home, of course).  In either case, achieving a reboot will require a hard reset, since attempting a software initiated reboot on the Invalid filesystem will fail with more Input/output or Bus errors.}}
 +
 
 +
===Operating system file systems===
 +
Live Operating System, '''LiveOS''', file systems are found within disk image '''.img''' files.
 +
 
 +
If one mounts a Fedora-Live-Desktop.iso file or Live CD, the resulting block device file system will list 3 folders:
 +
/EFI
 +
/isolinux
 +
/LiveOS
 +
    |- livecd-iso-to-disk
 +
    |- osmin.img
 +
    |- squashfs.img
 +
The LiveOS folder contains 3 files:
 +
* livecd-iso-to-disk is a Bash script used for loading (installing) the LiveOS image onto a USB or SD disk.
 +
* osmin.img is a minimized OS image which is used to aid traditional installation from a LiveOS image source to a hard disk.
 +
* squashfs.img is a [[wikipedia:SquashFS|SquashFS]] compressed read-only file system with the Fedora operating system root file system inside another LiveOS folder containing an ext3fs.img file.
 +
Mounting the squashfs.img file and listing its block device file system will show this hierarchy:
 +
/LiveOS
 +
    |- ext3fs.img    (This may be named rootfs.img and contains an ext2, ext3, or ext4 file system type.)
 +
Mounting the ext3fs.img file will finally reveal the Fedora operating system root file system.
 +
 
 +
Here is a summary of the whole structure:
 +
'''Fedora-Live-Desktop.iso'''
 +
  ''!(mount)''
 +
  /EFI
 +
  /isolinux
 +
  /LiveOS
 +
      |- livecd-iso-to-disk
 +
      |- osmin.img
 +
      |- '''squashfs.img'''
 +
            ''!(mount)''
 +
            /LiveOS
 +
                |- '''ext3fs.img'''
 +
                    ''!(mount)''         
 +
                    /bin -> usr/bin
 +
                    /boot
 +
                    /dev
 +
                    /etc
 +
                    /home
 +
                    /lib -> usr/lib
 +
                    /lost+found
 +
                    /media
 +
                    /mnt
 +
                    /opt
 +
                    /proc
 +
                    /root
 +
                    /run
 +
                    /sbin -> usr/sbin
 +
                    /srv
 +
                    /sys
 +
                    /tmp
 +
                    /usr
 +
                    /var
 +
 
 +
When the LiveOS image is loaded onto a USB or SD disk, the {{Code|isolinux}} folder is copied into a {{Code|syslinux}} folder.
 +
 
 +
If persistence is requested with the {{Code|--overlay-size-mb NNN}} option, a Device-mapper overlay file for the root file system is created in {{Code|LiveOS}}.
 +
 
 +
If a separate home file system is requested with the {{Code|--home-size-mb NNN}} option, an ext4 formatted {{Code|'''home.img'''}} file system is created.
 +
 
 +
The structure is then as follows:
 +
'''Fedora-Live-Desktop USB/SD device'''
 +
  ''!(mounted on /run/initramfs/live)'' (Before Fedora 17 the mount point is /mnt/live in the root file system.)
 +
  /syslinux
 +
  /LiveOS
 +
      |- '''home.img'''
 +
            ''!(mounted on /home)''      (This occurs during boot up by the /etc/rc.d/init.d/livesys script.)
 +
            /liveuser
 +
                /Desktop
 +
                /Documents
 +
                /Downloads
 +
                ...
 +
            /lost+found
 +
      |- livecd-iso-to-disk
 +
      |- '''overlay-NAME-XXXX-XXXX'''    (Where NAME is the device partition name and XXXX are hex numerals.)
 +
      |- osmin.img
 +
      |- '''squashfs.img'''
 +
            ''!(mount)''                (At boot up by the /usr/sbin/dmsquash-live-root.sh script in the initramfs.)
 +
            /LiveOS
 +
                |- '''ext3fs.img'''
 +
                    ''!(mounted on '/')''    (This occurs during boot up by the dmsquash-live-root.sh script.)
 +
                    /bin -> usr/bin
 +
                    /boot
 +
                    /dev
 +
                    /etc
 +
                    /home                (If there is a '''home.img''', then this is its mount point directory.)
 +
 
 +
If the {{Code|--skipcompress}} option is used during loading with {{Code|livecd-iso-to-disk}}, the '''squashfs.img''' compression layer will be skipped.  The structure is then as follows:
 +
'''Fedora-Live-Desktop USB/SD device'''
 +
  ''!(mounted on /run/initramfs/live)''
 +
  /syslinux
 +
  /LiveOS
 +
      |- '''home.img'''
 +
            ''!(mounted on /home)''
 +
            /liveuser
 +
                /...
 +
      |- livecd-iso-to-disk
 +
      |- '''overlay-NAME-XXXX-XXXX'''
 +
      |- osmin.img
 +
      |- '''ext3fs.img'''
 +
            ''!(mounted on '/')''         
 +
            /bin -> usr/bin
 +
            /boot
 +
            /dev
 +
            /etc
 +
            /home
 +
            ...
 +
 
 +
===Persistent storage===
  
 
The Fedora LiveOS system allows for persistent storage in 3 locations:
 
The Fedora LiveOS system allows for persistent storage in 3 locations:
  
# An all-purpose, persistent overlay - a write-once, fixed-size file space that will save updates and changes to the LiveOS image (Activities, operating system changes, anything written in the LiveOS file space).
+
# An all-purpose, persistent overlay-based file space that saves all updates and changes to the root LiveOS filesystem. But, this storage '''space is limited''' by its allocate-once, fixed-sized design, and must be used with caution (see [[#File Systems|File Systems]] below).
# Persistent home folder - a re-writable, re-sizable (with difficulty), uncompressed, optionally-encryptable, file space for anything that goes in the user's /home/ folder.  A persistent home folder is an option that may be selected at the time of installation of the LiveOS image (although with some effort, one could manually create a home.img filesystem in /LiveOS/ and move the /home/ folder to it). This installation option is only available through the script, '[[livecd-iso-to-disk]]'. The Windows and Fedora 'Live USB Creator' installers do not provide this option at present.
+
# Persistent home folder - a re-writable, re-sizable (with difficulty), uncompressed, optionally-encryptable, file space for anything that goes in the user's /home/ folder.  A persistent home folder is an option that may be selected at the time of installation of the LiveOS image (although with some effort, one could manually create a {{Code|home.img}} filesystem in {{Code|/LiveOS/}} and move the {{Code|/home/}} folder to it). This installation option is only available through the script, '[[livecd-iso-to-disk]]'. The Windows and Fedora 'Live USB Creator' installers do not provide this option at present.
# Host device file space - this is the USB stick or SD card file system that is outside of the LiveOS file tree, but which is accessible through the /mnt/live or /run/initramfs/live (since Fedora 17) mount point of a booted LiveOS installation.  There, one finds the boot configuration files and anything else one had on the device before loading the LiveOS image.  One may save files here without consuming the other, limited file spaces. (This file space is limited by the device capacity).
+
# Host device file space - this is the USB stick or SD card file system that is outside of the LiveOS file tree, but which is accessible through the {{Code|/run/initramfs/live}} or {{Code|/mnt/live}} (before Fedora 17) mount point of a booted LiveOS installation.  There, one finds the boot configuration files and anything else one had on the device before loading the LiveOS image.  One may save files here without consuming the other, limited file spaces. (This file space is limited only by the device capacity).
 +
/run/initramfs/live
 +
                  /LiveOS
 +
                      |- home.img
 +
                      |- livecd-iso-to-disk
 +
                      |- overlay-NAME-XXXX-XXXX
 +
                      |- osmin.img
 +
                      |- squashfs.img
 +
                  /syslinux
  
 
The all-purpose, persistent overlay is needed for operating system changes and updates.
 
The all-purpose, persistent overlay is needed for operating system changes and updates.
  
The file systems are prepared on each boot by the [http://git.fedorahosted.org/git/?p=spin-kickstarts.git;a=blob;f=fedora-live-base.ks;hb=HEAD#l63 /etc/rc.d/init.d/livesys script].
+
The file systems are prepared on each boot by the [http://git.fedorahosted.org/cgit/spin-kickstarts.git/tree/fedora-live-base.ks#n56 /etc/rc.d/init.d/livesys script].
  
 
===Home filesystem===
 
===Home filesystem===
Line 45: Line 164:
  
 
==File Systems==
 
==File Systems==
 
+
{{admon/note|Take note:|It is important to realize that because the LiveOS root filesystem normally resides in a compressed SquashFS image, the standard estimates of free disc space, such as those reported by {{Code|df}} and graphical file managers, will report '''"apparent" file space''' (as if the filesystem were not compressed), thus, such estimates are usually '''vast overestimates of the actual free space''' physically available to the root filesystem.
 +
: For example, the Fedora-18-x86_64-Live-Desktop.iso contains an apparent 4 GiB ext4 root filesystem that has been sparsed and compressed into under 900 MiB of actual disc space in the .iso file (or on a LiveOS installed device file system).  {{Code|df -h}} on an untouched mounting of the root filesystem will report that 3.1G is used and 695M is available space out of a total size of 3.9G.
 +
The actually available and allocated physical disc space for the root filesystem is determined by the size of the ''device-mapper'' overlay file and can only be queried by the {{Code|dmsetup status}} command (see below).
 +
: For example, one may add, and then delete, a large file in the root filesystem and see (the apparent virtual) used space go up, and then down, when checking with {{Code|df}}, but the {{Code|dmsetup status live-rw}} consumption report will only ever show an increase—even though allocated overlay sectors are available for reuse if an added file has been deleted (see discussion below).}}
 
The Fedora LiveOS uses the [[wikipedia:Device mapper|Device-mapper]] service of the Linux kernel to manage the file stores on the device.  This is the same service that is used by [[wikipedia:Logical Volume Manager (Linux)|Logical Volume Manager]] to provide disc partition services.
 
The Fedora LiveOS uses the [[wikipedia:Device mapper|Device-mapper]] service of the Linux kernel to manage the file stores on the device.  This is the same service that is used by [[wikipedia:Logical Volume Manager (Linux)|Logical Volume Manager]] to provide disc partition services.
  
One limitation, mentioned above, is that the LiveOS persistent overlay is a write-once file space.  This is related to its use of ''device mapper'' snapshots to combine a read-only file system image (copied from the compressed SquashFS.img on the read-only LiveCD or installation .iso file) with a [[wikipedia:Copy-on-write|Copy-on-write]] service that tracks only changed blocks of data in the snapshot (overlay) file and then re-referencing file pointers to the updated blocks.<ref>http://people.gnome.org/~markmc/code/merge-dm-snapshot.c</ref><ref>http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=blob;f=drivers/md/dm-snap-persistent.c;hb=HEAD</ref> Any changes to the operating system files are stored as differences from the base. As such, "deletions" of files are saved as additional difference references, and the originals are hidden.  With this mechanism, physical storage space is consumed in the write-once file space rather than recovered.
+
One critical limitation, mentioned above, is that the LiveOS persistent overlay is a allocate-once file space.  This is related to its use of ''device mapper'' snapshots to combine a read-only file system image (copied from the compressed SquashFS.img on the read-only LiveCD or installation .iso file) with a [[wikipedia:Copy-on-write|Copy-on-write]] service that tracks only changed blocks of data in the snapshot (overlay) file and then re-referencing file pointers to the updated blocks.<ref>http://people.gnome.org/~markmc/code/merge-dm-snapshot.c</ref><ref>http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=blob;f=drivers/md/dm-snap-persistent.c;hb=HEAD</ref> Any changes to the original operating system files are stored as differences from the base. As such, "deletions" of these original files are saved as additional difference references, and the originals are hidden.  With this mechanism, physical storage space is consumed in the overlay file space (nothing can be recovered from the read-only original). The apparent free space in the virtual root filesystem as reported by the {{Code|df}} command will increase, but this additional space is not physically available; however, when a new or changed file is deleted, the new or changed sectors only are available for reuse, but, unfortunately, the count of allocated sectors does not change, so one cannot be certain of the availability of free physical space after arbitrary changes to the root filesystem.
  
 
Consumption of the space allocated for persistent storage in the snapshot overlay file may be tracked with the ''device mapper'' {{Code|dmsetup status}} report.
 
Consumption of the space allocated for persistent storage in the snapshot overlay file may be tracked with the ''device mapper'' {{Code|dmsetup status}} report.
 +
 +
For example, {{Code|dmsetup status live-rw}} may return
 +
 +
live-rw: 0 8388608 snapshot 42296/1048576 176
 +
 +
where the fraction after {{command|snapshot}} is the number of 512-byte sectors allocated in the overlay over the total number available in the overlay. (The final number is the metadata sectors allocated, and the number before {{command|snapshot}} is the apparent size of the virtual filesystem.)
 +
 +
Unfortunately, there is no process written to monitor the overlay consumption level and provide a graceful warning of its imminent exhaustion and the subsequent failure of the root filesystem. So where long-term usage of a LiveOS image is anticipated, special attention to overlay consumption is advised.
 +
: (Last-ditch [[#Overlay recovery|recovery of a persistent overlay]] for a failed root filesystem may be attempted from a separate boot of a working system.)
  
 
Several developments in the LiveOS design may be considered to maximize the endurance of the LiveOS image.
 
Several developments in the LiveOS design may be considered to maximize the endurance of the LiveOS image.
Line 56: Line 187:
 
===Avoid persistent overlay consumption===
 
===Avoid persistent overlay consumption===
  
* Use a persistent /home folder (discussed above).
+
* Use a persistent {{Code|home.img}} file system to mount on the {{Code|/home}} folder (discussed above).
 
*: This is a very effective method to avoid consumption and will also make the user files more available for sharing and backup purposes.
 
*: This is a very effective method to avoid consumption and will also make the user files more available for sharing and backup purposes.
* Move the root user's home to /home/root in a persistent home.img
+
* Move the root user's home to {{Code|/home/root}} in a persistent {{Code|home.img}}.
 
*: This would avoid some consumption, but would compromise the root user account if there was a boot problem and the /home folder was not mounted.
 
*: This would avoid some consumption, but would compromise the root user account if there was a boot problem and the /home folder was not mounted.
 
* Mount more folders onto temporary, in-memory filesystems (like /var/cache/yum, /var/tmp, & /tmp are now).
 
* Mount more folders onto temporary, in-memory filesystems (like /var/cache/yum, /var/tmp, & /tmp are now).
Line 76: Line 207:
 
The snapshot overlay can then be reset before rebooting the LiveOS device.
 
The snapshot overlay can then be reset before rebooting the LiveOS device.
  
The following Bash script demonstrates the process, where the {{Code|$1}} parameter is a working folder on a disk partition with sufficient storage capacity, and {{Code|$2}} is the LiveOS device node name (such as, {{Code|/run/initramfs/livedev}}, for the currently booted LiveOS image, or {{Code|/dev/sdc1}}, for example, for an attached LiveOS device):
+
The following Bash script demonstrates the process, where the {{Code|$1}} parameter is a mount point directory for a disk partition with sufficient storage capacity (a LiveOS folder will be created there for holding the mirrored filesystem), and {{Code|$2}} is the LiveOS device node name (such as, {{Code|/run/initramfs/livedev}}, for the currently booted LiveOS image, or {{Code|/dev/sdc1}}, for example, for an attached LiveOS device). Options xtrace and verbose have been set to aid debugging.
 
{{admon/warning|Test and practice the following script!|This procedure will delete the LiveOS filesystem before replacing it with a recompressed merged version. Be sure to verify that you will have sufficient space for the replacement before running the full script.  (You could comment out the deletion, and squash into a directory on a large working drive to determine the new filesystem size.)}}
 
{{admon/warning|Test and practice the following script!|This procedure will delete the LiveOS filesystem before replacing it with a recompressed merged version. Be sure to verify that you will have sufficient space for the replacement before running the full script.  (You could comment out the deletion, and squash into a directory on a large working drive to determine the new filesystem size.)}}
 
<pre>
 
<pre>
#!/bin/bash
+
#!/bin/bash -xv
 +
#
 +
# Merge a LiveOS snapshot overlay into a new root filesystem, recompress it
 +
# into a SquashFS image (if the source was so packaged), replace the source
 +
# with the refresh, and reset the overlay.
 +
#
 +
# This program is free software; you can redistribute it and/or modify
 +
# it under the terms of the GNU General Public License as published by
 +
# the Free Software Foundation; version 2 of the License.
 +
#
 +
# This program is distributed in the hope that it will be useful,
 +
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 +
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +
# GNU Library General Public License for more details.
 +
#
 +
# You should have received a copy of the GNU General Public License
 +
# along with this program; if not, write to the Free Software
 +
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 +
 
 +
 
 +
export PATH=/usr/sbin:$PATH
 +
export \
 +
  PS4='+(${SHLVL}:${LINENO}:${BASH_SOURCE}:${EUID}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
 
set -o errexit
 
set -o errexit
 
set -o pipefail
 
set -o pipefail
Line 94: Line 247:
 
     printf '\nTotal time elapsed: %02d:%02d:%02d hh:mm:ss\n' $h $m $s
 
     printf '\nTotal time elapsed: %02d:%02d:%02d hh:mm:ss\n' $h $m $s
 
     [[ $1 == 0 ]] && exit 0 || exit 1
 
     [[ $1 == 0 ]] && exit 0 || exit 1
}
 
 
getloopdev () {
 
    # Return the loop device associated with a backing file.
 
    local loopdev=$(losetup -j "$1")
 
    echo ${loopdev%%:*}
 
 
}
 
}
  
Line 106: Line 253:
  
 
# Mount the source device and SquashFS.
 
# Mount the source device and SquashFS.
SRCMNT=$(mktemp -d /media/XXXXXX)
+
SRCMNT=$(mktemp -d /run/media/XXXXXX)
 
mount $2 $SRCMNT
 
mount $2 $SRCMNT
 
# >= Fedora 17
 
LiveOSMNT=/run/initramfs/live
 
# < Fedora 17
 
[[ -d /mnt/live/LiveOS ]] && LiveOSMNT=/mnt/live
 
  
 
if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
 
if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
     SQUASHMNT=$(mktemp -d /media/XXXXXX)
+
     SQUASHMNT=$(mktemp -d /run/media/XXXXXX)
 
     mount $SRCMNT/LiveOS/squashfs.img $SQUASHMNT --read-only
 
     mount $SRCMNT/LiveOS/squashfs.img $SQUASHMNT --read-only
 
     ORIGFS=$SQUASHMNT/LiveOS/ext3fs.img
 
     ORIGFS=$SQUASHMNT/LiveOS/ext3fs.img
Line 123: Line 265:
 
     [[ ! -f $ORIGFS ]] && ORIGFS=$SRCMNT/LiveOS/rootfs.img
 
     [[ ! -f $ORIGFS ]] && ORIGFS=$SRCMNT/LiveOS/rootfs.img
 
fi
 
fi
 +
 +
OVERLAY=/LiveOS/$(basename $SRCMNT/LiveOS/overlay-*)
 +
if [[ -f $SRCMNT$OVERLAY ]]; then
 +
    OVDEV=$(losetup -f --show $SRCMNT$OVERLAY --read-only)
 +
else
 +
    printf '\n  No persistent overlay for the filesystem was found.
 +
    Exiting...\n'
 +
    cleanup 1
 +
fi
 +
 +
# >= Fedora 17
 +
LiveOSMNT=/run/initramfs/live
 +
# < Fedora 17
 +
[[ -d /mnt/live/LiveOS ]] && LiveOSMNT=/mnt/live
 +
 +
# If we are processing a booted LiveOS device's root filesystem, then
 +
if [[ $(mountpoint -x $2) == $(mountpoint -dq $LiveOSMNT) ]]; then
 +
    # Remove live-osimg-min; free its loop devices.
 +
    if [[ -e $SRCMNT/LiveOS/osmin.img ]]; then
 +
        dmsetup remove live-osimg-min || :
 +
        losetup -d /dev/loop1 || :
 +
        losetup -d /dev/loop0 || :
 +
    fi
 +
else
 +
    LiveOSMNT=''
 +
fi
 +
# Remove expiring osmin.img
 +
rm $SRCMNT/LiveOS/osmin.img || :
  
 
# Prepare temporary devices for the Device-mapper mirror target.
 
# Prepare temporary devices for the Device-mapper mirror target.
 
FSTYPE=$(blkid -s TYPE -o value $ORIGFS || :)
 
FSTYPE=$(blkid -s TYPE -o value $ORIGFS || :)
 
FSLABEL=$(blkid -s LABEL -o value $ORIGFS || :)
 
FSLABEL=$(blkid -s LABEL -o value $ORIGFS || :)
stinfo=($(stat -c '%b %B %o' $ORIGFS || :))
+
stinfo=($(stat -c '%B %s %o' $ORIGFS || :))
BLOCKS=${stinfo[0]}
+
BLOCKSZ=${stinfo[0]}
BLOCKSZ=${stinfo[1]}
+
BLOCKS=$((${stinfo[1]}/$BLOCKSZ))
 
IOBLKSZ=${stinfo[2]}
 
IOBLKSZ=${stinfo[2]}
  
Line 139: Line 309:
  
 
roORIGFSDEV=$(losetup -f --show $ORIGFS --read-only)
 
roORIGFSDEV=$(losetup -f --show $ORIGFS --read-only)
OVERLAY=/LiveOS/$(basename $SRCMNT/LiveOS/overlay-*)
 
if [[ -f $SRCMNT$OVERLAY ]]; then
 
    OVDEV=$(losetup -f --show $SRCMNT$OVERLAY --read-only)
 
else
 
    printf '\n  No persistent overlay for the filesystem was found.
 
    Exiting...\n'
 
    losetup -d $NEWFSDEV $roORIGFSDEV
 
    cleanup 1
 
fi
 
  
dmsetup create ori --readonly <<< "0 $BLOCKS snapshot $roORIGFSDEV $OVDEV P 8"
+
table="0 $BLOCKS snapshot $roORIGFSDEV $OVDEV P 8"
 +
dmsetup create ori --readonly --table "$table"
 +
 
 
# Invoke mirror target device.
 
# Invoke mirror target device.
mirror="0 $BLOCKS mirror core 2 32 sync 2 /dev/mapper/ori 0 $NEWFSDEV 0"
+
table="0 $BLOCKS mirror core 2 32 sync 2 /dev/mapper/ori 0 $NEWFSDEV 0"
dmsetup create mir <<< "$mirror"
+
dmsetup create mir --table "$table"
  
 +
set +xv
 
# Wait for mirror completion.
 
# Wait for mirror completion.
 
while state=$(dmsetup status mir)
 
while state=$(dmsetup status mir)
Line 174: Line 338:
 
done
 
done
 
printf '\r  Mirroring 100 %% complete.    \n'
 
printf '\r  Mirroring 100 %% complete.    \n'
 
+
set -xv
# Remove outdated osmin.img.
+
if [[ -e $SRCMNT/LiveOS/osmin.img ]]; then
+
    dmsetup remove live-osimg-min
+
    losetup -d $(getloopdev /osmin)
+
    losetup -d $(getloopdev '/osmin.img (deleted)')
+
    rm $SRCMNT/LiveOS/osmin.img
+
fi
+
  
 
# Check the new filesystem.
 
# Check the new filesystem.
Line 217: Line 374:
  
 
# If we are processing a booted LiveOS device's root filesystem, then
 
# If we are processing a booted LiveOS device's root filesystem, then
if [[ $(mountpoint -x $2) == $(mountpoint -dq $LiveOSMNT) ]]; then
+
if [[ -n $LiveOSMNT ]]; then
     # The new merged filesystem will be made active.
+
     # Try to unmount the TMPDIR.
     origSQUASHDEV=$(blkid -o device -t TYPE=squashfs)
+
     mountpoint $TMPDIR && umount -l $TMPDIR || :
    origROOTFS=$(dmsetup table live-rw)
+
     shutdown -r +1 'The system will reboot in 1 minute.'
    origFSDEV=${origROOTFS#*:}
+
     origFSDEV=/dev/loop${origFSDEV%% *}
+
    origOVDEV=${origROOTFS##*:}
+
    origOVDEV=/dev/loop${origOVDEV%% *}
+
    if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
+
        mount $SRCMNT/LiveOS/squashfs.img $SQUASHMNT --read-only
+
        NEWFS=$SQUASHMNT/LiveOS/rootfs.img
+
    else
+
        NEWFS=$SRCMNT/LiveOS/rootfs.img
+
    fi
+
    NEWFSDEV=$(losetup -f --show $NEWFS)
+
    sync
+
    echo 3 > /proc/sys/vm/drop_caches
+
    dd if=/dev/zero of=$OVDEV bs=64k count=1 conv=notrunc,fsync
+
    dmsetup suspend live-rw
+
    dmsetup reload live-rw <<< "0 $BLOCKS snapshot $NEWFSDEV $OVDEV P 8"
+
    dmsetup resume live-rw
+
    dd if=/dev/zero of=$OVDEV bs=64k count=1 conv=notrunc,fsync
+
    losetup -d $origOVDEV
+
    losetup -d $origFSDEV
+
    losetup -d $origSQUASHDEV
+
 
else
 
else
 +
    sleep 1
 
     losetup -d $OVDEV
 
     losetup -d $OVDEV
 
fi
 
fi
 
cleanup 0
 
cleanup 0
 
</pre>
 
</pre>
'''Note:''' If the above script is invoked on a currently booted LiveOS root filesystem, the live reloading of the root filesystem can leave some dirty metadata buffers or other minor corruption (seen in /var/log/messages). These can be cleaned by resetting the overlay on or before the next boot.
+
'''Note:''' If the above script is invoked on a currently booted LiveOS root filesystem, the system will be scheduled for a reboot one minute after the script completes.
  
 
The Device-mapper snapshot-merge target also allows one to merge changes in a persistent snapshot into the original filesystem (See notes from [[{{TALKPAGENAMEE}}|Andrew Gilmore]]).
 
The Device-mapper snapshot-merge target also allows one to merge changes in a persistent snapshot into the original filesystem (See notes from [[{{TALKPAGENAMEE}}|Andrew Gilmore]]).
Line 388: Line 525:
 
where overlay_size and size_increase are now 512 byte units.
 
where overlay_size and size_increase are now 512 byte units.
  
Once you have a working filesystem, you should proceed to merge your overlay into the original filesystem as describe [[#Image recompression and overlay refreshment|above]].
+
Once you have a working filesystem, you should proceed to merge your overlay into the original filesystem as described [[#Merge overlay into new image|above]].
 +
 
 
==References==
 
==References==
 
<references />
 
<references />
 
:: See this [http://thread.gmane.org/gmane.linux.kernel.device-mapper.devel/14644 dm-devel thread].
 
:: See this [http://thread.gmane.org/gmane.linux.kernel.device-mapper.devel/14644 dm-devel thread].
 +
* The method of [[LiveOS_image#Merge_overlay_into_new_image|mirroring the LiveOS]] was adapted from Douglas McClendon's [http://cloudsession.com/dawg/projects/zyx-liveinstaller/ ZyX-LiveInstaller].

Revision as of 04:33, 18 March 2013

Contents



Introduction

Fedora has developed Live CD USB DVD images for their GNU/Linux operating system. Since the image file systems are stored in the /LiveOS folder of the image, this is the name we'll use to reference the product.

This page shares some critical information about the LiveOS design that helps users take better advantage of their more-limited-than-usual disc resources.

References

Storage

When a Live CD or Live DVD (a LiveOS image on read-only disc media) is booted, temporary storage is prepared for the system in RAM on each boot by /sbin/dmsquash-live-root in initrd0, the initial ram disk filesystem. An in-memory, copy-on-write, system overlay is used (see File Systems below). The boot script prepares up to 0.5 GiB of RAM space in a sparse file by default.

Important.png
Critical limitation
The overlay file of LiveOS holds new and changed file content and metadata in a pool of sectors allocated as needed in a fixed size file. Should the overlay storage space, whether temporary or persistent, be totally consumed, the filesystem will be flagged 'Invalid' and, if that filesystem is the booted rootfs, it will crash with Input/output or Bus errors. If such a crash does occur while using temporary storage space for the overlay, a simple reboot will rectify the situation. With persistent storage the situation is more dire and will require appending "rd.live.overlay.reset" (formerly "reset_overlay") to the kernel command line on boot-up. This will reset the state to its initial boot (though it won't reset a persistent home, of course). In either case, achieving a reboot will require a hard reset, since attempting a software initiated reboot on the Invalid filesystem will fail with more Input/output or Bus errors.

Operating system file systems

Live Operating System, LiveOS, file systems are found within disk image .img files.

If one mounts a Fedora-Live-Desktop.iso file or Live CD, the resulting block device file system will list 3 folders:

/EFI
/isolinux
/LiveOS
    |- livecd-iso-to-disk
    |- osmin.img
    |- squashfs.img

The LiveOS folder contains 3 files:

  • livecd-iso-to-disk is a Bash script used for loading (installing) the LiveOS image onto a USB or SD disk.
  • osmin.img is a minimized OS image which is used to aid traditional installation from a LiveOS image source to a hard disk.
  • squashfs.img is a SquashFS compressed read-only file system with the Fedora operating system root file system inside another LiveOS folder containing an ext3fs.img file.

Mounting the squashfs.img file and listing its block device file system will show this hierarchy:

/LiveOS
    |- ext3fs.img    (This may be named rootfs.img and contains an ext2, ext3, or ext4 file system type.)

Mounting the ext3fs.img file will finally reveal the Fedora operating system root file system.

Here is a summary of the whole structure:

Fedora-Live-Desktop.iso
  !(mount)
  /EFI
  /isolinux
  /LiveOS
      |- livecd-iso-to-disk
      |- osmin.img
      |- squashfs.img
           !(mount)
           /LiveOS
               |- ext3fs.img
                    !(mount)          
                    /bin -> usr/bin
                    /boot
                    /dev
                    /etc
                    /home
                    /lib -> usr/lib
                    /lost+found
                    /media
                    /mnt
                    /opt
                    /proc
                    /root
                    /run
                    /sbin -> usr/sbin
                    /srv
                    /sys
                    /tmp
                    /usr
                    /var

When the LiveOS image is loaded onto a USB or SD disk, the isolinux folder is copied into a syslinux folder.

If persistence is requested with the --overlay-size-mb NNN option, a Device-mapper overlay file for the root file system is created in LiveOS.

If a separate home file system is requested with the --home-size-mb NNN option, an ext4 formatted home.img file system is created.

The structure is then as follows:

Fedora-Live-Desktop USB/SD device
  !(mounted on /run/initramfs/live) (Before Fedora 17 the mount point is /mnt/live in the root file system.)
  /syslinux
  /LiveOS
      |- home.img
           !(mounted on /home)      (This occurs during boot up by the /etc/rc.d/init.d/livesys script.)
           /liveuser
               /Desktop
               /Documents
               /Downloads
               ...
           /lost+found
      |- livecd-iso-to-disk
      |- overlay-NAME-XXXX-XXXX     (Where NAME is the device partition name and XXXX are hex numerals.)
      |- osmin.img
      |- squashfs.img
           !(mount)                 (At boot up by the /usr/sbin/dmsquash-live-root.sh script in the initramfs.)
           /LiveOS
               |- ext3fs.img
                    !(mounted on '/')    (This occurs during boot up by the dmsquash-live-root.sh script.)
                    /bin -> usr/bin
                    /boot
                    /dev
                    /etc
                    /home                (If there is a home.img, then this is its mount point directory.)

If the --skipcompress option is used during loading with livecd-iso-to-disk, the squashfs.img compression layer will be skipped. The structure is then as follows:

Fedora-Live-Desktop USB/SD device
  !(mounted on /run/initramfs/live)
  /syslinux
  /LiveOS
      |- home.img
           !(mounted on /home)
           /liveuser
               /...
      |- livecd-iso-to-disk
      |- overlay-NAME-XXXX-XXXX
      |- osmin.img
      |- ext3fs.img
           !(mounted on '/')          
           /bin -> usr/bin
           /boot
           /dev
           /etc
           /home
           ...

Persistent storage

The Fedora LiveOS system allows for persistent storage in 3 locations:

  1. An all-purpose, persistent overlay-based file space that saves all updates and changes to the root LiveOS filesystem. But, this storage space is limited by its allocate-once, fixed-sized design, and must be used with caution (see File Systems below).
  2. Persistent home folder - a re-writable, re-sizable (with difficulty), uncompressed, optionally-encryptable, file space for anything that goes in the user's /home/ folder. A persistent home folder is an option that may be selected at the time of installation of the LiveOS image (although with some effort, one could manually create a home.img filesystem in /LiveOS/ and move the /home/ folder to it). This installation option is only available through the script, 'livecd-iso-to-disk'. The Windows and Fedora 'Live USB Creator' installers do not provide this option at present.
  3. Host device file space - this is the USB stick or SD card file system that is outside of the LiveOS file tree, but which is accessible through the /run/initramfs/live or /mnt/live (before Fedora 17) mount point of a booted LiveOS installation. There, one finds the boot configuration files and anything else one had on the device before loading the LiveOS image. One may save files here without consuming the other, limited file spaces. (This file space is limited only by the device capacity).
/run/initramfs/live
                  /LiveOS
                      |- home.img
                      |- livecd-iso-to-disk
                      |- overlay-NAME-XXXX-XXXX
                      |- osmin.img
                      |- squashfs.img
                  /syslinux

The all-purpose, persistent overlay is needed for operating system changes and updates.

The file systems are prepared on each boot by the /etc/rc.d/init.d/livesys script.

Home filesystem

One may find many advantages to installing the LiveOS, with a persistent, home folder (using the --home-size-mb NN --delete-home options), which will hold all the user files and documents one wishes and, perhaps later, throw away—all without consuming the write-once overlay, which can be consumed very quickly (and overlay file space is not normally reusable).

Device filesystem

Additionally, keeping some storage space on the device disc outside of the LiveOS system will let you copy, carry, and delete large resource files, such as image.iso files, or anything you might want to use or share.

Installation options

Fedora 17 Live Desktop may be installed on a 1 GB USB device using the following options with livecd-iso-to-disk (on a single, terminal or console command line, even though the wiki may wrap the following text to accommodate your browser window size):

./livecd-iso-to-disk --reset-mbr --overlay-size-mb 200 --home-size-mb 140 --delete-home --unencrypted-home /path/to/source/iso/or/device /dev/sd?1
where '?' in the final parameter represents the target bootable device node, such as sdb1 or sdc1, etc.

The above configuration would allow space for the home folder, the operating system, and a little on the device root.

But with a larger capacity device, one may allocate the resources to suit the anticipated use, as described above.

File Systems

Note.png
Take note:
It is important to realize that because the LiveOS root filesystem normally resides in a compressed SquashFS image, the standard estimates of free disc space, such as those reported by df and graphical file managers, will report "apparent" file space (as if the filesystem were not compressed), thus, such estimates are usually vast overestimates of the actual free space physically available to the root filesystem.
For example, the Fedora-18-x86_64-Live-Desktop.iso contains an apparent 4 GiB ext4 root filesystem that has been sparsed and compressed into under 900 MiB of actual disc space in the .iso file (or on a LiveOS installed device file system). df -h on an untouched mounting of the root filesystem will report that 3.1G is used and 695M is available space out of a total size of 3.9G.

The actually available and allocated physical disc space for the root filesystem is determined by the size of the device-mapper overlay file and can only be queried by the dmsetup status command (see below).

For example, one may add, and then delete, a large file in the root filesystem and see (the apparent virtual) used space go up, and then down, when checking with df, but the dmsetup status live-rw consumption report will only ever show an increase—even though allocated overlay sectors are available for reuse if an added file has been deleted (see discussion below).

The Fedora LiveOS uses the Device-mapper service of the Linux kernel to manage the file stores on the device. This is the same service that is used by Logical Volume Manager to provide disc partition services.

One critical limitation, mentioned above, is that the LiveOS persistent overlay is a allocate-once file space. This is related to its use of device mapper snapshots to combine a read-only file system image (copied from the compressed SquashFS.img on the read-only LiveCD or installation .iso file) with a Copy-on-write service that tracks only changed blocks of data in the snapshot (overlay) file and then re-referencing file pointers to the updated blocks.[1][2] Any changes to the original operating system files are stored as differences from the base. As such, "deletions" of these original files are saved as additional difference references, and the originals are hidden. With this mechanism, physical storage space is consumed in the overlay file space (nothing can be recovered from the read-only original). The apparent free space in the virtual root filesystem as reported by the df command will increase, but this additional space is not physically available; however, when a new or changed file is deleted, the new or changed sectors only are available for reuse, but, unfortunately, the count of allocated sectors does not change, so one cannot be certain of the availability of free physical space after arbitrary changes to the root filesystem.

Consumption of the space allocated for persistent storage in the snapshot overlay file may be tracked with the device mapper dmsetup status report.

For example, dmsetup status live-rw may return

live-rw: 0 8388608 snapshot 42296/1048576 176

where the fraction after snapshot is the number of 512-byte sectors allocated in the overlay over the total number available in the overlay. (The final number is the metadata sectors allocated, and the number before snapshot is the apparent size of the virtual filesystem.)

Unfortunately, there is no process written to monitor the overlay consumption level and provide a graceful warning of its imminent exhaustion and the subsequent failure of the root filesystem. So where long-term usage of a LiveOS image is anticipated, special attention to overlay consumption is advised.

(Last-ditch recovery of a persistent overlay for a failed root filesystem may be attempted from a separate boot of a working system.)

Several developments in the LiveOS design may be considered to maximize the endurance of the LiveOS image.

Avoid persistent overlay consumption

  • Use a persistent home.img file system to mount on the /home folder (discussed above).
    This is a very effective method to avoid consumption and will also make the user files more available for sharing and backup purposes.
  • Move the root user's home to /home/root in a persistent home.img.
    This would avoid some consumption, but would compromise the root user account if there was a boot problem and the /home folder was not mounted.
  • Mount more folders onto temporary, in-memory filesystems (like /var/cache/yum, /var/tmp, & /tmp are now).
    • /var/lib/NetworkManager (holds a timestamps file that is deleted and refreshed quite often, every 5 minutes)
    • /var/log/audit (holds the SELinux audit.log that records a great many file accesses.)
    • /var/spool/abrt (holds often large, error reports and core dumps). Users could be advised to act on any abrt reports in the current session or copy the reports to other permanent storage, such as in /home/ or external storage.
    • there may be other good candidates...

Merge overlay into new image

A new root filesystem image can be constructed by using some Device-mapper tools.

If one has sufficient free disk space available, typically on an attached hard drive, one can copy (and uncompress) the current filesystem to a working folder. (This may require, for example, 4.3 GiB of free space for Fedora 17 Live Desktop.)

Device-mapper's mirror target allows one to create a 'mirror' image of the LiveOS root filesystem (the snapshot based on the SquashFS and overlay device). The mirror image can be then be recompressed, and if one has an additional 660 MiB or more of free space (depending on how much software or other root filesystem files have been added) on your LiveOS device filesystem (the USB/SD card filesystem), one can delete the old SquashFS image and replace it with the recompressed version.

The snapshot overlay can then be reset before rebooting the LiveOS device.

The following Bash script demonstrates the process, where the $1 parameter is a mount point directory for a disk partition with sufficient storage capacity (a LiveOS folder will be created there for holding the mirrored filesystem), and $2 is the LiveOS device node name (such as, /run/initramfs/livedev, for the currently booted LiveOS image, or /dev/sdc1, for example, for an attached LiveOS device). Options xtrace and verbose have been set to aid debugging.

Warning (medium size).png
Test and practice the following script!
This procedure will delete the LiveOS filesystem before replacing it with a recompressed merged version. Be sure to verify that you will have sufficient space for the replacement before running the full script. (You could comment out the deletion, and squash into a directory on a large working drive to determine the new filesystem size.)
#!/bin/bash -xv
#
# Merge a LiveOS snapshot overlay into a new root filesystem, recompress it
# into a SquashFS image (if the source was so packaged), replace the source
# with the refresh, and reset the overlay.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


export PATH=/usr/sbin:$PATH
export \
   PS4='+(${SHLVL}:${LINENO}:${BASH_SOURCE}:${EUID}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -o errexit
set -o pipefail

t0=$(date +%s)

cleanup () {
    umount -l $SRCMNT
    rmdir $SRCMNT
    dt=$(($(date +%s)-t0))
    h=$((dt/3600))
    m=$((dt%3600/60))
    s=$((dt%60))
    printf '\nTotal time elapsed: %02d:%02d:%02d hh:mm:ss\n' $h $m $s
    [[ $1 == 0 ]] && exit 0 || exit 1
}

TMPDIR=$1
[[ ! -d $TMPDIR/LiveOS ]] && mkdir $TMPDIR/LiveOS 2>/dev/null

# Mount the source device and SquashFS.
SRCMNT=$(mktemp -d /run/media/XXXXXX)
mount $2 $SRCMNT

if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
    SQUASHMNT=$(mktemp -d /run/media/XXXXXX)
    mount $SRCMNT/LiveOS/squashfs.img $SQUASHMNT --read-only
    ORIGFS=$SQUASHMNT/LiveOS/ext3fs.img
    [[ ! -f $ORIGFS ]] && ORIGFS=$SQUASHMNT/LiveOS/rootfs.img
else
    ORIGFS=$SRCMNT/LiveOS/ext3fs.img
    [[ ! -f $ORIGFS ]] && ORIGFS=$SRCMNT/LiveOS/rootfs.img
fi

OVERLAY=/LiveOS/$(basename $SRCMNT/LiveOS/overlay-*)
if [[ -f $SRCMNT$OVERLAY ]]; then
    OVDEV=$(losetup -f --show $SRCMNT$OVERLAY --read-only)
else
    printf '\n  No persistent overlay for the filesystem was found.
    Exiting...\n'
    cleanup 1
fi

# >= Fedora 17
LiveOSMNT=/run/initramfs/live
# < Fedora 17
[[ -d /mnt/live/LiveOS ]] && LiveOSMNT=/mnt/live

# If we are processing a booted LiveOS device's root filesystem, then
if [[ $(mountpoint -x $2) == $(mountpoint -dq $LiveOSMNT) ]]; then
    # Remove live-osimg-min; free its loop devices.
    if [[ -e $SRCMNT/LiveOS/osmin.img ]]; then
        dmsetup remove live-osimg-min || :
        losetup -d /dev/loop1 || :
        losetup -d /dev/loop0 || :
    fi
else
    LiveOSMNT=''
fi
# Remove expiring osmin.img
rm $SRCMNT/LiveOS/osmin.img || :

# Prepare temporary devices for the Device-mapper mirror target.
FSTYPE=$(blkid -s TYPE -o value $ORIGFS || :)
FSLABEL=$(blkid -s LABEL -o value $ORIGFS || :)
stinfo=($(stat -c '%B %s %o' $ORIGFS || :))
BLOCKSZ=${stinfo[0]}
BLOCKS=$((${stinfo[1]}/$BLOCKSZ))
IOBLKSZ=${stinfo[2]}

NEWFS=$TMPDIR/LiveOS/rootfs.img
dd if=/dev/null of=$NEWFS count=1 bs=$BLOCKSZ seek=$BLOCKS
mkfs.$FSTYPE -F -L $FSLABEL -m 1 -b $IOBLKSZ $NEWFS
tune2fs -c0 -i0 -Odir_index -ouser_xattr,acl $NEWFS
NEWFSDEV=$(losetup -f --show $NEWFS)

roORIGFSDEV=$(losetup -f --show $ORIGFS --read-only)

table="0 $BLOCKS snapshot $roORIGFSDEV $OVDEV P 8"
dmsetup create ori --readonly --table "$table"

# Invoke mirror target device.
table="0 $BLOCKS mirror core 2 32 sync 2 /dev/mapper/ori 0 $NEWFSDEV 0"
dmsetup create mir --table "$table"

set +xv
# Wait for mirror completion.
while state=$(dmsetup status mir)
state=${state#*mirror 2 * * }
alloc=${state%/*}
size=${state#*/}
size=${size%% *}
[[ $alloc != $size ]]; do
    percent=$(dc <<< "8k 10 0.05 100 $alloc $size /*+*p")
    percent=$(dc <<< "1k $percent 10 /p")
    printf '\r  Mirroring %5.1f %% complete.  ' $percent
    printf '\b|'
    sleep 0.5
    printf '\b/'
    sleep 0.5
    printf '\b-'
    sleep 0.5
    printf '\b\'
    sleep 0.5
done
printf '\r  Mirroring 100 %% complete.    \n'
set -xv

# Check the new filesystem.
e2fsck -f -y $NEWFS || e2fsck -f -y $NEWFS

# Clean up.
dmsetup remove mir ori
sync

dt=$(($(date +%s)-t0))
h=$((dt/3600))
m=$((dt%3600/60))
s=$((dt%60))
printf '\nTime elapsed: %02d:%02d:%02d hh:mm:ss\n' $h $m $s

# Replace SquashFS or uncompressed root filesystem image.
if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
    umount -l $SQUASHMNT
    rm $SRCMNT/LiveOS/squashfs.img
    mksquashfs $TMPDIR/LiveOS $SRCMNT/LiveOS/squashfs.img -comp xz -keep-as-directory
else
    if [[ -x /usr/bin/rsync ]]; then
        rsync --inplace --progress $NEWFS $SRCMNT/LiveOS
    else
        cp $NEWFS $SRCMNT/LiveOS
    fi
fi

# Clean up.
losetup -d $OVDEV $NEWFSDEV $roORIGFSDEV
OVDEV=$(losetup -f --show $SRCMNT$OVERLAY)

# Reset overlay.
dd if=/dev/zero of=$OVDEV bs=64k count=1 conv=notrunc,fsync

# If we are processing a booted LiveOS device's root filesystem, then
if [[ -n $LiveOSMNT ]]; then
    # Try to unmount the TMPDIR.
    mountpoint $TMPDIR && umount -l $TMPDIR || :
    shutdown -r +1 'The system will reboot in 1 minute.'
else
    sleep 1
    losetup -d $OVDEV
fi
cleanup 0

Note: If the above script is invoked on a currently booted LiveOS root filesystem, the system will be scheduled for a reboot one minute after the script completes.

The Device-mapper snapshot-merge target also allows one to merge changes in a persistent snapshot into the original filesystem (See notes from Andrew Gilmore).

The mirror method copies and merges in one pass, while the snapshot-merge method copies the original filesystem first and then merges in the changes. I've found the mirror method to be about 15% faster.

Overlay recovery

Warning (medium size).png
Test and practice the following
This procedure is not thoroughly validated, and may destroy your data.

If one 'exhausts' the limited storage capacity of a LiveOS overlay, Device-mapper will mark the filesystem as 'Invalid', as shown by the dmsetup status command executed in Terminal or a console (if you haven't crashed):

# dmsetup status
live-osimg-min: 0 8388608 snapshot 2464/2464 24
live-rw: 0 8388608 snapshot Invalid

The invalid bit is 00 at byte 5 of the overlay. You might try to recover the overlay by switching it to 01 with the following command line:

# echo $'\x01' | dd of=/path/to/overlay-file bs=1 count=1 seek=4 conv=notrunc

where /path/to/overlay may be /mnt/live/LiveOS/overlay-devicename-discUUID or
/media/devicename/LiveOS/overlay-devicename-discUUID for an attached device.

Follow this by registering the LiveOS image with Device-mapper:

# mount /media/devicename/LiveOS/squashfs.img /mnt/some_mountpoint
# losetup /dev/loop1 /mnt/some_mountpoint/LiveOS/ext3fs.img -r
# losetup /dev/loop2 /media/devicename/LiveOS/overlay-devicename-discUUID
# dmsetup create devicename --table "0 8388608 snapshot 7:1 7:2 P 8"
  • devicename in the last line may be any string.
  • loop1 and loop2 (and the corresponding 7:1 7:2) may be any free loop devices; just substitute the appropriate numbers.
  • 8388608 is the size of the ext3fs.img file in 512 byte units. This can be read by the following command:
# blockdev -q --getsz /dev/loop1

Execute

# dmsetup status

to check the the virtual filesystem has been configured.

Then try to repair any damage with the following command:

# e2fsck -f -y /dev/mapper/devicename

where devicename is the string you used in the dmsetup create command.

Run a second check,

# e2fsck -p /dev/mapper/devicename

to verify if the filesystem could be repaired. At this point you will want to enlarge the overlay, or backup or rebuild the image.

Remove the virtual filesystem registration,

# dmsetup remove devicename

Determine the size of the overlay file:

# blockdev -q --getsz /dev/loop2
# losetup -d /dev/loop2
# losetup -d /dev/loop1
# dd if=/dev/zero of=/path/to/overlay-file seek=overlay_size count=size_increase

where overlay_size and size_increase are now 512 byte units.

Once you have a working filesystem, you should proceed to merge your overlay into the original filesystem as described above.

References

  1. http://people.gnome.org/~markmc/code/merge-dm-snapshot.c
  2. http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=blob;f=drivers/md/dm-snap-persistent.c;hb=HEAD
See this dm-devel thread.