source: mainline/uspace/app/init/init.c@ 71f713a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 71f713a was 75701004, checked in by Martin Decky <martin@…>, 7 years ago

use a TAR as the archive format for populating TMPFS root file system

Also remove the logic of populating a TMPFS file system from the TMPFS
file system driver. A more elegant separation of concerns is to populate
the file system from the client. This is now done by the init task (if
required) and should work universally for any file system.

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