~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to uspace/app/init/init.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005 Martin Decky
 
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
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup init Init
 
30
 * @brief Init process for user space environment configuration.
 
31
 * @{
 
32
 */
 
33
/**
 
34
 * @file
 
35
 */
 
36
 
 
37
#include <stdio.h>
 
38
#include <unistd.h>
 
39
#include <ipc/ipc.h>
 
40
#include <vfs/vfs.h>
 
41
#include <bool.h>
 
42
#include <errno.h>
 
43
#include <fcntl.h>
 
44
#include <sys/stat.h>
 
45
#include <task.h>
 
46
#include <malloc.h>
 
47
#include <macros.h>
 
48
#include <string.h>
 
49
#include <devmap.h>
 
50
#include <config.h>
 
51
#include "init.h"
 
52
 
 
53
static void info_print(void)
 
54
{
 
55
        printf(NAME ": HelenOS init\n");
 
56
}
 
57
 
 
58
static bool mount_root(const char *fstype)
 
59
{
 
60
        char *opts = "";
 
61
        const char *root_dev = "initrd";
 
62
        
 
63
        if (str_cmp(fstype, "tmpfs") == 0)
 
64
                opts = "restore";
 
65
        
 
66
        int rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING);
 
67
        
 
68
        switch (rc) {
 
69
        case EOK:
 
70
                printf(NAME ": Root filesystem mounted, %s at %s\n",
 
71
                    fstype, root_dev);
 
72
                break;
 
73
        case EBUSY:
 
74
                printf(NAME ": Root filesystem already mounted\n");
 
75
                return false;
 
76
        case ELIMIT:
 
77
                printf(NAME ": Unable to mount root filesystem\n");
 
78
                return false;
 
79
        case ENOENT:
 
80
                printf(NAME ": Unknown filesystem type (%s)\n", fstype);
 
81
                return false;
 
82
        default:
 
83
                printf(NAME ": Error mounting root filesystem (%d)\n", rc);
 
84
                return false;
 
85
        }
 
86
        
 
87
        return true;
 
88
}
 
89
 
 
90
static bool mount_devfs(void)
 
91
{
 
92
        char null[MAX_DEVICE_NAME];
 
93
        int null_id = devmap_null_create();
 
94
        
 
95
        if (null_id == -1) {
 
96
                printf(NAME ": Unable to create null device\n");
 
97
                return false;
 
98
        }
 
99
        
 
100
        snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
 
101
        int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING);
 
102
        
 
103
        switch (rc) {
 
104
        case EOK:
 
105
                printf(NAME ": Device filesystem mounted\n");
 
106
                break;
 
107
        case EBUSY:
 
108
                printf(NAME ": Device filesystem already mounted\n");
 
109
                devmap_null_destroy(null_id);
 
110
                return false;
 
111
        case ELIMIT:
 
112
                printf(NAME ": Unable to mount device filesystem\n");
 
113
                devmap_null_destroy(null_id);
 
114
                return false;
 
115
        case ENOENT:
 
116
                printf(NAME ": Unknown filesystem type (devfs)\n");
 
117
                devmap_null_destroy(null_id);
 
118
                return false;
 
119
        default:
 
120
                printf(NAME ": Error mounting device filesystem (%d)\n", rc);
 
121
                devmap_null_destroy(null_id);
 
122
                return false;
 
123
        }
 
124
        
 
125
        return true;
 
126
}
 
127
 
 
128
static void spawn(char *fname)
 
129
{
 
130
        char *argv[2];
 
131
        struct stat s;
 
132
        
 
133
        if (stat(fname, &s) == ENOENT)
 
134
                return;
 
135
        
 
136
        printf(NAME ": Spawning %s\n", fname);
 
137
        
 
138
        argv[0] = fname;
 
139
        argv[1] = NULL;
 
140
        
 
141
        if (!task_spawn(fname, argv))
 
142
                printf(NAME ": Error spawning %s\n", fname);
 
143
}
 
144
 
 
145
static void srv_start(char *fname)
 
146
{
 
147
        char *argv[2];
 
148
        task_id_t id;
 
149
        task_exit_t texit;
 
150
        int rc, retval;
 
151
        struct stat s;
 
152
        
 
153
        if (stat(fname, &s) == ENOENT)
 
154
                return;
 
155
        
 
156
        printf(NAME ": Starting %s\n", fname);
 
157
        
 
158
        argv[0] = fname;
 
159
        argv[1] = NULL;
 
160
        
 
161
        id = task_spawn(fname, argv);
 
162
        if (!id) {
 
163
                printf(NAME ": Error spawning %s\n", fname);
 
164
                return;
 
165
        }
 
166
 
 
167
        rc = task_wait(id, &texit, &retval);
 
168
        if (rc != EOK) {
 
169
                printf(NAME ": Error waiting for %s\n", fname);
 
170
                return;
 
171
        }
 
172
 
 
173
        if (texit != TASK_EXIT_NORMAL || retval != 0) {
 
174
                printf(NAME ": Server %s failed to start (returned %d)\n",
 
175
                        fname, retval);
 
176
        }
 
177
}
 
178
 
 
179
static void getvc(char *dev, char *app)
 
180
{
 
181
        char *argv[4];
 
182
        char vc[MAX_DEVICE_NAME];
 
183
        int rc;
 
184
        
 
185
        snprintf(vc, MAX_DEVICE_NAME, "/dev/%s", dev);
 
186
        
 
187
        printf(NAME ": Spawning getvc on %s\n", vc);
 
188
        
 
189
        dev_handle_t handle;
 
190
        rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
 
191
        
 
192
        if (rc == EOK) {
 
193
                argv[0] = "/app/getvc";
 
194
                argv[1] = vc;
 
195
                argv[2] = app;
 
196
                argv[3] = NULL;
 
197
                
 
198
                if (!task_spawn("/app/getvc", argv))
 
199
                        printf(NAME ": Error spawning getvc on %s\n", vc);
 
200
        } else {
 
201
                printf(NAME ": Error waiting on %s\n", vc);
 
202
        }
 
203
}
 
204
 
 
205
static void mount_data(void)
 
206
{
 
207
        int rc;
 
208
 
 
209
        printf("Trying to mount disk0 on /data... ");
 
210
        fflush(stdout);
 
211
 
 
212
        rc = mount("fat", "/data", "disk0", "wtcache", 0);
 
213
        if (rc == EOK)
 
214
                printf("OK\n");
 
215
        else
 
216
                printf("Failed\n");
 
217
}
 
218
 
 
219
int main(int argc, char *argv[])
 
220
{
 
221
        info_print();
 
222
        
 
223
        if (!mount_root(STRING(RDFMT))) {
 
224
                printf(NAME ": Exiting\n");
 
225
                return -1;
 
226
        }
 
227
        
 
228
        spawn("/srv/devfs");
 
229
        
 
230
        if (!mount_devfs()) {
 
231
                printf(NAME ": Exiting\n");
 
232
                return -2;
 
233
        }
 
234
        
 
235
        spawn("/srv/fb");
 
236
        spawn("/srv/kbd");
 
237
        spawn("/srv/console");
 
238
        spawn("/srv/fhc");
 
239
        spawn("/srv/obio");
 
240
 
 
241
        /*
 
242
         * Start these synchronously so that mount_data() can be
 
243
         * non-blocking.
 
244
         */
 
245
#ifdef CONFIG_START_BD
 
246
        srv_start("/srv/ata_bd");
 
247
        srv_start("/srv/gxe_bd");
 
248
#else
 
249
        (void) srv_start;
 
250
#endif
 
251
 
 
252
#ifdef CONFIG_MOUNT_DATA
 
253
        mount_data();
 
254
#else
 
255
        (void) mount_data;
 
256
#endif
 
257
 
 
258
        getvc("vc0", "/app/bdsh");
 
259
        getvc("vc1", "/app/bdsh");
 
260
        getvc("vc2", "/app/bdsh");
 
261
        getvc("vc3", "/app/bdsh");
 
262
        getvc("vc4", "/app/bdsh");
 
263
        getvc("vc5", "/app/bdsh");
 
264
        getvc("vc6", "/app/klog");
 
265
        
 
266
        return 0;
 
267
}
 
268
 
 
269
/** @}
 
270
 */