Skip to content

Commit 6ddd759

Browse files
Merge pull request #152 from yunwei37/master
fix regression/rlimit-open-files.exe in libc-test
2 parents ba4d213 + 2c7e392 commit 6ddd759

File tree

10 files changed

+109
-24
lines changed

10 files changed

+109
-24
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Cargo.lock
55
/rootfs
66
/prebuilt/linux/alpine*
77
.idea
8+
scripts/linux/test-result.txt

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Run all (non-panicked) core-tests for CI:
8383

8484
```sh
8585
pip3 install pexpect
86-
cd script && python3 core-tests.py
86+
cd scripts && python3 core-tests.py
8787
# Check `zircon/test-result.txt` for results.
8888
```
8989

@@ -92,7 +92,7 @@ Run Linux musl libc-tests for CI:
9292

9393
```sh
9494
make rootfs && make libc-test
95-
cd script && python3 libc-tests.py
95+
cd scripts && python3 libc-tests.py
9696
# Check `linux/test-result.txt` for results.
9797
```
9898

linux-loader/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ mod tests {
169169
fs::read("../rootfs/testtruncate").unwrap();
170170
}
171171

172+
#[async_std::test]
173+
async fn test_flock() {
174+
assert_eq!(test("/bin/busybox flock 0").await, 0);
175+
}
176+
172177
// syscall unit test
173178

174179
#[async_std::test]

linux-object/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
//! Linux kernel objects
22
33
#![no_std]
4-
#![deny(warnings, unsafe_code, unused_must_use, unreachable_patterns)]
4+
#![deny(
5+
warnings,
6+
unsafe_code,
7+
unused_must_use,
8+
unreachable_patterns,
9+
missing_docs
10+
)]
511
#![feature(bool_to_option)]
612

713
extern crate alloc;

linux-object/src/process.rs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::sync::atomic::AtomicI32;
1212
use hashbrown::HashMap;
1313
use kernel_hal::VirtAddr;
1414
use rcore_fs::vfs::{FileSystem, INode};
15-
use spin::Mutex;
15+
use spin::*;
1616
use zircon_object::{
1717
object::{KernelObject, KoID, Signal},
1818
signal::Futex,
@@ -143,6 +143,8 @@ struct LinuxProcessInner {
143143
///
144144
/// Omit leading '/'.
145145
current_working_directory: String,
146+
/// file open number limit
147+
file_limit: RLimit,
146148
/// Opened files
147149
files: HashMap<FileDesc, Arc<dyn FileLike>>,
148150
/// Futexes
@@ -151,6 +153,25 @@ struct LinuxProcessInner {
151153
children: HashMap<KoID, Arc<Process>>,
152154
}
153155

156+
/// resource limit
157+
#[repr(C)]
158+
#[derive(Debug, Copy, Clone)]
159+
pub struct RLimit {
160+
/// soft limit
161+
pub cur: u64,
162+
/// hard limit
163+
pub max: u64,
164+
}
165+
166+
impl Default for RLimit {
167+
fn default() -> Self {
168+
RLimit {
169+
cur: 1024,
170+
max: 1024,
171+
}
172+
}
173+
}
174+
154175
/// process exit code defination
155176
pub type ExitCode = i32;
156177

@@ -209,16 +230,40 @@ impl LinuxProcess {
209230

210231
/// Add a file to the file descriptor table.
211232
pub fn add_file(&self, file: Arc<dyn FileLike>) -> LxResult<FileDesc> {
212-
let mut inner = self.inner.lock();
233+
let inner = self.inner.lock();
213234
let fd = inner.get_free_fd();
214-
inner.files.insert(fd, file);
215-
Ok(fd)
235+
self.insert_file(inner, fd, file)
216236
}
217237

218238
/// Add a file to the file descriptor table at given `fd`.
219-
pub fn add_file_at(&self, fd: FileDesc, file: Arc<dyn FileLike>) {
239+
pub fn add_file_at(&self, fd: FileDesc, file: Arc<dyn FileLike>) -> LxResult<FileDesc> {
240+
let inner = self.inner.lock();
241+
self.insert_file(inner, fd, file)
242+
}
243+
244+
/// insert a file and fd into the file descriptor table
245+
fn insert_file(
246+
&self,
247+
mut inner: MutexGuard<LinuxProcessInner>,
248+
fd: FileDesc,
249+
file: Arc<dyn FileLike>,
250+
) -> LxResult<FileDesc> {
251+
if inner.files.len() < inner.file_limit.cur as usize {
252+
inner.files.insert(fd, file);
253+
Ok(fd)
254+
} else {
255+
Err(LxError::EMFILE)
256+
}
257+
}
258+
259+
/// get and set file limit number
260+
pub fn file_limit(&self, new_limit: Option<RLimit>) -> RLimit {
220261
let mut inner = self.inner.lock();
221-
inner.files.insert(fd, file);
262+
let old = inner.file_limit;
263+
if let Some(limit) = new_limit {
264+
inner.file_limit = limit;
265+
}
266+
old
222267
}
223268

224269
/// Get the `File` with given `fd`.

linux-object/src/sync/event_bus.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//! Event bus implement
2+
//!
3+
//! An Eventbus is a mechanism that allows different components to communicate with each other without knowing about each other.
14
use alloc::boxed::Box;
25
use alloc::{sync::Arc, vec::Vec};
36
use bitflags::bitflags;
@@ -10,45 +13,62 @@ use spin::Mutex;
1013

1114
bitflags! {
1215
#[derive(Default)]
16+
/// event bus Event flags
1317
pub struct Event: u32 {
14-
/// File
18+
/// File: is readable
1519
const READABLE = 1 << 0;
20+
/// File: is writeable
1621
const WRITABLE = 1 << 1;
22+
/// File: has error
1723
const ERROR = 1 << 2;
24+
/// File: is closed
1825
const CLOSED = 1 << 3;
1926

20-
/// Process
27+
/// Process: is Quit
2128
const PROCESS_QUIT = 1 << 10;
29+
/// Process: child process is Quit
2230
const CHILD_PROCESS_QUIT = 1 << 11;
31+
/// Process: received signal
2332
const RECEIVE_SIGNAL = 1 << 12;
2433

25-
/// Semaphore
34+
/// Semaphore: is removed
2635
const SEMAPHORE_REMOVED = 1 << 20;
36+
/// Semaphore: can acquired
2737
const SEMAPHORE_CAN_ACQUIRE = 1 << 21;
2838
}
2939
}
3040

41+
/// handler of event in the event bus
3142
pub type EventHandler = Box<dyn Fn(Event) -> bool + Send>;
3243

44+
/// event bus struct
3345
#[derive(Default)]
3446
pub struct EventBus {
47+
/// event type
3548
event: Event,
49+
/// EventBus callback
3650
callbacks: Vec<EventHandler>,
3751
}
3852

3953
impl EventBus {
54+
/// create an event bus
4055
pub fn new() -> Arc<Mutex<Self>> {
4156
Arc::new(Mutex::new(Self::default()))
4257
}
4358

59+
/// set event flag
4460
pub fn set(&mut self, set: Event) {
4561
self.change(Event::empty(), set);
4662
}
4763

64+
/// clear all event flag
4865
pub fn clear(&mut self, set: Event) {
4966
self.change(set, Event::empty());
5067
}
5168

69+
/// change event flag
70+
/// - `reset`: flag to remove
71+
/// - `set`: flag to insert
5272
pub fn change(&mut self, reset: Event, set: Event) {
5373
let orig = self.event;
5474
let mut new = self.event;
@@ -60,19 +80,23 @@ impl EventBus {
6080
}
6181
}
6282

83+
/// push a EventHandler into the callback vector
6384
pub fn subscribe(&mut self, callback: EventHandler) {
6485
self.callbacks.push(callback);
6586
}
6687

88+
/// get the callback vector length
6789
pub fn get_callback_len(&self) -> usize {
6890
self.callbacks.len()
6991
}
7092
}
7193

94+
/// wait for a event async
7295
pub fn wait_for_event(bus: Arc<Mutex<EventBus>>, mask: Event) -> impl Future<Output = Event> {
7396
EventBusFuture { bus, mask }
7497
}
7598

99+
/// EventBus future for async
76100
#[must_use = "future does nothing unless polled/`await`-ed"]
77101
struct EventBusFuture {
78102
bus: Arc<Mutex<EventBus>>,

linux-object/src/sync/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! Useful synchronization primitives.
12
pub use self::event_bus::*;
23

34
mod event_bus;

linux-syscall/src/file/fd.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,17 @@ impl Syscall<'_> {
7070
// close fd2 first if it is opened
7171
let _ = proc.close_file(fd2);
7272
let file_like = proc.get_file_like(fd1)?;
73-
proc.add_file_at(fd2, file_like);
73+
let fd2 = proc.add_file_at(fd2, file_like)?;
74+
Ok(fd2.into())
75+
}
76+
77+
/// create a copy of the file descriptor fd, and uses the lowest-numbered unused descriptor for the new descriptor.
78+
pub fn sys_dup(&self, fd1: FileDesc) -> SysResult {
79+
info!("dup: from {:?}", fd1);
80+
let proc = self.linux_process();
81+
82+
let file_like = proc.get_file_like(fd1)?;
83+
let fd2 = proc.add_file(file_like)?;
7484
Ok(fd2.into())
7585
}
7686

linux-syscall/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ impl Syscall<'_> {
108108
Sys::FCHOWN => self.unimplemented("fchown", Ok(0)),
109109
Sys::FCHOWNAT => self.unimplemented("fchownat", Ok(0)),
110110
Sys::FACCESSAT => self.sys_faccessat(a0.into(), a1.into(), a2, a3),
111+
Sys::DUP => self.sys_dup(a0.into()),
111112
Sys::DUP3 => self.sys_dup2(a0.into(), a1.into()), // TODO: handle `flags`
112113
Sys::PIPE2 => self.sys_pipe(a0.into()), // TODO: handle `flags`
113114
Sys::UTIMENSAT => self.sys_utimensat(a0.into(), a1.into(), a2.into(), a3),

linux-syscall/src/misc.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ impl Syscall<'_> {
9292
"prlimit64: pid: {}, resource: {}, new_limit: {:x?}, old_limit: {:x?}",
9393
pid, resource, new_limit, old_limit
9494
);
95+
let proc = self.linux_process();
9596
match resource {
9697
RLIMIT_STACK => {
9798
old_limit.write_if_not_null(RLimit {
@@ -101,10 +102,8 @@ impl Syscall<'_> {
101102
Ok(0)
102103
}
103104
RLIMIT_NOFILE => {
104-
old_limit.write_if_not_null(RLimit {
105-
cur: 1024,
106-
max: 1024,
107-
})?;
105+
let new_limit = new_limit.read_if_not_null()?;
106+
old_limit.write_if_not_null(proc.file_limit(new_limit))?;
108107
Ok(0)
109108
}
110109
RLIMIT_RSS | RLIMIT_AS => {
@@ -156,13 +155,6 @@ const RLIMIT_RSS: usize = 5;
156155
const RLIMIT_NOFILE: usize = 7;
157156
const RLIMIT_AS: usize = 9;
158157

159-
#[repr(C)]
160-
#[derive(Debug, Default)]
161-
pub struct RLimit {
162-
cur: u64, // soft limit
163-
max: u64, // hard limit
164-
}
165-
166158
/// sysinfo() return information sturct
167159
#[repr(C)]
168160
#[derive(Debug, Default)]

0 commit comments

Comments
 (0)