|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/usr/server/boot/boot.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.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 36 * 'init' process. It sends a setup message to other servers in 37 * order to let them know that this task becomes 'init' process. 38 * The bootstrap server is gone after it launches (exec) the 39 * 'init' process. 40 */ 41 42 #include <sys/prex.h> 43 #include <sys/mount.h> 44 #include <sys/stat.h> 45 #include <sys/fcntl.h> 46 #include <sys/syslog.h> 47 48 #include <ipc/fs.h> 49 #include <ipc/exec.h> 50 #include <ipc/proc.h> 51 #include <ipc/ipc.h> 52 53 #include <unistd.h> 54 #include <string.h> 55 #include <stdlib.h> 56 #include <stdio.h> 57 #include <signal.h> 58 #include <errno.h> 59 60 #ifdef DEBUG 61 #define DPRINTF(a) sys_log a 62 #else 63 #define DPRINTF(a) 64 #endif 65 66 static const char *initargs[] = { "1", NULL }; 67 static const char *initenvs[] = { "TERM=vt100", "USER=root", NULL }; 68 69 static char iobuf[BUFSIZ]; 70 71 /* 72 * Base directories at root. 73 */ 74 static char *base_dir[] = { 75 "/bin", /* applications */ 76 "/boot", /* system servers */ 77 "/dev", /* device files */ 78 "/etc", /* shareable read-only data */ 79 "/mnt", /* mount point for file systems */ 80 "/private", /* user's private data */ 81 "/tmp", /* temporary files */ 82 NULL 83 }; 84 85 static void 86 wait_server(const char *name, object_t *pobj) 87 { 88 int i, error = 0; 89 90 /* Give chance to run other servers. */ 91 thread_yield(); 92 93 /* 94 * Wait for server loading. timeout is 1 sec. 95 */ 96 for (i = 0; i < 100; i++) { 97 error = object_lookup((char *)name, pobj); 98 if (error == 0) 99 break; 100 101 /* Wait 10msec */ 102 timer_sleep(10, 0); 103 thread_yield(); 104 } 105 if (error) 106 sys_panic("boot: server not found"); 107 } 108 109 static void 110 send_bootmsg(object_t obj) 111 { 112 struct msg m; 113 int error; 114 115 m.hdr.code = STD_BOOT; 116 error = msg_send(obj, &m, sizeof(m)); 117 if (error) 118 sys_panic("boot: server error"); 119 } 120 121 static void 122 mount_fs(void) 123 { 124 char line[128]; 125 FILE *fp; 126 char *spec, *file, *type, *p; 127 char nodev[] = ""; 128 int i; 129 130 DPRINTF(("boot: mounting file systems\n")); 131 132 /* 133 * Mount root. 134 */ 135 if (mount("", "/", "ramfs", 0, NULL) < 0) 136 sys_panic("boot: mount failed"); 137 138 /* 139 * Create some default directories. 140 */ 141 i = 0; 142 while (base_dir[i] != NULL) { 143 if (mkdir(base_dir[i], 0) == -1) 144 sys_panic("boot: mkdir failed"); 145 i++; 146 } 147 148 /* 149 * Mount file system for /boot. 150 */ 151 if (mount("/dev/ram0", "/boot", "arfs", 0, NULL) < 0) 152 sys_panic("boot: mount failed"); 153 154 /* 155 * Mount file systems described in fstab. 156 */ 157 if ((fp = fopen("/boot/fstab", "r")) == NULL) 158 sys_panic("boot: no fstab"); 159 160 for (;;) { 161 if ((p = fgets(line, sizeof(line), fp)) == NULL) 162 break; 163 spec = strtok(p, " \t\n"); 164 if (spec == NULL || *spec == '#') 165 continue; 166 file = strtok(NULL, " \t\n"); 167 type = strtok(NULL, " \t\n"); 168 if (!strcmp(file, "/") || !strcmp(file, "/boot")) 169 continue; 170 if (!strcmp(spec, "none")) 171 spec = nodev; 172 173 /* We create the mount point automatically */ 174 mkdir(file, 0); 175 mount(spec, file, type, 0, 0); 176 } 177 fclose(fp); 178 } 179 180 static int 181 exec_init(object_t execobj) 182 { 183 struct exec_msg msg; 184 int error, i, argc, envc; 185 size_t bufsz; 186 char *dest; 187 char const *src; 188 189 DPRINTF(("boot: execute init\n")); 190 191 /* Get arg/env buffer size */ 192 bufsz = 0; 193 argc = 0; 194 while (initargs[argc]) { 195 bufsz += (strlen(initargs[argc]) + 1); 196 argc++; 197 } 198 envc = 0; 199 while (initenvs[envc]) { 200 bufsz += (strlen(initenvs[envc]) + 1); 201 envc++; 202 } 203 if (bufsz >= ARG_MAX) 204 sys_panic("boot: args too long"); 205 206 /* 207 * Build exec message. 208 */ 209 dest = msg.buf; 210 for (i = 0; i < argc; i++) { 211 src = initargs[i]; 212 while ((*dest++ = *src++) != 0); 213 } 214 for (i = 0; i < envc; i++) { 215 src = initenvs[i]; 216 while ((*dest++ = *src++) != 0); 217 } 218 msg.hdr.code = EXEC_EXECVE; 219 msg.argc = argc; 220 msg.envc = envc; 221 msg.bufsz = bufsz; 222 strlcpy(msg.cwd, "/", sizeof(msg.cwd)); 223 strlcpy(msg.path, "/boot/init", sizeof(msg.path)); 224 225 do { 226 error = msg_send(execobj, &msg, sizeof(msg)); 227 /* 228 * If exec server can execute new process 229 * properly, it will terminate the caller task 230 * automatically. So, the control never comes 231 * here in that case. 232 */ 233 } while (error == EINTR); 234 return -1; 235 } 236 237 static void 238 copy_file(char *src, char *dest) 239 { 240 int fold, fnew, n; 241 struct stat stbuf; 242 mode_t mode; 243 244 if ((fold = open(src, O_RDONLY)) == -1) 245 return; 246 247 fstat(fold, &stbuf); 248 mode = stbuf.st_mode; 249 250 if ((fnew = creat(dest, mode)) == -1) { 251 close(fold); 252 return; 253 } 254 while ((n = read(fold, iobuf, BUFSIZ)) > 0) { 255 if (write(fnew, iobuf, (size_t)n) != n) { 256 close(fold); 257 close(fnew); 258 return; 259 } 260 } 261 close(fold); 262 close(fnew); 263 } 264 265 int 266 main(int argc, char *argv[]) 267 { 268 object_t execobj, procobj, fsobj; 269 struct bind_msg bm; 270 struct msg m; 271 272 sys_log("Starting bootstrap server\n"); 273 274 thread_setpri(thread_self(), PRI_DEFAULT); 275 276 /* 277 * Wait until all required system servers 278 * become available. 279 */ 280 wait_server("!proc", &procobj); 281 wait_server("!fs", &fsobj); 282 wait_server("!exec", &execobj); 283 284 /* 285 * Send boot message to all servers. 286 * This is required to synchronize the server 287 * initialization without deadlock. 288 */ 289 send_bootmsg(execobj); 290 send_bootmsg(procobj); 291 send_bootmsg(fsobj); 292 293 /* 294 * Request to bind a new capabilities for us. 295 */ 296 bm.hdr.code = EXEC_BINDCAP; 297 strlcpy(bm.path, "/boot/boot", sizeof(bm.path)); 298 msg_send(execobj, &bm, sizeof(bm)); 299 300 /* 301 * Register this process as 'init'. 302 * We will become an init process later. 303 */ 304 m.hdr.code = PS_SETINIT; 305 msg_send(procobj, &m, sizeof(m)); 306 307 /* 308 * Initialize a library for file I/O. 309 */ 310 fslib_init(); 311 312 /* 313 * Mount file systems. 314 */ 315 mount_fs(); 316 317 /* 318 * Copy some files. 319 * Note that almost applications including 'init' 320 * does not have an access right to /boot directory... 321 */ 322 copy_file("/boot/rc", "/etc/rc"); 323 copy_file("/boot/fstab", "/etc/fstab"); 324 325 /* 326 * Exec first application. 327 */ 328 exec_init(execobj); 329 330 sys_panic("boot: failed to exec init"); 331 332 /* NOTREACHED */ 333 return 0; 334 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |