|
| 1 | +#![no_std] |
| 2 | + |
| 3 | +use core::cmp::min; |
| 4 | +use core::convert::TryInto; |
| 5 | +use core::sync::atomic::{AtomicBool, Ordering}; |
| 6 | + |
| 7 | +use serde::Serialize; |
| 8 | + |
| 9 | +use linux_kernel_module::cstr; |
| 10 | +use linux_kernel_module::sysctl::Sysctl; |
| 11 | +use linux_kernel_module::Mode; |
| 12 | + |
| 13 | +static A: AtomicBool = AtomicBool::new(false); |
| 14 | +static B: AtomicBool = AtomicBool::new(false); |
| 15 | +static C: AtomicBool = AtomicBool::new(false); |
| 16 | + |
| 17 | +struct JsonChrdev; |
| 18 | + |
| 19 | +impl linux_kernel_module::file_operations::FileOperations for JsonChrdev { |
| 20 | + const VTABLE: linux_kernel_module::file_operations::FileOperationsVtable = |
| 21 | + linux_kernel_module::file_operations::FileOperationsVtable::builder::<Self>() |
| 22 | + .read() |
| 23 | + .build(); |
| 24 | + |
| 25 | + fn open() -> linux_kernel_module::KernelResult<Self> { |
| 26 | + Ok(JsonChrdev) |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +impl linux_kernel_module::file_operations::Read for JsonChrdev { |
| 31 | + fn read( |
| 32 | + &self, |
| 33 | + _file: &linux_kernel_module::file_operations::File, |
| 34 | + buf: &mut linux_kernel_module::user_ptr::UserSlicePtrWriter, |
| 35 | + offset: u64, |
| 36 | + ) -> linux_kernel_module::KernelResult<()> { |
| 37 | + let o = Output { |
| 38 | + a: A.load(Ordering::Relaxed), |
| 39 | + b: B.load(Ordering::Relaxed), |
| 40 | + c: C.load(Ordering::Relaxed), |
| 41 | + }; |
| 42 | + let mut s = serde_json_core::to_vec::<typenum::U32, _>(&o) |
| 43 | + .map_err(|_| linux_kernel_module::Error::ENOMEM)?; |
| 44 | + s.push(b'\n') |
| 45 | + .map_err(|_| linux_kernel_module::Error::ENOMEM)?; |
| 46 | + let start = min(offset.try_into()?, s.len()); |
| 47 | + let end = min(start + buf.len(), s.len()); |
| 48 | + buf.write(&s[start..end])?; |
| 49 | + Ok(()) |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +struct JsonSysctlModule { |
| 54 | + _a: Sysctl<&'static AtomicBool>, |
| 55 | + _b: Sysctl<&'static AtomicBool>, |
| 56 | + _c: Sysctl<&'static AtomicBool>, |
| 57 | + _chrdev_registration: linux_kernel_module::chrdev::Registration, |
| 58 | +} |
| 59 | + |
| 60 | +#[derive(Serialize)] |
| 61 | +struct Output { |
| 62 | + a: bool, |
| 63 | + b: bool, |
| 64 | + c: bool, |
| 65 | +} |
| 66 | + |
| 67 | +impl linux_kernel_module::KernelModule for JsonSysctlModule { |
| 68 | + fn init() -> linux_kernel_module::KernelResult<Self> { |
| 69 | + let chrdev_registration = linux_kernel_module::chrdev::builder(cstr!("json"), 0..1)? |
| 70 | + .register_device::<JsonChrdev>() |
| 71 | + .build()?; |
| 72 | + Ok(JsonSysctlModule { |
| 73 | + _a: Sysctl::register(cstr!("json-sysctl"), cstr!("a"), &A, Mode::from_int(0o666))?, |
| 74 | + _b: Sysctl::register(cstr!("json-sysctl"), cstr!("b"), &B, Mode::from_int(0o666))?, |
| 75 | + _c: Sysctl::register(cstr!("json-sysctl"), cstr!("c"), &C, Mode::from_int(0o666))?, |
| 76 | + _chrdev_registration: chrdev_registration, |
| 77 | + }) |
| 78 | + } |
| 79 | +} |
| 80 | + |
| 81 | +linux_kernel_module::kernel_module!( |
| 82 | + JsonSysctlModule, |
| 83 | + author: b"Fish in a Barrel Contributors", |
| 84 | + description: b"Use JSON serialization in kernelspace", |
| 85 | + license: b"GPL" |
| 86 | +); |
0 commit comments