The Pedigree Project  0.1
modules/system/init/main.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "modules/Module.h"
21 #include "modules/subsys/posix/FileDescriptor.h"
22 #include "modules/subsys/posix/PosixProcess.h"
23 #include "modules/subsys/posix/PosixSubsystem.h"
24 #include "modules/system/vfs/VFS.h"
25 #include "pedigree/kernel/Log.h"
26 #include "pedigree/kernel/Subsystem.h"
27 #include "pedigree/kernel/compiler.h"
28 #include "pedigree/kernel/core/BootIO.h"
29 #include "pedigree/kernel/process/Process.h"
30 #include "pedigree/kernel/process/Thread.h"
31 #include "pedigree/kernel/processor/Processor.h"
32 #include "pedigree/kernel/processor/ProcessorInformation.h"
33 #include "pedigree/kernel/utilities/StaticString.h"
34 #include "pedigree/kernel/utilities/String.h"
35 #include "pedigree/kernel/utilities/Vector.h"
36 #include "pedigree/kernel/utilities/new"
37 
38 class File;
39 
40 static Mutex g_Started(false);
41 
42 static void error(const char *s)
43 {
44  extern BootIO bootIO;
45  static HugeStaticString str;
46  str += s;
47  str += "\n";
48  bootIO.write(str, BootIO::Red, BootIO::Black);
49  str.clear();
50 }
51 
52 static int init_stage2(void *param)
53 {
54 #if defined(HOSTED) && defined(HAS_ADDRESS_SANITIZER)
55  extern void system_reset();
56  NOTICE("Note: ASAN build, so triggering a restart now.");
57  system_reset();
58  return;
59 #endif
60 
61  bool tryingLinux = false;
62 
63  File *file = 0;
64 
65  String init_path("root»/applications/init");
66  NOTICE("Searching for init program at " << init_path);
67  file = VFS::instance().find(init_path);
68  if (!file)
69  {
70  WARNING(
71  "Did not find " << init_path
72  << ", trying for a Linux userspace...");
73  init_path = "root»/sbin/init";
74  tryingLinux = true;
75 
76  NOTICE("Searching for Linux init at " << init_path);
77  file = VFS::instance().find(init_path);
78  if (!file)
79  {
80  error("failed to find init program (tried root»/applications/init and root»/sbin/init)");
81  }
82  }
83 
84  NOTICE("Found an init program at " << init_path);
85 
86  Vector<String> argv, env;
87  argv.pushBack(init_path);
88 
89  if (tryingLinux)
90  {
91  // Jump to runlevel 5
92  argv.pushBack(String("5"));
93  }
94 
95  Process *pProcess =
96  Processor::information().getCurrentThread()->getParent();
97  if (!pProcess->getSubsystem()->invoke(file, init_path, argv, env))
98  {
99  error("failed to load init program");
100  }
101 
102  Process::setInit(pProcess);
103 
104  g_Started.release();
105 
106  return 0;
107 }
108 
109 static bool init()
110 {
111 #ifdef THREADS
112  g_Started.acquire();
113 
114  // Create a new process for the init process.
115  PosixProcess *pProcess = new PosixProcess(
116  Processor::information().getCurrentThread()->getParent());
117 
118  pProcess->setUserId(0);
119  pProcess->setGroupId(0);
120  pProcess->setEffectiveUserId(0);
121  pProcess->setEffectiveGroupId(0);
122  pProcess->setSavedUserId(0);
123  pProcess->setSavedGroupId(0);
124 
125  pProcess->description() = "init";
126  pProcess->setCwd(VFS::instance().find(String("root»/")));
127  pProcess->setCtty(0);
128 
129  PosixSubsystem *pSubsystem = new PosixSubsystem;
130  pProcess->setSubsystem(pSubsystem);
131 
132  // add an empty stdout, stdin
133  File *pNull = VFS::instance().find(String("dev»/null"));
134  if (!pNull)
135  {
136  error("dev»/null does not exist");
137  }
138 
139  FileDescriptor *stdinDescriptor = new FileDescriptor(pNull, 0, 0, 0, 0);
140  FileDescriptor *stdoutDescriptor = new FileDescriptor(pNull, 0, 1, 0, 0);
141 
142  pSubsystem->addFileDescriptor(0, stdinDescriptor);
143  pSubsystem->addFileDescriptor(1, stdoutDescriptor);
144 
145  Thread *pThread = new Thread(pProcess, init_stage2, 0);
146  pThread->detach();
147 
148  // wait for the other process to start before we move on with startup
149  g_Started.acquire();
150 #endif
151 
152  return true;
153 }
154 
155 static void destroy()
156 {
157 }
158 
159 #if defined(X86_COMMON)
160 #define __MOD_DEPS "vfs", "posix", "linker", "users"
161 #define __MOD_DEPS_OPT "gfx-deps", "mountroot", "confignics"
162 #else
163 #define __MOD_DEPS "vfs", "posix", "linker", "users"
164 #define __MOD_DEPS_OPT "mountroot", "confignics"
165 #endif
166 MODULE_INFO("init", &init, &destroy, __MOD_DEPS);
167 #ifdef __MOD_DEPS_OPT
168 MODULE_OPTIONAL_DEPENDS(__MOD_DEPS_OPT);
169 #endif
File * find(const String &path, File *pStartNode=0)
Definition: VFS.cc:243
void pushBack(const T &value)
Definition: Vector.h:270
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
Definition: Semaphore.h:62
A vector / dynamic array.
EXPORTED_PUBLIC void write(T &str, Colour foreColour, Colour backColour)
Definition: Mutex.h:58
Definition: String.h:49
static ProcessorInformation & information()
Definition: Processor.cc:45
void addFileDescriptor(size_t fd, FileDescriptor *pFd)
static VFS & instance()
Definition: VFS.cc:56
void setCtty(File *f)
Definition: Process.h:172
#define WARNING(text)
Definition: Log.h:78
virtual bool invoke(const char *name, Vector< String > &argv, Vector< String > &env)=0
void release(size_t n=1)
Definition: Semaphore.cc:239
#define NOTICE(text)
Definition: Log.h:74
static void setInit(Process *pProcess)
Definition: Process.cc:399
void setCwd(File *f)
Definition: Process.h:161
Definition: Thread.h:54
LargeStaticString & description()
Definition: Process.h:114
bool detach()
Definition: Thread.cc:885
Definition: BootIO.h:36
Definition: File.h:66