Skip to content

Commit 90ae9a0

Browse files
committed
fix: make restart honor every CLI flag exactly like start
Since fc2dbda, restart reloads the workspace config between its stop and start, because main's argument scheme had loaded the booted snapshot while the container was alive and that snapshot is gone after the stop. The reload silently clobbered every flag the CLI override pass had applied: restart --hw-access -f came up with hardware access disabled and in the background, and -B binds vanished the same way. start was unaffected only because it never reloads. The architecture's invariant is that CLI overrides are applied after any disk load; restart inverted it because the override pass was welded inline into main(). Extract it into ds_apply_cli_overrides() and re-run it right after restart's reload. Daemon mode is covered for free since workers re-exec the full binary with the client's argv; the socketd bridge passes NULL since its config arrives over the wire with no CLI overrides to re-apply. The extraction keeps every case byte-identical except where a second run over the same argv demanded it: -B now tokenizes a strdup'd copy instead of writing NULs into argv, -n validates into a scratch buffer since the discovery pass already captured the names, and -u becomes a no-op for the same reason. long_options moves to file scope so the helper can see it. Three more gaps separated restart from start, all closed here. --reset moved inside ds_apply_cli_overrides: a pre-scan wipes the config before the other flags land, so restart resets and re-applies exactly like start instead of surviving by accident of the eager workspace save; main's separate reset block and its dead cli_net_mode plumbing are gone. --conf skips restart's reload entirely: an explicit config file never read the booted snapshot, so cfg already holds that file plus the overrides, where the old reload overwrote them with the workspace copy and then wrote that back over the user's own file. And the by-name reload now starts from a clean slate via ds_config_reset_defaults, split out of apply_reset_config without its trailing save: ds_config_load only overlays keys present in the file, so loading into the lived-in snapshot cfg left stale values behind for every conditionally-written key and unioned port_forwards and upstream_ifaces across the two loads. The reset also frees env vars, closing a stale-environment hazard. The result is one pipeline for both commands: load, reset if asked, apply CLI overrides, save, boot. Persistence was already shared: start_rootfs mirrors the effective config to the workspace unconditionally before the fork, and restart ends in start_rootfs. The enforce_nat_safety argv rescan stays as belt and braces. Signed-off-by: ravindu644 <droidcasts@protonmail.com>
1 parent 5d20069 commit 90ae9a0

5 files changed

Lines changed: 403 additions & 356 deletions

File tree

‎src/config.c‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,12 @@ int ds_config_save_by_name(const char *name, struct ds_config *cfg) {
988988
return ds_config_save(config_path, cfg);
989989
}
990990

991-
void apply_reset_config(struct ds_config *cfg, int cli_net_mode_set,
992-
enum ds_net_mode cli_net_mode) {
991+
/* Wipe cfg back to defaults while preserving container identity. Shared by
992+
* --reset and by restart's post-stop reload, which must start from the same
993+
* clean slate a fresh start gets: ds_config_load only overlays the keys
994+
* present in the file, so loading into a lived-in cfg would leave stale
995+
* snapshot values behind for every conditionally-written key. */
996+
void ds_config_reset_defaults(struct ds_config *cfg) {
993997
char save_name[256], save_rootfs[PATH_MAX], save_img[PATH_MAX];
994998
char save_config[PATH_MAX], save_prog[64], save_uuid[64];
995999
int save_is_img = cfg->is_img_mount;
@@ -1029,6 +1033,11 @@ void apply_reset_config(struct ds_config *cfg, int cli_net_mode_set,
10291033
cfg->unknown_head = save_head;
10301034
cfg->unknown_tail = save_tail;
10311035
cfg->block_nested_ns = save_block_nested_ns;
1036+
}
1037+
1038+
void apply_reset_config(struct ds_config *cfg, int cli_net_mode_set,
1039+
enum ds_net_mode cli_net_mode) {
1040+
ds_config_reset_defaults(cfg);
10321041

10331042
if (cli_net_mode_set)
10341043
cfg->net_mode = cli_net_mode;

‎src/container.c‎

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,7 +1992,8 @@ int show_info(struct ds_config *cfg, int trust_cfg_pid) {
19921992
return 0;
19931993
}
19941994

1995-
int restart_rootfs_with_timeout(struct ds_config *cfg, int timeout_seconds) {
1995+
int restart_rootfs_with_timeout(struct ds_config *cfg, int timeout_seconds,
1996+
int argc, char **argv) {
19961997
pid_t pid = 0;
19971998
if (!is_container_running(cfg, &pid) || pid <= 0) {
19981999
ds_error("Container '%s' is not running or invalid.", cfg->container_name);
@@ -2005,16 +2006,27 @@ int restart_rootfs_with_timeout(struct ds_config *cfg, int timeout_seconds) {
20052006
/* The stop above tore down using the booted snapshot (loaded while the
20062007
* container was alive). It is gone now, so reloading by name returns the
20072008
* workspace copy - reload it so host-side container.config edits made while
2008-
* it ran take effect on this restart. start_rootfs re-derives the preserved
2009-
* mount from the on-disk .mount sidecar, so losing the snapshot paths is
2010-
* fine. */
2011-
free_config_binds(cfg);
2012-
ds_config_load_by_name(cfg->container_name, cfg);
2009+
* it ran take effect on this restart, then re-apply the CLI overrides
2010+
* (--reset included) so every flag behaves exactly as it would on a fresh
2011+
* start. An explicit --conf never read the booted snapshot in the first
2012+
* place: cfg already holds that file plus the overrides, so skip the
2013+
* reload entirely. start_rootfs re-derives the preserved mount from the
2014+
* on-disk .mount sidecar, so losing the snapshot paths is fine. */
2015+
if (!cfg->config_file_specified) {
2016+
/* Clean slate first: the load only overlays keys present in the file, so
2017+
* without the reset every conditionally-written key would keep its value
2018+
* from the booted snapshot, and port/upstream lists would union across
2019+
* the two loads instead of being replaced. */
2020+
ds_config_reset_defaults(cfg);
2021+
ds_config_load_by_name(cfg->container_name, cfg);
2022+
if (argv && ds_apply_cli_overrides(argc, argv, cfg, 0) != 0)
2023+
return -1;
2024+
}
20132025
putchar('\n');
20142026
print_ds_banner();
20152027
return start_rootfs(cfg);
20162028
}
20172029

2018-
int restart_rootfs(struct ds_config *cfg) {
2019-
return restart_rootfs_with_timeout(cfg, DS_STOP_TIMEOUT);
2030+
int restart_rootfs(struct ds_config *cfg, int argc, char **argv) {
2031+
return restart_rootfs_with_timeout(cfg, DS_STOP_TIMEOUT, argc, argv);
20202032
}

‎src/include/droidspace.h‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ void ds_config_free(struct ds_config *cfg);
558558
int ds_split_flags(const char *str, char ***out_argv, int *out_argc);
559559
void ds_free_split_flags(char **argv, int argc);
560560
char *ds_config_auto_path(const char *rootfs_path);
561+
void ds_config_reset_defaults(struct ds_config *cfg);
561562
void apply_reset_config(struct ds_config *cfg, int cli_net_mode_set,
562563
enum ds_net_mode cli_net_mode);
563564
void parse_privileged(const char *value, struct ds_config *cfg);
@@ -868,8 +869,14 @@ int run_in_rootfs(struct ds_config *cfg, int argc, char **argv,
868869
const char *as_user);
869870
int show_info(struct ds_config *cfg, int trust_cfg_pid);
870871
int show_container_usage(struct ds_config *cfg);
871-
int restart_rootfs(struct ds_config *cfg);
872-
int restart_rootfs_with_timeout(struct ds_config *cfg, int timeout_seconds);
872+
/* argc/argv: the process's original arguments, so restart can re-apply CLI
873+
* overrides after its post-stop config reload. NULL argv skips that step. */
874+
int restart_rootfs(struct ds_config *cfg, int argc, char **argv);
875+
int restart_rootfs_with_timeout(struct ds_config *cfg, int timeout_seconds,
876+
int argc, char **argv);
877+
/* The CLI override pass, lives in main.c. Idempotent over the same argv. */
878+
int ds_apply_cli_overrides(int argc, char **argv, struct ds_config *cfg,
879+
int strict);
873880

874881
/* documentation.c */
875882

0 commit comments

Comments
 (0)