1#include "internal.h"
2
3#include <cmdline.h>
4#include <math/range.h>
5#include <string.h>
6#include <time/time.h>
7
8/* This is a necessary evil, as the command line will
9 * pass in nanoseconds, and we map to milliseconds in the config
10 *
11 * It also helps us expand the command line options without
12 * bloating up a config file, if said options are operated
13 * upon to arrive at the final value in the config */
14static const char *nightmare_selector;
15static fx32_32_t nightmare_intensity = NIGHTMARE_INTENSITY_SENTINEL;
16static uint64_t nightmare_seed;
17static enum nightmare_seed_mode nightmare_seed_mode = NIGHTMARE_SEED_SPLIT;
18static time_ns_t nightmare_duration_ns;
19static time_ns_t nightmare_drain_grace_ns = SECONDS_TO_NS(20);
20static time_ns_t nightmare_stat_interval_ns = SECONDS_TO_NS(5);
21static time_ns_t nightmare_stall_threshold_ns = MS_TO_NS(3000);
22static enum test_on_stall nightmare_on_stall = TEST_ON_STALL_REPORT;
23static uint64_t nightmare_boot_index;
24static const char *nightmare_campaign_id;
25
26CMDLINE_DEFINE_VAR(nightmare_root, nightmare_selector, .name = "nightmare",
27 .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING),
28 .desc = "Select the single nightmare subject for this boot");
29
30CMDLINE_CHILDREN_DEFINE(
31 nightmare_root,
32 CMDLINE_INNER_FX(intensity, nightmare_intensity,
33 .desc = "Nightmare intensity in [0,1]",
34 .range = RANGE(0, FX_ONE)),
35 CMDLINE_INNER_VAR(seed, nightmare_seed, .desc = "Nightmare seed"),
36 CMDLINE_INNER_VAR(seed_mode, nightmare_seed_mode,
37 .desc = "Seed application mode",
38 .mappings = CMDLINE_MAPPINGS(
39 CMDLINE_MAP("split", NIGHTMARE_SEED_SPLIT),
40 CMDLINE_MAP("seedful", NIGHTMARE_SEED_SEEDFUL),
41 CMDLINE_MAP("seedless", NIGHTMARE_SEED_SEEDLESS))),
42 CMDLINE_INNER_DURATION(duration_ms, nightmare_duration_ns,
43 .desc = "Soft runtime budget"),
44 CMDLINE_INNER_DURATION(drain_grace_ms, nightmare_drain_grace_ns,
45 .desc = "Soft-to-hard deadline grace"),
46 CMDLINE_INNER_DURATION(stat_interval_ms, nightmare_stat_interval_ns,
47 .desc = "Heartbeat record cadence"),
48 CMDLINE_INNER_DURATION(stall_threshold_ms, nightmare_stall_threshold_ns,
49 .desc = "Liveness stall threshold duration",
50 .range = RANGE(MS_TO_NS(100), TIME_NS_MAX)),
51 CMDLINE_INNER_VAR(on_stall, nightmare_on_stall, .desc = "Stall response",
52 .mappings = CMDLINE_MAPPINGS(
53 CMDLINE_MAP("report", TEST_ON_STALL_REPORT),
54 CMDLINE_MAP("crash", TEST_ON_STALL_CRASH),
55 CMDLINE_MAP("snapshot", TEST_ON_STALL_CRASH),
56 CMDLINE_MAP("terminal", TEST_ON_STALL_CRASH))),
57 CMDLINE_INNER_VAR(boot_index, nightmare_boot_index,
58 .desc = "Opaque campaign boot index"),
59 CMDLINE_INNER_STRING(campaign_id, nightmare_campaign_id,
60 .desc = "Opaque campaign identifier"),
61 CMDLINE_INNER(perturb,
62 .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING,
63 CMDLINE_TYPE_LIST),
64 .desc = "Comma-separated perturbation services"));
65
66void nightmare_cmdline_get(struct nightmare_cmdline_config *config) {
67 *config = (struct nightmare_cmdline_config){
68 .selector = nightmare_selector,
69 .intensity = nightmare_intensity,
70 .seed = nightmare_seed,
71 .seed_present =
72 CMDLINE_CHILD(nightmare_root, seed)->status == CMDLINE_ENTRY_FOUND,
73 .seed_mode = nightmare_seed_mode,
74 .duration_ms = NS_TO_MS(nightmare_duration_ns),
75 .drain_grace_ms = NS_TO_MS(nightmare_drain_grace_ns),
76 .stat_interval_ms = NS_TO_MS(nightmare_stat_interval_ns),
77 .stall_threshold_ms = NS_TO_MS(nightmare_stall_threshold_ns),
78 .on_stall = nightmare_on_stall,
79 .boot_index = nightmare_boot_index,
80 .campaign_id = nightmare_campaign_id,
81 };
82
83 struct cmdline_entry *perturb = CMDLINE_CHILD(nightmare_root, perturb);
84 if (perturb->status != CMDLINE_ENTRY_FOUND)
85 return;
86
87 if (perturb->value.type == CMDLINE_TYPE_LIST) {
88 config->perturb_present =
89 CMDLINE_EXTRACT(&perturb->value, config->perturb) == ERR_OK;
90 return;
91 }
92
93 if (perturb->value.type == CMDLINE_TYPE_STRING) {
94 config->perturb = (struct cmdline_list){
95 .count = 1,
96 .items = &perturb->value,
97 };
98 config->perturb_present = true;
99 }
100}
101