decls.h 6.11 KB
Newer Older
Leigh B. Stoller's avatar
Leigh B. Stoller committed
1 2
/*
 * EMULAB-COPYRIGHT
3
 * Copyright (c) 2000-2003 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
4 5 6
 * All rights reserved.
 */

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * Shared for defintions for frisbee client/server code.
 */

#include "log.h"

/*
 * We operate in terms of this blocksize (in bytes). 
 */
#define BLOCKSIZE	1024

/*
 * Each chunk is this many blocks.
 */
#define CHUNKSIZE	1024

/*
 * The number of chunk buffers in the client.
 */
26
#define MAXCHUNKBUFS	64
27

28 29 30 31 32 33
/*
 * Socket buffer size, used for both send and receive in client and
 * server right now.
 */
#define SOCKBUFSIZE	(128 * 1024)

34 35
/*
 * The number of read-ahead chunks that the client will request
36
 * at a time. No point in requesting too far ahead either, since they
37 38 39 40 41
 * are uncompressed/written at a fraction of the network transfer speed.
 * Also, with multiple clients at different stages, each requesting blocks
 * it is likely that there will be plenty more chunks ready or in progress.
 */
#define MAXREADAHEAD	2
42
#define MAXINPROGRESS	8
43 44 45 46 47

/*
 * Timeout (in usecs) for packet receive. The idletimer number is how
 * many PKT timeouts we allow before requesting more data from the server.
 * That is, if we go TIMEOUT usecs without getting a packet, then ask for
48
 * more.
49 50
 */
#define PKTRCV_TIMEOUT		30000
51
#define CLIENT_IDLETIMER_COUNT	3
52 53
#define TIMEOUT_HZ		(1000000 / PKTRCV_TIMEOUT)
#define TIMEOUT_HALFHZ		(TIMEOUT_HZ / 2)
54 55 56

/*
 * Timeout (in seconds!) server will hang around with no active clients.
57
 * Make it zero to never exit. 
58
 */
59
#define SERVER_INACTIVE_SECONDS	(60 * 30)
60 61 62

/*
 * The number of disk read blocks in a single read on the server.
63
 * Must be an even divisor of CHUNKSIZE.
64
 */
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
#define SERVER_READ_SIZE	32

/*
 * Parameters for server network usage:
 *
 *	SERVER_BURST_SIZE	Max BLOCKSIZE packets sent in a burst.
 *				Should be a multiple of SERVER_READ_SIZE
 *				Should be less than SOCKBUFSIZE/BLOCKSIZE,
 *				bursts of greater than the send socket
 *				buffer size are almost certain to cause
 *				lost packets.
 *	SERVER_BURST_GAP	Delay in usec between output bursts.
 *				Given the typical scheduling granularity
 *				of 10ms for most unix systems, this
 *				will likely be set to either 0 or 10000.
 *
 * Together with the BLOCKSIZE, these two params form a theoretical upper
 * bound on bandwidth consumption for the server.  That upper bound (for
 * ethernet) is:
 *
 *	(1000000 / SERVER_BURST_GAP)		# bursts per second
 *	* (BLOCKSIZE + 42) * SERVER_BURST_SIZE	# * wire size of a burst
 *
 * which for the default 1k packets, gap of 10ms and burst of 64 packets
 * is about 6.8MB/sec.  In practice, the server is ultimately throttled by
 * clients' ability to generate requests which is limited by their ability
 * to decompress and write to disk.
 */
93
#define SERVER_BURST_SIZE	48
94
#define SERVER_BURST_GAP	1000
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

/*
 * Max burst size when doing dynamic bandwidth adjustment.
 * Needs to be large enough to induce loss.
 */ 
#define SERVER_DYNBURST_SIZE	(SOCKBUFSIZE/BLOCKSIZE)

/*
 * How long (in usecs) to wait before re-reqesting a chunk.
 * It will take the server more than:
 *
 *	(CHUNKSIZE/SERVER_BURST_SIZE) * SERVER_BURST_GAP
 *
 * usec (0.16 sec with defaults) for each each chunk it pumps out,
 * and we conservatively assume that there are a fair number of other
 * chunks that must be processed before it gets to our chunk.
 */
#define CLIENT_REQUEST_REDO_DELAY	\
	(10 * ((CHUNKSIZE/SERVER_BURST_SIZE)*SERVER_BURST_GAP))

/*
 * How long for the writer to sleep if there are no blocks currently
 * ready to write.  Allow a full server burst period, assuming that
 * something in the next burst will complete a block.
 */
#define CLIENT_WRITER_IDLE_DELAY	SERVER_BURST_GAP

/*
 * Client parameters and statistics.
 */
#define CLIENT_STATS_VERSION	1
typedef struct {
	int	version;
	union {
		struct {
			int	runsec;
			int	runmsec;
			int	delayms;
			unsigned long long rbyteswritten;
			unsigned long long ebyteswritten;
			int	chunkbufs;
			int	maxreadahead;
			int	maxinprogress;
			int	pkttimeout;
			int	startdelay;
			int	idletimer;
			int	idledelay;
			int	redodelay;
			int	randomize;
			unsigned long	nochunksready;
			unsigned long	nofreechunks;
			unsigned long	dupchunk;
			unsigned long	dupblock;
			unsigned long	lostblocks;
			unsigned long	recvidles;
			unsigned long	joinattempts;
			unsigned long	requests;
			unsigned long	decompidles;
			unsigned long	writeridles;
		} v1;
		unsigned long limit[256];
	} u;
} ClientStats_t;
158 159 160 161 162 163 164 165 166 167 168 169 170 171

/*
 * Packet defs.
 */
typedef struct {
	struct {
		int		type;
		int		subtype;
		int		datalen; /* Useful amount of data in packet */
		unsigned int	srcip;   /* Filled in by network level. */
	} hdr;
	union {
		/*
		 * Join/leave the Team. Send a randomized ID, and receive
172 173 174
		 * the number of blocks in the file. This is strictly
		 * informational; the info is reported in the log file.
		 * We must return the number of chunks in the file though.
175 176 177 178 179
		 */
		union {
			unsigned int	clientid;
			int		blockcount;
		} join;
180 181 182 183 184
		
		struct {
			unsigned int	clientid;
			int		elapsed;	/* Stats only */
		} leave;
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202

		/*
		 * A data block, indexed by chunk,block.
		 */
		struct {
			int		chunk;
			int		block;
			char		buf[BLOCKSIZE];
		} block;

		/*
		 * A request for a data block, indexed by chunk,block.
		 */
		struct {
			int		chunk;
			int		block;
			int		count;	/* Number of blocks */
		} request;
203 204 205 206 207 208 209 210 211

		/*
		 * Leave reporting client params/stats
		 */
		struct {
			unsigned int	clientid;
			int		elapsed;
			ClientStats_t	stats;
		} leave2;
212 213 214 215 216 217 218 219 220
	} msg;
} Packet_t;
#define PKTTYPE_REQUEST		1
#define PKTTYPE_REPLY		2

#define PKTSUBTYPE_JOIN		1
#define PKTSUBTYPE_LEAVE	2
#define PKTSUBTYPE_BLOCK	3
#define PKTSUBTYPE_REQUEST	4
221
#define PKTSUBTYPE_LEAVE2	5
222 223 224 225 226 227 228

/*
 * Protos.
 */
int	ClientNetInit(void);
int	ServerNetInit(void);
int	PacketReceive(Packet_t *p);
229 230 231
void	PacketSend(Packet_t *p, int *resends);
void	PacketReply(Packet_t *p);
int	PacketValid(Packet_t *p, int nchunks);
232
char   *CurrentTimeString(void);
233
int	sleeptime(unsigned int usecs, char *str);
234
int	fsleep(unsigned int usecs);
235
void	ClientStatsDump(unsigned int id, ClientStats_t *stats);
236 237 238 239 240 241

/*
 * Globals
 */
extern int		debug;
extern int		portnum;
242
extern int		broadcast;
243 244 245
extern struct in_addr	mcastaddr;
extern struct in_addr	mcastif;
extern char	       *filename;
246
extern int		clockres;