jcs's openbsd hax
openbsd
at jcs 691 lines 18 kB view raw
1# $OpenBSD: rc,v 1.588 2025/11/14 10:08:10 jca Exp $ 2 3# System startup script run by init on autoboot or after single-user. 4# Output and error are redirected to console by init, and the console is the 5# controlling terminal. 6 7# Turn off Strict Bourne shell. 8set +o sh 9 10# Subroutines (have to come first). 11 12# Strip in- and whole-line comments from a file. 13# Strip leading and trailing whitespace if IFS is set. 14# Usage: stripcom /path/to/file 15stripcom() { 16 local _file=$1 _line 17 18 [[ -s $_file ]] || return 19 20 while read _line ; do 21 _line=${_line%%#*} 22 [[ -n $_line ]] && print -r -- "$_line" 23 done <$_file 24} 25 26# Update resource limits based on login.conf settings. 27# Usage: update_limit -flag capability 28update_limit() { 29 local _flag=$1 # ulimit flag 30 local _cap=$2 _val # login.conf capability and its value 31 local _suffix 32 33 for _suffix in {,-max,-cur}; do 34 _val=$(getcap -f /etc/login.conf -s ${_cap}${_suffix} daemon 2>/dev/null) 35 [[ -n $_val ]] || continue 36 [[ $_val == infinity ]] && _val=unlimited 37 38 case $_suffix in 39 -cur) ulimit -S $_flag $_val 40 ;; 41 -max) ulimit -H $_flag $_val 42 ;; 43 *) ulimit $_flag $_val 44 return 45 ;; 46 esac 47 done 48} 49 50# Apply sysctl.conf(5) settings. 51sysctl_conf() { 52 [[ -s /etc/sysctl.conf ]] && sysctl -f /etc/sysctl.conf 53 update_limit -p maxproc $(sysctl -n kern.maxproc) 54 update_limit -n openfiles $(sysctl -n kern.maxfiles) 55} 56 57# Apply mixerctl.conf(5) settings. 58mixerctl_conf() { 59 stripcom /etc/mixerctl.conf | 60 while read _line; do 61 mixerctl -q "$_line" 2>/dev/null 62 done 63} 64 65# Apply wsconsctl.conf(5) settings. 66wsconsctl_conf() { 67 [[ -x /sbin/wsconsctl ]] || return 68 69 stripcom /etc/wsconsctl.conf | 70 while read _line; do 71 eval "wsconsctl $_line" 72 done 73} 74 75# Push the old seed into the kernel and create future seeds for the bootloader, 76# the installer and rc(8). 77store_random() { 78 local _bootseed=/etc/random.seed _hostseed=/var/db/host.random 79 80 dd if=$_hostseed of=/dev/random bs=65536 count=1 status=none 81 82 dd if=/dev/random of=$_bootseed bs=512 count=1 status=none 83 dd if=/dev/random of=$_hostseed bs=65536 count=1 status=none 84 85 # Removal of the sticky bit indicates the file has fresh contents for 86 # use by a subsequent bootloader (who sets the sticky bit to prevent 87 # content reuse). 88 chmod u=rw-t,go= $_bootseed $_hostseed 89} 90 91# Populate net.inet.(tcp|udp).baddynamic with the contents of /etc/services so 92# as to avoid randomly allocating source ports that correspond to well-known 93# services. 94# Usage: fill_baddynamic tcp|udp 95fill_baddynamic() { 96 local _service=$1 97 local _sysctl="net.inet.${_service}.baddynamic" 98 99 stripcom /etc/services | 100 { 101 _ban= 102 while IFS=" /" read _name _port _srv _junk; do 103 [[ $_srv == $_service ]] || continue 104 105 _ban="${_ban:+$_ban,}+$_port" 106 107 # Flush before argv gets too long 108 if ((${#_ban} > 1024)); then 109 sysctl -q "$_sysctl=$_ban" 110 _ban= 111 fi 112 done 113 [[ -n $_ban ]] && sysctl -q "$_sysctl=$_ban" 114 } 115} 116 117# Start daemon using the rc.d daemon control scripts. 118# Usage: start_daemon daemon1 daemon2 daemon3 119start_daemon() { 120 local _daemon 121 122 for _daemon; do 123 eval "_do=\${${_daemon}_flags}" 124 [[ $_do != NO ]] && /etc/rc.d/${_daemon} start 125 done 126} 127 128# Generate keys for isakmpd, iked and sshd if they don't exist yet. 129make_keys() { 130 local _isakmpd_key=/etc/isakmpd/private/local.key 131 local _isakmpd_pub=/etc/isakmpd/local.pub 132 local _iked_key=/etc/iked/private/local.key 133 local _iked_pub=/etc/iked/local.pub 134 local _ssh_pub=/etc/ssh/ssh_host_ed25519_key.pub _show_ssh_fp=false 135 136 if [[ ! -f $_isakmpd_key ]]; then 137 echo -n "openssl: generating isakmpd RSA keys... " 138 if openssl genrsa -out $_isakmpd_key 2048 >/dev/null 2>&1 && 139 chmod 600 $_isakmpd_key && 140 openssl rsa -out $_isakmpd_pub -in $_isakmpd_key \ 141 -pubout >/dev/null 2>&1; then 142 echo done. 143 else 144 echo failed. 145 fi 146 fi 147 148 if [[ ! -f $_iked_key ]]; then 149 echo -n "openssl: generating iked ECDSA keys... " 150 if openssl ecparam -genkey -name prime256v1 -out $_iked_key >/dev/null 2>&1 && 151 chmod 600 $_iked_key && 152 openssl ec -out $_iked_pub -in $_iked_key \ 153 -pubout >/dev/null 2>&1; then 154 echo done. 155 else 156 echo failed. 157 fi 158 fi 159 160 [[ -f $_ssh_pub ]] || _show_ssh_fp=true 161 ssh-keygen -A 162 $_show_ssh_fp && ssh-keygen -lf $_ssh_pub | 163 (read sz fp comm type && echo "sshd: $type $fp") 164 165 if [[ ! -f /etc/soii.key ]]; then 166 openssl rand -hex 16 > /etc/soii.key && chmod 600 /etc/soii.key 167 fi 168} 169 170# Re-link libraries, placing the objects in a random order. 171reorder_libs() { 172 local _error=false _dkdev _liba _libas _mp _ro_list _tmpdir 173 local _relink=/usr/share/relink 174 175 [[ $library_aslr == NO ]] && return 176 177 # Skip if /usr/lib, /usr/libexec or /usr/share/relink are on nfs mounted 178 # filesystems, otherwise record which ones are mounted read-only. 179 for _dkdev in $(df /usr/{lib,libexec} $_relink | 180 sed '1d;s/ .*//' | sort -u); do 181 _mp=$(mount -t ffs | grep "^$_dkdev") || return 182 if [[ $_mp == *read-only* ]]; then 183 _ro_list="$_ro_list ${_mp%% *}" 184 fi 185 done 186 187 echo 'reordering:' 188 189 # Remount the (read-only) filesystems in _ro_list as read-write. 190 for _mp in $_ro_list; do 191 if ! mount -u -w $_mp; then 192 echo '(failed).' 193 return 194 fi 195 done 196 197 # Only choose the latest version of the libraries. 198 for _liba in $_relink/usr/lib/lib{c,crypto}; do 199 _libas="$_libas $(ls $_liba.so.+([0-9.]).a | sort -rV | head -1)" 200 done 201 202 for _liba in $_relink/usr/libexec/ld.so.a $_libas; do 203 _tmpdir=$(mktemp -dq $_relink/_rebuild.XXXXXXXXXXXX) && 204 ( 205 set -o errexit 206 _install='install -F -o root -g bin -m 0444' 207 _lib=${_liba##*/} 208 _lib=${_lib%.a} 209 _lib_dir=${_liba#$_relink} 210 _lib_dir=${_lib_dir%/*} 211 cd $_tmpdir 212 ar x $_liba 213 if [[ $_lib == ld.so ]]; then 214 echo " $_lib" 215 args="-g -x -e _dl_start \ 216 --version-script=Symbols.map --shared -Bsymbolic \ 217 --no-undefined" 218 [[ -f ld.script ]] && args="$args -T ld.script" 219 ld $args -o ld.so.test $(ls *.o | sort -R) 220 chmod u+x test-ld.so 221 [[ $(./test-ld.so ok) == './test-ld.so: ok!' ]] 222 $_install /usr/libexec/ld.so /usr/libexec/ld.so.save 223 $_install ld.so.test $_lib_dir/ld.so 224 else 225 echo " ${_lib%%.*}" 226 cc -shared -o $_lib $(ls *.so | sort -R) $(<.ldadd) 227 [[ -s $_lib ]] && file $_lib | fgrep -q 'shared object' 228 LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir awk 'BEGIN {exit 0}' 229 LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir openssl \ 230 x509 -in /etc/ssl/cert.pem -out /dev/null 231 $_install $_lib $_lib_dir/$_lib 232 fi 233 ) || { _error=true; break; } 234 done 235 236 for _bin in $_relink/usr/sbin/sshd $_relink/usr/libexec/sshd-session \ 237 $_relink/usr/libexec/sshd-auth $_relink/usr/bin/ssh-agent; do 238 _tmpdir=$(mktemp -dq $_relink/_rebuild.XXXXXXXXXXXX) && 239 ( 240 set -o errexit 241 cd $_tmpdir 242 _binn=${_bin##*/} 243 _bint=${_bin}/${_binn}.tar 244 if [[ -f $_bint ]]; then 245 echo " $_binn" 246 tar xf $_bint 247 if [[ -f install.sh ]]; then 248 sh install.sh >/dev/null 2>&1 249 else 250 make -f Makefile.relink relink >/dev/null 2>&1 251 fi 252 fi 253 ) || { _error=true; break; } 254 done 255 256 rm -rf $_relink/_rebuild.* 257 258 # Restore previous mount state if it was changed. 259 for _mp in $_ro_list; do 260 mount -u -r $_mp || _error=true 261 done 262 263 if $_error; then 264 echo '(failed).' 265 else 266 echo '.' 267 fi 268} 269 270# Read output of reorder_libs co-process and output on console. 271wait_reorder_libs() { 272 local _line 273 274 [[ $library_aslr == NO ]] && return 275 276 while IFS= read -p _line; do 277 echo -n "$_line" 278 done 279 echo 280} 281 282# Run rc.* script and email output to root. 283# Usage: run_upgrade_script firsttime|sysmerge 284run_upgrade_script() { 285 local _suffix=$1 286 287 [[ -n $_suffix ]] || return 1 288 289 if [[ -f /etc/rc.$_suffix ]]; then 290 echo "running rc.$_suffix" 291 mv /etc/rc.$_suffix /etc/rc.$_suffix.run 292 . /etc/rc.$_suffix.run 2>&1 | tee /dev/tty | 293 mail -Es "$(hostname) rc.$_suffix output" root >/dev/null 294 fi 295 rm -f /etc/rc.$_suffix.run 296} 297 298# If system still has old 16-partition disklabel, create fallback device nodes 299# for the root filesystem to allow repair in a future kernel with 64-partition 300# disklabel. This is important if root isn't on sd0 or wd0. When things fail: 301# fsck /dev/rrootdisk 302# mount -uw /dev/rootdisk / 303# cd /dev && ./MAKEDEV redodisks 304rootdisk_nodes() { 305 if [ $(sysctl -n kern.maxpartitions) = 16 ]; then 306 _rootdev=$(mount | grep ' / ' | cut -d' ' -f1) 307 _maj=$(stat -f "%Hr" $_rootdev) 308 _omin=$(stat -f "%Lr" $_rootdev) 309 _min=$((_omin / 16 * 64)) 310 if [ -b /dev/rootdisk -a \ 311 "$(stat -qf %Hr,%Lr /dev/rootdisk)" = "$_maj,$_min" ]; then 312 return 313 fi 314 # does not exist or device changed, redo 315 _rrootdev=$(echo $_rootdev | sed -e 's,dev/,dev/r,') 316 _rmaj=$(stat -f "%Hr" $_rrootdev) 317 rm -f /dev/rrootdisk /dev/rootdisk 318 mknod -m 600 /dev/rrootdisk c $_rmaj $_min 319 mknod -m 600 /dev/rootdisk b $_maj $_min 320 fi 321} 322 323# Check filesystems, optionally by using a fsck(8) flag. 324# Usage: do_fsck [-flag] 325do_fsck() { 326 fsck -p "$@" 327 case $? in 328 0) ;; 329 2) exit 1 330 ;; 331 4) echo "Rebooting..." 332 reboot 333 echo "Reboot failed; help!" 334 exit 1 335 ;; 336 8) echo "Automatic file system check failed; help!" 337 exit 1 338 ;; 339 12) echo "Boot interrupted." 340 exit 1 341 ;; 342 130) # Interrupt before catcher installed. 343 exit 1 344 ;; 345 *) echo "Unknown error; help!" 346 exit 1 347 ;; 348 esac 349} 350 351# End subroutines. 352 353stty status '^T' 354 355# Set shell to ignore SIGINT (2), but not children; shell catches SIGQUIT (3) 356# and returns to single user after fsck. 357trap : 2 358trap : 3 # Shouldn't be needed. 359 360export HOME=/ 361export INRC=1 362export PATH=/sbin:/bin:/usr/sbin:/usr/bin 363 364# /etc/myname contains my symbolic name. 365if [[ -f /etc/myname ]]; then 366 hostname "$(stripcom /etc/myname)" 367fi 368 369# Must set the domainname before rc.conf, so YP startup choices can be made. 370if [[ -s /etc/defaultdomain && -z "$(sysctl -n kern.domainname)" ]]; then 371 domainname "$(stripcom /etc/defaultdomain)" 372fi 373 374# Get local functions from rc.subr to load rc.conf into scope. 375FUNCS_ONLY=1 . /etc/rc.d/rc.subr 376_rc_parse_conf 377 378# If executed with the 'shutdown' parameter by the halt, reboot or shutdown: 379# - update seed files 380# - execute the rc.d scripts specified by $pkg_scripts in reverse order 381# - bring carp interfaces down gracefully 382if [[ $1 == shutdown ]]; then 383 store_random 2>/dev/null || 384 echo 'warning: cannot write random seed to disk' 385 386 # If we are in secure level 0, assume single user mode. 387 if (($(sysctl -n kern.securelevel) == 0)); then 388 echo 'single user: not running shutdown scripts' 389 else 390 set -A _d -- $pkg_scripts 391 _i=${#_d[*]} 392 if ((_i)); then 393 echo -n 'stopping package daemons:' 394 while ((--_i >= 0)); do 395 [[ -x /etc/rc.d/${_d[_i]} ]] && 396 /etc/rc.d/${_d[_i]} stop 397 done 398 echo '.' 399 fi 400 401 if /etc/rc.d/vmd check > /dev/null; then 402 echo -n 'stopping VMs' 403 /etc/rc.d/vmd stop > /dev/null 404 echo '.' 405 fi 406 407 [[ -f /etc/rc.shutdown ]] && sh /etc/rc.shutdown 408 fi 409 410 ifconfig | while read _if _junk; do 411 [[ $_if == carp+([0-9]): ]] && ifconfig ${_if%:} down 412 done 413 414 exit 0 415fi 416 417# If bootblocks failed to give us random, try to cause some churn 418(dmesg; sysctl hw.{uuid,serialno,sensors} ) >/dev/random 2>&1 419 420# Add swap block-devices. 421swapctl -A -t blk 422 423# Run filesystem check unless a /fastboot file exists. 424if [[ -e /fastboot ]]; then 425 echo "Fast boot: skipping disk checks." 426elif [[ $1 == autoboot ]]; then 427 echo "Automatic boot in progress: starting file system checks." 428 do_fsck 429fi 430 431# From now on, allow user to interrupt (^C) the boot process. 432trap "echo 'Boot interrupted.'; exit 1" 3 433 434# Unmount all filesystems except root. 435umount -a >/dev/null 2>&1 436 437# Mount all filesystems except those of type NFS and VND. 438mount -a -t nonfs,vnd 439 440# Re-mount the root filesystem read/writeable. (root on nfs requires this, 441# others aren't hurt.) 442mount -uw / 443chmod og-rwx /bsd 444ln -fh /bsd /bsd.booted 445 446rm -f /fastboot 447 448rootdisk_nodes 449 450# Set flags on ttys. 451ttyflags -a 452 453# Set keyboard encoding. 454if [[ -x /sbin/kbd && -s /etc/kbdtype ]]; then 455 kbd "$(</etc/kbdtype)" 456fi 457 458wsconsctl_conf 459 460# Set initial temporary pf rule set. 461if [[ $pf != NO ]]; then 462 RULES=" 463 block all 464 pass on lo0 465 pass in proto tcp from any to any port ssh keep state 466 pass out proto { tcp, udp } from any to any port domain keep state 467 pass out inet proto icmp all icmp-type echoreq keep state 468 pass out inet proto udp from any port bootpc to any port bootps 469 pass in inet proto udp from any port bootps to any port bootpc" 470 471 if ifconfig lo0 inet6 >/dev/null 2>&1; then 472 RULES="$RULES 473 pass out inet6 proto icmp6 all icmp6-type neighbrsol 474 pass inet6 proto icmp6 all icmp6-type neighbradv no state 475 pass out inet6 proto icmp6 all icmp6-type routersol 476 pass in inet6 proto icmp6 all icmp6-type routeradv 477 pass out inet6 proto udp from any port dhcpv6-client to any port dhcpv6-server 478 pass in inet6 proto udp from any port dhcpv6-server to any port dhcpv6-client" 479 fi 480 481 RULES="$RULES 482 pass in proto carp keep state (no-sync) 483 pass out proto carp !received-on any keep state (no-sync)" 484 485 if (($(sysctl -n vfs.mounts.nfs 2>/dev/null)+0 > 0)); then 486 # Don't kill NFS. 487 RULES="set reassemble yes no-df 488 $RULES 489 pass in proto { tcp, udp } from any port { sunrpc, nfsd } to any 490 pass out proto { tcp, udp } from any to any port { sunrpc, nfsd } !received-on any" 491 fi 492 493 print -- "$RULES" | pfctl -f - 494 pfctl -e 495fi 496 497fill_baddynamic udp 498fill_baddynamic tcp 499 500sysctl_conf 501 502mount -s /var >/dev/null 2>&1 # cannot be on NFS 503mount -s /var/log >/dev/null 2>&1 # cannot be on NFS 504mount -s /usr >/dev/null 2>&1 # if NFS, fstab must use IP address 505 506reorder_libs 2>&1 |& 507 508start_daemon slaacd dhcpleased resolvd >/dev/null 2>&1 509 510echo 'starting network' 511 512# Set carp interlock by increasing the demotion counter. 513# Prevents carp from preempting until the system is booted. 514ifconfig -g carp carpdemote 128 515 516sh /etc/netstart 517 518start_daemon unwind >/dev/null 2>&1 519 520store_random 521 522wait_reorder_libs 523 524# Load pf rules and bring up pfsync interface. 525if [[ $pf != NO ]]; then 526 if [[ -f /etc/pf.conf ]]; then 527 pfctl -f /etc/pf.conf 528 fi 529 if [[ -f /etc/hostname.pfsync0 ]]; then 530 sh /etc/netstart pfsync0 531 fi 532fi 533 534# Clean up left-over files. 535rm -f /etc/nologin /var/spool/lock/LCK.* 536(cd /var/run && { rm -rf -- *; install -c -m 664 -g utmp /dev/null utmp; }) 537(cd /var/authpf && rm -rf -- *) 538 539# Save a copy of the boot messages. 540dmesg >/var/run/dmesg.boot 541 542make_keys 543 544echo -n 'starting early daemons:' 545start_daemon syslogd ldattach bpflogd pflogd nsd unbound ntpd 546start_daemon iscsid isakmpd iked sasyncd ldapd npppd 547echo '.' 548 549# Load IPsec rules. 550if [[ $ipsec != NO && -f /etc/ipsec.conf ]]; then 551 ipsecctl -f /etc/ipsec.conf 552fi 553 554echo -n 'starting RPC daemons:' 555start_daemon portmap 556if [[ -n $(domainname) ]]; then 557 start_daemon ypldap ypserv ypbind 558fi 559start_daemon mountd nfsd lockd statd amd 560echo '.' 561 562# Check and mount remaining file systems and enable additional swap. 563mount -a 564swapctl -A -t noblk 565do_fsck -N 566mount -a -N 567 568# Build kvm(3) and /dev databases. 569kvm_mkdb 570dev_mkdb 571 572# /var/crash should be a directory or a symbolic link to the crash directory 573# if core dumps are to be saved. 574if [[ -d /var/crash ]]; then 575 savecore $savecore_flags /var/crash 576fi 577 578# Store ACPI tables in /var/db/acpi to be used by sendbug(1). 579if [[ -x /usr/sbin/acpidump ]]; then 580 acpidump -q -o /var/db/acpi/ 581fi 582 583if [[ $check_quotas == YES ]]; then 584 echo -n 'checking quotas:' 585 quotacheck -a 586 echo ' done.' 587 quotaon -a 588fi 589 590# Set proper permission for the tty device files. 591chmod 666 /dev/tty[pqrstuvwxyzPQRST]* 592chown root:wheel /dev/tty[pqrstuvwxyzPQRST]* 593 594# Check for the password temp/lock file. 595if [[ -f /etc/ptmp ]]; then 596 logger -s -p auth.err \ 597 'password file may be incorrect -- /etc/ptmp exists' 598fi 599 600echo clearing /tmp 601 602# Prune quickly with one rm, then use find to clean up /tmp/[lqv]* 603# (not needed with mfs /tmp, but doesn't hurt there...). 604(cd /tmp && rm -rf [a-km-pr-uw-zA-Z]*) 605(cd /tmp && 606 find . -maxdepth 1 ! -name . ! -name lost+found ! -name quota.user \ 607 ! -name quota.group ! -name vi.recover -execdir rm -rf -- {} \;) 608 609# Create Unix sockets directories for X if needed and make sure they have 610# correct permissions. 611[[ -d /usr/X11R6/lib ]] && mkdir -m 1777 /tmp/.{X11,ICE}-unix 612 613# Create parent directory for XDG_RUNTIME_DIR 614mkdir -p -m 755 /tmp/run/user 615 616[[ -f /etc/rc.securelevel ]] && sh /etc/rc.securelevel 617 618# rc.securelevel did not specifically set -1 or 2, so select the default: 1. 619(($(sysctl -n kern.securelevel) == 0)) && sysctl kern.securelevel=1 620 621 622# Patch /etc/motd. 623if [[ ! -f /etc/motd ]]; then 624 install -c -o root -g wheel -m 664 /dev/null /etc/motd 625fi 626if T=$(mktemp /tmp/_motd.XXXXXXXXXX); then 627 sysctl -n kern.version | sed 1q >$T 628 sed -n '/^$/,$p' </etc/motd >>$T 629 cmp -s $T /etc/motd || cp $T /etc/motd 630 rm -f $T 631fi 632 633if [[ $accounting == YES ]]; then 634 [[ ! -f /var/account/acct ]] && touch /var/account/acct 635 echo 'turning on accounting' 636 accton /var/account/acct 637fi 638 639if [[ -x /sbin/ldconfig ]]; then 640 echo 'creating runtime link editor directory cache.' 641 [[ -d /usr/local/lib ]] && shlib_dirs="/usr/local/lib $shlib_dirs" 642 [[ -d /usr/X11R6/lib ]] && shlib_dirs="/usr/X11R6/lib $shlib_dirs" 643 ldconfig $shlib_dirs 644fi 645 646echo 'preserving editor files.'; /usr/libexec/vi.recover 647 648# If rc.sysmerge exists, run it just once, and make sure it is deleted. 649run_upgrade_script sysmerge 650 651echo -n 'starting network daemons:' 652start_daemon ldomd sshd snmpd ldpd ripd ospfd ospf6d bgpd ifstated 653start_daemon relayd dhcpd dhcrelay mrouted dvmrpd radiusd eigrpd route6d 654start_daemon dhcp6leased rad hostapd lpd smtpd slowcgi bgplgd httpd ftpd 655start_daemon ftpproxy ftpproxy6 tftpd tftpproxy identd inetd rarpd bootparamd 656start_daemon rbootd mopd vmd spamd spamlogd sndiod 657echo '.' 658 659# If rc.firsttime exists, run it just once, and make sure it is deleted. 660run_upgrade_script firsttime 661 662# Run rc.d(8) scripts from packages. 663if [[ -n $pkg_scripts ]]; then 664 echo -n 'starting package daemons:' 665 for _daemon in $pkg_scripts; do 666 if [[ -x /etc/rc.d/$_daemon ]]; then 667 start_daemon $_daemon 668 else 669 echo -n " ${_daemon}(absent)" 670 fi 671 done 672 echo '.' 673fi 674 675[[ -f /etc/rc.local ]] && sh /etc/rc.local 676 677# Disable carp interlock. 678ifconfig -g carp -carpdemote 128 679 680mixerctl_conf 681 682echo -n 'starting local daemons:' 683start_daemon apmd sensorsd hotplugd watchdogd cron wsmoused xenodm 684echo '.' 685 686# Re-link the kernel, placing the objects in a random order. 687# Replace current with relinked kernel and inform root about it. 688/usr/libexec/reorder_kernel & 689 690date 691exit 0