| 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 */ |
| 14 | static const char *nightmare_selector; |
| 15 | static fx32_32_t nightmare_intensity = NIGHTMARE_INTENSITY_SENTINEL; |
| 16 | static uint64_t nightmare_seed; |
| 17 | static enum nightmare_seed_mode nightmare_seed_mode = NIGHTMARE_SEED_SPLIT; |
| 18 | static time_ns_t nightmare_duration_ns; |
| 19 | static time_ns_t nightmare_drain_grace_ns = SECONDS_TO_NS(20); |
| 20 | static time_ns_t nightmare_stat_interval_ns = SECONDS_TO_NS(5); |
| 21 | static time_ns_t nightmare_stall_threshold_ns = MS_TO_NS(3000); |
| 22 | static enum nightmare_on_stall nightmare_on_stall = NIGHTMARE_ON_STALL_REPORT; |
| 23 | static uint64_t nightmare_boot_index; |
| 24 | static const char *nightmare_campaign_id; |
| 25 | |
| 26 | CMDLINE_DECLARE_VAR( |
| 27 | nightmare_root, nightmare_selector, .name = "nightmare" , |
| 28 | .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING), |
| 29 | .desc = "Select the single nightmare subject for this boot" ); |
| 30 | |
| 31 | CMDLINE_CHILDREN_DECLARE( |
| 32 | nightmare_root, |
| 33 | CMDLINE_INNER_FX(intensity, nightmare_intensity, |
| 34 | .desc = "Nightmare intensity in [0,1]" , |
| 35 | .range = RANGE(0, FX_ONE)), |
| 36 | CMDLINE_INNER_VAR(seed, nightmare_seed, .desc = "Nightmare seed" ), |
| 37 | CMDLINE_INNER_VAR(seed_mode, nightmare_seed_mode, |
| 38 | .desc = "Seed application mode" , |
| 39 | .mappings = CMDLINE_MAPPINGS( |
| 40 | CMDLINE_MAP("split" , NIGHTMARE_SEED_SPLIT), |
| 41 | CMDLINE_MAP("seedful" , NIGHTMARE_SEED_SEEDFUL), |
| 42 | CMDLINE_MAP("seedless" , NIGHTMARE_SEED_SEEDLESS))), |
| 43 | CMDLINE_INNER_DURATION(duration_ms, nightmare_duration_ns, |
| 44 | .desc = "Soft runtime budget" ), |
| 45 | CMDLINE_INNER_DURATION(drain_grace_ms, nightmare_drain_grace_ns, |
| 46 | .desc = "Soft-to-hard deadline grace" ), |
| 47 | CMDLINE_INNER_DURATION(stat_interval_ms, nightmare_stat_interval_ns, |
| 48 | .desc = "Heartbeat record cadence" ), |
| 49 | CMDLINE_INNER_DURATION(stall_threshold_ms, nightmare_stall_threshold_ns, |
| 50 | .desc = "Liveness stall threshold duration" , |
| 51 | .range = RANGE(MS_TO_NS(100), TIME_NS_MAX)), |
| 52 | CMDLINE_INNER_VAR(on_stall, nightmare_on_stall, .desc = "Stall response" , |
| 53 | .mappings = CMDLINE_MAPPINGS( |
| 54 | CMDLINE_MAP("report" , NIGHTMARE_ON_STALL_REPORT), |
| 55 | CMDLINE_MAP("crash" , NIGHTMARE_ON_STALL_CRASH), |
| 56 | CMDLINE_MAP("snapshot" , NIGHTMARE_ON_STALL_CRASH), |
| 57 | CMDLINE_MAP("terminal" , NIGHTMARE_ON_STALL_CRASH))), |
| 58 | CMDLINE_INNER_VAR(boot_index, nightmare_boot_index, |
| 59 | .desc = "Opaque campaign boot index" ), |
| 60 | CMDLINE_INNER_STRING(campaign_id, nightmare_campaign_id, |
| 61 | .desc = "Opaque campaign identifier" ), |
| 62 | CMDLINE_INNER(perturb, |
| 63 | .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING, |
| 64 | CMDLINE_TYPE_LIST), |
| 65 | .desc = "Comma-separated perturbation services" )); |
| 66 | |
| 67 | void nightmare_cmdline_get(struct nightmare_cmdline_config *config) { |
| 68 | *config = (struct nightmare_cmdline_config){ |
| 69 | .selector = nightmare_selector, |
| 70 | .intensity = nightmare_intensity, |
| 71 | .seed = nightmare_seed, |
| 72 | .seed_present = |
| 73 | CMDLINE_CHILD(nightmare_root, seed)->status == CMDLINE_ENTRY_FOUND, |
| 74 | .seed_mode = nightmare_seed_mode, |
| 75 | .duration_ms = NS_TO_MS(nightmare_duration_ns), |
| 76 | .drain_grace_ms = NS_TO_MS(nightmare_drain_grace_ns), |
| 77 | .stat_interval_ms = NS_TO_MS(nightmare_stat_interval_ns), |
| 78 | .stall_threshold_ms = NS_TO_MS(nightmare_stall_threshold_ns), |
| 79 | .on_stall = nightmare_on_stall, |
| 80 | .boot_index = nightmare_boot_index, |
| 81 | .campaign_id = nightmare_campaign_id, |
| 82 | }; |
| 83 | |
| 84 | struct cmdline_entry *perturb = CMDLINE_CHILD(nightmare_root, perturb); |
| 85 | if (perturb->status != CMDLINE_ENTRY_FOUND) |
| 86 | return; |
| 87 | |
| 88 | if (perturb->value.type == CMDLINE_TYPE_LIST) { |
| 89 | config->perturb_present = |
| 90 | CMDLINE_EXTRACT(&perturb->value, config->perturb) == ERR_OK; |
| 91 | return; |
| 92 | } |
| 93 | |
| 94 | if (perturb->value.type == CMDLINE_TYPE_STRING) { |
| 95 | config->perturb = (struct cmdline_list){ |
| 96 | .count = 1, |
| 97 | .items = &perturb->value, |
| 98 | }; |
| 99 | config->perturb_present = true; |
| 100 | } |
| 101 | } |
| 102 | |