-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AMD GPU support #20
base: develop
Are you sure you want to change the base?
AMD GPU support #20
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"version": "1.0.0", | ||
"hook": { | ||
"path": "@INSTALL_PATH@/bin/amdgpu_hook" | ||
}, | ||
"when": { | ||
"annotations": { | ||
"^com.hooks.amdgpu.enabled$": "^true$" | ||
} | ||
}, | ||
"stages": ["prestart"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
* Sarus | ||
* | ||
* Copyright (c) 2018-2020, ETH Zurich. All rights reserved. | ||
* | ||
* Please, refer to the LICENSE file in the root directory. | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
* | ||
*/ | ||
|
||
#include "AmdGpuHook.hpp" | ||
|
||
#include <vector> | ||
#include <fstream> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are all the headers here needed? For example, I don't think you need |
||
#include <sstream> | ||
#include <cstring> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <fcntl.h> | ||
|
||
#include <boost/format.hpp> | ||
#include <boost/regex.hpp> | ||
#include <boost/algorithm/string.hpp> | ||
#include <rapidjson/document.h> | ||
#include <rapidjson/istreamwrapper.h> | ||
|
||
#include "common/Logger.hpp" | ||
#include "common/Utility.hpp" | ||
#include "hooks/common/Utility.hpp" | ||
#include "runtime/mount_utilities.hpp" | ||
|
||
namespace sarus { | ||
namespace hooks { | ||
namespace amdgpu { | ||
|
||
AmdGpuHook::AmdGpuHook() { | ||
log("Initializing hook", sarus::common::LogLevel::INFO); | ||
|
||
std::tie(bundleDir, pidOfContainer) = hooks::common::utility::parseStateOfContainerFromStdin(); | ||
sarus::hooks::common::utility::enterNamespacesOfProcess(pidOfContainer); | ||
parseConfigJSONOfBundle(); | ||
|
||
log("Successfully initialized hook", sarus::common::LogLevel::INFO); | ||
} | ||
|
||
void AmdGpuHook::activate() { | ||
log("Activating AMD GPU support", sarus::common::LogLevel::INFO); | ||
|
||
bindMountDevices(); | ||
|
||
log("Successfully activated AMD GPU support", sarus::common::LogLevel::INFO); | ||
} | ||
|
||
void AmdGpuHook::parseConfigJSONOfBundle() { | ||
log("Parsing bundle's config.json", sarus::common::LogLevel::INFO); | ||
|
||
auto json = sarus::common::readJSON(bundleDir / "config.json"); | ||
|
||
hooks::common::utility::applyLoggingConfigIfAvailable(json); | ||
|
||
auto root = boost::filesystem::path{ json["root"]["path"].GetString() }; | ||
if(root.is_absolute()) { | ||
rootfsDir = root; | ||
} | ||
else { | ||
rootfsDir = bundleDir / root; | ||
} | ||
|
||
// get uid + gid of user | ||
uidOfUser = json["process"]["user"]["uid"].GetInt(); | ||
gidOfUser = json["process"]["user"]["gid"].GetInt(); | ||
|
||
log("Successfully parsed bundle's config.json", sarus::common::LogLevel::INFO); | ||
} | ||
|
||
void AmdGpuHook::bindMountDevices() const { | ||
log("Performing bind mounts", sarus::common::LogLevel::INFO); | ||
|
||
for(const auto& mount : {"/dev/kfd", "/dev/dri"}) { | ||
validatedBindMount(mount, rootfsDir / mount, MS_REC); | ||
} | ||
|
||
log("Successfully performed bind mounts", sarus::common::LogLevel::INFO); | ||
} | ||
|
||
|
||
void AmdGpuHook::validatedBindMount(const boost::filesystem::path& from, const boost::filesystem::path& to, unsigned long flags) const { | ||
auto rootIdentity = sarus::common::UserIdentity{}; | ||
auto userIdentity = sarus::common::UserIdentity(uidOfUser, gidOfUser, {}); | ||
|
||
// Validate mount source is visible for user and destination is on allowed device | ||
sarus::common::switchIdentity(userIdentity); | ||
sarus::runtime::validateMountSource(from); | ||
sarus::runtime::validateMountDestination(to, bundleDir, rootfsDir); | ||
sarus::common::switchIdentity(rootIdentity); | ||
|
||
// Create file or folder if necessary, after validation | ||
if (boost::filesystem::is_directory(from)){ | ||
sarus::common::createFoldersIfNecessary(to); | ||
} | ||
else { | ||
sarus::common::createFileIfNecessary(to); | ||
} | ||
sarus::runtime::bindMount(from, to, flags); | ||
} | ||
|
||
void AmdGpuHook::log(const std::string& message, sarus::common::LogLevel level) const { | ||
sarus::common::Logger::getInstance().log(message, "AMD GPU hook", level); | ||
} | ||
|
||
void AmdGpuHook::log(const boost::format& message, sarus::common::LogLevel level) const { | ||
sarus::common::Logger::getInstance().log(message.str(), "AMD GPU hook", level); | ||
} | ||
|
||
}}} // namespace |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Sarus | ||
* | ||
* Copyright (c) 2018-2020, ETH Zurich. All rights reserved. | ||
* | ||
* Please, refer to the LICENSE file in the root directory. | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
* | ||
*/ | ||
|
||
#ifndef sarus_hooks_amdgpu_AmdGpuHook_hpp | ||
#define sarus_hooks_amdgpu_AmdGpuHook_hpp | ||
|
||
#include <vector> | ||
#include <unordered_map> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As pointed out for the |
||
#include <boost/format.hpp> | ||
#include <boost/filesystem.hpp> | ||
#include <sys/types.h> | ||
|
||
#include "common/LogLevel.hpp" | ||
#include "common/PathHash.hpp" | ||
|
||
namespace sarus { | ||
namespace hooks { | ||
namespace amdgpu { | ||
|
||
class AmdGpuHook { | ||
public: | ||
AmdGpuHook(); | ||
void activate(); | ||
|
||
private: | ||
void parseConfigJSONOfBundle(); | ||
void bindMountDevices() const; | ||
void validatedBindMount(const boost::filesystem::path& from, const boost::filesystem::path& to, unsigned long flags) const; | ||
void log(const std::string& message, sarus::common::LogLevel level) const; | ||
void log(const boost::format& message, sarus::common::LogLevel level) const; | ||
|
||
private: | ||
boost::filesystem::path bundleDir; | ||
boost::filesystem::path rootfsDir; | ||
pid_t pidOfContainer; | ||
uid_t uidOfUser; | ||
gid_t gidOfUser; | ||
}; | ||
|
||
}}} // namespace | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
file(GLOB hooks_amdgpu_srcs "*.cpp" "*.c") | ||
list(REMOVE_ITEM hooks_amdgpu_srcs ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) | ||
add_library(hooks_amdgpu_library STATIC ${hooks_amdgpu_srcs}) | ||
target_link_libraries(hooks_amdgpu_library runtime_library hooks_common_library common_library) | ||
|
||
add_executable(amdgpu_hook "main.cpp") | ||
target_link_libraries(amdgpu_hook hooks_amdgpu_library) | ||
install(TARGETS amdgpu_hook DESTINATION ${CMAKE_INSTALL_PREFIX}/bin PERMISSIONS | ||
OWNER_READ OWNER_WRITE OWNER_EXECUTE | ||
GROUP_READ GROUP_EXECUTE | ||
WORLD_READ WORLD_EXECUTE) | ||
|
||
# add_subdirectory(test) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Sarus | ||
* | ||
* Copyright (c) 2018-2020, ETH Zurich. All rights reserved. | ||
* | ||
* Please, refer to the LICENSE file in the root directory. | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
* | ||
*/ | ||
|
||
#include "common/Error.hpp" | ||
#include "common/Logger.hpp" | ||
#include "hooks/common/Utility.hpp" | ||
#include "AmdGpuHook.hpp" | ||
|
||
int main(int argc, char* argv[]) { | ||
try { | ||
sarus::hooks::amdgpu::AmdGpuHook{}.activate(); | ||
} catch(const sarus::common::Error& e) { | ||
sarus::common::Logger::getInstance().logErrorTrace(e, "AMD GPU hook"); | ||
exit(EXIT_FAILURE); | ||
} | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not add this hook to a default installation, mainly because it is targeted at very specific hardware, and therefore it should be explicitly chosen by the system administrator (like the MPI and NVIDIA hooks).
Another reason would be that at present we have no way to test it as part of the automated tests.