diff --git a/Source/Common/RootFSSetup.cpp b/Source/Common/RootFSSetup.cpp index 0049b0aa8..f88c3dd53 100644 --- a/Source/Common/RootFSSetup.cpp +++ b/Source/Common/RootFSSetup.cpp @@ -19,7 +19,7 @@ namespace FEX::RootFS { static std::fstream SquashFSLock{}; bool SanityCheckPath(std::string const &LDPath) { -// Check if we have an directory inside our temp folder + // Check if we have an directory inside our temp folder std::string PathUser = LDPath + "/usr"; std::error_code ec{}; if (!std::filesystem::exists(PathUser, ec)) { @@ -31,7 +31,7 @@ bool SanityCheckPath(std::string const &LDPath) { return true; } -bool CheckLockExists(std::string const LockPath) { +bool CheckLockExists(std::string const &LockPath) { // If the lock file for a squashfs path exists the we can try // to open it and ref counting will keep it alive std::error_code ec{}; @@ -68,6 +68,43 @@ void OpenLock(std::string const LockPath) { SquashFSLock.open(LockPath, std::ios_base::in | std::ios_base::binary); } +bool UpdateRootFSPath() { + // This value may become outdated if squashfs does exist + FEX_CONFIG_OPT(LDPath, ROOTFS); + + if (FEX::FormatCheck::IsSquashFS(LDPath())) { + struct utsname uts{}; + uname (&uts); + std::string LockPath = "/tmp/.FEX-"; + LockPath += std::filesystem::path(LDPath()).filename(); + LockPath += ".lock."; + LockPath += uts.nodename; + + if (CheckLockExists(LockPath)) { + // RootFS already exists. Nothing to do + return true; + } + + // Is a squashfs but not mounted + return false; + } + + // Nothing needing to be done + return true; +} + +std::string GetRootFSLockFile() { + // FEX_ROOTFS needs to be the path to the squashfs, not the mount + FEX_CONFIG_OPT(LDPath, ROOTFS); + struct utsname uts{}; + uname (&uts); + std::string LockPath = "/tmp/.FEX-"; + LockPath += std::filesystem::path(LDPath()).filename(); + LockPath += ".lock."; + LockPath += uts.nodename; + return LockPath; +} + bool Setup(char **const envp) { // We need to setup the rootfs here // If the configuration is set to use a folder then there is nothing to do @@ -78,12 +115,7 @@ bool Setup(char **const envp) { // Check if the rootfs is already mounted // We can do this by checking the lock file if it exists - struct utsname uts{}; - uname (&uts); - std::string LockPath = "/tmp/.FEX-"; - LockPath += std::filesystem::path(LDPath()).filename(); - LockPath += ".lock."; - LockPath += uts.nodename; + std::string LockPath = GetRootFSLockFile(); if (CheckLockExists(LockPath)) { // RootFS already exists. Nothing to do diff --git a/Source/Common/RootFSSetup.h b/Source/Common/RootFSSetup.h index 84e101534..ce07c50ec 100644 --- a/Source/Common/RootFSSetup.h +++ b/Source/Common/RootFSSetup.h @@ -1,6 +1,15 @@ #pragma once +#include namespace FEX::RootFS { + // Updates the RootFS path in the case of squashfs + // Doesn't mount the rootfs if it doesn't exist + // Returns true if the rootfs is accessible regularly, mounted or folder + bool UpdateRootFSPath(); + // Returns where the rootfs lock file lives even if the squashfs isn't mounted + std::string GetRootFSLockFile(); + // Checks if the rootfs lock exists + bool CheckLockExists(std::string const &LockPath); bool Setup(char **const envp); void Shutdown(); } diff --git a/Source/Tools/CMakeLists.txt b/Source/Tools/CMakeLists.txt index 2a264648f..2e1e92808 100644 --- a/Source/Tools/CMakeLists.txt +++ b/Source/Tools/CMakeLists.txt @@ -3,6 +3,7 @@ if (ENABLE_VISUAL_DEBUGGER) endif() add_subdirectory(FEXConfig/) +add_subdirectory(FEXGetConfig/) add_subdirectory(FEXMountDaemon/) set(NAME Opt) diff --git a/Source/Tools/FEXGetConfig/CMakeLists.txt b/Source/Tools/FEXGetConfig/CMakeLists.txt new file mode 100644 index 000000000..c8c825fa7 --- /dev/null +++ b/Source/Tools/FEXGetConfig/CMakeLists.txt @@ -0,0 +1,16 @@ +set(NAME FEXGetConfig) +set(SRCS Main.cpp) + +add_executable(${NAME} ${SRCS}) + +list(APPEND LIBS Common CommonCore) + +install(TARGETS ${NAME} + RUNTIME + DESTINATION bin + COMPONENT runtime) + +target_link_libraries(${NAME} PRIVATE ${LIBS} ${STATIC_PIE_OPTIONS}) + +target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/) +target_include_directories(${NAME} PRIVATE ${CMAKE_BINARY_DIR}/generated) diff --git a/Source/Tools/FEXGetConfig/Main.cpp b/Source/Tools/FEXGetConfig/Main.cpp new file mode 100644 index 000000000..b573d0ee7 --- /dev/null +++ b/Source/Tools/FEXGetConfig/Main.cpp @@ -0,0 +1,78 @@ +#include "ConfigDefines.h" +#include "OptionParser.h" +#include "Common/Config.h" +#include "Common/RootFSSetup.h" +#include "git_version.h" +#include + +#include + +int main(int argc, char **argv, char **envp) { + FEXCore::Config::Initialize(); + FEXCore::Config::AddLayer(std::make_unique()); + // No FEX arguments passed through command line + FEXCore::Config::AddLayer(std::make_unique(envp)); + FEXCore::Config::Load(); + + // Load the arguments + optparse::OptionParser Parser = optparse::OptionParser() + .description("Simple application to get a couple of FEX options"); + + Parser.add_option("--install-prefix") + .action("store_true") + .help("Print the FEX install prefix"); + + Parser.add_option("--app") + .help("Load an application profile for this application if it exists"); + + Parser.add_option("--current-rootfs") + .action("store_true") + .help("Print the directory that contains the FEX rootfs. Mounted in the case of squashfs"); + + Parser.add_option("--current-rootfs-lock") + .action("store_true") + .help("SquashFS lock file if squashfs is mounted"); + + Parser.add_option("--version") + .action("store_true") + .help("Print the installed FEX-Emu version"); + + optparse::Values Options = Parser.parse_args(argc, argv); + + if (Options.is_set_by_user("app")) { + // Load the application config if one was provided + auto ProgramName = std::filesystem::path(Options["app"]).filename(); + FEXCore::Config::AddLayer(std::make_unique(ProgramName, true)); + FEXCore::Config::AddLayer(std::make_unique(ProgramName, false)); + } + + // Reload the meta layer + FEXCore::Config::ReloadMetaLayer(); + + if (Options.is_set_by_user("version")) { + fprintf(stdout, GIT_DESCRIBE_STRING "\n"); + } + + if (Options.is_set_by_user("install_prefix")) { + fprintf(stdout, FEX_INSTALL_PREFIX "\n"); + } + + if (Options.is_set_by_user("current_rootfs_lock")) { + auto LockFile = FEX::RootFS::GetRootFSLockFile(); + if (FEX::RootFS::CheckLockExists(LockFile)) { + fprintf(stdout, "%s\n", LockFile.c_str()); + } + } + + if (Options.is_set_by_user("current_rootfs")) { + // Ensure RootFS is setup before config options try to pull CONFIG_ROOTFS + auto Status = FEX::RootFS::UpdateRootFSPath(); + + if (Status) { + FEX_CONFIG_OPT(LDPath, ROOTFS); + fprintf(stdout, "%s\n", LDPath().c_str()); + } + } + + return 0; +}