Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to simplify logging a bit #3

Merged
merged 4 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use std::path::{Path, PathBuf};
use std::process::{exit, id, Command, Stdio};
use std::thread;
use std::time::Duration;

#[macro_use]
mod utils;

#[cfg(test)]
Expand Down Expand Up @@ -198,7 +200,7 @@ const USER_SCRIPT: &str = "/tmp/.virtme-script";

fn check_init_pid() {
if id() != 1 {
utils::log("must be run as PID 1");
log!("must be run as PID 1");
exit(1);
}
}
Expand All @@ -208,7 +210,7 @@ fn poweroff() {
libc::sync();
}
if let Err(err) = reboot::reboot(reboot::RebootMode::RB_POWER_OFF) {
utils::log(&format!("error powering off: {}", err));
log!("error powering off: {}", err);
exit(1);
}
exit(0);
Expand Down Expand Up @@ -248,7 +250,7 @@ fn get_active_console() -> Option<String> {
None
}
Err(error) => {
utils::log(&format!("failed to open /proc/consoles: {}", error));
log!("failed to open /proc/consoles: {}", error);
None
}
}
Expand All @@ -257,10 +259,10 @@ fn get_active_console() -> Option<String> {
fn configure_hostname() {
if let Ok(hostname) = env::var("virtme_hostname") {
if let Err(err) = sethostname(hostname) {
utils::log(&format!("failed to change hostname: {}", err));
log!("failed to change hostname: {}", err);
}
} else {
utils::log("virtme_hostname is not defined");
log!("virtme_hostname is not defined");
}
}

Expand Down Expand Up @@ -321,7 +323,7 @@ fn override_system_files() {
fn set_cwd() {
if let Ok(dir) = env::var("virtme_chdir") {
if let Err(err) = env::set_current_dir(dir) {
utils::log(&format!("error changing directory: {}", err));
log!("error changing directory: {}", err);
}
}
}
Expand Down Expand Up @@ -450,14 +452,14 @@ fn disable_uevent_helper() {

if Path::new(uevent_helper_path).exists() {
// This kills boot performance.
utils::log("you have CONFIG_UEVENT_HELPER on, turn it off");
log!("you have CONFIG_UEVENT_HELPER on, turn it off");
let mut file = OpenOptions::new().write(true).open(uevent_helper_path).ok();
match &mut file {
Some(file) => {
write!(file, "").ok();
}
None => {
utils::log(&format!("error opening {}", uevent_helper_path));
log!("error opening {}", uevent_helper_path);
}
}
}
Expand All @@ -483,16 +485,16 @@ fn run_udevd() -> Option<thread::JoinHandle<()>> {
disable_uevent_helper();
let args: &[&str] = &["--daemon", "--resolve-names=never"];
utils::run_cmd(udevd_path, args);
utils::log("triggering udev coldplug");
log!("triggering udev coldplug");
utils::run_cmd("udevadm", &["trigger", "--type=subsystems", "--action=add"]);
utils::run_cmd("udevadm", &["trigger", "--type=devices", "--action=add"]);
utils::log("waiting for udev to settle");
log!("waiting for udev to settle");
utils::run_cmd("udevadm", &["settle"]);
utils::log("udev is done");
log!("udev is done");
});
Some(handle)
} else {
utils::log("unable to find udevd, skip udev.");
log!("unable to find udevd, skip udev.");
None
}
}
Expand Down Expand Up @@ -547,7 +549,7 @@ fn setup_network() -> Option<thread::JoinHandle<()>> {
if cmdline.contains("virtme.dhcp") {
if let Some(guest_tools_dir) = get_guest_tools_dir() {
if let Some(network_dev) = get_network_device() {
utils::log(&format!("setting up network device {}", network_dev));
log!("setting up network device {}", network_dev);
let handle = thread::spawn(move || {
let args = [
"udhcpc",
Expand Down Expand Up @@ -584,9 +586,7 @@ fn run_user_script() {
|| !std::path::Path::new("/dev/virtio-ports/virtme.dev_stdout").exists()
|| !std::path::Path::new("/dev/virtio-ports/virtme.dev_stderr").exists()
{
utils::log(
"virtme-init: cannot find script I/O ports; make sure virtio-serial is available",
);
log!("virtme-init: cannot find script I/O ports; make sure virtio-serial is available",);
} else {
// Re-create stdout/stderr to connect to the virtio-serial ports.
let io_files = [
Expand Down Expand Up @@ -677,7 +677,7 @@ fn configure_terminal(consdev: &str) {
.stderr(Stdio::inherit())
// Replace the current init process with a shell session.
.output();
utils::log(String::from_utf8_lossy(&output.unwrap().stderr).trim_end_matches('\n'));
log!("{}", String::from_utf8_lossy(&output.unwrap().stderr));
}
}

Expand Down Expand Up @@ -740,7 +740,7 @@ fn run_user_gui(tty_fd: libc::c_int) {
0o0644,
&format!("{}\n/bin/bash {}", pre_exec_cmd, USER_SCRIPT),
) {
utils::log(&format!("failed to generate {}: {}", xinitrc, err));
log!("failed to generate {}: {}", xinitrc, err);
return;
}

Expand Down Expand Up @@ -776,7 +776,7 @@ fn run_user_session() {
let consdev = match get_active_console() {
Some(console) => console,
None => {
utils::log("failed to determine console");
log!("failed to determine console");
Command::new("bash").arg("-l").exec();
return;
}
Expand All @@ -795,7 +795,7 @@ fn run_user_session() {
}

fn setup_user_session() {
utils::log("initialization done");
log!("initialization done");
print_logo();
setup_root_home();
}
Expand Down
61 changes: 40 additions & 21 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,47 @@ use nix::mount::{mount, MsFlags};
use nix::sys::stat::Mode;
use nix::unistd::{chown, Gid, Uid};
use std::ffi::{CString, OsStr};
use std::fmt::Arguments;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::os::unix::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::{Command, Stdio};
use users::get_user_by_name;

static PROG_NAME: &str = "virtme-ng-init";
macro_rules! log {
($($arg:tt)*) => {
$crate::utils::log_impl(std::format_args!($($arg)*))
};
}

pub fn log_impl(msg: Arguments<'_>) {
static PREFIX: &str = "<6>virtme-ng-init: ";
static LOG_LEVEL: &str = "<6>";

pub fn log(msg: &str) {
if msg.is_empty() {
let mut msg = format!("{}{}", PREFIX, msg);

// Remove all trailing \n
while msg.ends_with('\n') {
msg.pop();
}

// Was the message empty? If so, do not log anything
if PREFIX == msg {
return;
}
let msg = format!("{}: {}", PROG_NAME, msg.trim_end_matches('\n'));
let mut file = OpenOptions::new().write(true).open("/dev/kmsg").ok();
match &mut file {
Some(file) => {
let msg = format!("<6>{}\n", msg);
file.write(msg.as_bytes()).ok();

match OpenOptions::new().write(true).open("/dev/kmsg") {
Ok(mut file) => {
msg.push('\n');
file.write_all(msg.as_bytes()).ok();
}
None => {
println!("{}", msg);
Err(_) => {
println!(
"{}",
msg.strip_prefix(LOG_LEVEL)
.expect("The message should always start with the log level")
);
}
}
}
Expand All @@ -54,7 +73,7 @@ pub fn do_unlink(path: &str) {
match std::fs::remove_file(path) {
Ok(_) => (),
Err(err) => {
log(&format!("failed to unlink file {}: {}", path, err));
log!("failed to unlink file {}: {}", path, err);
}
}
}
Expand All @@ -68,7 +87,7 @@ fn do_touch(path: &str, mode: u32) {
Ok(())
}
if let Err(err) = _do_touch(path, mode) {
log(&format!("error creating file: {}", err));
log!("error creating file: {}", err);
}
}

Expand All @@ -86,10 +105,7 @@ pub fn do_symlink(src: &str, dst: &str) {
match fs::symlink(src, dst) {
Ok(_) => (),
Err(err) => {
log(&format!(
"failed to create symlink {} -> {}: {}",
src, dst, err
));
log!("failed to create symlink {} -> {}: {}", src, dst, err);
}
}
}
Expand All @@ -107,7 +123,7 @@ pub fn do_mount(source: &str, target: &str, fstype: &str, flags: usize, fsdata:
Some(fsdata_cstr.as_ref()),
);
if let Err(err) = result {
log(&format!("mount {} -> {}: {}", source, target, err));
log!("mount {} -> {}: {}", source, target, err);
}
}

Expand All @@ -122,15 +138,18 @@ pub fn run_cmd(cmd: impl AsRef<OsStr>, args: &[&str]) {
match output {
Ok(output) => {
if !output.stderr.is_empty() {
log(String::from_utf8_lossy(&output.stderr).trim_end_matches('\n'));
log!(
"{}",
String::from_utf8_lossy(&output.stderr).trim_end_matches('\n')
);
}
}
Err(_) => {
log(&format!(
log!(
"WARNING: failed to run: {:?} {}",
cmd.as_ref(),
args.join(" ")
));
);
}
}
}