]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/boot/bootrc
provide /n and /mnt early in bootrc to allow consistent use in /lib/namespace
[plan9front.git] / sys / src / 9 / boot / bootrc
old mode 100644 (file)
new mode 100755 (executable)
index b5a9cfb..b8c96cc
@@ -1,26 +1,38 @@
-# TODO
-# settime
-# handle rootspec
-# handle rootdir
-# clean rc environment before running init(8)
-# kfs
-# caching
-
-rfork e
-# boot methods
-mlocal = (configlocal connectlocal)
-mtcp = (configtcp connecttcp)
-mtab = (mlocal mtcp)
-config=1
-connect=2
-bootargs=()
-
-. /rc/lib/conf.rc
-. /rc/lib/menu.rc
-. /rc/lib/local.rc
-. /rc/lib/tcp.rc
-
-cputype=`{cat '#e'/cputype}
+#!/bin/rc
+
+# mount points
+mntgen -s slashn /n && chmod 666 /srv/slashn
+mntgen -s slashmnt /mnt && chmod 666 /srv/slashmnt
+mntgen -s mntexport /mnt/exportfs && chmod 666 /srv/mntexport
+
+bind /root /mnt/broot
+unmount /root
+
+bind -q '#d' /fd
+bind -q '#p' /proc
+for(i in S f k æ t b m)
+       bind -qa '#'^$i /dev
+
+# bind in an ip interface
+for(i in I l^(0 1 2 3))
+       bind -qa '#'$i /net
+
+# usualy better than 1970
+cat '#r/rtc' >/dev/time >[2]/dev/null
+
+# reparse variables
+for(i in `{ls -Qp /env}){
+       switch($i){
+       case '*'* 'fn#'* e820 apm0 apid ifs path pid prompt status ?
+               # ignore these
+       case *
+               $i=`{echo $$i}
+       }
+}
+
+fn sigint {
+       status=interrupted
+}
 
 fn fatal {
        echo $*
@@ -31,116 +43,118 @@ fn must {
        $* || fatal $"*^': '^$status
 }
 
-fn devinit{
-       bind -qa '#c' /dev
-       bind -qa '#S' /dev
-       bind -qa '#f' /dev
-       bind -qa '#k' /dev
-       bind -qa '#æ' /dev
-}
-
-fn usbinit{
-       if(test -e '#u'){
-               bind -a '#u' /dev
-               usb/usbd
+fn ask {
+       echo -n $1
+       echo -n $2
+       if(! ~ $#3 0){
+               echo -n '['
+               echo -n $3
+               echo -n '] '
        }
-}
-
-fn kbmap{
-       if(! ~ $#kbmap 0){
-               bind -a '#κ' /dev
-               cat $kbmap > /dev/kbmap
+       $1=`{dd -bs 64 -count 1 >[2]/dev/null}
+       if(~ $#$1 0)
+               $1=$3
+       if(~ $"$1 '!rc'){
+               rc -i
+               $1=()
        }
+       if(~ $#$1 0)
+               ask $*
 }
 
-fn readmethod{
-       echo
-       echo Storage devices
-       for(i in /dev/sd[A-Z][0-9]*){
-               echo -n local!^$i'      '
-               echo `{sed 's/inquiry[ ]+//g; q' $i/ctl}\
-                       partitions: `{cat $i/ctl | grep part | awk '{print $2}'}
-       }
+mt=()
 
-       found=0
-       while(~ $found 0){
-               timeo=5
-               resp=()
-               while(~ $#resp 0){
-                       echo -n 'root is from: '
-                       resp=`{tread $timeo}
-                       if(! ~ $status ''){
-                               bootconf        # set configuration from file
-                               if(! ~ $#nobootprompt 0)
-                                       bootargs=$nobootprompt
-                               resp=$bootargs
-                       }
-                       if(~ $resp !rc)
-                               rc -i
-                       timeo=0
-               }
-
-               method=`{echo $resp | awk -F! '{print $1}'}
-               NF=`{echo $resp | awk -F! '{print NF}'}
-
-               for(i in `{seq 1 $#mtab}){
-                       if(~ $mtab($i) m^$method)
-                               found = $i 
+fn main{
+       mp=()
+       while(~ $#mp 0){
+               if(~ $#nobootprompt 0){
+                       echo
+                       showlocaldevs
+                       ask bootargs ' is (tcp, il, local!device)' $"bootargs
                }
-               if(~ $found 0){
-                       echo method $method not found
+               if not bootargs=$nobootprompt
+               nobootprompt=()
+               mn=`{echo $bootargs | sed 's,!, ,'}
+               ma=$mn(2-)
+               mn=$mn(1)
+               switch(m$"mn){
+               case $mt
+                       mp=m$mn
+                       mp=$$mp
                }
        }
 
-       methodarg = `{echo $resp | sed 's/^[A-Za-z]+!(.*)$/\1/'}
-       mp = $$mtab($found)
-}
-
-fn authentication{
+       # authentication agent
        if(! test -f /srv/factotum){
-               x=(auth/factotum -sfactotum)
-               if(~ $cpuflag 1)
-                       x=($x -kS)
+               x=(/boot/factotum -n -sfactotum)
+               if(~ $service cpu){
+                       x=($x -S)
+                       if(~ -k $ff)
+                               x=($x -k)
+               }
                if not
                        x=($x -u)
-               if(! ~ $#authaddr 0)
-                       x=($x -a $authaddr)
                if(! ~ $#debugfactotum 0)
                        x=($x -p)
                must $x
        }
-}
 
-fn swapproc{
-       if(test -x '#c'/swap)
-               echo -n start > '#c'/swap
-}
+       # config method
+       $mp(1) $ma
+
+       # load keys from secstore if $auth or $secstore is not empty
+       x=secstore
+       if(~ $#$x 0) x=auth
+       if(! ~ $#$x 0 && test -x /bin/auth/secstore && test -f /mnt/factotum/ctl){
+               x=(auth/secstore -G factotum -s^$$x)
+               if(~ $service cpu)
+                       $x -n >/mnt/factotum/ctl
+               if(~ $status *readnvram* || ! ~ $service cpu)
+                       $x >/mnt/factotum/ctl
+       }
 
-fn main{
-       readmethod
-       $mp($config)
-
-       switch($method){
-       case local
-               islocal=1
-       case hybrid
-               ishybrid=1
+       # connect method
+       $mp(2) $ma
+
+       # insert cfs in the pipeline
+       if(test -x /bin/cfs){
+               if(~ $#bootdisk 1 && ~ $#cfs 0)
+                       cfs=$bootdisk/cache
+               if(~ $#cfs 1 && ! ~ $cfs off && test -f $cfs){
+                       x=(/bin/cfs -s -f $cfs)
+                       if(~ -f $ff)
+                               x=($x -r)
+                       {$x </srv/boot &} | echo 0 >/srv/cfs
+                       rm /srv/boot
+                       mv /srv/cfs /srv/boot
+               }
        }
 
-       # authentication agent
-       authentication
+       # mount and change root in new enviroment and namespace
+       rfork ne
 
-       # connect to the root file system
-       $mp($connect)
+       # mount root filesystem
+       if(~ $#rootdir 0)
+               rootdir=/root
+       must mount -c /srv/boot $rootdir
 
-       must mount -c /srv/boot /root
+       # compile init command
+       if(~ $#init 0){
+               init=/$cputype/init
+               if(~ $service cpu)
+                       init=($init -c)
+               if not
+                       init=($init -t)
+               if(~ -m $ff)
+                       init=($init -m)
+       }
 
-       swapproc
+       # remove enviroment variables
+       rm -f '#e/'^$mt '#e/'? '#e/'?? '#e/fn#'* 
 
        # remove part of our temporary root
-       unmount /$cputype/bin /bin
+       /mnt/broot/$cputype/bin/unmount /$cputype/bin /bin
        /mnt/broot/$cputype/bin/unmount /rc/bin /bin
-       /mnt/broot/$cputype/bin/unmount /boot /bin
        /mnt/broot/$cputype/bin/unmount /
 
        # create the name space, mount the root fs
@@ -150,27 +164,74 @@ fn main{
        # remove the remaining temporary root
        /mnt/broot/$cputype/bin/unmount /mnt/broot
 
-       rootdir=/root
-
-       if(~ $#init 0){
-               init=/$cputype/init
-               if(~ $cpuflag 1)
-                       init=($init -c)
-               if not
-                       init=($init -t)
-               # TODO handle mflag
-       }
        exec $init
 }
 
-bind -q '#p' /proc
+# keyboard and serial console
+if(test -x /bin/aux/kbdfs){
+       a=$console(1)
+       if(! ~ $#a 0)
+               a=/dev/eia^$a
+       aux/kbdfs -q -s cons $a
+}
 
-devinit
-usbinit                # set up usb keyboard, mouse, and disk, if any
-kbmap
+# usb devices
+if(test -x /bin/nusbrc && ! test -e /env/nousbrc)
+       nusbrc
 
-configlocal    # add partitions and binds
+# load boot methods
+fn showlocaldevs {}
+fn configlocal {}
+for(i in /rc/lib/*.rc){
+       . $i
+}
 
-while(){
-       @{rfork n; main}
+# add partitions and binds
+configlocal
+
+# boot(8) command line arguments
+ff=()
+aa=()
+while(! ~ $#* 0){
+       if(~ $1 -*){
+               if(~ $1 -u*){
+                       if(~ $1 -u){
+                               user=$2
+                               shift
+                       }
+                       if not {
+                               user=`{echo $1 | sed 's,^-u,,g'}
+                       }
+               }
+               if not {
+                       if(~ $1 -*f*)
+                               ff=($ff -f)
+                       if(~ $1 -*k*)
+                               ff=($ff -k)
+                       if(~ $1 -*m*)
+                               ff=($ff -m)
+               }
+               shift
+       }
+       if not {
+               while(! ~ $#* 0){
+                       aa=($aa $1)
+                       shift
+               }
+       }
 }
+if(! ~ $#aa 0 && ~ $#bootargs 0 && ~ $#nobootprompt 0){
+       bootargs=$aa
+       nobootprompt=$aa
+}
+
+while(){
+       @{main}
+
+       # subshell doesnt wait on interrupts
+       while(~ $status interrupted){wait}
+
+       # cleanup so it can be restarted
+       nobootprompt=()
+       rm -f /srv/^(cfs boot cs dns)
+} </dev/cons