VFS: Populate the initial filesystem based on the initial ramdisk
This commit is contained in:
parent
ac304073b4
commit
c6aa2fe4ad
@ -1,6 +1,7 @@
|
||||
#include "InitRD.h"
|
||||
#include "arch/MMU.h"
|
||||
#include "boot/bootboot.h"
|
||||
#include "fs/VFS.h"
|
||||
|
||||
TarStream g_initrd;
|
||||
extern const BOOTBOOT bootboot;
|
||||
@ -11,3 +12,29 @@ void InitRD::initialize()
|
||||
|
||||
g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size);
|
||||
}
|
||||
|
||||
static Result<void> vfs_create_dir_if_not_exists(const char* path)
|
||||
{
|
||||
auto rc = VFS::create_directory(path);
|
||||
if (rc.has_error())
|
||||
{
|
||||
if (rc.error() == EEXIST) return {};
|
||||
return rc.release_error();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> InitRD::populate_vfs()
|
||||
{
|
||||
TarStream::Entry entry;
|
||||
while (TRY(g_initrd.read_next_entry(entry)))
|
||||
{
|
||||
if (entry.type == TarStream::EntryType::RegularFile)
|
||||
{
|
||||
auto file = TRY(VFS::create_file(entry.name));
|
||||
file->write(entry.data(), 0, entry.size);
|
||||
}
|
||||
else if (entry.type == TarStream::EntryType::Directory) { TRY(vfs_create_dir_if_not_exists(entry.name)); }
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -6,4 +6,5 @@ extern TarStream g_initrd;
|
||||
namespace InitRD
|
||||
{
|
||||
void initialize();
|
||||
Result<void> populate_vfs();
|
||||
}
|
||||
|
@ -15,18 +15,12 @@ namespace VFS
|
||||
{
|
||||
auto parser = TRY(PathParser::create(path));
|
||||
|
||||
kdbgln("vfs: trying to resolve path %s", path);
|
||||
|
||||
SharedPtr<Inode> current_inode = root_fs->root_inode();
|
||||
|
||||
// FIXME: Properly handle relative paths.
|
||||
|
||||
const char* section;
|
||||
while (parser.next().try_set_value(section))
|
||||
{
|
||||
kdbgln("vfs: searching for entry '%s' in inode %zu", section, current_inode->inode_number());
|
||||
current_inode = TRY(current_inode->find(section));
|
||||
}
|
||||
while (parser.next().try_set_value(section)) { current_inode = TRY(current_inode->find(section)); }
|
||||
|
||||
return current_inode;
|
||||
}
|
||||
@ -40,8 +34,22 @@ namespace VFS
|
||||
|
||||
auto child_name = TRY(parser.basename());
|
||||
|
||||
kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
||||
// kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
||||
|
||||
return parent_inode->create_subdirectory(child_name.chars());
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_file(const char* path)
|
||||
{
|
||||
auto parser = TRY(PathParser::create(path));
|
||||
auto parent_path = TRY(parser.dirname());
|
||||
|
||||
auto parent_inode = TRY(resolve_path(parent_path.chars()));
|
||||
|
||||
auto child_name = TRY(parser.basename());
|
||||
|
||||
// kdbgln("vfs: creating file '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
||||
|
||||
return parent_inode->create_file(child_name.chars());
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ namespace VFS
|
||||
Result<SharedPtr<Inode>> resolve_path(const char* path);
|
||||
|
||||
Result<SharedPtr<Inode>> create_directory(const char* path);
|
||||
Result<SharedPtr<Inode>> create_file(const char* path);
|
||||
|
||||
Inode& root_inode();
|
||||
}
|
||||
|
@ -51,37 +51,7 @@ static Result<void> try_init_vfs()
|
||||
{
|
||||
VFS::root_fs = TRY(TmpFS::FileSystem::create());
|
||||
|
||||
VFS::Inode& root_inode = VFS::root_inode();
|
||||
|
||||
kinfoln("root inode number: %zu", root_inode.inode_number());
|
||||
|
||||
kinfoln("root inode's '.' entry inode number: %zu", TRY(root_inode.find("."))->inode_number());
|
||||
kinfoln("root inode's '..' entry inode number: %zu", TRY(root_inode.find(".."))->inode_number());
|
||||
|
||||
TRY(VFS::create_directory("/etc/"));
|
||||
|
||||
kinfoln("root inode's 'etc' entry inode number: %zu", TRY(root_inode.find("etc"))->inode_number());
|
||||
|
||||
auto& etc = *TRY(root_inode.find("etc"));
|
||||
|
||||
kinfoln("etc inode's '.' entry inode number: %zu", TRY(etc.find("."))->inode_number());
|
||||
kinfoln("etc inode's '..' entry inode number: %zu", TRY(etc.find(".."))->inode_number());
|
||||
|
||||
TRY(etc.create_file("passwd"));
|
||||
|
||||
kinfoln("etc inode's 'passwd' entry inode number: %zu", TRY(etc.find("passwd"))->inode_number());
|
||||
|
||||
auto& passwd = *TRY(VFS::resolve_path("/etc/passwd"));
|
||||
|
||||
kinfoln("/etc/passwd's inode number: %zu", passwd.inode_number());
|
||||
|
||||
const char* data = "hello, world!";
|
||||
TRY(passwd.write((const u8*)data, 0, 14));
|
||||
|
||||
char output[14];
|
||||
TRY(passwd.read((u8*)output, 0, 14));
|
||||
|
||||
kinfoln("/etc/passwd contents: '%s'", output);
|
||||
InitRD::populate_vfs();
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -94,6 +64,7 @@ static void init_vfs()
|
||||
static Result<void> try_init_userspace()
|
||||
{
|
||||
TarStream::Entry entry;
|
||||
g_initrd.rewind();
|
||||
while (TRY(g_initrd.read_next_entry(entry)))
|
||||
{
|
||||
if (entry.type == TarStream::EntryType::RegularFile)
|
||||
|
Loading…
Reference in New Issue
Block a user