home *** CD-ROM | disk | FTP | other *** search
/ host-198-236-40-254.wlwv.k12.or.us / host-198-236-40-254.wlwv.k12.or.us.tar / host-198-236-40-254.wlwv.k12.or.us / tsu / BareMetalInstall.iso / tools / liblinuxlive < prev    next >
Text File  |  2012-12-18  |  17KB  |  583 lines

  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. #determine which mksquashfs is being called
  7. export BUILD_BIN_DIR=$HOST_BUILD_BIN_DIR
  8.  
  9. # ===========================================================
  10. # variables
  11. # ===========================================================
  12.  
  13. # linux live flag to fstab, if fstab line doesn't contain it,
  14. # never remove it from fstab automatically (user added it)
  15. FSTABLLFLAG="# AutoUpdate"
  16.  
  17. # We have to set these variables very carefully
  18. UNION=union
  19. MEMORY=memory
  20. MOUNTDIR=mnt
  21. CHANGES=$MEMORY/changes
  22. COPY2RAM=$MEMORY/copy2ram
  23. IMAGES=$MEMORY/images
  24. INITRAMDISK=$MOUNTDIR/live
  25. ISOMOUNT=$MOUNTDIR/iso
  26. LIVECDSGN=livecd.sgn
  27.  
  28. # ===========================================================
  29. # user interface functions
  30. # ===========================================================
  31.  
  32. # echogreen will echo $@ in green color
  33. # $1 = text
  34. #
  35. echogreen()
  36. {
  37.    echo -ne """$@"""
  38. }
  39.  
  40. # echolog
  41. # $1 = text to show and to write to /var/log/messages
  42. #
  43. echolog()
  44. {
  45.    if [ "$1" != "" ]; then
  46.       echogreen "* "
  47.       if [ "$LIVEDBG_LOGFILE" = "" ]; then
  48.         echo "LIVECD:" "$@" >>/var/log/livedbg
  49.       else
  50.         echo "LIVECD:" "$@" >>$LIVEDBG_LOGFILE; fi
  51.       echo "$@"
  52.    fi
  53. }
  54.  
  55. # debug
  56. # commands executed when debug boot parameter is present
  57. #
  58. debug()
  59. {
  60.    echo
  61.    echo "====="
  62.    echo ": Debugging started. Here is the root shell for you."
  63.    echo ": Type your desired command or hit Ctrl+D to continue booting."
  64.    echo
  65.    ash < /dev/console
  66.    echo
  67. }
  68.  
  69. # header
  70. # $1 = text to show
  71. #
  72. header()
  73. {
  74.    echo """$@"""
  75. }
  76.  
  77. fatal()
  78. {
  79.    echolog
  80.    header "Fatal error occured - $1"
  81.    echolog "Something went wrong and we can't continue. This should never happen."
  82.    echolog "Please reboot your computer with Ctrl+Alt+Delete ..."
  83.    echolog
  84.    umount -a -r
  85.    mount -t proc proc /proc
  86.    mount -t sysfs sysfs /sys
  87.    ash < /dev/console
  88. }
  89.  
  90. allow_only_root()
  91. {
  92.   # test if the script is started by root user. If not, exit
  93.   if [ "0$UID" -ne 0 ]; then
  94.      echo "Only root can run `basename $0`"; exit 1
  95.   fi
  96. }
  97.  
  98. # ===========================================================
  99. # text processing functions
  100. # ===========================================================
  101.  
  102. # egrep_o is a replacement for "egrep -o". It prints only the last
  103. # matching text
  104. # $1 = regular expression
  105. #
  106. egrep_o()
  107. {
  108.    SED="`echo \"$1\" | sed -r 's/\\//\\\\\\//g'`"
  109.    cat | egrep "$1" | sed -r "s/.*$SED.*/\\1/" 2>/dev/null
  110. }
  111.  
  112. # look into cmdline and echo $1 back if $1 is set
  113. # $1 = value name, case sensitive, for example livecd_subdir
  114. # $2 = file to use instead /proc/cmdline, optional
  115. #
  116. cmdline_parameter()
  117. {
  118.    CMDLINE=/proc/cmdline
  119.    if [ "$2" != "" ]; then CMDLINE="$2"; fi
  120.    cat "$CMDLINE" | egrep_o "((^|[[:space:]]+)$1(\$|=|[[:space:]]+))" | egrep_o "($1)"
  121. }
  122.  
  123. # look into cmdline and echo value of $1 option
  124. # $1 = value name, case sensitive, for example livecd_subdir
  125. # $2 = file to use instead /proc/cmdline, optional
  126. #
  127. cmdline_value()
  128. {
  129.    CMDLINE=/proc/cmdline
  130.    if [ "$2" != "" ]; then CMDLINE="$2"; fi
  131.    cat "$CMDLINE" | egrep_o "((^|[[:space:]]+)$1=([^[:space:]]+))" | egrep_o "(=.*)" | cut -b 2- | tail -n 1
  132. }
  133.  
  134. # ===========================================================
  135. # system functions
  136. # ===========================================================
  137.  
  138. # modprobe module $1, including all dependencies, suppress all messages
  139. # (own function because modprobe in busybox doesn't work with gzipped modules)
  140. # $1 = module name, eg. ehci-hcd
  141. # $2 = optional argument
  142. #
  143. modprobe_module()
  144. {
  145.   if [ "$1" = "" ]; then return 1; fi
  146.   PRINTK=`cat /proc/sys/kernel/printk`
  147.   echo "7" >/proc/sys/kernel/printk
  148.  
  149.   KERNEL="`uname -r`"; LSMOD=/tmp/_lsmod
  150.   MODULEDEPS="`cat /lib/modules/$KERNEL/modules.dep | egrep \"$1\\.ko(\\.gz)?:\"`"
  151.  
  152.   for MODULE in `echo $MODULEDEPS | cut -d ":" -f 2-` `echo $MODULEDEPS | cut -d ":" -f 1`; do
  153.      TMPMOD="/tmp/j/`basename $MODULE .gz`";
  154.      # if the module is not loaded already
  155.      if [ "`cat $LSMOD 2>/dev/null | egrep \"^$TMPMOD\\\$\"`" = "" ]; then
  156.     mkdir -p /tmp/j
  157.     mount -t tmpfs tmpfs /tmp/j
  158.         gunzip -c $MODULE 2>/dev/null >$TMPMOD
  159.         if [ 0$? -ne 0 ]; then cp $MODULE $TMPMOD; fi # can't gunzip? copy
  160.         insmod $TMPMOD $2 >/dev/null 2>/dev/null; err=$?
  161.         if [ 0$err -eq 0 ]; then echo $TMPMOD >>$LSMOD; fi # module log
  162.         rm $TMPMOD
  163.     umount /tmp/j
  164.     rmdir /tmp/j
  165.      fi
  166.   done
  167.  
  168.   echo "$PRINTK" >/proc/sys/kernel/printk
  169.   if [ 0$err -ne 0 ]; then echolog "error inserting module $1 ($err) for your kernel `uname -r`"; fi
  170.   return $err
  171. }
  172.  
  173. # Mount device $1 to $2
  174. # $1 = /dev device to mount, eg. /dev/hda1, or loop file, or directory
  175. # $2 = mountpoint, eg. /mnt/hda1
  176. # $3 = optional mount options, for example "ro", or "remount,rw"
  177. # $4 = optional filesystem type
  178. #
  179. mount_device()
  180. {
  181.   # make sure we have enough arguments
  182.   if [ "$2" = "" ]; then return 1; fi
  183.  
  184.   mkdir -p "$2"
  185.   if [ -f "$1" ]; then LOOP="-o loop"; else LOOP=""; fi
  186.   if [ -d "$1" ]; then LOOP="-o rbind"; fi
  187.   if [ "$OPTIONS" ]; then OPTIONS="-o $3"; else OPTIONS=""; fi
  188.   if [ "$4" ]; then FILESYSTEM="-t $4"; else FILESYSTEM=""; fi
  189.  
  190.   PRINTK=`cat /proc/sys/kernel/printk`
  191.   echo "0" >/proc/sys/kernel/printk
  192.  
  193.   mount $FILESYSTEM "$1" "$2" $OPTIONS $LOOP >/dev/null 2>/dev/null
  194.   err=$?
  195.  
  196.   if [ 0$err -ne 0 ]; then rmdir $2 2>/dev/null; fi
  197.   echo "$PRINTK" >/proc/sys/kernel/printk
  198.   return $err
  199. }
  200.  
  201. # Force unmount of all parameters
  202. # $1..$n = directories to be unmounted
  203. #
  204. fumount()
  205. {
  206.    while [ "$1" ]; do
  207.       umount "$1" >/dev/null 2>&1
  208.       if [ 0$? -ne 0 ]; then
  209.          umount -l "$1" >/dev/null 2>&1
  210.       fi
  211.       shift
  212.    done
  213. }
  214.  
  215. # ===========================================================
  216. # live module functions
  217. # ===========================================================
  218.  
  219. # Create module
  220. # call mksquashfs with apropriate arguments
  221. # $1 = directory which will be compressed to squashfs module
  222. # $2 = output .mo file
  223. # $3 = optional -keep-as-directory argument
  224. #
  225. create_module()
  226. {
  227.    if [ -x $BUILD_BIN_DIR/mksquashfs ] ; then
  228.      $BUILD_BIN_DIR/mksquashfs "$1" "$2" $3 >/dev/null
  229.    else
  230.      mksquashfs "$1" "$2" $3 >/dev/null
  231.    fi
  232.    if [ 0$? -ne 0 ]; then return 1; fi
  233.    chmod oga-x "$2" # remove execute attrib
  234. }
  235.  
  236. # Mountpoint exits with 0 if $1 is mountpoint, else exits with 1
  237. # $1 = directory
  238. #
  239. mountpoint()
  240. {
  241.    cat /proc/mounts | cut -d " " -f 2 | egrep "^$1\$" >/dev/null 2>&1
  242. }
  243.  
  244. # Mount .mo module to destination directory
  245. # $1 = path to .mo livecd compressed module
  246. # $2 = destination folder
  247. #
  248. mount_module()
  249. {
  250.    mount -t squashfs -o loop,ro "$1" "$2"
  251.    err=$?
  252.    if [ 0$err -eq 0 ]; then
  253.       echo "$1 $2" >>/tmp/_mounts
  254.    fi
  255.    return $err
  256. }
  257.  
  258. # Insert a directory tree $2 to an union specified by $1
  259. # Top-level read-write branch is specified by it's index 0
  260. # $1 = union absolute path (starting with /)
  261. # $2 = path to data directory
  262. #
  263. union_insert_dir()
  264. {
  265.    mount -n -t unionfs -o remount,add=:"$2"=ro none "$1"
  266. }
  267.  
  268. # List all modules in all directories (base, modules, optional)
  269. # and filter out unneeded optional modules (not specified by load= kernel parameter)
  270. # separator for load and noload arguments is "," or ";"
  271. # $1 = root directory of mounted DATAdir
  272. #
  273. list_modules()
  274. {
  275.    LOAD="`cmdline_value load | sed -r 's/\*/.\*/g' | sed -r 's/,|;/|/g'`"
  276.    NOLOAD="`cmdline_value noload | sed -r 's/\*/.\*/g' | sed -r 's/,|;/|/g'`"
  277.    find $1/base $1/modules $1/optional -name "*.mo" 2>/dev/null | sort | while read LINE; do
  278.       MODNAME="`echo $LINE | cut -b ${#1}- | cut -b 2-`"
  279.       if [ "`echo $LINE | grep /optional/`" ]; then
  280.          if [ ! "$LOAD" -o ! "`echo $MODNAME | egrep -i \"$LOAD\"`" ]; then continue; fi
  281.       fi
  282.       if [ "$NOLOAD" -a "`echo $MODNAME | egrep -i \"$NOLOAD\"`" ]; then continue; fi
  283.       echo $LINE
  284.    done
  285. }
  286.  
  287. # Insert one single .mo module to the union
  288. # $1 = union absolute path
  289. # $2 = module.mo full path
  290. # $3 = destination folder, where images will be mounted to
  291. # $4 = preffix length strip (number of characters)
  292. #
  293. union_insert_module()
  294. {
  295.    TARGET="$3/`basename $2`"
  296.    if mountpoint $TARGET >/dev/null 2>&1; then return; fi # skip mounted modules
  297.    mkdir -p $TARGET
  298.    mount_module $2 $TARGET
  299.    if [ 0$? -ne 0 ]; then echo "Cannot read module data. corrupted download?" >&2; return 1; fi
  300.    union_insert_dir $1 $TARGET
  301.    if [ 0$? -ne 0 ]; then echo "can't insert module to union" >&2; return 2; fi
  302.    echo "$2" | cut -b $4- | cut -b 2-
  303.    echolog "$2" >/dev/null
  304.    return 0
  305. }
  306.  
  307. # Insert all .mo modules, in $2 directory and subdirectories, to the union
  308. # $1 = union absolute path (starting with /)
  309. # $2 = LiveCD data dir (with directories /base, /modules, etc.)
  310. # $3 = destination folder, where images will be mounted to
  311. #
  312. union_insert_modules()
  313. {
  314.    list_modules $2 | while read MODULE; do
  315.       echolog -n " -> "
  316.       union_insert_module $1 $MODULE $3 ${#2}
  317.    done
  318. }
  319.  
  320. # Copy LiveCD modules to RAM directory
  321. # will copy only /boot, and module files from $1
  322. # $1 = data directory
  323. # $2 = target directory in RAM
  324. #
  325. copy_to_ram()
  326. {
  327.    cp -a "$1/rootcopy" "$2" 2>/dev/null # could be empty
  328.    list_modules "$1" | while read MODULE; do
  329.       TARGET="$2/`basename \`dirname $MODULE\``"
  330.       mkdir -p "$TARGET"
  331.       cp "$MODULE" "$TARGET"
  332.       if [ $? -ne 0 ]; then fatal "Not enough memory. Using ramsize=$RAMSIZE"; fi
  333.    done
  334. }
  335.  
  336. # ===========================================================
  337. # discovery functions
  338. # ===========================================================
  339.  
  340. # List all CD-ROMs
  341. # by using /proc entries
  342. #
  343. list_cdrom_devices()
  344. {
  345.    if [ "`cmdline_parameter nocd`" != "" ]; then return 1; fi
  346.    for CDDEVICE in `cat /proc/sys/dev/cdrom/info 2>/dev/null | head -n 3 | tail -n 1 | cut -d ":" -f 2`; do
  347.       echo "/dev/$CDDEVICE"
  348.    done
  349. }
  350.  
  351. # List all devices with filesystems
  352. # Return empty result when nohd parameter was given.
  353. #
  354. list_partition_devices()
  355. {
  356.    if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
  357.    cat /proc/partitions | grep -v loop |grep -v major | grep -v "^\$" | sed -r "s/^[0-9 ]+/\\/dev\\//"
  358. }
  359.  
  360. # List all disk devices
  361. #
  362. list_disk_devices()
  363. {
  364.    list_partition_devices | egrep -v "[0-9]"
  365. }
  366.  
  367. # List all partitions marked as Linux Swap
  368. #
  369. list_swap_devices()
  370. {
  371.    if [ "`cmdline_parameter nohd`" != "" -o "`cmdline_parameter noswap`" != "" ]; then return 1; fi
  372.    blkid -t TYPE="swap" | cut -d : -f 1
  373. }
  374.  
  375. # List all block devices
  376. #
  377. list_block_devices()
  378. {
  379.    list_cdrom_devices
  380.    list_partition_devices
  381. }
  382.  
  383. # Find file-path on given device
  384. # Mounts the device in $1 and returns path if found,
  385. # else unmounts and exits
  386. # $1 = mountpoint, eg. /mnt
  387. # $2 = device
  388. # $3 = path/filename
  389. #
  390. find_filepath()
  391. {
  392.    DIR="$1/`basename $2`"
  393.    mount_device $2 $DIR
  394.    if [ 0$? -ne 0 ]; then rmdir $DIR 2>/dev/null; return 1; fi
  395.    FOUND="`ls -A1d $DIR/$3 2>/dev/null | head -n 1`"
  396.    if [ "$FOUND" = "" ]; then umount $DIR 2>/dev/null; rmdir $DIR 2>/dev/null; return 1
  397.    else echo "$FOUND" | tr -s '/'; return 0; fi
  398. }
  399.  
  400. # Find file in computer by mounting disks or other storage devices in $1
  401. # and searching for $2 in the mounted directory
  402. # $1 = mountpoint, eg. /mnt
  403. # $2 = filename or device-path or devicepath/filename
  404. #
  405. find_file()
  406. {
  407.    # if parameter is just a device, echo it and exit
  408.    if [ -b "$2" -o -c "$2" -o "$2" = "" ]; then echo "$2"; return; fi
  409.    # if path doesn't start with /dev/, find the path exactly on all devices
  410.  
  411.    # split DEV/PATH parts
  412.    DEVPART="`echo \"$2\" | egrep_o \"(^/dev/[^/]+)\"`"
  413.  
  414.    if [ "$DEVPART" = "" ]; then
  415.       # no device is specified, search all devices for filename $1
  416.       PATHPART="$2";
  417.       list_block_devices | while read DEVICE; do
  418.          find_filepath $1 $DEVICE $PATHPART
  419.          if [ 0$? -eq 0 ]; then return 0; fi
  420.       done
  421.    else
  422.       # try to find PATHPART only on the given device
  423.       PATHPART="`echo \"$2\" | egrep_o \"^/dev/[^/]+/(.*)\"`"
  424.       find_filepath $1 $DEVPART $PATHPART
  425.    fi
  426. }
  427.  
  428. # ===========================================================
  429. # hardware preparation functions
  430. # ===========================================================
  431.  
  432. # Create block devices to /dev described by /sys entries
  433. #
  434. create_block_devices()
  435. {
  436.    echolog "creating /dev entries for block devices"
  437.    ls -A1d /sys/block/*/dev /sys/block/*/*/dev 2>/dev/null | grep -v loop | while read BLOCK; do
  438.       DEVICE="/dev/`basename \`dirname $BLOCK\``"
  439.       if [ ! -b $DEVICE ]; then
  440.          MINORMAJOR="`head -n 1 $BLOCK | tr ':' ' '`"
  441.          mknod $DEVICE b $MINORMAJOR
  442.       fi
  443.    done
  444. }
  445.  
  446. # modprobe kernel modules needed for the LiveCD
  447. #
  448. modprobe_essential_modules()
  449. {
  450.    echolog "starting loop device support"
  451.    modprobe_module loop max_loop=255
  452.    echolog "starting cdrom filesystem support"
  453.    modprobe_module isofs
  454.    echolog "starting squashfs support"
  455.    modprobe_module squashfs
  456.    echolog "starting unionfs support"
  457.    modprobe_module unionfs
  458.    modprobe_module ide-cd
  459.    echolog "starting vfat support"
  460.    modprobe_module nls_cp437
  461.    modprobe_module nls_iso8859-1
  462.    modprobe_module nls_iso8859-2
  463.    modprobe_module vfat
  464.    echolog "starting ntfs support"
  465.    modprobe_module ntfs
  466.    echolog "starting USB Core"
  467.    modprobe_module usbcore
  468.    modprobe_module ehci-hcd
  469.    modprobe_module ohci-hcd
  470.    modprobe_module uhci-hcd
  471.    modprobe_module usbhid
  472.    create_block_devices
  473. }
  474.  
  475. # modprobe kernel modules needed for USB masstorage devices
  476. #
  477. modprobe_usb_modules()
  478. {
  479.    SLEEP="`cmdline_value probeusb | sed -r 's/[^0-9]*([0-9]+).*/\1/'`"
  480.    if [ "$SLEEP" = "" ]; then SLEEP=5; fi
  481.  
  482.    echolog "starting USB support"
  483.    modprobe_module usb-storage
  484.    sleep $SLEEP
  485.    create_block_devices
  486. }
  487.  
  488. # enable/disable CD autoejecting when unmounted
  489. # $1 = 1|0 ... enable|disable
  490. #
  491. cd_autoeject()
  492. {
  493.    echo $1 >/proc/sys/dev/cdrom/autoeject
  494. }
  495.  
  496. # Disable DMA if nodma boot parameter is present
  497. #
  498. setup_dma()
  499. {
  500.    if [ ! "`cmdline_parameter nodma`" = "" ]; then
  501.       for DEVICE in `list_cdrom_devices` `list_disk_devices`; do
  502.          echolog "setting DMA support off for $DEVICE"
  503.          hdparm -d 0 $DEVICE
  504.       done
  505.    fi
  506. }
  507.  
  508. # update given line in fstab, add new values only if the device is not found
  509. # $1 = fstab file to parse
  510. # $2 = device name
  511. # $3 = mountpoint
  512. # $4 = filesystem
  513. # $5 = mount options
  514. #
  515. fstab_update_line()
  516. {
  517.    if [ "`cat \"$1\" | sed -r \"s/#.*//\" | egrep \"^[[:space:]]*[^[:space:]]+[[:space:]]+$2[[:space:]]+\"`" = "" ]; then
  518.       echo "$2" "$3" "$4" "$5" 0 0 "$FSTABLLFLAG" >>$1
  519.    fi
  520. }
  521.  
  522. # create correct fstab file in $1/etc/fstab and create apropriate
  523. # mount directories in $1/mnt. Check for iocharset boot option,
  524. # if present, add iocharset to all DOS/Win filesystems (vfat,ntfs)
  525. # $1 = root directory (union)
  526. #
  527. fstab_update()
  528. {
  529.    IOCHARSET="`cmdline_value iocharset`"
  530.    AUTO="`cmdline_parameter noauto`"
  531.    if [ "$AUTO" = "" ]; then AUTO="auto"; fi
  532.  
  533.    FSTAB="$1/etc/fstab"
  534.    mkdir -p $1/etc $1/mnt
  535.    cat $FSTAB 2>/dev/null | grep -v "$FSTABLLFLAG" >$FSTAB~
  536.  
  537. #   fstab_update_line $FSTAB~ tmpfs / tmpfs defaults
  538.    fstab_update_line $FSTAB~ proc /proc proc defaults
  539.    fstab_update_line $FSTAB~ sysfs /sys sysfs defaults
  540.    fstab_update_line $FSTAB~ devpts /dev/pts devpts defaults
  541.    fstab_update_line $FSTAB~ relayfs /mnt/relay relayfs defaults
  542.    fstab_update_line $FSTAB~ tmpfs /dev/shm tmpfs defaults
  543.  
  544.    list_cdrom_devices | while read DEVICE; do
  545.       MOUNTDIR="/mnt/`basename $DEVICE`_cdrom"
  546.       mkdir -p $1/$MOUNTDIR
  547.       fstab_update_line $FSTAB~ $DEVICE $MOUNTDIR iso9660 noauto,users,exec
  548.    done
  549.    list_partition_devices | while read DEVICE; do
  550.       unset REMOVABLE; unset OPT; DEV="`basename $DEVICE`"; DEV0="`echo $DEV | cut -b 1-3`"
  551.       if [ "0`cat /sys/block/$DEV0/removable 2>/dev/null`" -ne 0 ]; then
  552.          REMOVABLE="_removable"
  553.       fi
  554.  
  555.       MOUNTDIR="/mnt/$DEV$REMOVABLE"
  556.       FS="`blkid -s TYPE $DEVICE | cut -d = -f 2 | tr -d ' \"'`"
  557.  
  558.       # add special options for NTFS
  559.       if [ "$FS" = "ntfs" ]; then
  560.          OPT=",ro"
  561.          if [ "$IOCHARSET" != "" ]; then OPT="$OPT,nls=$IOCHARSET"; fi
  562.       fi
  563.  
  564.       # add special options for VFAT
  565.       if [ "$FS" = "vfat" -a "$IOCHARSET" != ""  ]; then OPT=",iocharset=$IOCHARSET"; fi
  566.  
  567.       # if the partition has filesystem, add it to fstab
  568.       if [ "$FS" != "" ]; then
  569.          if [ "$FS" = "swap" ]; then
  570.             fstab_update_line $FSTAB~ $DEVICE swap swap defaults
  571.          else
  572.             fstab_update_line $FSTAB~ $DEVICE $MOUNTDIR $FS $AUTO,users,suid,dev,exec$OPT
  573.             mkdir -p "$1/$MOUNTDIR"
  574.          fi
  575.       fi
  576.    done
  577.  
  578.    fstab_update_line $FSTAB~ /dev/fd0 /mnt/floppy vfat,msdos noauto,users,suid,dev,exec
  579.    mkdir -p $1/mnt/floppy
  580.    
  581.    mv -f $FSTAB~ $FSTAB
  582. }
  583.