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