blob: 0ef89975b18c4941be4c02afe9337b84b8db4112 [file]
/*
* Copyright (C) 2026 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );
#include <string.h>
#include <stdio.h>
#include <ipxe/peerdist.h>
#include <ipxe/peerdisc.h>
#include <usr/peermgmt.h>
/** @file
*
* Peer Content Caching and Retrieval (PeerDist) protocol management
*
*/
/**
* Print PeerDist error breakdown
*
* @v stats Error statistics
*/
static void peerstat_errors ( struct error_statistics *stats ) {
unsigned int i;
/* Print breakdown */
for ( i = 0 ; i < ( sizeof ( stats->errors ) /
sizeof ( stats->errors[0] ) ) ; i++ ) {
if ( stats->errors[i].count ) {
printf ( " [%d x \"%s\"]\n",
stats->errors[i].count,
strerror ( stats->errors[i].rc ) );
}
}
}
/**
* Print PeerDist discovery socket statistics
*
* @v socket PeerDist discovery socket
*/
static void peerstat_socket ( struct peerdisc_socket *socket ) {
struct error_statistics *stats = &socket->stats;
/* Print breakdown */
printf ( "%s discovery replies [OK:%d ERR:%d]\n",
socket->name, stats->good, stats->bad );
peerstat_errors ( stats );
}
/**
* Print PeerDist retrieval method statistics
*
* @v stats PeerDist retrieval method statistics
* @v name Retrieval type name
*/
static void peerstat_method ( struct error_statistics *stats,
const char *name ) {
char buf[ 4 /* "xxx" + NUL */ ];
unsigned int percentage;
/* Construct percentage */
percentage = ( peerstats.blocks ?
( ( stats->good * 100 ) / peerstats.blocks ) : 0 );
snprintf ( buf, sizeof ( buf ), "%3d", percentage );
if ( ( stats->good > 0 ) && ( percentage == 0 ) )
snprintf ( buf, sizeof ( buf ), " <1" );
/* Print breakdown */
printf ( "%s%% %s retrievals [OK:%d ERR:%d]\n",
buf, name, stats->good, stats->bad );
peerstat_errors ( stats );
}
/**
* Print PeerDist statistics
*
*/
void peerstat ( void ) {
struct peerdisc_socket *socket;
/* Overall statistics */
printf ( "Downloads:%d Blocks:%d Discoveries:%d(+%d) Peers:%d\n",
peerstats.downloads, peerstats.blocks, peerstats.discoveries,
peerstats.rediscoveries, peerstats.peers );
peerstat_errors ( &peerstats.general );
/* Statistics for each retrieval method */
peerstat_method ( &peerstats.path, "local cache" );
peerstat_method ( &peerstats.host, "hosted cache" );
peerstat_method ( &peerstats.disc, "discovered peer" );
peerstat_method ( &peerstats.prev, "prediscovered peer" );
peerstat_method ( &peerstats.origin, "origin server" );
/* Statistics for each discovery socket address family */
for_each_table_entry ( socket, PEERDISC_SOCKETS )
peerstat_socket ( socket );
}