source: mainline/uspace/app/init/init.c@ 80743a1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 80743a1 was 80743a1, checked in by Jakub Jermar <jakub@…>, 8 years ago

Rename (un)mount to vfs_(un)mount_path

  • Property mode set to 100644
File size: 9.6 KB
Line 
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 <stdarg.h>
40#include <vfs/vfs.h>
41#include <stdbool.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <task.h>
45#include <malloc.h>
46#include <macros.h>
47#include <str.h>
48#include <loc.h>
49#include <str_error.h>
50#include <config.h>
51#include <io/logctl.h>
52#include "init.h"
53
54#define ROOT_DEVICE "bd/initrd"
55#define ROOT_MOUNT_POINT "/"
56
57#define LOCFS_FS_TYPE "locfs"
58#define LOCFS_MOUNT_POINT "/loc"
59
60#define TMPFS_FS_TYPE "tmpfs"
61#define TMPFS_MOUNT_POINT "/tmp"
62
63#define SRV_CONSOLE "/srv/console"
64#define APP_GETTERM "/app/getterm"
65
66#define SRV_COMPOSITOR "/srv/compositor"
67
68#define HID_INPUT "hid/input"
69#define HID_OUTPUT "hid/output"
70#define HID_COMPOSITOR_SERVER ":0"
71
72#define srv_start(path, ...) \
73 srv_startl(path, path, ##__VA_ARGS__, NULL)
74
75/** Print banner */
76static void info_print(void)
77{
78 printf("%s: HelenOS init\n", NAME);
79}
80
81/** Report mount operation success */
82static bool mount_report(const char *desc, const char *mntpt,
83 const char *fstype, const char *dev, int rc)
84{
85 switch (rc) {
86 case EOK:
87 if (dev != NULL)
88 printf("%s: %s mounted on %s (%s at %s)\n", NAME, desc, mntpt,
89 fstype, dev);
90 else
91 printf("%s: %s mounted on %s (%s)\n", NAME, desc, mntpt, fstype);
92 break;
93 case EBUSY:
94 printf("%s: %s already mounted on %s\n", NAME, desc, mntpt);
95 return false;
96 case ELIMIT:
97 printf("%s: %s limit exceeded\n", NAME, desc);
98 return false;
99 case ENOENT:
100 printf("%s: %s unknown type (%s)\n", NAME, desc, fstype);
101 return false;
102 default:
103 printf("%s: %s not mounted on %s (%s)\n", NAME, desc, mntpt,
104 str_error(rc));
105 return false;
106 }
107
108 return true;
109}
110
111/** Mount root filesystem
112 *
113 * The operation blocks until the root filesystem
114 * server is ready for mounting.
115 *
116 * @param[in] fstype Root filesystem type.
117 *
118 * @return True on success.
119 * @return False on failure.
120 *
121 */
122static bool mount_root(const char *fstype)
123{
124 const char *opts = "";
125
126 if (str_cmp(fstype, "tmpfs") == 0)
127 opts = "restore";
128
129 int rc = vfs_mount_path(ROOT_MOUNT_POINT, fstype, ROOT_DEVICE, opts,
130 IPC_FLAG_BLOCKING, 0);
131 if (rc == EOK)
132 logctl_set_root();
133 return mount_report("Root filesystem", ROOT_MOUNT_POINT, fstype,
134 ROOT_DEVICE, rc);
135}
136
137/** Mount locfs filesystem
138 *
139 * The operation blocks until the locfs filesystem
140 * server is ready for mounting.
141 *
142 * @return True on success.
143 * @return False on failure.
144 *
145 */
146static bool mount_locfs(void)
147{
148 int rc = vfs_mount_path(LOCFS_MOUNT_POINT, LOCFS_FS_TYPE, "", "",
149 IPC_FLAG_BLOCKING, 0);
150 return mount_report("Location service filesystem", LOCFS_MOUNT_POINT,
151 LOCFS_FS_TYPE, NULL, rc);
152}
153
154static int srv_startl(const char *path, ...)
155{
156 struct stat s;
157 if (vfs_stat_path(path, &s) != EOK) {
158 printf("%s: Unable to stat %s\n", NAME, path);
159 return ENOENT;
160 }
161
162 printf("%s: Starting %s\n", NAME, path);
163
164 va_list ap;
165 const char *arg;
166 int cnt = 0;
167
168 va_start(ap, path);
169 do {
170 arg = va_arg(ap, const char *);
171 cnt++;
172 } while (arg != NULL);
173 va_end(ap);
174
175 va_start(ap, path);
176 task_id_t id;
177 task_wait_t wait;
178 int rc = task_spawn(&id, &wait, path, cnt, ap);
179 va_end(ap);
180
181 if (rc != EOK) {
182 printf("%s: Error spawning %s (%s)\n", NAME, path,
183 str_error(rc));
184 return rc;
185 }
186
187 if (!id) {
188 printf("%s: Error spawning %s (invalid task id)\n", NAME,
189 path);
190 return EINVAL;
191 }
192
193 task_exit_t texit;
194 int retval;
195 rc = task_wait(&wait, &texit, &retval);
196 if (rc != EOK) {
197 printf("%s: Error waiting for %s (%s)\n", NAME, path,
198 str_error(rc));
199 return rc;
200 }
201
202 if (texit != TASK_EXIT_NORMAL) {
203 printf("%s: Server %s failed to start (unexpectedly "
204 "terminated)\n", NAME, path);
205 return EINVAL;
206 }
207
208 if (retval != 0)
209 printf("%s: Server %s failed to start (exit code %d)\n", NAME,
210 path, retval);
211
212 return retval;
213}
214
215static int console(const char *isvc, const char *osvc)
216{
217 /* Wait for the input service to be ready */
218 service_id_t service_id;
219 int rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);
220 if (rc != EOK) {
221 printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
222 str_error(rc));
223 return rc;
224 }
225
226 /* Wait for the output service to be ready */
227 rc = loc_service_get_id(osvc, &service_id, IPC_FLAG_BLOCKING);
228 if (rc != EOK) {
229 printf("%s: Error waiting on %s (%s)\n", NAME, osvc,
230 str_error(rc));
231 return rc;
232 }
233
234 return srv_start(SRV_CONSOLE, isvc, osvc);
235}
236
237static int compositor(const char *isvc, const char *name)
238{
239 /* Wait for the input service to be ready */
240 service_id_t service_id;
241 int rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);
242 if (rc != EOK) {
243 printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
244 str_error(rc));
245 return rc;
246 }
247
248 return srv_start(SRV_COMPOSITOR, isvc, name);
249}
250
251static int gui_start(const char *app, const char *srv_name)
252{
253 char winreg[50];
254 snprintf(winreg, sizeof(winreg), "%s%s%s", "comp", srv_name, "/winreg");
255
256 printf("%s: Spawning %s %s\n", NAME, app, winreg);
257
258 task_id_t id;
259 task_wait_t wait;
260 int rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
261 if (rc != EOK) {
262 printf("%s: Error spawning %s %s (%s)\n", NAME, app,
263 winreg, str_error(rc));
264 return -1;
265 }
266
267 task_exit_t texit;
268 int retval;
269 rc = task_wait(&wait, &texit, &retval);
270 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
271 printf("%s: Error retrieving retval from %s (%s)\n", NAME,
272 app, str_error(rc));
273 return -1;
274 }
275
276 return retval;
277}
278
279static void getterm(const char *svc, const char *app, bool msg)
280{
281 if (msg) {
282 printf("%s: Spawning %s %s %s --msg --wait -- %s\n", NAME,
283 APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
284
285 int rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
286 LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL);
287 if (rc != EOK)
288 printf("%s: Error spawning %s %s %s --msg --wait -- %s\n",
289 NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
290 } else {
291 printf("%s: Spawning %s %s %s --wait -- %s\n", NAME,
292 APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
293
294 int rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
295 LOCFS_MOUNT_POINT, "--wait", "--", app, NULL);
296 if (rc != EOK)
297 printf("%s: Error spawning %s %s %s --wait -- %s\n",
298 NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
299 }
300}
301
302static bool mount_tmpfs(void)
303{
304 int rc = vfs_mount_path(TMPFS_MOUNT_POINT, TMPFS_FS_TYPE, "", "", 0, 0);
305 return mount_report("Temporary filesystem", TMPFS_MOUNT_POINT,
306 TMPFS_FS_TYPE, NULL, rc);
307}
308
309int main(int argc, char *argv[])
310{
311 int rc;
312
313 info_print();
314
315 if (!mount_root(STRING(RDFMT))) {
316 printf("%s: Exiting\n", NAME);
317 return 1;
318 }
319
320 /* Make sure tmpfs is running. */
321 if (str_cmp(STRING(RDFMT), "tmpfs") != 0)
322 srv_start("/srv/tmpfs");
323
324 srv_start("/srv/klog");
325 srv_start("/srv/locfs");
326 srv_start("/srv/taskmon");
327
328 if (!mount_locfs()) {
329 printf("%s: Exiting\n", NAME);
330 return 2;
331 }
332
333 mount_tmpfs();
334
335 srv_start("/srv/devman");
336 srv_start("/srv/apic");
337 srv_start("/srv/i8259");
338 srv_start("/srv/icp-ic");
339 srv_start("/srv/obio");
340 srv_start("/srv/cuda_adb");
341 srv_start("/srv/s3c24xx_uart");
342 srv_start("/srv/s3c24xx_ts");
343
344 srv_start("/srv/vbd");
345 srv_start("/srv/volsrv");
346
347 srv_start("/srv/loopip");
348 srv_start("/srv/ethip");
349 srv_start("/srv/inetsrv");
350 srv_start("/srv/tcp");
351 srv_start("/srv/udp");
352 srv_start("/srv/dnsrsrv");
353 srv_start("/srv/dhcp");
354 srv_start("/srv/nconfsrv");
355
356 srv_start("/srv/clipboard");
357 srv_start("/srv/remcons");
358
359 srv_start("/srv/input", HID_INPUT);
360 srv_start("/srv/output", HID_OUTPUT);
361 srv_start("/srv/hound");
362
363 if (!config_key_exists("console")) {
364 rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
365 if (rc == EOK) {
366 gui_start("/app/barber", HID_COMPOSITOR_SERVER);
367 gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
368 gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
369 }
370 }
371
372 rc = console(HID_INPUT, HID_OUTPUT);
373 if (rc == EOK) {
374 getterm("term/vc0", "/app/bdsh", true);
375 getterm("term/vc1", "/app/bdsh", false);
376 getterm("term/vc2", "/app/bdsh", false);
377 getterm("term/vc3", "/app/bdsh", false);
378 getterm("term/vc4", "/app/bdsh", false);
379 getterm("term/vc5", "/app/bdsh", false);
380 }
381
382 return 0;
383}
384
385/** @}
386 */
Note: See TracBrowser for help on using the repository browser.