11use crate :: RestartSignal ;
22use digest:: Digest ;
33use feos_proto:: host_service:: {
4- upgrade_request, CpuInfo , GetCpuInfoResponse , HostnameResponse , KernelLogEntry , MemInfo ,
5- MemoryResponse , RebootRequest , RebootResponse , ShutdownRequest , ShutdownResponse ,
6- UpgradeRequest , UpgradeResponse ,
4+ upgrade_request, CpuInfo , GetCpuInfoResponse , GetNetworkInfoResponse , HostnameResponse ,
5+ KernelLogEntry , MemInfo , MemoryResponse , NetDev , RebootRequest , RebootResponse ,
6+ ShutdownRequest , ShutdownResponse , UpgradeRequest , UpgradeResponse ,
77} ;
88use log:: { error, info, warn} ;
99use nix:: sys:: reboot:: { reboot, RebootMode } ;
@@ -13,9 +13,9 @@ use std::collections::HashMap;
1313use std:: fs:: Permissions ;
1414use std:: io:: Write ;
1515use std:: os:: unix:: fs:: PermissionsExt ;
16- use std:: path:: PathBuf ;
16+ use std:: path:: { Path , PathBuf } ;
1717use tempfile:: NamedTempFile ;
18- use tokio:: fs:: File ;
18+ use tokio:: fs:: { self , File } ;
1919use tokio:: io:: { AsyncBufReadExt , AsyncReadExt , BufReader } ;
2020use tokio:: sync:: mpsc;
2121use tokio:: sync:: oneshot;
@@ -235,6 +235,81 @@ pub async fn handle_get_cpu_info(responder: oneshot::Sender<Result<GetCpuInfoRes
235235 }
236236}
237237
238+ async fn read_net_stat ( base_path : & Path , stat_name : & str ) -> u64 {
239+ let stat_path = base_path. join ( stat_name) ;
240+ fs:: read_to_string ( stat_path)
241+ . await
242+ . ok ( )
243+ . and_then ( |s| s. trim ( ) . parse :: < u64 > ( ) . ok ( ) )
244+ . unwrap_or ( 0 )
245+ }
246+
247+ async fn read_all_net_stats ( ) -> Result < Vec < NetDev > , std:: io:: Error > {
248+ let mut devices = Vec :: new ( ) ;
249+ let mut entries = fs:: read_dir ( "/sys/class/net" ) . await ?;
250+
251+ while let Some ( entry) = entries. next_entry ( ) . await ? {
252+ let path = entry. path ( ) ;
253+ if !path. is_dir ( ) {
254+ continue ;
255+ }
256+
257+ let name = entry
258+ . file_name ( )
259+ . into_string ( )
260+ . unwrap_or_else ( |_| "invalid_utf8" . to_string ( ) ) ;
261+ let stats_path = path. join ( "statistics" ) ;
262+
263+ if !stats_path. is_dir ( ) {
264+ continue ;
265+ }
266+
267+ let device = NetDev {
268+ name,
269+ rx_bytes : read_net_stat ( & stats_path, "rx_bytes" ) . await ,
270+ rx_packets : read_net_stat ( & stats_path, "rx_packets" ) . await ,
271+ rx_errors : read_net_stat ( & stats_path, "rx_errors" ) . await ,
272+ rx_dropped : read_net_stat ( & stats_path, "rx_dropped" ) . await ,
273+ rx_fifo : read_net_stat ( & stats_path, "rx_fifo_errors" ) . await ,
274+ rx_frame : read_net_stat ( & stats_path, "rx_frame_errors" ) . await ,
275+ rx_compressed : read_net_stat ( & stats_path, "rx_compressed" ) . await ,
276+ rx_multicast : read_net_stat ( & stats_path, "multicast" ) . await ,
277+ tx_bytes : read_net_stat ( & stats_path, "tx_bytes" ) . await ,
278+ tx_packets : read_net_stat ( & stats_path, "tx_packets" ) . await ,
279+ tx_errors : read_net_stat ( & stats_path, "tx_errors" ) . await ,
280+ tx_dropped : read_net_stat ( & stats_path, "tx_dropped" ) . await ,
281+ tx_fifo : read_net_stat ( & stats_path, "tx_fifo_errors" ) . await ,
282+ tx_collisions : read_net_stat ( & stats_path, "collisions" ) . await ,
283+ tx_carrier : read_net_stat ( & stats_path, "tx_carrier_errors" ) . await ,
284+ tx_compressed : read_net_stat ( & stats_path, "tx_compressed" ) . await ,
285+ } ;
286+ devices. push ( device) ;
287+ }
288+
289+ Ok ( devices)
290+ }
291+
292+ pub async fn handle_get_network_info (
293+ responder : oneshot:: Sender < Result < GetNetworkInfoResponse , Status > > ,
294+ ) {
295+ info ! ( "HOST_WORKER: Processing GetNetworkInfo request." ) ;
296+ let result = match read_all_net_stats ( ) . await {
297+ Ok ( devices) => Ok ( GetNetworkInfoResponse { devices } ) ,
298+ Err ( e) => {
299+ error ! ( "HOST_WORKER: ERROR - Failed to get network info: {e}" ) ;
300+ Err ( Status :: internal ( format ! (
301+ "Failed to get network info from sysfs: {e}"
302+ ) ) )
303+ }
304+ } ;
305+
306+ if responder. send ( result) . is_err ( ) {
307+ error ! (
308+ "HOST_WORKER: Failed to send response for GetNetworkInfo. API handler may have timed out."
309+ ) ;
310+ }
311+ }
312+
238313pub async fn handle_stream_kernel_logs ( grpc_tx : mpsc:: Sender < Result < KernelLogEntry , Status > > ) {
239314 info ! ( "HOST_WORKER: Opening {KMSG_PATH} for streaming kernel logs." ) ;
240315
0 commit comments