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