source: mainline/uspace/app/init/init.c

Last change on this file was 514108e, checked in by Jiri Svoboda <jiri@…>, 9 months ago

Minimize /app/init, once root is mounted, go to /srv/system

  • Property mode set to 100644
File size: 5.6 KB
RevLine 
[3eddaff]1/*
[04e520e]2 * Copyright (c) 2024 Jiri Svoboda
[df4ed85]3 * Copyright (c) 2005 Martin Decky
[3eddaff]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
[a63966d]30/** @addtogroup init
[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>
[8e9b2534]48#include <io/logctl.h>
[0b63dc2]49#include <vfs/vfs.h>
[75701004]50#include "untar.h"
[860271d4]51#include "init.h"
52
[51da086]53#define BANNER_LEFT "######> "
54#define BANNER_RIGHT " <######"
55
[d9fae235]56#define ROOT_DEVICE "bd/initrd"
57#define ROOT_MOUNT_POINT "/"
58
[6d5e378]59#define srv_start(path, ...) \
60 srv_startl(path, path, ##__VA_ARGS__, NULL)
61
[53d6ac3d]62/** Print banner */
[36b8100a]63static void info_print(void)
64{
[d9fae235]65 printf("%s: HelenOS init\n", NAME);
[36b8100a]66}
67
[51da086]68static void oom_check(errno_t rc, const char *path)
69{
70 if (rc == ENOMEM) {
71 printf("%sOut-of-memory condition detected%s\n", BANNER_LEFT,
72 BANNER_RIGHT);
73 printf("%sBailing out of the boot process after %s%s\n",
74 BANNER_LEFT, path, BANNER_RIGHT);
75 printf("%sMore physical memory is required%s\n", BANNER_LEFT,
76 BANNER_RIGHT);
77 exit(ENOMEM);
78 }
79}
80
[53d6ac3d]81/** Report mount operation success */
[d9fae235]82static bool mount_report(const char *desc, const char *mntpt,
[b7fd2a0]83 const char *fstype, const char *dev, errno_t rc)
[860271d4]84{
[f49cf64]85 switch (rc) {
86 case EOK:
[75701004]87 if ((dev != NULL) && (str_cmp(dev, "") != 0))
[d9fae235]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);
[f49cf64]92 break;
93 case EBUSY:
[d9fae235]94 printf("%s: %s already mounted on %s\n", NAME, desc, mntpt);
[f49cf64]95 return false;
96 case ELIMIT:
[d9fae235]97 printf("%s: %s limit exceeded\n", NAME, desc);
[f49cf64]98 return false;
99 case ENOENT:
[d9fae235]100 printf("%s: %s unknown type (%s)\n", NAME, desc, fstype);
[f49cf64]101 return false;
102 default:
[d9fae235]103 printf("%s: %s not mounted on %s (%s)\n", NAME, desc, mntpt,
104 str_error(rc));
[f49cf64]105 return false;
[860271d4]106 }
[a35b458]107
[860271d4]108 return true;
109}
110
[75701004]111/** Mount root file system
[53d6ac3d]112 *
[75701004]113 * The operation blocks until the root file system
[53d6ac3d]114 * server is ready for mounting.
115 *
[75701004]116 * @param[in] fstype Root file system type.
[53d6ac3d]117 *
118 * @return True on success.
119 * @return False on failure.
120 *
121 */
[d9fae235]122static bool mount_root(const char *fstype)
[a095d20]123{
[75701004]124 const char *root_device = "";
[a35b458]125
[75701004]126 if (str_cmp(fstype, "tmpfs") != 0)
127 root_device = ROOT_DEVICE;
[a35b458]128
[75701004]129 errno_t rc = vfs_mount_path(ROOT_MOUNT_POINT, fstype, root_device, "",
[4979403]130 IPC_FLAG_BLOCKING, 0);
[8e9b2534]131 if (rc == EOK)
132 logctl_set_root();
[75701004]133
134 bool ret = mount_report("Root file system", ROOT_MOUNT_POINT, fstype,
135 root_device, rc);
136
137 rc = vfs_cwd_set(ROOT_MOUNT_POINT);
138 if (rc != EOK) {
139 printf("%s: Unable to set current directory to %s (%s)\n",
140 NAME, ROOT_MOUNT_POINT, str_error(ret));
141 return false;
142 }
143
144 if ((ret) && (str_cmp(fstype, "tmpfs") == 0)) {
145 printf("%s: Extracting root file system archive\n", NAME);
146 ret = bd_untar(ROOT_DEVICE);
147 }
148
149 return ret;
[d9fae235]150}
151
[b7fd2a0]152static errno_t srv_startl(const char *path, ...)
[860271d4]153{
[39330200]154 vfs_stat_t s;
[23a0368]155 if (vfs_stat_path(path, &s) != EOK) {
[6d5e378]156 printf("%s: Unable to stat %s\n", NAME, path);
157 return ENOENT;
158 }
[a35b458]159
[6d5e378]160 printf("%s: Starting %s\n", NAME, path);
[a35b458]161
[6d5e378]162 va_list ap;
163 const char *arg;
164 int cnt = 0;
[a35b458]165
[6d5e378]166 va_start(ap, path);
167 do {
168 arg = va_arg(ap, const char *);
169 cnt++;
170 } while (arg != NULL);
171 va_end(ap);
[a35b458]172
[6d5e378]173 va_start(ap, path);
174 task_id_t id;
[1c635d6]175 task_wait_t wait;
[b7fd2a0]176 errno_t rc = task_spawn(&id, &wait, path, cnt, ap);
[6d5e378]177 va_end(ap);
[a35b458]178
[0485135]179 if (rc != EOK) {
[51da086]180 oom_check(rc, path);
[6d5e378]181 printf("%s: Error spawning %s (%s)\n", NAME, path,
[0485135]182 str_error(rc));
[6d5e378]183 return rc;
[0485135]184 }
[a35b458]185
[95bc57c]186 if (!id) {
[6d5e378]187 printf("%s: Error spawning %s (invalid task id)\n", NAME,
188 path);
189 return EINVAL;
[95bc57c]190 }
[a35b458]191
[6d5e378]192 task_exit_t texit;
193 int retval;
[1c635d6]194 rc = task_wait(&wait, &texit, &retval);
[95bc57c]195 if (rc != EOK) {
[6d5e378]196 printf("%s: Error waiting for %s (%s)\n", NAME, path,
[0485135]197 str_error(rc));
[6d5e378]198 return rc;
[95bc57c]199 }
[a35b458]200
[0485135]201 if (texit != TASK_EXIT_NORMAL) {
202 printf("%s: Server %s failed to start (unexpectedly "
[6d5e378]203 "terminated)\n", NAME, path);
204 return EINVAL;
[0485135]205 }
[a35b458]206
[6d5e378]207 if (retval != 0)
[0485135]208 printf("%s: Server %s failed to start (exit code %d)\n", NAME,
[6d5e378]209 path, retval);
[a35b458]210
[1569a9b]211 return retval == 0 ? EOK : EPARTY;
[95bc57c]212}
213
[5106e98]214int main(int argc, char *argv[])
215{
[860271d4]216 info_print();
[a35b458]217
[36b8100a]218 if (!mount_root(STRING(RDFMT))) {
[d9fae235]219 printf("%s: Exiting\n", NAME);
[6d5e378]220 return 1;
[860271d4]221 }
[a35b458]222
[514108e]223 /* System server takes over once root is mounted */
224 srv_start("/srv/system");
[3eddaff]225 return 0;
226}
[b2951e2]227
228/** @}
229 */
Note: See TracBrowser for help on using the repository browser.