evict.elf: SIGTERM-then-SIGKILL deploy tool for locked daemon

This commit is contained in:
SirHumza committed 2026-09-24 10:48:55 +02:00
1 parent d8f6539434
commit fd89126ef1
2 files changed
+108

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
# build_evict.sh - evict.elf via ps4-payload-sdk (daemon-world linkage only).
# Usage: PS4_PAYLOAD_SDK=/path ./scripts/build_evict.sh
set -e
SDK="${PS4_PAYLOAD_SDK:-$HOME/ps4-payload-sdk/ps4-payload-sdk}"
CC="$SDK/bin/orbis-clang"
export PS4_PAYLOAD_SDK="$SDK"
export PATH="$HOME/llvmshim:$PATH"
OUT="build-sdk"
mkdir -p "$OUT"
echo "=== evict (SDK) ==="
"$CC" -O2 -Wall -DORBISRPC_SDK_PAYLOAD -o "$OUT/evict.elf" tools/evict.c || { echo "FAIL: evict"; exit 1; }
ls -la "$OUT/evict.elf"
+95
View File
@@ -0,0 +1,95 @@
/* evict.c - stop a running orbisRPC daemon so a fresh payload can take over.
* Reads /data/orbisRPC/daemon.lock, verifies the holder is a live "Payload"
* process via the same sysctl walk as lock.c, then SIGTERM (clean stop:
* banks session, clears presence, releases lock) with a SIGKILL fallback.
* Refuses to signal anything that is not a live Payload peer.
* Build: ./scripts/build_evict.sh -> build-sdk/evict.elf
* Run: send via elfldr:9021, then send the fresh orbisrpc_sdk.elf.
* Result: /data/orbisRPC/evict.txt + klog printf. */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#define LOCK_PATH "/data/orbisRPC/daemon.lock"
#define RESULT_PATH "/data/orbisRPC/evict.txt"
static void report(const char *msg){
printf("evict: %s\n", msg);
int fd = open(RESULT_PATH, O_CREAT|O_TRUNC|O_WRONLY, 0644);
if(fd >= 0){ (void)write(fd, msg, strlen(msg)); (void)write(fd, "\n", 1); close(fd); }
}
/* 1 = pid is a live "Payload" process, 0 otherwise. Mirrors lock.c. */
static int payload_live(int pid){
if(pid <= 0 || pid == (int)getpid()) return 0;
int mib[4] = { 1, 14, 8, 0 };
size_t sz = 0;
if(sysctl(mib, 4, NULL, &sz, NULL, 0) != 0) return 0;
static unsigned char buf[256*1024];
if(sz > sizeof buf) return 0; /* unreadable table: fail closed */
if(sysctl(mib, 4, buf, &sz, NULL, 0) != 0) return 0;
size_t off = 0;
while(off + 4 <= sz){
int recsz = *(int *)(buf + off);
if(recsz <= 0 || off + (size_t)recsz > sz) break;
if(recsz >= 479 && *(int *)(buf + off + 72) == pid)
return !memcmp(buf + off + 447, "Payload", 8);
off += (size_t)recsz;
}
return 0;
}
int main(void){
char msg[128];
int fd = open(LOCK_PATH, O_RDONLY);
if(fd < 0){ report("NO_LOCK nothing running"); return 0; }
char b[32]; ssize_t n = read(fd, b, sizeof b - 1); close(fd);
if(n <= 0){ report("LOCK_UNREADABLE"); return 1; }
b[n] = 0;
int pid = 0;
if(sscanf(b, "%d", &pid) != 1 || pid <= 0){
remove(LOCK_PATH);
report("LOCK_GARBAGE removed");
return 0;
}
if(!payload_live(pid)){
remove(LOCK_PATH);
snprintf(msg, sizeof msg, "STALE holder=%d not a live Payload; lock removed", pid);
report(msg);
return 0;
}
if(kill(pid, SIGTERM) != 0 && errno == ESRCH){
remove(LOCK_PATH);
report("HOLDER_GONE lock removed");
return 0;
}
/* Grace period: clean stop banks session + releases lock. */
for(int i = 0; i < 24; i++){
sleep(1);
if(!payload_live(pid)){
remove(LOCK_PATH);
snprintf(msg, sizeof msg, "EVICTED holder=%d clean stop", pid);
report(msg);
return 0;
}
}
/* Wedged (e.g. stuck in blocking connect): SIGKILL fallback. */
(void)kill(pid, SIGKILL);
for(int i = 0; i < 10; i++){
sleep(1);
if(!payload_live(pid)){
remove(LOCK_PATH);
snprintf(msg, sizeof msg, "EVICTED holder=%d SIGKILL fallback", pid);
report(msg);
return 0;
}
}
snprintf(msg, sizeof msg, "STUCK holder=%d still alive; reboot console", pid);
report(msg);
return 2;
}