From f228ee5462ac06b578343db598ce9ded1ca808b6 Mon Sep 17 00:00:00 2001 From: elvis Date: Fri, 20 May 2022 19:53:43 +0200 Subject: [PATCH] Opdate README --- README.md | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce004ba..c0d8cb3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,177 @@ -# Progetto +# Introduzione -Progetto del Laboratorio di Sistemi Operativi \ No newline at end of file +Il progetto realizzato consiste in un file storage gestito da un server +multithreaded e un client che possono comunicarsi attraverso le funzioni +implementate dall'API. Il codice è presente sulla repository privata al +link: [tautocrono.it](http://tautocrono.it).\ +Si può accedere usando le credenziali: + +::: center + Username Password + ---------- ----------------- + Guest CNs7Vbx3vLJQ2aK +::: + +Il progetto è compilato in modo automatico tramite makefile con i +target: all, test1, test2, test3. Il target all fa partire un'altro +sottoprocesso make che eseguirà il target multi con degli argomenti +aggiuntivi, tipo `-j` in modo da rendere la compilazione multiprocesso. +Ci sono anche i target clean e cleanall che rimuovono gli eseguibili +creati con i precedenti target. + +Sono inclusi anche dei file per testare le funzionalità del client e del +server nella cartella *testFiles*. + +Gli oggetti vengono creati nella directory *obj/*, mentre gli eseguibili +vengono creati nella directory *build/*. La directory *src/* contiene il +codice che fa parte del main del server e del client; il resto del +codice è contenuto nella directory *lib/*. + +È stata implementata sia la politica di rimpiazzamento FIFO che la +politica LRU. + +# Server + +Il server prende come unico argomento il path al file di configurazione. +Un esempio di file di configurazione è `config.ini` presente nella root +del progetto. La struttura del file è analoga a quella di un file +[INI](https://en.wikipedia.org/wiki/INI_file), quindi l'ordine degli +argomenti dentro a sezione è irrilevante. Il file di configurazione +viene letto da una libreria di \"*terza parte*\" ottenuta da +[rxi/ini](https://github.com/rxi/ini). Si sarebbe potuto usare la +libreria [Glib](https://gitlab.gnome.org/GNOME/glib) tuttavia si è +riscontrata una memory leak con valgrind. + +La libreria threadpool e la libreria conn sono state tratte dalla +soluzione dell'esercitazione 11 pubblicata sulla pagina del corso. Si è +preferito l'utilizzo di `strsep` invece di `strtok` o `strtok_r` sia nel +programma server che client. Il codice è stato adattato leggermente da +quello presente nella libreria C GNU +([strsep](https://sourceware.org/git/?p=glibc.git;a=blob;f=string/strsep.c;h=b534a1ec17fd2e91087af04abe1c3f1ac3e74ce0;hb=HEAD)) +in modo da utilizzare la funzione omonima su piattaforme BSD e MacOS. + +## Main + +Il thread principale accetta le connessioni in arrivo da i client su un +socket di tipo `AF_UNIX` con nome di default *socket*. Viene interrotto +dal thread `sighandler_thread` se ricevuto un segnale fra: `SIGHUP`, +`SIGINT` o `SIGQUIT`. + +## serverWorker + +Il thread main dopo aver accettato la connessione di un client crea un +thread \"*worker*\" che aggiunge alla threadpool (definita nei file +omonimi). Ogni worker serve una singola richiesta da parte di un +qualsiasi client connesso. Se le richieste contemporanee dei client +fossero maggiori della dimensione della threadpool, le richieste vengono +accodate in una *pending queue* di dimensione stabilita nel file di +configurazione del server. La singola richiesta viene letta dal worker +thread e viene poi eseguita la funzione associata alla richiesta +presente nella libreria *apiFile*. Alcune di queste operazioni possono +richiedere la presa di una lock associata a un file, quindi per gestire +queste richieste si è fatto uso di una struttura di dati interna +`waiting_t`. La richiesta accodata non è quindi gestita dal thread +corrente, ma dal thread che rilascerà la lock al file associato. Si +evitano quindi *polling* o l'utilizzo di *condition*. + +## sighandler_thread + +Il thread gestisce i segnali in arrivo al server. Se il segnale ricevuto +è di tipo `SIGINT` o `SIGQUIT`, il server termina prima possibile. Se il +segnale ricevuto è del tipo `SIGHUP` invece si attende che ogni worker +abbiano servito le richieste dei client precedentemente connessi. + +# Storage + +Il server gestisce la memorizzazione dei file tramite la libreria +*fileQueue*. Nel header file *fileQueue.h* la costante `ALGORITHM` +imposta la politica di rimpiazzamento. Le funzioni che differiscono in +comportamento sono: `dequeueN`, `lockFileInQueue`, `unlockFileInQueue`, +`openFileInQueue`, `find`, `request`, `searchFile`. Infatti l'elemento +che richiedono come input viene accodato alla fine della struttura nella +politica LRU. Le altre funzioni invece non modificano l'ordine degli +elementi. + +La struttura principale è una linked list chiamata `nodeT` che contiene +i dati del file associato e un puntatore al prossimo elemento. Dato che +l'operazione di scrittura di un file in memoria non è atomica, si è +deciso di usare due misure dell'occupazione della memoria di un file: +`size` e `valid`. L'unico momento in cui potrebbero essere differenti è +quando il client ha richiesto la scrittura di dati, comunicando la +dimensione, quindi il server \"alloca\" tale dimensione come `size`, +lasciando invariato la dimensione `valid`. Dopo che il client ha inviato +i dati da inserire nel file, le dimensioni dovrebbero di nuovo +combaciare. Una singola operazione di scrittura può richiedere più di un +file rimosso per aver abbastanza memoria libera; questa operazione viene +attuata atomicamente e viene considerata come un'unica operazione di +rimpiazzamento. + +# Logging + +Il server usa la libreria \"`taglialegna`\" per scrivere i messaggi di +log su un file specificato nel file di configurazione. Le scritture +vengono sincronizzate tramite lock. Sono state scritte due funzioni che +permettono la scrittura: `taglia_write`, `taglia_log`. `taglia_log` +scrive anche un timestamp prima del messaggio di log. All'inizio +dell'esecuzione del server vengono stampate alcune informazioni lette +dal file di configurazione, come ad esempio la dimensione del threadpool +o la dimensione massima della struttura di cache del server. Al termine +vengono invece scritti alcuni dati di sunto delle operazioni, ad esempio +il numero massimo di file memorizzati o la dimensione massima raggiunta. + +# Client + +Oltre alle funzioni di API richieste dalla specifica è stata +implementata la funzione `setDirectory`, perchè si è interpretata come +se le opzioni `-d` e `-D` dovessero poter essere associate a più di un +comando. Tuttavia questa funzionalità non è presente nel client in modo +diretto dato che vengono inserite `-d`/`-D /dev/null` fra due opzioni +`-w`/`-W` o `-r`/`-R` successive. L'opzione `-d /dev/null` o +`-D /dev/null` è stata ottimizzata leggermente in modo da non fare +chiamate di sistema.\ +Il client esegue prima l'opzione `-f`, in seguito l'opzione `-t`, poi in +ordine tutti gli altri argomenti. In caso di errore durante la scrittura +su un file dopo la creazione, il client richiede la rimozione del file.\ +Per la comunicazione con il server si è optato per un protocollo +ispirato a quello html o ftp, costituito da due cifre, la prima denota +il risultato (positive completion/transient negative +completion/permanent negative completion), la seconda invece è una +specifica della prima. Non tutte le combinazioni sono state usate. + +::: center + Number Meaning + ---------------------------- ------------------------------------------------------------ + 2[\*]{style="color: gray"} positive completion reply + 4[\*]{style="color: gray"} transient negative completion reply (command not executed) + 5[\*]{style="color: gray"} permanent negative completion reply (errors) + [\*]{style="color: gray"}0 syntax + [\*]{style="color: gray"}1 information + [\*]{style="color: gray"}2 connection + [\*]{style="color: gray"}5 file system +::: + +Di seguito una tabella in cui si associa ogni numero al codice usato: + +::: center + Number Meaning Code + --------------------------- --------------------------------- ---------------------------- + 20 OK `MEOK` + [21]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + [22]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + 25 file purged `MEFP` + [40]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + [41]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + 42 shutting down `MESD` + 45 requested file action not taken `MENT` + 50 syntax error `MESY` + [51]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + [52]{style="color: gray"} [not used]{style="color: gray"} [`-`]{style="color: gray"} + 55 server error `MESE` +::: + +Il client invia per primo la dimensione del messaggio come `long`, poi +il messaggio. Il server risponde prima con due caratteri che +simboleggiano is response number, seguito dal errno se si è riscontrato +un errore, oppure i file richiesti o espulsi. Il server per inviare i +file richiesti o espulsi, prima invia il numero di file, poi per ogni +file la dimensione come `int64_t` e poi successivamente il file.