Commit f5bda928 authored by Mike Hibler's avatar Mike Hibler
Browse files

Fix some overflow conditions related to memory buffer sizes.

Ryan fixed this before, but apparently didn't check it in.
This commit also revisits the setting of the "max" values for buffering
limits and distinguishes the default values from the max.
parent 8dbe7f4b
......@@ -39,8 +39,8 @@ static int exitstatus;
#endif
/* Tunable constants */
int maxchunkbufs = MAXCHUNKBUFS;
int maxwritebufmem = MAXWRITEBUFMEM;
int maxchunkbufs = DEFCHUNKBUFS;
int maxwritebufmem = DEFWRITEBUFMEM;
int maxmem = 0;
int pkttimeout = PKTRCV_TIMEOUT;
int idletimer = CLIENT_IDLETIMER_COUNT;
......@@ -83,9 +83,9 @@ extern int ImageUnzipInitKeys(char *uuidstr, char *sig_keyfile,
char *enc_keyfile);
extern int ImageUnzipInit(char *filename, int slice, int debug, int zero,
int nothreads, int dostype, int dodots,
unsigned long writebufmem, int directio);
unsigned long long writebufmem, int directio);
extern void ImageUnzipSetChunkCount(unsigned long chunkcount);
extern void ImageUnzipSetMemory(unsigned long writebufmem);
extern void ImageUnzipSetMemory(unsigned long long writebufmem);
extern int ImageWriteChunk(int chunkno, char *chunkdata, int chunksize);
extern int ImageUnzipChunk(char *chunkdata, int chunksize);
extern int ImageUnzipFlush(void);
......@@ -338,18 +338,17 @@ main(int argc, char **argv)
mem = atoi(optarg);
if (mem < 1)
mem = 1;
else if (mem > 32768)
mem = 32768;
maxchunkbufs = (mem * 1024 * 1024) /
sizeof(ChunkBuffer_t);
else if (mem > MAXCHUNKBUFS)
mem = MAXCHUNKBUFS;
maxchunkbufs = mem;
break;
case 'W':
mem = atoi(optarg);
if (mem < 1)
mem = 1;
else if (mem > 32768)
mem = 32768;
else if (mem > MAXWRITEBUFMEM)
mem = MAXWRITEBUFMEM;
maxwritebufmem = mem;
break;
......@@ -357,8 +356,8 @@ main(int argc, char **argv)
mem = atoi(optarg);
if (mem < 2)
mem = 2;
else if (mem > 65536)
mem = 65536;
else if (mem > MAXMEMUSE)
mem = MAXMEMUSE;
maxmem = mem;
break;
......@@ -538,20 +537,20 @@ main(int argc, char **argv)
else
idletimer = CLIENT_IDLETIMER_COUNT;
if (event.data.start.chunkbufs >= 0 &&
event.data.start.chunkbufs <= 1024)
event.data.start.chunkbufs <= MAXCHUNKBUFS)
maxchunkbufs = event.data.start.chunkbufs;
else
maxchunkbufs = MAXCHUNKBUFS;
if (event.data.start.writebufmem >= 0 &&
event.data.start.writebufmem < 4096)
event.data.start.writebufmem < MAXWRITEBUFMEM)
maxwritebufmem = event.data.start.writebufmem;
else
maxwritebufmem = MAXWRITEBUFMEM;
if (event.data.start.maxmem >= 0 &&
event.data.start.maxmem < 4096)
event.data.start.maxmem < MAXMEMUSE)
maxmem = event.data.start.maxmem;
else
maxmem = 0;
maxmem = MAXMEMUSE;
if (event.data.start.readahead >= 0 &&
event.data.start.readahead <= maxchunkbufs)
maxreadahead = event.data.start.readahead;
......@@ -625,7 +624,8 @@ main(int argc, char **argv)
*/
if (maxmem != 0) {
/* XXX divide it up 50/50 */
maxchunkbufs = (maxmem/2 * 1024*1024) / sizeof(ChunkBuffer_t);
maxchunkbufs = (int)((unsigned long long)maxmem/2 * 1024*1024
/ sizeof(ChunkBuffer_t));
maxwritebufmem = maxmem/2;
}
......@@ -639,7 +639,9 @@ main(int argc, char **argv)
* The writer thread synchronizes only with us (the decompresser).
*/
ImageUnzipInit(filename, slice, debug, zero, nothreads, dostype,
quiet ? 0 : 3, maxwritebufmem*1024*1024, forcedirectio);
quiet ? 0 : 3,
(unsigned long long)maxwritebufmem*1024*1024,
forcedirectio);
if (tracing) {
ClientTraceInit(traceprefix);
......@@ -1768,6 +1770,9 @@ PlayFrisbee(void)
TotalChunkCount = TotalChunks();
ImageUnzipSetChunkCount(TotalChunkCount);
if (maxchunkbufs == 0)
maxchunkbufs = TotalChunkCount;
/*
* If we have partitioned up the memory and have allocated
* more chunkbufs than chunks in the file, reallocate the
......@@ -1777,12 +1782,14 @@ PlayFrisbee(void)
if (maxmem != 0 && maxchunkbufs > TotalChunkCount) {
int excessmb;
excessmb = ((maxchunkbufs - TotalChunkCount) *
sizeof(ChunkBuffer_t)) / (1024 * 1024);
excessmb = (int)((((unsigned long long)
(maxchunkbufs - TotalChunkCount) *
sizeof(ChunkBuffer_t)) / (1024 * 1024)));
maxchunkbufs = TotalChunkCount;
if (excessmb > 0) {
maxwritebufmem += excessmb;
ImageUnzipSetMemory(maxwritebufmem*1024*1024);
ImageUnzipSetMemory((unsigned long long)
maxwritebufmem*1024*1024);
}
}
......
......@@ -68,8 +68,11 @@
* The ratio of the number of these two buffer types depends on the ratio
* of network to disk speed and the degree of compression in the image.
*/
#define MAXCHUNKBUFS 64 /* 64MB with default chunk size */
#define MAXWRITEBUFMEM 64 /* in MB */
#define DEFCHUNKBUFS 64 /* 64MB with default chunk size */
#define MAXCHUNKBUFS (128*1024) /* 128GB with default chunk size */
#define DEFWRITEBUFMEM 64 /* in MB */
#define MAXWRITEBUFMEM (128*1024) /* in MB */
#define MAXMEMUSE (256*1024) /* in MB */
/*
* Socket buffer size, used for both send and receive in client and
......
......@@ -194,8 +194,8 @@ typedef struct {
char *data;
} writebuf_t;
static unsigned long maxwritebufmem = MAXWRITEBUFMEM;
static volatile unsigned long curwritebufmem, curwritebufs;
static unsigned long long maxwritebufmem = MAXWRITEBUFMEM;
static volatile unsigned long long curwritebufmem, curwritebufs;
#ifndef NOTHREADS
static queue_head_t writequeue;
static pthread_mutex_t writebuf_mutex;
......@@ -206,7 +206,8 @@ static pthread_cond_t writebuf_cond;
static volatile int writebufwanted;
/* stats */
unsigned long maxbufsalloced, maxmemalloced;
unsigned long maxbufsalloced;
unsigned long long maxmemalloced;
unsigned long splits;
#ifdef WITH_CRYPTO
......@@ -332,7 +333,7 @@ void dodots(int dottype, off_t cc)
void
dump_writebufs(void)
{
fprintf(stderr, "%lu max bufs, %lu max memory\n",
fprintf(stderr, "%lu max bufs, %llu max memory\n",
maxbufsalloced, maxmemalloced);
fprintf(stderr, "%lu buffers split\n",
splits);
......@@ -640,8 +641,8 @@ main(int argc, char *argv[])
#ifndef NOTHREADS
case 'W':
maxwritebufmem = atoi(optarg);
if (maxwritebufmem >= 4096)
maxwritebufmem = (unsigned long long)atoi(optarg);
if (maxwritebufmem >= MAXWRITEBUFMEM)
maxwritebufmem = MAXWRITEBUFMEM;
maxwritebufmem *= (1024 * 1024);
break;
......@@ -1005,7 +1006,7 @@ ImageUnzipInitKeys(char *uuidstr, char *sig_keyfile, char *enc_keyfile)
int
ImageUnzipInit(char *filename, int _slice, int _debug, int _fill,
int _nothreads, int _dostype, int _dodots,
unsigned long _writebufmem, int _directio)
unsigned long long _writebufmem, int _directio)
{
int flags;
......@@ -1084,7 +1085,7 @@ ImageUnzipSetChunkCount(unsigned long _chunkcount)
}
void
ImageUnzipSetMemory(unsigned long _writebufmem)
ImageUnzipSetMemory(unsigned long long _writebufmem)
{
#ifndef NOTHREADS
maxwritebufmem = _writebufmem;
......
......@@ -263,22 +263,16 @@ loadone() {
HOSTMEM=`expr $HOSTMEM / 1048576`
if [ $HOSTMEM -ge `expr $RESIDMEM + 2` ]; then
HOSTMEM=`expr $HOSTMEM - $RESIDMEM`
BYTES=`expr $HOSTMEM \* 1024`
KBYTES=`expr $HOSTMEM \* 1024`
DATASEGSZ=`ulimit -d`
if [ $BYTES -gt $DATASEGSZ ]; then
BYTES=$DATASEGSZ
HOSTMEM=`expr $BYTES / 1024`
if [ $KBYTES -gt $DATASEGSZ ]; then
KBYTES=$DATASEGSZ
HOSTMEM=`expr $KBYTES / 1024`
echo "WARNING: kernel limits buffering to $HOSTMEM MB"
fi
ulimit -v $BYTES
ulimit -v $KBYTES
## For GaTech we use more memory for disks since the disks are so slow
#NETMEM=`expr $HOSTMEM \* 1 / 3`
#DISKMEM=`expr $HOSTMEM \* 2 / 3`
#MEMARGS="-C $NETMEM -W $DISKMEM"
# For Utah, we let the client split up the memory
# (50/50, but no more chunk buffers than there are chunks in the image)
# Let the client split up the memory
MEMARGS="-M $HOSTMEM"
fi
......
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