summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown2017-09-05 23:55:05 +0200
committerMichael Brown2017-09-06 00:23:22 +0200
commit7e673a6b67be1594e16a8cc5ab4a0d6c17799547 (patch)
tree863552df11d5bd2800203e7dd94a20e53177b096 /src/net
parent[monojob] Display job status message, if present (diff)
downloadipxe-7e673a6b67be1594e16a8cc5ab4a0d6c17799547.tar.gz
ipxe-7e673a6b67be1594e16a8cc5ab4a0d6c17799547.tar.xz
ipxe-7e673a6b67be1594e16a8cc5ab4a0d6c17799547.zip
[peerdist] Gather and report peer statistics during download
Record and report the number of peers (calculated as the maximum number of peers discovered for a block's segment at the time that the block download is complete), and the percentage of blocks retrieved from peers rather than from the origin server. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net')
-rw-r--r--src/net/peerblk.c8
-rw-r--r--src/net/peerdisc.c30
-rw-r--r--src/net/peermux.c57
3 files changed, 95 insertions, 0 deletions
diff --git a/src/net/peerblk.c b/src/net/peerblk.c
index 9fd52b73..78888d2d 100644
--- a/src/net/peerblk.c
+++ b/src/net/peerblk.c
@@ -270,6 +270,9 @@ static int peerblk_deliver ( struct peerdist_block *peerblk,
*/
static void peerblk_done ( struct peerdist_block *peerblk, int rc ) {
struct digest_algorithm *digest = peerblk->digest;
+ struct peerdisc_segment *segment = peerblk->discovery.segment;
+ struct peerdisc_peer *head;
+ struct peerdisc_peer *peer;
uint8_t hash[digest->digestsize];
unsigned long now = peerblk_timestamp();
@@ -296,6 +299,11 @@ static void peerblk_done ( struct peerdist_block *peerblk, int rc ) {
profile_custom ( &peerblk_attempt_success_profiler,
( now - peerblk->attempted ) );
+ /* Report peer statistics */
+ head = list_entry ( &segment->peers, struct peerdisc_peer, list );
+ peer = ( ( peerblk->peer == head ) ? NULL : peerblk->peer );
+ peerdisc_stat ( &peerblk->xfer, peer, &segment->peers );
+
/* Close download */
peerblk_close ( peerblk, 0 );
return;
diff --git a/src/net/peerdisc.c b/src/net/peerdisc.c
index 4c3cd2ea..20ac2427 100644
--- a/src/net/peerdisc.c
+++ b/src/net/peerdisc.c
@@ -78,6 +78,36 @@ static int peerdisc_discovered ( struct peerdisc_segment *segment,
/******************************************************************************
*
+ * Statistics reporting
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Report peer discovery statistics
+ *
+ * @v intf Interface
+ * @v peer Selected peer (or NULL)
+ * @v peers List of available peers
+ */
+void peerdisc_stat ( struct interface *intf, struct peerdisc_peer *peer,
+ struct list_head *peers ) {
+ struct interface *dest;
+ peerdisc_stat_TYPE ( void * ) *op =
+ intf_get_dest_op ( intf, peerdisc_stat, &dest );
+ void *object = intf_object ( dest );
+
+ if ( op ) {
+ op ( object, peer, peers );
+ } else {
+ /* Default is to do nothing */
+ }
+
+ intf_put ( dest );
+}
+
+/******************************************************************************
+ *
* Discovery sockets
*
******************************************************************************
diff --git a/src/net/peermux.c b/src/net/peermux.c
index 634c6999..a391ed37 100644
--- a/src/net/peermux.c
+++ b/src/net/peermux.c
@@ -24,9 +24,11 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
+#include <stdio.h>
#include <errno.h>
#include <ipxe/uri.h>
#include <ipxe/xferbuf.h>
+#include <ipxe/job.h>
#include <ipxe/peerblk.h>
#include <ipxe/peermux.h>
@@ -75,6 +77,28 @@ static void peermux_close ( struct peerdist_multiplexer *peermux, int rc ) {
}
/**
+ * Report progress of PeerDist download
+ *
+ * @v peermux PeerDist download multiplexer
+ * @v progress Progress report to fill in
+ * @ret ongoing_rc Ongoing job status code (if known)
+ */
+static int peermux_progress ( struct peerdist_multiplexer *peermux,
+ struct job_progress *progress ) {
+ struct peerdist_statistics *stats = &peermux->stats;
+ unsigned int percentage;
+
+ /* Construct PeerDist status message */
+ if ( stats->total ) {
+ percentage = ( ( 100 * stats->local ) / stats->total );
+ snprintf ( progress->message, sizeof ( progress->message ),
+ "%3d%% from %d peers", percentage, stats->peers );
+ }
+
+ return 0;
+}
+
+/**
* Receive content information
*
* @v peermux PeerDist download multiplexer
@@ -275,6 +299,35 @@ peermux_block_buffer ( struct peerdist_multiplexed_block *peermblk ) {
}
/**
+ * Record peer discovery statistics
+ *
+ * @v peermblk PeerDist multiplexed block download
+ * @v peer Selected peer (or NULL)
+ * @v peers List of available peers
+ */
+static void peermux_block_stat ( struct peerdist_multiplexed_block *peermblk,
+ struct peerdisc_peer *peer,
+ struct list_head *peers ) {
+ struct peerdist_multiplexer *peermux = peermblk->peermux;
+ struct peerdist_statistics *stats = &peermux->stats;
+ struct peerdisc_peer *tmp;
+ unsigned int count = 0;
+
+ /* Record maximum number of available peers */
+ list_for_each_entry ( tmp, peers, list )
+ count++;
+ if ( count > stats->peers )
+ stats->peers = count;
+
+ /* Update block counts */
+ if ( peer )
+ stats->local++;
+ stats->total++;
+ DBGC2 ( peermux, "PEERMUX %p downloaded %d/%d from %d peers\n",
+ peermux, stats->local, stats->total, stats->peers );
+}
+
+/**
* Close multiplexed block download
*
* @v peermblk PeerDist multiplexed block download
@@ -303,6 +356,8 @@ static void peermux_block_close ( struct peerdist_multiplexed_block *peermblk,
/** Data transfer interface operations */
static struct interface_operation peermux_xfer_operations[] = {
+ INTF_OP ( job_progress, struct peerdist_multiplexer *,
+ peermux_progress ),
INTF_OP ( intf_close, struct peerdist_multiplexer *, peermux_close ),
};
@@ -330,6 +385,8 @@ static struct interface_operation peermux_block_operations[] = {
peermux_block_deliver ),
INTF_OP ( xfer_buffer, struct peerdist_multiplexed_block *,
peermux_block_buffer ),
+ INTF_OP ( peerdisc_stat, struct peerdist_multiplexed_block *,
+ peermux_block_stat ),
INTF_OP ( intf_close, struct peerdist_multiplexed_block *,
peermux_block_close ),
};