/* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * * Ryosuke Yasuoka */ //! This file contains trivial example code to output console log. This file //! connects to the running VM and waits for logs as a console client. //! 1st arg is URI, 2nd arg is the name of VM, and 3rd arg is a console name. //! If the console name is omitted, then the first console will be opened. //! //! Examples //! ``` //! $ cargo run --example console-read -- 'qemu:///system' 'mytestvm' 'serial0' //! ``` //! //! Largely inspired by libvirt-python/examples/consolecallback.py use std::env; use virt::{ connect::Connect, domain::Domain, stream::Stream, sys::{ virEventRegisterDefaultImpl, virEventRunDefaultImpl, virStreamEventType, VIR_DOMAIN_CONSOLE_FORCE, VIR_STREAM_EVENT_READABLE, VIR_STREAM_NONBLOCK, }, }; fn read_callback(stream: &Stream, event_type: virStreamEventType) { if event_type == VIR_STREAM_EVENT_READABLE { let mut buf = vec![0; 1024]; match stream.recv(buf.as_mut_slice()) { Ok(t) => { if let Ok(received_data) = std::str::from_utf8(&buf[..t]) { print!("{}", received_data); } else { eprint!("Invalid UTF-8 sequence received."); } } Err(e) => { println!("{}", e); } } } } fn event_register_default_impl() { unsafe { virEventRegisterDefaultImpl() }; } fn event_run_default_impl() { unsafe { virEventRunDefaultImpl() }; } fn main() { event_register_default_impl(); let uri = env::args().nth(1); let name = env::args().nth(2).unwrap(); let dev_name = env::args().nth(3); let conn = Connect::open(uri.as_deref()).unwrap(); let dom = Domain::lookup_by_name(&conn, &name).unwrap(); let mut st = Stream::new(&conn, VIR_STREAM_NONBLOCK).unwrap(); dom.open_console(dev_name.as_deref(), &st, VIR_DOMAIN_CONSOLE_FORCE) .unwrap(); st.event_add_callback(VIR_STREAM_EVENT_READABLE, move |st, event_type| { read_callback(st, event_type) }) .unwrap(); loop { event_run_default_impl(); } }