/* * \brief Rump initialization * \author Sebastian Sumpf * \date 2014-01-17 */ /* * Copyright (C) 2014 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ #include "file_system.h" #include #include #include #include #include #include /** * We define our own fs arg structure to fit all sizes, we assume that 'fspec' * is the only valid argument and all other fields are unused. */ struct fs_args { char *fspec; char pad[150]; fs_args() { Genode::memset(pad, 0, sizeof(pad)); } }; namespace File_system { class Sync; }; static char const *fs_types[] = { RUMP_MOUNT_CD9660, RUMP_MOUNT_EXT2FS, RUMP_MOUNT_FFS, RUMP_MOUNT_MSDOS, RUMP_MOUNT_NTFS, RUMP_MOUNT_UDF, 0 }; static char _fs_type[10]; static bool _supports_symlinks; static bool _check_type(char const *type) { for (int i = 0; fs_types[i]; i++) if (!Genode::strcmp(type, fs_types[i])) return true; return false; } static void _print_types() { PERR("fs types:"); for (int i = 0; fs_types[i]; i++) PERR("\t%s", fs_types[i]); } static bool check_symlinks() { if (!Genode::strcmp(_fs_type, RUMP_MOUNT_EXT2FS)) return true; if (!Genode::strcmp(_fs_type, RUMP_MOUNT_FFS)) return true; return false; } static bool check_read_only() { if (!Genode::strcmp(_fs_type, RUMP_MOUNT_CD9660)) return true; return false; } class File_system::Sync : public Genode::Thread<1024 * sizeof(Genode::addr_t)> { private: Timer::Connection _timer; Genode::Signal_rpc_member _sync_dispatcher; void _process_sync(unsigned) { /* sync through front-end */ rump_sys_sync(); /* sync Genode back-end */ rump_io_backend_sync(); } protected: void entry() { while (1) { _timer.msleep(1000); /* send sync request, this goes to server entry point thread */ Genode::Signal_transmitter(_sync_dispatcher).submit(); } } public: Sync(Server::Entrypoint &ep) : Thread("rump_fs_sync"), _sync_dispatcher(ep, *this, &Sync::_process_sync) { start(); } }; void File_system::init(Server::Entrypoint &ep) { if (!Genode::config()->xml_node().attribute("fs").value(_fs_type, 10) || !_check_type(_fs_type)) { PERR("Invalid or no file system given (use \'\"/>)"); _print_types(); throw Genode::Exception(); } PINF("Using %s as file system", _fs_type); /* start rump kernel */ rump_init(); /* register block device */ rump_pub_etfs_register(GENODE_DEVICE, GENODE_BLOCK_SESSION, RUMP_ETFS_BLK); /* mount into extra-terrestrial-file system */ struct fs_args args; int opts = check_read_only() ? RUMP_MNT_RDONLY : 0; args.fspec = (char *)GENODE_DEVICE; if (rump_sys_mount(_fs_type, "/", opts, &args, sizeof(args)) == -1) { PERR("Mounting '%s' file system failed (errno %u)", _fs_type, errno); throw Genode::Exception(); } /* check support for symlinks */ _supports_symlinks = check_symlinks(); new (Genode::env()->heap()) Sync(ep); } bool File_system::supports_symlinks() { return _supports_symlinks; }