diff --git a/lib/log/taglialegna.c b/lib/log/taglialegna.c index 98141c1..b9ae058 100644 --- a/lib/log/taglialegna.c +++ b/lib/log/taglialegna.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -136,7 +137,7 @@ int taglia_update(taglia_t *taglia, queueT *q, int miss) { taglia->max_files = (len > taglia->max_files)?len:taglia->max_files; taglia->max_size = (size > taglia->max_size)?size:taglia->max_size; - logFileT->cache_miss += (miss>0)?miss:0; + taglia->cache_misses += (miss>0)?miss:0; pthread_mutex_unlock(&taglia->m); @@ -155,7 +156,7 @@ int taglia_stats(taglia_t *taglia, FILE *stream) { 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, "Numero di volte in cui l’algoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \"vittima\": %zu\n", taglia->cache_miss); + 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); @@ -166,7 +167,7 @@ int taglia_stats(taglia_t *taglia, FILE *stream) { if(mcache_miss); + n += snprintf(tmp_buf+n, m-n, "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); if(mm); diff --git a/lib/threadpool/apiFile.c b/lib/threadpool/apiFile.c index ff4585c..cb50500 100644 --- a/lib/threadpool/apiFile.c +++ b/lib/threadpool/apiFile.c @@ -1,3 +1,5 @@ +#include + #include #include @@ -21,6 +23,30 @@ // ----------------------------------------------------------------------------- /* funzioni ausiliarie */ +// invio il messaggio al client e poi l'errno +void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) { + if(!m) { + errno = EINVAL; + m = MESY; + } + if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) { + perror("writen"); + goto _serror_cleanup; + } + if(writen(fd_c, &errno, sizeof(errno)) < 0) { + perror("writen"); + goto _serror_cleanup; + } + + if(taglia_write(taglia, mlog) < 0) + goto _serror_cleanup; + + return; + +_serror_cleanup: + return; +} + // invio il messaggio al client void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) { if(!m) { @@ -45,11 +71,13 @@ _sendM_cleanup: void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) { if(!f) { errno = EINVAL; - serror(MESY, fd_c); + char errmlog[2048] = "Errore negli argomenti alla funzione sendMessagefile (fileT == NULL). Messaggio originale:\n\t"; + strncat(errmlog, mlog, sizeof(errmlog)-strlen(errmlog)-1); + serror(MESY, fd_c, taglia, errmlog); goto _sendMF_cleanup; } if(!m) { - m = MEPF; + m = MEFP; } if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) { @@ -72,30 +100,32 @@ _sendMF_cleanup: } // invio il messaggio al client e poi n file -void sendMessageFileN(char *m, fileT **f, int n, long fd_c, taglia *taglia, char *mlog) { +void sendMessageFileN(char *m, fileT **f, int n, long fd_c, taglia_t *taglia, char *mlog) { if(!f) { errno = EINVAL; - serror(MESY, fd_c); + char errmlog[2048] = "Errore negli argomenti alla funzione sendMessagefile (fileT == NULL). Messaggio originale:\n\t"; + strncat(errmlog, mlog, sizeof(errmlog)-strlen(errmlog)-1); + serror(MESY, fd_c, taglia, errmlog); goto _sendMFN_cleanup; } if(!m) { - m = MEPF; + m = MEFP; } if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) { perror("writen"); - goto _sendMF_cleanup; + goto _sendMFN_cleanup; } for(int i=0; imaxLen) { // capacity miss + if(getLen(q) == q->maxLen) { // capacity miss removed = dequeue(q); if(!removed) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath); @@ -188,14 +194,14 @@ void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) if(!f) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("createFileT"); - serror(MESE, fd_c, taglia); + serror(MESE, fd_c, taglia, tmp_buf); return; } if(enqueue(q, f) != 0) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("enqueue"); - serror(MESE, fd_c, taglia); + serror(MESE, fd_c, taglia, tmp_buf); return; } @@ -211,14 +217,14 @@ void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) if(!f) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("createFileT"); - serror(MESE, fd_c, taglia); + serror(MESE, fd_c, taglia, tmp_buf); return; } if(enqueue(q, f) != 0) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("enqueue"); - serror(MESE, fd_c, taglia); + serror(MESE, fd_c, taglia, tmp_buf); return; } // abbiamo aggiunto un file quindi il numero di file è cambiato @@ -238,7 +244,7 @@ void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia) { size_t m = sizeof(tmp_buf); if(!filepath || !q || !taglia) { - n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath); + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" e' terminata con errore\n", fd_c, filepath); errno = EINVAL; serror(MESY, fd_c, taglia, tmp_buf); return; @@ -247,21 +253,21 @@ void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia) { fileT *f = NULL; f = find(q, filepath); if(!f) { - n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath); + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" e' terminata con errore\n", fd_c, filepath); errno = ENOENT; serror(MESE, fd_c, taglia, tmp_buf); return; } if(f->open != 0) { // file already open - n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath); + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" e' terminata con errore\n", fd_c, filepath); errno = EPERM; serror(MENT, fd_c, taglia, tmp_buf); destroyFile(f); // f is a copy so we need to cleen up return; } - n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con successo\n", fd_c, flags, filepath); + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile sul file \"%s\" e' terminata con successo\n", fd_c, filepath); sendMessageFile(MEOK, f, fd_c, taglia, tmp_buf); destroyFile(f); // f is a copy so we need to cleen up return; @@ -355,19 +361,19 @@ void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *tagl if(append) { if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) { perror("appendFileInQueue"); - free(content) + free(content); return; } } else { if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) { perror("writeFileInQueue"); - free(content) + free(content); return; } } taglia_update(taglia, q, 0); - free(content) + free(content); return; } @@ -388,62 +394,62 @@ void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *tagl if(append) { if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) { perror("appendFileInQueue"); - free(content) + free(content); return; } } else { if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) { perror("writeFileInQueue"); - free(content) + free(content); return; } } - taglia_write(taglia, mlog); + taglia_write(taglia, tmp_buf); taglia_update(taglia, q, 0); - free(content) + free(content); return; } -void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting) { +void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) { return; } -void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting) { +void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) { return; } -void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting) { +void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) { return; } -void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting) { +void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) { return; } int sendFile(fileT *f, long fd_c, taglia_t *taglia) { - return; + return 0; } -int addWaiting(waitingT **waiting, char *file, int fd) { - return; +int addWaiting(waiting_t **waiting, char *file, int fd) { + return 0; } -int removeFirstWaiting(waitingT **waiting, char *file) { - return; +int removeFirstWaiting(waiting_t **waiting, char *file) { + return 0; } -void clearWaiting(waitingT **waiting) { +void clearWaiting(waiting_t **waiting) { return; } diff --git a/lib/threadpool/fileQueue.c b/lib/threadpool/fileQueue.c index 8df4be9..1b17630 100644 --- a/lib/threadpool/fileQueue.c +++ b/lib/threadpool/fileQueue.c @@ -1,7 +1,7 @@ #include #include -#define NAMELEN 256 +#define MAXNAMELEN 256 // creazione di un fileT fileT* createFileT(char *f, int O_LOCK, int client, int open){ @@ -12,30 +12,31 @@ fileT* createFileT(char *f, int O_LOCK, int client, int open){ fileT *file = malloc(sizeof(fileT)); - if (f == NULL) { + if (file == NULL) { perror("Malloc createFileT"); return NULL; } - f->O_LOCK = (O_LOCK == 0)? 0 : 1; - f->owner = client; - f->open = (open == 0)? 0 : 1; - f->size = 0; - f->valid = 0; + file->O_LOCK = (O_LOCK == 0)? 0 : 1; + file->owner = client; + file->open = (open == 0)? 0 : 1; + file->size = 0; + file->valid = 0; - if ((f->filepath = malloc(sizeof(char)*NAMELEN)) == NULL) { + if ((file->filepath = malloc(sizeof(char)*MAXNAMELEN)) == NULL) { perror("Malloc filepath"); - destroyFile(f); + destroyFile(file); return NULL; } - strncpy(f->filepath, f, NAMELEN); + strncpy(file->filepath, f, MAXNAMELEN); - if ((f->data = malloc(1)) == NULL) { // così semplicemente facciamo realloc + // in seguito semplicemente facciamo realloc + if ((file->data = malloc(1)) == NULL) { perror("Malloc content"); return NULL; } - return f; + return file; } // append su fileT @@ -53,6 +54,7 @@ int writeFileT(fileT *f, void *data, size_t size) { memcpy((char*) f->data + f->valid, data, size); f->valid = f->valid + size; f->size = (f->valid>f->size)?f->valid:f->size; + return 0; } // destroy fileT @@ -126,15 +128,15 @@ int enqueue(queueT *q, fileT* data) { newNode->data = data; newNode->next = NULL; - nodeT *tmp = queue->head; + nodeT *tmp = q->head; if (q->head == NULL) q->head = newNode; else { while (tmp->next) - tmp = temp->next; + tmp = tmp->next; - temp->next = newNode; + tmp->next = newNode; } q->tail = newNode; @@ -228,14 +230,8 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { goto _end_dequeueN; } - if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) { - // if file non è aperto o la lock non è del owner - errno = EPERM; - goto _end_dequeueN; - } - fileT **returnList = NULL; // lista dei file rimossi - nodeT *tmp = NULL; + tmp = NULL; returnList = calloc(1, sizeof(fileT*)); returnList[0] = NULL; diff --git a/lib/threadpool/fileQueue.h b/lib/threadpool/fileQueue.h index 3a2870e..f335867 100644 --- a/lib/threadpool/fileQueue.h +++ b/lib/threadpool/fileQueue.h @@ -2,6 +2,10 @@ #ifndef _FILE_QUEUE #define _FILE_QUEUE +#include + +#include +#include // struttura dati per gestire i file in memoria principale typedef struct { diff --git a/src/server.c b/src/server.c index 687ce77..b0ec8f7 100644 --- a/src/server.c +++ b/src/server.c @@ -236,7 +236,7 @@ int main(int argc, char *argv[]) { // cerchiamo di capire da quale fd abbiamo ricevuto una richiesta for(int i=0; i <= fdmax; ++i) { if (FD_ISSET(i, &tmpset)) { - long* connfd = malloc(sizeof(long)); + int* connfd = malloc(sizeof(long)); if (!connfd) { perror("ERROR FATAL malloc"); goto _cleanup; @@ -260,7 +260,7 @@ int main(int argc, char *argv[]) { // scrivo sul log - n = snprintf(buf, sizeof(buf), "New client: %ld\n", (long) *connfd); + n = snprintf(buf, sizeof(buf), "New client: %d\n", *connfd); if( n<0 ) { perror("snprintf"); goto _cleanup; diff --git a/src/serverWorker.c b/src/serverWorker.c index 2e981c3..7ce9766 100644 --- a/src/serverWorker.c +++ b/src/serverWorker.c @@ -10,6 +10,11 @@ #include #include #include +#include +#include + + +int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, pthread_mutex_t *lock, waiting_t **waiting); // funzione eseguita dal Worker thread del pool void threadF(void *arg) { @@ -18,13 +23,20 @@ void threadF(void *arg) { return; } - // TODO add necessary variables from main - long* connfd = ; + threadT *argl = (threadT *) arg; + int 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; + pthread_mutex_t *lock = argl->lock; + waiting_t **waiting = argl->waiting; fd_set set, tmpset; FD_ZERO(&set); - FD_SET(*connfd, &set); + FD_SET(connfd, &set); while(*quit == 0) { tmpset=set; @@ -47,58 +59,92 @@ void threadF(void *arg) { // comunicate with the client msg_t str; long n; + // leggo la dimensione del messaggio if ((n=readn(connfd, &str.len, sizeof(long))) == -1) { perror("read1"); - break; + goto _cleanup; } if (n==0) - break; + goto _cleanup;; str.str = calloc(str.len+1, sizeof(char)); if (!str.str) { perror("calloc"); fprintf(stderr, "Calloc.\n"); - break; + goto _cleanup; } + // leggo il messaggio if ((n=readn(connfd, str.str, str.len * sizeof(char))) == -1) { perror("read2"); free(str.str); - break; + goto _cleanup; } - str.str[str.len+1] = '\0'; + str.str[str.len] = '\0'; if(strncmp(str.str, "quit", 5)) { // il client vuole chiudere la connessione + close(connfd); + + int close = -1; // comunico al manager che ho chiuso la connessione - // ... + if (writen(request_pipe, &close, sizeof(int)) == -1) { + perror("writen"); + goto _cleanup; + } // log chiusura connessione - // ... + int n = 0; + char buf[1024]; + n = snprintf(buf, sizeof(buf), "Chiusa connessione con il client %d.\n", connfd); + if( n<0 ) { + perror("snprintf"); + goto _cleanup; + } + if( taglia_log(taglia, buf) < 0 ) + goto _cleanup; goto _cleanup; } // eseguo quello che mi chiede il client di fare - if (parser(str.len, str.str) == -1) { - // str.str non è più valido perchè parser fa free - + if (parser(str.len, str.str, q, connfd, taglia, lock, waiting) == -1) { + goto _cleanup; } + // str.str non è più valido perchè parser fa free // comunico al manager che è stata servita la richiesta - + if (writen(request_pipe, &connfd, sizeof(int)) == -1) { + perror("writen"); + } // log + int m = 0; + char buf[1024]; + m = snprintf(buf, sizeof(buf), "Servito una richiesta del client %d.\n", connfd); + if( m<0 ) { + perror("snprintf"); + goto _cleanup; + } + if( taglia_log(taglia, buf) < 0 ) + goto _cleanup; + return; _cleanup: - if(arg) - free(arg); - close(connfd); + // nothing to do because no memory needs to be freed + return; } -int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, pthread_mutex_t *lock, waitingT **waiting) { - if(len<0 || !command || !queue || !logFileT || !waiting) { +int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, pthread_mutex_t *lock, waiting_t **waiting) { + if(len<0 || !command || !queue || !taglia || !waiting) { errno = EINVAL; return -1; } - char *save = command; + char *string = calloc(1, len); + if(string == NULL) { + perror("calloc"); + return -1; + } + strncpy(string, command, len-1); // strlcpy is only bsd :( + string[len-1] = '\0'; + char *token = NULL; char *token2 = NULL; char *token3 = NULL; @@ -116,7 +162,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p int arg = (int) strtol(token3, NULL, 10); - openFile(token2, arg, queue, fd_c, logFileT); + openFile(token2, arg, queue, fd_c, taglia); goto _parser_end; } @@ -124,7 +170,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - readFile(token2, queue, fd_c, logFileT); + readFile(token2, queue, fd_c, taglia); goto _parser_end; } @@ -132,7 +178,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - readNFiles(token2, queue, fd_c, logFileT); + readNFiles(token2, queue, fd_c, taglia); goto _parser_end; } @@ -141,7 +187,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p goto _parser_cleanup; size_t sz = (size_t) strtol(token3, NULL, 10); - writeFile(token2, sz, queue, fd_c, logFileT, 0); + writeFile(token2, sz, queue, fd_c, taglia, 0); goto _parser_end; } @@ -150,7 +196,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p goto _parser_cleanup; size_t sz = (size_t) strtol(token3, NULL, 10); - writeFile(token2, sz, queue, fd_c, logFileT, 1); + writeFile(token2, sz, queue, fd_c, taglia, 1); goto _parser_end; } @@ -158,7 +204,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - lockFile(token2, queue, fd_c, logFileT, lock, waiting); + lockFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } @@ -166,7 +212,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - unlockFile(token2, queue, fd_c, logFileT, lock, waiting); + unlockFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } @@ -174,7 +220,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - closeFile(token2, queue, fd_c, logFileT, lock, waiting); + closeFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } @@ -182,7 +228,7 @@ int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, p if(!token2) goto _parser_cleanup; - removeFile(token2, queue, fd_c, logFileT, lock, waiting); + removeFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } // se arrivo qui non ho riconosciuto il comando diff --git a/src/serverWorker.h b/src/serverWorker.h index 457068b..0f925b9 100644 --- a/src/serverWorker.h +++ b/src/serverWorker.h @@ -5,12 +5,13 @@ #include #include #include +#include // struttura dati che contiene gli argomenti da passare ai worker threads typedef struct struct_thread { volatile int *quit; int request_pipe; - long *connfd; + int *connfd; queueT *q; // puntatore alla queue dei file taglia_t *taglia; // puntatore alla struct del file di log threadpool_t *pool; // puntatore alla threadpool