in resctl-bench/src/bench/iocost_qos.rs [315:389]
fn run_one(
rctx: &mut RunCtx,
sjob: &mut StorageJob,
pjob: &mut ProtectionJob,
qos_cfg: &IoCostQoSCfg,
nr_stor_retries: u32,
) -> Result<IoCostQoSRecordRun> {
let started_at = unix_now();
// Run the storage bench.
let mut tries = 0;
let rec_json = loop {
tries += 1;
qos_cfg.apply(rctx)?;
let r = sjob.clone().run(rctx.disable_zswap());
rctx.stop_agent();
match r {
Ok(r) => break r,
Err(e) => {
if prog_exiting() {
return Err(e);
}
if tries > nr_stor_retries {
return Err(e.context("Storage benchmark failed too many times"));
}
warn!(
"iocost-qos: Storage benchmark failed ({:#}), retrying...",
&e
);
}
}
};
// Acquire storage record and result. We need the result too because
// it determines how the protection benchmark is run.
let stor_rec = parse_json_value_or_dump::<StorageRecord>(rec_json.clone())
.context("Parsing storage record")?;
let stor_res = parse_json_value_or_dump::<StorageResult>(
sjob.study(rctx, rec_json)
.context("Studying storage record")?,
)
.context("Parsing storage result")?;
// Run the protection bench with the hashd params committed by the
// storage bench.
qos_cfg.apply(rctx)?;
Self::set_prot_size_range(pjob, &stor_rec, &stor_res);
let out = pjob.run(rctx.disable_zswap());
rctx.stop_agent();
let prot_rec = match out {
Ok(r) => parse_json_value_or_dump::<ProtectionRecord>(r)
.context("Parsing protection record")
.unwrap(),
Err(e) => {
warn!("iocost-qos: Protection benchmark failed ({:#})", &e);
ProtectionRecord::default()
}
};
let qos = if qos_cfg.ovr.off {
None
} else {
Some(rctx.access_agent_files(|af| af.bench.data.iocost.qos.clone()))
};
Ok(IoCostQoSRecordRun {
period: (started_at, unix_now()),
ovr: qos_cfg.ovr.clone(),
qos,
stor: stor_rec,
prot: prot_rec,
})
}