The Pedigree Project  0.1
modules/system/mountroot/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/system/lodisk/LoDisk.h"
23 #include "modules/system/vfs/Filesystem.h"
24 #include "modules/system/vfs/VFS.h"
25 #include "pedigree/kernel/Log.h"
26 #include "pedigree/kernel/core/BootIO.h"
27 #include "pedigree/kernel/machine/Device.h"
28 #include "pedigree/kernel/machine/Disk.h"
29 #include "pedigree/kernel/utilities/Iterator.h"
30 #include "pedigree/kernel/utilities/List.h"
31 #include "pedigree/kernel/utilities/StaticString.h"
32 #include "pedigree/kernel/utilities/String.h"
33 #include "pedigree/kernel/utilities/Tree.h"
34 #include "pedigree/kernel/utilities/utility.h"
35 
36 class File;
37 
38 static bool bRootMounted = false;
39 
40 static void error(const char *s)
41 {
42  extern BootIO bootIO;
43  static HugeStaticString str;
44  str += s;
45  str += "\n";
46  bootIO.write(str, BootIO::Red, BootIO::Black);
47  str.clear();
48 }
49 
50 static Device *probeDisk(Device *diskDevice)
51 {
52  if (diskDevice->getType() != Device::Disk)
53  {
54  return diskDevice;
55  }
56 
57  Disk *pDisk = static_cast<Disk *>(diskDevice);
58  String alias; // Null - gets assigned by the filesystem.
59  if (VFS::instance().mount(pDisk, alias))
60  {
61  // For mount message
62  bool didMountAsRoot = false;
63 
64  // Search for the root specifier, if we haven't already mounted root
65  if (!bRootMounted)
66  {
68  s += alias;
69  s += "»/.pedigree-root";
70 
71  File *f =
72  VFS::instance().find(String(static_cast<const char *>(s)));
73  if (f && !bRootMounted)
74  {
75  NOTICE("Mounted " << alias << " successfully as root.");
76  VFS::instance().addAlias(alias, String("root"));
77  bRootMounted = didMountAsRoot = true;
78  }
79  }
80 
81  if (!didMountAsRoot)
82  {
83  NOTICE("Mounted " << alias << ".");
84  }
85  }
86 
87  return diskDevice;
88 }
89 
90 static bool init()
91 {
92  // Mount scratch filesystem (ie, pure ram filesystem, for POSIX /tmp etc)
93  RamFs *pRamFs = new RamFs;
94  pRamFs->initialise(0);
95  VFS::instance().addAlias(pRamFs, String("scratch"));
96 
97  // Mount runtime filesystem.
98  // The runtime filesystem assigns a Process ownership to each file, only
99  // that process can modify/remove it. If the Process terminates without
100  // removing the file, the file is not removed.
101  RamFs *pRuntimeFs = new RamFs;
102  pRuntimeFs->initialise(0);
103  pRuntimeFs->setProcessOwnership(true);
104  VFS::instance().addAlias(pRuntimeFs, String("runtime"));
105 
106  // Mount all available filesystems.
107  Device::foreach (probeDisk);
108 
109  if (VFS::instance().find(String("raw»/")) == 0)
110  {
111  error("raw» does not exist - cannot continue startup.");
112  return false;
113  }
114 
115  // Are we running a live CD?
119  if (VFS::instance().find(String("root»/livedisk.img")))
120  {
121  NOTICE("trying to find live disk");
122  FileDisk *pRamDisk =
123  new FileDisk(String("root»/livedisk.img"), FileDisk::RamOnly);
124  if (pRamDisk && pRamDisk->initialise())
125  {
126  NOTICE("have a live disk");
127  Device::addToRoot(pRamDisk);
128 
129  // Mount it in the VFS
130  VFS::instance().removeAlias(String("root"));
131  bRootMounted = false;
132  NOTICE("probing ram disk for partitions");
133  Device::foreach (probeDisk, pRamDisk);
134  }
135  else
136  delete pRamDisk;
137  }
138 
139  // Is there a root disk mounted?
140  if (VFS::instance().find(String("root»/.pedigree-root")) == 0)
141  {
142  error("No root disk on this system (no root»/.pedigree-root found).");
143  return false;
144  }
145 
146  // All done, nothing more to do here.
147  return true;
148 }
149 
150 static void destroy()
151 {
152  NOTICE("Unmounting all filesystems...");
153 
155  List<Filesystem *> deletionQueue;
156 
157  for (auto it = mounts.begin(); it != mounts.end(); ++it)
158  {
159  deletionQueue.pushBack(it.key());
160  }
161 
162  while (deletionQueue.count())
163  {
164  Filesystem *pFs = deletionQueue.popFront();
165  NOTICE(
166  "Unmounting " << pFs->getVolumeLabel() << " [" << Hex << pFs
167  << "]...");
169  NOTICE("unmount done");
170  }
171 
172  NOTICE("Unmounting all filesystems has completed.");
173 }
174 
175 MODULE_INFO("mountroot", &init, &destroy, "vfs", "partition");
176 
177 // We expect the filesystems metamodule to fail, but by the time it does and
178 // we are allowed to continue, all the filesystems are loaded.
179 MODULE_OPTIONAL_DEPENDS("filesystems");
void removeAlias(const String &alias)
Definition: VFS.cc:179
File * find(const String &path, File *pStartNode=0)
Definition: VFS.cc:243
Iterator end()
Definition: Tree.h:348
void pushBack(const T &value)
Definition: List.h:232
virtual bool initialise(Disk *pDisk)
Definition: RamFs.cc:139
An in-RAM filesystem.
EXPORTED_PUBLIC void write(T &str, Colour foreColour, Colour backColour)
Tree< Filesystem *, List< String * > * > & getMounts()
Definition: VFS.h:98
void addAlias(Filesystem *pFs, const String &alias)
Definition: VFS.cc:123
A disk device - a block device in UNIX terms.
Definition: Device.h:54
T popFront()
Definition: List.h:319
static void addToRoot(Device *device)
Definition: Device.cc:102
void removeAllAliases(Filesystem *pFs, bool canDelete=true)
Definition: VFS.cc:185
Definition: String.h:49
static VFS & instance()
Definition: VFS.cc:56
Definition: Disk.h:32
Definition: Device.h:43
Definition: List.h:64
Iterator begin()
Definition: Tree.h:326
#define NOTICE(text)
Definition: Log.h:74
Definition: Log.h:136
A key/value dictionary.
Definition: Tree.h:33
static void foreach(Callback callback, Device *root=0)
Definition: Device.cc:94
Definition: RamFs.h:86
virtual Type getType()
Definition: Device.h:163
virtual String getVolumeLabel() const =0
bool mount(Disk *pDisk, String &alias)
Definition: VFS.cc:88
Definition: BootIO.h:36
Definition: File.h:66
size_t count() const
Definition: List.h:227