last bug fixes and test2 & test3
This commit is contained in:
26
Makefile
26
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
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
[threadpool]
|
||||
|
||||
quantity = 1
|
||||
pending = 10
|
||||
quantity = 4
|
||||
pending = 100
|
||||
|
||||
[files]
|
||||
|
||||
MaxFiles = 10000
|
||||
MaxSize = 128000
|
||||
MaxFiles = 4
|
||||
MaxSize = 1000
|
||||
|
||||
[log]
|
||||
|
||||
|
||||
@ -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;i<res->numfiles;++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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;i<ntosend;++i) {
|
||||
toSend[i] = dequeue(q);
|
||||
if(!toSend[i]) {
|
||||
@ -383,8 +384,10 @@ void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia){
|
||||
serror(MESE, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
n += snprintf(tmp_buf+n, m-n, "\t%d) \"%s\"\n", i, toSend[i]->filepath);
|
||||
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
|
||||
|
||||
@ -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;
|
||||
|
||||
55
scripts/statistiche.sh
Executable file
55
scripts/statistiche.sh
Executable file
@ -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<cur)?cur:max}; where = match($0, /Chiusa connessione.*/); if(where != 0) {--cur}} END{print max}' $LOGFILE)
|
||||
|
||||
echo "Operazioni di read: $READS (dimensione media: $READSMEANB)"
|
||||
echo "Operazioni di readN: $NREADS (numero medio: $NREADSMEANN, dimensione media: $NREADSMEANB)"
|
||||
echo "Operazioni totali di lettura: $LETTURA"
|
||||
|
||||
echo "Operazioni di write: $WRITES (dimensione media: $WRITESMEANB)"
|
||||
|
||||
echo "Operazioni di lock: $LOCKS"
|
||||
echo "Operazioni di openlock: $OPENLOCKS"
|
||||
echo "Operazioni di unlock: $UNLOCKS"
|
||||
echo "Operazioni di close: $CLOSES"
|
||||
|
||||
for ((i=0;i<$NTHREADS;i++)); do
|
||||
echo "Richieste servite dal worker thread $i: ${T[$i]}"
|
||||
done
|
||||
|
||||
echo "Numero massimo di file: $MAXNFILES"
|
||||
echo "Dimensione massima dei file: $MAXBFILES MB"
|
||||
echo "Numero di volte in cui l’algoritmo di rimpiazzamento della cache è stato eseguito per selezionare un file vittima: $MAXVITTIMS"
|
||||
echo "Massimo numero di connessioni contemporanee: $MAXCLIENTS"
|
||||
0
scripts/test1.sh
Normal file → Executable file
0
scripts/test1.sh
Normal file → Executable file
10
scripts/test2.sh
Normal file → Executable file
10
scripts/test2.sh
Normal file → Executable file
@ -1,10 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
./build/client -t 200 -f socket -w testFiles/1 -l testFiles/1/file1 -W testFiles/6/f1 -D build/Wdir -r testFiles/1/file1 -R n=3 -d build/Rdir -u testFiles/1/file1 -p &
|
||||
./build/client -t 200 -f socket -w testFiles/2 -W testFiles/6/f2 -D build/Wdir -l testFiles/1/file1 -r testFiles/2/file6 -R n=3 -d build/Rdir -u testFiles/1/file1 -p &
|
||||
./build/client -t 200 -f socket -w testFiles/3 -W testFiles/6/f3 -D build/Wdir -r testFiles/3/file11 -R n=3 -d build/Rdir -l testFiles/3/file11 -c testFiles/3/file11 -p &
|
||||
./build/client -t 200 -f socket -w testFiles/4 -W testFiles/6/f4 -D build/Wdir -r testFiles/4/file16 -R n=3 -d build/Rdir -l testFiles/3/file12 -c testFiles/3/file12 -p &
|
||||
./build/client -t 200 -f socket -w testFiles/5 -W testFiles/6/f5 -D build/Wdir -r testFiles/5/file21 -R n=3 -d build/Rdir -l testFiles/3/file13 -c testFiles/3/file13 -p &
|
||||
./build/client -t 200 -f socket -w testFiles/1 -D build/Wdir -l testFiles/1/file5 -r testFiles/1/file5 -R n=3 -d build/Rdir -u testFiles/1/file5 -p > ./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
|
||||
|
||||
18
scripts/test3.sh
Executable file
18
scripts/test3.sh
Executable file
@ -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
|
||||
@ -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
|
||||
|
||||
20
src/server.c
20
src/server.c
@ -19,12 +19,7 @@
|
||||
#include <taglialegna.h>
|
||||
|
||||
|
||||
/**
|
||||
* @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 <config file location>\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
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user