feat(scheduler-sim-decision-trace): pass the scheduler log path to the simulation driver
Task 4.4: the --logfile path (or the default, now SCHED_DEFAULT_LOG_PATH) reaches the sim driver as an owned copy so the trace file checks can reject the scheduler log. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aa4c43c897
commit
e01ffe4c9c
5 changed files with 118 additions and 2 deletions
|
|
@ -225,7 +225,7 @@
|
|||
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.7, 1.8, 1.9, 1.10, 1.12_
|
||||
- _Depends: 4.2_
|
||||
|
||||
- [ ] 4.4 Pass the scheduler log path to the simulation driver (P)
|
||||
- [x] 4.4 Pass the scheduler log path to the simulation driver (P)
|
||||
- The scheduler's log path goes from the command line through the simulation arguments into the simulation driver, where the trace file checks can read it. Only the simulation driver and the command-line entry point change.
|
||||
- Done when a simulation start test under ASAN shows the driver holds the configured log path, or the default path when none is given.
|
||||
- _Requirements: 8.3_
|
||||
|
|
@ -367,3 +367,4 @@
|
|||
- 4.1: the renderer is `repl_trace_render(rec, units, out1, out2)`, declared in repl_internal.h, in repl_trace_render.c plus repl_trace_render_outcome.c, with a private repl_trace_render.h. It renders once per sink, so the bytes are identical. Amounts use `repl_format_numeric_resource_value` ("8.00 GB" in human mode) and times use `repl_format_ts_human`. Wording where the design is silent is fixed by the golden tests in test_trace_render.c, so 4.2/4.6/6.1 must reuse the renderer, never re-format. Pend-reason arrays may contain NULL entries (capture keeps them); every walk must skip them. The renderer is not yet in sched_sim_isolation_lib or the sim isolation scan list (5.1).
|
||||
- 4.2: the store API is `repl_trace_store_put`, `repl_trace_store_bytes`, `repl_cmd_info_trace` and `repl_trace_store_fini` (an addition; nothing calls it at shutdown yet, so 4.5/4.6/5.2 must). `xce_repl_trace_state_t` (repl_internal.h) holds only the store fields; 4.3 adds next/cur/session flags to it. The 1.3 "file tag" is dropped: `info trace` is console-only (Req 8.1) and emission writes through the session's `cur` settings. `info trace` is not yet routed from repl_cmd_info (5.2). Open (6.2): an `id_list_add` OOM can silently drop array elements from a listing.
|
||||
- 4.3: `trace` is parsed from the raw line by repl_trace.c. The settings are a refcounted REPL-side wrapper around xce_sched_trace_ctl_t (trace.h untouched), held as `next`/`cur` in xce_repl_trace_state_t together with session_in_progress, round_traced and round_flushed. The 1.3 bare-id item is settled: an array-aligned bare id adds both an exact and a whole-array selector, so later elements match; status shows that as `<base>[*]`. A range expands to one exact selector per element. The wrapper frees `ctl.policy_name` on its last release, so 4.6 must heap-allocate it. Nothing frees next/cur at REPL shutdown yet, so 4.5/4.6 must add the shutdown path; routing `trace` from repl.c is 5.2.
|
||||
- 4.4: the driver holds its own copy of the scheduler log path in `sim->log_path` (from `sched_sim_args_t.log_path`, else `SCHED_DEFAULT_LOG_PATH` in sim.h, "/tmp/xce_scheduler.log"). The log is always open in sim mode, so 4.5 can `stat(sim->log_path)` for its dev/ino same-file check.
|
||||
|
|
|
|||
|
|
@ -101,8 +101,22 @@ typedef struct {
|
|||
* style direct core init, matching sched_sim_driver_start()'s own
|
||||
* memset(sim, 0, sizeof(*sim)) default. */
|
||||
bool allocator_thread_live;
|
||||
/* scheduler-sim-decision-trace task 4.4 (Req 8.3): the scheduler log
|
||||
* file this process writes to (--logfile, else SCHED_DEFAULT_LOG_PATH).
|
||||
* An owned copy made by sched_sim_driver_start() and freed by
|
||||
* sched_sim_driver_fini(); the REPL's trace-file checks reject a trace
|
||||
* file that is the same file (dev/inode) as this one. */
|
||||
char* log_path;
|
||||
} xce_sched_sim_driver_t;
|
||||
|
||||
/*
|
||||
* SCHED_DEFAULT_LOG_PATH - the scheduler log file main.c uses when --logfile
|
||||
* is not given. sched_sim_driver_start() falls back to the same path when
|
||||
* `sched_sim_args_t.log_path` is NULL, so the driver always names the file
|
||||
* the scheduler actually logs to.
|
||||
*/
|
||||
#define SCHED_DEFAULT_LOG_PATH "/tmp/xce_scheduler.log"
|
||||
|
||||
/*
|
||||
* SCHED_SIM_START_TS_LATEST - default value for `sched_sim_args_t.sim_start_ts`
|
||||
* when the caller does not pass --sim-start-ts (main.c). AC 13's own
|
||||
|
|
@ -148,6 +162,8 @@ typedef struct {
|
|||
alt_events_path; /* --sim-alt-events FILE (optional, task 11.5) */
|
||||
const char* output_path; /* --sim-output FILE (optional, task 11.5) */
|
||||
bool interactive; /* --interactive / -i (task 12) */
|
||||
const char* log_path; /* --logfile FILE (optional; NULL means
|
||||
* SCHED_DEFAULT_LOG_PATH) */
|
||||
} sched_sim_args_t;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ static void sig_handler(int signo)
|
|||
int main(int argc, char* argv[])
|
||||
{
|
||||
struct arguments arguments;
|
||||
char* logfile = "/tmp/xce_scheduler.log";
|
||||
char* logfile = SCHED_DEFAULT_LOG_PATH;
|
||||
char* loglevel = "info";
|
||||
int logsize = 64 * 1024 * 1024;
|
||||
int logcount = 10;
|
||||
|
|
@ -387,6 +387,7 @@ int main(int argc, char* argv[])
|
|||
sim_args.alt_events_path = arguments.sim_alt_events;
|
||||
sim_args.output_path = arguments.sim_output;
|
||||
sim_args.interactive = (arguments.interactive != 0);
|
||||
sim_args.log_path = logfile;
|
||||
|
||||
rc = sched_sim_driver_run(&sim, &sim_args);
|
||||
if (rc == -ENOSYS) {
|
||||
|
|
|
|||
|
|
@ -671,6 +671,28 @@ int sched_sim_driver_start(xce_sched_sim_driver_t* sim,
|
|||
}
|
||||
}
|
||||
|
||||
/* scheduler-sim-decision-trace task 4.4 (Req 8.3): keep our own copy of
|
||||
* the scheduler log path (argv memory belongs to the caller); with no
|
||||
* --logfile the scheduler logs to SCHED_DEFAULT_LOG_PATH. */
|
||||
sim->log_path = strdup((args->log_path != NULL) ? args->log_path
|
||||
: SCHED_DEFAULT_LOG_PATH);
|
||||
if (sim->log_path == NULL) {
|
||||
ERROR("%s cannot copy the scheduler log path: out of memory",
|
||||
__func__);
|
||||
if (sim->record_file != NULL) {
|
||||
fclose(sim->record_file);
|
||||
sim->record_file = NULL;
|
||||
}
|
||||
if (sim->alt_events_file != NULL) {
|
||||
fclose(sim->alt_events_file);
|
||||
sim->alt_events_file = NULL;
|
||||
}
|
||||
fclose(sim->replay_file);
|
||||
sim->replay_file = NULL;
|
||||
xce_sched_core_fini(&(sim->core));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -753,6 +775,9 @@ void sched_sim_driver_fini(xce_sched_sim_driver_t* sim)
|
|||
sim->replay_file = NULL;
|
||||
}
|
||||
|
||||
free(sim->log_path);
|
||||
sim->log_path = NULL;
|
||||
|
||||
sim_take_alloc_wrappers_(sim, wrappers);
|
||||
xce_sched_core_fini(&(sim->core));
|
||||
sim_free_alloc_wrappers_(wrappers);
|
||||
|
|
|
|||
|
|
@ -588,6 +588,77 @@ static void test_null_arguments_return_einval(void)
|
|||
printf("test_null_arguments_return_einval: PASS\n");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Test 6 (scheduler-sim-decision-trace task 4.4, Req 8.3): the driver */
|
||||
/* holds the scheduler log path it was started with -- its own copy, not */
|
||||
/* the caller's buffer -- or SCHED_DEFAULT_LOG_PATH (the same default */
|
||||
/* main.c logs to without --logfile) when none is given. The trace-file */
|
||||
/* checks compare a trace file against this path. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void test_driver_holds_configured_log_path(void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char log_path[PATH_MAX + 16];
|
||||
uint64_t snapshot_ts = 0;
|
||||
sched_sim_args_t args;
|
||||
xce_sched_sim_driver_t sim;
|
||||
int rc;
|
||||
|
||||
write_valid_fixture(path, sizeof(path), &snapshot_ts, "_logpath");
|
||||
snprintf(log_path, sizeof(log_path), "%s.sched.log", path);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.replay_path = path;
|
||||
args.sim_start_ts = SCHED_SIM_START_TS_LATEST;
|
||||
args.log_path = log_path;
|
||||
|
||||
rc = sched_sim_driver_start(&sim, &args);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(sim.log_path);
|
||||
TEST_ASSERT_EQUAL_STRING(log_path, sim.log_path);
|
||||
TEST_ASSERT_TRUE(sim.log_path != log_path); /* owned copy */
|
||||
|
||||
/* The caller's buffer going away must not change the driver's path. */
|
||||
memset(log_path, 'x', sizeof(log_path) - 1);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN(path, sim.log_path, strlen(path));
|
||||
|
||||
xce_core_set_active_for_logging(NULL);
|
||||
sched_sim_driver_fini(&sim);
|
||||
TEST_ASSERT_NULL(sim.log_path);
|
||||
|
||||
printf("test_driver_holds_configured_log_path: PASS\n");
|
||||
}
|
||||
|
||||
static void test_driver_holds_default_log_path_when_none_given(void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
uint64_t snapshot_ts = 0;
|
||||
sched_sim_args_t args;
|
||||
xce_sched_sim_driver_t sim;
|
||||
int rc;
|
||||
|
||||
write_valid_fixture(path, sizeof(path), &snapshot_ts, "_logdefault");
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.replay_path = path;
|
||||
args.sim_start_ts = SCHED_SIM_START_TS_LATEST;
|
||||
|
||||
rc = sched_sim_driver_start(&sim, &args);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(sim.log_path);
|
||||
TEST_ASSERT_EQUAL_STRING(SCHED_DEFAULT_LOG_PATH, sim.log_path);
|
||||
TEST_ASSERT_EQUAL_STRING("/tmp/xce_scheduler.log", sim.log_path);
|
||||
|
||||
xce_core_set_active_for_logging(NULL);
|
||||
sched_sim_driver_fini(&sim);
|
||||
TEST_ASSERT_NULL(sim.log_path);
|
||||
|
||||
printf("test_driver_holds_default_log_path_when_none_given: PASS\n");
|
||||
}
|
||||
|
||||
/* Test 6 (sched_sim_driver_run() -- design.md's literal entry point --
|
||||
* calling start() then failing loudly with -ENOSYS pending the event loop)
|
||||
* was removed here: the event loop now exists (scheduler-core spec, task
|
||||
|
|
@ -607,6 +678,8 @@ int main(void)
|
|||
RUN_TEST(test_first_message_not_replayheader_fails_cleanly);
|
||||
RUN_TEST(test_missing_replay_file_fails_cleanly);
|
||||
RUN_TEST(test_null_arguments_return_einval);
|
||||
RUN_TEST(test_driver_holds_configured_log_path);
|
||||
RUN_TEST(test_driver_holds_default_log_path_when_none_given);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue