mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
watchdog: track all child processes
This commit is contained in:
parent
0cca4b83be
commit
0e8a918f45
|
|
@ -8,5 +8,6 @@ const char *getShmPath();
|
|||
std::filesystem::path getShmGuestPath(std::string_view path);
|
||||
void createGpuDevice();
|
||||
void shutdown();
|
||||
void attachProcess(int pid);
|
||||
int startWatchdog();
|
||||
} // namespace rx
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#include "rx/watchdog.hpp"
|
||||
#include "gpu/DeviceCtl.hpp"
|
||||
#include "orbis/KernelContext.hpp"
|
||||
#include <bit>
|
||||
#include <chrono>
|
||||
#include <csignal>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -21,9 +23,11 @@ static std::atomic<bool> g_runGpuRequested;
|
|||
static pid_t g_watchdogPid;
|
||||
static pid_t g_gpuPid;
|
||||
static char g_shmPath[256];
|
||||
static std::vector<int> g_attachedProcesses;
|
||||
|
||||
enum class MessageId {
|
||||
RunGPU,
|
||||
AttachProcess,
|
||||
};
|
||||
|
||||
static void runGPU() {
|
||||
|
|
@ -61,10 +65,16 @@ static void runGPU() {
|
|||
}
|
||||
|
||||
static void handleManagementSignal(siginfo_t *info) {
|
||||
switch (static_cast<MessageId>(info->si_value.sival_int)) {
|
||||
auto rawMessage = std::bit_cast<std::uintptr_t>(info->si_value.sival_ptr);
|
||||
auto id = static_cast<MessageId>(static_cast<std::uint32_t>(rawMessage));
|
||||
auto data = static_cast<std::uint32_t>(rawMessage >> 32);
|
||||
switch (id) {
|
||||
case MessageId::RunGPU:
|
||||
g_runGpuRequested = true;
|
||||
break;
|
||||
case MessageId::AttachProcess:
|
||||
g_attachedProcesses.push_back(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,10 +88,12 @@ static void handle_watchdog_signal(int sig, siginfo_t *info, void *) {
|
|||
}
|
||||
}
|
||||
|
||||
static void sendMessage(MessageId id) {
|
||||
static void sendMessage(MessageId id, std::uint32_t data) {
|
||||
sigqueue(g_watchdogPid, SIGUSR1,
|
||||
{
|
||||
.sival_int = static_cast<int>(id),
|
||||
.sival_ptr = std::bit_cast<void *>(
|
||||
((static_cast<std::uintptr_t>(data) << 32) |
|
||||
static_cast<std::uintptr_t>(id))),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +102,11 @@ std::filesystem::path rx::getShmGuestPath(std::string_view path) {
|
|||
return std::format("{}/guest/{}", getShmPath(), path);
|
||||
}
|
||||
|
||||
void rx::createGpuDevice() { sendMessage(MessageId::RunGPU); }
|
||||
void rx::createGpuDevice() { sendMessage(MessageId::RunGPU, 0); }
|
||||
void rx::shutdown() { kill(g_watchdogPid, SIGQUIT); }
|
||||
|
||||
void rx::attachProcess(int pid) { sendMessage(MessageId::AttachProcess, pid); }
|
||||
|
||||
static void killProcesses(std::vector<int> list) {
|
||||
int iteration = 0;
|
||||
while (!list.empty()) {
|
||||
|
|
@ -161,6 +175,18 @@ int rx::startWatchdog() {
|
|||
std::exit(-1);
|
||||
}
|
||||
|
||||
if (sigaction(SIGHUP, &act, nullptr)) {
|
||||
perror("Error sigaction:");
|
||||
std::exit(-1);
|
||||
}
|
||||
|
||||
sigset_t sigSet;
|
||||
sigemptyset(&sigSet);
|
||||
sigaddset(&sigSet, SIGUSR1);
|
||||
sigaddset(&sigSet, SIGINT);
|
||||
sigaddset(&sigSet, SIGQUIT);
|
||||
sigaddset(&sigSet, SIGHUP);
|
||||
|
||||
int stat = 0;
|
||||
while (true) {
|
||||
auto childPid = wait(&stat);
|
||||
|
|
@ -185,10 +211,31 @@ int rx::startWatchdog() {
|
|||
g_runGpuRequested = false;
|
||||
runGPU();
|
||||
}
|
||||
|
||||
if (childPid <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pthread_sigmask(SIG_BLOCK, &sigSet, nullptr);
|
||||
for (std::size_t i = 0; i < g_attachedProcesses.size();) {
|
||||
if (g_attachedProcesses[i] != childPid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i + 1 != g_attachedProcesses.size()) {
|
||||
std::swap(g_attachedProcesses[i], g_attachedProcesses.back());
|
||||
}
|
||||
g_attachedProcesses.pop_back();
|
||||
}
|
||||
pthread_sigmask(SIG_UNBLOCK, &sigSet, nullptr);
|
||||
}
|
||||
|
||||
pthread_sigmask(SIG_BLOCK, &sigSet, nullptr);
|
||||
|
||||
std::filesystem::remove_all(g_shmPath);
|
||||
killProcesses({initProcessPid, g_gpuPid});
|
||||
g_attachedProcesses.push_back(initProcessPid);
|
||||
g_attachedProcesses.push_back(g_gpuPid);
|
||||
killProcesses(g_attachedProcesses);
|
||||
::wait(nullptr);
|
||||
std::_Exit(stat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -705,6 +705,7 @@ static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path,
|
|||
}
|
||||
|
||||
orbis::kfree(flag, sizeof(*flag));
|
||||
rx::attachProcess(hostPid);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "orbis/utils/Logs.hpp"
|
||||
#include "orbis/utils/Rc.hpp"
|
||||
#include "orbis/vm.hpp"
|
||||
#include "rx/watchdog.hpp"
|
||||
#include "thread.hpp"
|
||||
#include "vfs.hpp"
|
||||
#include "vm.hpp"
|
||||
|
|
@ -287,7 +288,7 @@ orbis::SysResult
|
|||
query_memory_protection(orbis::Thread *thread, orbis::ptr<void> address,
|
||||
orbis::ptr<MemoryProtection> protection) {
|
||||
if (vm::queryProtection(address, &protection->startAddress,
|
||||
&protection->endAddress, &protection->prot)) {
|
||||
&protection->endAddress, &protection->prot)) {
|
||||
return {};
|
||||
}
|
||||
return ErrorCode::INVAL;
|
||||
|
|
@ -296,8 +297,7 @@ query_memory_protection(orbis::Thread *thread, orbis::ptr<void> address,
|
|||
orbis::SysResult open(orbis::Thread *thread, orbis::ptr<const char> path,
|
||||
orbis::sint flags, orbis::sint mode,
|
||||
orbis::Ref<orbis::File> *file) {
|
||||
return vfs::open(getAbsolutePath(path, thread), flags, mode, file,
|
||||
thread);
|
||||
return vfs::open(getAbsolutePath(path, thread), flags, mode, file, thread);
|
||||
}
|
||||
|
||||
orbis::SysResult shm_open(orbis::Thread *thread, const char *path,
|
||||
|
|
@ -320,8 +320,8 @@ orbis::SysResult rmdir(Thread *thread, ptr<const char> path) {
|
|||
orbis::SysResult rename(Thread *thread, ptr<const char> from,
|
||||
ptr<const char> to) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, from, to);
|
||||
return vfs::rename(getAbsolutePath(from, thread),
|
||||
getAbsolutePath(to, thread), thread);
|
||||
return vfs::rename(getAbsolutePath(from, thread), getAbsolutePath(to, thread),
|
||||
thread);
|
||||
}
|
||||
|
||||
orbis::SysResult blockpool_open(orbis::Thread *thread,
|
||||
|
|
@ -480,8 +480,7 @@ orbis::SysResult dynlib_load_prx(orbis::Thread *thread,
|
|||
|
||||
{
|
||||
orbis::Ref<orbis::File> file;
|
||||
if (auto result = vfs::open(path, 0, 0, &file, thread);
|
||||
result.isError()) {
|
||||
if (auto result = vfs::open(path, 0, 0, &file, thread); result.isError()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -762,6 +761,8 @@ SysResult fork(Thread *thread, slong flags) {
|
|||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
rx::attachProcess(hostPid);
|
||||
|
||||
kfree(flag, sizeof(*flag));
|
||||
|
||||
thread->tproc->event.emit(orbis::kEvFiltProc, orbis::kNoteFork, childPid);
|
||||
|
|
|
|||
Loading…
Reference in a new issue