[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / prex-old / usr / server / boot

Annotation of prex-old/usr/server/boot/main.c, Revision 1.1.1.1

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * main.c - bootstrap server
                     32:  */
                     33:
                     34: /*
                     35:  * A bootstrap server works to setup the POSIX environment for 'init'
                     36:  * process. It sends a setup message to other servers in order to let
                     37:  * them know that this task becomes 'init' process.
                     38:  * The bootstrap server is gone after it launches (exec) the 'init'
                     39:  * process.
                     40:  */
                     41:
                     42: #include <prex/prex.h>
                     43: #include <sys/mount.h>
                     44: #include <server/fs.h>
                     45: #include <server/object.h>
                     46: #include <server/exec.h>
                     47: #include <server/proc.h>
                     48: #include <server/stdmsg.h>
                     49:
                     50: #include <unistd.h>
                     51: #include <string.h>
                     52: #include <stdlib.h>
                     53: #include <stdio.h>
                     54: #include <signal.h>
                     55: #include <errno.h>
                     56: #include <fstab.h>
                     57:
                     58: extern const struct fstab fstab[];
                     59: extern const int fstab_size;
                     60:
                     61: #define PRIO_BOOT      131             /* priority of boot server */
                     62:
                     63: /* forward declarations */
                     64: static void wait_server(const char *);
                     65: static void process_init(void);
                     66: static int run_init(char *);
                     67: static void mount_fs(void);
                     68:
                     69: static object_t proc_obj;
                     70:
                     71: static char *init_argv[] = { "arg", NULL };
                     72: static char *init_envp[] = { "HOME=/", NULL };
                     73:
                     74: static char *base_dir[] = {
                     75:        "/bin",         /* essential user commands */
                     76:        "/boot",        /* static files for boot */
                     77:        "/dev",         /* device files */
                     78:        "/etc",         /* system conifguration */
                     79:        "/mnt",         /* mount point for file systems */
                     80:        "/mnt/floppy",  /* mount point for floppy */
                     81:        "/mnt/cdrom",   /* mount point for cdrom */
                     82:        "/tmp",         /* temporary files */
                     83:        "/usr",         /* shareable read-only data */
                     84:        "/var",         /* log files, spool data */
                     85:        NULL
                     86: };
                     87:
                     88: /*
                     89:  * Main routine for boot strap
                     90:  */
                     91: int
                     92: main(int argc, char *argv[])
                     93: {
                     94:
                     95:        sys_log("Starting Bootstrap Server\n");
                     96:
                     97:        /*
                     98:         * Boost current priority.
                     99:         */
                    100:        thread_setprio(thread_self(), PRIO_BOOT);
                    101:
                    102:        /*
                    103:         * Wait until required system servers become available.
                    104:         */
                    105:        wait_server(OBJNAME_PROC);
                    106:        wait_server(OBJNAME_FS);
                    107:        wait_server(OBJNAME_EXEC);
                    108:
                    109:        /*
                    110:         * Register this task to other servers.
                    111:         */
                    112:        process_init();
                    113:        fslib_init();
                    114:
                    115:        /*
                    116:         * Mount file systems
                    117:         */
                    118:        mount_fs();
                    119:
                    120:        /*
                    121:         * Run init process
                    122:         */
                    123:        run_init("/boot/init");
                    124:
                    125:        sys_log("boot: failed to run init\n");
                    126:        return 0;
                    127: }
                    128:
                    129: /*
                    130:  * Wait until specified server starts.
                    131:  */
                    132: static void
                    133: wait_server(const char *name)
                    134: {
                    135:        int i, err = 0;
                    136:        object_t obj = 0;
                    137:
                    138:        thread_yield();
                    139:
                    140:        /*
                    141:         * Wait for server loading. timeout is 2 sec.
                    142:         */
                    143:        for (i = 0; i < 200; i++) {
                    144:                err = object_lookup((char *)name, &obj);
                    145:                if (err == 0)
                    146:                        break;
                    147:
                    148:                /* Wait 10msec */
                    149:                timer_sleep(10, 0);
                    150:                thread_yield();
                    151:        }
                    152:        if (err)
                    153:                sys_panic("boot: server not found");
                    154: }
                    155:
                    156: static void
                    157: process_init(void)
                    158: {
                    159:        struct msg m;
                    160:
                    161:        /*
                    162:         * This task will become an init process.
                    163:         */
                    164:        object_lookup(OBJNAME_PROC, &proc_obj);
                    165:        m.hdr.code = PS_SETINIT;
                    166:        msg_send(proc_obj, &m, sizeof(m));
                    167: }
                    168:
                    169: /*
                    170:  * Run init process
                    171:  */
                    172: static int
                    173: run_init(char *path)
                    174: {
                    175:        struct exec_msg *msg;
                    176:        int err, i, argc, envc;
                    177:        size_t bufsz;
                    178:        char *dest, *src;
                    179:        object_t obj;
                    180:
                    181:        sys_log("boot: Run init process\n");
                    182:
                    183:        /*
                    184:         * Allocate a message buffer with arg/env data.
                    185:         */
                    186:        bufsz = 0;
                    187:        argc = 0;
                    188:        while (init_argv[argc]) {
                    189:                bufsz += (strlen(init_argv[argc]) + 1);
                    190:                argc++;
                    191:        }
                    192:        envc = 0;
                    193:        while (init_envp[envc]) {
                    194:                bufsz += (strlen(init_envp[envc]) + 1);
                    195:                envc++;
                    196:        }
                    197:        msg = (struct exec_msg *)malloc(sizeof(struct exec_msg) + bufsz);
                    198:        if (msg == NULL)
                    199:                return -1;
                    200:
                    201:        /*
                    202:         * Build exec message.
                    203:         */
                    204:        dest = (char *)&msg->buf;
                    205:        for (i = 0; i < argc; i++) {
                    206:                src = init_argv[i];
                    207:                while ((*dest++ = *src++) != 0);
                    208:        }
                    209:        for (i = 0; i < envc; i++) {
                    210:                src = init_envp[i];
                    211:                while ((*dest++ = *src++) != 0);
                    212:        }
                    213:        msg->argc = argc;
                    214:        msg->envc = envc;
                    215:        msg->bufsz = bufsz;
                    216:        strcpy((char *)&msg->path, path);
                    217:
                    218:        /*
                    219:         * Request exec() to exec server
                    220:         */
                    221:        object_lookup(OBJNAME_EXEC, &obj);
                    222:        do {
                    223:                msg->hdr.code = EX_EXEC;
                    224:                err = msg_send(obj, msg,
                    225:                               sizeof(struct exec_msg) + bufsz);
                    226:                /*
                    227:                 * If exec server can execute new process properly, it
                    228:                 * will terminate the caller task automatically. So,
                    229:                 * the control never comes here in that case.
                    230:                 */
                    231:        } while (err == EINTR);
                    232:        return -1;
                    233: }
                    234:
                    235: static void
                    236: mount_fs(void)
                    237: {
                    238:        int i;
                    239:
                    240:        sys_log("boot: Mounting file systems\n");
                    241:
                    242:        /*
                    243:         * Mount RAMFS as root file system.
                    244:         */
                    245:        if (mount("", "/", "ramfs", 0, NULL) < 0)
                    246:                sys_panic("boot: mount failed");
                    247:
                    248:        /*
                    249:         * Create some default directories on RAMFS.
                    250:         */
                    251:        for (i = 0;; i++) {
                    252:                if (base_dir[i] == NULL)
                    253:                        break;
                    254:                mkdir(base_dir[i], 0);
                    255:        }
                    256:
                    257:        /*
                    258:         * Mount other file systems.
                    259:         */
                    260:        for (i = 0; i < fstab_size; i++) {
                    261:                mount(fstab[i].fs_spec, fstab[i].fs_file,
                    262:                      fstab[i].fs_vfstype, 0, (void *)fstab[i].fs_mntops);
                    263:        }
                    264: }

CVSweb