Commit 1ac5239a authored by Leigh B. Stoller's avatar Leigh B. Stoller

Kill old frisbee directory.

parent f9530c20
all: userfrisbee frisbeed
CFLAGS = -O -g
CFROMAGEFLAGS = -O -g -static -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads
CFRISBEEFLAGS = -O -g
FROMAGELIBS = -lz -L/usr/local/lib -llthread -llgcc_r
FRISBEELIBS = -L/usr/local/lib
f_network_withsyslog.c: f_network.c
echo "#define SYSLOG" > f_network_withsyslog.c
cat f_network.c >> f_network_withsyslog.c
userfrisbee: fromage.o f_chunker.o f_frisbee.o f_network.o f_timer.o
$(CC) $(CFROMAGEFLAGS) fromage.o f_chunker.o f_frisbee.o f_network.o f_timer.o $(FROMAGELIBS) -o userfrisbee
cp userfrisbee userfrisbee.debug
strip userfrisbee
frisbeed: server.o f_network_withsyslog.o f_timer.o
$(CC) $(CFRISBEEFLAGS) server.o f_network_withsyslog.o f_timer.o $(FRISBEELIBS) -o frisbeed
cp frisbeed frisbeed.debug
strip frisbeed
tidy:
-/bin/rm -f *.o
clean: tidy
-/bin/rm userfrisbee frisbeed userfrisbee.debug frisbeed.debug
This is the first implementation of Frisbee which is no
longer used. The ../frisbee.redux directory contains
the current system that is the one actually used.
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "f_common.h"
#include "f_chunker.h"
#define BufferSlotCount 32
/* the number of empty bufferslots there must be
for the system to request more data.
Originally, this was 1 (any slots), but
having more means potentially better synchronization. */
#define BUFFER_HEADROOM 7
typedef struct {
int mb; /* -1 = none. */
int gotCount;
uchar gotBitmap[ 1024 ];
uchar data[ 1024 * 1024 ];
} BufferSlot;
BufferSlot slots[BufferSlotCount];
int totalMB;
uchar * finishedMBBitmap;
unsigned int redundantKBs; /* intraMB redundant */
unsigned int redundantKBs2; /* MB redundant */
void c_init( uint sizeM, uint bufferCount )
{
int i;
redundantKBs = 0;
redundantKBs2 = 0;
/* ignoring BufferCount. */
totalMB = sizeM;
finishedMBBitmap = malloc( totalMB );
assert( finishedMBBitmap );
bzero( finishedMBBitmap, totalMB );
for (i = 0; i < BufferSlotCount; i++) {
slots[i].mb = -1;
}
}
void c_finish()
{
int i;
assert( finishedMBBitmap );
for (i = 0; i < totalMB; i++) {
if (!finishedMBBitmap[i]) {
printf("Chunker: Warning! finish called without all MBs being finished.\n");
}
}
free( finishedMBBitmap );
}
static int inProgressMB( int mb )
{
int i;
assert( mb >= 0 );
assert( mb < totalMB );
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb == mb) {
return 1;
}
}
return 0;
}
static int getOrAllocBufferSlotForMB( BufferSlot ** returnPointer, int mb )
{
int i;
assert( mb >= 0 );
assert( mb < totalMB );
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb == mb) {
*returnPointer = &(slots[i]);
return 1;
}
}
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb == -1) {
slots[i].mb = mb;
slots[i].gotCount = 0;
bzero( slots[i].gotBitmap, 1024 );
*returnPointer = &(slots[i]);
/*
printf("Chunker: Starting MB %i (in slot %i)\n", mb, i );
*/
return 1;
}
}
/* no slots */
return 0;
}
void c_addKtoM( uint kb, uchar * data )
{
int mb = kb / 1024;
int kbOffset = kb % 1024;
int byteOffset = kbOffset * 1024;
BufferSlot * bsp;
assert( mb >= 0 );
assert( mb < totalMB );
if (!finishedMBBitmap[ mb ]) {
if (getOrAllocBufferSlotForMB( &bsp, mb )) {
if (!bsp->gotBitmap[ kbOffset ]) {
bsp->gotBitmap[ kbOffset ] = 1;
memcpy( bsp->data + byteOffset, data, 1024 );
bsp->gotCount++;
} else {
redundantKBs++;
}
}
} else {
redundantKBs2++;
}
}
int minIncompleteSlot()
{
int min = -1;
int minCount, i;
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb != -1 && slots[i].gotCount != 1024) {
if (min == -1 || slots[i].gotCount < minCount) {
min = i;
minCount = slots[i].gotCount;
}
}
}
return min;
}
int maxIncompleteSlot()
{
int max = -1;
int maxCount, i;
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb != -1 && slots[i].gotCount != 1024) {
if (max == -1 || slots[i].gotCount > maxCount) {
max = i;
maxCount = slots[i].gotCount;
}
}
}
return max;
}
int getKForIncompleteBufferSlot( int slot )
{
int i;
assert( slots[slot].mb != -1 && slots[slot].gotCount != 1024 );
for ( i = 0; i < 1024; i++) {
if (!slots[slot].gotBitmap[i]) {
return i;
}
}
}
/* this is the heart of Chunker, and indeed, Frisbee.
Could possibly be broken into two or three subfunctions,
though it is fairly linear. */
int c_suggestK()
{
static int lastMessage = 0;
static int lastMessageCount = 0;
int allDone;
int i, ii, j, ei;
int freeCount = 0;
int highestWeHave;
int m = maxIncompleteSlot();
if (m != -1) {
return slots[m].mb * 1024 + getKForIncompleteBufferSlot( m );
}
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb == -1) {
freeCount++;
}
}
#if 0
int foo = rand() % BufferSlotCount;
/* find an incompletely full buffer slot --
but start from a random location, as not to give
bucket #0 preferential treatment. */
for (ii = 0; ii < BufferSlotCount; ii++) {
i = (ii + foo) % BufferSlotCount;
if (slots[i].mb != -1) {
if (slots[i].gotCount != 1024) {
for (j = 0; j < 1024; j++) {
if (!slots[i].gotBitmap[j]) {
if (lastMessage != 1) {
if (lastMessageCount) {
/*
printf("ChunkerSK: Last ChunkerSK message repeated %i times.\n",
lastMessageCount );
*/
lastMessageCount = 0;
}
/*
printf("ChunkerSK: Suggesting kb from existing MB...\n");
*/
lastMessage = 1;
} else {
lastMessageCount++;
}
return (slots[i].mb * 1024 + j);
}
}
assert( 0 ); /* shouldn't happen */
}
} else {
/* slots[i].mb == -1, ergo it's free. */
freeCount++;
}
}
#endif
/* since all 'inProgress' MBs were shown to be complete,
at this point "inProgressMB" means complete, but not consumed.
Establish whether there are MB's that arent either complete and consumed,
or sitting complete (but not consumed) in our buffer. */
allDone = 1;
for (i = 0; i < totalMB; i++) {
if (!finishedMBBitmap[i] && !inProgressMB(i)) {
allDone = 0;
break;
}
}
/* if there weren't incomplete MBs, craft a suitable reply. */
if (allDone) {
if (lastMessageCount) {
/*
printf("ChunkerSK: Last chunkerSK message repeated %i times.\n",
lastMessageCount );
*/
lastMessageCount = 0;
}
printf("ChunkerSK: No incomplete MB's - done.\n");
printf("ChunkerSK: %i redundant KBs (MB needed, KB not)\n", redundantKBs);
printf("ChunkerSK: %i redundant2 KBs (MB not needed)\n", redundantKBs2);
/* tell caller we're done. */
return -2;
}
if (freeCount < BUFFER_HEADROOM) {
/* there exists one or more incomplete MBs,
but we cannot (or choose not to) deal with data. */
if (lastMessage != 3) {
if (lastMessageCount) {
/*
printf("ChunkerSK: Last chunkerSK message repeated %i times.\n",
lastMessageCount );
*/
lastMessageCount = 0;
}
/*
printf("ChunkerSK: Buffer too full to recommend chunks.\n", i);
*/
lastMessage = 3;
} else {
lastMessageCount++;
}
/* tell caller to punt. */
return -1;
} else {
int beginEqualsICount = 0;
int oneDoneYet = 0;
int begin = rand() % totalMB;
i = begin;
/* okay.. starting at a random MB, go through list of complete MBs;
first find a MB which _is_ finished, then find the next MB which is _not_,
and request that.
If there are no finished MBs, request MB #1.
Note this loop must be processed twice for i == begin,
for the (rare) case that MB[begin] is the only incomplete MB in the list.
*/
while (1) {
/* this loop must get processed twice for i == begin, once for
each other MB. */
if (begin == i) {
beginEqualsICount++;
}
if (oneDoneYet) {
if (!finishedMBBitmap[i] && !inProgressMB(i)) {
/* found it. */
if (lastMessage != 2) {
if (lastMessageCount) {
/*
printf("ChunkerSK: Last chunkerSK message repeated %i times.\n",
lastMessageCount );
*/
lastMessageCount = 0;
}
/*
printf("ChunkerSK: Suggesting a new MB (%i)...\n", i);
*/
lastMessage = 2;
} else {
lastMessageCount++;
}
return i * 1024;
}
} else {
if (finishedMBBitmap[i] || inProgressMB(i)) {
oneDoneYet = 1;
}
}
if (beginEqualsICount == 2) {
/* we've now handled begin == i twice, so break. */
break;
}
i = (i + 1) % totalMB;
} /* while (1) */
if (oneDoneYet == 0) {
/* there were no complete MBs, so request beginning. */
return 0;
} else {
/* there were no incomplete MBs-- this should've been caught. */
assert( 0 ); /* there should be an incomplete. */
}
}
}
int c_consumeM( uint * mb, uchar ** data )
{
int i;
assert( mb );
assert( data );
for (i = 0; i < BufferSlotCount; i++) {
if ((slots[i].mb != -1) && (slots[i].gotCount == 1024)) {
*mb = slots[i].mb;
*data = slots[i].data;
return 1;
}
}
return 0;
}
void c_finishedM( uint mb )
{
int i;
assert( mb >= 0 );
assert( mb < totalMB );
finishedMBBitmap[mb] = 1;
for (i = 0; i < BufferSlotCount; i++) {
if (slots[i].mb == mb) {
/*
printf("Chunker: Finished MB %i (in slot %i)\n", mb, i );
*/
slots[i].mb = -1;
return;
}
}
assert( 0 );
}
/* initialize chunker, passing the size of the file (in MB) and
the number of buffers to allocate (1 MB apiece) */
void c_init( uint sizeM, uint bufferCount );
/* close down chunker */
void c_finish();
/* suggest which kilobyte to request to help chunker on its path to glory */
int c_suggestK();
/* slip the chunker a kilobyte of data we've obtained */
void c_addKtoM( uint kb, uchar * data );
/* query for a complete megabyte;
mb will get the mb identifier, data will get a pointer to data.
returns 1 if there was something available, 0 otherwise. */
int c_consumeM( uint * mb, uchar ** data );
/* indicate that a complete megabyte has been processed and may be dumped */
void c_finishedM( uint mb );
#include <sys/types.h>
#define traceprintf printf
/* define traceprintf( X, ... ) */
#ifndef ulong
typedef unsigned long ulong;
#endif
typedef unsigned char uchar;
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <assert.h>
#include <poll.h>
#include <stdio.h>
#ifdef OSKIT
#include <oskit/startup.h>
#include <oskit/clientos.h>
#endif
#include "f_common.h"
#include "f_network.h"
#include "f_timer.h"
#include "f_chunker.h"
/* implements the following API: */
#include "frisbee.h"
#define FRISBEE_PORT 3564
/* timeout before it decides the server is dead */
#define TIMEOUT 3000
/* the minimum number of msecs between alive hint attempts */
#define ALIVE_HINT_MIN 1000
/* when added to ALIVE_HINT_MIN, the maximum number of msecs between alive hint attempts */
#define ALIVE_HINT_RANGE 2000
/* define GUNS_ABLAZING to make the client send
an alive hint immediately after it starts, rather
than holding back a while. */
#define GUNS_ABLAZING
int packetTotal;
int nextExpectedPacket;
int packetsReceivedSoFar;
int skipNextAlive;
int finishedMarker;
uint myId;
extern char version[];
extern char build_info[];
static void sendAliveHint();
static void sendGoneHint();
int frisbeeInit( const char * imageName,
unsigned int broadcastAddr )
{
#ifdef OSKIT
/* redundant calls removed.
oskit_clientos_init();
start_clock();
start_network();
*/
#endif
printf("frisbeeInit: called.\n");
/* setup my unique id */
srandomdev();
myId = random();
packetTotal = -1;
nextExpectedPacket = -1;
packetsReceivedSoFar = 0;
printf("frisbeeInit: calling n_init.\n");
n_init( FRISBEE_PORT, FRISBEE_PORT, broadcastAddr );
printf("frisbeeInit: calling t_init.\n");
t_init();
printf("frisbeeInit: calling t_setTimer.\n");
t_setTimer( ALIVE_HINT_MIN + (random() % ALIVE_HINT_RANGE) );
skipNextAlive = 0;
finishedMarker = -1;
#ifdef GUNS_ABLAZING
printf("frisbeeInit: sending alive hint.\n");
sendAliveHint();
#endif
/* XXX detect network errors, etc, and return appropriate errorcodes. */
printf("frisbeeInit: returning FRISBEE_OK\n");
return FRISBEE_OK;
}
int frisbeeInit2( const char * imageName,
const char * broadcastAddr,
int port )
{
#ifdef OSKIT
/* redundant calls removed.
oskit_clientos_init();
start_clock();
start_network();
*/
#endif
printf("frisbeeInit: called.\n");
/* setup my unique id */
srandomdev();
myId = random();
packetTotal = -1;
nextExpectedPacket = -1;
packetsReceivedSoFar = 0;
printf("frisbeeInit: calling n_init.\n");
n_initLookup( port, port, broadcastAddr );
printf("frisbeeInit: calling t_init.\n");
t_init();
printf("frisbeeInit: calling t_setTimer.\n");
t_setTimer( ALIVE_HINT_MIN + (random() % ALIVE_HINT_RANGE) );
skipNextAlive = 0;
finishedMarker = -1;
#ifdef GUNS_ABLAZING
printf("frisbeeInit: sending alive hint.\n");
sendAliveHint();
#endif
/* XXX detect network errors, etc, and return appropriate errorcodes. */
printf("frisbeeInit: returning FRISBEE_OK\n");
return FRISBEE_OK;
}
int frisbeeInitOld( const char * imageName,
unsigned short localPort,
const char * remoteAddr,
unsigned short remotePort )
{
#ifdef OSKIT
oskit_clientos_init();
start_clock();
start_network();
#endif
printf("frisbeeInitOld: called. =(\n");
/* setup my unique id */
srandomdev();
myId = random();
packetTotal = -1;
nextExpectedPacket = -1;
packetsReceivedSoFar = 0;
n_initLookup( localPort, remotePort, remoteAddr );
t_init();
t_setTimer( ALIVE_HINT_MIN + (random() % ALIVE_HINT_RANGE) );
skipNextAlive = 0;
finishedMarker = -1;
#ifdef GUNS_ABLAZING
sendAliveHint();
#endif
/* XXX detect network errors, etc, and return appropriate errorcodes. */
return FRISBEE_OK;
}
int frisbeeLockReadyChunk( uint * chunkId, uchar ** data )
{
return c_consumeM( chunkId, data ) ? FRISBEE_OK : FRISBEE_NO_CHUNK;
}
int frisbeeUnlockReadyChunk( uint chunkId )
{
/* XXX should check to make sure that chunkId is valid. */
c_finishedM( chunkId );
return FRISBEE_OK;
}
int frisbeeLoop()
{
Packet p;
static int done = 0;
if (done) {
return FRISBEE_DONE;
}
if (n_packetRecv( &p, TIMEOUT, NPT_DATA | NPT_POLL)) {
if ((p.type == NPT_DATA) && (packetTotal != -1)) {