Skip to content
This repository was archived by the owner on Mar 7, 2021. It is now read-only.

Commit 7de460c

Browse files
committed
WIP: json-sysctl: add a chrdev
Depends on some changes to core that we should land with a bit more consideration
1 parent 6c21d81 commit 7de460c

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

src/chrdev.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
125125
};
126126
let f = &*((*file).private_data as *const T);
127127
// TODO: Pass offset to read()?
128-
match f.read(&mut data) {
128+
match f.read(&mut data, *offset) {
129129
Ok(()) => {
130130
let written = len - data.len();
131131
(*offset) += written as bindings::loff_t;
@@ -191,5 +191,5 @@ pub trait FileOperations: Sync + Sized {
191191
const VTABLE: FileOperationsVtable;
192192

193193
fn open() -> KernelResult<Self>;
194-
fn read(&self, buf: &mut UserSlicePtrWriter) -> KernelResult<()>;
194+
fn read(&self, buf: &mut UserSlicePtrWriter, offset: i64) -> KernelResult<()>;
195195
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod allocator;
99
pub mod bindings;
1010
mod c_types;
1111
pub mod chrdev;
12-
mod error;
12+
pub mod error;
1313
pub mod filesystem;
1414
pub mod printk;
1515
pub mod sysctl;

tests/json-sysctl/src/lib.rs

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,64 @@
22
#![feature(const_str_as_bytes)]
33

44
use core::sync::atomic::{AtomicBool, Ordering};
5+
use core::convert::TryInto;
56

67
use serde::Serialize;
78
use serde_json_core;
89

9-
use linux_kernel_module::sysctl::Sysctl;
10+
use linux_kernel_module::sysctl::{Sysctl, SysctlStorage};
1011
use linux_kernel_module::Mode;
12+
use linux_kernel_module::error;
1113
use linux_kernel_module::println;
14+
use linux_kernel_module::user_ptr::UserSlicePtrWriter;
15+
16+
struct Reference(&'static AtomicBool);
17+
18+
impl SysctlStorage for Reference {
19+
fn store_value(&self, data: &[u8]) -> (usize, error::KernelResult<()>) {
20+
self.0.store_value(&*data)
21+
}
22+
fn read_value(&self, data: &mut UserSlicePtrWriter) -> (usize, error::KernelResult<()>) {
23+
self.0.read_value(&mut *data)
24+
}
25+
}
26+
27+
static A: AtomicBool = AtomicBool::new(false);
28+
static B: AtomicBool = AtomicBool::new(false);
29+
static C: AtomicBool = AtomicBool::new(false);
30+
31+
struct JsonChrdev;
32+
33+
impl linux_kernel_module::chrdev::FileOperations for JsonChrdev {
34+
const VTABLE: linux_kernel_module::chrdev::FileOperationsVtable =
35+
linux_kernel_module::chrdev::FileOperationsVtable::new::<Self>();
36+
37+
fn open() -> linux_kernel_module::KernelResult<Self> {
38+
Ok(JsonChrdev)
39+
}
40+
41+
fn read(
42+
&self,
43+
buf: &mut linux_kernel_module::user_ptr::UserSlicePtrWriter,
44+
offset: i64,
45+
) -> linux_kernel_module::KernelResult<()> {
46+
let o = Output {
47+
a: A.load(Ordering::Relaxed),
48+
b: B.load(Ordering::Relaxed),
49+
c: C.load(Ordering::Relaxed),
50+
};
51+
let mut s = serde_json_core::to_string::<typenum::U32, _>(&o).map_err(|_| error::Error::ENOMEM)?;
52+
s.push_str("\n").map_err(|_| error::Error::ENOMEM)?;
53+
buf.write(&s.into_bytes()[offset.try_into()?..])?;
54+
Ok(())
55+
}
56+
}
1257

1358
struct JsonSysctlModule {
14-
a: Sysctl<AtomicBool>,
15-
b: Sysctl<AtomicBool>,
16-
c: Sysctl<AtomicBool>,
59+
_a: Sysctl<Reference>,
60+
_b: Sysctl<Reference>,
61+
_c: Sysctl<Reference>,
62+
_chrdev_registration: linux_kernel_module::chrdev::Registration,
1763
}
1864

1965
#[derive(Serialize)]
@@ -25,40 +71,33 @@ struct Output {
2571

2672
impl linux_kernel_module::KernelModule for JsonSysctlModule {
2773
fn init() -> linux_kernel_module::KernelResult<Self> {
74+
let chrdev_registration = linux_kernel_module::chrdev::builder("json\x00", 0..1)?
75+
.register_device::<JsonChrdev>()
76+
.build()?;
2877
Ok(JsonSysctlModule {
29-
a: Sysctl::register(
78+
_a: Sysctl::register(
3079
"json-sysctl\x00",
3180
"a\x00",
32-
AtomicBool::new(false),
81+
Reference(&A),
3382
Mode::from_int(0o666),
3483
)?,
35-
b: Sysctl::register(
84+
_b: Sysctl::register(
3685
"json-sysctl\x00",
3786
"b\x00",
38-
AtomicBool::new(false),
87+
Reference(&B),
3988
Mode::from_int(0o666),
4089
)?,
41-
c: Sysctl::register(
90+
_c: Sysctl::register(
4291
"json-sysctl\x00",
4392
"c\x00",
44-
AtomicBool::new(false),
93+
Reference(&C),
4594
Mode::from_int(0o666),
4695
)?,
96+
_chrdev_registration: chrdev_registration,
4797
})
4898
}
4999
}
50100

51-
impl Drop for JsonSysctlModule {
52-
fn drop(&mut self) {
53-
let o = Output {
54-
a: self.a.get().load(Ordering::Relaxed),
55-
b: self.b.get().load(Ordering::Relaxed),
56-
c: self.c.get().load(Ordering::Relaxed),
57-
};
58-
println!("{}", serde_json_core::to_string::<typenum::U32, _>(&o).unwrap());
59-
}
60-
}
61-
62101
linux_kernel_module::kernel_module!(
63102
JsonSysctlModule,
64103
author: "Alex Gaynor and Geoffrey Thomas",

0 commit comments

Comments
 (0)