fix(px4): contain instance state under build dir when -d points to <root>/etc

When a user launches `px4 -i N -d <build>/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_<N>` to the derived path,
keeping multi-instance state in `<build>/instance_N/` rather than
overwriting the primary instance's state at `<build>/`.

Explicit -w still wins for both single- and multi-instance launches.

Signed-off-by: Nuno Marques <n.marques21@hotmail.com>
This commit is contained in:
Nuno Marques
2026-05-07 15:53:56 -07:00
parent 35df4aab62
commit 3ca6829219
+37 -3
View File
@@ -423,6 +423,31 @@ int main(int argc, char **argv)
commands_file = "etc/init.d-posix/rcS";
}
// When -d <path>/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_<N>/"
@@ -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 <build>/etc` lands at `<build>/instance_5/` rather than
// having all sisters share `<build>/`.
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());
}