From 4b7f15c55594b4542ff7f1ed466d6400234f1bed Mon Sep 17 00:00:00 2001 From: elvis Date: Tue, 3 May 2022 23:14:39 +0200 Subject: [PATCH] last bug fixes and test2 & test3 --- Makefile | 26 ++++++++++++++++-- config.ini | 8 +++--- lib/api/api.c | 8 +++--- lib/log/taglialegna.c | 3 ++- lib/threadpool/apiFile.c | 14 ++++++++-- lib/threadpool/fileQueue.c | 2 +- scripts/statistiche.sh | 55 ++++++++++++++++++++++++++++++++++++++ scripts/test1.sh | 0 scripts/test2.sh | 10 +++---- scripts/test3.sh | 18 +++++++++++++ src/client.c | 2 +- src/server.c | 20 ++------------ src/serverWorker.c | 15 +++++++++-- 13 files changed, 141 insertions(+), 40 deletions(-) create mode 100755 scripts/statistiche.sh mode change 100644 => 100755 scripts/test1.sh mode change 100644 => 100755 scripts/test2.sh create mode 100755 scripts/test3.sh diff --git a/Makefile b/Makefile index ca0a058..11dc549 100644 --- a/Makefile +++ b/Makefile @@ -114,7 +114,7 @@ test1: all @echo "[socket]" >> $(BUILD_DIR)/config.ini @echo "name = ./socket" >> $(BUILD_DIR)/config.ini @echo "backlog = 100" >> $(BUILD_DIR)/config.ini - valgrind --leak-check=full --track-origins=yes $(BUILD_DIR)/server $(BUILD_DIR)/config.ini & + valgrind --leak-check=full $(BUILD_DIR)/server $(BUILD_DIR)/config.ini & bash scripts/test1.sh pkill --signal SIGHUP memcheck @@ -135,4 +135,26 @@ test2: all @echo "backlog = 100" >> $(BUILD_DIR)/config.ini $(BUILD_DIR)/server $(BUILD_DIR)/config.ini & bash scripts/test2.sh - pkill --signal SIGHUP server + pkill --signal SIGHUP -f $(BUILD_DIR)/server + +test3: all + @echo "[threadpool]" > $(BUILD_DIR)/config.ini + @echo "quantity = 8" >> $(BUILD_DIR)/config.ini + @echo "pending = 100" >> $(BUILD_DIR)/config.ini + @echo "" >> $(BUILD_DIR)/config.ini + @echo "[files]" >> $(BUILD_DIR)/config.ini + @echo "MaxSize = 32000000" >> $(BUILD_DIR)/config.ini + @echo "MaxFiles = 100" >> $(BUILD_DIR)/config.ini + @echo "" >> $(BUILD_DIR)/config.ini + @echo "[log]" >> $(BUILD_DIR)/config.ini + @echo "logFile = ./logs/l.log" >> $(BUILD_DIR)/config.ini + @echo "" >> $(BUILD_DIR)/config.ini + @echo "[socket]" >> $(BUILD_DIR)/config.ini + @echo "name = ./socket" >> $(BUILD_DIR)/config.ini + @echo "backlog = 100" >> $(BUILD_DIR)/config.ini + $(BUILD_DIR)/server $(BUILD_DIR)/config.ini & + bash scripts/test3.sh & + @echo "" + @echo "waiting for 30 seconds" + @sleep 30 + pkill --signal SIGINT -f $(BUILD_DIR)/server diff --git a/config.ini b/config.ini index 5db8ea7..e8cc2cf 100644 --- a/config.ini +++ b/config.ini @@ -1,12 +1,12 @@ [threadpool] -quantity = 1 -pending = 10 +quantity = 4 +pending = 100 [files] -MaxFiles = 10000 -MaxSize = 128000 +MaxFiles = 4 +MaxSize = 1000 [log] diff --git a/lib/api/api.c b/lib/api/api.c index aa8eb10..06e5cb9 100644 --- a/lib/api/api.c +++ b/lib/api/api.c @@ -255,15 +255,15 @@ int openFile(const char* pathname, int flags) { if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) { // some files were purged if(openedFiles->print){ - fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n"); + fprintf(openedFiles->out, "\nIl server ha espulso i seguenti file:\n"); fflush(openedFiles->out); for(int i=0;inumfiles;++i) { - fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path); + fprintf(openedFiles->out, "\t%d) %s\n", i+1, res->rf[i].path); } } if(openedFiles->wDir) { if(openedFiles->print) { - fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", openedFiles->wDir); + fprintf(openedFiles->out, "\tI file espulsi sono stati scritti nella cartella: %s\n", openedFiles->wDir); fflush(openedFiles->out); } if(storeFilesInDirectory(openedFiles->wDir, res->numfiles, res->rf) == -1) { @@ -275,7 +275,7 @@ int openFile(const char* pathname, int flags) { } } else { if(openedFiles->print) { - fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n"); + fprintf(openedFiles->out, "\tI file espulsi non sono stati memorizzati su disco\n"); fflush(openedFiles->out); } } diff --git a/lib/log/taglialegna.c b/lib/log/taglialegna.c index 36f4516..8788b81 100644 --- a/lib/log/taglialegna.c +++ b/lib/log/taglialegna.c @@ -157,7 +157,8 @@ int taglia_stats(taglia_t *taglia, FILE *stream) { double res = ((double) taglia->max_size)/((double) 1000000); fprintf(stream, "Numero di file massimo memorizzato nel server: %zu\n", taglia->max_files); - fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res); + // fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res); + fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %lf MB\n", res); fprintf(stream, "Numero di volte in cui l’algoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \"vittima\": %zu\n", taglia->cache_misses); fflush(stream); diff --git a/lib/threadpool/apiFile.c b/lib/threadpool/apiFile.c index c5610f2..8df0450 100644 --- a/lib/threadpool/apiFile.c +++ b/lib/threadpool/apiFile.c @@ -339,7 +339,7 @@ void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia) { return; } - n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" e' terminata con successo\n", fd_c, filepath); + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" di dimensione = %ld e' terminata con successo\n", fd_c, filepath, f->valid); sendMessageFile(MEOK, f, fd_c, taglia, tmp_buf); destroyFile(f); // f is a copy so we need to cleen up return; @@ -366,6 +366,7 @@ void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia){ n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readNFile (n = %d) e' terminata con successo. File inviati:\n", fd_c, num); // extract n files, we dont check if the client can actually modify // the files since we add them back immediatly + size_t tot = 0; for(int i=0;ifilepath); + tot += toSend[i]->valid; + n += snprintf(tmp_buf+n, m-n, "\t%d) \"%s\" dim = %ld\n", i, toSend[i]->filepath, toSend[i]->valid); } + n += snprintf(tmp_buf+n, m-n, "readNFile dimensione totale = %ld\n", tot); sendMessageFileN(MEOK, toSend, ntosend, fd_c, taglia, tmp_buf); free(toSend); @@ -434,6 +437,13 @@ void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *tagl } destroyFile(f); // not needed anymore + if(trueSizeAdded > q->maxSize) { // removing all files would not be enought + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld ma il file e' piu' grande della dimensione massima\n", fd_c, append, filepath, size); + errno = EFBIG; + serror(MENT, fd_c, taglia, tmp_buf); + return; + } + if(trueSizeAdded + getSize(q) > q->maxSize) { // writing would be more than capacity fileT **removed = NULL; // array that may (worst case) hold all files to be sent to the client diff --git a/lib/threadpool/fileQueue.c b/lib/threadpool/fileQueue.c index 76ae637..8ef8f0d 100644 --- a/lib/threadpool/fileQueue.c +++ b/lib/threadpool/fileQueue.c @@ -264,7 +264,7 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { break; // we eliminated everything so we must have enought space } } - returnList = realloc(returnList, purged+1 * sizeof(fileT*)); + returnList = realloc(returnList, (purged+1) * sizeof(fileT*)); returnList[purged] = NULL; // null terminated tmp->data->size += s; diff --git a/scripts/statistiche.sh b/scripts/statistiche.sh new file mode 100755 index 0000000..5ed29a6 --- /dev/null +++ b/scripts/statistiche.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +LOGFILE="logs/l.log" + +READS=$(awk 'BEGIN{cnt=0} /readFile.*successo/{++cnt} END{print cnt}' $LOGFILE) +READSMEANB=$(awk 'BEGIN{cnt=0; tot=0} /readFile.*successo/{where = match($0, /dimensione = ([0-9]+)/, arr); if(where != 0) {++cnt; tot+=strtonum(arr[1])}} END{if(cnt!=0){print tot/cnt} else {print 0}}' $LOGFILE) + +NREADS=$(awk 'BEGIN{cnt=0} /readNFile.*successo/{++cnt} END {print cnt}' $LOGFILE) +NREADSMEANN=$(awk 'BEGIN{cnt=0; tot=0} /readNFile.*successo/{where = match($0, /\(n = ([0-9]+)\)/, arr); if(where != 0) {++cnt; tot+=strtonum(arr[1])}} END{if(cnt!=0) {print tot/cnt} else {print 0}}' $LOGFILE) +NREADSMEANB=$(awk 'BEGIN{cnt=0; tot=0} /readNFile/{where = match($0, /totale = ([0-9]+)/, arr); if(where != 0) {++cnt; tot+=strtonum(arr[1])}} END{if(cnt!=0) {print tot/cnt} else {print 0}}' $LOGFILE) + +LETTURA=$(echo $READS + $NREADS | bc -l) + + +WRITES=$(awk 'BEGIN{cnt=0} /writeFile.*successo/{++cnt} END{print cnt}' $LOGFILE) +WRITESMEANB=$(awk 'BEGIN{cnt=0; tot=0} /writeFile.*successo/{where = match($0, /dimensione = ([0-9]+)/, arr); if(where != 0) {++cnt; tot+=strtonum(arr[1])}} END{if(cnt!=0){print tot/cnt} else {print 0}}' $LOGFILE) + + +LOCKS=$(awk 'BEGIN{cnt=0} /lockFile.*successo/{++cnt} END{print cnt}' $LOGFILE) +OPENLOCKS=$(awk 'BEGIN{cnt=0} /openFile.*flags = [23].*successo/{++cnt} END{print cnt}' $LOGFILE) +UNLOCKS=$(awk 'BEGIN{cnt=0} /unlockFile.*successo/{++cnt} END{print cnt}' $LOGFILE) +CLOSES=$(awk 'BEGIN{cnt=0} /closeFile.*successo/{++cnt} END{print cnt}' $LOGFILE) + + +NTHREADS=$(awk 'BEGIN{n=0} /Creato threadpool.*/{where = match($0, /dimensione ([0-9]+)/, arr); if(where != 0) {n=strtonum(arr[1])}} END{print n}' $LOGFILE) +T=() +for ((i=0;i<$NTHREADS;i++)); do + T[$i]=$(awk -v i=$i 'BEGIN{cnt=0; pat="Thread "i".*ha servito una richiesta"} $0 ~ pat{++cnt} END{print cnt}' $LOGFILE) +done + +MAXNFILES=$(awk 'BEGIN{n=0} /Numero di file massimo.*/{where = match($0, /: ([0-9]+)/, arr); if(where != 0) {n=strtonum(arr[1])}} END{print n}' $LOGFILE) +MAXBFILES=$(awk 'BEGIN{n=0} /Dimensione massima.*/{where = match($0, /: ([0-9.]+)/, arr); if(where != 0) {n=strtonum(arr[1])}} END{print n}' $LOGFILE) +MAXVITTIMS=$(awk 'BEGIN{n=0} /vittima.*/{where = match($0, /: ([0-9.]+)/, arr); if(where != 0) {n=strtonum(arr[1])}} END{print n}' $LOGFILE) + +MAXCLIENTS=$(awk 'BEGIN{max=0; cur=0} {where = match($0, /Nuovo client.*/); if(where != 0) {++cur; max = (max ./logs/client1.log & +./build/client -t 200 -f socket -w testFiles/2 -D build/Wdir -r testFiles/2/file10 -R n=3 -d build/Rdir -p > ./logs/client2.log & +./build/client -t 200 -f socket -w testFiles/3 -D build/Wdir -r testFiles/3/file15 -R n=3 -d build/Rdir -p > ./logs/client3.log & +./build/client -t 200 -f socket -w testFiles/4 -D build/Wdir -r testFiles/4/file20 -R n=3 -d build/Rdir -p > ./logs/client4.log & +./build/client -t 200 -f socket -w testFiles/5 -D build/Wdir -r testFiles/5/file25 -R n=3 -d build/Rdir -p > ./logs/client5.log & wait exit 0 diff --git a/scripts/test3.sh b/scripts/test3.sh new file mode 100755 index 0000000..eb841c8 --- /dev/null +++ b/scripts/test3.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +for ((i = 0; i <= 30; i++)); do + ./build/client -t 0 -f socket -w testFiles/1 -W testFiles/6/f1 -D build/Wdir -r testFiles/1/file1 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/2 -W testFiles/6/f2 -D build/Wdir -r testFiles/2/file6 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/3 -W testFiles/6/f3 -D build/Wdir -r testFiles/3/file11 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/4 -W testFiles/6/f4 -D build/Wdir -r testFiles/4/file16 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/5 -W testFiles/6/f5 -D build/Wdir -r testFiles/5/file21 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/1 -W testFiles/6/f1 -D build/Wdir -r testFiles/1/file2 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/2 -W testFiles/6/f2 -D build/Wdir -r testFiles/2/file7 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/3 -W testFiles/6/f3 -D build/Wdir -r testFiles/3/file12 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/4 -W testFiles/6/f4 -D build/Wdir -r testFiles/4/file17 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/5 -W testFiles/6/f5 -D build/Wdir -r testFiles/5/file22 -R n=5 -d build/Rdir & + ./build/client -t 0 -f socket -w testFiles/6 -r testFiles/1/file1 -R n=5 -d build/Rdir & + sleep 1 +done + +exit 0 diff --git a/src/client.c b/src/client.c index aa27fbc..3b9b707 100644 --- a/src/client.c +++ b/src/client.c @@ -323,7 +323,7 @@ int reorderCommandList(cmd_t **l) { prev->arg = t.arg; prev->name = t.name; - if(!prev->next) + if(!tmp->next) break; // add redirect to dev/null for next command if it's r or R diff --git a/src/server.c b/src/server.c index 8209c4e..d5ab115 100644 --- a/src/server.c +++ b/src/server.c @@ -19,12 +19,7 @@ #include -/** - * @struct sigHandlerArgs_t - * @brief struttura contenente le informazioni da passare - * al signal handler thread - * - */ + typedef struct { sigset_t *set; // set dei segnali da gestire (mascherati) int signal_pipe; // descrittore di scrittura di una pipe senza nome @@ -34,7 +29,6 @@ typedef struct { static void *sigHandler(void *arg); static void usage(const char *argv0) { - // TODO change this fprintf(stderr, "use: %s \n", argv0); } @@ -266,7 +260,7 @@ int main(int argc, char *argv[]) { // scrivo sul log - n = snprintf(buf, sizeof(buf), "New client: %ld\n", *connfd); + n = snprintf(buf, sizeof(buf), "Nuovo client: %ld\n", *connfd); if( n<0 ) { perror("snprintf"); free(connfd); @@ -318,16 +312,6 @@ int main(int argc, char *argv[]) { switch (pdr) { case -1: // client disconnected --numberOfConnections; - n = snprintf(buf, sizeof(buf), "Client %ld disconnected.\n", pdr); - if( n<0 ) { - perror("snprintf"); - free(connfd); - goto _cleanup; - } - if( taglia_log(taglia, buf) < 0) { - free(connfd); - goto _cleanup; - } if (stopNewConnections && numberOfConnections <= 0) { quit = 1; // termino il signalThread diff --git a/src/serverWorker.c b/src/serverWorker.c index dc103ad..74068b5 100644 --- a/src/serverWorker.c +++ b/src/serverWorker.c @@ -27,15 +27,26 @@ void threadF(void *arg) { } threadT *argl = (threadT *) arg; + long connfd = argl->connfd; volatile int *quit = argl->quit; int request_pipe = argl->request_pipe; queueT *q = argl->q; taglia_t *taglia = argl->taglia; - // threadpool_t *pool = argl->pool; + threadpool_t *pool = argl->pool; pthread_mutex_t *lock = argl->lock; waiting_t **waiting = argl->waiting; + int myid = -1; + pthread_t tid = pthread_self(); + + for (int i = 0; i < pool->numthreads ; ++i) { + if(pthread_equal(pool->threads[i], tid)) { + myid = i; + break; + } + } + fd_set set, tmpset; FD_ZERO(&set); FD_SET(connfd, &set); @@ -121,7 +132,7 @@ closeConnection: // log int m = 0; char buf[1024]; - m = snprintf(buf, sizeof(buf), "Servito una richiesta del client %ld.\n", connfd); + m = snprintf(buf, sizeof(buf), "Thread %d ha servito una richiesta del client %ld.\n", myid, connfd); if( m<0 ) { perror("snprintf"); goto _cleanup;