From b11640aff0cd6fc10c23723d411342f96ba6936b Mon Sep 17 00:00:00 2001 From: elvis Date: Mon, 21 Mar 2022 01:51:45 +0100 Subject: [PATCH] Librearia di log --- lib/log/taglialegna.c | 181 ++++++++++++++++++++++++++++++++++++++++++ lib/log/taglialegna.h | 40 ++++++++++ src/server.c | 13 +-- 3 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 lib/log/taglialegna.c create mode 100644 lib/log/taglialegna.h diff --git a/lib/log/taglialegna.c b/lib/log/taglialegna.c new file mode 100644 index 0000000..62af1fc --- /dev/null +++ b/lib/log/taglialegna.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include + +#include + +taglia_t *taglia_init(char *file, int n, ...) { + int max_files; + int max_size; + int cache_misses; + + taglia_t *new = calloc(1, sizeof(taglia_t)); + if(new == NULL) { + perror("calloc"); + return NULL; + } + va_list ap; + va_start(ap, n); // nota: si ha sempre default argument promotion, + // ma noi leggiamo solo int quindi ignoriamo il problema + max_files = (n<1)?0:va_arg(ap, int); + max_size = (n<2)?0:va_arg(ap, int); + cache_misses = (n<3)?0:va_arg(ap, int); + va_end(ap); + + if ( (new->file = fopen(file, "w")) == NULL ) { + perror("fopen logfile"); + goto _error_init; + } + + new->max_files = max_files; + new->max_size = max_size; + new->cache_misses = cache_misses; + + if (pthread_mutex_init(&new->m, NULL) != 0) { + perror("mutex init"); + fclose(new->file); + goto _error_init; + } + + return new; + +_error_init: + free(new); + return NULL; +} + +void taglia_del(taglia_t *taglia) { + fclose(taglia->file); + pthread_mutex_destroy(&taglia->m); + free(taglia); +} + +size_t taglia_write(taglia_t *taglia, char *buf) { + if(!taglia || !buf) { + errno = EINVAL; + return -1; + } + size_t n = 0; + pthread_mutex_lock(&taglia->m); + if ((n = fwrite(buf, sizeof(char), strlen(buf)+1, taglia->file)) < 0) { + // strlen conta il numero di caratteri senza EOF quindi aggiungiamo 1 + perror("fwrite"); + goto _error_write; + } + pthread_mutex_unlock(&taglia->m); + + return n; + +_error_write: + pthread_mutex_unlock(&taglia->m); + return -1; +} + +size_t taglia_log(taglia_t *taglia, char *buf) { + if(!taglia || !buf) { + errno = EINVAL; + return -1; + } + + time_t now = time(NULL); + if(now == (time_t)(-1)) { // errore a ottenere l'ora + perror("ERROR: time"); + goto _error_taglia_log; + } + struct tm tmp_buf; + struct tm *now_tm; + + now_tm = gmtime_r(&now, &tmp_buf); + if(!now_tm){ + perror("ERROR: gmtime_r"); + goto _error_taglia_log; + } + + char buff[15]; // 13 only should strictly needed + + if(!strftime(buff, sizeof(buff), "[%T] ", now_tm)) { + perror("ERROR: strftime"); + goto _error_taglia_log; + } + + size_t n, m; + pthread_mutex_lock(&taglia->m); + if((n = fwrite(buff, sizeof(char), sizeof(buff), taglia->file)) < 0){ + perror("ERROR: fwrite"); + goto _error_taglia_log_mutex; + } + + if((m = fwrite(buf, sizeof(char), strlen(buff)+1, taglia->file)) < 0){ + // strlen conta il numero di caratteri senza EOF quindi aggiungiamo 1 + perror("ERROR: fwrite"); + goto _error_taglia_log_mutex; + } + pthread_mutex_unlock(&taglia->m); + + return n+m; + +_error_taglia_log_mutex: + pthread_mutex_unlock(&taglia->m); +_error_taglia_log: + return -1; +} + +int taglia_update(taglia_t *taglia, queueT *q, int miss) { + if(!taglia || !q) { + errno = EINVAL; + return -1; + } + + pthread_mutex_lock(&taglia->m); + + size_t len = getLen(q); + size_t size = getSize(q); + + 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; + + pthread_mutex_unlock(&taglia->m); + + return 0; +} + +int taglia_stats(taglia_t *taglia, FILE *stream) { + if (!taglia) { + errno = EINVAL; + return -1; + } + + pthread_mutex_lock(&taglia->m); + + 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, "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); + fflush(stream); + + + char tmp_buf[2048]; + int n = 0; + size_t m = sizeof(tmp_buf); + n += snprintf(tmp_buf+n, m-n, "Numero di file massimo memorizzato nel server: %zu\n", taglia->max_files); + if(mcache_miss); + if(mm); + + if(taglia_write(taglia, tmp_buf) < 0) + return -1; + + return 0; + +_error_taglia_stats: + pthread_mutex_unlock(&taglia->m); + return -1; +} diff --git a/lib/log/taglialegna.h b/lib/log/taglialegna.h new file mode 100644 index 0000000..48ed1d3 --- /dev/null +++ b/lib/log/taglialegna.h @@ -0,0 +1,40 @@ +#pragma once +#ifndef _TAGLIALEGNA +#define _TAGLIALEGNA + +#include + +typedef struct taglia_s { + FILE *file; + size_t max_files; + long max_size; + size_t cache_misses; + pthread_mutex_t m; // per sincronizzare le scritture al file +} taglia_t; + +// crea una nuova istanza +// \param file: file su cui scrivere i dati +// \param n: numero di parametri opzionali +// parametri opzionali in questo ordine: +// max_files, max_size, cache_misses +// \return istanza creata, NULL se errore +taglia_t *taglia_init(char *file, int n, ...); + +// elimina un'istanza deallocando e chiudendo le rispettive risorse +void taglia_del(taglia_t *taglia); + +// scrive quello contenuto dentro a buf sul file +// \return numero di char scritti, -1 se errore +size_t taglia_write(taglia_t *taglia, char *buf); + +// scrive il contenuto di buf sul file con ora associata +size_t taglia_log(taglia_t *taglia, char *buf); + +// update delle statistiche +// \return 0 successo, -1 errore +int taglia_update(taglia_t *taglia, queueT *queue, int miss); + +// print delle statistiche attuali su stream +int taglia_stats(taglia_t *taglia, FILE *stream); + +#endif /* _TAGLIALEGNA */ diff --git a/src/server.c b/src/server.c index 68c8cdc..acd4450 100644 --- a/src/server.c +++ b/src/server.c @@ -54,7 +54,7 @@ static void checkargs(int argc, char* argv[]) { } int main(int argc, char *argv[]) { - // TODO read config file + // read config file checkargs(argc, argv); ini_t *config = ini_load(argv[1]); int threadsInPool; CONFGETINT(threadsInPool, config, "threadpool", "quantity", NULL, 10); @@ -64,12 +64,10 @@ int main(int argc, char *argv[]) { ini_free(config); sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGQUIT); - sigaddset(&mask, SIGTERM); + sigfillset(&mask); + sigdelset(&mask, SIGPIPE); // tolgo soltanto la sigpipe - if (pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0) { + if (pthread_sigmask(SIG_SETMASK, &mask, NULL) != 0) { fprintf(stderr, "ERROR setting mask\n"); goto _cleanup; } @@ -83,6 +81,9 @@ int main(int argc, char *argv[]) { goto _cleanup; } + // remove("mysock"); maybe necessary??? + + printf("File Server ready."); fflush(stdout);