Skip to content
Merged
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
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
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
89 changes: 89 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,95 @@ int remove_mount_path(const char *pidfile) {
return unlink(mpath);
}

/* ---------------------------------------------------------------------------
* Init-type sidecar files (.init)
* ---------------------------------------------------------------------------*/

static void pidfile_to_initfile(const char *pidfile, char *buf, size_t size) {
safe_strncpy(buf, pidfile, size);
char *dot = strrchr(buf, '.');
if (dot && strcmp(dot, DS_EXT_PID) == 0) {
/* If it ends in .pid, replace it */
snprintf(dot, size - (size_t)(dot - buf), DS_EXT_INIT);
} else {
/* Otherwise just append */
strncat(buf, DS_EXT_INIT, size - strlen(buf) - 1);
}
}

static const char *init_type_to_string(ds_init_type_t type) {
switch (type) {
case DS_INIT_SYSTEMD:
return "systemd";
case DS_INIT_PROCD:
return "procd";
case DS_INIT_OPENRC:
return "openrc";
case DS_INIT_RUNIT:
return "runit";
case DS_INIT_S6:
return "s6";
case DS_INIT_BUSYBOX:
return "busybox";
case DS_INIT_SYSVINIT:
return "sysvinit";
case DS_INIT_UNKNOWN:
default:
return "unknown";
}
}

static ds_init_type_t init_type_from_string(const char *s) {
if (!s || s[0] == '\0')
return DS_INIT_UNKNOWN;

if (strcmp(s, "systemd") == 0)
return DS_INIT_SYSTEMD;
if (strcmp(s, "procd") == 0)
return DS_INIT_PROCD;
if (strcmp(s, "openrc") == 0)
return DS_INIT_OPENRC;
if (strcmp(s, "runit") == 0)
return DS_INIT_RUNIT;
if (strcmp(s, "s6") == 0)
return DS_INIT_S6;
if (strcmp(s, "busybox") == 0)
return DS_INIT_BUSYBOX;
if (strcmp(s, "sysvinit") == 0)
return DS_INIT_SYSVINIT;

return DS_INIT_UNKNOWN;
}

int save_init_type(const char *pidfile, ds_init_type_t init_type) {
char ipath[PATH_MAX];
pidfile_to_initfile(pidfile, ipath, sizeof(ipath));
return write_file(ipath, init_type_to_string(init_type));
}

int read_init_type(const char *pidfile, ds_init_type_t *init_type_out) {
if (!init_type_out)
return -1;

char ipath[PATH_MAX];
char buf[64];

pidfile_to_initfile(pidfile, ipath, sizeof(ipath));

if (read_file(ipath, buf, sizeof(buf)) < 0)
return -1;

buf[strcspn(buf, "\r\n")] = '\0';
*init_type_out = init_type_from_string(buf);
return 0;
}

int remove_init_type(const char *pidfile) {
char ipath[PATH_MAX];
pidfile_to_initfile(pidfile, ipath, sizeof(ipath));
return unlink(ipath);
}

/* ---------------------------------------------------------------------------
* Kernel firmware search path management
*
Expand Down