shadow_rs/host/syscall/handler/
sysinfo.rs

1use linux_api::sysinfo::sysinfo;
2use shadow_shim_helper_rs::emulated_time::EmulatedTime;
3use shadow_shim_helper_rs::syscall_types::ForeignPtr;
4
5use crate::core::worker::Worker;
6use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
7use crate::host::syscall::types::SyscallError;
8
9impl SyscallHandler {
10    log_syscall!(
11        sysinfo,
12        /* rv */ std::ffi::c_int,
13        /* info */ *const linux_api::sysinfo::sysinfo,
14    );
15    pub fn sysinfo(
16        ctx: &mut SyscallContext,
17        info_ptr: ForeignPtr<linux_api::sysinfo::sysinfo>,
18    ) -> Result<(), SyscallError> {
19        // Seconds are needed for uptime.
20        let seconds = Worker::current_time()
21            .unwrap()
22            .duration_since(&EmulatedTime::SIMULATION_START)
23            .as_secs();
24
25        // Get a zeroed struct to make sure we init all fields.
26        let mut info = shadow_pod::zeroed::<sysinfo>();
27
28        // These values are chosen arbitrarily; we don't think it matters too
29        // much, except to maintain determinism. For example, Tor make decisions
30        // about how many circuits to allow to be open (and other OOM settings)
31        // based on available memory.
32        info.uptime = i64::try_from(seconds).unwrap_or(i64::MAX);
33        info.loads[0] = 1;
34        info.loads[1] = 1;
35        info.loads[2] = 1;
36        info.totalram = 32;
37        info.freeram = 24;
38        info.sharedram = 4;
39        info.bufferram = 4;
40        info.totalswap = 0;
41        info.freeswap = 0;
42        info.procs = 100;
43        info.totalhigh = 4;
44        info.freehigh = 3;
45        info.mem_unit = 1024 * 1024 * 1024; // GiB
46
47        // Write the result to plugin memory.
48        ctx.objs
49            .process
50            .memory_borrow_mut()
51            .write(info_ptr, &info)?;
52        Ok(())
53    }
54}