Attached is a _first pass_ patch that enables LiveOS persistence for
livecd-tools. Before you read this and get _too_ excited, note that I'm really
only posting this because of the f8t1 devel freeze. If I get any encouragement,
I am very willing to work my ass off in the next few days to get this cleaned up
into respectable shape for a potential f8t1 feature. But I also realize it is
probably just too late for that. (OTOH the code is already structured so that it
is obvious that in the absence of a persistence bootarg, the code has no impact)
The Principals Of OPeration are-
- unless a boot argument of "persistence[=[devspec][:pathspec]]" is seen,
nothing will behave differently, except for the existence of a new tool
/usr/sbin/livetool
- after booting normally (no persistence bootarg), if you invoke
"/usr/sbin/livetool persistence initialize [devspec][:pathspec]"
then a persistence file will be initialized. By tomorrow I should have an
option that allows the existing in-ram-overlay to be live migrated to the new
file (thus freeing the ram by the time the command completes). I have done this
manually. Currently this tool is not implemented. Creating a sparse or zeros
file of any size (say 512M) should work fine.
e.g. dd if=/dev/zero of=/mnt/stick/LiveOS/Persistence-mylabel \
bs=1k count=1 seek=$(( 1024 * 512)
- to use the persistence file on a subsequent boot, add the bootarg
"persistence" which is equivalent to "persistence=auto"
- devspec can be in the following forms (should be obvious what they mean),
and defaults to auto, which means to search all mountable partitions. (the
search process mounts readonly (with paranoid blockdev --setro as well)
sda1
sdb
/dev/sdc3
LABEL=MyLabel
UUID=MyUUID
- pathspec defaults to /LiveOS/Persistence-LIVEOS_LABEL
(e.g. /LiveOS/Persistence-Fedora-7-Live-i386)
if pathspec does not start with a /, it prepends the above default.
(e.g. persistence=:dmc would mean to search all partitions for
/LiveOS/Persistence-Fedora-7-Live-i386-dmc)
if pathspec starts with a / then it is used as is. e.g.
persistence=:/home/dmc/testpers would search all partitions(and whole devices)
for /home/dmc/testpers )
To round out the examples, persistence=LABEL="my usb stick":/my/path/to/file
Finally: Known bugs:
1) I had to comment out the mayflower generated init's trap and set -e
2) ext3's inability to mounted readonly is annoying (yeah, I know norecovery or
ext2 will probably get it for me, still annoying)
3) choice handling is broken. Don't use auto when it will find more than one
entry. Maybe just don't use auto at all.
4) livetool doesn't do anything. For now, just create a sparse file of any
interesting length (512M is fine) as mentioned above.
Well, that about covers it for now. As always, comments, suggestions, and
criticisms will be greatly appreciated. (though feel free to wait 48 hours for
plenty of obvious improvements, such as fixing those known bugs).
"release early, release often"...
-dmc
diff -Naur livecd.git.20070723/creator/livecd-creator livecd/creator/livecd-creator
--- livecd.git.20070723/creator/livecd-creator 2007-07-23 02:39:15.000000000 -0500
+++ livecd/creator/livecd-creator 2007-07-24 03:35:57.000000000 -0500
@@ -768,6 +768,16 @@
"/usr/lib/livecd-creator/mayflower not found")
shutil.copy("/usr/lib/livecd-creator/mayflower",
"%s/install_root/sbin/mayflower" %(self.build_dir,))
+ if not os.path.isfile("/usr/lib/livecd-creator/livepersistence"):
+ raise InstallationError("livecd-creator not correctly installed : "+
+ "/usr/lib/livecd-creator/livepersistence not found")
+ shutil.copy("/usr/lib/livecd-creator/livepersistence",
+ "%s/install_root/sbin/livepersistence" %(self.build_dir,))
+ if not os.path.isfile("/usr/lib/livecd-creator/livetool"):
+ raise InstallationError("livecd-creator not correctly installed : "+
+ "/usr/lib/livecd-creator/livetool not found")
+ shutil.copy("/usr/lib/livecd-creator/livetool",
+ "%s/install_root/sbin/livetool" %(self.build_dir,))
# modules needed for booting (this is butt ugly and we need to retrieve this from elsewhere, e.g. the kernel)
mayflowerconf = open(self.build_dir + "/install_root/etc/mayflower.conf", "w")
mayflowerconf.write('MODULES+="cdrom ide-cd ahci loop dm_snapshot squashfs ext3 ext2 ehci_hcd uhci_hcd ohci_hcd usb_storage sd_mod sr_mod usbhid ata_piix vfat msdos "\n')
@@ -776,12 +786,14 @@
mayflowerconf.write('MODULES+="sata_promise sata_sil sata_sx4 sata_vsc "\n')
mayflowerconf.write('MODULES+="ata_generic pata_ali pata_amd pata_artop pata_atiixp pata_cmd64x pata_cs5520 pata_cs5530 pata_cs5535 pata_cypress pata_efar pata_hpt366 pata_hpt37x pata_hpt3x2n pata_hpt3x3 pata_isapnp pata_it821x pata_jmicron pata_marvell pata_mpiix pata_netcell pata_ns87410 pata_oldpiix pata_optidma pata_opti pata_pcmcia pata_pdc2027x pata_pdc202xx_old pata_qdi pata_serverworks pata_sil680 pata_sis pata_sl82c105 pata_triflex pata_via pdc_adma "\n')
mayflowerconf.write('MODULES+="sym53c8xx aic7xxx "\n')
+ mayflowerconf.write('MODULES+="fuse vfat "\n')
mayflowerconf.close()
subprocess.call(["/sbin/mayflower", "-f", "/boot/livecd-initramfs.img",
self.get_kernel_version()],
preexec_fn=self.run_in_root)
- for f in ("/sbin/mayflower", "/etc/mayflower.conf"):
+ for f in ("/sbin/mayflower", "/etc/mayflower.conf",
+ "/sbin/livepersistence"):
os.unlink("%s/install_root/%s" %(self.build_dir, f))
def relabelSystem(self):
diff -Naur livecd.git.20070723/creator/livepersistence livecd/creator/livepersistence
--- livecd.git.20070723/creator/livepersistence 1969-12-31 18:00:00.000000000 -0600
+++ livecd/creator/livepersistence 2007-07-24 03:36:31.000000000 -0500
@@ -0,0 +1,175 @@
+#!/bin/bash
+#
+# livepersistence - set up persistence (/dev/loop119) device
+#
+# Copyright 2007 Douglas McClendon <[EMAIL PROTECTED]>
+#
+# Licensed under the GPLv2. See the file COPYING for details.
+#
+
+#set -o verbose
+
+#
+# Note: this is a very ugly first pass at the moment
+#
+
+# this will be pulled by init's parsing of /proc/cmdline
+persistence=$1
+
+echo "persistence invoked"
+
+LIVEOS_SAFELABEL=$( vol_id -l /dev/root )
+
+# calculate pathspec
+if ( echo $pathspec | grep -q ":" ); then
+ pathspec=$( echo $persistence | sed -e 's/^.*://' )
+else
+ pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}"
+fi
+
+if [ ! -n "$pathspec" ]; then
+ pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}"
+elif [ "$pathspec" == "auto" ]; then
+ pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}"
+elif ( echo $pathspec | grep -q "/" ); then
+ pathspec="$pathspec"
+else
+ pathspec="/LiveOS/Persistence-${LIVEOS_SAFELABEL}-${pathspec}"
+fi
+
+# calculate devspec
+devspec=$( echo $persistence | sed -e 's/:.*$//' )
+if [ ! -n "$devspec" ]; then
+ devspec="auto"
+fi
+
+echo "DEBUG: parsed devspec is $devspec"
+echo "DEBUG: parsed pathspec is $pathspec"
+
+# load filesystem modules that may be required for persistence
+modprobe vfat
+# for ntfs
+modprobe fuse
+
+# check if devspec is auto
+numcandidates=0
+candidates=""
+if [ "$devspec" == "auto" ]; then
+ devices="$( ls /dev/sd* /dev/scd* 2> /dev/null )"
+# devices=""
+# devices="$devices /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sda4"
+# devices="$devices /dev/sdb /dev/sdb1 /dev/sdb2 /dev/sdb3 /dev/sdb4"
+# devices="$devices /dev/sdc /dev/sdc1 /dev/sdc2 /dev/sdc3 /dev/sdc4"
+# devices="$devices /dev/sr0 /dev/sr1 /dev/sr2 /dev/sr3"
+# devices="$devices /dev/scd0 /dev/scd1 /dev/scd2 /dev/scd3"
+ mkdir /testmount
+ for device in $devices; do
+ echo "DEBUG: about to test readonly on device $device"
+ if (( ! $( blockdev --getro $device ) )); then
+ blockdev --setro $device
+ echo "DEBUG: about to test mount persistence device $device"
+ fstype=$( vol_id -t $device )
+ if [ "$fstype" == "ntfs" ]; then
+ nflag=""
+ else
+ nflag="-n"
+ fi
+ if ( mount $nflag -o ro -t $fstype $device /testmount ); then
+ echo "DEBUG: about to look for /testmount/${pathspec} on $device"
+ if [ -f /testmount/${pathspec} ]; then
+ echo "DEBUG: found /testmount/${pathspec} on $device"
+ numcandidates=$(( $numcandidates + 1 ))
+ candidates="$candidates $device"
+ echo "DEBUG: numcandidates is now $numcandidates"
+ echo "DEBUG: candidates is now $candidates"
+ fi
+ umount /testmount
+ fi
+ blockdev --setrw $device
+ fi
+ done
+ rmdir /testmount
+
+ if [ $numcandidates -gt 1 ]; then
+ xdone=0
+ while (( ! $xdone )); do
+ echo -en "\n\n\nLiveOS Auto Persistence: multiple images found, plese select one:\n\n\n"
+ echo -en "choices:\n\n"
+ echo -en "0: ignore persistence images, create overlay in ram\n"
+ candidate_0=""
+ candidatenum=1
+ for candidate in $candidates; do
+ cfslabel="$( /sbin/vol_id -L $candidate )"
+ cuuid="$( /sbin/vol_id -u $candidate )"
+ cfstype="$( /sbin/vol_id -t $candidate )"
+ eval "candidate_${candidatenum}=${candidate}"
+ echo -en "${candidatenum}: ${candidate} LABEL=${cfslabel} FSTYPE=${cfstype} UUID=${cuuid}\n"
+ candidatenum=$(( $candidatenum + 1 ))
+ done
+ echo -en "\n\nchoice? "
+ read choice
+
+ eval "pdev=candidate_${choice}"
+ if (( ! $choice )); then
+ xdone=1
+ elif ( blockdev $pdev > /dev/null 2>&1 ); then
+ xdone=1
+ else
+ echo -en "\n\nInvalid Choice - Please Choose Again\n\n"
+ fi
+ done
+ elif [ $numcandidates -eq 0 ]; then
+ pdev=""
+ else
+ pdev=$candidates
+ fi
+else
+ # specific devspec given
+
+ # normalize devicename
+ #
+ # devspec may be of the following forms:
+ #
+ # /dev/sda1 # normalized form
+ # sda1
+ # LABEL=MyLABEL
+ # UUID=MyUUID
+ if ( echo $devspec | grep -q "^UUID=" ); then
+ cuuid=$( echo $devspec | sed -e 's/^UUID=//' )
+ pdev=$( findfs UUID=${cuuid} )
+ elif ( echo $devspec | grep -q "^LABEL=" ); then
+ clabel=$( echo $devspec | sed -e 's/^LABEL=//' )
+ pdev=$( findfs LABEL=${clabel} )
+ elif ( echo $devspec | grep -q '/' ); then
+ pdev=$devspec
+ else
+ pdev="/dev/${devspec}"
+ fi
+fi
+
+# now that we have the normalized reference to the persistence device
+# set it up
+echo "DEBUG: pdev is xx $pdev xx"
+pdev=$( echo $pdev | sed -e 's/^\s*//' | sed -e 's/\s*$//' )
+echo "DEBUG: now pdev is xx $pdev xx"
+mkdir /persistence
+echo "pdev is $pdev" > /persistence.pdev
+pmounted=0
+if ( blockdev $pdev > /dev/null 2>&1 ); then
+ echo "DEBUG: about to mount persistence device $pdev"
+ mount -n -t auto $pdev /persistence
+ pmounted=1
+fi
+
+if [ -w "/persistence${pathspec}" ]; then
+ echo "DEBUG: livepersistence, setting up persistence file"
+ losetup /dev/loop119 /persistence${pathspec}
+else
+ echo "DEBUG: livepersistence, aborting persistence file, setting up ram"
+ dd if=/dev/null of=/livepersistence_ram_overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
+ losetup /dev/loop119 /livepersistence_ram_overlay
+fi
+
+if (( $pmounted )); then
+ umount -l /persistence
+fi
diff -Naur livecd.git.20070723/creator/livetool livecd/creator/livetool
--- livecd.git.20070723/creator/livetool 1969-12-31 18:00:00.000000000 -0600
+++ livecd/creator/livetool 2007-07-24 03:36:41.000000000 -0500
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# livetool - manage special features of LiveOS environments
+#
+# Copyright 2007 Douglas McClendon <[EMAIL PROTECTED]>
+#
+# Licensed under the GPLv2. See the file COPYING for details.
+#
+
+# TODO: implement persistence file creation with dm-mirror
+
diff -Naur livecd.git.20070723/creator/mayflower livecd/creator/mayflower
--- livecd.git.20070723/creator/mayflower 2007-07-23 02:39:15.000000000 -0500
+++ livecd/creator/mayflower 2007-07-24 03:36:09.000000000 -0500
@@ -79,6 +79,16 @@
cp /sbin/dmsetup sbin
cp /bin/dd bin
+cp /lib/udev/vol_id sbin
+cp /sbin/findfs sbin
+cp /bin/sed bin
+cp /sbin/livepersistence sbin
+cp /sbin/mount.ntfs-fuse sbin
+cp /sbin/mount.ntfs-3g sbin
+cp /sbin/mount.ntfs sbin
+cp /usr/bin/fusermount bin
+cp /bin/rmdir bin
+
MODULES=
if [ -e /etc/mayflower.conf ] ; then
@@ -200,10 +210,10 @@
echo
bash
}
-trap "emergency_shell" 0 2
+#trap "emergency_shell" 0 2
# exit immediately if a command fails
-set -e
+#set -e
export PATH=/sbin:/bin
@@ -239,6 +249,7 @@
live_ram=0
check_iso=0
live_locale=""
+persistence=""
# Parse kernel commandline options
#
@@ -268,6 +279,12 @@
live_locale=*)
live_locale=\${o#live_locale=}
;;
+ persistence)
+ persistence=auto
+ ;;
+ persistence=*)
+ persistence=\${o#persistence=}
+ ;;
check)
check_iso=1
;;
@@ -557,8 +574,14 @@
# live cd helper function
do_live_from_loop121() {
# create a sparse file for the overlay
- dd if=/dev/null of=/overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
- losetup /dev/loop119 /overlay
+ if [ "x\${persistence}" != "x" ]; then
+ echo "DEBUG: about to run livepersistence"
+ /sbin/livepersistence "\$persistence"
+ echo "DEBUG: done running livepersistence"
+ else
+ dd if=/dev/null of=/overlay bs=1024 count=1 seek=$((512*1024)) 2> /dev/null
+ losetup /dev/loop119 /overlay
+ fi
# set up the snapshot
echo 0 \`blockdev --getsize /dev/loop121\` snapshot /dev/loop121 /dev/loop119 p 8 | dmsetup create live-rw
diff -Naur livecd.git.20070723/Makefile livecd/Makefile
--- livecd.git.20070723/Makefile 2007-07-23 02:39:15.000000000 -0500
+++ livecd/Makefile 2007-07-24 03:38:24.000000000 -0500
@@ -12,6 +12,8 @@
$(INSTALL_PROGRAM) -D creator/livecd-creator $(DESTDIR)/usr/bin/livecd-creator
$(INSTALL_PROGRAM) -D creator/isotostick.sh $(DESTDIR)/usr/bin/livecd-iso-to-disk
$(INSTALL_PROGRAM) -D creator/mayflower $(DESTDIR)/usr/lib/livecd-creator/mayflower
+ $(INSTALL_PROGRAM) -D creator/livepersistence $(DESTDIR)/usr/lib/livecd-creator/livepersistence
+ $(INSTALL_PROGRAM) -D creator/livetool $(DESTDIR)/usr/lib/livecd-creator/livetool
$(INSTALL_DATA) -D AUTHORS $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/AUTHORS
$(INSTALL_DATA) -D COPYING $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/COPYING
$(INSTALL_DATA) -D README $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/README
--
Fedora-livecd-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/fedora-livecd-list