Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
virtme-ng-init: allow virtme-ng to specify a console device
Browse files Browse the repository at this point in the history
If virtme-ng defines a specific virtme_console device in the kernel boot
parameter use that console, instead of trying to autodetect one.

Otherwise try to detect a valid console from /proc/consoles.

This is required to implement kernel log redirection to stderr as
disussed in arighi/virtme-ng#60.

Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
  • Loading branch information
Andrea Righi committed Feb 4, 2024
1 parent b8cba09 commit b1a0f1e
Showing 1 changed file with 40 additions and 1 deletion.
41 changes: 40 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use nix::unistd::sethostname;
use std::env;
use std::fs::{File, OpenOptions};
use std::io::{self, BufRead, BufReader, BufWriter, Write};
use std::os::fd::{AsRawFd, IntoRawFd};
use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
use std::process::{exit, id, Command, Stdio};
Expand Down Expand Up @@ -234,7 +235,7 @@ fn get_kernel_version(show_machine: bool) -> String {
}
}

fn get_active_console() -> Option<String> {
fn get_legacy_active_console() -> Option<String> {
// See Documentation/filesystems/proc.rst for /proc/consoles documentation.
match File::open("/proc/consoles") {
Ok(file) => {
Expand All @@ -256,6 +257,14 @@ fn get_active_console() -> Option<String> {
}
}

fn get_active_console() -> Option<String> {
if let Ok(console) = env::var("virtme_console") {
Some(format!("/dev/{}", console))
} else {
get_legacy_active_console()
}
}

fn configure_hostname() {
if let Ok(hostname) = env::var("virtme_hostname") {
if let Err(err) = sethostname(hostname) {
Expand Down Expand Up @@ -727,6 +736,33 @@ fn clear_virtme_envs() {
}
}

// Redirect a file descriptor to another.
fn redirect_fd(src_fd: i32, dst_fd: i32) {
unsafe {
libc::dup2(src_fd, dst_fd);
}
}

// Redirect stdout/stderr to a new console device.
fn redirect_console(consdev: &str) {
let file = OpenOptions::new()
.write(true)
.open(consdev)
.expect("Failed to open console device");

let fd = file.into_raw_fd();

let stdout = std::io::stdout();
let handle = stdout.lock();
let stdout_fd = handle.as_raw_fd();
redirect_fd(fd, stdout_fd);

let stderr = std::io::stderr();
let handle = stderr.lock();
let stderr_fd = handle.as_raw_fd();
redirect_fd(fd, stderr_fd);
}

fn configure_terminal(consdev: &str, uid: u32) {
if let Ok(params) = env::var("virtme_stty_con") {
let output = Command::new("stty")
Expand All @@ -740,6 +776,9 @@ fn configure_terminal(consdev: &str, uid: u32) {
}
// Set proper user ownership on the default console device
utils::do_chown(&consdev, uid, None).ok();

// Redirect stdout/stderr to the new console device.
redirect_console(&consdev);
}

fn detach_from_terminal(tty_fd: libc::c_int) {
Expand Down

0 comments on commit b1a0f1e

Please sign in to comment.