stamparm/maltrail · error

create worker log dir

Error message

create worker log dir

What it means

Panic from `.expect("create worker log dir")` when `std::fs::create_dir_all` cannot create the per-worker temporary logs directory under `$TMPDIR/maltrail-worker-<pid>-<n>`. The worker context needs this directory for LOG_DIR before any worker can run.

Solutions

  1. Check that std::env::temp_dir() is writable and has free space in the failing environment
  2. Remove any non-directory file occupying the target path
  3. Clear stale maltrail-worker-* leftovers in TMPDIR
  4. Run tests with TMPDIR set to a known-writable directory
Defensive patterns

Strategy: validation

Validate before calling

let log_dir = dir.join("logs");
assert!(std::env::temp_dir().is_dir(), "TMPDIR does not exist");
std::fs::create_dir_all(&log_dir).unwrap_or_else(|e| panic!("create worker log dir {}: {e}", log_dir.display()));

Try / catch

match std::fs::create_dir_all(&log_dir) {
    Ok(_) => {},
    Err(e) => panic!("create worker log dir {}: {e}", log_dir.display()),
}

Prevention

When it happens

Trigger: `worker_context()` invoked while the temp filesystem is unwritable or full, the computed temp path collides with an existing non-directory file, or the OS temp dir is unwritable (permissions, read-only mount, sandboxed test runner).

Common situations: CI runners with restricted TMPDIR; TMPDIR pointing to a non-writable path; leftover file at the same path after a prior crashed run; disk-full container.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13). Data as JSON: /api/errors/8a8f96e4c28a01f6. Report an issue: GitHub.

Appendix: source

Thrown at sensor/src/testkit.rs:301

}

impl Drop for Harness {
    fn drop(&mut self) {
        let _ = std::fs::remove_dir_all(&self.dir);
    }
}

/// A `WorkerContext` wired to `registry.slots[id]`, for tests that need to drive the real
/// `worker::run` rather than the packet path alone — worker lifecycle, exit classification and
/// the liveness metrics all live in `run`, not in `process_packet`.
///
/// The temporary directory is deliberately leaked (tests are short-lived and the OS reclaims
/// `TMPDIR`); a `Drop` guard would have to outlive the returned context.
pub fn worker_context(registry: &Arc<crate::metrics::Registry>, id: usize) -> crate::worker::WorkerContext {
    let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
    let dir = std::env::temp_dir().join(format!("maltrail-worker-{}-{}", std::process::id(), counter));
    let log_dir = dir.join("logs");
    std::fs::create_dir_all(&log_dir).expect("create worker log dir");
    let trails_file = dir.join("trails.csv");
    std::fs::write(&trails_file, "").expect("write trails");

    let config_file = dir.join("worker.conf");
    std::fs::write(
        &config_file,
        format!(
            "MONITOR_INTERFACE any\n\
             CAPTURE_BUFFER 1MB\n\
             PROCESS_COUNT 1\n\
             UPDATE_PERIOD 999999999\n\
             DISABLE_CHECK_SUDO true\n\
             USE_CONDENSED_STORAGE false\n\
             USE_HEURISTICS false\n\
             SENSOR_NAME harness\n\
             LOG_DIR {}\n\
             TRAILS_FILE {}\n",
            log_dir.display(),

View on GitHub (pinned to 77cfb06d76)