1/**
2 * \file
3 * \brief Spawn daemon for Barrelfish.
4 * Offers a service on each core to spawn programs from
5 * the file system.
6 */
7
8/*
9 * Copyright (c) 2010-2011, ETH Zurich.
10 * All rights reserved.
11 *
12 * This file is distributed under the terms in the attached LICENSE file.
13 * If you do not find this file, copies can be found by writing to:
14 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
15 */
16
17#include <stdio.h>
18#include <string.h>
19
20#include <barrelfish/barrelfish.h>
21#include <barrelfish/dispatch.h>
22#include <barrelfish_kpi/cpu.h> // for cpu_type_to_archstr()
23#include <barrelfish/cpu_arch.h> // for CURRENT_CPU_TYPE
24
25#include <vfs/vfs.h>
26
27#include <if/monitor_defs.h>
28
29#include "internal.h"
30
31coreid_t my_core_id;
32bool is_bsp_core;
33const char *gbootmodules;
34
35/* set an initial default environment for our boot-time children */
36static void init_environ(void)
37{
38    int r;
39
40    /* PATH=/arch/sbin */
41    char pathstr[64];
42    snprintf(pathstr, sizeof(pathstr), "/" BF_BINARY_PREFIX "%s/sbin",
43             cpu_type_to_archstr(CURRENT_CPU_TYPE));
44    pathstr[sizeof(pathstr) - 1] = '\0';
45    r = setenv("PATH", pathstr, 0);
46    if (r != 0) {
47        USER_PANIC("failed to set PATH");
48    }
49
50    /* HOME=/ */
51    r = setenv("HOME", "/", 0);
52    if (r != 0) {
53        USER_PANIC("failed to set HOME");
54    }
55}
56
57/* open bootmodules file and read it in */
58static void get_bootmodules(void)
59{
60    errval_t err;
61
62    // open bootmodules file and read it in
63    vfs_handle_t vh;
64    err = vfs_open("/bootmodules", &vh);
65    if (err_is_fail(err)) {
66        USER_PANIC_ERR(err, "unable to open /bootmodules");
67    }
68
69    struct vfs_fileinfo info;
70    err = vfs_stat(vh, &info);
71    if (err_is_fail(err)) {
72        USER_PANIC_ERR(err, "unable to stat /bootmodules");
73    }
74
75    char *bootmodules = malloc(info.size + 1);
76    if (bootmodules == NULL) {
77        USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL,
78                       "failed to allocate memory for bootmodules");
79    }
80    size_t bootmodules_len;
81    err = vfs_read(vh, bootmodules, info.size, &bootmodules_len);
82    if (err_is_fail(err)) {
83        USER_PANIC_ERR(err, "unable to read /bootmodules");
84    } else if (bootmodules_len == 0) {
85        USER_PANIC_ERR(err, "/bootmodules is empty");
86    } else if (bootmodules_len != info.size) {
87        USER_PANIC_ERR(err, "unexpected short read of /bootmodules");
88    }
89
90    err = vfs_close(vh);
91    if (err_is_fail(err)) {
92        DEBUG_ERR(err, "could not close bottmodules file");
93    }
94
95    // terminate as a string
96    bootmodules[bootmodules_len] = '\0';
97    gbootmodules = bootmodules;
98
99}
100
101int main(int argc, const char *argv[])
102{
103    errval_t err;
104
105    my_core_id = disp_get_core_id();
106
107    printf("spawnd.%u up.\n", my_core_id);
108
109    vfs_init();
110
111    // read in the bootmodules file so that we know what to start
112    get_bootmodules();
113
114    // construct sane inital environment
115    init_environ();
116
117    err = start_service();
118    if (err_is_fail(err)) {
119            USER_PANIC_ERR(err, "failed to start spawnd service loop");
120    }
121
122    messages_handler_loop();
123}
124