LCOV - code coverage report
Current view: top level - disco/net - fd_linux_bond.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 60 72 83.3 %
Date: 2026-09-17 04:28:31 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "fd_linux_bond.h"
       2             : 
       3             : #include <errno.h>
       4             : #include <stdio.h>
       5             : #include <sys/stat.h>
       6             : 
       7             : int
       8           3 : fd_bonding_is_master( char const * device ) {
       9           3 :   char path[ PATH_MAX ];
      10           3 :   FD_TEST( fd_cstr_printf_check( path, PATH_MAX, NULL, "/sys/class/net/%s/bonding", device ) );
      11           3 :   struct stat st;
      12           3 :   int err = stat( path, &st );
      13           3 :   if( FD_UNLIKELY( err && errno != ENOENT ) )
      14           0 :     FD_LOG_ERR(( "error checking if device `%s` is bonded, stat(%s) failed (%i-%s)",
      15           3 :                  device, path, errno, fd_io_strerror( errno ) ));
      16           3 :   return !err;
      17           3 : }
      18             : 
      19             : static void
      20             : read_slaves( char const * device,
      21           6 :              char         output[ 4096 ] ) {
      22           6 :   char path[ PATH_MAX ];
      23           6 :   FD_TEST( fd_cstr_printf_check( path, PATH_MAX, NULL, "/sys/class/net/%s/bonding/slaves", device ) );
      24             : 
      25           6 :   FILE * fp = fopen( path, "r" );
      26           6 :   if( FD_UNLIKELY( !fp ) )
      27           0 :     FD_LOG_ERR(( "error configuring network device, fopen(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      28           6 :   if( FD_UNLIKELY( !fgets( output, 4096, fp ) ) )
      29           0 :     FD_LOG_ERR(( "error configuring network device, fgets(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      30           6 :   if( FD_UNLIKELY( feof( fp ) ) ) FD_LOG_ERR(( "error configuring network device, fgets(%s) failed (EOF)", path ));
      31           6 :   if( FD_UNLIKELY( ferror( fp ) ) ) FD_LOG_ERR(( "error configuring network device, fgets(%s) failed (error)", path ));
      32           6 :   if( FD_UNLIKELY( strlen( output ) == 4095 ) ) FD_LOG_ERR(( "line too long in `%s`", path ));
      33           6 :   if( FD_UNLIKELY( strlen( output ) == 0 ) ) FD_LOG_ERR(( "line empty in `%s`", path ));
      34           6 :   if( FD_UNLIKELY( fclose( fp ) ) )
      35           0 :     FD_LOG_ERR(( "error configuring network device, fclose(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      36           6 :   output[ strlen( output ) - 1 ] = '\0';
      37           6 : }
      38             : 
      39             : fd_bonding_slave_iter_t *
      40             : fd_bonding_slave_iter_init(
      41             :     fd_bonding_slave_iter_t * iter,
      42             :     char const * device
      43           6 : ) {
      44           6 :   read_slaves( device, iter->line );
      45           6 :   iter->saveptr = NULL;
      46           6 :   iter->tok     = strtok_r( iter->line, " \t", &iter->saveptr );
      47           6 :   return iter;
      48           6 : }
      49             : 
      50             : int
      51          18 : fd_bonding_slave_iter_done( fd_bonding_slave_iter_t const * iter ) {
      52          18 :   return !iter->tok;
      53          18 : }
      54             : 
      55             : void
      56             : fd_bonding_slave_iter_next(
      57             :     fd_bonding_slave_iter_t * iter
      58          12 : ) {
      59          12 :   iter->tok = strtok_r( NULL, " \t", &iter->saveptr );
      60          12 : }
      61             : 
      62             : char const *
      63             : fd_bonding_slave_iter_ele(
      64             :     fd_bonding_slave_iter_t const * iter
      65           6 : ) {
      66           6 :   return iter->tok;
      67           6 : }
      68             : 
      69             : int
      70           3 : fd_bonding_is_lacp( char const * device ) {
      71           3 :   char path[ PATH_MAX ];
      72           3 :   FD_TEST( fd_cstr_printf_check( path, PATH_MAX, NULL, "/sys/class/net/%s/bonding/mode", device ) );
      73             : 
      74           3 :   FILE * fp = fopen( path, "r" );
      75           3 :   if( FD_UNLIKELY( !fp ) ) {
      76           0 :     FD_LOG_WARNING(( "failed to detect bonding mode of device `%s`, fopen(%s) failed (%i-%s)",
      77           0 :                      device, path, errno, fd_io_strerror( errno ) ));
      78           0 :     return 0;
      79           0 :   }
      80             : 
      81             :   /* The mode node holds the mode name followed by its numeric ID,
      82             :      e.g. "802.3ad 4" */
      83           3 :   char line[ 64 ];
      84           3 :   errno = 0;
      85           3 :   char * res = fgets( line, sizeof(line), fp );
      86           3 :   int    err = errno;
      87           3 :   fclose( fp );
      88           3 :   if( FD_UNLIKELY( !res ) ) {
      89           0 :     FD_LOG_WARNING(( "failed to detect bonding mode of device `%s`, fgets(%s) failed (%i-%s)",
      90           0 :                      device, path, err, fd_io_strerror( err ) ));
      91           0 :     return 0;
      92           0 :   }
      93             : 
      94           3 :   return 0==strncmp( line, "802.3ad ", 8UL );
      95           3 : }
      96             : 
      97             : uint
      98           3 : fd_bonding_slave_cnt( char const * device ) {
      99           3 :   fd_bonding_slave_iter_t iter_[1];
     100           3 :   uint cnt = 0U;
     101           3 :   for( fd_bonding_slave_iter_t * iter = fd_bonding_slave_iter_init( iter_, device );
     102           9 :        !fd_bonding_slave_iter_done( iter );
     103           6 :        fd_bonding_slave_iter_next( iter ) ) {
     104           6 :     cnt++;
     105           6 :   }
     106           3 :   return cnt;
     107           3 : }

Generated by: LCOV version 1.14