b228a77f9074f19b921af63e8ed4595b793a81da
[genkernel.git] / defaults / initrd.scripts
1 #!/bin/ash
2
3 . /etc/initrd.defaults
4
5 backup() {
6         echo -ne "\033[0G\033[0K"
7 }
8
9 parse_opt() {
10         case "$1" in
11                 *\=*)
12                         echo "$1" | cut -d= -f2-
13                 ;;
14         esac
15 }
16
17 modules_load() {
18         for module in $*
19         do
20                 echo ${module} >> /etc/modules/extra_load
21         done
22
23         modules_scan extra_load
24 }
25
26 modules_scan() {
27         local MODS
28         [ -d "/etc/modules/${1}" ] || touch /etc/modules/${1}
29
30         [ -f "/etc/modules/${1}" ] && MODS=`cat /etc/modules/${1}`
31         for x in ${MODS}
32         do
33                 MLOAD=`echo ${MLIST} | sed -e "s/.*${x}.*/${x}/"`
34                 if [ "${MLOAD}" = "${x}" ] # Only module to no-load
35                 then
36                         echo -e "${BOLD}   ::${NORMAL} Skipping ${x}..."
37                 elif [ "${MLOAD}" = "${MLIST}" ] # == No change == No specified no-load
38                 then
39                         [ -n "${DEBUG}" ] && echo -ne "${BOLD}   ::${NORMAL} Checking for ${x}..."
40                         # find -name does not work since the return status is always zero
41                         if find /lib/modules/${KV} | grep /"${x}${KSUFF}" >/dev/null 2>&1
42                         then
43                                 echo -ne "${BOLD}   ::${NORMAL} Scanning for ${x}..."
44                                 modprobe ${x} -n
45                                 backup
46                                 echo -ne "${NORMAL}"
47                         fi
48                 else
49                         echo -e "${BOLD}   ::${NORMAL} Skipping ${x}..."
50                 fi
51         done
52 }
53
54 uppercase(){
55         # needs tr on busybox
56         echo $1 | tr 'a-z' 'A-Z'
57 }
58
59
60 findmediamount() {
61         # $1 = mount dir name / media name
62         # $2 = recognition file
63         # $3 = variable to have the device path
64         # $4 = directory before /mnt, like NEW_ROOT
65         # args remaining are possible devices 
66
67         local media=$1 recon=$2 vrbl=$3
68         local mntdir="${4}/mnt/${media}"
69         shift 4
70
71         good_msg "Looking for the ${media}" ${CRYPT_SILENT}
72
73         if [ "$#" -gt "0" ]
74         then
75                 [ ! -d "${mntdir}" ] && mkdir -p ${mntdir} 2>/dev/null >/dev/null
76                 if [ -n "${ISOBOOT}" ]
77                 then
78                         mntcddir="${mntdir%${media}}iso"
79                         if [ ! -f ${mntcddir} ]
80                         then
81                                 mkdir ${mntcddir}
82                         fi
83                 else
84                         mntcddir=${mntdir}
85                 fi
86
87                 for x in $*
88                 do
89                         # Check for a block device to mount
90                         if [ -b "${x}" ]
91                         then
92                                 skip=0
93                                 bsn=`basename "${x}"`
94                                 #
95                                 # If disk and it has at least one partition, skip.
96                                 # We use /sys/block/${bsn}/${bsn}[0-9]* to make sure that we
97                                 # don't skip device mapper devices. Even the craziest scenario
98                                 # deserves a fair chance.
99                                 #
100                                 for part in `ls /sys/block/${bsn}/${bsn}[0-9]* 2>/dev/null`
101                                 do
102                                         skip=1
103                                         break;
104                                 done
105                                 if [ ${skip} -eq 1 ]
106                                 then
107                                         continue
108                                 fi
109                                 good_msg "Attempting to mount media:- ${x}" ${CRYPT_SILENT}
110
111 #                               if [ "${media}" = "cdrom" ]; then
112 #                                       mount -r -t iso9660 ${x} ${mntdir} &>/dev/null
113 #                               else
114 #                                       mount -r -t auto ${x} ${mntdir} &>/dev/null
115 #                               fi
116                                 mount -r -t ${CDROOT_TYPE} ${x} ${mntcddir} >/dev/null 2>&1
117                                 if [ "$?" = '0' ]
118                                 then
119                                         if [ -n "${ISOBOOT}" ]; then
120                                                 if [ -f ${mntcddir}/${ISOBOOT} ]; then
121                                                         mount -o loop ${mntcddir}/${ISOBOOT} ${mntdir}
122                                                         if [ "$?" = "0" ]; then
123                                                                 good_msg "iso mounted on ${mntdir}"
124                                                         fi
125                                                 fi
126                                         fi
127
128                                         # Check for the media
129                                         if [ -f "${mntdir}/${recon}" ]
130                                         then
131                                                 #set REAL_ROOT, CRYPT_ROOT_KEYDEV or whatever ${vrbl} is
132                                                 eval ${vrbl}'='"${x}"
133                                                 good_msg "Media found on ${x}" ${CRYPT_SILENT}
134                                                 break
135                                         else
136                                                 umount ${mntcddir}
137                                         fi
138                                 fi
139                         fi
140                 done
141         fi
142
143         eval local result='$'${vrbl}
144
145         [ -n "${result}" ] || bad_msg "Media not found" ${CRYPT_SILENT}
146 }
147
148 devicelist(){
149         # Locate the cdrom device with our media on it.
150         # CDROM DEVICES
151         local DEVICES="/dev/cdroms/* /dev/ide/cd/* /dev/sr*"
152         # USB Keychain/Storage
153         DEVICES="$DEVICES /dev/sd*"
154         # IDE devices
155         DEVICES="$DEVICES /dev/hd*"
156         # USB using the USB Block Driver
157         DEVICES="$DEVICES /dev/ubd* /dev/ubd/*"
158         # iSeries devices
159         DEVICES="$DEVICES /dev/iseries/vcd*"
160         echo ${DEVICES}
161 }
162
163 bootstrapCD() {
164         local DEVICES=`devicelist`
165         # The device was specified on the command line, so there's no need to scan
166         # a bunch of extra devices
167         [ -n "${CDROOT_DEV}" ] && DEVICES="${CDROOT_DEV}"
168
169         findmediamount "cdrom" "${SUBDIR}/livecd" "REAL_ROOT" "${NEW_ROOT}" ${DEVICES}
170 }
171
172 bootstrapKey() {
173         # $1 = ROOT/SWAP
174         local KEYDEVS=`devicelist`
175         eval local keyloc='"${CRYPT_'${1}'_KEY}"'
176
177         findmediamount "key" "${keyloc}" "CRYPT_${1}_KEYDEV" "" ${KEYDEVS}
178 }
179
180 cache_cd_contents() {
181         # Check loop file exists and cache to ramdisk if DO_cache is enabled
182         if [ "${LOOPTYPE}" != "noloop" ] && [ "${LOOPTYPE}" != "sgimips" ]
183         then
184                 check_loop
185                 if [ "${DO_cache}" ]
186                 then
187                         # TODO: Check the size of the image versus the size of our tmpfs
188                         # along with the amount of available RAM and increase tmpfs size
189                         # if necessary. (Not having awk sucks...)
190                         # z=0
191                         # for i in $(cat /proc/meminfo | grep -e ^MemFree -e ^Cached | \
192                         # cut -d: -f2 | cut -dk -f1 | sed -e "s/^\s*//") ; do
193                         # z=$(($z + $i)) ; done
194                         # echo $z
195                         good_msg "Copying loop file for caching..."
196                         # Verify that the needed directory exists
197                         mkdir -p "$(dirname ${NEW_ROOT}/mnt/${LOOP})"
198                         cp -a ${NEW_ROOT}/mnt/cdrom/${LOOP} ${NEW_ROOT}/mnt/${LOOP}
199                         if [ $? -ne 0 ]
200                         then
201                                 bad_msg "Failed to cache the loop file! Lack of space?"
202                                 rm -rf ${NEW_ROOT}/mnt/livecd.* 2>/dev/null
203                                 rm -rf ${NEW_ROOT}/mnt/image.* 2>/dev/null
204                                 rm -rf ${NEW_ROOT}/mnt/zisofs 2>/dev/null
205                         else
206                                 LOOPEXT='../'
207                         fi
208                 fi
209         fi
210 }
211
212 mount_sysfs() {
213         mount -t sysfs sysfs /sys -o noexec,nosuid,nodev >/dev/null 2>&1
214         ret=$?
215         [ ${ret} -eq 0 ] || bad_msg "Failed to mount /sys!"
216 }
217
218 findnfsmount() {
219         if [ "${IP}" != '' ] || busybox udhcpc -n -T 15 -q
220         then
221                 [ -e /rootpath ] && NFSROOT=`cat /rootpath`
222
223                 if [ "${NFSROOT}" = '' ]
224                 then
225                         # Obtain NFSIP  
226                         OPTIONS=`busybox dmesg | grep rootserver | sed -e "s/,/ /g"`
227                         for OPTION in $OPTIONS
228                         do
229                                 if [ `echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 1` = 'rootserver' ]
230                                 then
231                                         NFSIP=`echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 2`
232                                 fi 
233                         done
234                         
235                         # Obtain NFSPATH
236                         OPTIONS=`busybox dmesg | grep rootpath | sed -e "s/,/ /g"`      
237                         for OPTION in $OPTIONS
238                         do
239                                 if [ `echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 1` = 'rootpath' ]
240                                 then
241                                         NFSPATH=`echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 2`
242                                 fi
243                         done
244
245                         # Setup NFSROOT
246                         if [ "${NFSIP}" != '' ] && [ "$NFSPATH" != '' ]
247                         then
248                                 NFSROOT="${NFSIP}:${NFSPATH}"
249                         else
250                                 bad_msg "The DHCP Server did not send a valid root-path."
251                                 bad_msg "Please check your DHCP setup, or provide a nfsroot=<...> parameter."
252                         fi
253                 fi
254
255                 if [ "${NFSROOT}" != '' ]
256                 then
257                         NFSOPTIONS=${NFSROOT#*,}
258                         NFSROOT=${NFSROOT%%,*}
259                         if [ "${NFSOPTIONS}" = "${NFSROOT}" ]
260                         then
261                                 NFSOPTIONS=$DEFAULT_NFSOPTIONS
262                         else
263                                 NFSOPTIONS="${DEFAULT_NFSOPTIONS},${NFSOPTIONS}"
264                         fi
265
266                         if [ "${CDROOT}" != '0' ]
267                         then
268                                 good_msg "Attempting to mount NFS CD image on ${NFSROOT} with options ${NFSOPTIONS}"
269                                 mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${NEW_ROOT}/mnt/cdrom
270                                 if [ "$?" = '0' ]
271                                 then
272                                         REAL_ROOT="/dev/nfs"
273                                 else
274                                         bad_msg "NFS Mounting failed. Is the path corrent ?"
275                                 fi
276                         else    
277                                 good_msg "Attempting to mount NFS root on ${NFSROOT} with options ${NFSOPTIONS}"
278                                 mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${NEW_ROOT}
279                                 if [ "$?" = '0' ]
280                                 then
281                                         REAL_ROOT="/dev/nfs"
282                                 else
283                                         bad_msg "NFS Mounting failed. Is the path correct ?"
284                                 fi
285                                 # FIXME: Need to start portmap and the other rpc daemons in
286                                 # order to remount rw.
287                         fi
288
289                 fi
290         fi
291 }
292
293 check_loop() {
294         if [ "${LOOP}" = '' -o ! -e "mnt/cdrom/${LOOP}" ]
295         then
296         
297                 bad_msg "Invalid loop location: ${LOOP}"
298                 bad_msg 'Please export LOOP with a valid location, or reboot and pass a proper loop=...'
299                 bad_msg 'kernel command line!'
300         
301                 run_shell
302         fi
303 }
304
305 run_shell() {
306         /bin/ash
307 }
308
309 runmdev() {
310         # Use devtmpfs if enabled in kernel,
311         # else tmpfs. Always run mdev just in case
312         devfs=tmpfs
313         if grep -qs devtmpfs /proc/filesystems ; then
314                 devfs=devtmpfs
315         fi
316
317         # Options copied from /etc/init.d/udev-mount, should probably be kept in sync
318         mount -t $devfs -o "exec,nosuid,mode=0755,size=10M" udev /dev \
319                 || bad_msg "Failed to mount /dev as ${devfs}"
320
321         # http://git.busybox.net/busybox/plain/docs/mdev.txt
322         mkdir /dev/pts
323         mount -t devpts devpts /dev/pts  || bad_msg "Failed to mount /dev/pts"
324         mdev -s  || bad_msg "Failed to receive dynamic updates from mdev"
325 }
326
327 test_success() {
328         retcode=$?
329         # If last command failed send error message and fall back to a shell    
330         if [ "$retcode" != '0' ]
331         then
332                 error_string=$1
333                 error_string="${error_string:-run command}"
334                 bad_msg 'Failed to $1; failing back to the shell...'
335                 run_shell
336         fi
337 }
338
339
340 # msg functions arguments
341 # $1 string
342 # $2 hide flag
343
344 good_msg() {    
345         msg_string=$1
346         msg_string="${msg_string:-...}"
347         [ "$2" != 1 ] && echo -e "${GOOD}>>${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
348 }
349
350 bad_msg() {
351         msg_string=$1
352         msg_string="${msg_string:-...}"
353         if [ "$2" != 1 ]
354         then
355                 splash 'verbose' > /dev/null &
356                 echo -e "${BAD}!!${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
357         fi
358
359
360 warn_msg() {
361         msg_string=$1
362         msg_string="${msg_string:-...}"
363         [ "$2" != 1 ] && echo -e "${WARN}**${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
364 }
365
366 crypt_filter() {
367         if [ "${CRYPT_SILENT}" = '1' ]
368         then
369                 eval $1 >/dev/null 2>/dev/null
370         else
371                 splash 'verbose' > /dev/null &
372                 eval $1
373                 if [ $? -eq 0 ]
374                 then
375                         splash set_msg 'Disk unlocked.'
376                 fi
377         fi
378 }
379
380 whereis(){
381         # $1 = variable whose value is the path (examples: "REAL_ROOT",
382         #      "LUKS_KEYDEV")
383         # $2 = label
384         # $3 = optional explanations for failure
385
386         eval local oldvalue='$'${1}
387
388         [ \( $# != 2 \) -a \( $# != 3 \) ] && \
389                 bad_msg "Bad invocation of function whereis, please file a bug \
390                 report with this message" && exit 1
391         [ -n "${3}" ] && local explnt=" or : ${3}" || local explnt="."
392         
393         bad_msg "Could not find the ${2} in ${oldvalue}${explnt}"
394         echo '   Please specify another value or: press Enter for the same, type "shell" for a shell, or "q" to skip...'
395         echo -n "${2}(${oldvalue}) :: "
396         read ${1}
397         case `eval echo '$'${1}` in
398                 'q')
399                         eval ${1}'='${oldvalue}
400                         warn_msg "Skipping step, this will likely cause a boot failure."
401                         break
402                         ;;
403                 'shell')
404                         eval ${1}'='${oldvalue}
405                         echo "To leave and try again just press <Ctrl>+D"
406                         run_shell
407                         ;;
408                 '')
409                         eval ${1}'='${oldvalue}
410                         ;;
411         esac
412 }
413
414 setup_hotplug() {
415         if [ "${KV_2_6_OR_GREATER}" ]
416         then
417                 echo /sbin/mdev > /proc/sys/kernel/hotplug
418         fi
419 }
420
421 setup_slowusb() {
422         # This function removes unset DO_slowusb if there is no usb-storage attached.
423         # If noslowusb is set, skip this function
424         [ "${DO_slowusb}" ] || return
425
426         # Unset DO_slowusb, so we can set it again if usb-storage has something attached
427         unset DO_slowusb
428
429         local usb_storage_dir="/sys/bus/usb/drivers/usb-storage"
430         if [ ! -d "${usb_storage_dir}" ]
431         then
432                 # no automated slowusb required. no usb-storage devices attached.
433                 return
434         fi
435         for x in "${usb_storage_dir}"/*
436         do
437                 [ -d "${x}" ]  && [ "${x}" != "${usb_storage_dir}/module" ] \
438                         && { DO_slowusb="1" ; break ; }
439         done
440 }
441
442 start_dev_mgr() {
443         if [ "${KV_2_6_OR_GREATER}" ]
444         then
445                 cd /sys
446                 good_msg 'Activating mdev'
447                 runmdev
448                 cd /
449         fi
450 }
451
452 cmdline_hwopts() {
453         # Scan CMDLINE for any "doscsi" or "noscsi"-type arguments
454         local FOUND
455         local TMP_HWOPTS
456
457         for x in $HWOPTS
458         do
459                 for y in $CMDLINE
460                 do
461                         if [ "${y}" = "do${x}" ]
462                         then
463                                 MY_HWOPTS="${MY_HWOPTS} $x"
464                         elif [ "${y}" = "no${x}" ]
465                         then
466                                 MY_HWOPTS="`echo ${MY_HWOPTS} | sed -e \"s/${x}//g\" -`"
467                         fi
468                         if [ "$(echo ${y} | cut -b -7)" = "keymap=" ]
469                         then
470                                 MY_HWOPTS="${MY_HWOPTS} keymap"
471                         fi
472                 done
473         done
474    
475         # Shouldnt need to sort this as the following loop should figure out the
476         # duplicates and strip them out
477         #MY_HWOPTS=`echo ${MY_HWOPTS}|  sort`
478         
479         for x in ${MY_HWOPTS}
480         do
481                 FOUND=0
482                 for y in ${TMP_HWOPTS}
483                 do
484                         if [ "${y}" = "${x}" ]
485                         then 
486                                 continue 2
487                         fi
488                 done
489                 TMP_HWOPTS="${TMP_HWOPTS} ${x}"
490                 eval DO_`echo ${x} | sed 's/-//'`=1
491         done
492
493         MY_HWOPTS=${TMP_HWOPTS}
494 }
495
496 load_modules() {
497         # Load modules listed in MY_HWOPTS if /lib/modules exists for the running
498         # kernel version
499         if [ -d "/lib/modules/${KV}" ]
500         then
501                 good_msg 'Loading modules'
502                 # Load appropriate kernel modules
503                 for modules in $MY_HWOPTS
504                 do
505                         modules_scan $modules
506                 done
507         else
508                 good_msg 'Skipping module load; no modules in the ramdisk!'
509         fi
510 }
511
512 setup_keymap() {
513         if [ "${DO_keymap}" ]
514         then
515                 if [ ! -e /dev/vc/0 -a ! -e /dev/tty0 ]
516                 then
517                         DEVBIND=1
518                         mount -o bind ${NEW_ROOT}/dev /dev
519                 fi
520                 [ ! -e /dev/tty0 ] && ln -s /dev/tty1 /dev/tty0
521
522                 [ -f /lib/keymaps/keymapList ] && chooseKeymap
523
524                 [ "${DEVBIND}" = '1' ] && umount /dev
525                 
526                 if [ -e /etc/sysconfig/keyboard -a "${CDROOT}" = '1' ]
527                 then
528                         mkdir -p ${NEW_ROOT}/etc/sysconfig/
529                         cp /etc/sysconfig/keyboard ${NEW_ROOT}/etc/sysconfig/keyboard
530                 fi
531         fi
532 }
533
534 chooseKeymap() {
535         good_msg "Loading keymaps"
536         if [ -z "${keymap}" ]
537         then
538                 splash 'verbose' > /dev/null &
539                 cat /lib/keymaps/keymapList
540                 read -t 10 -p '<< Load keymap (Enter for default): ' keymap
541                 case ${keymap} in
542                         1|azerty) keymap=azerty ;;
543                         2|be) keymap=be ;;
544                         3|bg) keymap=bg ;;
545                         4|br-a) keymap=br-a ;;
546                         5|br-l) keymap=br-l ;;
547                         6|by) keymap=by ;;
548                         7|cf) keymap=cf ;;
549                         8|croat) keymap=croat ;;
550                         9|cz) keymap=cz ;;
551                         10|de) keymap=de ;;
552                         11|dk) keymap=dk ;;
553                         12|dvorak) keymap=dvorak ;;
554                         13|es) keymap=es ;;
555                         14|et) keymap=et ;;
556                         15|fi) keymap=fi ;;
557                         16|fr) keymap=fr ;;
558                         17|gr) keymap=gr ;;
559                         18|hu) keymap=hu ;;
560                         19|il) keymap=il ;;
561                         20|is) keymap=is ;;
562                         21|it) keymap=it ;;
563                         22|jp) keymap=jp ;;
564                         23|la) keymap=la ;;
565                         24|lt) keymap=lt ;;
566                         25|mk) keymap=mk ;;
567                         26|nl) keymap=nl ;;
568                         27|no) keymap=no ;;
569                         28|pl) keymap=pl ;;
570                         29|pt) keymap=pt ;;
571                         30|ro) keymap=ro ;;
572                         31|ru) keymap=ru ;;
573                         32|se) keymap=se ;;
574                         33|sg) keymap=sg ;;
575                         34|sk-y) keymap=sk-y ;;
576                         35|sk-z) keymap=sk-z ;;
577                         36|slovene) keymap=slovene ;;
578                         37|trf) keymap=trf ;;
579                         38|trq) keymap=trq ;;
580                         39|ua) keymap=ua ;;
581                         40|uk) keymap=uk ;;
582                         41|us) keymap=us ;;
583                         42|wangbe) keymap=wangbe ;;
584                 esac
585         fi
586         if [ -e /lib/keymaps/${keymap}.map ]
587         then
588                 good_msg "Loading the ''${keymap}'' keymap"
589                 loadkmap < /lib/keymaps/${keymap}.map
590 #               xkeymap=${keymap}
591 #               echo ${keymap} | egrep -e "[0-9]+" >/dev/null 2>&1
592 #               if [ $? -eq 0 ]
593 #               then
594 #                       xkeymap=`tail -n 7 /lib/keymaps/keymapList | grep ${keymap} | sed -r "s/.*\s+${keymap}\s+([a-z-]+).*/\1/g" | egrep -v 1`
595 #               fi
596                 mkdir -p /etc/sysconfig
597 #               echo "XKEYBOARD=${xkeymap}" > /etc/sysconfig/keyboard
598                 echo "XKEYBOARD=${keymap}" > /etc/sysconfig/keyboard
599                 splash set_msg "Set keymap to ${keymap}"
600         elif [ -z "${keymap}" ]
601         then
602                 echo
603                 good_msg "Keeping default keymap"
604                 splash set_msg "Keeping default keymap"
605         else
606                 bad_msg "Sorry, but keymap ''${keymap}'' is invalid!"
607                 unset keymap
608                 chooseKeymap
609         fi
610 }
611
612 startVolumes() {
613         #good_msg 'Checking if volumes need to be started...'
614
615         # Here, we check for /dev/device-mapper, and if it exists, we setup a
616         # a symlink, which should hopefully fix bug #142775 and bug #147015
617         if [ -e /dev/device-mapper ] && [ ! -e /dev/mapper/control ]
618         then
619                 mkdir -p /dev/mapper
620                 ln -sf /dev/device-mapper /dev/mapper/control
621         fi
622         
623         if [ "${USE_MDADM}" = '1' ]
624         then
625                 /sbin/mdadm --assemble --scan
626         fi
627
628         if [ "${USE_DMRAID_NORMAL}" = '1' ]
629         then
630                 if [ -e '/sbin/dmraid' ]
631                 then
632                         good_msg "Activating Device-Mapper RAID(s)"
633                         if [ '${DMRAID_OPTS}' = '' ]
634                         then
635                                 /sbin/dmraid -ay
636                         else
637                                 /sbin/dmraid -ay ${DMRAID_OPTS}
638                         fi
639                 fi
640         fi
641
642         if [ "${USE_LVM_NORMAL}" = '1' ]
643         then
644                 if [ -e '/bin/lvm' ]
645                 then
646                         for dev in ${RAID_DEVICES}
647                         do
648                                 setup_md_device "${dev}"
649                         done
650
651                         # This is needed for /bin/lvm to accept the following logic
652                         lvm_commands="#! /bin/lvm"
653
654                         # If there is a cahe, update it. Unbreak at least dmcrypt
655                         [ -d /etc/lvm/cache ] && lvm_commands="${lvm_commands} \nvgscan"
656
657                         # To activate volumegroups on all devices in the cache
658                         lvm_commands="${lvm_commands} \nvgchange -ay --sysinit"
659
660                         # And finally execute it all (/proc/... needed if lvm is compiled without readline)
661                         good_msg "Scanning for and activating Volume Groups"
662                         printf "%b\n" "${lvm_commands}" | /bin/lvm /proc/self/fd/0
663
664                         # Disable EVMS since lvm is activated and they dont work together.
665                         if [ "${USE_EVMS_NORMAL}" = '1' ]
666                         then
667                                 bad_msg "Disabling EVMS Support because LVM started"
668                                 bad_msg "Do not add dolvm to the cmdline if this is not what you want"
669                                 bad_msg "LVM and EVMS do not work well together"
670                                 USE_EVMS_NORMAL=0
671                         fi
672                 else
673                         bad_msg "vgscan or vgchange not found: skipping LVM volume group activation!"
674                 fi
675         fi
676
677         if [ "${USE_EVMS_NORMAL}" = '1' ]
678         then
679                 if [ -e '/sbin/evms_activate' ]
680                 then
681                         good_msg "Activating EVMS"
682                         evms_activate
683                 fi
684         fi
685 }
686
687 startiscsi() {
688         
689         if [ ! -n "${ISCSI_NOIBFT}" ]
690         then
691                 good_msg "Activating iSCSI via iBFT"
692                 iscsistart -b
693         fi
694
695         if [ -n "${ISCSI_INITIATORNAME}" ] && [ -n "${ISCSI_TARGET}" ] && [ -n "${ISCSI_ADDRESS}" ]
696         then
697                 good_msg "Activating iSCSI via cmdline"
698
699                 if [ "${ISCSI_TGPT}" ]
700                 then
701                         ADDITIONAL="${ADDITIONAL} -g ${ISCSI_TGPT}"
702                 else
703                         ADDITIONAL="${ADDITIONAL} -g 1"
704                 fi
705                 
706                 if [ "${ISCSI_PORT}" ]
707                 then
708                         ADDITIONAL="${ADDITIONAL} -p ${ISCSI_PORT}"
709                 fi
710
711                 if [ "${ISCSI_USERNAME}" ]
712                 then
713                         ADDITIONAL="${ADDITIONAL} -u ${ISCSI_USERNAME}"
714                 fi
715
716                 if [ "${ISCSI_PASSWORD}" ]
717                 then
718                         ADDITIONAL="${ADDITIONAL} -w ${ISCSI_PASSWORD}"
719                 fi
720
721                 if [ "${ISCSI_USERNAME_IN}" ]
722                 then
723                         ADDITIONAL="${ADDITIONAL} -U ${ISCSI_USERNAME_IN}"
724                 fi
725
726                 if [ "${ISCSI_PASSWORD_IN}" ]
727                 then
728                         ADDITIONAL="${ADDITIONAL} -W ${ISCSI_PASSWORD_IN}"
729                 fi
730
731                 if [ "${ISCSI_DEBUG}" ]
732                 then
733                         ADDITIONAL="${ADDITIONAL} -d ${ISCSI_DEBUG}"
734                 fi
735
736                 iscsistart -i "${ISCSI_INITIATORNAME}" -t "${ISCSI_TARGET}" -a "${ISCSI_ADDRESS}" ${ADDITIONAL}
737
738                 # let iscsid settle - otherwise mounting the iSCSI-disk will fail (very rarely, though)
739                 sleep 1
740         fi
741 }
742
743
744 # Open a LUKS device
745 # It is either the root or a swap, other devices are supported in the scripts provided with sys-fs/cryptsetup-luks
746 # $1 - root/swap
747 openLUKS() {
748         # please use 'tr' and this line, or remove it
749         # eval local TYPE=`uppercase $1`
750
751         case $1 in
752                 root)
753                         local TYPE=ROOT
754                         ;;
755                 swap)
756                         local TYPE=SWAP
757                         ;;
758         esac
759
760         eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' LUKS_NAME="$1" LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"' LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"'
761         local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0
762         local mntkey="/mnt/key/" cryptsetup_options=''
763
764         [ ! -e /sbin/cryptsetup ] && bad_msg "The ramdisk does not support LUKS" && exit 1
765         while [ 1 ]
766         do
767                 local gpg_cmd=""
768                 # if crypt_silent=1 and some error occurs, enter shell quietly
769                 if [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ]
770                 then
771                         run_shell
772                 elif [ ${DEV_ERROR} -eq 1 ]
773                 then
774                         whereis "LUKS_DEVICE" "${LUKS_NAME}"
775                         DEV_ERROR=0
776                 elif [ ${KEY_ERROR} -eq 1 ]
777                 then
778                         whereis "LUKS_KEY" "${LUKS_NAME} key"
779                         KEY_ERROR=0
780                 elif [ ${KEYDEV_ERROR} -eq 1 ]
781                 then
782                         whereis "LUKS_KEYDEV" "${LUKS_NAME} key device"
783                         KEYDEV_ERROR=0
784                 else
785                         case "${LUKS_DEVICE}" in
786                                 UUID\=*|LABEL\=*)
787                                         local REAL_LUKS=""
788                                         local retval=1
789
790                                         if [ "${retval}" -ne 0 ]; then
791                                                 REAL_LUKS=`findfs "${LUKS_DEVICE}" 2>/dev/null`
792                                                 retval=$?
793                                         fi
794
795                                         if [ "$retval" -ne 0 ]; then
796                                                 REAL_LUKS=`busybox findfs "${LUKS_DEVICE}" 2>/dev/null`
797                                                 retval=$?
798                                         fi
799
800                                         if [ "${retval}" -ne 0 ]; then
801                                                 REAL_LUKS=`blkid -l -t "${LUKS_DEVICE}" | cut -d ":" -f 1 2>/dev/null`
802                                                 retval=$?
803                                         fi
804
805                                         if [ "${retval}" -eq 0 ] && [ -n "${REAL_LUKS}" ]; then
806                                                 good_msg "Detected device ${REAL_LUKS}"
807                                                 LUKS_DEVICE="${REAL_LUKS}"
808                                         fi
809                                 ;;
810                         esac
811
812                         setup_md_device ${LUKS_DEVICE}
813                         cryptsetup isLuks ${LUKS_DEVICE}
814                         if [ $? -ne 0 ]
815                         then
816                                 bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT}
817                                 DEV_ERROR=1
818                                 continue
819                         else
820                                 # Handle keys
821                                 if [ -n "${LUKS_KEY}" ] 
822                                 then
823                                         if [ ! -e "${mntkey}${LUKS_KEY}" ] 
824                                         then
825                                                 if [ -b "${LUKS_KEYDEV}" ]
826                                                 then good_msg "Using key device ${LUKS_KEYDEV}." ${CRYPT_SILENT}
827                                                 else
828                                                         good_msg "Please insert removable device ${LUKS_KEYDEV} for ${LUKS_NAME}" ${CRYPT_SILENT}
829                                                         # abort after 10 secs
830                                                         local count=10
831                                                         while [ ${count} -gt 0 ]
832                                                         do 
833                                                                 count=$((count-1))
834                                                                 sleep 1
835                                                                 if [ -b "${LUKS_KEYDEV}" ]
836                                                                 then
837                                                                         good_msg "Removable device ${LUKS_KEYDEV} detected." ${CRYPT_SILENT}
838                                                                         break
839                                                                 fi
840                                                         done
841                                                         if [ ! -b "${LUKS_KEYDEV}" ]
842                                                         then
843                                                                 eval CRYPT_${TYPE}_KEY=${LUKS_KEY}
844                                                                 bootstrapKey ${TYPE}
845                                                                 eval LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"'
846                                                                 if [ ! -b "${LUKS_KEYDEV}" ]; then
847                                                                         KEYDEV_ERROR=1
848                                                                         bad_msg "Removable device ${LUKS_KEYDEV} not found." ${CRYPT_SILENT}
849                                                                         continue
850                                                                 fi
851                                                                 # continue otherwise will mount keydev which is mounted by bootstrap
852                                                                 continue
853                                                         fi
854                                                 fi
855                                                 # At this point a device was recognized, now let's see if the key is there
856                                                 [ ! -d "$mntkey" ] && mkdir -p ${mntkey} 2>/dev/null >/dev/null
857
858                                                 mount -n -o ro ${LUKS_KEYDEV} ${mntkey} >/dev/null 2>/dev/null
859                                                 if [ "$?" != '0' ]
860                                                 then
861                                                         KEYDEV_ERROR=1
862                                                         bad_msg "Mounting of device ${LUKS_KEYDEV} failed." ${CRYPT_SILENT}
863                                                         continue
864                                                 else
865                                                         good_msg "Removable device ${LUKS_KEYDEV} mounted." ${CRYPT_SILENT}
866                                                         sleep 2
867                                                         # keyfile exists?
868                                                         if [ ! -e "${mntkey}${LUKS_KEY}" ]; then
869                                                                 umount -n ${mntkey} 2>/dev/null >/dev/null
870                                                                 KEY_ERROR=1
871                                                                 KEYDEV_ERROR=1
872                                                                 bad_msg "Key {LUKS_KEY} on device ${LUKS_KEYDEV} not found." ${CRYPT_SILENT}
873                                                                 continue
874                                                         fi
875                                                 fi
876                                         fi
877                                         # At this point a candidate key exists (either mounted before or not)
878                                         good_msg "${LUKS_KEY} on device ${LUKS_KEYDEV} found" ${CRYPT_SILENT}
879                                         if [ $(echo ${LUKS_KEY} | grep -o '.gpg$') = ".gpg" ] && [ -e /sbin/gpg ] ; then
880                                                 [ -e /dev/tty ] && mv /dev/tty /dev/tty.org
881                                                 mknod /dev/tty c 5 1
882                                                 cryptsetup_options="-d -"
883                                                 gpg_cmd="/sbin/gpg --logger-file /dev/null --quiet --decrypt ${mntkey}${LUKS_KEY} |"
884                                         else
885                                                 cryptsetup_options="-d ${mntkey}${LUKS_KEY}"
886                                         fi
887                                 fi
888                                 # At this point, keyfile or not, we're ready!
889                                 crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}"
890                                 if [ $? -eq 0 ]
891                                 then
892                                         good_msg "LUKS device ${LUKS_DEVICE} opened" ${CRYPT_SILENT}
893                                         break
894                                 else
895                                         bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT}
896                                         DEV_ERROR=1
897                                         KEY_ERROR=1
898                                         KEYDEV_ERROR=1
899                                 fi
900                         fi
901                 fi
902         done
903         umount ${mntkey} 2>/dev/null >/dev/null
904         rmdir -p ${mntkey} 2>/dev/null >/dev/null
905 }
906
907 startLUKS() {
908
909         # if key is set but key device isn't, find it
910         
911         [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \
912                 && sleep 6 && bootstrapKey "ROOT"
913
914         if [ -n "${CRYPT_ROOT}" ]; then
915                 openLUKS "root"
916                 if [ -n "${REAL_ROOT}" ]
917                 then
918                         # Rescan volumes
919                         startVolumes
920                 else
921                         REAL_ROOT="/dev/mapper/root"
922                 fi
923         fi
924
925         # same for swap, but no need to sleep if root was unencrypted
926         [ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \
927                 && { [ -z "${CRYPT_ROOT}" ] && sleep 6; bootstrapKey "SWAP"; }
928
929         if [ -n "${CRYPT_SWAP}" ]; then
930                 openLUKS "swap"
931                 if [ -z "${REAL_RESUME}" ]
932                 then
933                         # Resume from swap as default
934                         REAL_RESUME="/dev/mapper/swap"
935                 fi
936         fi
937 }
938
939 sdelay() {
940         # Sleep a specific number of seconds if SDELAY is set
941         if [ "${SDELAY}" ]
942         then
943                 good_msg 'Waiting ${SDELAY} seconds...'
944                 sleep ${SDELAY}
945         else
946                 good_msg 'Hint: Use parameter scandelay[=seconds] if you need waiting here'
947         fi
948 }
949
950 quiet_kmsg() {
951         # if QUIET is set make the kernel less chatty
952         [ -n "$QUIET" ] && echo '0' > /proc/sys/kernel/printk
953 }
954
955 verbose_kmsg() {
956         # if QUIET is set make the kernel less chatty
957         [ -n "$QUIET" ] && echo '6' > /proc/sys/kernel/printk
958 }
959
960
961 cdupdate() {
962         if [ "${CDROOT}" = '1' ]
963         then
964                 if [ -x /${NEW_ROOT}/mnt/cdrom/cdupdate.sh ]
965                 then
966                         good_msg "Running cdupdate.sh"
967                         ${NEW_ROOT}/mnt/cdrom/cdupdate.sh
968                         if [ "$?" != '0' ]
969                         then
970                                 bad_msg "Executing cdupdate.sh failed!"
971                                 run_shell
972                         fi
973                 else
974                         good_msg 'No cdupdate.sh script found, skipping...'
975                 fi
976         fi
977 }
978
979 setup_btrfsctl() {
980         # start BTRFS volume detection, if available
981         [ -x /sbin/btrfsctl ] && /sbin/btrfsctl -a
982 }
983
984 setup_md_device() {
985         local device
986
987         [ -z "$1" ] && device="${REAL_ROOT}" || device="$1"
988         [ -z "${device}" ] && return # LiveCD
989
990         if [ `echo ${device}|sed -e 's#\(luks:\)\?\(/dev/md\)[[:digit:]]\+#\2#'` = "/dev/md" ]
991         then
992                 good_msg 'Detected real_root as a md device. Setting up the device node...'
993                 MD_NUMBER=`echo ${device}|sed -e 's#\(luks:\)\?/dev/md\([[:digit:]]\+\)#\2#'`
994                 if [ ! -e /dev/md${MD_NUMBER} ]
995                 then
996                         mknod /dev/md${MD_NUMBER} b 9 ${MD_NUMBER} >/dev/null 2>&1
997                         [ $? -ne 0 ] && bad_msg "Creation of /dev/md${MD_NUMBER} failed..."
998                 fi
999                 mdstart ${MDPART} /dev/md${MD_NUMBER}
1000         fi
1001 }
1002
1003 rundebugshell() {
1004         if [ -n "$DEBUG" ]
1005         then
1006                 good_msg 'Starting debug shell as requested by "debug" option.'
1007                 good_msg 'Type "exit" to continue with normal bootup.'
1008                 [ -x /bin/sh ] && /bin/sh || /bin/ash
1009         fi
1010 }
1011
1012 do_resume() {
1013         if [ -d /proc/suspend2 -o -d /sys/power/suspend2 -o -d /sys/power/tuxonice ]; then
1014                 tuxonice_resume
1015         else
1016                 swsusp_resume
1017         fi
1018 }
1019
1020 swsusp_resume() {
1021         # determine swap resume partition
1022         local device=$(ls -lL "${REAL_RESUME}" | sed 's/\  */ /g' | cut -d \  -f 5-6 | sed 's/,\ */:/')
1023         [ -f /sys/power/resume ] && echo "${device}" > /sys/power/resume
1024 }
1025
1026 tuxonice_resume() {
1027         local splash_theme
1028         if grep "splash=" /proc/cmdline > /dev/null 2>&1; then
1029                 splash_theme=$(cat /proc/cmdline | sed 's/.*splash=/splash=/' | sed 's/ .*//' | sed 's/.*theme://' | sed 's/,.*//')
1030         fi
1031
1032         local tuxonice_userui_program="/sys/power/tuxonice/user_interface/program"
1033         local tuxonice_do_resume="/sys/power/tuxonice/do_resume"
1034         local tuxonice_resumedev="/sys/power/tuxonice/resume"
1035         local tuxonice_replace_swsusp="/sys/power/tuxonice/replace_swsusp"
1036
1037         #
1038         # Backward compatibility
1039         #
1040         if [ -e /sys/power/suspend2 ]; then
1041                 tuxonice_userui_program="/sys/power/suspend2/user_interface/program"
1042                 tuxonice_do_resume="/sys/power/suspend2/do_resume"
1043                 tuxonice_resumedev="/sys/power/suspend2/resume"
1044                 tuxonice_replace_swsusp="/sys/power/suspend2/replace_swsusp"
1045         elif [ -e /proc/suspend2 ]; then
1046                 tuxonice_userui_program="/proc/suspend2/userui_program"
1047                 tuxonice_do_resume="/proc/suspend2/do_resume"
1048                 tuxonice_resumedev="/proc/suspend2/resume"
1049                 tuxonice_replace_swsusp="/proc/suspend2/replace_swsusp"
1050         fi
1051
1052         # if 'use_swsusp' is given, use swsusp instead
1053         if grep "use_swsusp" /proc/cmdline > /dev/null 2>&1; then
1054                 echo 0 > ${tuxonice_replace_swsusp}
1055                 swsusp_resume
1056                 return
1057         fi
1058
1059         modules_scan tuxonice
1060
1061         # we both configure tuxonice and activate resuming,
1062         # however the kernel will resume only if an image is found
1063
1064         if ! grep suspend_noui /proc/cmdline > /dev/null 2>&1; then
1065                 which suspend2ui_text > /dev/null 2>&1 && which suspend2ui_text > "${tuxonice_userui_program}"
1066                 which tuxoniceui_text > /dev/null 2>&1 && which tuxoniceui_text > "${tuxonice_userui_program}"
1067
1068                 if [ -n "${splash_theme}" ]; then
1069                         ln -s /etc/splash/${splash_theme} /etc/splash/suspend2
1070                         ln -s /etc/splash/${splash_theme} /etc/splash/tuxonice
1071
1072                         which suspend2ui_fbsplash > /dev/null 2>&1 && which suspend2ui_fbsplash > "${tuxonice_userui_program}"
1073                         which tuxoniceui_fbsplash > /dev/null 2>&1 && which tuxoniceui_fbsplash > "${tuxonice_userui_program}"
1074                 fi
1075
1076         fi
1077         echo "${REAL_RESUME}" > "${tuxonice_resumedev}"
1078         echo > "${tuxonice_do_resume}"
1079 }
1080
1081 find_loop() {
1082         CDROM="${NEW_ROOT}/mnt/cdrom"
1083         for loop in ${LOOPS}
1084         do
1085                 if [ -e "${CDROM}""${loop}" ]
1086                 then
1087                         LOOP="${loop}"
1088                 fi
1089         done
1090 }
1091
1092 find_looptype() {
1093         LOOPTYPE="${LOOP##*.}"
1094         [ "${LOOPTYPE}" == "loop" ] && LOOPTYPE="normal"
1095         [ "${LOOP}" == "/zisofs" ] && LOOPTYPE="${LOOP#/}"
1096         [ -z "${LOOPTYPE}" ] && LOOPTYPE="noloop"
1097 }
1098
1099 getdvhoff() {
1100         echo $(( $(hexdump -n 4 -s $((316 + 12 * $2)) -e '"%i"' $1) * 512))
1101 }
1102
1103 setup_unionfs() {
1104         local rw_dir=$1
1105         local ro_dir=$2
1106         if [ "${USE_UNIONFS_NORMAL}" = '1' ]
1107         then
1108                 # Directory used for rw changes in union mount filesystem
1109                 UNION=/union
1110 #               MEMORY=/memory
1111 #               if [ -z "$UID" ]
1112 #               then
1113 #                       CHANGES=$MEMORY/unionfs_changes/default
1114 #               else
1115 #                       CHANGES=$MEMORY/unionfs_changes/$UID
1116 #               fi
1117
1118 #               mkdir -p ${MEMORY}
1119                 mkdir -p ${UNION}
1120                 good_msg "Loading fuse module"
1121                 modprobe fuse > /dev/null 2>&1
1122 #                 if [ -n "${UNIONFS}" ]         
1123 #                 then   
1124 #                         CHANGESDEV=${UNIONFS}          
1125 #                         good_msg "mounting $CHANGESDEV to $MEMORY for unionfs support"         
1126 #                         mount -t auto $CHANGESDEV $MEMORY      
1127 #                         # mount tmpfs only in the case when changes= boot parameter was        
1128 #                         # empty or we were not able to mount the storage device        
1129 #                         ret=$?         
1130 #                         if [ ${ret} -ne 0 ]
1131 #                         then   
1132 #                                 bad_msg "mount of $CHANGESDEV failed falling back to ramdisk based unionfs"    
1133 #                                 mount -t tmpfs tmpfs $MEMORY   
1134 #                         fi     
1135 #                         if [ "${CDROOT}" -eq '1' -a ! -f ${MEMORY}/livecd.unionfs  ]   
1136 #                         then   
1137 #                                 umount $MEMORY         
1138 #                                 bad_msg "failed to find livecd.unionfs file on $CHANGESDEV"    
1139 #                                 bad_msg "create a livecd.unionfs file on this device if you wish to use it for unionfs"        
1140 #                                 bad_msg "falling back to ramdisk based unionfs for safety"     
1141 #                                 mount -t tmpfs tmpfs $MEMORY   
1142 #                         fi     
1143 #                 else   
1144 #                         good_msg "Mounting ramdisk to $MEMORY for unionfs support..."          
1145 #                         mount -t tmpfs tmpfs $MEMORY   
1146 #                 fi     
1147          
1148                 mkdir /tmp
1149                 mkdir -p ${UNION}
1150 #               mkdir -p $CHANGES
1151 #               mount -t unionfs -o dirs=$CHANGES=rw unionfs ${UNION}
1152                 good_msg "Creating union mount"
1153                 unionfs -o allow_other,cow,noinitgroups,suid,dev,default_permissions,use_ino ${rw_dir}=RW:${ro_dir}=RO ${UNION} 2>/dev/null
1154                 ret=$?
1155                 if [ ${ret} -ne 0 ]
1156                 then
1157                         bad_msg "Can't setup union mount!"
1158                         USE_UNIONFS_NORMAL=0
1159                 fi
1160         else
1161                 USE_UNIONFS_NORMAL=0
1162         fi
1163 }