123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- #!/bin/ash
- #2007 Lesser GPL licence v2 (http://www.fsf.org/licensing/licenses/lgpl.html)
- #Barry Kauler www.puppylinux.com
- #called from savepuppyd and rc.shutdown, to save tmpfs layer to permanent flash storage.
- #updated 13 Sept 2007. copy-down only. flushing is done in petget.
- #updated 24 Sept 2007. removed '-u' option when copy-down files.
- #8 oct 2007: screen out /root/tmp when saving.
- #4 nov 2007: reintroduce '-u' copy option.
- #v4.01 19may2008 BK: now called from /sbin/pup_eventd daemon (savepuppyd now history).
- #v4.01 19may2008 BK: if called from pup_eventd then X running: graceful exit if X shutdown.
- #v409 BK: XRUNNING test should be 'pup_event_frontend_d'.
- #v409 BK: save /var dir. previously screened out to save space, but prevents crontab from running.
- #v412 /etc/DISTRO_SPECS, renamed pup_xxx.sfs, pup_save.2fs etc.
- #w000 pup files renamed to woofr555.sfs, woofsave.2fs.
- #w003 bug fix for .wh.__dir_opaque whiteout file.
- #w003 screened out some dirs in /dev that should not be saved.
- #v424 fix for more layers in unionfs/aufs.
- #100222 shinobar: possible timezone problem with BOOTCONFIG. more file exclusions.
- #100422 added ^root/ftpd exclusion.
- #100429 modify 'trash' exclusion.
- #100820 added /var/tmp exclusion (apparently filled by opera crashes).
- #101221 yaf-splash fix.
- #110206 Dougal: clean up some testing. speedup: LANG=C, also change to /bin/ash.
- #110212 recent aufs: .wh.__dir_opaque name changed to .wh..wh..opq.
- #110212 Jemimah: files may disappear, more efficient calc of free space, fix i/o err.
- #110222 shinobar: remove all /dev, allow 'pup_ro10-19', exit code for no space
- #110224 BK: revert remove all /dev, for now. 110503 added dev/snd
- #110505 support sudo for non-root user.
- #111229 rerwin: fix jemimah code (110212).
- #120103 rerwin: screen out /.XLOADED when save.
- #140102 SFR: various fixes + gettext
- #140512 SFR: performance improvements
- [ "`whoami`" != "root" ] && exec sudo -A ${0} ${@} #110505
- export TEXTDOMAIN=snapmergepuppy
- export OUTPUT_CHARSET=UTF-8
- OLDLANG="$LANG"
- export LANG=C #110206 Dougal: I **think** this should not cause problems with filenames
- #variables created at bootup by 'init' script in initramfs...
- . /etc/rc.d/PUPSTATE
- . /etc/DISTRO_SPECS #v412
- SAVEPART="`echo -n "$PUPSAVE" | cut -f 1 -d ','`"
- #v3.02 first time, do not use '-u' option when saving, save everything...
- NEXTPASSTHRU=""
- [ -e /tmp/flagnextpassthru ] && NEXTPASSTHRU="yes"
- RUNPS="`ps`"
- SHUTDOWN="no"
- [ "`echo "$RUNPS" | grep 'rc.shutdown'`" != "" ] && SHUTDOWN="yes"
- XRUNNING="no"
- [ "`echo "$RUNPS" | grep 'pup_event_frontend_d'`" != "" ] && XRUNNING="yes"
- PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R7/bin"
- WD="`pwd`"
- SNAP="/initrd/pup_rw"
- cd $SNAP || exit 1
- if [ "$SAVE_LAYER" ]; then #defined in PUPSTATE
- BASE="/initrd${SAVE_LAYER}"
- else
- BASE="/initrd/pup_ro1"
- fi
- # Precautions
- [ $PUPMODE -eq 3 -o $PUPMODE -eq 7 -o $PUPMODE -eq 13 ] || { echo "Wrong PUPMODE ($PUPMODE)!"; exit 1; }
- mountpoint -q "$BASE" || { echo "$BASE is not mounted!"; exit 1; }
- echo "Merging $SNAP onto $BASE..."
- # =============================================================================
- # WHITEOUTS
- # =============================================================================
- SFSPoints=$( grep -o -E "/initrd/pup_ro[0-9]+" /proc/mounts |sort -t o -k2 -nu ) #110206 Dougal: get a list of the sfs mountpoints SFR: increase amount of mountpoints (sfs_load can load >=10)
- find . -mount \( -regex '.*/\.wh\.[^/]*' -type f \) | sed -e 's/\.\///;s/\.wh\.//' |
- while read -r N
- do
- DN="${N%/*}"
- BN="${N##*/}"
- [ "$DN" = "$N" ] || [ "$DN" = "" ] && DN="."
- [ "$DN" = "." ] && continue
- [ "$BN" = ".wh.aufs" ] && continue #w003 aufs has file .wh..wh.aufs in /initrd/pup_rw.
- #110212 unionfs and early aufs: '.wh.__dir_opaque' marks ignore all contents in lower layers...
- if [ "$BN" = "__dir_opaque" ];then #w003
- #'.wh.__dir_opaque' marks ignore all contents in lower layers...
- rm -rf "${BASE}/${DN}" 2>/dev/null #wipe anything in save layer. 110212 delete entire dir.
- mkdir -p "${BASE}/${DN}" #jemimah: files sometimes mysteriously reappear if you don't delete and recreate the directory, aufs bug? 111229 rerwin: need -p, may have to create parent dir.
- #also need to save the whiteout file to block all lower layers (may be readonly)...
- touch "${BASE}/${DN}/.wh.__dir_opaque" 2>/dev/null
- rm -f "$SNAP/$DN/.wh.__dir_opaque" #should force aufs layer "reval".
- continue
- fi
- #110212 recent aufs: .wh.__dir_opaque name changed to .wh..wh..opq ...
- if [ "$BN" = ".wh..opq" ] ; then
- rm -rf "${BASE}/${DN}" 2>/dev/null #wipe anything in save layer.
- mkdir -p "${BASE}/${DN}" #jemimah: files sometimes mysteriously reappear if you don't delete and recreate the directory, aufs bug? 111229 rerwin: need -p, may have to create parent dir.
- #also need to save the whiteout file to block all lower layers (may be readonly)...
- touch "${BASE}/${DN}/.wh..wh..opq" 2>/dev/null
- rm -f "$SNAP/$DN/.wh..wh..opq" #should force aufs layer "reval".
- continue
- fi
- #comes in here with the '.wh.' prefix stripped off, leaving actual filename...
- rm -rf "$BASE/$N"
-
- #if file exists on a lower layer, have to save the whiteout file...
- #110206 Dougal: speedup and refine the search...
- for P in $SFSPoints
- do
- if [ -e "$P/$N" ] || [ -L "$P/$N" ] ; then # SFR: broken symlinks also deserve to be processed ( '-e' won't detect them, needs to be also '-L')
- [ -d "${BASE}/${DN}" ] || mkdir -p "${BASE}/${DN}"
- touch "${BASE}/${DN}/.wh.${BN}"
- break
- fi
- done #110206 End Dougal.
- rm -f "$SNAP/$DN/.wh.$BN" #remove whiteout file. should force aufs layer "reval".
- done
- # =============================================================================
- # DIRECTORIES
- # =============================================================================
- #110224 BK revert, leave save of /dev in for now, just take out some subdirs... 110503 added dev/snd
- find . -mount -type d | tail +2 | sed -e 's/\.\///' | grep -v -E '^mnt|^initrd|^proc|^sys|^tmp|^root/tmp|^\.wh\.|/\.wh\.|^dev/\.|^dev/fd|^dev/pts|^dev/shm|^dev/snd|^var/tmp' |
- while read -r N
- do
- #v4.01 graceful exit if shutdown X (see /usr/X11R7/bin/restartwm,wmreboot,wmpoweroff)...
- [ "$XRUNNING" = "yes" ] && [ -f /tmp/wmexitmode.txt ] && exit
- mkdir -p "$BASE/$N"
- #i think nathan advised this, to handle non-root user (SFR: improved/simplified)
- chmod "$BASE/$N" --reference="$N"
- OWNERSHIP="`stat --format=%u:%g "$N"`"
- chown $OWNERSHIP "$BASE/$N"
- touch "$BASE/$N" --reference="$N"
- done
- # =============================================================================
- # FILES
- # =============================================================================
- #100222 a quick hack: BOOTCONFIG written to in init, before timezone set, can cause trouble...
- touch /etc/rc.d/BOOTCONFIG
- FREEBASE=`df -B 1 | grep -w "$BASE"| head -n 1 | tr -s ' ' | cut -f 4 -d ' '` #110212 Jemimah #110222 shinobar # SFR: result in bytes (see 'find' below)
- rm -f /tmp/snapmergepuppy-nospace #110222 shinobar
- rm -f /tmp/snapmergepuppy-error #140102 SFR
- #Copy Files... v409 remove '^var'. w003 screen out some /dev files. 100222 shinobar: more exclusions. 100422 added ^root/ftpd. 100429 modify 'trash' exclusion. 100820 added var/tmp #110224 BK: revert, leave save of /dev in for now... 120103 rerwin: add .XLOADED # SFR: added dev/snd # SFR: added .crdownload
- # SFR: move as much as possible into 'find' itself
- # Limitation - files with newline (\n) in its name are processed wrong (but this is not a new issue)
- find . -mount \
- -not -path . \
- -not -type d \
- -regextype posix-extended \
- -not \( -regex '.*/\.wh\.[^\]*' -type f \) \
- -not \( -regex '^./mnt.*|^./initrd.*|^./proc.*|^./sys.*|^./tmp.*|^./pup_.*|^./zdrv_.*|^./root/tmp.*|.*_zdrv_.*|^./dev/\..*|^./dev/fd.*|^./dev/pts.*|^./dev/snd.*|^./dev/shm.*|^./\.wh\..*|^./var/run.*|^./root/ftpd.*|^./var/tmp.*|.*\.XLOADED$' \) \
- -not \( -regex '.*\.thumbnails.*|.*\.part$|.*\.crdownload$' \) \
- -printf "%s %C@ %P\n" |
- while read -r NSIZE NCTIME N
- do
- #v4.01 graceful exit if shutdown X (see /usr/X11R7/bin/restartwm,wmreboot,wmpoweroff)...
- [ "$XRUNNING" = "yes" ] && [ -f /tmp/wmexitmode.txt ] && exit
- ([ ! -e "$N" ] && [ ! -L "$N" ]) && continue # SFR: skip non-existing files (btw, '-e' won't detect broken symlinks, so '-L' is necessary!)
- #stop saving if not enough room left in ${DISTRO_FILE_PREFIX}save file...
- if [ $((NSIZE+204800)) -gt $FREEBASE ]; then # 204800 = 200K slack space
- FREEBASE=`df -B 1 | grep -w "$BASE" | head -n 1 | tr -s ' ' | cut -f 4 -d ' '` #110212 Jemimah: this is very slow; try not to check every iteration #110222 shinobar: fix for pup_ro10 and more
- if [ $((NSIZE+204800)) -gt $FREEBASE ]; then #110212 Jemimah.
- touch /tmp/snapmergepuppy-nospace #110222 shinobar
- break
- fi
- else
- FREEBASE=$((FREEBASE-NSIZE)) #110212 Jemimah: keep track of the worst case
- fi
-
- ##v2.21 -u causes trouble if timezone malconfigured...
- [ -L "$BASE/$N" ] && rm -f "$BASE/$N"
- if [ -L "$N" -o "$NEXTPASSTHRU" = "" ];then
- #link, or first run of snapmergepuppy. no '-u' (update) option.
- [ -L "$N" ] && [ -d "$BASE/$N" ] && rm -rf "$BASE/$N" # SFR: in case if folder has been replaced with a symlink (cp won't overwrite a dir with a symlink)
- cp -a -f "$N" "$BASE/$N" 2>>/tmp/snapmergepuppy-error
- else
- [ ! -e "$BASE/$N" ] || [ ${NCTIME%%.*} -gt `stat -c %Z "$BASE/$N"` ] && cp -a -f "$N" "$BASE/$N" 2>>/tmp/snapmergepuppy-error
- fi
- DN="${N%/*}" #111229 rerwin: bugfix for jemimah code (110212) (SFR: improved performance)
- BN="${N##*/}" #111229 "
- [ "$DN" = "$N" ] || [ "$DN" = "" ] && DN="."
- [ -e "$BASE/$DN/.wh.${BN}" ] && rm "$BASE/$DN/.wh.${BN}" #110212 jemimah bugfix - I/O errors if you don't do this
- done
- # =============================================================================
- touch /tmp/flagnextpassthru
- # SFR: fix for .wh files not being created (in some cases) in pup_rw
- if [ "`lsmod | grep "^aufs" `" != "" ]; then
- # force re-evalution of all the layers
- busybox mount -t aufs -o remount,udba=reval unionfs /
- fi
- sync
- cd "$WD"
- # =============================================================================
- error_msg () {
- if [ "$SHUTDOWN" = "no" -a "$XRUNNING" = "yes" ];then
- export DISPLAY=':0'
- /usr/lib/gtkdialog/box_splash -timeout 30 -close box -icon gtk-dialog-warning -bg red -text "$1"
- else
- echo "$1"
- fi
- }
- export LANG="$OLDLANG"
- ERRSTATUS=0
- if [ -f /tmp/snapmergepuppy-nospace ]; then #110222 shinobar
- ERRMSG="$(gettext 'WARNING!
- Unable to save all files. You need to delete some.')"
- error_msg "$ERRMSG"
- ERRSTATUS=1
- fi
- if [ -s /tmp/snapmergepuppy-error ]; then #140102 SFR
- ERRMSG="$(gettext "WARNING!
- There were some errors detected.
- (see '/tmp/snapmergepuppy-error' for details)
- Filesystem check of the savefile (pfix=fsck) is highly recommended.")"
- error_msg "$ERRMSG"
- ERRSTATUS=1
- fi
- exit $ERRSTATUS
- # =============================================================================
|