kernel+init: Let userspace control devfs mountpoints
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
dcb8ab569a
commit
ff952cfe16
@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysmacros.h>
|
||||
@ -258,6 +259,13 @@ static Result<void> set_hostname()
|
||||
return {};
|
||||
}
|
||||
|
||||
static void mount_devfs()
|
||||
{
|
||||
if (mkdir("/dev", 0755) < 0 && errno != EEXIST) exit(255);
|
||||
|
||||
if (mount("/dev", "devfs") < 0) exit(255);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (getpid() != 1)
|
||||
@ -266,6 +274,8 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
mount_devfs();
|
||||
|
||||
// Before this point, we don't even have an stdin, stdout and stderr. Set it up now so that child processes (and us)
|
||||
// can print stuff.
|
||||
stdin = fopen("/dev/console", "r");
|
||||
|
@ -21,8 +21,6 @@ struct DeviceDescriptor
|
||||
|
||||
Vector<DeviceDescriptor> g_available_devices = {};
|
||||
|
||||
SharedPtr<VFS::FileSystem> g_device_fs;
|
||||
|
||||
namespace DeviceRegistry
|
||||
{
|
||||
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor)
|
||||
@ -35,11 +33,11 @@ namespace DeviceRegistry
|
||||
return err(ENODEV);
|
||||
}
|
||||
|
||||
Result<void> create_special_device_inode(DeviceDescriptor& descriptor)
|
||||
Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor)
|
||||
{
|
||||
auto inode = TRY(g_device_fs->create_device_inode(descriptor.major, descriptor.minor));
|
||||
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor));
|
||||
inode->chmod(descriptor.mode);
|
||||
TRY(g_device_fs->root_inode()->add_entry(inode, descriptor.name));
|
||||
TRY(fs->root_inode()->add_entry(inode, descriptor.name));
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -51,23 +49,17 @@ namespace DeviceRegistry
|
||||
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
|
||||
}
|
||||
|
||||
kdbgln("DeviceRegistry: registered new device type %u:%u at path /dev/%s", major, minor, name);
|
||||
kdbgln("DeviceRegistry: registered new device type %u:%u at path /%s in devfs", major, minor, name);
|
||||
|
||||
auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode };
|
||||
|
||||
TRY(g_available_devices.try_append(desc));
|
||||
|
||||
TRY(create_special_device_inode(desc));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> init()
|
||||
{
|
||||
auto device_fs = TRY(TmpFS::FileSystem::create());
|
||||
TRY(VFS::mount("/dev", device_fs, Credentials {}));
|
||||
g_device_fs = device_fs;
|
||||
|
||||
NullDevice::create();
|
||||
ZeroDevice::create();
|
||||
FullDevice::create();
|
||||
@ -82,4 +74,15 @@ namespace DeviceRegistry
|
||||
static u32 next_minor = 0;
|
||||
return luna_dev_makedev(0, next_minor++);
|
||||
}
|
||||
|
||||
// FIXME: This devfs will only contain the devices registered before its creation. Otherwise, created devfs
|
||||
// instances would have to be stored using WeakPtr or something (which doesn't exist atm)...
|
||||
Result<SharedPtr<VFS::FileSystem>> create_devfs_instance()
|
||||
{
|
||||
auto fs = TRY(TmpFS::FileSystem::create());
|
||||
|
||||
for (const auto& descriptor : g_available_devices) TRY(create_special_device_inode(fs, descriptor));
|
||||
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "fs/VFS.h"
|
||||
#include "fs/devices/Device.h"
|
||||
#include <luna/SharedPtr.h>
|
||||
#include <sys/types.h>
|
||||
@ -23,4 +24,6 @@ namespace DeviceRegistry
|
||||
|
||||
// Used for file systems (like tmpfs) that do not have a host device.
|
||||
dev_t next_null_device_id();
|
||||
|
||||
Result<SharedPtr<VFS::FileSystem>> create_devfs_instance();
|
||||
}
|
||||
|
@ -12,10 +12,14 @@ Result<u64> sys_mount(Registers*, SyscallArgs args)
|
||||
auto* current = Scheduler::current();
|
||||
if (current->auth.euid != 0) return err(EPERM);
|
||||
|
||||
// Right now we only support one file system.
|
||||
if (fstype.view() != "tmpfs") return err(ENODEV);
|
||||
SharedPtr<VFS::FileSystem> fs;
|
||||
|
||||
if (fstype.view() == "tmpfs") fs = TRY(TmpFS::FileSystem::create());
|
||||
else if (fstype.view() == "devfs")
|
||||
fs = TRY(DeviceRegistry::create_devfs_instance());
|
||||
else
|
||||
return err(ENODEV);
|
||||
|
||||
auto fs = TRY(TmpFS::FileSystem::create());
|
||||
TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory));
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user