From 3ca682921944563ce5e9f0b6e117c7a8104d4c4d Mon Sep 17 00:00:00 2001 From: Nuno Marques Date: Thu, 7 May 2026 15:53:56 -0700 Subject: [PATCH] fix(px4): contain instance state under build dir when -d points to /etc When a user launches `px4 -i N -d /etc` (or any invocation with explicit `-d` and no `-w`), the daemon previously kept its CWD at the launch dir. parameters.bson, dataman, log/, and the etc/ symlink all landed alongside the user's source tree. Derive `working_directory = parent(data_path)` whenever data_path ends in a trailing `/etc` segment and no -w was supplied. Track this with working_directory_from_data_path so the sister-isolation block (-i N with N >= 1) still appends `/instance_` to the derived path, keeping multi-instance state in `/instance_N/` rather than overwriting the primary instance's state at `/`. Explicit -w still wins for both single- and multi-instance launches. Signed-off-by: Nuno Marques --- platforms/posix/src/px4/common/main.cpp | 40 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/platforms/posix/src/px4/common/main.cpp b/platforms/posix/src/px4/common/main.cpp index 5e71548be5..cc6cc6f400 100644 --- a/platforms/posix/src/px4/common/main.cpp +++ b/platforms/posix/src/px4/common/main.cpp @@ -423,6 +423,31 @@ int main(int argc, char **argv) commands_file = "etc/init.d-posix/rcS"; } + // When -d /etc is supplied without -w, derive working_directory + // from data_path's parent so the daemon chdirs into the build dir + // rather than the launch cwd. Otherwise state files (parameters.bson, + // parameters_backup.bson, dataman, log/, the etc symlink) land in + // whatever directory the user happened to launch from — typically + // the repo root, polluting the source tree. + bool working_directory_from_data_path = false; + + if (working_directory.empty() && !data_path.empty()) { + std::string p = data_path; + + if (!p.empty() && (p.back() == '/' || p.back() == '\\')) { + p.pop_back(); + } + + const size_t last_sep = p.find_last_of("/\\"); + const std::string tail = (last_sep == std::string::npos) ? p : p.substr(last_sep + 1); + + if (tail == "etc") { + working_directory = (last_sep == std::string::npos) ? std::string(".") : p.substr(0, last_sep); + working_directory_from_data_path = true; + PX4_INFO("auto work_dir from data_path: %s", working_directory.c_str()); + } + } + // Sister-isolation: when -i N (N >= 1) is given but neither -w nor a // platform default (PX4_INSTALL_PREFIX rootfs, PX4_BINARY_DIR/rootfs) // supplied a working_directory, derive a per-instance "instance_/" @@ -438,9 +463,18 @@ int main(int argc, char **argv) // The primary instance (-i 0 or no -i) keeps the bare-cwd behavior // to match the historical Linux default for single-daemon dev runs; // only -i N >= 1 signals multi-instance intent. Explicit -w still - // wins for either case. - if (instance > 0 && working_directory.empty()) { - working_directory = "instance_" + std::to_string(instance); + // wins for either case. When the work_dir was just derived from + // data_path (above), still apply the per-instance subdir so + // `-i 5 -d /etc` lands at `/instance_5/` rather than + // having all sisters share `/`. + if (instance > 0 && (working_directory.empty() || working_directory_from_data_path)) { + if (working_directory.empty()) { + working_directory = "instance_" + std::to_string(instance); + + } else { + working_directory += "/instance_" + std::to_string(instance); + } + PX4_INFO("auto work_dir: %s (use -w to override)", working_directory.c_str()); }