Commit 82adef9c authored by Leigh B Stoller's avatar Leigh B Stoller

Merge branch 'master' of

parents c09fe991 978d19d9
diff -ru linux-2.6.34/net/ipv4/Kconfig linux-2.6.34-emulab/net/ipv4/Kconfig
--- linux-2.6.34/net/ipv4/Kconfig 2008-08-29 09:50:50.000000000 -0600
+++ linux-2.6.34-emulab/net/ipv4/Kconfig 2008-08-29 09:53:39.000000000 -0600
@@ -627,3 +627,9 @@
If unsure, say N.
+# Emulab special
+ bool "ICMP: ICMP Ping-of-Death (Emulab)"
diff -ru linux-2.6.34/net/ipv4/icmp.c linux-2.6.34-emulab/net/ipv4/icmp.c
--- linux-2.6.34/net/ipv4/icmp.c 2010-05-16 23:17:36.000000000 +0200
+++ linux-2.6.34-emulab/net/ipv4/icmp.c 2010-06-03 17:32:26.000000000 +0200
......@@ -46,6 +46,10 @@ NEW FEATURES:
data will go into every chunk and still compress that, but there
is no point since we pad out every chunk to 1MB.
[ The discovery protocol is now done. On-the-fly images has not
though we can distribute arbitrary files, we do so without creating
imagezip-format images. ]
Now one could imagine a super, caching frisbee server that creates
compressed images on the fly and caches them for later use. Perhaps
it would become more of a chunk server where it caches every chunk
......@@ -137,6 +141,13 @@ ENHANCEMENTS:
chunks. So maybe 1448B/blk * 768 blks/chunk == 1.06MB/chunk. PREQUEST
BlockMaps come down from 128 bytes to 96.
[ Support for jumbo packets has been done. This increases the block
size to 8192 and reduces the blocks/chunk to 128 to keep the chunk
size constant (so that we can continue to distribute our existing
images). Currently this requires static re-compilation of both the
client and server, though some support has been put in for negotiating
the blocksize (in join v2 messages). ]
6. Dynamic rate pacing in the server.
Our attempts to date have been pretty feeble. I think we have a
......@@ -152,6 +163,36 @@ ENHANCEMENTS:
and frisbeed pad it out, we can save a lot of disk space for these
small images.
[ DONE ]
8. Allow a server to serve multiple unicast clients.
Right now an instance of the server not only serves just a single
image, but only to a single destination address. This is reasonable
for broadcast/multicast but is overly restrictive for unicast. Changing
this should be minor, we just need to keep track of destinations
(addr/port) in the queue along with block ranges to send out. We would
need to back off the queue optimizations where we combine incoming
requests with those already in the queue (i.e., now we would also have
to make sure that they are for the same destination before we combine).
Minor changes would be needed to PacketSend/Recv to track the client
IP/port rather than just assuming/using the global mcastaddr/portnum.
9. Allow the frisbee client to be used in a pipe.
If we could pipe the output of frisbee into another utility, this would
make it more useful for arbitrary file distribution. For example:
frisbee -m <addr> -p <port> - | tar xzf
to download and unpack a tarfile. The problem is out-of-order processing
of chunks and there are a couple of ways around it. Frisbee can already
request chunks in-order, but it is also opportunistic and saves other
chunk data it needs that other clients have requested. We could just
ignore that data and keep re-requesting blocks in order as we need them,
or we could do some limited memory caching of incoming data; i.e., save
but don't decompress chunks until we need them. We could cache to disk
as well, but then we don't really save anything over just frisbeeing into
a tmp file and giving that to the next util in the pipeline.
1. Have seen the clients run out of socket buffer space causing them
......@@ -57,6 +57,7 @@ int tracing = 0;
char traceprefix[64];
int randomize = 1;
int zero = 0;
int keepalive;
int portnum;
struct in_addr mcastaddr;
struct in_addr mcastif;
......@@ -137,7 +138,7 @@ ClientStats_t Stats;
char *usagestr =
"usage: frisbee [-drzbn] [-s #] <-p #> <-m ipaddr> <output filename>\n"
"usage: frisbee [-drzbnN] [-s #] <-m ipaddr> <-p #> <output filename>\n"
" -d Turn on debugging. Multiple -d options increase output.\n"
" -r Randomly delay first request by up to one second.\n"
" -z Zero fill unused block ranges (default is to seek past).\n"
......@@ -149,6 +150,7 @@ char *usagestr =
" -i mcastif Specify a multicast interface in dotted notation.\n"
" -s slice Output to DOS slice (DOS numbering 1-4)\n"
" NOTE: Must specify a raw disk device for output filename.\n"
" -K seconds Send a multicast keep alive after a period of inactivity.\n"
"tuning options (if you don't know what they are, don't use em!):\n"
" -C MB Max MB of memory to use for network chunk buffering.\n"
......@@ -191,7 +193,7 @@ main(int argc, char **argv)
int dostype = -1;
int slice = 0;
while ((ch = getopt(argc, argv, "dhp:m:s:i:tbznT:r:E:D:C:W:S:M:R:I:ON")) != -1)
while ((ch = getopt(argc, argv, "dhp:m:s:i:tbznT:r:E:D:C:W:S:M:R:I:ONK:")) != -1)
switch(ch) {
case 'd':
......@@ -306,6 +308,12 @@ main(int argc, char **argv)
nodecompress = 1;
case 'K':
keepalive = atoi(optarg);
if (keepalive < 0)
keepalive = 0;
case 'h':
case '?':
......@@ -459,6 +467,14 @@ main(int argc, char **argv)
DiskStatusCallback = WriterStatusCallback;
* Set the MC keepalive counter (but only if we are multicasting!)
if (broadcast || (ntohl(mcastaddr.s_addr) >> 28) != 14)
keepalive = 0;
if (keepalive)
log("Enabling MC keepalive at %d seconds", keepalive);
if (tracing) {
......@@ -499,12 +515,14 @@ void *
ClientRecvThread(void *arg)
Packet_t packet, *p = &packet;
int IdleCounter, BackOff;
int IdleCounter, BackOff, KACounter;
static int gotone;
if (debug)
log("Receive pthread starting up ...");
KACounter = keepalive * TIMEOUT_HZ;
* Use this to control the rate at which we request blocks.
* The IdleCounter is how many ticks we let pass without a
......@@ -549,6 +567,23 @@ ClientRecvThread(void *arg)
if (PacketReceive(p) != 0) {
* See if we should send a keep alive
if (KACounter == 1) {
/* If for some reason it fails, stop trying */
if (debug)
log("sending keepalive...");
if (NetMCKeepAlive()) {
log("Multicast keepalive failed, "
"disabling keepalive");
keepalive = 0;
KACounter = keepalive * TIMEOUT_HZ;
} else if (KACounter > 1)
if (--IdleCounter <= 0) {
if (gotone)
......@@ -569,6 +604,8 @@ ClientRecvThread(void *arg)
if (keepalive)
KACounter = keepalive * TIMEOUT_HZ;
gotone = 1;
if (! PacketValid(p, TotalChunkCount)) {
......@@ -320,7 +320,7 @@ typedef struct {
int GetSockbufSize(void);
int ClientNetInit(void);
int ServerNetInit(void);
int ServerNetMCKeepAlive(void);
int NetMCKeepAlive(void);
unsigned long ClientNetID(void);
int PacketReceive(Packet_t *p);
void PacketSend(Packet_t *p, int *resends);
......@@ -249,7 +249,7 @@ ServerNetInit(void)
* We need a better way to do this!
struct ip_mreq mreq;
......@@ -604,7 +604,7 @@ ServerRecvThread(void *arg)
if (PacketReceive(p) != 0) {
if (keepalive && ++idles > keepalive) {
if (ServerNetMCKeepAlive()) {
if (NetMCKeepAlive()) {
warning("Multicast keepalive failed");
if (++kafails > 5) {
warning("too many failures, disabled");
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment