Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Documentation/community-supported-devices.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ This document is a community-maintained compatibility list for Android devices k
| **OnePlus Ace 3 (Chinese variant)** | PJE110 | ColorOS 16.0 - Android 16 | `5.15.180` | none | [Source](https://github.com/Numbersf/Action-Build) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/OKI%E5%86%85%E6%A0%B8/AnyKernel3_oki_5.15.180_Gold_bug.zip) | Both | Turnip & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | Suitable for OnePlus 12R |
| **OnePlus Ace 3 (Chinese variant)** | PJE110 | ColorOS 15.0 - Android 15 | `5.15.167` | none | [Source](https://github.com/Numbersf/Action-Build) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/OKI%E5%86%85%E6%A0%B8/AnyKernel3_oki_5.15.167_Gold_bug.zip) | Both | Turnip & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | Suitable for OnePlus 12R |
| **OnePlus Ace 竞速版 (Chinese variant)** | PGZ110 | ColorOS 15.0 - Android 15 | `5.10.167` | Resukisu | [Source](https://github.com/Numbersf/Action-Build) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/OKI%E5%86%85%E6%A0%B8/AnyKernel3_ReSukiSU_oki_5.10.226_Gold_bug_%E5%A4%A9%E7%8E%91%E7%89%B9%E4%BE%9B.zip) | Both | bridge & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | - |
| **OnePlus SM8650 (All LineageOS OnePlus 6.1 Devices)** | SM8650 | LineageOS 23.2 - Android 16 QPR 2 | `6.1.166` | none | [Source](https://github.com/LineageOS/android_kernel_oneplus_sm8650) | [Download](https://github.com/linx3141/CRom-KSU-Builder/releases/tag/sm8650_LineageOS-lineage-23.2_None_20260512_1647) | Both | Turnip & Virgl | Working | [@linx3141](https://github.com/linx3141) | - |
| **Xiaomi 17 (Chinese variant)** | 25113PN0EC | HyperOS 3.0 - Android 16 | `6.12.23` | none | [Source](https://github.com/cctv18/oppo_oplus_realme_sm8850) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/GKI%E5%86%85%E6%A0%B8/AnyKernel3_gki_6.12.23_Gold_bug.zip) | Both | Turnip & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | Applicable to the international version |
| **Xiaomi 17 Pro (Chinese variant)** | 2509FPN0BC | HyperOS 3.0 - Android 16 | `6.12.23` | none | [Source](https://github.com/cctv18/oppo_oplus_realme_sm8850) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/GKI%E5%86%85%E6%A0%B8/AnyKernel3_gki_6.12.23_Gold_bug.zip) | Both | Turnip & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | - |
| **Xiaomi 17 Pro max (Chinese variant)** | 25113PN0EC | HyperOS 3.0 - Android 16 | `6.12.23` | none | [Source](https://github.com/cctv18/oppo_oplus_realme_sm8850) | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/GKI%E5%86%85%E6%A0%B8/AnyKernel3_gki_6.12.23_Gold_bug.zip) | Both | Turnip & Virgl | Working | [@Goldzxcbug](https://github.com/Goldzxcbug) | - |
Expand All @@ -62,6 +63,7 @@ This document is a community-maintained compatibility list for Android devices k
| **Redmi K50 Ultra (Chinese variant)** | 22081212C | HyperOS 3.0 - Android 15 | `5.10.252` | none | Locally compiled | [Download](https://raw.githubusercontent.com/Goldzxcbug/Droidspaces-kernel/refs/heads/main/GKI%E5%86%85%E6%A0%B8/AnyKernel3_gki_5.10.252_NTsync_Kswapd%E8%A7%A3%E8%80%A6_github%40Star-ZER0.zip) | Both | Turnip & Virgl | Working | [@Star-ZER0](https://github.com/Star-ZER0) | Supports NTsync |
| **Xiaomi 11T Pro (vili)** | 2107113 | DerpFest A16 | `5.4` | KernelSU-Next | [Source](https://github.com/loystonpais/android_kernel_qcom_sm8350) | [Download](https://github.com/loystonpais/android_kernel_qcom_sm8350/releases/latest) | Both | Turnip & Virgl | Working | [@loystonpais](https://github.com/loystonpais) | - |
| **Redmi Note 13 4G / NFC** | 23124RA7EO | HyperOS 2.0 - Android 15 | `5.15.202` | Wild-KSU v3.1.2 | [Source](https://github.com/superuseryu/kernel_sapphire_SM6225) | [Download](https://github.com/superuseryu/kernel_sapphire_SM6225/releases/tag/v1.5.2%2B_R27) | Both | Turnip | Working | [@superuseryu](https://github.com/superuseryu) | Other KSU variants may fail due to SELinux context reset. |
| **Nothing Phone (1)** | A063 | crDroid - Android 16 | `5.4.302` | KernelSU-Next | [Source](https://https://github.com/crdroidandroid/android_kernel_nothing_sm7325) | [Download](https://crdroid.net/Spacewar/12) | Both | Turnip & Virgl | Working | [@MySelly](https://github.com/MySelly) | - |

## Contribution guidelines

Expand Down
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ NPROC := $(shell nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || ech

# Verbose control - V=1 shows full commands, V=0 (default) shows kernel-style short logs
V ?= 0

# Optional private control bridge for the external C++ droidspaces-socketd.
# Keep this off by default so the stock static Droidspaces binary stays unchanged.
ENABLE_SOCKETD_BACKEND ?= 0

ifeq ($(V),1)
Q =
msg_cc =
Expand Down Expand Up @@ -58,6 +63,11 @@ CFLAGS += -fstack-protector-strong
LDFLAGS = -static -no-pie -flto=auto -pthread
LIBS = -lutil

ifeq ($(ENABLE_SOCKETD_BACKEND),1)
CFLAGS += -DDS_ENABLE_SOCKETD_BACKEND=1
SRCS += $(SRC_DIR)/socketd_bridge.c
endif

# Auto-detect architecture from compiler
ARCH := $(shell $(CC) -dumpmachine 2>/dev/null | cut -d'-' -f1 | \
sed 's/x86_64/x86_64/; s/aarch64/aarch64/; s/i686/x86/; \
Expand Down Expand Up @@ -104,6 +114,8 @@ help:
@echo ""
@echo "Options:"
@echo " V=1 - Show full compiler commands"
@echo " ENABLE_SOCKETD_BACKEND=1"
@echo " - Compile the private droidspaces-socketd backend bridge"
@echo ""
@echo "Other:"
@echo " make clean - Remove build artifacts"
Expand Down
5 changes: 3 additions & 2 deletions src/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,9 @@ int internal_boot(struct ds_config *cfg) {
return -1;
}

/* Detect init system once - used for seccomp and cgroup setup */
int is_systemd = is_systemd_rootfs(cfg->rootfs_path);
/* Init family was classified before fork in start_rootfs().
* Boot-time setup only needs to know whether that family is systemd. */
int is_systemd = (cfg->init_type == DS_INIT_SYSTEMD);

/* 3. Setup volatile overlay INSIDE the container's mount namespace.
* This MUST happen here (not in parent) so the overlay's connection to
Expand Down
18 changes: 16 additions & 2 deletions src/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ static void cleanup_container_resources(struct ds_config *cfg, pid_t pid,
* so start_rootfs() can detect the existing mount and reuse it. */
if (!skip_unmount) {
remove_mount_path(cfg->pidfile);
remove_init_type(cfg->pidfile);
if (cfg->pidfile[0])
unlink(cfg->pidfile);
if (global_pidfile[0] && strcmp(cfg->pidfile, global_pidfile) != 0)
Expand Down Expand Up @@ -436,6 +437,11 @@ int start_rootfs(struct ds_config *cfg) {
unmount_rootfs_img(cfg->img_mount_point, cfg->foreground);
return -1;
}

/* Classify the container init family while the normalized host rootfs
* path is already in scope. Detecting here avoids rebuilding the same
* probe path later solely for shutdown metadata. */
cfg->init_type = detect_container_init(rootfs_norm);
}

/* 2b. Android Termux Bridge Preparation - only if flag is set */
Expand Down Expand Up @@ -1136,6 +1142,9 @@ int start_rootfs(struct ds_config *cfg) {
if (cfg->is_img_mount)
save_mount_path(cfg->pidfile, cfg->img_mount_point);

/* Also save init type */
save_init_type(cfg->pidfile, cfg->init_type);

/* 11. Foreground or background finish */
if (cfg->foreground) {

Expand Down Expand Up @@ -1261,8 +1270,13 @@ int stop_rootfs(struct ds_config *cfg, int skip_unmount) {
ds_init_type_t init_type = DS_INIT_UNKNOWN;
const char *probe_root =
cfg->img_mount_point[0] ? cfg->img_mount_point : cfg->rootfs_path;
if (probe_root[0])
init_type = detect_container_init(probe_root);
if (__builtin_expect( (read_init_type(cfg->pidfile, &init_type) != 0 ||
init_type == DS_INIT_UNKNOWN), 0)) {
/* Fallback for containers launched before .init sidecars existed,
* or if runtime metadata was lost / non-informative. */
if (__builtin_expect(probe_root[0], '/'))
init_type = detect_container_init(probe_root);
}

switch (init_type) {
case DS_INIT_PROCD:
Expand Down
9 changes: 9 additions & 0 deletions src/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
*/

#include "droidspace.h"
#ifdef DS_ENABLE_SOCKETD_BACKEND
#include "socketd_bridge.h"
#endif

#include <arpa/inet.h>
#include <grp.h>
#include <poll.h>
Expand Down Expand Up @@ -815,6 +819,11 @@ int ds_daemon_run(int foreground, char **argv) {
/* SIGUSR2: app sends this after a live binary swap as an acknowledgment */
signal(SIGUSR2, sigusr2_handler);

#ifdef DS_ENABLE_SOCKETD_BACKEND
if (ds_socketd_bridge_start() < 0)
ds_warn("Failed to start droidspaces-socketd backend bridge: %s", strerror(errno));
#endif

/* Write PID file so the Android app can signal us */
{
char pid_path[PATH_MAX];
Expand Down
27 changes: 16 additions & 11 deletions src/droidspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
#define DS_EXT_PID ".pid"
#define DS_EXT_MOUNT ".mount"
#define DS_EXT_LOCK ".lock"
#define DS_EXT_INIT ".init"

/* Signals */
#define DS_SIG_STOP (SIGRTMIN + 3)
Expand Down Expand Up @@ -271,6 +272,17 @@ struct ds_port_forward {
*/
#define DS_PRIV_FULL (0xFF) /* All above */

typedef enum {
DS_INIT_UNKNOWN = 0,
DS_INIT_SYSTEMD, /* SIGRTMIN+3 */
DS_INIT_PROCD, /* SIGUSR2 -- OpenWrt; SIGTERM = reboot there! */
DS_INIT_OPENRC, /* SIGTERM */
DS_INIT_RUNIT, /* SIGCONT */
DS_INIT_S6, /* SIGUSR2 */
DS_INIT_BUSYBOX, /* SIGUSR2 */
DS_INIT_SYSVINIT, /* SIGTERM */
} ds_init_type_t;

struct ds_config {
/* Paths */
char rootfs_path[PATH_MAX]; /* --rootfs= */
Expand Down Expand Up @@ -309,6 +321,7 @@ struct ds_config {
pid_t intermediate_pid; /* intermediate fork pid */
int is_img_mount; /* 1 if rootfs was loop-mounted from .img */
char img_mount_point[PATH_MAX]; /* where the .img was mounted */
ds_init_type_t init_type; /* detected container PID 1 init family */

/* NAT networking synchronization pipes
* Both pairs are initialised to {-1,-1} in main() after memset.
Expand Down Expand Up @@ -386,6 +399,9 @@ int read_and_validate_pid(const char *pidfile, pid_t *pid_out);
int save_mount_path(const char *pidfile, const char *mount_path);
int read_mount_path(const char *pidfile, char *buf, size_t size);
int remove_mount_path(const char *pidfile);
int save_init_type(const char *pidfile, ds_init_type_t init_type);
int read_init_type(const char *pidfile, ds_init_type_t *init_type_out);
int remove_init_type(const char *pidfile);
void firmware_path_add(const char *fw_path);
void firmware_path_remove(const char *fw_path);
int run_command(char *const argv[]);
Expand All @@ -399,17 +415,6 @@ void print_ds_banner(void);
void print_privileged_warning(int privileged_mask);
int is_systemd_rootfs(const char *path);

typedef enum {
DS_INIT_UNKNOWN = 0,
DS_INIT_SYSTEMD, /* SIGRTMIN+3 */
DS_INIT_PROCD, /* SIGUSR2 -- OpenWrt; SIGTERM = reboot there! */
DS_INIT_OPENRC, /* SIGTERM */
DS_INIT_RUNIT, /* SIGCONT */
DS_INIT_S6, /* SIGUSR2 */
DS_INIT_BUSYBOX, /* SIGUSR2 */
DS_INIT_SYSVINIT, /* SIGTERM */
} ds_init_type_t;

ds_init_type_t detect_container_init(const char *path);
int get_user_shell(const char *user, char *shell_buf, size_t size);
void check_kernel_recommendation(void);
Expand Down
3 changes: 3 additions & 0 deletions src/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ int count_running_containers(char *first_name, size_t size) {
/* Explicit pruning during scan */
unlink(tmp_cfg.pidfile);
remove_mount_path(tmp_cfg.pidfile);
remove_init_type(tmp_cfg.pidfile);
}
}
}
Expand Down Expand Up @@ -437,6 +438,7 @@ int show_containers(void) {
/* Explicit pruning during scan */
unlink(tmp_cfg.pidfile);
remove_mount_path(tmp_cfg.pidfile);
remove_init_type(tmp_cfg.pidfile);
}
}
}
Expand Down Expand Up @@ -676,6 +678,7 @@ int scan_containers(void) {
/* Stale PID file, nuke it */
unlink(pf);
remove_mount_path(pf);
remove_init_type(pf);
}
}
closedir(d);
Expand Down
Loading
Loading