Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.

Commit ccfa066

Browse files
committed
Improve handling of errors while cmdline parsing
Depending on the commandline formatting, there was a case where this resulted in an endless loop in processing the command line. Errors were printed using the `error!` macro, that used the logger functionality before it was setup. We introduce an error return value for parsing the commandline. It returns an error whenever there was something wrong with the command line that could lead to a misconfiguration of the runtime parameters. For that we have two error values: - InvalidCmdLineOptions indicating the command line parsed fine, but the selected option are not supported - MalformedCmdLine indicating that there were issues with parsing the commandline that would have led to skipped arguments. Signed-off-by: Reto Achermann <achreto@gmail.com>
1 parent dd84480 commit ccfa066

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

kernel/src/arch/x86_64/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ fn _start(argc: isize, _argv: *const *const u8) -> isize {
249249

250250
// Very early init:
251251
sprint!("\r\n");
252+
sprint!("NRK booting on x86_64...\r\n");
252253
enable_sse();
253254
enable_fsgsbase();
254255
unsafe {
@@ -276,7 +277,14 @@ fn _start(argc: isize, _argv: *const *const u8) -> isize {
276277
// memory for us
277278
unsafe { transmute::<u64, &'static KernelArgs>(argc as u64) };
278279
// Parse the command line arguments:
279-
let cmdline = CommandLineArguments::from_str(kernel_args.command_line);
280+
let cmdline = match CommandLineArguments::from_str(kernel_args.command_line) {
281+
Ok(cmdline) => cmdline,
282+
Err(err) => {
283+
sprint!("Parsing the commandline failed ({err}). Halting...\r\n");
284+
halt();
285+
}
286+
};
287+
280288
// Initialize cmdline arguments as global
281289
crate::CMDLINE.call_once(move || cmdline);
282290
// Initialize kernel arguments as global

kernel/src/cmdline.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use logos::Logos;
1212
use kpi::system::MachineId;
1313

1414
use crate::arch::memory::paddr_to_kernel_vaddr;
15+
use crate::error::{KError, KResult};
1516
use crate::memory::PAddr;
1617

1718
/// Definition to parse the kernel command-line arguments.
@@ -148,7 +149,9 @@ impl CommandLineArguments {
148149
/// Parse command line argument and initialize the logging infrastructure.
149150
///
150151
/// Example: If args is './kernel log=trace' -> sets level to Level::Trace
151-
pub(crate) fn from_str(args: &'static str) -> Self {
152+
pub(crate) fn from_str(args: &'static str) -> KResult<Self> {
153+
use klogger::sprint;
154+
152155
// The args argument will be a physical address slice that
153156
// goes away once we switch to a process address space
154157
// make sure we translate it into a kernel virtual address:
@@ -217,8 +220,8 @@ impl CommandLineArguments {
217220
prev = CmdToken::Error;
218221
}
219222
_ => {
220-
error!("Invalid cmd arguments: {} (skipped {})", args, slice);
221-
continue;
223+
sprint!("Invalid cmd arguments: {} (skipped {})\r\n", args, slice);
224+
return Err(KError::InvalidCmdLineOptions);
222225
}
223226
},
224227
CmdToken::KVSeparator => {
@@ -230,8 +233,8 @@ impl CommandLineArguments {
230233
&& prev != CmdToken::MachineId
231234
&& prev != CmdToken::Workers
232235
{
233-
error!("Malformed args (unexpected equal sign) in {}", args);
234-
continue;
236+
sprint!("Malformed args (unexpected equal sign) in {}\r\n", args);
237+
return Err(KError::MalformedCmdLine);
235238
}
236239
}
237240
CmdToken::LiteralString => {
@@ -268,35 +271,41 @@ impl CommandLineArguments {
268271
prev = CmdToken::Error;
269272
}
270273
_ => {
271-
error!("Invalid cmd arguments: {} (skipped {})", args, slice);
274+
sprint!("Invalid cmd arguments: {} (skipped {})\r\n", args, slice);
272275
continue;
273276
}
274277
}
275278
}
276279
CmdToken::Error => {
277-
error!("Ignored '{}' while parsing cmd args: {}", slice, args);
278-
continue;
280+
sprint!(
281+
"Malformed commandline! Encoutered '{}' while parsing cmd args: {}\r\n",
282+
slice,
283+
args
284+
);
285+
return Err(KError::MalformedCmdLine);
279286
}
280287
}
281288
}
282289

283290
#[cfg(not(feature = "shmem"))]
284291
{
285292
if parsed_args.mode != Mode::Native && parsed_args.transport == Transport::Shmem {
286-
panic!("kernel feature 'shmem' must be present to use shmem as an RPC transport");
293+
sprint!("kernel feature 'shmem' must be present to use shmem as an RPC transport");
294+
return Err(KError::InvalidCmdLineOptions);
287295
}
288296
}
289297

290298
#[cfg(not(feature = "ethernet"))]
291299
{
292300
if parsed_args.mode != Mode::Native && parsed_args.transport == Transport::Ethernet {
293-
panic!(
301+
sprint!(
294302
"kernel feature 'ethernet' must be present to use ethernet as an RPC transport"
295303
);
304+
return Err(KError::InvalidCmdLineOptions);
296305
}
297306
}
298307

299-
parsed_args
308+
Ok(parsed_args)
300309
}
301310
}
302311

kernel/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ pub enum KError {
173173
TryFromIntError,
174174
/// The provided file-descriptor value was too big (>= MAX_FILES_PER_PROCESS)
175175
FileDescriptorTooLarge,
176+
/// The command line was malformed
177+
MalformedCmdLine,
178+
/// The command line had invalid option configurations
179+
InvalidCmdLineOptions,
176180
/// Rackscale: Unable to convert message ID to valid RPC type (faulty message?)
177181
InvalidRpcType,
178182
/// Rackscale: Unable to perform DCM transaction (faulty message?)

0 commit comments

Comments
 (0)