slitaz-modular diff initramfs/liblinuxlive @ rev 0

first release
author Christopher Rogers <slaxemulator@gmail.com>
date Thu Nov 25 03:30:16 2010 +0000 (2010-11-25)
parents
children d52e861c9970
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/initramfs/liblinuxlive	Thu Nov 25 03:30:16 2010 +0000
     1.3 @@ -0,0 +1,1128 @@
     1.4 +#!/bin/bash
     1.5 +
     1.6 +# Functions library :: for Linux Live scripts 6
     1.7 +# Author: Tomas M. <http://www.linux-live.org>
     1.8 +#
     1.9 +
    1.10 +# ===========================================================
    1.11 +# GLOBAL variables
    1.12 +# ===========================================================
    1.13 +
    1.14 +# linux live flag to fstab, if fstab line doesn't contain it,
    1.15 +# never remove it from fstab automatically (user added it)
    1.16 +FSTABLLFLAG="# AutoUpdate"
    1.17 +
    1.18 +# We have to set these variables very carefully
    1.19 +UNION=union
    1.20 +MEMORY=memory
    1.21 +MOUNTDIR=mnt
    1.22 +CHANGES=$MEMORY/changes
    1.23 +XINO=$MEMORY/xino
    1.24 +COPY2RAM=$MEMORY/copy2ram
    1.25 +IMAGES=$MEMORY/images
    1.26 +INITRAMDISK=$MOUNTDIR/live
    1.27 +LOOPMOUNT=$MOUNTDIR/tmp
    1.28 +FINDISOMNT=$MOUNTDIR/findiso
    1.29 +
    1.30 +# this will be replaced by build script, so never change the following line!
    1.31 +LIVECDNAME="slitaz"
    1.32 +
    1.33 +# =================================================================
    1.34 +# debug and output functions
    1.35 +# =================================================================
    1.36 +
    1.37 +# global variable
    1.38 +DEBUG_IS_ENABLED=$(cat /proc/cmdline 2>/dev/null | grep debug)
    1.39 +
    1.40 +debug_log()
    1.41 +{
    1.42 +   if [ "$DEBUG_IS_ENABLED" ]; then
    1.43 +      echo "- debug: $*" >&2
    1.44 +      log "- debug: $*"
    1.45 +   fi
    1.46 +}
    1.47 +
    1.48 +# echogreen will echo $@ in green color
    1.49 +# $1 = text
    1.50 +#
    1.51 +echogreen()
    1.52 +{
    1.53 +   echo -ne " ""$@"""
    1.54 +}
    1.55 +
    1.56 +# echolog
    1.57 +# $1 = text to show and to write to /var/log/messages
    1.58 +#
    1.59 +echolog()
    1.60 +{
    1.61 +   if [ "$1" != "" ]; then
    1.62 +      echogreen "* "
    1.63 +      log "LIVECD:" "$@" 
    1.64 +      echo "$@"
    1.65 +   fi
    1.66 +}
    1.67 +
    1.68 +# log
    1.69 +# store given text in /var/log/livedbg
    1.70 +log()
    1.71 +{
    1.72 +   echo "$@" 2>/dev/null >>/var/log/livedbg
    1.73 +}
    1.74 +
    1.75 +# show information about the debug shell
    1.76 +show_debug_banner()
    1.77 +{
    1.78 +   echo
    1.79 +   echo "====="
    1.80 +   echo ": Debugging started. Here is the root shell for you."
    1.81 +   echo ": Type your desired commands or hit Ctrl+D to continue booting."
    1.82 +   echo
    1.83 +}
    1.84 +
    1.85 +# debug_shell
    1.86 +# executed when debug boot parameter is present
    1.87 +#
    1.88 +debug_shell()
    1.89 +{
    1.90 +   if [ "$DEBUG_IS_ENABLED" ]; then
    1.91 +      show_debug_banner
    1.92 +      ash < /dev/console
    1.93 +      echo
    1.94 +   fi
    1.95 +}
    1.96 +
    1.97 +# header
    1.98 +# $1 = text to show
    1.99 +#
   1.100 +header()
   1.101 +{
   1.102 +   echo """$@"""
   1.103 +}
   1.104 +
   1.105 +fatal()
   1.106 +{
   1.107 +   echolog
   1.108 +   header "Fatal error occured - $1"
   1.109 +   echolog "Something went wrong and we can't continue. This should never happen."
   1.110 +   echolog "Please reboot your computer with Ctrl+Alt+Delete ..."
   1.111 +   echolog
   1.112 +   ash < /dev/console
   1.113 +}
   1.114 +
   1.115 +allow_only_root()
   1.116 +{
   1.117 +  # test if the script is started by root user. If not, exit
   1.118 +  if [ "0$UID" -ne 0 ]; then
   1.119 +     echo "Only root can run $(basename $0)"; exit 1
   1.120 +  fi
   1.121 +}
   1.122 +
   1.123 +# ===========================================================
   1.124 +# text processing functions
   1.125 +# ===========================================================
   1.126 +
   1.127 +# look into cmdline and echo $1 back if $1 is set
   1.128 +# $1 = value name, case sensitive, for example 'debug'
   1.129 +#
   1.130 +cmdline_parameter()
   1.131 +{
   1.132 +   debug_log "cmdline_parameter" "$*"
   1.133 +   log "searching for bootparam: $1"
   1.134 +   egrep -o "(^|[[:space:]])$1([[:space:]]|\$)" /proc/cmdline | tr -d " " | tail -n 1
   1.135 +}
   1.136 +
   1.137 +# look into cmdline and echo value of $1 option
   1.138 +# $1 = value name, case sensitive, for example 'changes'
   1.139 +#
   1.140 +cmdline_value()
   1.141 +{
   1.142 +   debug_log "cmdline_value" "$*"
   1.143 +   log "searching for bootparam value: $1"
   1.144 +   egrep -o "(^|[[:space:]])$1=[^[:space:]]+" /proc/cmdline | cut -d "=" -f 2- | tail -n 1
   1.145 +}
   1.146 +
   1.147 +# Make sure the part of a script after 'mutex_lock' call is atomic,
   1.148 +# that means the 'locked' part of the script can never be execuetd 
   1.149 +# from several processes at the same time, in parallel.
   1.150 +# Every script waits until it gathers the lock.
   1.151 +# The lock directory is saved in /dev instead of /tmp, because /tmp may be
   1.152 +# readonly at the time when the lock is needed (eg. when udev is starting)
   1.153 +# $1 = name of the lock
   1.154 +#
   1.155 +mutex_lock()
   1.156 +{
   1.157 +   debug_log "mutex_lock" "$*"
   1.158 +   while ! mkdir "/dev/ll-mutex-lock-$1" 2>/dev/null; do
   1.159 +      usleep 100000;
   1.160 +   done
   1.161 +}
   1.162 +
   1.163 +# Unlock the lock so another waiting process can reusse it and continue
   1.164 +# $1 = name of the lock
   1.165 +#
   1.166 +mutex_unlock()
   1.167 +{
   1.168 +   debug_log "mutex_unlock" "$*"
   1.169 +   rmdir "/dev/ll-mutex-lock-$1" 2>/dev/null
   1.170 +}
   1.171 +
   1.172 +# ===========================================================
   1.173 +# system functions
   1.174 +# ===========================================================
   1.175 +
   1.176 +# setup /usr from /usr.lzm inside initrd
   1.177 +mount_initrd_loops()
   1.178 +{
   1.179 +   debug_log "mount_initrd_loops" "$*"
   1.180 +   if [ -e /usr.lzm ]; then
   1.181 +      mount_device /usr.lzm /usr loop,ro squashfs
   1.182 +   fi
   1.183 +   if [ -e /drivers.lzm ]; then
   1.184 +      mount_device /drivers.lzm /lib/modules/*/kernel/drivers loop,ro squashfs
   1.185 +   fi
   1.186 +}
   1.187 +
   1.188 +# modprobe module $1, including all dependencies, suppress all messages
   1.189 +# This was own function, because modprobe in busybox didn't support
   1.190 +# neither gzipped modules nor dependencies. Seems to be fixed now, though.
   1.191 +# $1 = module name, eg. ehci-hcd
   1.192 +# $* = optional arguments
   1.193 +#
   1.194 +modprobe_module()
   1.195 +{
   1.196 +   debug_log "modprobe_module" "$*"
   1.197 +   local MODULE
   1.198 +
   1.199 +   MODULE="$1"
   1.200 +   shift
   1.201 +
   1.202 +   if [ ! "$MODULE" ]; then return 1; fi
   1.203 +   modprobe "$MODULE" $* 2>/dev/null
   1.204 +}
   1.205 +
   1.206 +cdname()
   1.207 +{
   1.208 +	if [ "$(cmdline_value cdname)" != "" ]; then
   1.209 +		LIVECDNAME="$(cmdline_value cdname)"
   1.210 +	else
   1.211 +		LIVECDNAME="${LIVECDNAME}"
   1.212 +	fi
   1.213 +}
   1.214 +
   1.215 +cdname
   1.216 +
   1.217 +# mknod next loop device
   1.218 +# - find biggest loop device in /dev/loop/, assume it to be used
   1.219 +# - preallocate (mknod) 20 more loop devices in one round
   1.220 +mknod_next_loop_dev()
   1.221 +{
   1.222 +   debug_log "mknod_next_loop_dev" "$*"
   1.223 +   local i NR END PFX
   1.224 +
   1.225 +   mutex_lock mknod_next_loop_dev
   1.226 +
   1.227 +   if [ -d /dev/loop ]; then
   1.228 +      NR=$(find /dev/loop/ -maxdepth 1 | sed -r 's/[^0-9]+//' | sort -n | tail -n 1)
   1.229 +      PFX="/"
   1.230 +   else
   1.231 +      NR=$(find /dev/ -maxdepth 1 | grep loop | sed -r 's/[^0-9]+//' | sort -n | tail -n 1)
   1.232 +      PFX=""
   1.233 +   fi
   1.234 +   NR=$(expr 0$NR + 1)
   1.235 +   END=$(expr 0$NR + 20)
   1.236 +   for i in $(seq $NR $END); do
   1.237 +      mknod /dev/loop$PFX$i b 7 $i 2>/dev/null
   1.238 +   done
   1.239 +   echo /dev/loop$PFX$NR
   1.240 +
   1.241 +   mutex_unlock mknod_next_loop_dev
   1.242 +}
   1.243 +
   1.244 +# ===========================================================
   1.245 +# Filesystem functions
   1.246 +# ===========================================================
   1.247 +
   1.248 +# Find out what locale is requested
   1.249 +# If no locale is given, use the firts one available (if any)
   1.250 +# $1 = locale (optional argument, if exists, no autodetection is made)
   1.251 +locale_id()
   1.252 +{
   1.253 +   debug_log "locale_id" "$*"
   1.254 +   local LOCALE i
   1.255 +
   1.256 +   # first try to find out locale from boot parameters
   1.257 +   LOCALE="$1"
   1.258 +   if [ "$LOCALE" = "" ]; then LOCALE=$(cmdline_value locale); fi
   1.259 +   if [ "$LOCALE" = "" ]; then LOCALE=$(cmdline_value language); fi
   1.260 +   if [ "$LOCALE" = "" ]; then LOCALE=$(cmdline_value lang); fi
   1.261 +
   1.262 +   # if not found, set it to locale from usr/lib/locale,
   1.263 +   # but only if there is just ONE directory, nothing more
   1.264 +   # (so we are sure which one to use)
   1.265 +   if [ "$LOCALE" = "" ]; then
   1.266 +      for LOCALE in $(ls -A1p /usr/lib/locale 2>/dev/null | grep / | sed -r "s:[/]|[.].*::"); do
   1.267 +         i="1$i"
   1.268 +      done
   1.269 +      if [ "$i" != "1" ]; then LOCALE=""; fi
   1.270 +   fi
   1.271 +
   1.272 +   if [ "$LOCALE" != "" -a -e /usr/share ]; then
   1.273 +      cat /usr/share/locale/locale.alias | sed -r "s/#.*//" | egrep "$LOCALE|$LOCALE""_" | tail -n 1 | tr -s "[[:space:]]" " " | cut -d " " -f 2- | tr -d " "
   1.274 +   fi
   1.275 +}
   1.276 +
   1.277 +# Find out what iocharset to use
   1.278 +iocharset()
   1.279 +{
   1.280 +   debug_log "iocharset" "$*"
   1.281 +   local CHARSET IOCHARSET
   1.282 +
   1.283 +   # if iocharset is explicitly set at the boot prompt,
   1.284 +   # return it regardless the locale settings
   1.285 +   IOCHARSET=$(cmdline_value iocharset)
   1.286 +   if [ "$IOCHARSET" != "" ]; then
   1.287 +      echo $IOCHARSET
   1.288 +      return 0;
   1.289 +   fi
   1.290 +
   1.291 +   # else find out the iocharset from locale_id output, it should match
   1.292 +   # some kernel module (after stripping out few of the dashes)
   1.293 +   IOCHARSET=$(locale_id | cut -d . -f 2- | tr "[[:upper:]]" "[[:lower:]]" | tr -d -)
   1.294 +   if [ "$IOCHARSET" = "" ]; then return 0; fi
   1.295 +
   1.296 +   find /lib/modules -name "nls_*" | sed -r 's:^.*/|[.]ko$::g' | cut -b 5- | while read CHARSET; do
   1.297 +      if [ "$(echo $CHARSET | tr "[[:upper:]]" "[[:lower:]]" | tr -d -)" = "$IOCHARSET" ]; then
   1.298 +         echo "$CHARSET"
   1.299 +         return 0
   1.300 +      fi
   1.301 +   done
   1.302 +   return 1
   1.303 +}
   1.304 +
   1.305 +# Get filesystem options
   1.306 +# $1 = filesystem
   1.307 +# $2 = 'fstab' or 'mount' ... 'auto'/'noauto' string is enabled (fstab) or disabled (mount)
   1.308 +#
   1.309 +
   1.310 +fs_options()
   1.311 +{
   1.312 +   debug_log "fs_options" "$*"
   1.313 +   local NOAUTO IOCHARSET
   1.314 +
   1.315 +   NOAUTO=$(cmdline_parameter noauto)
   1.316 +   if [ "$NOAUTO" = "" ]; then NOAUTO="auto"; fi
   1.317 +   if [ "$2" = "fstab" ]; then echo -n "$NOAUTO," ; fi
   1.318 +   if [ "$1" = "swap" ]; then echo "defaults,pri=1"; return 0; fi
   1.319 +   echo -n "noatime,users,suid,dev,exec"
   1.320 +
   1.321 +   IOCHARSET=$(iocharset)
   1.322 +
   1.323 +   if [ "$1" = "vfat" ]; then
   1.324 +      echo -n ",quiet,umask=0,check=s,shortname=mixed"
   1.325 +      if [ "$IOCHARSET" ]; then
   1.326 +         echo ",iocharset=$IOCHARSET"
   1.327 +      fi
   1.328 +   fi
   1.329 +
   1.330 +   if [ "$1" = "iso9660" -o "$1" = "iso9660,udf" ]; then
   1.331 +      echo -n ",ro"
   1.332 +      if [ "$IOCHARSET" ]; then
   1.333 +         echo ",iocharset=$IOCHARSET"
   1.334 +      fi
   1.335 +   fi
   1.336 +
   1.337 +   if [ "$1" = "ntfs" ]; then
   1.338 +      echo -n ",ro"
   1.339 +      if [ "$IOCHARSET" ]; then
   1.340 +         echo ",nls=$IOCHARSET"
   1.341 +      fi
   1.342 +   fi
   1.343 +
   1.344 +   if [ "$1" = "ntfs-3g" ]; then
   1.345 +      echo ",locale=$(locale_id)"
   1.346 +   fi
   1.347 +   
   1.348 +   if [ "$1" = "ext3" -o "$1" = "ext4" ]; then
   1.349 +      echo ",barrier=1,data=ordered"
   1.350 +   fi
   1.351 +
   1.352 +}
   1.353 +
   1.354 +# discover filesystem used on the given device
   1.355 +# Use vfat for msdos filesystem. Use ntfs-3g for ntfs if ntfs-3g exists.
   1.356 +# $1 = device, eg. /dev/hda1
   1.357 +#
   1.358 +device_filesystem()
   1.359 +{
   1.360 +   debug_log "device_filesystem" "$*"
   1.361 +   local NTFS
   1.362 +
   1.363 +   if [ -e /bin/ntfs-3g ]; then NTFS="ntfs-3g"; else NTFS="ntfs"; fi
   1.364 +   blkid -s TYPE "$1" -o value | sed "s/msdos/vfat/" | sed "s/ntfs/$NTFS/"
   1.365 +}
   1.366 +
   1.367 +# tell us if the given filesystem is supported
   1.368 +# (eg. it's in /proc/filesystems or we know it)
   1.369 +# $1 = filesystem name
   1.370 +#
   1.371 +is_supported_filesystem()
   1.372 +{
   1.373 +   debug_log "is_supported_filesystem" "$*"
   1.374 +
   1.375 +   if [ -e /bin/ntfs-3g -a "$1" = "ntfs-3g" ]; then
   1.376 +      return 0
   1.377 +   fi
   1.378 +
   1.379 +   # the following command will set the return value
   1.380 +   egrep -q "[[:space:]]$1\$" /proc/filesystems
   1.381 +}
   1.382 +
   1.383 +# Mount device $1 to $2
   1.384 +# If the device is using vfat or ntfs filesystem, use iocharset as a mount option
   1.385 +# $1 = /dev device to mount, eg. /dev/hda1, or loop file, or directory
   1.386 +# $2 = mountpoint, eg. /mnt/hda1
   1.387 +# $3 = optional mount options, for example "ro", or "remount,rw"
   1.388 +# $4 = optional filesystem name, in order to skip autodetection
   1.389 +#
   1.390 +mount_device()
   1.391 +{
   1.392 +   debug_log "mount_device" "$*"
   1.393 +   local FS DEV LOOPDEV OPTIONS FILESYSTEM ERR
   1.394 +
   1.395 +   # make sure we have enough arguments
   1.396 +   if [ "$2" = "" ]; then return 1; fi
   1.397 +   if [ "$1" = "" ]; then rmdir "$2" 2>/dev/null; return 1; fi
   1.398 +   mkdir -p "$2"
   1.399 +
   1.400 +   DEV="$1"
   1.401 +   if [ "$4" != "" ]; then FS="$4"; else FS=$(device_filesystem "$1"); fi
   1.402 +   if [ "$FS" ]; then OPTIONS=$(fs_options $FS mount); FS="-t $FS"; fi
   1.403 +   if [ "$OPTIONS" ]; then OPTIONS="$OPTIONS"; else OPTIONS=""; fi
   1.404 +   if [ -f "$DEV" ]; then OPTIONS="$OPTIONS,loop"; fi
   1.405 +   if [ -d "$DEV" ]; then OPTIONS="$OPTIONS,rbind"; fi
   1.406 +   if [ "$3" ]; then OPTIONS="$OPTIONS,$3"; fi
   1.407 +   OPTIONS=$(echo "$OPTIONS" | sed -r "s/^,+//")
   1.408 +
   1.409 +   if [ "$FS" = "-t ntfs-3g" ]; then
   1.410 +      ntfs-3g "$DEV" "$2" -o $OPTIONS >/dev/null 2>&1
   1.411 +      ERR=$?
   1.412 +   else
   1.413 +      mount -n -o $OPTIONS $FS "$DEV" "$2" >/dev/null 2>&1
   1.414 +      ERR=$?
   1.415 +   fi
   1.416 +
   1.417 +   # not enough loop devices? try to create one.
   1.418 +   if [ $ERR -eq 2 ]; then
   1.419 +       LOOPDEV=$(mknod_next_loop_dev)
   1.420 +       OPTIONS=$(echo "$OPTIONS" | sed -r "s/,loop//g")
   1.421 +       losetup "$LOOPDEV" "$DEV" 2>/dev/null # busybox's losetup doesn't support -r
   1.422 +       if [ $? -ne 0 ]; then
   1.423 +          losetup -r "$LOOPDEV" "$DEV" 2>/dev/null # force read-only in case of error
   1.424 +       fi
   1.425 +       mount -n -o $OPTIONS $FS "$LOOPDEV" "$2" >/dev/null 2>&1
   1.426 +       ERR=$?
   1.427 +   fi
   1.428 +
   1.429 +   # if nothing works, try to force read-only mount
   1.430 +   if [ $ERR -ne 0 ]; then
   1.431 +       mount -n -r -o $OPTIONS $FS "$DEV" "$2" >/dev/null 2>&1
   1.432 +       ERR=$?
   1.433 +   fi
   1.434 +
   1.435 +   if [ $ERR -ne 0 ]; then rmdir $2 2>/dev/null; fi
   1.436 +   return $ERR
   1.437 +}
   1.438 +
   1.439 +# unmount all parameters. If the parameter is not mountpoint but
   1.440 +# it's a file or directory, umount the device where the file/dir is stored.
   1.441 +#
   1.442 +# First try normal umount, if that fails then remount read-only
   1.443 +# If -l parameter is specified, do lazy-umount when normal umount fails
   1.444 +# $1..$n = files/directories/devices to be unmounted
   1.445 +#
   1.446 +fumount()
   1.447 +{
   1.448 +   debug_log "fumount" "$*"
   1.449 +   local TARGET LAZY
   1.450 +
   1.451 +   while [ "$1" ]; do
   1.452 +      if [ "$1" = "-l" ]; then LAZY="yes"; shift; fi
   1.453 +      TARGET=$(readlink -f "$1")
   1.454 +      if ! ismountpoint "$TARGET"; then
   1.455 +         if [ -f "$TARGET" -o -d "$TARGET" ]; then
   1.456 +            TARGET=$(df "$TARGET" | tail -n 1 | tr -s " " | cut -d " " -f 6)
   1.457 +         fi
   1.458 +      fi
   1.459 +
   1.460 +      if [ "$TARGET" != "" ]; then
   1.461 +         umount -n "$TARGET" >/dev/null 2>&1
   1.462 +         if [ $? -ne 0 ]; then
   1.463 +            mount -n -o remount,ro -t ignored ignored "$TARGET" >/dev/null 2>&1
   1.464 +            if [ "$LAZY" ]; then umount -n -l "$TARGET" >/dev/null 2>&1; fi
   1.465 +         fi
   1.466 +      fi
   1.467 +      shift
   1.468 +   done
   1.469 +}
   1.470 +
   1.471 +# ===========================================================
   1.472 +# live module functions
   1.473 +# ===========================================================
   1.474 +
   1.475 +# Create module
   1.476 +# call mksquashfs with apropriate arguments
   1.477 +# $1 = directory which will be compressed to squashfs module
   1.478 +# $2 = output filesystem module file
   1.479 +# $3..$9 = optional arguments like -keep-as-directory or -b 123456789
   1.480 +#
   1.481 +create_module()
   1.482 +{
   1.483 +   debug_log "create_module" "$*"
   1.484 +   rm -f "$2" # overwrite, never append to existing file
   1.485 +   mksquashfs "$1" "$2" -b 256K $3 $4 $5 $6 $7 $8 $9>/dev/null
   1.486 +   if [ $? -ne 0 ]; then return 1; fi
   1.487 +   chmod a-wx "$2" # remove execute and write attrib
   1.488 +   chmod a+r "$2" # add read for everyone
   1.489 +}
   1.490 +
   1.491 +# ismountpoint exits with 0 if $1 is mountpoint, else exits with 1
   1.492 +# $1 = directory or loop_file
   1.493 +#
   1.494 +ismountpoint()
   1.495 +{
   1.496 +   debug_log "ismountpoint" "$*"
   1.497 +   local MDIR
   1.498 +
   1.499 +   MDIR=$(readlink -f "$1")
   1.500 +   cat /proc/mounts | cut -d " " -f 2 | egrep "^$MDIR\$" >/dev/null 2>&1
   1.501 +}
   1.502 +
   1.503 +# Mount filesystem module to destination directory
   1.504 +# $1 = path to the compressed module
   1.505 +# $2 = destination folder
   1.506 +#
   1.507 +mount_module()
   1.508 +{
   1.509 +   debug_log "mount_module" "$*"
   1.510 +   mount_device "$1" "$2" loop,ro squashfs
   1.511 +}
   1.512 +
   1.513 +# Insert a directory tree $2 to an union specified by $1
   1.514 +# Top-level read-write branch is specified by it's index 0
   1.515 +# Using =rr enables aufs to optimize real readonly branches
   1.516 +# $1 = union absolute path (starting with /)
   1.517 +# $2 = path to data directory
   1.518 +#
   1.519 +union_insert_dir()
   1.520 +{
   1.521 +   debug_log "union_insert_dir" "$*"
   1.522 +   mount -n -o remount,add:1:$2=rr aufs $1
   1.523 +}
   1.524 +
   1.525 +# Find LZM modules in given dir
   1.526 +# $1 = root directory of mounted DATAdir
   1.527 +#
   1.528 +find_modules()
   1.529 +{
   1.530 +   debug_log "find_modules" "$*"
   1.531 +   if [ "$(cmdline_parameter baseonly)" ]; then
   1.532 +   	find "$1/base" "$1/optional" -name "*.sqfs" 2>/dev/null | sort
   1.533 +   	find "$1/base" "$1/optional" -name "*.lzm" 2>/dev/null | sort
   1.534 +   else
   1.535 +   	find "$1/base" "$1/modules" "$1/optional" "$1/tmp" -name "*.sqfs" 2>/dev/null | sort
   1.536 +   	find "$1/base" "$1/modules" "$1/optional" "$1/tmp" -name "*.lzm" 2>/dev/null | sort
   1.537 +   fi
   1.538 +}
   1.539 +
   1.540 +# List all modules in all directories (base, modules, optional)
   1.541 +# and filter out unneeded optional modules (not specified by load= kernel parameter)
   1.542 +# separator for load and noload arguments is "," or ";"
   1.543 +# $1 = root directory of mounted DATAdir
   1.544 +#
   1.545 +list_modules()
   1.546 +{
   1.547 +   debug_log "list_modules" "$*"
   1.548 +   local LOAD NOLOAD
   1.549 +
   1.550 +   LOAD=$(cmdline_value load | sed -r 's/\*/.\*/g' | sed -r 's/,|;/|/g')
   1.551 +   NOLOAD=$(cmdline_value noload | sed -r 's/\*/.\*/g' | sed -r 's/,|;/|/g')
   1.552 +   find_modules "$1" | while read LINE; do
   1.553 +      MODNAME=$(echo $LINE | cut -b ${#1}- | cut -b 2-)
   1.554 +      if [ "$(echo $LINE | grep /optional/)" ]; then
   1.555 +         if [ ! "$LOAD" -o ! "$(echo $MODNAME | egrep -i "$LOAD")" ]; then continue; fi
   1.556 +      fi
   1.557 +      if [ "$NOLOAD" -a "$(echo $MODNAME | egrep -i "$NOLOAD")" ]; then continue; fi
   1.558 +      echo $LINE
   1.559 +   done
   1.560 +}
   1.561 +
   1.562 +# Insert one single filesystem module to the union
   1.563 +# $1 = union absolute path
   1.564 +# $2 = module full path
   1.565 +# $3 = destination folder, where images will be mounted to
   1.566 +# $4 = preffix length strip (number of characters)
   1.567 +#
   1.568 +union_insert_module()
   1.569 +{
   1.570 +   debug_log "union_insert_module" "$*"
   1.571 +   local TARGET
   1.572 +
   1.573 +   TARGET="$3/$(basename $2)"
   1.574 +   if ismountpoint $TARGET; then return 1; fi # skip already used modules
   1.575 +   mkdir -p $TARGET
   1.576 +   mount_module $2 $TARGET
   1.577 +   if [ $? -ne 0 ]; then echo "Cannot read module data. corrupted download?" >&2; return 1; fi
   1.578 +   union_insert_dir $1 $TARGET
   1.579 +   if [ $? -ne 0 ]; then echo "can't insert module to union" >&2; return 2; fi
   1.580 +   echo "$2" | cut -b $(($4+1))-
   1.581 +   echolog "$2" >/dev/null
   1.582 +   return 0
   1.583 +}
   1.584 +
   1.585 +# Insert all filesystem modules from $2 directory and subdirectories, to the union
   1.586 +# $1 = union absolute path (starting with /)
   1.587 +# $2 = LiveCD data dir (with directories /base, /modules, etc.)
   1.588 +# $3 = destination folder, where images will be mounted to
   1.589 +#
   1.590 +union_insert_modules()
   1.591 +{
   1.592 +   debug_log "union_insert_modules" "$*"
   1.593 +   local INSERTED
   1.594 +
   1.595 +   list_modules $2 | while read MODULE; do
   1.596 +      INSERTED=$(union_insert_module $1 $MODULE $3 ${#2})
   1.597 +      if [ "$INSERTED" != "" ]; then echolog " -> $(echo $INSERTED | sed -r s:^/::)"; fi
   1.598 +   done
   1.599 +}
   1.600 +
   1.601 +# Copy LiveCD modules to RAM directory
   1.602 +# will copy only /boot, and module files from $1
   1.603 +# $1 = data directory
   1.604 +# $2 = target directory in RAM
   1.605 +#
   1.606 +copy_to_ram()
   1.607 +{
   1.608 +   debug_log "copy_to_ram" "$*"
   1.609 +   cp -a "$1/rootcopy" "$2" 2>/dev/null # could be empty
   1.610 +   list_modules "$1" | while read MODULE; do
   1.611 +      TARGET=$(dirname "$MODULE" | cut -b ${#1}- | cut -b 2-)
   1.612 +      mkdir -p "$2/$TARGET"
   1.613 +      cp "$MODULE" "$2/$TARGET"
   1.614 +      if [ $? -ne 0 ]; then fatal "Not enough memory. Using ramsize=$RAMSIZE"; fi
   1.615 +   done
   1.616 +}
   1.617 +
   1.618 +# ===========================================================
   1.619 +# discovery functions
   1.620 +# ===========================================================
   1.621 +
   1.622 +# List all supported network drivers
   1.623 +#
   1.624 +list_network_drivers()
   1.625 +{
   1.626 +   debug_log "list_network_drivers" "$*"
   1.627 +
   1.628 +   # these drivers are probed in Slackware's initrd
   1.629 +   # (see initrd.img/scripts/network.sh).
   1.630 +   # I don't have personal experiences with most of these drivers
   1.631 +   # so I'll be happy if you report any particular one to be not working
   1.632 +   # (eg. causing hangups) in order to remove it from this list.
   1.633 +
   1.634 +   echo 3c59x acenic atl1 de4x5 dgrs eepro100 e1000 epic100 hp100 ne2k-pci \
   1.635 +   olympic pcnet32 r8169 rcpci 8139too 8139cp sktr skge sky2 tulip via-rhine \
   1.636 +   yellowfin tg3 dl2k ns83820 depca ibmtr 3c501 3c503 3c505 3c507 3c509 3c515 \
   1.637 +   ac3200 acenic at1700 cosa cs89x0 de4x5 de600 de620 e2100 eepro eexpress \
   1.638 +   es3210 eth16i ewrk3 fmv18x forcedeth hostess_sv11 hp-plus hp lne390 ne3210 \
   1.639 +   ni5010 ni52 ni65 sb1000 sealevel smc-ultra sis900 smc-ultra32 smc9194 wd \
   1.640 +   | tr " " "\n"
   1.641 +}
   1.642 +
   1.643 +# List all CD-ROMs
   1.644 +# by using /proc entries
   1.645 +#
   1.646 +list_cdrom_devices()
   1.647 +{
   1.648 +   debug_log "list_cdrom_devices" "$*"
   1.649 +   local CDDEVICE
   1.650 +
   1.651 +   for CDDEVICE in $(cat /proc/sys/dev/cdrom/info 2>/dev/null | head -n 3 | tail -n 1 | cut -d ":" -f 2); do
   1.652 +      echo "/dev/$CDDEVICE"
   1.653 +   done
   1.654 +}
   1.655 +
   1.656 +# List all mounted directories
   1.657 +#
   1.658 +list_mounted_directories()
   1.659 +{
   1.660 +   debug_log "list_mounted_directories" "$*"
   1.661 +   if [ "$MOUNTDIR" ]; then
   1.662 +      ls -1 $MOUNTDIR | while read DIR; do
   1.663 +         if ismountpoint $MOUNTDIR/$DIR; then echo $DIR; fi
   1.664 +      done
   1.665 +   fi
   1.666 +}
   1.667 +
   1.668 +# List all devices with filesystems
   1.669 +# Return empty result when nohd parameter was given.
   1.670 +#
   1.671 +list_partition_devices()
   1.672 +{
   1.673 +   debug_log "list_partition_devices" "$*"
   1.674 +   if [ "$(cmdline_parameter nohd)" != "" ]; then return 1; fi
   1.675 +   cat /proc/partitions | grep -v loop | grep -v major | grep -v '^$' | sed -r "s:^[0-9 ]+:/dev/:"
   1.676 +   if [ -e /dev/mapper/control ]; then # list LVM partitions if available
   1.677 +      ls -1 /dev/mapper/ | grep -v "^control\$" | sed -r "s:^:/dev/mapper/:"
   1.678 +   fi
   1.679 +}
   1.680 +
   1.681 +# List all disk devices
   1.682 +#
   1.683 +list_disk_devices()
   1.684 +{
   1.685 +   debug_log "list_disk_devices" "$*"
   1.686 +   list_partition_devices | egrep -v "[0-9]"
   1.687 +}
   1.688 +
   1.689 +# List all partitions marked as Linux Swap
   1.690 +#
   1.691 +list_swap_devices()
   1.692 +{
   1.693 +   debug_log "list_swap_devices" "$*"
   1.694 +   if [ "$(cmdline_parameter nohd)" != "" -o "$(cmdline_parameter noswap)" != "" ]; then return 1; fi
   1.695 +   blkid -t TYPE="swap" -o device
   1.696 +}
   1.697 +
   1.698 +# List all block devices
   1.699 +#
   1.700 +list_block_devices()
   1.701 +{
   1.702 +   debug_log "list_block_devices" "$*"
   1.703 +   if [ "$(cmdline_parameter nocd)" = "" ]; then
   1.704 +      list_cdrom_devices
   1.705 +   fi
   1.706 +   list_partition_devices
   1.707 +}
   1.708 +
   1.709 +# Format mountdir for device. This function used to append _cdrom or _removable
   1.710 +# suffix to the directory name so KDE was able to assign a nice icon for evey
   1.711 +# device, but this should be done using HAL in KDE nowadays, so we do not
   1.712 +# support these stupid suffixes anymore. Many people will be happy :)
   1.713 +# $1 = device full path, eg. /dev/hda1
   1.714 +#
   1.715 +device_mountdir()
   1.716 +{
   1.717 +   debug_log "device_mountdir" "$*"
   1.718 +   echo "/$MOUNTDIR/$(basename "$1")" | tr -s /
   1.719 +}
   1.720 +
   1.721 +# Find file-path on given device
   1.722 +# First it mounts the device read-only. If then the 'path' is found, 
   1.723 +# then remount without RO flag (causes it to be mounted read-write if possible)
   1.724 +# and return the path, else unmount and exit.
   1.725 +# If the device/dev_directory is already mounted, preserve it mounted
   1.726 +# $1 = device
   1.727 +# $2 = path/filename
   1.728 +#
   1.729 +find_filepath()
   1.730 +{
   1.731 +   debug_log "find_filepath" "$*"
   1.732 +   local DIR FOUND PRESERVE
   1.733 +
   1.734 +   DIR=$(device_mountdir $1)
   1.735 +   ismountpoint $DIR
   1.736 +   if [ $? -eq 0 ]; then
   1.737 +      PRESERVE="true"
   1.738 +   else
   1.739 +      mount_device $1 $DIR ro
   1.740 +      if [ $? -ne 0 ]; then rmdir $DIR 2>/dev/null; return 1; fi
   1.741 +      PRESERVE=""
   1.742 +   fi
   1.743 +
   1.744 +   FOUND=$(ls -A1d $DIR/$2 2>/dev/null | head -n 1 | tr -s '/')
   1.745 +
   1.746 +   if [ "$FOUND" = "" ]; then
   1.747 +      if [ "$PRESERVE" != "true" ]; then
   1.748 +         fumount $DIR
   1.749 +         rmdir $DIR 2>/dev/null
   1.750 +      fi
   1.751 +      return 1
   1.752 +   else
   1.753 +      # remount without the 'ro' option now, so use rw or defaults
   1.754 +      # Only in the case it was not mounted already before.
   1.755 +      if [ "$PRESERVE" != "true" ]; then
   1.756 +         fumount $DIR
   1.757 +         mount_device $1 $DIR
   1.758 +         if [ $? -ne 0 ]; then
   1.759 +            rmdir $DIR 2>/dev/null
   1.760 +	    return 2
   1.761 +	 fi
   1.762 +      fi
   1.763 +      echo "$FOUND"
   1.764 +      return 0
   1.765 +   fi
   1.766 +}
   1.767 +
   1.768 +# Find file in computer by mounting disks or other storage devices
   1.769 +# and searching for $1 in the mounted directory
   1.770 +# $1 = filename or device-path or devicepath/filename
   1.771 +#
   1.772 +find_file()
   1.773 +{
   1.774 +   debug_log "find_file" "$*"
   1.775 +   local FIND DEVICE DEVPART PATHPART
   1.776 +
   1.777 +   # allow using /mnt/... as well as /dev/...
   1.778 +   FIND=$(echo "$1" | sed -r "s:^/mnt/:/dev/:")
   1.779 +
   1.780 +   # if parameter is just a device, echo it and exit
   1.781 +   if [ -b "$FIND" -o -c "$FIND" -o "$FIND" = "" ]; then echo "$FIND"; return; fi
   1.782 +
   1.783 +   # If path doesn't start with /dev/, try to find the exact path on all devices
   1.784 +   # First, split DEV/PATH parts
   1.785 +   DEVPART=$(echo "$FIND" | egrep -o "^/dev/[^/]+")
   1.786 +
   1.787 +   if [ "$DEVPART" = "" ]; then
   1.788 +      # no device is specified. Search all devices for filename $FIND
   1.789 +      PATHPART="$FIND";
   1.790 +      for DEVICE in $(list_mounted_directories) $(list_block_devices); do
   1.791 +         if ! grep -q ":$DEVICE@$PATHPART:" /tmp/_findfile 2>/dev/null; then
   1.792 +            find_filepath "$DEVICE" "$PATHPART"
   1.793 +            if [ $? -eq 0 ]; then return 0; fi
   1.794 +            echo ":$DEVICE@$PATHPART:" >>/tmp/_findfile
   1.795 +         fi
   1.796 +      done
   1.797 +   else
   1.798 +      # try to find PATHPART only on the given device
   1.799 +      PATHPART=$(echo "$FIND" | sed -r 's:^/dev/[^/]+(.*):\1:')
   1.800 +      find_filepath $DEVPART $PATHPART
   1.801 +   fi
   1.802 +}
   1.803 +
   1.804 +# Find In Computer
   1.805 +# use 'find_file' function to find the given file/dir
   1.806 +# if nothing found, sleep for a while to allow devices to settle and try again.
   1.807 +# (is there any way to find out if there are devices queued through /sys?)
   1.808 +# $1 = file or directory to find
   1.809 +#
   1.810 +find_in_computer()
   1.811 +{
   1.812 +   debug_log "find_in_computer" "$*"
   1.813 +   local TIMEOUT RESULT
   1.814 +
   1.815 +   TIMEOUT=$(cmdline_value scantimeout | sed -r 's/[^0-9]*([0-9]+).*/\1/')
   1.816 +   if [ "$TIMEOUT" = "" ]; then TIMEOUT=10; fi
   1.817 +
   1.818 +   RESULT=$(find_file "$1")
   1.819 +
   1.820 +   while [ $TIMEOUT -gt 0 -a "$RESULT" = "" ]; do
   1.821 +      echo -ne "- wait a while\r" >&2
   1.822 +      sleep 1
   1.823 +      TIMEOUT=$((TIMEOUT-1))
   1.824 +      RESULT=$(find_file "$1")
   1.825 +   done
   1.826 +
   1.827 +   echo $RESULT
   1.828 +}
   1.829 +
   1.830 +# Find and run all scripts from the given module
   1.831 +# This function is used by the activate and deactivate script when the distro
   1.832 +# is already started, not during live setup
   1.833 +# $1 = mounted module full path
   1.834 +# $2..$n = optional arguments for the scripts, eg. 'start'
   1.835 +#
   1.836 +find_n_run_scripts()
   1.837 +{
   1.838 +   debug_log "find_n_run_scripts" "$*"
   1.839 +   local MOD
   1.840 +
   1.841 +   MOD="$1"
   1.842 +   shift
   1.843 +
   1.844 +   if [ -d $MOD/etc/rc.d -o -d $MOD/etc/rc.d/init.d -o -d $MOD/etc/init.d ]; then
   1.845 +      ( find $MOD/etc/rc.d -type f -maxdepth 1 2>/dev/null ; \
   1.846 +        find $MOD/etc/init.d -type f -maxdepth 1 2>/dev/null  ; \
   1.847 +        find $MOD/etc/rc.d/init.d -type f -maxdepth 1 2>/dev/null \
   1.848 +      ) | cut -b ${#MOD}- | cut -b 2- | xargs -n 1 -r readlink -f | sort -u | while read SCRIPT; do
   1.849 +         if [ "$SCRIPT" != "" -a -x "$SCRIPT" -a ! -d "$SCRIPT" ]; then
   1.850 +            # call the script by real path, not from the module
   1.851 +            log "starting '$SCRIPT $@'"
   1.852 +            ${SCRIPT} "$@"
   1.853 +         fi
   1.854 +      done
   1.855 +   fi
   1.856 +}
   1.857 +
   1.858 +# ===========================================================
   1.859 +# hardware preparation functions
   1.860 +# ===========================================================
   1.861 +
   1.862 +# Create block devices to /dev described by /sys entries
   1.863 +#
   1.864 +mdev_start_hotplug()
   1.865 +{
   1.866 +   debug_log "mdev_start_hotplug" "$*"
   1.867 +   echolog "Creating /dev entries for block devices"
   1.868 +   mdev -s
   1.869 +   #rm /dev/pty??* /dev/tty??* # remove unneeded pty and tty devices
   1.870 +   echo /bin/mdev > /proc/sys/kernel/hotplug # use mdev as a hotplug handler
   1.871 +}
   1.872 +
   1.873 +# Modprobe kernel modules needed for the LiveCD
   1.874 +#
   1.875 +modprobe_essential_modules()
   1.876 +{
   1.877 +   debug_log "modprobe_essential_modules" "$*"
   1.878 +
   1.879 +   echolog "Loading filesystems modules ..."
   1.880 +   modprobe_module loop
   1.881 +   modprobe_module isofs
   1.882 +   #modprobe_module sqlzma
   1.883 +   modprobe_module squashfs
   1.884 +   #modprobe_module unlzma
   1.885 +   modprobe_module aufs brs=1
   1.886 +   modprobe_module ext2
   1.887 +   modprobe_module ext3
   1.888 +   modprobe_module ext4
   1.889 +   modprobe_module btrfs
   1.890 +   modprobe_module reiserfs
   1.891 +   modprobe_module xfs
   1.892 +   modprobe_module vfat
   1.893 +   modprobe_module fuse # for ntfs-3g
   1.894 +   modprobe_module ntfs # for ro driver
   1.895 +}
   1.896 +
   1.897 +# Modprobe kernel modules needed for USB masstorage devices
   1.898 +#
   1.899 +modprobe_usb_modules()
   1.900 +{
   1.901 +   debug_log "modprobe_usb_modules" "$*"
   1.902 +   local LSPCI
   1.903 +
   1.904 +   # skip module loading if nohotplug bootparam is present
   1.905 +   if [ "$(cmdline_parameter nohotplug)" ]; then return 0; fi
   1.906 +
   1.907 +   LSPCI=$(lspci -v | grep -i prog-if)
   1.908 +   if [ "$(echo $LSPCI | egrep -i [eou]hci)" = "" ]; then
   1.909 +      return 0
   1.910 +   fi
   1.911 +
   1.912 +   echolog "Loading USB modules ..."
   1.913 +   if [ "$(echo $LSPCI | grep -i ehci)" != "" ]; then
   1.914 +      modprobe_module ehci-hcd
   1.915 +   fi
   1.916 +   if [ "$(echo $LSPCI | grep -i ohci)" != "" ]; then
   1.917 +      modprobe_module ohci-hcd
   1.918 +   fi
   1.919 +   if [ "$(echo $LSPCI | grep -i uhci)" != "" ]; then
   1.920 +      modprobe_module uhci-hcd
   1.921 +   fi
   1.922 +   modprobe_module usb-storage
   1.923 +}
   1.924 +
   1.925 +# Load drivers for PCMCIA CardBus devices
   1.926 +#
   1.927 +modprobe_pcmcia_modules()
   1.928 +{
   1.929 +   debug_log "modprobe_pcmcia_modules" "$*"
   1.930 +
   1.931 +   # skip module loading if nohotplug bootparam is present
   1.932 +   if [ "$(cmdline_parameter nohotplug)" ]; then return 0; fi
   1.933 +
   1.934 +   echolog "Loading PCMCIA CardBus modules ..."
   1.935 +   modprobe_module pcmcia_core
   1.936 +   modprobe_module pcmcia
   1.937 +   modprobe_module rsrc_nonstatic
   1.938 +   modprobe_module yenta_socket
   1.939 +}
   1.940 +
   1.941 +# Load network drivers unless eth[0-9] is found
   1.942 +#
   1.943 +modprobe_network_modules()
   1.944 +{
   1.945 +   debug_log "modprobe_network_modules" "$*"
   1.946 +   local ETH
   1.947 +
   1.948 +   # skip module loading if nohotplug bootparam is present
   1.949 +   if [ "$(cmdline_parameter nohotplug)" ]; then return 0; fi
   1.950 +
   1.951 +   # probe all drivers. Start by the ones mentioned in pcimodules' output
   1.952 +   for module in $(list_network_drivers | egrep "$(pcimodules | tr "\n" "|")!") $(list_network_drivers); do
   1.953 +      modprobe_module $module
   1.954 +      ETH=$(cat /proc/net/dev | grep : | grep -v lo: | cut -d : -f 1 | tr -d " ")
   1.955 +      if [ "$ETH" != "" ]; then
   1.956 +         echo $ETH
   1.957 +         return 0
   1.958 +      fi
   1.959 +      rmmod $module 2>/dev/null
   1.960 +   done
   1.961 +}
   1.962 +
   1.963 +# Start udhcpc to get IP address from DHCP server
   1.964 +# $1 = interface to use (optional)
   1.965 +#
   1.966 +init_dhcp()
   1.967 +{
   1.968 +   debug_log "start_dhcp_client" "$*"
   1.969 +
   1.970 +   if [ "$1" != "" ]; then
   1.971 +      ifconfig $1 up
   1.972 +      udhcpc -i $1 -q
   1.973 +   else
   1.974 +      ifconfig eth0 up
   1.975 +      udhcpc -q
   1.976 +   fi
   1.977 +}
   1.978 +
   1.979 +# Mount http filesystem from the given server
   1.980 +# $1 = server
   1.981 +# $2 = mountdir
   1.982 +#
   1.983 +mount_httpfs()
   1.984 +{
   1.985 +   debug_log "mount_httpfs" "$*"
   1.986 +
   1.987 +   mkdir -p $2
   1.988 +   httpfs $1 $2
   1.989 +}
   1.990 +
   1.991 +
   1.992 +# Unload modules loaded to kernel which are not used
   1.993 +# This function used to unload more modules, but it may cause
   1.994 +# problems to auto-remove some of them (eg. a network module 
   1.995 +# can seem unneeded even if network is to be used very soon.
   1.996 +#
   1.997 +rmmod_unused_modules()
   1.998 +{
   1.999 +   debug_log "rmmod_unused_modules" "$*"
  1.1000 +   rmmod usb-storage uhci-hcd ohci-hcd ehci-hcd 2>/dev/null
  1.1001 +   rmmod yenta_socket rsrc_nonstatic pcmcia pcmcia_core 2>/dev/null
  1.1002 +}
  1.1003 +
  1.1004 +# kill all unneeded processes, which have bigger PID then the PID of
  1.1005 +# current shell. We can't use killall5, as it would kill some processes
  1.1006 +# which may be currently needed, for example ntfs-3g.
  1.1007 +# $1 = maximum pid (kill all lower)
  1.1008 +#
  1.1009 +killall_unneeded()
  1.1010 +{
  1.1011 +   debug_log "killall_unneeded" "$*"
  1.1012 +   local LIST PID
  1.1013 +
  1.1014 +   PID=$1
  1.1015 +   for pid in $(ps | grep -v "PID" | egrep -v "\[.*\]" | fgrep -v mount | fgrep -v posixovl | fgrep -v ntfs | sed -r "s/^[[:space:]]*([0-9]+).*/\\1/"); do
  1.1016 +      if [ $pid -lt $PID ]; then
  1.1017 +         LIST="$LIST $pid"
  1.1018 +      fi
  1.1019 +   done
  1.1020 +
  1.1021 +   kill -SIGTERM $LIST 2>/dev/null # SIGTERM
  1.1022 +   sleep 2
  1.1023 +   kill -SIGKILL $LIST 2>/dev/null # SIGKILL
  1.1024 +}
  1.1025 +
  1.1026 +# enable/disable CD autoejecting when unmounted
  1.1027 +# $1 = 1|0 ... enable|disable
  1.1028 +#
  1.1029 +cd_autoeject()
  1.1030 +{
  1.1031 +   debug_log "cd_autoeject" "$*"
  1.1032 +   echo $1 >/proc/sys/dev/cdrom/autoeject
  1.1033 +}
  1.1034 +
  1.1035 +# ===========================================================
  1.1036 +# FSTAB functions
  1.1037 +# ===========================================================
  1.1038 +
  1.1039 +# $1 = fstab file
  1.1040 +# $2 = device name
  1.1041 +dev_is_in_fstab()
  1.1042 +{
  1.1043 +   debug_log "dev_is_in_fstab" "$*"
  1.1044 +   cat "$1" | sed -r "s/#.*//" | egrep -q "^[[:space:]]*$2[[:space:]]"
  1.1045 +}
  1.1046 +
  1.1047 +# update given line in fstab, add new values only if the device is not found
  1.1048 +# $1 = fstab file to parse
  1.1049 +# $2 = device name
  1.1050 +# $3 = mountpoint
  1.1051 +# $4 = filesystem
  1.1052 +# $5 = mount options
  1.1053 +#
  1.1054 +fstab_add_line()
  1.1055 +{
  1.1056 +   debug_log "fstab_add_line" "$*"
  1.1057 +   local DIR
  1.1058 +
  1.1059 +   if [ "$4" != "swap" ]; then DIR="$3"; else DIR="none"; fi
  1.1060 +   if ! dev_is_in_fstab "$1" "$2"; then
  1.1061 +      echo "$2" "$DIR" "$4" "$5" 0 0 "$FSTABLLFLAG" >>$1
  1.1062 +   fi
  1.1063 +}
  1.1064 +
  1.1065 +# create correct fstab file in $1/etc/fstab and create apropriate
  1.1066 +# mount directories in $1/mnt. This function is only calld once,
  1.1067 +# during liveCD startup (even before init from the distro is started).
  1.1068 +# $1 = root directory (union)
  1.1069 +#
  1.1070 +fstab_update()
  1.1071 +{
  1.1072 +   debug_log "fstab_update" "$*"
  1.1073 +   local FSTAB FSTABTMP
  1.1074 +
  1.1075 +   FSTAB="$1/etc/fstab"
  1.1076 +   FSTABTMP=$FSTAB$$
  1.1077 +   mkdir -p $1/etc $1/mnt
  1.1078 +   cat $FSTAB 2>/dev/null | grep -v "$FSTABLLFLAG" >$FSTABTMP
  1.1079 +
  1.1080 +   fstab_add_line $FSTABTMP none / unionfs defaults
  1.1081 +   fstab_add_line $FSTABTMP none /proc proc defaults
  1.1082 +   fstab_add_line $FSTABTMP none /sys sysfs defaults
  1.1083 +   fstab_add_line $FSTABTMP none /dev/pts devpts gid=5,mode=620
  1.1084 +   fstab_add_line $FSTABTMP tmpfs /dev/shm tmpfs defaults
  1.1085 +
  1.1086 +   list_cdrom_devices | while read DEVICE; do
  1.1087 +      MNT=$(device_mountdir $DEVICE)
  1.1088 +      FS=$(device_filesystem $DEVICE)
  1.1089 +      if [ "$FS" = "" ]; then FS=iso9660,udf; fi
  1.1090 +      mkdir -p "$1/$MNT"
  1.1091 +      fstab_add_line $FSTABTMP $DEVICE $MNT $FS $(fs_options $FS fstab)
  1.1092 +   done
  1.1093 +   list_partition_devices | while read DEVICE; do
  1.1094 +      MNT=$(device_mountdir $DEVICE)
  1.1095 +      FS=$(device_filesystem $DEVICE)
  1.1096 +      OPT=$(fs_options $FS fstab)
  1.1097 +
  1.1098 +      if [ "$FS" = "swap" ]; then
  1.1099 +         fstab_add_line $FSTABTMP $DEVICE $MNT $FS $OPT
  1.1100 +      fi
  1.1101 +
  1.1102 +      # If the partition has a valid filesystem, add it to fstab
  1.1103 +      if is_supported_filesystem "$FS"; then
  1.1104 +         fstab_add_line $FSTABTMP $DEVICE $MNT $FS $OPT
  1.1105 +         mkdir -p "$1/$MNT"
  1.1106 +      fi
  1.1107 +   done
  1.1108 +
  1.1109 +   mv -f $FSTABTMP $FSTAB
  1.1110 +}
  1.1111 +
  1.1112 +# create correct fstab file in $1/etc/fstab only with aufs,proc,sysfs and devpts
  1.1113 +# No partition will be mounted and mount point created
  1.1114 +# HAL is going to manage mount points and medias
  1.1115 +fstab_clean()
  1.1116 +{
  1.1117 +   debug_log "fstab_update" "$*"
  1.1118 +   local FSTAB FSTABTMP
  1.1119 +
  1.1120 +   FSTAB="$1/etc/fstab"
  1.1121 +   FSTABTMP=$FSTAB$$
  1.1122 +   mkdir -p $1/etc $1/mnt
  1.1123 +   cat $FSTAB 2>/dev/null | grep -v "$FSTABLLFLAG" >$FSTABTMP
  1.1124 +
  1.1125 +   fstab_add_line $FSTABTMP aufs / aufs defaults
  1.1126 +   fstab_add_line $FSTABTMP proc /proc proc defaults
  1.1127 +   fstab_add_line $FSTABTMP sysfs /sys sysfs defaults
  1.1128 +   fstab_add_line $FSTABTMP devpts /dev/pts devpts gid=5,mode=620
  1.1129 +   fstab_add_line $FSTABTMP tmpfs /dev/shm tmpfs defaults
  1.1130 +   mv -f $FSTABTMP $FSTAB
  1.1131 +}