# Common functions shared by LTSP init scripts # ltsp_config sources ltsp-common-functions . /usr/share/ltsp/ltsp_config warn() { msg="$1" logger -p user.warning -t ltsp-client "warning: $msg" } start_sound() { if boolean_is_true "$SOUND" ; then case "$SOUND_DAEMON" in pulse|'') # The default when no value is set # Explicitly allow pulse user access to sound devices, ignore errors if [ -x /usr/bin/setfacl ]; then /usr/bin/setfacl -m u:pulse:rw /dev/snd/* > /dev/null 2>&1 fi # Detect method, 0.9.16+ uses module-udev-detect instead of # module-detect and module-stream-restore instead of # module-volume-restore unset PULSE_DETECT unset PULSE_VOLUME_RESTORE # Replace "awk" with shell built-in "while read" case $(pulseaudio --version |while read a b; do echo $b; done) in 0.9.1[6-9]*|0.9.[2-9][0-9]*) PULSE_DETECT=module-udev-detect PULSE_VOLUME_RESTORE=module-stream-restore ;; 0.[0-9].*) PULSE_DETECT=module-detect PULSE_VOLUME_RESTORE=module-volume-restore ;; *) PULSE_DETECT=module-udev-detect PULSE_VOLUME_RESTORE=module-stream-restore ;; esac /usr/bin/pulseaudio --system \ --exit-idle-time=-1 \ --disable-shm \ --no-cpu-limit \ --resample-method=trivial \ --high-priority \ --log-target=syslog \ -L $PULSE_DETECT \ -L "module-esound-protocol-tcp auth-anonymous=1" \ -L "module-native-protocol-tcp auth-anonymous=1" \ -L $PULSE_VOLUME_RESTORE \ -L module-rescue-streams \ -L "module-native-protocol-unix auth-anonymous=1" \ -n & ;; esd) /usr/bin/esd -nobeeps -public -tcp & ;; nasd) /usr/bin/nasd -aa & # Line copied from old LTSP: Should we use it? [pere 2006-03-03] #aumix-minimal -v100 -w100 -c90 -m10 ;; [Ff][Aa][Ll][Ss][Ee]|[Nn]|[Nn][Oo]) # Do not do anything if SOUND_DAEMON is False, N, or No true ;; *) warn "Unable to start unsupported sound daemon: '$SOUND_DAEMON'" ;; esac fi } configure_sound_volume() { if boolean_is_true "$SOUND" ; then # Set up sound volume ## Set higher volume than default if not specified by lts.conf [ -z "$VOLUME" ] && VOLUME=90 [ -z "$PCM_VOLUME" ] && PCM_VOLUME=90 LANG=C amixer -c0 scontents | while read line; do if [ -n "$(echo $line|grep 'Simple mixer control')" ]; then channel=$(echo $line|sed -e 's/^Simple mixer control //') else if [ -n "$channel" ]; then # Translate the channel name into an environmentally # friendly variable. In other words, a variable # in all caps, where forward slashes, hyphens, and # spaces are replaced by underscores, and anything # in parentheses is dropped completely # eg. if the channel is named 'Mic Boost (+20dB)' # then the variable is simply MIC_BOOST_SWITCH # # Oh, and SWITCH is used for on/off switches - value # should be on or off, and VOLUME is used for volumes # where the value should be a number representing a # percentage channel_name=$(echo ${channel}|sed -e s/^\'// -e s/\'.*$// -e 's/ -//g' -e 's/ [(].*[)]//' -e 's/\//_/g' -e 's/ /_/g' -e 's/-/_/g' |tr [a-z] [A-Z]) if [ -n "$(echo $line|grep volume)" ]; then eval channel_vol="\$${channel_name}_VOLUME" if [ "${channel_name}" = "MIC" ]; then cap="cap" else unset cap fi if boolean_is_true "${VOLUME_MANUAL}"; then [ -n "${channel_vol}" ] && echo sset "${channel}" ${channel_vol}% unmute $cap else # Set default MIC volumes to 40 if unspecified # This should resolve feedback issues case "${channel_name}" in *MIC*) [ -z "${channel_vol}" ] && channel_vol=40 ;; esac echo sset "${channel}" ${channel_vol:-$VOLUME}% unmute $cap fi fi if [ -n "$(echo $line|grep switch)" ]; then eval channel_switch="\$${channel_name}_SWITCH" [ -n "${channel_switch}" ] && echo sset "${channel}" ${channel_switch} fi fi unset channel fi done | amixer -c0 --stdin >/dev/null 2>&1 fi } configure_localdev() { if boolean_is_true "$LOCALDEV" ; then # Make mountpoint dir mkdir -p /var/run/drives # Make this sessions secret auth cookie for ltspfs if [ ! -f /var/run/ltspfs_token ]; then mcookie > /var/run/ltspfs_token fi if [ -z "$(pgrep ltspfsd)" ]; then /usr/bin/ltspfsd fi # cdrom devices are handled by the cdpingerponger if [ -z "$(pgrep -l -f -x "/usr/sbin/cdpinger cdrom$")" ]; then /usr/sbin/cdpinger cdrom # default for usb cdroms fi # and start one for every additional cdrom device if [ -L /dev/cdrom?* ];then for CDDEV in $(ls /dev/cdrom?*); do if [ -z "$(pgrep -l -f -x "/usr/sbin/cdpinger ${CDDEV}$")" ]; then /usr/sbin/cdpinger $(basename ${CDDEV}) fi done fi fi } configure_swap() { if boolean_is_true "$USE_LOCAL_SWAP" ; then # Enable local swap partition if found on local disk for part in `sfdisk -l 2>/dev/null | awk '/ 82 / { print $1}'`; do swap_devices="$swap_devices $part" done fi # Enable NBD_SWAP for clients with RAM < NBD_SWAP_THRESHOLD (in MB) if [ -n "$NBD_SWAP_THRESHOLD" ] && [ -z "$NBD_SWAP" ] && [ -z "$swap_devices" ]; then memtotal=$(sed -n 's/MemTotal: *\([0-9]*\) .*/\1/p' /proc/meminfo) # Clients with less than 64 MB RAM already got a network swap in ltsp_nbd if [ "$memtotal" -gt 65536 ] && [ "$memtotal" -lt $((1024*$NBD_SWAP_THRESHOLD)) ]; then echo "Only found ${memtotal}k main ram, trying network swap." NBD_SWAP=true fi fi if boolean_is_true "$NBD_SWAP" ; then NBD_SWAP_SERVER=${NBD_SWAP_SERVER:-"$SERVER"} NBD_SWAP_PORT=${NBD_SWAP_PORT:-"9572"} modprobe nbd # Detect first unused nbd device, skip nbd0 for num in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do nbd-client -c /dev/nbd${num} > /dev/null [ $? -eq 1 ] && break done nbd-client $NBD_SWAP_SERVER $NBD_SWAP_PORT /dev/nbd${num} -swap && \ swap_devices="$swap_devices /dev/nbd${num}" fi if boolean_is_true "$ENCRYPT_SWAP" ; then if [ -x /sbin/cryptsetup ]; then modprobe dm_crypt else echo "ERROR: ENCRYPT_SWAP=Y, but /sbin/cryptsetup not found. disabling swap." swap_devices="" fi fi num=0 for device in $swap_devices ; do swap="$device" if boolean_is_true "$ENCRYPT_SWAP" ; then if [ -x /sbin/cryptsetup ]; then cryptsetup -d /dev/urandom create swap$num $swap && swap="/dev/mapper/swap$num" num=$(($num+1)) fi fi mkswap $swap swapon $swap done # If any swap device was used, there's no need for compcache, so unload it to # gain that 25% of RAM. It makes a significant difference on low end clients. if [ -n "$swap_devices" ]; then for swap in /dev/ramzswap*; do if [ -b "$swap" ]; then swapoff "$swap" && remove_ramzswap=true || true fi done if [ -n "$remove_ramzswap" ]; then modprobe -r ramzswap || true fi fi } configure_printer() { for I in 0 1 2; do eval DEVICE=\$\{PRINTER_${I}_DEVICE\} if [ -n "${DEVICE}" ]; then if [ "$LPSERVER" != "lp_server" ]; then eval PORT=\$\{PRINTER_${I}_PORT:="910${I}"\} eval BAUD=\$\{PRINTER_${I}_SPEED:-"9600"\} eval SIZE=\$\{PRINTER_${I}_DATABITS:-"8"\} eval PARITY=\$\{PRINTER_${I}_PARITY:-"none"\} eval FLOW=\$\{PRINTER_${I}_FLOWCTRL:-"soft"\} JETPIPE_ARGS= [ -n "$BAUD" ] && JETPIPE_ARGS="${JETPIPE_ARGS} -b ${BAUD}" [ -n "$SIZE" ] && JETPIPE_ARGS="${JETPIPE_ARGS} -y ${SIZE}" [ -n "$PARITY" ] && JETPIPE_ARGS="${JETPIPE_ARGS} -p ${PARITY}" if [ -n "$FLOW" ]; then if [ "$FLOW" = "soft" ]; then JETPIPE_ARGS="${JETPIPE_ARGS} -x" else JETPIPE_ARGS="${JETPIPE_ARGS} -r" fi fi /usr/sbin/jetpipe ${JETPIPE_ARGS} ${DEVICE} ${PORT} else eval TYPE=\$\{PRINTER_${I}_TYPE:="P"\} eval PORT=\$\{PRINTER_${I}_PORT:="910${I}"\} eval BAUD=\$\{PRINTER_${I}_SPEED:-"9600"\} eval SIZE=\$\{PRINTER_${I}_DATABITS:-"8"\} eval PARITY=\$\{PRINTER_${I}_PARITY:-"none"\} eval FLOW=\$\{PRINTER_${I}_FLOWCTRL:-"soft"\} eval DEVWO=\${PRINTER_${I}_WRITE_ONLY:="Y"\} eval PRT_OPTIONS=\$\{PRINTER_${I}_OPTIONS\} eval DBG_OPT=\$\{PRINTER_${I}_DEBUG\} PRT_OPTS= if [ "${TYPE}" = "S" ]; then case "${PARITY}" in E) PRT_PARITY_OPT="parenb -parodd";; O) PRT_PARITY_OPT="parenb parodd";; *) PRT_PARITY_OPT="-parity";; esac case "${SIZE}" in 7) PRT_DATABITS_OPT="cs7";; *) PRT_DATABITS_OPT="cs8";; esac case "${FLOW}" in S|soft) PRT_FLOW_OPT="ixon ixoff -crtscts";; *) PRT_FLOW_OPT="-ixon -ixoff crtscts";; esac PRT_OPTS="${BAUD} ${PRT_FLOW_OPT} ${PRT_PARITY_OPT} ${PRT_DATABITS_OPT}" fi WO_OPT= [ "${DEVWO}" = "Y" ] && WO_OPT="-w" DBG_OPT= [ "$PRT_DEBUG" ] && DBG_OPT="-D $PRT_DEBUG" if [ -n "${PRT_OPTS}" ]; then logger -t lp_server "Started with: -n ${PORT} ${WO_OPT} ${DBG_OPT} -d ${DEVICE} -t \"${PRT_OPTS}\"" /usr/sbin/lp_server -n ${PORT} ${WO_OPT} ${DBG_OPT} -d ${DEVICE} -t "${PRT_OPTS}" >/dev/null 2>&1 /dev/null 2>&1 /dev/null 2>/dev/null ; then case "${X_MOUSE_DEVICE}" in *ttyS*) inputattach --"$X_MOUSE_PROTOCOL" "$X_MOUSE_DEVICE" & ;; esac fi } set_time() { # Set up timezone if [ -n "$TIMEZONE" ] && [ -e "/usr/share/zoneinfo/$TIMEZONE" ]; then cp /usr/share/zoneinfo/$TIMEZONE /etc/localtime 2>/dev/null fi # Set timeserver to $SERVER if set to autodetect if [ "$TIMESERVER" = "auto" ]; then TIMESERVER=${SERVER} fi # Set up timeserver if [ -n "$TIMESERVER" ]; then (ntpdate $TIMESERVER; hwclock --systohc --${HWCLOCK:-"utc"} --noadjfile) & fi } load_modules() { for module in $(env|grep ^MODULE_|sed -e s/^MODULE_[0-9]*\=//|sed -e s/\ /*/);do modprobe $(echo $module|tr "*" " ") done } configure_console() { if [ -n "$CONSOLE_KEYMAP" ]; then ckbcomp -model pc105 "$CONSOLE_KEYMAP" | loadkeys fi } configure_resolver() { hostname=$(cat /proc/sys/kernel/hostname) if [ -z "$hostname" ] || [ "$hostname" = "(none)" ]; then # ensure a default hostname, otherwise /etc/hosts may get borked. hostname=ltsp echo $hostname > /proc/sys/kernel/hostname || true fi cat < /etc/hosts 127.0.0.1 localhost 127.0.0.2 $hostname $SERVER server EOF if [ -f /etc/hosts.ltsp ]; then cat /etc/hosts.ltsp >> /etc/hosts fi if [ -n "$DNS_SERVER" ] || [ -n "$SEARCH_DOMAIN" ]; then :>/etc/resolv.conf if [ -n "$SEARCH_DOMAIN" ]; then echo "search $SEARCH_DOMAIN" >> /etc/resolv.conf fi if [ -n "$DNS_SERVER" ]; then for n in $DNS_SERVER; do echo "nameserver ${n}" >> /etc/resolv.conf done fi fi } configure_syslog() { if [ -z "$SYSLOG" ] || [ "$SYSLOG" = "remote" ]; then syslog_conf=/etc/syslog.conf if [ -d /etc/rsyslog.d ]; then syslog_conf=/etc/rsyslog.d/ltsp.conf touch $syslog_conf fi if [ -f "$syslog_conf" ]; then cat < "$syslog_conf" *.* @${SYSLOG_HOST:-$SERVER} EOF fi fi } configure_fstab() { if [ -z "$CONFIGURE_FSTAB" ] || boolean_is_true "$CONFIGURE_FSTAB" ; then echo "/dev/root / rootfs defaults 0 0" > /etc/fstab echo "tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0" >> /etc/fstab mount /tmp fi } configure_home() { test -n "$NFS_HOME" || return 0 # if $NFS_HOME doesn't contain a :/ part if [ "$NFS_HOME" = ${NFS_HOME#*:/} ]; then NFS_HOME="$SERVER:/$NFS_HOME" fi NFS_HOME_OPTIONS=${NFS_HOME_OPTIONS:-defaults} if ! mount -t nfs -o "$NFS_HOME_OPTIONS" "$NFS_HOME" /home; then unset NFS_HOME else if [ -z "$CONFIGURE_FSTAB" ] || boolean_is_true "$CONFIGURE_FSTAB" ; then echo "$NFS_HOME /home nfs $NFS_HOME_OPTIONS 0 0" >> /etc/fstab fi fi } configure_cron() { CRON_FILE=/etc/cron.d/ltsp if [ ! -w "/etc/cron.d" ]; then echo "Warning: /etc/cron.d is not writeable." return 1 fi if [ -n "$SHUTDOWN_TIME" ] ; then echo $SHUTDOWN_TIME | awk -F : '{print $2" "$1" * * * root test ! -S \"$(ls -1 /var/run/ldm_socket_* | head -1)\" && PATH=\$PATH:/sbin/ poweroff -fp" }' >> $CRON_FILE fi for ltsconf in /etc/lts.conf /var/cache/getltscfg-cluster/lts.conf; do if [ -f $ltsconf ]; then cat $ltsconf | grep -E "^[[:blank:]]*CRONTAB_[0-9]{2}[[:blank:]]*=" | sed -e "s/[[:blank:]]*CRONTAB_[0-9]\{2\}[[:blank:]]*=[[:blank:]]*\"//g" -e "s/\"[[:blank:]]*$//g" >> $CRON_FILE fi done } run_rcfiles() { for i in 01 02 03 04 05 06 07 08 09 10; do eval rcfile=\${RCFILE_${i}} [ -x "$rcfile" ] && "$rcfile" $@ done } bind_mounts () { # set defaults test -z "$tmpfs_dir" && tmpfs_dir=/var/lib/ltsp-client-setup mount -t tmpfs -o mode=0755 tmpfs $tmpfs_dir bind_missing="" # preserve directory structure for d in $rw_dirs ; do if [ -d "$d" ]; then cd $tmpfs_dir tar --no-recursion -cpf - $(find $d -type d 2> /dev/null) 2> /dev/null | tar xpf - mount --bind $tmpfs_dir/$d $d else bind_missing="$bind_missing $d" fi done # copy contents into tmpfs for d in $copy_dirs $temp_copy_dirs; do if [ -d "$d" ]; then cd $tmpfs_dir tar -cpf - $d 2> /dev/null | tar xpf - mount --bind $tmpfs_dir/$d $d else bind_missing="$bind_missing $d" fi done # mount one file on top of another for f in $bindfiles ; do if [ -e "$f" ]; then mkdir -p "$(dirname $tmpfs_dir/$f)" cp $f $tmpfs_dir/$f mount --bind $tmpfs_dir/$f $f else bind_missing="$bind_missing $f" fi done if [ -n "$bind_missing" ]; then echo "note: ltsp: missing files or directories for bind mounting: $bind_missing" fi } bind_unmounts() { for dir in $temp_copy_dirs; do umount $dir rm -rf $tmpfs_dir/${dir#/} done } nbd_sendsigs_protection() { if [ -n "$NBD_SERVER" ]; then # register pids of nbd-client and nbd-proxy so that sendsigs doesn't kill # them on shutdown/reboot. # FIXME: only register pids relevent to the root filesystem. nbd_pids=$(pgrep '^nbd-client|^nbd-proxy') for d in /lib/init/rw/sendsigs.omit.d /var/run/sendsigs.omit.d ; do if [ -d "$d" ]; then for p in $nbd_pids ; do echo "$p" >> "$d"/ltsp || true done fi done fi }