The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/local.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include <u.h>
    2 #include <libc.h>
    3 #include <../boot/boot.h>
    4 
    5 static char diskname[64];
    6 static char *disk;
    7 static char **args;
    8 
    9 void
   10 configlocal(Method *mp)
   11 {
   12         char *p;
   13         int n;
   14 
   15         if(*sys == '/' || *sys == '#'){
   16                 /*
   17                  *  if the user specifies the disk in the boot cmd or
   18                  * 'root is from' prompt, use it
   19                  */
   20                 disk = sys;
   21         } else if(strncmp(argv0, "dksc(0,", 7) == 0){
   22                 /*
   23                  *  on many mips arg0 of the boot command specifies the
   24                  *  scsi logical unit number
   25                  */
   26                 p = strchr(argv0, ',');
   27                 n = strtoul(p+1, 0, 10);
   28                 sprint(diskname, "#w%d/sd%dfs", n, n);
   29                 disk = diskname;
   30         } else if(mp->arg){
   31                 /*
   32                  *  a default is supplied when the kernel is made
   33                  */
   34                 disk = mp->arg;
   35         } else if(*bootdisk){
   36                 /*
   37                  *  an environment variable from a pc's plan9.ini or
   38                  *  from the mips nvram or generated by the kernel
   39                  *  is the last resort.
   40                  */
   41                 disk = bootdisk;
   42         }
   43 
   44         /* if we've decided on one, pass it on to all programs */
   45         if(disk)
   46                 setenv("bootdisk", disk);
   47 
   48         USED(mp);
   49 }
   50 
   51 int
   52 connectlocalkfs(void)
   53 {
   54         int i, pid, fd, p[2];
   55         char partition[64];
   56         char *dev;
   57         char **arg, **argp;
   58         Dir *d;
   59 
   60         if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
   61                 return -1;
   62 
   63         dev = disk ? disk : bootdisk;
   64         snprint(partition, sizeof partition, "%sfs", dev);
   65         fd = open(partition, OREAD);
   66         if(fd < 0){
   67                 strcpy(partition, dev);
   68                 fd = open(partition, OREAD);
   69                 if(fd < 0)
   70                         return -1;
   71         }
   72         /*
   73          * can't do this check -- might be some other server posing as kfs.
   74          *
   75         memset(buf, 0, sizeof buf);
   76         pread(fd, buf, 512, 0);
   77         close(fd);
   78         if(memcmp(buf+256, "kfs wren device\n", 16) != 0){
   79                 if(strstr(partition, "/fs"))
   80                         print("no kfs file system found on %s\n", partition);
   81                 return -1;
   82         }
   83          *
   84          */
   85         d = dirfstat(fd);
   86         close(fd);
   87         if(d == nil)
   88                 return -1;
   89         if(d->mode&DMDIR){
   90                 free(d);
   91                 return -1;
   92         }
   93         free(d);
   94 
   95         print("kfs...");
   96         if(pipe(p)<0)
   97                 fatal("pipe");
   98         switch(pid = fork()){
   99         case -1:
  100                 fatal("fork");
  101         case 0:
  102                 arg = malloc((bargc+5)*sizeof(char*));
  103                 argp = arg;
  104                 *argp++ = "kfs";
  105                 *argp++ = "-f";
  106                 *argp++ = partition;
  107                 *argp++ = "-s";
  108                 for(i=1; i<bargc; i++)
  109                         *argp++ = bargv[i];
  110                 *argp = 0;
  111 
  112                 dup(p[0], 0);
  113                 dup(p[1], 1);
  114                 close(p[0]);
  115                 close(p[1]);
  116                 exec("/boot/kfs", arg);
  117                 fatal("can't exec kfs");
  118         default:
  119                 break;
  120         }
  121         for(;;){
  122                 if((i = waitpid()) == -1)
  123                         fatal("waitpid for kfs failed");
  124                 if(i == pid)
  125                         break;
  126         }
  127 
  128         close(p[1]);
  129         return p[0];
  130 }
  131 
  132 static void
  133 run(char *file, ...)
  134 {
  135         char buf[64];
  136         Waitmsg *w;
  137         int pid;
  138 
  139         switch(pid = fork()){
  140         case -1:
  141                 fatal("fork");
  142         case 0:
  143                 exec(file, &file);
  144                 snprint(buf, sizeof buf, "can't exec %s", file);
  145                 fatal(buf);
  146         default:
  147                 while((w = wait()) != nil)
  148                         if(w->pid == pid)
  149                                 break;
  150                 if(w == nil){
  151                         snprint(buf, sizeof buf, "wait returned nil running %s", file);
  152                         fatal(buf);
  153                 }
  154         }
  155 }
  156 
  157 static int
  158 print1(int fd, char *s)
  159 {
  160         return write(fd, s, strlen(s));
  161 }
  162 
  163 void
  164 configloopback(void)
  165 {
  166         int fd;
  167 
  168         if((fd = open("/net/ipifc/clone", ORDWR)) < 0){
  169                 bind("#I", "/net", MAFTER);
  170                 if((fd = open("/net/ipifc/clone", ORDWR)) < 0)
  171                         fatal("open /net/ipifc/clone for loopback");
  172         }
  173         if(print1(fd, "bind loopback /dev/null") < 0
  174         || print1(fd, "add 127.0.0.1 255.255.255.255") < 0)
  175                 fatal("write /net/ipifc/clone for loopback");
  176 }
  177 
  178 int
  179 connectlocalfossil(void)
  180 {
  181         int fd;
  182         char *venti, *f[32], *p;
  183         int nf;
  184         char partition[128], buf[512];
  185         char *dev;
  186 
  187         if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0)
  188                 return -1;
  189 
  190         /* look for fossil partition */
  191         dev = disk ? disk : bootdisk;
  192         snprint(partition, sizeof partition, "%sfossil", dev);
  193         fd = open(partition, OREAD);
  194         if(fd < 0){
  195                 strcpy(partition, dev);
  196                 fd = open(partition, OREAD);
  197                 if(fd < 0)
  198                         return -1;
  199         }
  200         memset(buf, 0, sizeof buf);
  201         pread(fd, buf, 512, 127*1024);
  202         close(fd);
  203         if(memcmp(buf, "fossil config\n", 14) != 0){
  204                 if(strstr(partition, "/fossil"))
  205                         print("no fossil config found on %s\n", partition);
  206                 return -1;
  207         }
  208 
  209         settime(1, -1, nil);
  210 
  211         /* make venti available */
  212         if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){
  213                 if((fd = open(f[0], OREAD)) >= 0){
  214                         print("venti...");
  215                         memset(buf, 0, sizeof buf);
  216                         pread(fd, buf, 512, 248*1024);
  217                         close(fd);
  218                         if(memcmp(buf, "venti config\n", 13) != 0){
  219                                 print("no venti config found on %s\n", f[0]);
  220                                 return -1;
  221                         }
  222                         if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){
  223                                 print("/boot/venti does not exist\n");
  224                                 return -1;
  225                         }
  226                         switch(nf){
  227                         case 1:
  228                                 f[1] = "tcp!127.1!17034";
  229                         case 2:
  230                                 f[2] = "tcp!127.1!8000";
  231                         }
  232                         configloopback();
  233                         run("/boot/venti", "-c", f[0], "-a", f[1], "-h", f[2], 0);
  234                         /*
  235                          * If the announce address is tcp!*!foo, then set
  236                          * $venti to tcp!127.1!foo instead, which is actually dialable.
  237                          */
  238                         if((p = strstr(f[1], "!*!")) != 0){
  239                                 *p = 0;
  240                                 snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p+3);
  241                                 f[1] = buf;
  242                         }
  243                         setenv("venti", f[1]);
  244                 }else{
  245                         /* set up the network so we can talk to the venti server */
  246                         /* this is such a crock. */
  247                         configip(nf, f, 0);
  248                         setenv("venti", f[0]);
  249                 }
  250         }
  251 
  252         /* start fossil */
  253         print("fossil(%s)...", partition);
  254         run("/boot/fossil", "-f", partition, "-c", "srv -A fboot", "-c", "srv -p fscons", 0);
  255         fd = open("#s/fboot", ORDWR);
  256         if(fd < 0){
  257                 print("open #s/fboot: %r\n");
  258                 return -1;
  259         }
  260         remove("#s/fboot");     /* we'll repost as #s/boot */
  261         return fd;
  262 }
  263 
  264 int
  265 connectlocal(void)
  266 {
  267         int fd;
  268 
  269         if(bind("#c", "/dev", MREPL) < 0)
  270                 fatal("bind #c");
  271         if(bind("#p", "/proc", MREPL) < 0)
  272                 fatal("bind #p");
  273         bind("#S", "/dev", MAFTER);
  274         bind("#k", "/dev", MAFTER);
  275         bind("#æ", "/dev", MAFTER);
  276 
  277         if((fd = connectlocalfossil()) < 0)
  278         if((fd = connectlocalkfs()) < 0)
  279                 return -1;
  280         return fd;
  281 }

Cache object: 8e443328fe5add572a969bd635497dd5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.