Applied patch from Jesse W. Hathaway <jesse@mbuki-mvuki.org> to move cow mount rather...
[live-boot-grml.git] / scripts / live
1 #!/bin/sh
2
3 # set -e
4
5 export PATH="/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:/usr/bin:/usr/sbin:/bin:/sbin"
6
7 echo "/root/lib" >> /etc/ld.so.conf
8 echo "/root/usr/lib" >> /etc/ld.so.conf
9
10 mountpoint="/live/image"
11 LIVE_MEDIA_PATH="live"
12
13 root_persistence="live-rw"
14 home_persistence="home-rw"
15 root_snapshot_label="live-sn"
16 home_snapshot_label="home-sn"
17
18 USERNAME="user"
19 USERFULLNAME="Live user"
20 HOSTNAME="host"
21 BUILD_SYSTEM="Custom"
22
23 mkdir -p "${mountpoint}"
24
25 [ -f /etc/live.conf ] && . /etc/live.conf
26 export USERNAME USERFULLNAME HOSTNAME BUILD_SYSTEM
27
28 . /scripts/live-helpers
29
30 if [ ! -f /live.vars ]
31 then
32         touch /live.vars
33 fi
34
35 Arguments ()
36 {
37         PRESEEDS=""
38
39         for ARGUMENT in $(cat /proc/cmdline)
40         do
41                 case "${ARGUMENT}" in
42                         access=*)
43                                 ACCESS="${ARGUMENT#access=}"
44                                 export ACCESS
45                                 ;;
46
47                         console=*)
48                                 DEFCONSOLE="${ARGUMENT#*=}"
49                                 export DEFCONFSOLE
50                                 ;;
51
52                         debug)
53                                 DEBUG="Yes"
54                                 export DEBUG
55
56                                 set -x
57                                 ;;
58
59                         fetch=*)
60                                 FETCH="${ARGUMENT#fetch=}"
61                                 export FETCH
62                                 ;;
63
64                         hostname=*)
65                                 HOSTNAME="${ARGUMENT#hostname=}"
66                                 LIVECONF="changed"
67                                 export HOSTNAME LIVECONF
68                                 ;;
69
70                         username=*)
71                                 USERNAME="${ARGUMENT#username=}"
72                                 LIVECONF="changed"
73                                 export USERNAME LIVECONF
74                                 ;;
75
76                         userfullname=*)
77                                 USERFULLNAME="${ARGUMENT#userfullname=}"
78                                 LIVECONF="changed"
79                                 export USERFULLNAME LIVECONF
80                                 ;;
81
82                         ip=*)
83                                 STATICIP="${ARGUMENT#ip=}"
84
85                                 if [ -z "${STATICIP}" ]
86                                 then
87                                         STATICIP="frommedia"
88                                 fi
89
90                                 export STATICIP
91                                 ;;
92
93                         keyb=*|kbd-chooser/method=*)
94                                 KBD="${ARGUMENT#*=}"
95                                 export KBD
96                                 ;;
97
98                         klayout=*|console-setup/layoutcode=*)
99                                 KLAYOUT="${ARGUMENT#*=}"
100                                 export KLAYOUT
101                                 ;;
102
103                         kvariant=*|console-setup/variantcode=*)
104                                 KVARIANT="${ARGUMENT#*=}"
105                                 export KVARIANT
106                                 ;;
107
108                         kmodel=*|console-setup/modelcode=*)
109                                 KMODEL="${ARGUMENT#*=}"
110                                 export KMODEL
111                                 ;;
112
113                         koptions=*)
114                                 KOPTIONS="${ARGUMENT#koptions=}"
115                                 export KOPTIONS
116                                 ;;
117
118                         live-getty)
119                                 LIVE_GETTY="1"
120                                 export LIVE_GETTY
121                                 ;;
122
123                         live-media=*|bootfrom=*)
124                                 LIVE_MEDIA="${ARGUMENT#*=}"
125                                 export LIVE_MEDIA
126                                 ;;
127
128                         live-media-encryption=*|encryption=*)
129                                 LIVE_MEDIA_ENCRYPTION="${ARGUMENT#*=}"
130                                 export LIVE_MEDIA_ENCRYPTION
131                                 ;;
132
133                         live-media-offset=*)
134                                 LIVE_MEDIA_OFFSET="${ARGUMENT#live-media-offset=}"
135                                 export LIVE_MEDIA_OFFSET
136                                 ;;
137
138                         live-media-path=*)
139                                 LIVE_MEDIA_PATH="${ARGUMENT#live-media-path=}"
140                                 export LIVE_MEDIA_PATH
141                                 ;;
142
143                         live-media-timeout=*)
144                                 LIVE_MEDIA_TIMEOUT="${ARGUMENT#live-media-timeout=}"
145                                 export LIVE_MEDIA_TIMEOUT
146                                 ;;
147
148                         locale=*|debian-installer/locale=*)
149                                 LOCALE="${ARGUMENT#*=}"
150                                 export LOCALE
151                                 ;;
152
153                         module=*)
154                                 MODULE="${ARGUMENT#module=}"
155                                 export MODULE
156                                 ;;
157
158                         netboot=*)
159                                 NETBOOT="${ARGUMENT#netboot=}"
160                                 export NETBOOT
161                                 ;;
162
163                         nfsopts=*)
164                                 NFSOPTS="${ARGUMENT#nfsopts=}"
165                                 export NFSOPTS
166                                 ;;
167
168                         noaccessibility)
169                                 NOACCESSIBILITY="Yes"
170                                 export NOACCESSIBILITY
171                                 ;;
172
173                         noapparmor)
174                                 NOAPPARMOR="Yes"
175                                 export NOAPPARMOR
176                                 ;;
177
178                         noaptcdrom)
179                                 NOAPTCDROM="Yes"
180                                 export NOAPTCDROM
181                                 ;;
182
183                         noautologin)
184                                 NOAUTOLOGIN="Yes"
185                                 export NOAUTOLOGIN
186                                 ;;
187
188                         noxautologin)
189                                 NOXAUTOLOGIN="Yes"
190                                 export NOXAUTOLOGIN
191                                 ;;
192
193                         noconsolekeyboard)
194                                 NOCONSOLEKEYBOARD="Yes"
195                                 export NOCONSOLEKEYBOARD
196                                 ;;
197
198                         nofastboot)
199                                 NOFASTBOOT="Yes"
200                                 export NOFASTBOOT
201                                 ;;
202
203                         nofstab)
204                                 NOFSTAB="Yes"
205                                 export NOFSTAB
206                                 ;;
207
208                         nognomepanel)
209                                 NOGNOMEPANEL="Yes"
210                                 export NOGNOMEPANEL
211                                 ;;
212
213                         nohosts)
214                                 NOHOSTS="Yes"
215                                 export NOHOSTS
216                                 ;;
217
218                         nokpersonalizer)
219                                 NOKPERSONALIZER="Yes"
220                                 export NOKPERSONALIZER
221                                 ;;
222
223                         nokwallet)
224                                 NOKWALLET="Yes"
225                                 export NOKWALLET
226                                 ;;
227
228                         nolanguageselector)
229                                 NOLANGUAGESELECTOR="Yes"
230                                 export NOLANGUAGESELECTOR
231                                 ;;
232
233                         nolocales)
234                                 NOLOCALES="Yes"
235                                 export NOLOCALES
236                                 ;;
237
238                         nonetworking)
239                                 NONETWORKING="Yes"
240                                 export NONETWORKING
241                                 ;;
242
243                         nopowermanagement)
244                                 NOPOWERMANAGEMENT="Yes"
245                                 export NOPOWERMANAGEMENT
246                                 ;;
247
248                         noprogramcrashes)
249                                 NOPROGRAMCRASHES="Yes"
250                                 export NOPROGRAMCRASHES
251                                 ;;
252
253                         norestrictedmanager)
254                                 NORESTRICTEDMANAGER="Yes"
255                                 export NORESTRICTEDMANAGER
256                                 ;;
257
258                         nosudo)
259                                 NOSUDO="Yes"
260                                 export NOSUDO
261                                 ;;
262
263                         noswap)
264                                 NOSWAP="Yes"
265                                 export NOSWAP
266                                 ;;
267
268                         noupdatenotifier)
269                                 NOUPDATENOTIFIER="Yes"
270                                 export NOUPDATENOTIFIER
271                                 ;;
272
273                         nouser)
274                                 NOUSER="Yes"
275                                 export NOUSER
276                                 ;;
277
278                         noxautoconfig)
279                                 NOXAUTOCONFIG="Yes"
280                                 export NOXAUTOCONFIG
281                                 ;;
282
283                         noxscreensaver)
284                                 NOXSCREENSAVER="Yes"
285                                 export NOXSCREENSAVER
286                                 ;;
287
288                         persistent)
289                                 PERSISTENT="Yes"
290                                 export PERSISTENT
291                                 ;;
292
293                         nopersistent)
294                                 NOPERSISTENT="Yes"
295                                 export NOPERSISTENT
296                                 ;;
297
298                         preseed/file=*|file=*)
299                                 LOCATION="${ARGUMENT#*=}"
300                                 export LOCATION
301                                 ;;
302
303                         nopreseed)
304                                 NOPRESEED="Yes"
305                                 export NOPRESEED
306                                 ;;
307
308                         url=*)
309                                 location="${ARGUMENT#url=}"
310
311                                 mount -n -o bind /sys /root/sys
312                                 mount -n -o bind /proc /root/proc
313                                 mount -n -o bind /dev /root/dev
314
315                                 mkdir -p /root/var/run/network
316                                 chroot /root ifup -a
317                                 chroot /root wget -P /tmp "${location}"
318                                 chroot /root ifdown -a
319
320                                 umount /root/sys
321                                 umount /root/proc
322                                 umount /root/dev
323
324                                 LOCATION="/tmp/$(basename "${location}")"
325                                 ;;
326
327                         */*=*)
328                                 question="${ARGUMENT%%=*}"
329                                 value="${ARGUMENT#*=}"
330                                 PRESEEDS="${PRESEEDS}\"${question}=${value}\" "
331                                 export PRESEEDS
332                                 ;;
333
334                         showmounts)
335                                 SHOWMOUNTS="Yes"
336                                 export SHOWMOUNTS
337                                 ;;
338
339                         timezone=*)
340                                 TIMEZONE="${ARGUMENT#timezone=}"
341                                 export TIMEZONE
342                                 ;;
343
344                         notimezone)
345                                 NOTIMEZONE="Yes"
346                                 export NOTIMEZONE
347                                 ;;
348
349                         todisk=*)
350                                 TODISK="${ARGUMENT#todisk=}"
351                                 export TODISK
352                                 ;;
353
354                         toram)
355                                 TORAM="Yes"
356                                 export TORAM
357                                 ;;
358
359                         toram=*)
360                                 TORAM="Yes"
361                                 MODULETORAM="${ARGUMENT#toram=}"
362                                 export TORAM MODULETORAM
363                                 ;;
364
365                         union=*)
366                                 UNIONTYPE="${ARGUMENT#union=}"
367                                 export UNIONTYPE
368                                 ;;
369
370                         utc=*)
371                                 UTC="${ARGUMENT#utc=}"
372                                 export UTC
373                                 ;;
374
375                         xdebconf)
376                                 XDEBCONF="Yes"
377                                 export XDEBCONF
378                                 ;;
379
380                         xvideomode=*)
381                                 XVIDEOMODE="${ARGUMENT#xvideomode=}"
382                                 export XVIDEOMODE
383                                 ;;
384                 esac
385         done
386
387         # sort of compatibility with netboot.h from linux docs
388         if [ -z "${NETBOOT}" ]
389         then
390                 if [ "${ROOT}" = "/dev/nfs" ]
391                 then
392                         NETBOOT="nfs"
393                         export NETBOOT
394                 elif [ "${ROOT}" = "/dev/cifs" ]
395                 then
396                         NETBOOT="cifs"
397                         export NETBOOT
398                 fi
399         fi
400
401         if [ -z "${MODULE}" ]
402         then
403                 MODULE="filesystem"
404                 export MODULE
405         fi
406
407         if [ -z "${UNIONTYPE}" ]
408         then
409                 UNIONTYPE="unionfs"
410                 export UNIONTYPE
411         fi
412 }
413
414 is_live_path ()
415 {
416         DIRECTORY="${1}"
417
418         if [ -d "${DIRECTORY}"/"${LIVE_MEDIA_PATH}" ]
419         then
420                 for FILESYSTEM in squashfs ext2 ext3 xfs dir
421                 do
422                         if [ "$(echo ${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM})" != "${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM}" ]
423                         then
424                                 return 0
425                         fi
426                 done
427         fi
428
429         return 1
430 }
431
432 get_backing_device ()
433 {
434         case "${1}" in
435                 *.squashfs|*.ext2|*.ext3)
436                         echo $(setup_loop "${1}" "loop" "/sys/block/loop*" '0' "${LIVE_MEDIA_ENCRYPTION}")
437                         ;;
438
439                 *.dir)
440                         echo "directory"
441                         ;;
442
443                 *)
444                         panic "Unrecognized live filesystem: ${1}"
445                         ;;
446         esac
447 }
448
449 match_files_in_dir ()
450 {
451         # Does any files match pattern ${1} ?
452         local pattern="${1}"
453
454         if [ "$(echo ${pattern})" != "${pattern}" ]
455         then
456                 return 0
457         fi
458
459         return 1
460 }
461
462 mount_images_in_directory ()
463 {
464         directory="${1}"
465         rootmnt="${2}"
466
467         if match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.squashfs" ||
468                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext2" ||
469                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext3" ||
470                 match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.dir"
471         then
472                 setup_unionfs "${directory}/${LIVE_MEDIA_PATH}" "${rootmnt}"
473         else
474                 :
475         fi
476 }
477
478 is_nice_device ()
479 {
480         sysfs_path="${1#/sys}"
481
482         if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-[ide|scsi|usb])"
483         then
484                 return 0
485         fi
486
487         return 1
488 }
489
490 is_supported_fs ()
491 {
492         # FIXME: do something better like the scan of supported filesystems
493         fstype="${1}"
494
495         case ${fstype} in
496                 vfat|iso9660|udf|ext2|ext3|ntfs)
497                         return 0
498                         ;;
499         esac
500
501         return 1
502 }
503
504 copy_live_to ()
505 {
506         copyfrom="${1}"
507         copytodev="${2}"
508         copyto="${copyfrom}_swap"
509
510         if [ -z "${MODULETORAM}" ]
511         then
512                 size=$(fs_size "" ${copyfrom} "used")
513         else
514                 MODULETORAMFILE="${copyfrom}/${LIVE_MEDIA_PATH}/${MODULETORAM}"
515
516                 if [ -f "${MODULETORAMFILE}" ]
517                 then
518                         size=$( expr $(ls -la ${MODULETORAMFILE} | awk '{print $5}') / 1024 + 5000 )
519                 else
520                         log_warning_msg "Error: toram-module ${MODULETORAM} (${MODULETORAMFILE}) could not be read."
521                         return 1
522                 fi
523         fi
524
525         if [ "${copytodev}" = "ram" ]
526         then
527                 # copying to ram:
528                 freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ) )
529                 mount_options="-o size=${size}k"
530                 free_string="memory"
531                 fstype="tmpfs"
532                 dev="/dev/shm"
533         else
534                 # it should be a writable block device
535                 if [ -b "${copytodev}" ]
536                 then
537                         dev="${copytodev}"
538                         free_string="space"
539                         fstype=$(get_fstype "${dev}")
540                         freespace=$(fs_size "${dev}")
541                 else
542                         [ "$quiet" != "y" ] && log_warning_msg "${copytodev} is not a block device."
543                         return 1
544                 fi
545         fi
546
547         if [ "${freespace}" -lt "${size}" ]
548         then
549                 [ "${quiet}" != "y" ] && log_warning_msg "Not enough free ${free_string} (${freespace}k free, ${size}k needed) to copy live media in ${copytodev}."
550                 return 1
551         fi
552
553         # begin copying (or uncompressing)
554         mkdir "${copyto}"
555         echo "mount -t ${fstype} ${mount_options} ${dev} ${copyto}"
556         mount -t "${fstype}" ${mount_options} "${dev}" "${copyto}"
557
558         if [ "${extension}" = "tgz" ]
559         then
560                 cd "${copyto}"
561                 tar zxf "${copyfrom}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})"
562                 rm -f "${copyfrom}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})"
563                 mount -r --move "${copyto}" "${rootmnt}"
564                 cd "${OLDPWD}"
565         else
566                 if [ -n "${MODULETORAMFILE}" ]
567                 then
568                         cp ${MODULETORAMFILE} ${copyto} # copy only the filesystem module
569                 else
570                         cp -a ${copyfrom}/* ${copyto}   # "cp -a" from busybox also copies hidden files
571                 fi
572
573                 livefs_root
574                 umount ${copyfrom}
575                 mount -r --move ${copyto} ${copyfrom}
576         fi
577
578         rmdir ${copyto}
579         return 0
580 }
581
582 do_netmount ()
583 {
584         rc=1
585
586         modprobe "${MP_QUIET}" af_packet # For DHCP
587
588         udevtrigger
589         udevsettle
590
591         ipconfig ${DEVICE} | tee /netboot.config
592
593         # source relevant ipconfig output
594         OLDHOSTNAME=${HOSTNAME}
595         . /tmp/net-${DEVICE}.conf
596         [ -z ${HOSTNAME} ] && HOSTNAME=${OLDHOSTNAME}
597         export HOSTNAME
598
599         if [ "${NFSROOT}" = "auto" ]
600         then
601                 NFSROOT=${ROOTSERVER}:${ROOTPATH}
602         fi
603
604         if [ -n "${FETCH}" ] && do_httpmount
605         then
606                 rc=0
607                 return ${rc}
608         fi
609
610         if [ "${NFSROOT#*:}" = "${NFSROOT}" ] && [ "$NETBOOT" != "cifs" ]
611         then
612                 NFSROOT=${ROOTSERVER}:${NFSROOT}
613         fi
614
615         [ "${quiet}" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
616
617         if [ "${NETBOOT}" != "nfs" ] && do_cifsmount
618         then
619                 rc=0
620         elif do_nfsmount
621         then
622                 NETBOOT="nfs"
623                 export NETBOOT
624                 rc=0
625         fi
626
627         [ "${quiet}" != "y" ] && log_end_msg
628         return ${rc}
629 }
630
631 do_httpmount ()
632 {
633         rc=1
634         extension=$(echo "${FETCH}" | sed 's/\(.*\)\.\(.*\)/\2/')
635
636         case "${extension}" in
637                 squashfs|tgz|tar)
638                         [ "${quiet}" != "y" ] && log_begin_msg "Trying wget ${FETCH} -O ${mountpoint}/$(basename ${FETCH})"
639                         mkdir -p "${mountpoint}/${LIVE_MEDIA_PATH}"
640                         wget "${FETCH}" -O "${mountpoint}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})"
641                         [ ${?} -eq 0 ] && rc=0
642                         [ "${extension}" = "tgz" ] && live_dest="ram"
643                         ;;
644
645                 *)
646                         [ "${quiet}" != "y" ] && log_begin_msg "Unrecognized archive extension for ${FETCH}"
647         esac
648
649         return ${rc}
650 }
651
652 do_nfsmount ()
653 {
654         rc=1
655
656         modprobe "${MP_QUIET}" nfs
657
658         if [ -z "${NFSOPTS}" ]
659         then
660                 NFSOPTS=""
661         fi
662
663         [ "${quiet}" != "y" ] && log_begin_msg "Trying nfsmount -o nolock -o ro ${NFSOPTS} ${NFSROOT} ${mountpoint}"
664
665         # FIXME: This for loop is an ugly HACK round an nfs bug
666         for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13
667         do
668                 nfsmount -o nolock -o ro ${NFSOPTS} "${NFSROOT}" "${mountpoint}" && rc=0 && break
669                 sleep 1
670         done
671
672         return ${rc}
673 }
674
675 do_cifsmount ()
676 {
677         rc=1
678
679         if [ -x "/sbin/mount.cifs" ]
680         then
681                 if [ -z "${NFSOPTS}" ]
682                 then
683                         CIFSOPTS="-ouser=root,password="
684                 else
685                         CIFSOPTS="${NFSOPTS}"
686                 fi
687
688                 [ "${quiet}" != "y" ] && log_begin_msg "Trying mount.cifs ${NFSROOT} ${mountpoint} ${CIFSOPTS}"
689                 modprobe "${MP_QUIET}" cifs
690
691                 if mount.cifs "${NFSROOT}" "${mountpoint}" "${CIFSOPTS}"
692                 then
693                         rc=0
694                 fi
695         fi
696
697         return ${rc}
698 }
699
700 do_snap_copy ()
701 {
702         fromdev="${1}"
703         todir="${2}"
704         snap_type="${3}"
705         size=$(fs_size "${fromdev}" "" "used")
706
707         if [ -b "${fromdev}" ]
708         then
709                 # look for free mem
710                 if [ -n "${HOMEMOUNTED}" -a "${snap_type}" = "HOME" ]
711                 then
712                         todev=$(cat /proc/mounts | grep -s " $(base_path ${todir}) " | awk '{print $1}' )
713                         freespace=$(df -k  | grep -s ${todev} | awk '{print $4}')
714                 else
715                         freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ))
716                 fi
717
718                 tomount="/mnt/tmpsnap"
719
720                 if [ ! -d "${tomount}" ]
721                 then
722                         mkdir -p "${tomount}"
723                 fi
724
725                 fstype=$(get_fstype "${fromdev}")
726
727                 if [ -n "${fstype}" ]
728                 then
729                         # Copying stuff...
730                         mount -t "${fstype}" -o ro "${fromdev}" "${tomount}"
731                         cp -a "${tomount}"/* ${todir}
732                         umount "${tomount}"
733                 else
734                         log_warning_msg "Unrecognized fstype: ${fstype} on ${fromdev}:${snap_type}"
735                 fi
736
737                 rmdir "${tomount}"
738
739                 if echo ${fromdev} | grep -qs loop
740                 then
741                         losetup -d "${fromdev}"
742                 fi
743
744                 return 0
745         else
746                 return 1
747
748                 [ "${quiet}" != "y" ] && log_warning_msg "Unable to find the snapshot ${snap_type} medium"
749         fi
750 }
751
752 try_snap ()
753 {
754         # Look for ${snap_label}.* in block devices and copy the contents to ${snap_mount}
755         # and remember the device and filename for resync on exit in live-initramfs.init
756
757         snap_label="${1}"
758         snap_mount="${2}"
759         snap_type="${3}"
760         snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2 ${snap_label}.ext3")
761
762         if [ ! -z "${snapdata}" ]
763         then
764                 snapdev="$(echo ${snapdata} | cut -f1 -d ' ')"
765                 snapback="$(echo ${snapdata} | cut -f2 -d ' ')"
766                 snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
767
768                 if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\|ext3\)'
769                 then
770                         # squashfs or ext2/ext3 snapshot
771                         dev=$(get_backing_device "${snapback}/${snapfile}")
772
773                         if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"
774                         then
775                                 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
776                                 return 1
777                         fi
778                 else
779                         # cpio.gz snapshot
780                         if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d 2>/dev/null)
781                         then
782                                 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
783                                 return 1
784                         fi
785                 fi
786
787                 umount "${snapback}"
788         else
789                 dev=$(find_cow_device "${snap_label}")
790
791                 if [ -b ${dev} ]
792                 then
793                         if echo "${dev}" | grep -qs loop
794                         then
795                                 # strange things happens, user confused?
796                                 snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' )
797                                 snapfile=$(basename ${snaploop})
798                                 snapdev=$(cat /proc/mounts | awk '{print $2,$1}' | grep -es "^$( dirname ${snaploop} )" | cut -f2 -d ' ')
799                         else
800                                 snapdev="${dev}"
801                         fi
802
803                         if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"
804                         then
805                                 log_warning_msg "Impossible to include the ${snap_label} Snapshot"
806                                 return 1
807                         else
808                                 if [ -n "${snapfile}" ]
809                                 then
810                                         # it was a loop device, user confused
811                                         umount ${snapdev}
812                                 fi
813                         fi
814                 else
815                         log_warning_msg "Impossible to include the ${snap_label} Snapshot"
816                         return 1
817                 fi
818         fi
819
820         echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/live.conf # for resync on reboot/halt
821         return 0
822 }
823
824 setup_unionfs ()
825 {
826         image_directory="${1}"
827         rootmnt="${2}"
828
829         modprobe "${MP_QUIET}" -b ${UNIONTYPE}
830
831         # run-init can't deal with images in a subdir, but we're going to
832         # move all of these away before it runs anyway.  No, we're not,
833         # put them in / since move-mounting them into / breaks mono and
834         # some other apps.
835
836         croot="/"
837
838         # Let's just mount the read-only file systems first
839         rofsstring=""
840         rofslist=""
841         minor_kernel_version=$(uname -r|cut -c 5-|sed 's/[^0-9].*//')
842
843         if [ "${NETBOOT}" = "nfs" ] && [ "${minor_kernel_version}" -lt 22 ]
844         then
845                 # go aroung a bug in nfs-unionfs locking for unionfs <= 1.4
846                 roopt="nfsro"
847         else
848                 roopt="ro"
849         fi
850
851         # Read image names from ${MODULE}.module if it exists
852         if [ -e "${image_directory}/filesystem.${MODULE}.module" ]
853         then
854                 for IMAGE in $(cat ${image_directory}/filesystem.${MODULE}.module)
855                 do
856                         image_string="${image_string} ${image_directory}/${image}"
857                 done
858         elif [ -e "${image_directory}/${MODULE}.module" ]
859         then
860                 for IMAGE in $(cat ${image_directory}/${MODULE}.module)
861                 do
862                         image_string="${image_string} ${image_directory}/${image}"
863                 done
864         else
865                 # ${MODULE}.module does not exist, create a list of images
866                 for FILESYSTEM in squashfs ext2 ext3 xfs dir
867                 do
868                         for IMAGE in "${image_directory}"/*."${FILESYSTEM}"
869                         do
870                                 if [ -e "${IMAGE}" ]
871                                 then
872                                         image_string="${image_string} ${IMAGE}"
873                                 fi
874                         done
875                 done
876
877                 # Now sort the list
878                 image_string="$(echo ${image_string} | sed -e 's/ /\n/g' | sort )"
879         fi
880
881         [ -n "${MODULETORAMFILE}" ] && image_string="${image_directory}/$(basename ${MODULETORAMFILE})"
882
883         mkdir -p "${croot}"
884
885         for image in ${image_string}
886         do
887                 imagename=$(basename "${image}")
888
889                 if [ -d "${image}" ]
890                 then
891                         # it is a plain directory: do nothing
892                         rofsstring="${image}=${roopt}:${rofsstring}"
893                         rofslist="${image} ${rofslist}"
894                 elif [ -f "${image}" ]
895                 then
896                         backdev=$(get_backing_device "${image}")
897                         fstype=$(get_fstype "${backdev}")
898
899                         if [ "${fstype}" = "unknown" ]
900                         then
901                                 panic "Unknown file system type on ${backdev} (${image})"
902                         fi
903
904                         mkdir -p "${croot}/${imagename}"
905                         echo "debug: Can not mount backdev ${backdev} (image = ${image}) on croot/imagename ${croot}/${imagename}"
906                         mount -t "${fstype}" -o ro "${backdev}" "${croot}/${imagename}" || panic "Can not mount ${backdev} (${image}) on ${croot}/${imagename}" && rofsstring="${croot}/${imagename}=${roopt}:${rofsstring}" && rofslist="${croot}/${imagename} ${rofslist}"
907                 fi
908         done
909
910         rofsstring=${rofsstring%:}
911
912         mkdir -p /cow
913         cowdevice="tmpfs"
914         cow_fstype="tmpfs"
915
916         # Looking for "${root_persistence}" device or file
917         if [ -n "${PERSISTENT}" ]
918         then
919                 cowprobe=$(find_cow_device "${root_persistence}")
920
921                 if [ -b "${cowprobe}" ]
922                 then
923                         cowdevice=${cowprobe}
924                         cow_fstype=$(get_fstype "${cowprobe}")
925                 else
926                         [ "${quiet}" != "y" ] && log_warning_msg "Unable to find the persistent medium"
927                 fi
928         fi
929
930         mount ${cowdevice} -t ${cow_fstype} -o rw /cow || panic "Can not mount ${cowdevice} on /cow"
931
932         mount -t ${UNIONTYPE} -o dirs=/cow=rw:${rofsstring} ${UNIONTYPE} "${rootmnt}" || panic "${UNIONTYPE} mount failed"
933
934         # Adding other custom mounts
935         if [ -n "${PERSISTENT}" ]
936         then
937                 # directly mount /home
938                 # FIXME: add a custom mounts configurable system
939                 homecow=$(find_cow_device "${home_persistence}" )
940
941                 if [ -b "${homecow}" ]
942                 then
943                         mount -t $(get_fstype "${homecow}") -o rw "${homecow}" "${rootmnt}/home"
944                         export HOMEMOUNTED=1 # used to proper calculate free space in do_snap_copy()
945                 else
946                         [ "${quiet}" != "y" ] && log_warning_msg "Unable to find the persistent home medium"
947                 fi
948
949                 # Look for other snapshots to copy in
950                 try_snap "${root_snapshot_label}" "${rootmnt}" "ROOT"
951                 try_snap "${home_snapshot_label}" "${rootmnt}/home" "HOME"
952         fi
953
954         if [ -n "${SHOWMOUNTS}" ]
955         then
956                 for d in ${rofslist}
957                 do
958                         mkdir -p "${rootmnt}/live/${d##*/}"
959
960                         case d in
961                                 *.dir)
962                                         # do nothing # mount -o bind "${d}" "${rootmnt}/live/${d##*/}"
963                                         ;;
964
965                                 *)
966                                         mount --move "${d}" "${rootmnt}/live/${d##*/}"
967                                         ;;
968                         esac
969                 done
970         fi
971
972         # shows cow fs on /cow for use by live-snapshot
973         mkdir -p "${rootmnt}/live/cow"
974         mount -o move /cow "${rootmnt}/live/cow"
975 }
976
977 check_dev ()
978 {
979         sysdev="${1}"
980         devname="${2}"
981
982         if [ -z "${devname}" ]
983         then
984                 devname=$(sys2dev "${sysdev}")
985         fi
986
987         if [ -n "${LIVE_MEDIA_OFFSET}" ]
988         then
989                 loopdevname=$(setup_loop "${devname}" "loop" "/sys/block/loop*" "${LIVE_MEDIA_OFFSET}" '')
990                 devname="${loopdevname}"
991         fi
992
993         fstype=$(get_fstype "${devname}")
994
995         if is_supported_fs ${fstype}
996         then
997                 mount -t ${fstype} -o ro "${devname}" ${mountpoint} || continue
998
999                 if is_live_path ${mountpoint}
1000                 then
1001                         echo ${mountpoint}
1002                         return 0
1003                 else
1004                         umount ${mountpoint}
1005                 fi
1006         fi
1007
1008         if [ -n "${LIVE_MEDIA_OFFSET}" ]
1009         then
1010                 losetup -d "${loopdevname}"
1011         fi
1012
1013         return 1
1014 }
1015
1016 find_livefs ()
1017 {
1018         timeout="${1}"
1019
1020         # first look at the one specified in the command line
1021         if [ ! -z "${LIVE_MEDIA}" ]
1022         then
1023                 if check_dev "null" "${LIVE_MEDIA}"
1024                 then
1025                         return 0
1026                 fi
1027         fi
1028
1029         # don't start autodetection before timeout has expired
1030         if [ -n "${LIVE_MEDIA_TIMEOUT}" ]
1031         then
1032                 if [ "${timeout}" -lt "${LIVE_MEDIA_TIMEOUT}" ]
1033                 then
1034                         return 1
1035                 fi
1036         fi
1037
1038         # or do the scan of block devices
1039         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram)
1040         do
1041                 devname=$(sys2dev "${sysblock}")
1042                 fstype=$(get_fstype "${devname}")
1043
1044                 if /lib/udev/cdrom_id ${devname} > /dev/null
1045                 then
1046                         if check_dev "null" "${devname}"
1047                         then
1048                                 return 0
1049                         fi
1050                 elif is_nice_device "${sysblock}"
1051                 then
1052                         for dev in $(subdevices "${sysblock}")
1053                         do
1054                                 if check_dev "${dev}"
1055                                 then
1056                                         return 0
1057                                 fi
1058                         done
1059                 elif [ "${fstype}" = "squashfs" -o \
1060                         "${fstype}" = "ext2" -o \
1061                         "${fstype}" = "ext3" ]
1062                 then
1063                         # This is an ugly hack situation, the block device has
1064                         # an image directly on it.  It's hopefully
1065                         # live-initramfs, so take it and run with it.
1066                         ln -s "${devname}" "${devname}.${fstype}"
1067                         echo "${devname}.${fstype}"
1068                         return 0
1069                 fi
1070         done
1071
1072         return 1
1073 }
1074
1075 pulsate ()
1076 {
1077         if [ -x /sbin/usplash_write ]
1078         then
1079                 /sbin/usplash_write "PULSATE"
1080         fi
1081 }
1082
1083 set_usplash_timeout ()
1084 {
1085         if [ -x /sbin/usplash_write ]
1086         then
1087                 /sbin/usplash_write "TIMEOUT 120"
1088         fi
1089 }
1090
1091 mountroot ()
1092 {
1093         exec 6>&1
1094         exec 7>&2
1095         exec > live.log
1096         exec 2>&1
1097
1098         Arguments
1099
1100         set_usplash_timeout
1101         [ "${quiet}" != "y" ] && log_begin_msg "Running /scripts/live-premount"
1102         pulsate
1103         run_scripts /scripts/live-premount
1104         [ "${quiet}" != "y" ] && log_end_msg
1105
1106         # Needed here too because some things (*cough* udev *cough*)
1107         # changes the timeout
1108
1109         set_usplash_timeout
1110
1111         if [ ! -z "${NETBOOT}" ] || [ ! -z "${FETCH}" ]
1112         then
1113                 if do_netmount
1114                 then
1115                         livefs_root="${mountpoint}"
1116                 else
1117                         panic "Unable to find a live file system on the network"
1118                 fi
1119         else
1120                 # Scan local devices for the image
1121                 for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1122                 do
1123                         livefs_root=$(find_livefs ${i})
1124
1125                         if [ -n "${livefs_root}" ]
1126                         then
1127                                 break
1128                         fi
1129
1130                         sleep 1
1131                 done
1132         fi
1133
1134         if [ -z "${livefs_root}" ]
1135         then
1136                 panic "Unable to find a medium containing a live file system"
1137         fi
1138
1139         if [ "${TORAM}" ]
1140         then
1141                 live_dest="ram"
1142         elif [ "${TODISK}" ]
1143         then
1144                 live_dest="${TODISK}"
1145         fi
1146
1147         if [ "${live_dest}" ]
1148         then
1149                 log_begin_msg "Copying live media to ${live_dest}"
1150                 copy_live_to "${livefs_root}" "${live_dest}"
1151                 log_end_msg
1152         fi
1153
1154         if [ -n "${MODULETORAMFILE}" ]
1155         then
1156                 setup_unionfs "${livefs_root}" "${rootmnt}"
1157         else
1158                 mount_images_in_directory "${livefs_root}" "${rootmnt}"
1159         fi
1160
1161         log_end_msg
1162
1163         maybe_break live-bottom
1164         [ "${quiet}" != "y" ] && log_begin_msg "Running /scripts/live-bottom"
1165
1166         pulsate
1167         run_scripts /scripts/live-bottom
1168         [ "${quiet}" != "y" ] && log_end_msg
1169
1170         exec 1>&6 6>&-
1171         exec 2>&7 7>&-
1172         cp live.log "${rootmnt}/var/log/"
1173 }