| 1 | beyerle@PS | 1 | #!/bin/ash
 | 
        
           |  |  | 2 | #
 | 
        
           |  |  | 3 | # Functions library :: for Linux Live scripts 5.x.y
 | 
        
           |  |  | 4 | # Author: Tomas M. <http://www.linux-live.org>
 | 
        
           |  |  | 5 | #
 | 
        
           |  |  | 6 | # modified by Urs Beyerle, PSI
 | 
        
           |  |  | 7 | # - to allow LiveCD mounted over nfs
 | 
        
           |  |  | 8 | # - add scsi_mod, sd_mod for usb-storage module
 | 
        
           |  |  | 9 | # - only with boot option "automount", all devices in fstab are rw automounted
 | 
        
           |  |  | 10 | # - remove detect of CD and Floppy (done by fstab-sync)
 | 
        
           |  |  | 11 | # - add sr_mod (USB CDROM support)
 | 
        
           |  |  | 12 | # - add SATA to modprobe_usb_modules -> modprobe_usb_sata_modules
 | 
        
           |  |  | 13 | # - add fscache (for SL5) 
 | 
        
           |  |  | 14 | # - add ide-cd, sr_mod, cdrom (for SL5 cdrom support)
 | 
        
           | 37 | beyerle@PS | 15 | # - add aufs (unionfs replacement)
 | 
        
           |  |  | 16 | # - to allow LiveCD mounted over NFS (for diskless client)
 | 
        
           | 48 | beyerle@PS | 17 | # - add functions get_dhcp_lease() and load_network_modules()
 | 
        
           | 85 | beyerle@PS | 18 | # - add ata_piix to modprobe_usb_sata_modules
 | 
        
           | 100 | beyerle@PS | 19 | # - works with unionfs 2.x
 | 
        
           |  |  | 20 | # - better detection of network card in case of diskless client
 | 
        
           | 1 | beyerle@PS | 21 | #
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 | # ===========================================================
 | 
        
           |  |  | 24 | # user interface functions
 | 
        
           |  |  | 25 | # ===========================================================
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | # echolog
 | 
        
           |  |  | 28 | # $1 = text to show and to write to /var/log/messages
 | 
        
           |  |  | 29 | #
 | 
        
           |  |  | 30 | echolog()
 | 
        
           |  |  | 31 | {
 | 
        
           |  |  | 32 |    echo "LIVECD:" "$@" >>/var/log/livedbg
 | 
        
           |  |  | 33 |    echo "$@"
 | 
        
           |  |  | 34 | }
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 | # debug
 | 
        
           |  |  | 37 | # commands executed when debug boot parameter is present
 | 
        
           |  |  | 38 | #
 | 
        
           |  |  | 39 | debug()
 | 
        
           |  |  | 40 | {
 | 
        
           |  |  | 41 |    echo
 | 
        
           |  |  | 42 |    echo "====="
 | 
        
           |  |  | 43 |    echo ": Debugging started. Here is the root shell for you."
 | 
        
           |  |  | 44 |    echo ": Type your desired command or hit Ctrl+D to continue booting."
 | 
        
           |  |  | 45 |    echo
 | 
        
           |  |  | 46 |    ash
 | 
        
           |  |  | 47 | }
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 | # header
 | 
        
           |  |  | 50 | # $1 = text to show
 | 
        
           |  |  | 51 | #
 | 
        
           |  |  | 52 | header()
 | 
        
           |  |  | 53 | {
 | 
        
           |  |  | 54 |    echolog "[0;1m$1[0;0m"
 | 
        
           |  |  | 55 | }
 | 
        
           |  |  | 56 |   | 
        
           |  |  | 57 | fatal()
 | 
        
           |  |  | 58 | {
 | 
        
           |  |  | 59 |    header "Fatal error occured - $1"
 | 
        
           |  |  | 60 |    echolog "Something went wrong and we can't continue booting :("
 | 
        
           |  |  | 61 |    echolog "You may explore the system by using simple commands like ls, lsmod, mount, etc."
 | 
        
           |  |  | 62 |    echolog "You may also try to hit Ctrl+D. Booting will continue. Use at your own risk."
 | 
        
           |  |  | 63 |    echolog "To be safe, hit Ctrl+Alt+Delete to reboot."
 | 
        
           |  |  | 64 |    echolog
 | 
        
           |  |  | 65 |    ash
 | 
        
           |  |  | 66 | }
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | # ===========================================================
 | 
        
           |  |  | 69 | # text processing functions
 | 
        
           |  |  | 70 | # ===========================================================
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 | # egrep_o is a replacement for "egrep -o". It prints only the last
 | 
        
           |  |  | 73 | # matching text
 | 
        
           |  |  | 74 | # $1 = regular expression
 | 
        
           |  |  | 75 | #
 | 
        
           |  |  | 76 | egrep_o()
 | 
        
           |  |  | 77 | {
 | 
        
           |  |  | 78 |    cat | egrep "$1" | sed -r "s/.*($1).*/\\1/"
 | 
        
           |  |  | 79 | }
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 | # look into cmdline and echo $1 back if $1 is set
 | 
        
           |  |  | 82 | # $1 = value name, case sensitive, for example livecd_subdir
 | 
        
           |  |  | 83 | # $2 = file to use instead /proc/cmdline, optional
 | 
        
           |  |  | 84 | #
 | 
        
           |  |  | 85 | cmdline_parameter()
 | 
        
           |  |  | 86 | {
 | 
        
           |  |  | 87 |    CMDLINE=/proc/cmdline
 | 
        
           |  |  | 88 |    if [ "$2" != "" ]; then CMDLINE="$2"; fi
 | 
        
           |  |  | 89 |    cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1(\$|=|[[:space:]]+)" | egrep_o "$1"
 | 
        
           |  |  | 90 | }
 | 
        
           |  |  | 91 |   | 
        
           |  |  | 92 | # look into cmdline and echo value of $1 option
 | 
        
           |  |  | 93 | # $1 = value name, case sensitive, for example livecd_subdir
 | 
        
           |  |  | 94 | # $2 = file to use instead /proc/cmdline, optional
 | 
        
           |  |  | 95 | #
 | 
        
           |  |  | 96 | cmdline_value()
 | 
        
           |  |  | 97 | {
 | 
        
           |  |  | 98 |    CMDLINE=/proc/cmdline
 | 
        
           |  |  | 99 |    if [ "$2" != "" ]; then CMDLINE="$2"; fi
 | 
        
           |  |  | 100 |    cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1=([^[:space:]]+)" | egrep_o "=.*" | cut -b 2- | tail -n 1
 | 
        
           |  |  | 101 | }
 | 
        
           |  |  | 102 |   | 
        
           |  |  | 103 | # ===========================================================
 | 
        
           |  |  | 104 | # system functions
 | 
        
           |  |  | 105 | # ===========================================================
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 | # modprobe module $1, including all dependencies, suppress all messages
 | 
        
           |  |  | 108 | # (own function because modprobe in busybox doesn't work with gzipped modules)
 | 
        
           |  |  | 109 | # $1 = module name, eg. ehci-hcd
 | 
        
           |  |  | 110 | # $2 = optional argument
 | 
        
           |  |  | 111 | #
 | 
        
           |  |  | 112 | modprobe_module()
 | 
        
           |  |  | 113 | {
 | 
        
           |  |  | 114 |   if [ "$1" = "" ]; then return 1; fi
 | 
        
           |  |  | 115 |   PRINTK=`cat /proc/sys/kernel/printk`
 | 
        
           |  |  | 116 |   echo "0" >/proc/sys/kernel/printk
 | 
        
           |  |  | 117 |   | 
        
           |  |  | 118 |   KERNEL="`uname -r`"; LSMOD=/tmp/lsmod
 | 
        
           |  |  | 119 |   MODULEDEPS="`cat /lib/modules/$KERNEL/modules.dep | egrep \"$1\\.ko(\\.gz)?:\"`"
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 |   for MODULE in `echo $MODULEDEPS | cut -d ":" -f 2-` `echo $MODULEDEPS | cut -d ":" -f 1`; do
 | 
        
           |  |  | 122 |      MODULE=${MODULE%%:};   # remove : at the end, a bug 
 | 
        
           |  |  | 123 |      TMPMOD="/tmp/`basename $MODULE .gz`";
 | 
        
           |  |  | 124 |      # if the module is not loaded already
 | 
        
           |  |  | 125 |      if [ "`cat $LSMOD 2>/dev/null | egrep \"^$TMPMOD\\\$\"`" = "" ]; then
 | 
        
           |  |  | 126 |         gunzip -c $MODULE 2>/dev/null >$TMPMOD
 | 
        
           | 100 | beyerle@PS | 127 |         if [ $? -ne 0 ]; then cp $MODULE $TMPMOD; fi # can't gunzip? copy
 | 
        
           | 1 | beyerle@PS | 128 |         insmod $TMPMOD $2; err=$?
 | 
        
           |  |  | 129 |         ### insmod $TMPMOD $2 >/dev/null 2>/dev/null; err=$?
 | 
        
           |  |  | 130 |         if [ "$err" -eq 0 ]; then echo $TMPMOD >>$LSMOD; fi # module log
 | 
        
           |  |  | 131 |         rm $TMPMOD
 | 
        
           |  |  | 132 |      fi
 | 
        
           |  |  | 133 |   done
 | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 |   echo "$PRINTK" >/proc/sys/kernel/printk
 | 
        
           |  |  | 136 |   if [ "$err" -ne 0 ]; then echolog "error inserting module $1 ($err)"; fi
 | 
        
           |  |  | 137 |   return $err
 | 
        
           |  |  | 138 | }
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 | # Mount device $1 to $2
 | 
        
           |  |  | 141 | # $1 = /dev device to mount, eg. /dev/hda1
 | 
        
           |  |  | 142 | # $2 = mountpoint, eg. /mnt/hda1
 | 
        
           |  |  | 143 | # $3 = mount options, for example "loop", "ro", or "remount,rw"
 | 
        
           |  |  | 144 | #
 | 
        
           |  |  | 145 | mount_device()
 | 
        
           |  |  | 146 | {
 | 
        
           |  |  | 147 |   mkdir -p $2
 | 
        
           |  |  | 148 |   if [ "$3" != "" ]; then OPTIONS="-o $3"; else OPTIONS=""; fi
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 |   PRINTK=`cat /proc/sys/kernel/printk`
 | 
        
           |  |  | 151 |   echo "0" >/proc/sys/kernel/printk
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |   mount -t auto $1 $2 $OPTIONS >/dev/null 2>/dev/null
 | 
        
           |  |  | 154 |   err=$?
 | 
        
           |  |  | 155 |   | 
        
           |  |  | 156 |   if [ "$err" -ne 0 ]; then rmdir $2 2>/dev/null; fi
 | 
        
           |  |  | 157 |   echo "$PRINTK" >/proc/sys/kernel/printk
 | 
        
           |  |  | 158 |   return $err
 | 
        
           |  |  | 159 | }
 | 
        
           |  |  | 160 |   | 
        
           |  |  | 161 | # ===========================================================
 | 
        
           |  |  | 162 | # live module functions
 | 
        
           |  |  | 163 | # ===========================================================
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 | # Create module
 | 
        
           |  |  | 166 | # call mksquashfs with apropriate arguments
 | 
        
           |  |  | 167 | # $1 = directory which will be compressed to squashfs module
 | 
        
           |  |  | 168 | # $2 = output .mo file
 | 
        
           |  |  | 169 | # $3 = optional -keep-as-directory argument
 | 
        
           |  |  | 170 | #
 | 
        
           |  |  | 171 | create_module()
 | 
        
           |  |  | 172 | {
 | 
        
           |  |  | 173 |    mksquashfs $1 $2 $3 >/dev/null
 | 
        
           |  |  | 174 |    if [ $? -ne 0 ]; then return 1; fi
 | 
        
           |  |  | 175 |    chmod oga-x $2 # remove execute attrib
 | 
        
           |  |  | 176 | }
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 | # Mount .mo module to destination directory
 | 
        
           |  |  | 179 | # $1 = path to .mo livecd compressed module
 | 
        
           |  |  | 180 | # $2 = destination folder
 | 
        
           |  |  | 181 | #
 | 
        
           |  |  | 182 | mount_module()
 | 
        
           |  |  | 183 | {
 | 
        
           |  |  | 184 |    mount -t squashfs -o loop,ro $1 $2
 | 
        
           |  |  | 185 | }
 | 
        
           |  |  | 186 |   | 
        
           |  |  | 187 | # Insert a directory tree $2 to an union specified by $1
 | 
        
           |  |  | 188 | # Top-level read-write branch is specified by it's index 0
 | 
        
           |  |  | 189 | # $1 = union absolute path (starting with /)
 | 
        
           |  |  | 190 | # $2 = path to data directory
 | 
        
           |  |  | 191 | #
 | 
        
           |  |  | 192 | union_insert_dir()
 | 
        
           |  |  | 193 | {
 | 
        
           | 100 | beyerle@PS | 194 |    which unionctl >/dev/null 2>&1
 | 
        
           |  |  | 195 |    if [ $? -eq 0 ]; then
 | 
        
           |  |  | 196 |        # unionfs 1.x or aufs
 | 
        
           |  |  | 197 |        unionctl "$1" --add --after 0 --mode ro "$2"
 | 
        
           |  |  | 198 |    else
 | 
        
           |  |  | 199 |        # unionfs 2.x
 | 
        
           |  |  | 200 |        mount -t unionfs -o remount,add=:${2}=ro none "$1"
 | 
        
           |  |  | 201 |    fi
 | 
        
           | 1 | beyerle@PS | 202 | }
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 | # List all modules in all directories (base, modules, optional)
 | 
        
           |  |  | 205 | # and filter out unneeded optional modules (not specified by load= kernel parameter)
 | 
        
           |  |  | 206 | # $1 = root directory of mounted DATAdir
 | 
        
           |  |  | 207 | #
 | 
        
           |  |  | 208 | list_modules()
 | 
        
           |  |  | 209 | {
 | 
        
           |  |  | 210 |    LOAD="`cmdline_value load`"
 | 
        
           |  |  | 211 |    ls -A1d $1/*.mo $1/*/*.mo 2>/dev/null | while read LINE; do
 | 
        
           |  |  | 212 |       MODNAME="`basename $LINE .mo`"
 | 
        
           |  |  | 213 |       if [ "$LOAD" != "*" -a "`echo $LINE | grep optional`" != "" -a "`echo $LOAD | egrep \"(^|,)$MODNAME(\\\$|,)\"`" = "" ]; then continue
 | 
        
           |  |  | 214 |         else echo $LINE; fi
 | 
        
           |  |  | 215 |    done
 | 
        
           |  |  | 216 | }
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 | # Insert one single .mo module to the union
 | 
        
           |  |  | 219 | # $1 = union absolute path (starting with /)
 | 
        
           |  |  | 220 | # $2 = module.mo full path
 | 
        
           |  |  | 221 | # $3 = destination folder, where images will be mounted to
 | 
        
           |  |  | 222 | #
 | 
        
           |  |  | 223 | union_insert_module()
 | 
        
           |  |  | 224 | {
 | 
        
           |  |  | 225 |    TARGET="$3/`basename $2`"
 | 
        
           |  |  | 226 |    while [ -e $TARGET ]; do TARGET=$TARGET.X; done
 | 
        
           |  |  | 227 |    mkdir -p $TARGET
 | 
        
           |  |  | 228 |    mount_module $2 $TARGET
 | 
        
           |  |  | 229 |    if [ $? -ne 0 ]; then echo "can't read module data"; return 1; fi
 | 
        
           |  |  | 230 |    union_insert_dir $1 $TARGET; 
 | 
        
           |  |  | 231 | }
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 | # Insert all .mo modules, in $2 directory and subdirectories, to the union
 | 
        
           |  |  | 234 | # $1 = union absolute path (starting with /)
 | 
        
           |  |  | 235 | # $2 = LiveCD data dir (with directories /base, /modules, etc.)
 | 
        
           |  |  | 236 | # $3 = destination folder, where images will be mounted to
 | 
        
           |  |  | 237 | #
 | 
        
           |  |  | 238 | union_insert_modules()
 | 
        
           |  |  | 239 | {
 | 
        
           | 38 | beyerle@PS | 240 |    PRINTK=`cat /proc/sys/kernel/printk`
 | 
        
           |  |  | 241 |    echo "0" >/proc/sys/kernel/printk
 | 
        
           |  |  | 242 |   | 
        
           | 1 | beyerle@PS | 243 |    list_modules $2 | while read MODULE; do
 | 
        
           |  |  | 244 |       echo " -> `basename $MODULE`"
 | 
        
           |  |  | 245 |       union_insert_module $1 $MODULE $3
 | 
        
           |  |  | 246 |    done
 | 
        
           | 38 | beyerle@PS | 247 |   | 
        
           |  |  | 248 |    echo "$PRINTK" >/proc/sys/kernel/printk
 | 
        
           | 1 | beyerle@PS | 249 | }
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 | # Copy modules to RAM directory
 | 
        
           |  |  | 252 | # $1 = data directory
 | 
        
           |  |  | 253 | # $2 = target directory in RAM
 | 
        
           |  |  | 254 | #
 | 
        
           |  |  | 255 | copy_to_ram()
 | 
        
           |  |  | 256 | {
 | 
        
           |  |  | 257 |    cp -R $1/* $2
 | 
        
           | 100 | beyerle@PS | 258 |    if [ $? -ne 0 ]; then fatal "can't copy to RAM, not enough memory?"; fi
 | 
        
           | 1 | beyerle@PS | 259 | }
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 | # Copy content of "rootcopy" directory on the CD to $2 (union, usually)
 | 
        
           |  |  | 262 | # $1 = source
 | 
        
           |  |  | 263 | # $2 = destination
 | 
        
           |  |  | 264 | #
 | 
        
           |  |  | 265 | copy_rootchanges()
 | 
        
           |  |  | 266 | {
 | 
        
           |  |  | 267 |    cp -a $1/rootcopy/* $2 2>/dev/null # could be empty
 | 
        
           |  |  | 268 | }
 | 
        
           |  |  | 269 |   | 
        
           |  |  | 270 | # ===========================================================
 | 
        
           |  |  | 271 | # discovery functions
 | 
        
           |  |  | 272 | # ===========================================================
 | 
        
           |  |  | 273 |   | 
        
           |  |  | 274 | # List all CD-ROMs
 | 
        
           |  |  | 275 | # by using /proc entries
 | 
        
           |  |  | 276 | #
 | 
        
           |  |  | 277 | list_cdrom_devices()
 | 
        
           |  |  | 278 | {
 | 
        
           |  |  | 279 |    if [ "`cmdline_parameter nocd`" != "" ]; then return 1; fi
 | 
        
           |  |  | 280 |    for CDDEVICE in `cat /proc/sys/dev/cdrom/info | head -n 3 | tail -n 1 | cut -d ":" -f 2`; do
 | 
        
           |  |  | 281 |       echo "/dev/$CDDEVICE"
 | 
        
           |  |  | 282 |    done
 | 
        
           |  |  | 283 | }
 | 
        
           |  |  | 284 |   | 
        
           |  |  | 285 | # List all partition devices
 | 
        
           |  |  | 286 | # take list of all partitions and output unique disks.
 | 
        
           |  |  | 287 | # Return empty result when nohd parameter was given.
 | 
        
           |  |  | 288 | #
 | 
        
           |  |  | 289 | list_partition_devices()
 | 
        
           |  |  | 290 | {
 | 
        
           |  |  | 291 |    if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
 | 
        
           |  |  | 292 |    cat /proc/partitions | grep -v loop | sed -r "s/^[0-9[:space:]]+/\/dev\//" | grep /dev/
 | 
        
           |  |  | 293 | }
 | 
        
           |  |  | 294 |   | 
        
           |  |  | 295 | # List all disk devices
 | 
        
           |  |  | 296 | #
 | 
        
           |  |  | 297 | list_disk_devices()
 | 
        
           |  |  | 298 | {
 | 
        
           |  |  | 299 |    list_partition_devices | egrep -v "[0-9]"
 | 
        
           |  |  | 300 | }
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 | # List all block devices
 | 
        
           |  |  | 303 | #
 | 
        
           |  |  | 304 | list_block_devices()
 | 
        
           |  |  | 305 | {
 | 
        
           |  |  | 306 |    list_cdrom_devices
 | 
        
           |  |  | 307 |    list_partition_devices
 | 
        
           |  |  | 308 | }
 | 
        
           |  |  | 309 |   | 
        
           |  |  | 310 | # Try to mount all disks, partitions and cdroms and Find where the LiveCD is.
 | 
        
           |  |  | 311 | # If LiveCD found in the device, echo dirname of it's directory,
 | 
        
           |  |  | 312 | # and leave the device mounted. Mounting is not ro, but without any argument.
 | 
        
           |  |  | 313 | # $1 = directory where devices will be mounted
 | 
        
           |  |  | 314 | # added: mount $NFSROOT to /$1/nfs if NFSROOT is set. and search there for LiveCD
 | 
        
           |  |  | 315 | #
 | 
        
           |  |  | 316 | find_live_data_dir()
 | 
        
           |  |  | 317 | {
 | 
        
           |  |  | 318 |    if [ "$NFSROOT" != "" ]; then 
 | 
        
           |  |  | 319 |       DIR="/$1/nfs"
 | 
        
           |  |  | 320 |       mkdir -p $DIR
 | 
        
           | 108 | beyerle@PS | 321 |   | 
        
           |  |  | 322 |       # disable kernel warnings
 | 
        
           |  |  | 323 |       PRINTK=`cat /proc/sys/kernel/printk`
 | 
        
           |  |  | 324 |       echo "0" >/proc/sys/kernel/printk
 | 
        
           |  |  | 325 |       # try to mount nfs dir
 | 
        
           | 1 | beyerle@PS | 326 |       mount -t nfs -o nolock,ro,rsize=8192,wsize=8192,hard,intr $NFSROOT $DIR
 | 
        
           | 108 | beyerle@PS | 327 |       # enable kernel warnings
 | 
        
           |  |  | 328 |       echo "$PRINTK" >/proc/sys/kernel/printk
 | 
        
           |  |  | 329 |   | 
        
           | 1 | beyerle@PS | 330 |       FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
 | 
        
           |  |  | 331 |       if [ "$FOUND" != "" ]; then 
 | 
        
           |  |  | 332 |          dirname "$FOUND"
 | 
        
           |  |  | 333 |       fi
 | 
        
           |  |  | 334 |    else
 | 
        
           |  |  | 335 |       list_block_devices | while read DEVICE; do
 | 
        
           |  |  | 336 |          DIR="/$1/`basename $DEVICE`"
 | 
        
           |  |  | 337 |          mount_device $DEVICE $DIR
 | 
        
           |  |  | 338 |          if [ $? -ne 0 ]; then continue; fi
 | 
        
           |  |  | 339 |          FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
 | 
        
           |  |  | 340 |          if [ "$FOUND" = "" ]; then umount $DIR 2>/dev/null; rmdir $DIR 2>/dev/null
 | 
        
           |  |  | 341 |          else dirname "$FOUND"; return 1; fi
 | 
        
           |  |  | 342 |       done
 | 
        
           |  |  | 343 |    fi
 | 
        
           |  |  | 344 | }
 | 
        
           |  |  | 345 |   | 
        
           |  |  | 346 | # ===========================================================
 | 
        
           |  |  | 347 | # hardware preparation functions
 | 
        
           |  |  | 348 | # ===========================================================
 | 
        
           |  |  | 349 |   | 
        
           |  |  | 350 | # Create block devices to /dev described by /sys entries
 | 
        
           |  |  | 351 | #
 | 
        
           |  |  | 352 | create_block_devices()
 | 
        
           |  |  | 353 | {
 | 
        
           |  |  | 354 |    echolog "creating /dev entries for block devices"
 | 
        
           |  |  | 355 |    ls -A1d /sys/block/*/dev /sys/block/*/*/dev 2>/dev/null | grep -v loop | while read BLOCK; do
 | 
        
           |  |  | 356 |       DEVICE="/dev/`basename \`dirname $BLOCK\``"
 | 
        
           |  |  | 357 |       if [ ! -b $DEVICE ]; then
 | 
        
           |  |  | 358 |          MINORMAJOR="`head -n 1 $BLOCK | tr ':' ' '`"
 | 
        
           |  |  | 359 |          mknod $DEVICE b $MINORMAJOR
 | 
        
           |  |  | 360 |       fi
 | 
        
           |  |  | 361 |    done
 | 
        
           |  |  | 362 | }
 | 
        
           |  |  | 363 |   | 
        
           |  |  | 364 | # modprobe kernel modules needed for the LiveCD
 | 
        
           |  |  | 365 | #
 | 
        
           |  |  | 366 | modprobe_essential_modules()
 | 
        
           |  |  | 367 | {
 | 
        
           |  |  | 368 |    echolog "starting loop device support"
 | 
        
           | 109 | beyerle@PS | 369 |    modprobe_module loop max_loop=32
 | 
        
           | 1 | beyerle@PS | 370 |    echolog "starting cdrom support"
 | 
        
           |  |  | 371 |    modprobe_module ide_cd
 | 
        
           |  |  | 372 |    modprobe_module ide-cd
 | 
        
           |  |  | 373 |    modprobe_module sr_mod
 | 
        
           |  |  | 374 |    modprobe_module cdrom
 | 
        
           |  |  | 375 |    echolog "starting cdrom filesystem support"
 | 
        
           |  |  | 376 |    modprobe_module isofs
 | 
        
           |  |  | 377 |    echolog "starting squashfs support"
 | 
        
           |  |  | 378 |    modprobe_module squashfs
 | 
        
           | 37 | beyerle@PS | 379 |    echolog "starting unionfs/aufs support"
 | 
        
           | 1 | beyerle@PS | 380 |    modprobe_module unionfs
 | 
        
           | 37 | beyerle@PS | 381 |    modprobe_module aufs
 | 
        
           | 1 | beyerle@PS | 382 |    echolog "starting vfat support"
 | 
        
           |  |  | 383 |    modprobe_module nls_cp437
 | 
        
           |  |  | 384 |    modprobe_module nls_iso8859-1
 | 
        
           |  |  | 385 |    modprobe_module nls_iso8859-2
 | 
        
           |  |  | 386 |    modprobe_module vfat
 | 
        
           |  |  | 387 |    echolog "starting ntfs support"
 | 
        
           |  |  | 388 |    modprobe_module ntfs
 | 
        
           |  |  | 389 |    create_block_devices
 | 
        
           |  |  | 390 | }
 | 
        
           |  |  | 391 |   | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 | # modprobe kernel modules needed for USB masstorage devices
 | 
        
           |  |  | 394 | #
 | 
        
           |  |  | 395 | modprobe_usb_sata_modules()
 | 
        
           |  |  | 396 | {
 | 
        
           |  |  | 397 |    echolog "starting USB and SATA support"
 | 
        
           |  |  | 398 |    modprobe_module ehci-hcd
 | 
        
           |  |  | 399 |    modprobe_module ohci-hcd
 | 
        
           |  |  | 400 |    modprobe_module uhci-hcd
 | 
        
           |  |  | 401 |    modprobe_module scsi_mod
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 |    modprobe_module libata
 | 
        
           | 85 | beyerle@PS | 404 |    modprobe_module ata_piix
 | 
        
           | 1 | beyerle@PS | 405 |    modprobe_module ahci
 | 
        
           | 116 | beyerle@PS | 406 |    modprobe_module sg
 | 
        
           | 1 | beyerle@PS | 407 |   | 
        
           |  |  | 408 |    modprobe_module sd_mod
 | 
        
           |  |  | 409 |    modprobe_module sr_mod
 | 
        
           |  |  | 410 |    modprobe_module usb-storage
 | 
        
           |  |  | 411 |    echolog "waiting for USB devices, max 9 seconds"
 | 
        
           |  |  | 412 |    sleep 9
 | 
        
           |  |  | 413 |    create_block_devices
 | 
        
           |  |  | 414 | }
 | 
        
           |  |  | 415 |   | 
        
           |  |  | 416 | # modprobe nfs kernel modules
 | 
        
           |  |  | 417 | #
 | 
        
           |  |  | 418 | modprobe_nfs_modules()
 | 
        
           |  |  | 419 | {
 | 
        
           |  |  | 420 |    echolog "starting nfs support"
 | 
        
           |  |  | 421 |    modprobe_module lockd
 | 
        
           |  |  | 422 |    modprobe_module fscache
 | 
        
           |  |  | 423 |    modprobe_module nfs_acl
 | 
        
           |  |  | 424 |    modprobe_module nfs
 | 
        
           |  |  | 425 | }
 | 
        
           |  |  | 426 |   | 
        
           |  |  | 427 | # enable/disable CD autoejecting when unmounted
 | 
        
           |  |  | 428 | # $1 = 1|0 ... enable|disable
 | 
        
           |  |  | 429 | #
 | 
        
           |  |  | 430 | cd_autoeject()
 | 
        
           |  |  | 431 | {
 | 
        
           |  |  | 432 |    echo $1 >/proc/sys/dev/cdrom/autoeject
 | 
        
           |  |  | 433 | }
 | 
        
           |  |  | 434 |   | 
        
           |  |  | 435 | # Disable DMA if nodma boot parameter is present
 | 
        
           |  |  | 436 | #
 | 
        
           |  |  | 437 | setup_dma()
 | 
        
           |  |  | 438 | {
 | 
        
           |  |  | 439 |    if [ ! "`cmdline_parameter nodma`" = "" ]; then
 | 
        
           |  |  | 440 |       for DEVICE in `list_cdrom_devices` `list_disk_devices`; do
 | 
        
           |  |  | 441 |          echolog "setting DMA support off for $DEVICE"
 | 
        
           |  |  | 442 |          hdparm -d 0 $DEVICE
 | 
        
           |  |  | 443 |       done
 | 
        
           |  |  | 444 |    fi
 | 
        
           |  |  | 445 | }
 | 
        
           |  |  | 446 |   | 
        
           |  |  | 447 | # create correct fstab file in $1/etc/fstab and create apropriate
 | 
        
           |  |  | 448 | # mount directories in $1
 | 
        
           |  |  | 449 | # $1 = root directory (union)
 | 
        
           |  |  | 450 | #
 | 
        
           |  |  | 451 | activate_fstab()
 | 
        
           |  |  | 452 | {
 | 
        
           |  |  | 453 |    mkdir -p $1/etc
 | 
        
           |  |  | 454 |    FSTAB="$1/etc/fstab"
 | 
        
           |  |  | 455 |    echo "tmpfs            /                tmpfs       defaults         0   0" >$FSTAB
 | 
        
           |  |  | 456 |    echo "devpts           /dev/pts         devpts      gid=5,mode=620   0   0" >>$FSTAB
 | 
        
           |  |  | 457 |    echo "proc             /proc            proc        defaults         0   0" >>$FSTAB
 | 
        
           |  |  | 458 |   | 
        
           | 48 | beyerle@PS | 459 |    # all the rest will be done by runlast or by fstab-sync
 | 
        
           |  |  | 460 |    # search for SWAP done later in /etc/rc.sysinit
 | 
        
           |  |  | 461 | }
 | 
        
           | 1 | beyerle@PS | 462 |   | 
        
           |  |  | 463 |   | 
        
           | 48 | beyerle@PS | 464 | # ===========================================================
 | 
        
           |  |  | 465 | # functions used for LiveCD on NFS 
 | 
        
           |  |  | 466 | # ===========================================================
 | 
        
           | 1 | beyerle@PS | 467 |   | 
        
           | 37 | beyerle@PS | 468 | # load network modules, if NFSROOT is set
 | 
        
           |  |  | 469 | # Urs Beyerle, PSI
 | 
        
           | 48 | beyerle@PS | 470 | #
 | 
        
           | 100 | beyerle@PS | 471 |   | 
        
           | 104 | beyerle@PS | 472 | # 1. load network driver defined by kernel parameter nic
 | 
        
           |  |  | 473 | #
 | 
        
           |  |  | 474 | load_network_module_nic()
 | 
        
           | 37 | beyerle@PS | 475 | {
 | 
        
           | 104 | beyerle@PS | 476 |     if [ -n "$NIC" ] && [ "$NIC" != "auto" ]; then
 | 
        
           | 100 | beyerle@PS | 477 | 	echolog "load module $NIC"
 | 
        
           | 104 | beyerle@PS | 478 | 	modprobe_module $NIC
 | 
        
           |  |  | 479 |         # FOUND_NIC="yes" # we are not yet sure ;-)
 | 
        
           | 100 | beyerle@PS | 480 |     fi
 | 
        
           | 104 | beyerle@PS | 481 | }
 | 
        
           | 100 | beyerle@PS | 482 |   | 
        
           | 104 | beyerle@PS | 483 | # 2. detecting network card from pcitable list
 | 
        
           |  |  | 484 | #
 | 
        
           |  |  | 485 | load_network_module_pcitable()
 | 
        
           |  |  | 486 | {
 | 
        
           | 37 | beyerle@PS | 487 |     PCITABLE=/bin/pcitable
 | 
        
           |  |  | 488 |     NICS=`lspci -n | awk '/Class 0200/ {print $4}' | tr ':' ' ' \
 | 
        
           |  |  | 489 | 	| while read x y ; do grep "0x$x.*0x$y" $PCITABLE \
 | 
        
           |  |  | 490 | 	| awk '$3 !~ /"unknown"/ {print $3}' | tr -d '"' ; done`
 | 
        
           |  |  | 491 |   | 
        
           |  |  | 492 |     if [ -n "$NICS" ]; then
 | 
        
           | 100 | beyerle@PS | 493 | 	echolog "found network card(s): $NICS"
 | 
        
           | 104 | beyerle@PS | 494 | 	for driver in $NICS; do
 | 
        
           |  |  | 495 | 	    echolog "load module $driver"
 | 
        
           |  |  | 496 | 	    modprobe_module $driver
 | 
        
           |  |  | 497 | 	    FOUND_NIC="$driver"
 | 
        
           | 37 | beyerle@PS | 498 | 	done
 | 
        
           | 100 | beyerle@PS | 499 |     fi
 | 
        
           | 104 | beyerle@PS | 500 | }
 | 
        
           | 100 | beyerle@PS | 501 |   | 
        
           | 104 | beyerle@PS | 502 | found_nic()
 | 
        
           |  |  | 503 | {
 | 
        
           | 100 | beyerle@PS | 504 |     for iface in eth0 eth1 eth2 eth3; do
 | 
        
           |  |  | 505 | 	ifconfig $iface > /dev/null 2>&1
 | 
        
           |  |  | 506 | 	if [ $? -eq 0 ]; then  FOUND_NIC="yes"; break; fi
 | 
        
           |  |  | 507 |     done
 | 
        
           | 104 | beyerle@PS | 508 | }
 | 
        
           |  |  | 509 |   | 
        
           |  |  | 510 | # 3. probe for more network card drivers, if no ethX devices found
 | 
        
           |  |  | 511 | #
 | 
        
           |  |  | 512 | load_network_module_auto()
 | 
        
           |  |  | 513 | {
 | 
        
           |  |  | 514 |     echolog "auto-detection of network driver ..."
 | 
        
           |  |  | 515 |     KERNEL="`uname -r`"
 | 
        
           |  |  | 516 |     NETDRIVERS="`find /lib/modules/$KERNEL/kernel/drivers/net | grep -v mii | grep .ko | cut -d"/" -f8 | cut -d"." -f1 | uniq`"
 | 
        
           |  |  | 517 |     for driver in $NETDRIVERS; do
 | 
        
           |  |  | 518 | 	modprobe_module $driver > /dev/null 2>&1
 | 
        
           |  |  | 519 | 	for iface in eth0 eth1 eth2 eth3; do
 | 
        
           | 100 | beyerle@PS | 520 | 	    ifconfig $iface > /dev/null 2>&1
 | 
        
           |  |  | 521 | 	    if [ $? -eq 0 ]; then 
 | 
        
           |  |  | 522 | 		echolog "load $driver"
 | 
        
           | 104 | beyerle@PS | 523 | 		# tr brocken in busybox
 | 
        
           |  |  | 524 | 		# FOUND_NIC="`echo $driver | tr '-' '_'`"
 | 
        
           |  |  | 525 | 		FOUND_NIC="`echo $driver | cut -d"-" -f1`"
 | 
        
           |  |  | 526 | 		break 2
 | 
        
           | 100 | beyerle@PS | 527 | 	    fi
 | 
        
           |  |  | 528 | 	done
 | 
        
           | 104 | beyerle@PS | 529 | 	rmmod $driver > /dev/null 2>&1
 | 
        
           |  |  | 530 |     done
 | 
        
           |  |  | 531 |   | 
        
           |  |  | 532 |     # clean up: remove unused modules until driver "mii"
 | 
        
           |  |  | 533 |     LOADED_DRIVERS="`lsmod | grep -v Module | grep -v $FOUND_NIC | cut -d" " -f1`"
 | 
        
           |  |  | 534 |     for driver in $LOADED_DRIVERS; do
 | 
        
           |  |  | 535 | 	[ "$driver" = "mii" ]  && break
 | 
        
           |  |  | 536 | 	[ "$driver" = "ntfs" ] && break
 | 
        
           |  |  | 537 | 	[ "$driver" = "vfat" ] && break
 | 
        
           |  |  | 538 | 	rmmod $driver > /dev/null 2>&1
 | 
        
           |  |  | 539 |     done
 | 
        
           | 37 | beyerle@PS | 540 | }
 | 
        
           |  |  | 541 |   | 
        
           | 104 | beyerle@PS | 542 | # 4. ask the user for a network driver
 | 
        
           |  |  | 543 | #
 | 
        
           |  |  | 544 | load_network_module_ask()
 | 
        
           |  |  | 545 | {
 | 
        
           |  |  | 546 |     echo "ERROR: No network card detected!"
 | 
        
           |  |  | 547 |     echo "Type in your network card driver (e.g. tg3, e1000). "
 | 
        
           |  |  | 548 |     echo "Or ask your system administrator for help."
 | 
        
           |  |  | 549 |     echo -n "Network card driver: "
 | 
        
           |  |  | 550 |     read driver
 | 
        
           |  |  | 551 |     echo "Load module $driver"
 | 
        
           |  |  | 552 |     modprobe_module $driver
 | 
        
           |  |  | 553 | }
 | 
        
           |  |  | 554 |   | 
        
           |  |  | 555 | # Try to find a network driver
 | 
        
           |  |  | 556 | #
 | 
        
           |  |  | 557 | load_network_modules()
 | 
        
           |  |  | 558 | {
 | 
        
           |  |  | 559 |     # mii maybe need by NIC
 | 
        
           |  |  | 560 |     echolog "load module mii"
 | 
        
           |  |  | 561 |     modprobe_module mii
 | 
        
           |  |  | 562 |   | 
        
           |  |  | 563 |     FOUND_NIC=""
 | 
        
           |  |  | 564 |     NIC="`cmdline_value nic`"
 | 
        
           |  |  | 565 |     load_network_module_nic
 | 
        
           |  |  | 566 |     [ "$NIC" != "auto" ] && load_network_module_pcitable
 | 
        
           |  |  | 567 |     found_nic
 | 
        
           |  |  | 568 |     [ -z $FOUND_NIC ] && load_network_module_auto
 | 
        
           |  |  | 569 |     [ -z $FOUND_NIC ] && load_network_module_ask
 | 
        
           |  |  | 570 |   | 
        
           |  |  | 571 |     # remove mii, if not needed
 | 
        
           |  |  | 572 |     rmmod mii > /dev/null 2>&1
 | 
        
           |  |  | 573 | }
 | 
        
           |  |  | 574 |   | 
        
           | 37 | beyerle@PS | 575 | # get DHCP lease
 | 
        
           |  |  | 576 | # Urs Beyerle, PSI
 | 
        
           | 48 | beyerle@PS | 577 | #
 | 
        
           | 37 | beyerle@PS | 578 | get_dhcp_lease()
 | 
        
           |  |  | 579 | {
 | 
        
           |  |  | 580 |     # create /dev/urandom (needed by udhcpc)
 | 
        
           |  |  | 581 |     mknod /dev/urandom c 1 9
 | 
        
           | 102 | beyerle@PS | 582 |     for iface in eth0 eth0 eth1 eth1; do
 | 
        
           |  |  | 583 | 	echolog "Try to get DHCP lease on $iface"
 | 
        
           |  |  | 584 | 	udhcpc --now --quit --interface=$iface --script=/bin/udhcpc.script
 | 
        
           |  |  | 585 | 	[ $? -eq 0 ] && return
 | 
        
           | 37 | beyerle@PS | 586 | 	echo "ERROR: couldn't get DHCP lease, trying again"
 | 
        
           | 102 | beyerle@PS | 587 |     done
 | 
        
           |  |  | 588 |     echo "ERROR: can't get DHCP lease on eth0 and eth1"
 | 
        
           | 37 | beyerle@PS | 589 | }
 | 
        
           |  |  | 590 |   |